# 画面設計書 47-コマンドパレット

## 概要

本ドキュメントは、VSCodeのコマンドパレット画面の設計を記載したものです。コマンドパレットは、VSCodeの全コマンドを検索・実行できるクイックアクセスインターフェースです。

### 本画面の処理概要

コマンドパレットは、Visual Studio Codeの中核的なUIコンポーネントの一つです。ユーザーはコマンド名の一部を入力することで、利用可能な全コマンドをファジー検索し、キーボードから素早く実行できます。

**業務上の目的・背景**：
VSCodeには数百のコマンドが存在し、全てをメニューやショートカットで覚えることは困難です。コマンドパレットは、コマンド名のあいまい検索を可能にし、マウスに頼らずキーボード中心のワークフローを実現します。また、使用頻度に基づく履歴機能により、よく使うコマンドに素早くアクセスできます。

**画面へのアクセス方法**：
- キーボードショートカット `Ctrl+Shift+P`（Windows/Linux）または `Cmd+Shift+P`（macOS）
- `F1` キー
- メニュー「表示」→「コマンドパレット」
- ステータスバーのコマンドセンターをクリック

**主要な操作・処理内容**：
1. コマンド検索：入力テキストでコマンド一覧をファジーフィルタリング
2. コマンド実行：選択したコマンドを実行
3. キーバインド設定：コマンドのキーバインドを設定画面で編集
4. コマンド履歴：過去に実行したコマンドの優先表示
5. AI関連検索：自然言語でコマンドを検索（実験的機能）
6. チャットへの転送：検索クエリをAIチャットに送信

**画面遷移**：
- ショートカット/メニュー → コマンドパレット（オーバーレイ）
- コマンド実行 → 対象機能の画面
- キーバインド設定ボタン → キーボードショートカット設定画面

**権限による表示制御**：
- 全てのユーザーがアクセス可能
- 一部コマンドはコンテキスト（エディタの状態など）に応じて非表示

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 47 | コマンドパレット | 主機能 | コマンド検索・実行 |

## 画面種別

クイックピック（オーバーレイ）

## URL/ルーティング

プレフィックス: `>` (CommandsQuickAccessProvider.PREFIX)
コマンドID: `workbench.action.showCommands`

## 入出力項目

| 項目名 | 入力/出力 | 型 | 必須 | 説明 |
|--------|----------|-----|------|------|
| 検索クエリ | 入力 | string | No | コマンド名の検索文字列 |
| コマンド一覧 | 出力 | ICommandQuickPick[] | Yes | 表示するコマンドのリスト |
| 選択コマンド | 出力 | string (commandId) | Yes | 実行するコマンドのID |
| キーバインド | 出力 | string | No | コマンドに割り当てられたキーバインド |

## 表示項目

| 項目名 | 表示位置 | 説明 |
|--------|----------|------|
| 検索入力欄 | 上部 | コマンド検索用テキストボックス |
| コマンドアイコン | 行左 | カテゴリに応じたアイコン |
| コマンドラベル | 行中央 | コマンド名（ローカライズ済み） |
| カテゴリ | ラベル前 | コマンドのカテゴリ（例: "View:", "Git:"） |
| キーバインド | 行右 | 割り当てられたショートカット |
| 設定ボタン | 行右端 | キーバインド設定への歯車アイコン |
| セパレータ | 行間 | グループ区切り |
| Ask in Chat | 下部 | AIチャットへの転送オプション |

## イベント仕様

### 1-コマンドパレット起動

`Ctrl+Shift+P` または `F1` を押すと：
1. `ShowAllCommandsAction.run()` が実行される
2. `quickInputService.quickAccess.show()` でクイックアクセスを開く
3. `CommandsQuickAccessProvider.PREFIX` (`>`) がプレフィックスとして設定
4. `getCommandPicks()` でコマンド一覧を取得
5. 拡張機能の登録完了を最大800msまで待機

### 2-コマンド検索

検索テキストを入力すると：
1. 入力テキストでコマンドをフィルタリング
2. `getCodeEditorCommandPicks()` でエディタコマンドを取得
3. `getGlobalCommandPicks()` でグローバルコマンドを取得
4. ファジースコアリングで関連度を計算
5. 履歴を考慮してソート
6. AI関連情報検索（実験的機能）

### 3-コマンド実行

コマンドを選択（Enter）すると：
1. `accept()` コールバックが実行される
2. `commandService.executeCommand()` でコマンドを実行
3. コマンド履歴に追加
4. クイックピックを閉じる

### 4-キーバインド設定

歯車ボタンをクリックすると：
1. `trigger()` コールバックが実行される
2. `preferencesService.openGlobalKeybindingSettings()` を呼び出し
3. 該当コマンドでフィルターされた状態でキーバインド設定を開く
4. `TriggerAction.CLOSE_PICKER` でクイックピックを閉じる

### 5-コマンド履歴クリア

「Clear Command History」コマンドを実行すると：
1. `ClearCommandHistoryAction.run()` が実行される
2. 確認ダイアログを表示
3. `CommandsHistory.clearHistory()` で履歴を削除

### 6-AIチャットへの転送

「Ask in Chat」を選択すると：
1. `CHAT_OPEN_ACTION_ID` または `ASK_QUICK_QUESTION_ACTION_ID` を実行
2. 検索クエリをチャットに転送
3. チャットビューまたはクイックチャットを開く

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| コマンド実行 | Storage (global) | UPDATE | コマンド履歴の更新 |
| 履歴クリア | Storage (global) | DELETE | コマンド履歴の削除 |

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

#### Storage (global)

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | commandPalette.mru.cache | コマンド実行履歴 | CommandsHistory |
| DELETE | commandPalette.mru.cache | 全履歴を削除 | clearHistory |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| commandsQuickAccessPlaceholder | プレースホルダー | "Type the name of a command to run." | クイックアクセス |
| showTriggerActions | タイトル | "Show All Commands" | コマンド名 |
| clearCommandHistory | タイトル | "Clear Command History" | コマンド名 |
| noCommandResults | メッセージ | "No matching commands" | 検索結果0件時 |
| configure keybinding | ツールチップ | "Configure Keybinding" | 歯車ボタン |
| askInChat | オプション | "Ask in Chat: {0}" | チャット転送 |
| configureAskInChatSetting | ツールチップ | "Configure visibility" | 設定ボタン |
| confirmClearMessage | ダイアログ | "Do you want to clear the history of recently used commands?" | 履歴クリア確認 |
| confirmClearDetail | ダイアログ | "This action is irreversible!" | 履歴クリア確認 |
| clearButtonLabel | ボタン | "&&Clear" | 履歴クリア確認 |

## 例外処理

| 例外パターン | 処理内容 | 表示メッセージ |
|-------------|---------|---------------|
| 拡張機能未登録 | 800msタイムアウト後に利用可能なコマンドのみ表示 | なし |
| キャンセル | 空配列を返却 | なし |
| AI検索エラー | 無視してAsk in Chatオプションを追加 | なし |

## 備考

- `CommandsQuickAccessProvider` が `AbstractEditorCommandsQuickAccessProvider` を継承
- `extensionRegistrationRace` で拡張機能登録を800msまで待機
- `useAiRelatedInfo` で実験的なAI関連検索を制御
- `AI_RELATED_INFORMATION_MAX_PICKS` で最大5件のAI提案
- `AI_RELATED_INFORMATION_DEBOUNCE` で200msのデバウンス
- 設定 `workbench.commandPalette.preserveInput` で入力値の保持を制御
- 設定 `workbench.commandPalette.showAskInChat` でチャット転送オプションを制御
- 設定 `workbench.commandPalette.experimental.suggestCommands` で提案コマンドを制御

---

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

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

### 推奨読解順序

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

まず、コマンドパレットで扱う主要なデータ構造を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | commandsQuickAccess.ts | `src/vs/platform/quickinput/browser/commandsQuickAccess.ts` | ICommandQuickPick, CommandsHistory |
| 1-2 | quickAccess.ts | `src/vs/platform/quickinput/common/quickAccess.ts` | IQuickAccessProvider, DefaultQuickAccessFilterValue |

**読解のコツ**: コマンドピックの構造（commandId, label, keybinding）と履歴管理の仕組みを把握してください。

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

処理の起点となるプロバイダークラスを確認します。

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

**主要処理フロー**:
1. **L44-94**: コンストラクタで依存サービスを注入、extensionRegistrationRaceを初期化
2. **L96-104**: configuration getterでユーザー設定を取得
3. **L106-117**: updateOptions()で設定変更を反映
4. **L119-142**: getCommandPicks()でコマンド一覧を取得
5. **L144-155**: hasAdditionalCommandPicks()でAI検索の有無を判定
6. **L157-198**: getAdditionalCommandPicks()でAI関連ピックを取得
7. **L226-268**: getGlobalCommandPicks()でグローバルコマンドを取得

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

コマンドパレットの起動と履歴クリアのアクションを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | commandsQuickAccess.ts | `src/vs/workbench/contrib/quickaccess/browser/commandsQuickAccess.ts` | ShowAllCommandsAction, ClearCommandHistoryAction |

**主要処理フロー**:
- **L273-294**: ShowAllCommandsActionでコマンドパレットを起動
- **L296-329**: ClearCommandHistoryActionで履歴をクリア

#### Step 4: 登録を理解する

クイックアクセスプロバイダーの登録を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | quickAccess.contribution.ts | `src/vs/workbench/contrib/quickaccess/browser/quickAccess.contribution.ts` | プロバイダー登録、メニュー登録 |

**主要処理フロー**:
- **L21-48**: quickAccessRegistryにCommandsQuickAccessProviderを登録
- **L55-108**: MenuRegistryにメニューアイテムを登録
- **L115-118**: アクションを登録

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

```
ShowAllCommandsAction.run()
    │
    └─ quickInputService.quickAccess.show('>')
           │
           └─ CommandsQuickAccessProvider
                  │
                  ├─ getCommandPicks()
                  │      ├─ extensionRegistrationRace [800ms待機]
                  │      ├─ getCodeEditorCommandPicks()
                  │      └─ getGlobalCommandPicks()
                  │             └─ menuService.getMenuActions(MenuId.CommandPalette)
                  │
                  ├─ hasAdditionalCommandPicks()
                  │      └─ aiRelatedInformationService.isEnabled()
                  │
                  ├─ getAdditionalCommandPicks()
                  │      ├─ timeout() [200msデバウンス]
                  │      ├─ getRelatedInformationPicks()
                  │      │      └─ aiRelatedInformationService.getRelatedInformation()
                  │      │
                  │      └─ "Ask in Chat" オプション追加
                  │
                  ├─ accept()
                  │      └─ commandService.executeCommand()
                  │
                  └─ trigger() [歯車ボタン]
                         └─ preferencesService.openGlobalKeybindingSettings()
```

### データフロー図

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

Ctrl+Shift+P           ───▶ ShowAllCommandsAction       ───▶ クイックピック表示
                             │
検索クエリ             ───▶ CommandsQuickAccessProvider ───▶ コマンド一覧
                             │
                             ├─ getCommandPicks()
                             │      ├─ エディタコマンド
                             │      └─ グローバルコマンド
                             │
IMenuService           ───▶ ├─ メニューアクション取得
  └─ CommandPalette          │      └─ MenuItemAction[]
                             │
CommandsHistory        ───▶ ├─ 履歴ベースのソート
                             │
IAiRelatedInfoService  ───▶ └─ AI関連ピック
  └─ getRelatedInfo          └─ Ask in Chatオプション
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| commandsQuickAccess.ts | `src/vs/workbench/contrib/quickaccess/browser/commandsQuickAccess.ts` | ソース | メインプロバイダー |
| quickAccess.contribution.ts | `src/vs/workbench/contrib/quickaccess/browser/quickAccess.contribution.ts` | ソース | プロバイダー登録 |
| commandsQuickAccess.ts | `src/vs/platform/quickinput/browser/commandsQuickAccess.ts` | ソース | 基底クラス、CommandsHistory |
| commandsQuickAccess.ts | `src/vs/editor/contrib/quickAccess/browser/commandsQuickAccess.ts` | ソース | エディタコマンド取得 |
| quickaccess.ts | `src/vs/workbench/browser/quickaccess.ts` | ソース | ワークベンチ設定 |
| quickAccess.ts | `src/vs/platform/quickinput/common/quickAccess.ts` | ソース | プラットフォームインターフェース |
