Skip to content

file attachment support_ja

Kazushi Kamegawa edited this page Jul 19, 2026 · 1 revision

ファイル添付サポート

日付: 2026-07-19 追跡: Issue #67、sub-issue #68、#69、#70、#71、#72

概要

チャットツールウィンドウにファイル添付を実装する。クリップボタンで複数 ファイル選択ダイアログを開き、コンポーザー内の # トークンでワークスペース ファイルのインライン候補リストを表示し、保留中の添付はコンポーザー上部に 削除可能なチップとして表示する。送信時に添付は turn/start の入力アイテムに 変換される — ローカル画像は localImage、その他のファイルは既存の IDE コンテキスト mention 直列化を再利用した mention アイテムになる。

drag & drop は今回明示的に見送る。Remote UI はコードビハインドとイベント ハンドラーを備えず、Drop イベントのファイルパスを拡張プロセスへ渡せない。 SDK への機能要望(VSExtensibility request 561)がオープン中。見送りの判断は doc/adr.md に記録する。

設計判断

  • チップが添付の唯一の真実であり、#filename テキストは表示上のエコー。 Remote UI はキャレット位置を取得できずトークン追跡は信頼できないため、 テキストを消しても添付は外れず、チップの削除ボタンで外す。
  • ユーザーが明示的に選んだファイルはワークスペース外も許可するが、拡張側と Worker 側の両方で存在チェックと保護ディレクトリポリシーを検証する (多層防御)。IDE コンテキスト由来の mention は従来どおりワークスペース内 限定。
  • steering ターンは text のみ。保留チップは次の turn/start で消費される。 チップは送信成功時のみクリアする。

実装

  1. Contracts と Worker: AttachmentInfo { Path, Kind } と StartTurnRequest.Attachments を追加し、BuildTurnInput で新設の IsAllowedAttachmentPath ゲートを通して localImage/mention アイテムを 送出(IDE コンテキストとの重複排除、上限 10)。
  2. サービス: シェルの複数ファイルダイアログを包む IFilePickerService と、 ワークスペースの project query+ディスク列挙フォールバック+短 TTL キャッシュ+テスト可能なフィルター/ランクロジック(上位 20 件、 ファイル名前方一致 > 部分一致 > パス部分一致)による IWorkspaceFileSearchService。
  3. チップ UI: AttachmentChipViewModel データコントラクト、ChatViewModel の PendingAttachments コレクション、コンポーザーグリッドへのチップ行追加、 添付ボタンの実処理(検証・重複排除・上限・通知)。
  4. # トリガー: スラッシュコマンドと並行のファイル候補プレゼンテーション VM、末尾トークン検出(## エスケープ、スラッシュ候補との相互排他)、 150 ms デバウンス、確定時のトークン置換とチップ追加。
  5. ドキュメント: doc/adr.md を新規作成(D&D 見送りと上記の判断)し、 doc/task.md に作業を記録する。

検証

  • turn-input 形状、パスポリシー、重複排除、添付なしの後方互換の単体テスト。
  • fake の picker/検索サービスによる ViewModel テスト: チップ追加/削除/上限、 送信時の複写とクリア、失敗時保持、steering 時保持。
  • トリガーテスト: 末尾トークンのみ発火、## エスケープ、スラッシュ候補との 排他、確定時の置換、トークン編集後のチップ残存、デバウンスキャンセル。
  • warnings-as-errors での Release ビルド。実験インスタンスでピッカー動作、 チップ表示、# のキー操作、入力中のキャレット安定性を手動確認。

制約

  • Remote UI XAML ではコードビハインドとイベントハンドラーを使わない。 新規 ViewModel 型はすべて DataContract/DataMember を付与する。
  • localImage の対応可否はインストール済み Codex CLI のバージョンに依存 する。非対応時は既存の app-server エラー経路で可視化される。

Clone this wiki locally