# 画面設計書 44-インラインチャット

## 概要

本ドキュメントは、VSCodeのインラインチャット画面の設計を記載したものです。インラインチャットは、コードエディタ内に直接AIチャットインターフェースを表示し、コンテキストを維持したままコード生成・編集を行う機能です。

### 本画面の処理概要

インラインチャットは、Visual Studio Codeのエディタ内に表示されるAIアシスタント対話ウィジェットです。ユーザーが選択したコード範囲に対して、その場で質問や編集指示を行い、AIが生成したコードを直接適用できます。

**業務上の目的・背景**：
従来のサイドバーチャットでは、コードとチャット画面の間を行き来する必要がありました。インラインチャットは、編集対象のコードを見ながらAIと対話できるため、コンテキストの切り替えコストを削減し、より自然なコーディングフローを実現します。特にリファクタリング、バグ修正、コード説明などの局所的な作業に効果的です。

**画面へのアクセス方法**：
- エディタ内で `Ctrl+I`（Windows/Linux）または `Cmd+I`（macOS）
- エディタ右クリックメニューから「Copilot」→「Start Inline Chat」
- コマンドパレットから「Inline Chat: Start Inline Chat」
- ガターのスパークルアイコンをクリック（設定で有効時）

**主要な操作・処理内容**：
1. インラインチャットの起動：選択範囲またはカーソル位置でウィジェットを開く
2. プロンプト入力：AIへの指示をテキスト入力
3. コード生成/編集：AIがコードを生成し、差分プレビューを表示
4. 変更の適用：生成されたコードを承認してエディタに適用
5. 変更の破棄：生成されたコードを拒否して元に戻す
6. 追加の対話：結果に対してさらに指示を追加

**画面遷移**：
- エディタ（通常編集）→ インラインチャット（起動）→ エディタ（変更適用）
- インラインチャット → チャットビュー（詳細な対話へ移動）

**権限による表示制御**：
- GitHub Copilotのサブスクリプションが必要
- `inlineChat.mode` 設定で表示モードを制御
- `inlineChat.accessibleDiffView` 設定でアクセシビリティモードを制御

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 65 | GitHub Copilot | 主機能 | AI対話・コード生成 |
| 66 | コード補完 | 補助機能 | コード挿入・編集 |

## 画面種別

オーバーレイ（エディタ内ウィジェット）

## URL/ルーティング

エディタコントリビューションID: `editor.contrib.inlineChatController`

## 入出力項目

| 項目名 | 入力/出力 | 型 | 必須 | 説明 |
|--------|----------|-----|------|------|
| ユーザープロンプト | 入力 | string | Yes | AIへの指示テキスト |
| 選択範囲 | 入力 | ISelection | No | 編集対象のコード範囲 |
| 添付ファイル | 入力 | URI[] | No | コンテキストとして添付するファイル |
| モデルセレクター | 入力 | ILanguageModelChatSelector | No | 使用するAIモデル |
| 生成コード | 出力 | TextEdit[] | Yes | AIが生成したコード編集 |
| 差分プレビュー | 出力 | DiffEditorWidget | No | 変更前後の差分表示 |

## 表示項目

| 項目名 | 表示位置 | 説明 |
|--------|----------|------|
| 入力エリア | ウィジェット内 | プロンプト入力用のミニエディタ |
| 送信ボタン | 入力欄右側 | リクエスト送信/キャンセル |
| ステータスバー | ウィジェット下部 | アクションボタン（適用、破棄） |
| プログレス | ウィジェット内 | 生成中のインジケーター |
| 差分表示 | エディタ内 | 生成コードの差分プレビュー |
| ガターアイコン | エディタガター | インラインチャット起動アイコン |

## イベント仕様

### 1-インラインチャット起動

`Ctrl+I` またはガターアイコンをクリックすると：
1. `StartSessionAction` が実行される
2. `InlineChatController.run()` が呼び出される
3. `InlineChatZoneWidget` がエディタに挿入される
4. `InlineChatSessionService` で新しいセッションを作成
5. ウィジェットにフォーカスが移動

### 2-プロンプト送信

Enter または送信ボタンをクリックすると：
1. `ChatSubmitAction` が実行される（インラインチャットコンテキスト）
2. 現在の選択範囲と入力テキストからリクエストを構築
3. `chatService.sendRequest()` で AI にリクエスト送信
4. ストリーミングで応答を受信
5. 生成されたコードを差分プレビューで表示

### 3-変更の適用

「Keep」または `Ctrl+Enter` で：
1. `KeepSessionAction2` が実行される
2. 生成されたコード編集をエディタに適用
3. `chatModel.acceptChanges()` で変更を確定
4. セッションを終了しウィジェットを閉じる

### 4-変更の破棄

「Discard」または `Escape` で：
1. `UndoAndCloseSessionAction2` が実行される
2. 差分プレビューを破棄
3. エディタを元の状態に戻す
4. セッションを終了しウィジェットを閉じる

### 5-ガターインジケーター表示

マーカー（問題）がある行で：
1. `InlineChatAffordance` がガターを監視
2. マーカーのある行にスパークルアイコンを表示
3. クリックでインラインチャットを起動（診断情報付き）

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| セッション開始 | Memory (transient) | INSERT | セッション情報の作成 |
| 変更適用 | Editor Document | UPDATE | ドキュメントの編集 |

### テーブル別更新項目詳細

#### Memory (transient)

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | inlineChat.sessions | セッションオブジェクト | IInlineChatSession2 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| placeholder | プレースホルダー | "Generate code" | 選択なし時 |
| placeholderWithSelection | プレースホルダー | "Modify selected code" | 選択あり時 |
| send.edit | ボタン | "Edit Code" | 編集モード時 |
| send.generate | ボタン | "Generate" | 生成モード時 |
| cancel | ボタン | "Cancel Request" | リクエスト中 |
| refactor.label | メニュー | "Refactor..." | ガターメニュー |
| source.label | メニュー | "Source Action..." | ガターメニュー |

## 例外処理

| 例外パターン | 処理内容 | 表示メッセージ |
|-------------|---------|---------------|
| モデル未登録 | エディタにフォーカスを戻す | なし |
| リクエストキャンセル | セッションを維持、入力を保持 | なし |
| 生成エラー | エラーメッセージを表示 | "Failed to generate" |
| セッション不正 | セッションを破棄 | なし |

## 備考

- `InlineChatController` がエディタコントリビューションとして登録
- `EditorContributionInstantiation.Eager` で即座にインスタンス化（Notebook対応）
- `InlineChatZoneWidget` がエディタ内に表示されるウィジェット
- `EditorBasedInlineChatWidget` が実際のチャットUI
- `InlineChatSessionServiceImpl` でセッション管理
- `ChatAgentLocation.EditorInline` でロケーション識別
- 設定 `inlineChat.mode` で 'zone' または 'hover' モードを選択可能
- `CTX_INLINE_CHAT_VISIBLE` コンテキストキーで表示状態を管理

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、インラインチャットで扱う主要なデータ構造を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | inlineChat.ts | `src/vs/workbench/contrib/inlineChat/common/inlineChat.ts` | CTX_INLINE_CHAT_*, InlineChatConfigKeysなどのコンテキストキーと設定 |
| 1-2 | inlineChatSessionService.ts | `src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionService.ts` | IInlineChatSession2インターフェース |

**読解のコツ**: コンテキストキーの役割を理解し、UI状態管理のパターンを把握してください。

#### Step 2: エントリーポイントを理解する

処理の起点となるコントローラークラスを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | inlineChatController.ts | `src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts` | InlineChatControllerクラス |

**主要処理フロー**:
1. **L100-140**: コンストラクタで依存サービスを注入、コンテキストキーの初期化
2. **L143-186**: _gutterIndicatorの初期化、renderModeの設定
3. **L148-216**: InlineChatZoneWidgetのLazy初期化
4. **L223-228**: _currentSessionのderived observable

#### Step 3: ウィジェット実装を理解する

インラインチャットのUIウィジェットを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | inlineChatWidget.ts | `src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts` | InlineChatWidgetクラス |
| 3-2 | inlineChatZoneWidget.ts | `src/vs/workbench/contrib/inlineChat/browser/inlineChatZoneWidget.ts` | InlineChatZoneWidgetクラス |

**主要処理フロー**:
- **L78-93**: DOM構造の定義（_elements）
- **L112-283**: コンストラクタでChatWidgetを構築、イベントハンドラを登録
- **L285-299**: _updateAriaLabel()でアクセシビリティラベルを設定

#### Step 4: アクションを理解する

ユーザーアクションの実装を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | inlineChatActions.ts | `src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts` | StartSessionAction, KeepSessionAction2, UndoAndCloseSessionAction2 |
| 4-2 | inlineChat.contribution.ts | `src/vs/workbench/contrib/inlineChat/browser/inlineChat.contribution.ts` | アクション登録、メニュー定義 |

**主要処理フロー**:
- **L27-34**: InlineChatControllerをエディタコントリビューションとして登録
- **L29-30**: KeepSessionAction2, UndoAndCloseSessionAction2を登録
- **L38-84**: メニューアイテムの定義（Edit Code, Generate, Cancel）
- **L88-89**: StartSessionAction, FocusInlineChatを登録

### プログラム呼び出し階層図

```
StartSessionAction
    │
    └─ InlineChatController.run()
           │
           ├─ InlineChatZoneWidget (Lazy初期化)
           │      ├─ EditorBasedInlineChatWidget
           │      │      └─ ChatWidget
           │      │             └─ ChatInputPart
           │      │
           │      └─ show() / hide()
           │
           ├─ InlineChatSessionService
           │      ├─ createSession()
           │      └─ getSessionByTextModel()
           │
           └─ autorun()
                  ├─ visibleSessionObs管理
                  ├─ widget.chatWidget.setModel()
                  └─ zone.show() / zone.hide()

ChatSubmitAction
    │
    └─ chatService.sendRequest()
           │
           └─ 応答ストリーミング → 差分表示

KeepSessionAction2
    │
    └─ session.accept()
           │
           └─ エディタに変更適用

UndoAndCloseSessionAction2
    │
    └─ session.dispose()
           │
           └─ 変更破棄、ウィジェット非表示
```

### データフロー図

```
[入力]                       [処理]                           [出力]

Ctrl+I / ガタークリック ───▶ InlineChatController       ───▶ ウィジェット表示
                             │
選択範囲              ───▶ ├─ InlineChatZoneWidget
  └─ ISelection              │      └─ ChatWidget
                             │
プロンプト            ───▶ ├─ chatService.sendRequest()
                             │      └─ AI応答ストリーミング
                             │
                       ───▶ └─ 差分プレビュー表示
                                   │
Keep/Discard          ───▶         └─ 変更適用 / 破棄
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| inlineChatController.ts | `src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts` | ソース | メインコントローラー |
| inlineChatWidget.ts | `src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts` | ソース | UIウィジェット |
| inlineChatZoneWidget.ts | `src/vs/workbench/contrib/inlineChat/browser/inlineChatZoneWidget.ts` | ソース | ゾーンウィジェット |
| inlineChatActions.ts | `src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts` | ソース | アクション定義 |
| inlineChat.contribution.ts | `src/vs/workbench/contrib/inlineChat/browser/inlineChat.contribution.ts` | ソース | コントリビューション登録 |
| inlineChatSessionService.ts | `src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionService.ts` | ソース | セッションサービス |
| inlineChatSessionServiceImpl.ts | `src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionServiceImpl.ts` | ソース | セッションサービス実装 |
| inlineChatAffordance.ts | `src/vs/workbench/contrib/inlineChat/browser/inlineChatAffordance.ts` | ソース | ガターインジケーター |
| inlineChat.ts | `src/vs/workbench/contrib/inlineChat/common/inlineChat.ts` | ソース | 共通定義 |
| inlineChat.css | `src/vs/workbench/contrib/inlineChat/browser/media/inlineChat.css` | スタイル | スタイルシート |
