Skip to Content
デベロッパーガイドDaemon共有UI トランスクリプトレイヤー

共有UI トランスクリプトレイヤー

現在のステータス: packages/cli/src/ui/daemon/daemon-tui-adapter.ts はレガシーの実験的CLIサイドアダプターとして main ブランチに引き続き存在します。このドキュメントでは、新しいSDKサイドの共有UIトランスクリプトレイヤーについて説明します。これは、Web、TUI、IDE、IMチャンネルなど、あらゆるUIホストが利用できる再利用可能なデーモンイベント正規化とトランスクリプトプリミティブです。CLI TUI、チャンネル、VS Code IDEのマイグレーションはフォローアップ作業となります。

概要

packages/sdk-typescript/src/daemon/ui/ はSDKに ui/* サブパッケージを追加します。再利用可能なプリミティブを通じて、デーモンSSEイベントストリームをUIがレンダリング可能なトランスクリプトブロックに変換します。

  • 正規化 (normalizer.ts): デーモンワイヤースキーマの既知の43種類のイベントタイプ(09-event-schema.md 参照)を、assistant.text.deltatool.updatesession.metadata.changed などの37種類のUI向け DaemonUiEventType セマンティクスイベントにマッピングします。
  • ステートマシン (transcript.tsstore.ts): 純粋なリデューサーと購読可能なストアで、UIイベントを順序付きの DaemonTranscriptBlock[] に変換します。
  • レンダラー (render.tsterminal.tstoolPreview.ts): トランスクリプトブロックをHTML、ターミナルテキスト、ツールプレビュー文字列に変換します。ホストはこれらを利用するか、独自のものに置き換えることができます。
  • 適合性テスト (conformance.ts): チャンネル、TUI、IDEのサーフェスがこれらのプリミティブに移行する際に使用するクロスホスト整合性テストです。

最初のプロダクション消費者は packages/webui/src/daemon/ (#4328 ) です。ReactのDaemonSessionProviderとトランスクリプトアダプターにより、Web UIはホストの postMessage トラフィックをレンダリングするだけでなく、デーモンのHTTP+SSEに直接接続できます。CLI TUI、チャンネルベース、VS Code IDEは後で同じレイヤーを再利用できます。../daemon-ui/MIGRATION.md にはv2の段階的なマイグレーションガイドが記載されています。

責務

  • デーモンの43種類のワイヤーイベントを安定したUI語彙(DaemonUiEventType)に正規化し、レンダラーが rawEvent.data を検査しなくて済むようにします。
  • デーモンの単調増加するSSE eventId主要な順序付けキーとして保持し、異なるクライアントが同じ順序でトランスクリプトをレンダリングできるようにします。
  • 純粋なリデューサーを使用してトランスクリプトブロックを生成し、保留中の権限、現在のツール、承認モード、ツールの進捗状況、サブエージェントの子などのセレクターを提供します。
  • ベースラインHTMLおよびターミナルレンダラーを提供しつつ、ホスト固有のレンダリングも許可します。
  • プランパネル用の DAEMON_PLAN_TOOL_CALL_ID などのパブリック定数を公開します。
  • 追加的なワイヤー互換性を維持します。未知のイベントタイプは破棄されるのではなく debug に正規化されます。

アーキテクチャ

パッケージ構造

ファイルエクスポート目的
packages/sdk-typescript/src/daemon/ui/index.tsサブパッケージのバレルパブリックエントリーポイント
ui/types.tsDaemonUiEventType、タイプ別 DaemonUiEvent* インターフェース、DaemonTranscriptBlockDaemonTranscriptStateDaemonUiToolProvenanceDAEMON_PLAN_TOOL_CALL_ID型定義
ui/normalizer.tsnormalizeDaemonEvent(evt) -> DaemonUiEventgetSessionUpdatePayload(evt)ワイヤーからUIへのマッピング
ui/transcript.tscreateDaemonTranscriptState()appendLocalUserTranscriptMessage()reduceDaemonTranscriptEvents()rebuildDaemonTranscriptBlockIndex()、セレクターステートマシンとセレクター
ui/store.tscreateDaemonTranscriptStore(initial?)購読可能なリデューサーストア
ui/toolPreview.tscreateDaemonToolPreview(toolEvent)ツールコールのサマリーテキスト
ui/render.tsDaemonHtmlRenderOptionsDaemonRenderOptions、レンダー関数HTMLおよび汎用レンダリング
ui/terminal.tsターミナル固有のレンダリングTUI向け準備
ui/conformance.tsクロスホスト適合性スイートマイグレーション同等性テスト
ui/utils.tsDaemonUiContentPart などのヘルパー内部共有ユーティリティ

DaemonUiEventType 語彙

ui/types.ts はドメインごとにグループ化された37種類のUIイベントタイプを定義しています。

チャットストリーム(Stage 1)

  • user.text.deltauser.image.deltauser.shell.commandassistant.text.deltaassistant.donethought.text.delta
  • tool.updateshell.outputuser.shell.output
  • permission.requestpermission.resolved
  • model.changedstatuserrordebug

セッションメタデータ

  • session.metadata.changedsession.approval_mode.changed
  • session.available_commandssession.state_resync_requiredsession.replay_complete

プロンプトライフサイクル(クロスクライアント)

  • prompt.cancelledfollowup.suggestion

ワークスペース(Wave 3-4)

  • workspace.memory.changedworkspace.agent.changed
  • workspace.tool.toggledworkspace.settings.changedworkspace.initialized
  • workspace.mcp.budget_warningworkspace.mcp.child_refused
  • workspace.mcp.server_restartedworkspace.mcp.server_restart_refused

認証フロー(Wave 4 OAuth)

  • auth.device_flow.startedauth.device_flow.throttledauth.device_flow.authorized
  • auth.device_flow.failedauth.device_flow.cancelled

normalizeDaemonEvent はデーモンの既知の43種類のワイヤーイベントをこの語彙にマッピングします。未知、未モデル化、または不正なイベントタイプは debug に正規化され、ホストの診断用に rawEvent が保持されます。

リデューサーとセレクター

// 初期状態を作成する。 const state = createDaemonTranscriptState(); // SSEイベントシーケンスを適用する。 const next = reduceDaemonTranscriptEvents(state, daemonUiEvents); // セレクター。 selectTranscriptBlocks(state); // すべてのブロック selectTranscriptBlocksOrderedByEventId(state); // eventIdで順序付け(推奨キー) selectPendingPermissionBlocks(state); selectCurrentTool(state); selectApprovalMode(state); selectToolProgress(state, toolCallId); selectSubagentChildBlocks(state, parentBlockId); isSubagentChildBlock(block); formatBlockTimestamp(block); formatMissedRange(state); // state_resync_required後の "X件のイベントを見逃しました" テキスト

ストア

createDaemonTranscriptStore() はsubscribeとdispatchを提供します。

const store = createDaemonTranscriptStore(); store.subscribe(() => render(store.getState())); store.dispatch(uiEvents); // 内部でリデューサーを実行する

Web UIの DaemonSessionProvider はこのストアの上にReactコンテキストを構築します。

フロー

単一SSEイベントのエンドツーエンド

ホストは (E) で止まって独自のリデューサーを実装するか、(G) と提供されたセレクターを利用することができます。Web UIは (B) -> (H) の完全なパスを使用します。マイグレーション済みのTUIは (G) を利用して、Ink固有のコンポーネントでレンダリングできます。

state_resync_required

session.state_resync_required はトランスクリプトの「見逃した範囲」マーカーにマッピングされます。UIコードは formatMissedRange(state) を呼び出して、“missed events X-Y” のようなテキストをレンダリングできます。リデューサーはその後のイベントの適用を継続しますが、影響を受けるブロックに resyncRecovery: true をマークし、レンダラーが視覚的なコンテキストを追加できるようにします。リングエビクションと state_resync_required のセマンティクスについては 10-event-bus.md を参照してください。

コンシューマー

packages/webui/src/daemon/

これは #4328  でマージされました。

ファイルエクスポート
DaemonSessionProvider.tsxReact <DaemonSessionProvider />useDaemonSession()useDaemonTranscriptStore()useDaemonTranscriptState()useDaemonTranscriptBlocks()useDaemonPendingPermissions()useDaemonActions()useDaemonConnection() フック;DaemonConnectionStatusDaemonConnectionStateDaemonSessionContextValue
transcriptAdapter.tsSDK の DaemonTranscriptBlock をWeb UIの UnifiedMessage に変換します。マークダウンストリーミングのチャンクマージとツールコールサマリーを含みます。
index.tsサブパッケージのバレル

Web UIはデーモンのHTTP+SSEに直接接続してトランスクリプトをレンダリングできるようになりました。旧来の ACPAdapter ホストの postMessage パスは引き続き利用可能です。

今後のマイグレーション

../daemon-ui/MIGRATION.md はWebチャットとWebターミナルアダプターのv2段階的ガイドを提供しています。そのPRでは CLI TUI、チャンネルベース、VS Code IDEは移行されていないことを明示しており、それぞれフォローアップPRで移行し、適合性スイートを使用してレンダリングの同等性を維持します。

レガシー daemon-tui-adapter.ts との関係

次元レガシーCLI DaemonTuiAdapter新しい共有トランスクリプトレイヤー
パッケージpackages/cli/src/ui/daemon/packages/sdk-typescript/src/daemon/ui/
パブリックサーフェスDaemonTuiAdapterDaemonTuiUpdateDaemonTuiSessionClientDaemonUiEventTypereduceDaemonTranscriptEvents、セレクター
スコープCLI Ink TUI のみWeb、TUI、IDE、またはIM UI
状態の形状TUIローカルの更新ユニオン純粋なトランスクリプトブロックリストと状態フィールド
順序付けcreatedAteventId(デーモン単調増加、クライアント間で一貫)
未知のワイヤータイプreduceDaemonEventToTuiUpdates で破棄debug に正規化して保持
テスト単一パッケージのユニットテストクロスホスト同等性のためのグローバル適合性スイート

依存関係

設定

  • ランタイム設定はありません。リデューサーとセレクターは純粋関数です。
  • ホストはレンダラーを選択します: HTML(render.ts)、ターミナル(terminal.ts)、またはカスタムレンダリング。
  • デバッグ用に、render.tsincludeRawEvent: true をサポートしており、レンダリング出力に生のワイヤーフレームを含めることができます。

注意事項と既知の制限

  • daemon-tui-adapter.ts は引き続き存在します。これはCLIパッケージのレガシーな実験的アダプターです。新しいコードはSDKの ui/*normalizeDaemonEventreduceDaemonTranscriptEventsDaemonTranscriptBlock)を優先して使用してください。
  • CLI TUI、チャンネルベース、VS Code IDEはまだ移行されていません。これらは独自のレンダリングロジックを維持しています。docs/developers/daemon-client-adapters/ ディレクトリには ide.mdchannel-web.md、歴史的な tui.md ドラフトが引き続き存在します。新しい web-ui.md はWeb UIアダプターの設計をカバーしています。
  • eventId が主要な順序付けキーですcreatedAt は非推奨のエイリアス(clientReceivedAt)として残っています。新しいコードでは selectTranscriptBlocksOrderedByEventId(state) を使用してください。MIGRATION.md には createdAt 順序から eventId 順序への切り替えのコード差分が記載されています。
  • 未知のワイヤータイプは debug に正規化されます。旧アダプターのように破棄されなくなりました。レンダラーはデフォルトで debug を表示しません。ホストが表示を有効化する必要があります。
  • バンドルサイズ: ui/* サブパッケージは @qwen-code/sdk/daemon 経由でESMサブパスとしてエクスポートされており、ReactやDOM依存関係を引き込みません。React統合はWeb UIコンシューマーが DaemonSessionProvider を使用する場合にのみロードされます。

参考資料

  • packages/sdk-typescript/src/daemon/ui/types.tsDaemonUiEventType 語彙)
  • packages/sdk-typescript/src/daemon/ui/transcript.ts(リデューサーとセレクター)
  • packages/sdk-typescript/src/daemon/ui/normalizer.ts(ワイヤーからUIへのマッピング)
  • packages/sdk-typescript/src/daemon/ui/store.tsrender.tsterminal.tstoolPreview.tsconformance.ts
  • packages/sdk-typescript/src/daemon/index.tsui/* 再エクスポートブロック)
  • packages/webui/src/daemon/DaemonSessionProvider.tsxtranscriptAdapter.ts
  • 上流ドキュメント: ../daemon-ui/README.md../daemon-ui/MIGRATION.md../daemon-client-adapters/web-ui.md
  • 関連PR: #4328 (v1トランスクリプトレイヤーとWeb UIプロバイダー)、#4353 (v2統合完全性フォローアップ)
Last updated on