# 画面設計書 52-プロセスエクスプローラー

## 概要

本ドキュメントは、VSCodeのプロセスエクスプローラー画面の設計仕様を記載する。この画面は、VSCodeおよび関連プロセスのリソース使用状況（CPU、メモリ、PID）をリアルタイムで監視するための開発者向けツールである。

### 本画面の処理概要

プロセスエクスプローラー画面は、VSCodeプロセスとその子プロセス（拡張機能ホスト、レンダラー、リモートサーバーなど）のリソース使用状況をツリー形式で表示する画面である。プロセスの強制終了やデバッグアタッチなどの操作も可能である。

**業務上の目的・背景**：VSCodeは拡張機能や複数のサブプロセスで構成される複雑なアプリケーションである。パフォーマンス問題（高CPU使用率、メモリリークなど）が発生した際に、どのプロセスが原因かを特定する必要がある。プロセスエクスプローラーは、開発者がVSCodeの内部プロセス構造を理解し、問題のあるプロセスを特定・対処するための診断ツールとして機能する。

**画面へのアクセス方法**：以下の方法でアクセス可能である。
- メニューバー: ヘルプ → Open Process Explorer
- コマンドパレット: `workbench.action.openProcessExplorer` コマンドを実行
- コマンドパレットで「Open Process Explorer」を検索

**主要な操作・処理内容**：
1. プロセスツリーの表示（階層構造でプロセス親子関係を表示）
2. CPU使用率、メモリ使用量、PIDの表示
3. プロセスの強制終了（SIGTERM/SIGKILL）
4. Node.jsプロセスへのデバッガアタッチ
5. プロセス情報のクリップボードへのコピー
6. 1秒間隔での自動更新

**画面遷移**：
- 遷移元: ワークベンチ全般（コマンドパレット、ヘルプメニュー）
- 遷移先: なし（独立したAuxiliaryウィンドウとして表示）
- 連携: デバッグ機能（debug.startFromConfigコマンド経由）

**権限による表示制御**：
- デスクトップ版: フル機能が利用可能
- Web版（リモートなし）: 利用不可（preconditionでブロック）
- Web版（リモートあり）: リモートサーバーのプロセス情報のみ表示

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 58 | プロセス | 主機能 | VSCodeプロセスのリソース使用状況表示 |
| 24 | デバッグ | 補助機能 | プロセスへのデバッガアタッチ |

## 画面種別

一覧 / 診断ツール

## URL/ルーティング

- URI Scheme: `process-explorer:`
- リソース: `process-explorer:/default`
- ウィンドウ種別: Auxiliaryウィンドウ（独立した小ウィンドウ）

## 入出力項目

| 項目名 | 型 | 入力/出力 | 説明 |
|--------|-----|----------|------|
| processes | IMachineProcessInformation[] | 入力 | プロセスツリー情報 |
| pidToNames | [number, string][] | 入力 | PIDと表示名のマッピング |

## 表示項目

| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| Process Name | テキスト | プロセス名（VSCode、remote-server、拡張機能名など） |
| CPU (%) | 数値 | CPU使用率（パーセント） |
| Memory (MB) | 数値 | メモリ使用量（メガバイト） |
| PID | 数値 | プロセスID |

### ヘッダー行
| カラム | ラベル |
|--------|--------|
| name | Process Name |
| cpu | CPU (%) |
| memory | Memory (MB) |
| pid | PID |

## イベント仕様

### 1-画面表示

OpenProcessExplorerアクションの`run`メソッドが呼び出され、以下の処理が実行される。

1. IEditorService.openEditorでProcessExplorerEditorInputを開く
2. AUX_WINDOW_GROUP指定により独立したAuxiliaryウィンドウとして表示
3. 前回のウィンドウ位置・サイズを復元（StorageServiceから取得）
4. BrowserProcessExplorerControlが生成され、プロセスツリーを構築
5. 1秒間隔でプロセス情報を自動更新

### 2-プロセスツリー更新

ProcessExplorerControlの`update`メソッドで以下の処理が実行される。

1. resolveProcesses()でプロセス情報を取得
2. ProcessExplorerModelを更新
3. WorkbenchDataTreeのupdateChildren()を呼び出し
4. Delayerで1秒後に再度update()をスケジュール

### 3-コンテキストメニュー操作

プロセス項目を右クリックすると以下のメニューが表示される。

| メニュー項目 | アクション | 条件 |
|------------|----------|------|
| Kill Process | SIGTERM送信 | デスクトップ版のみ |
| Force Kill Process | SIGKILL送信 | デスクトップ版のみ |
| Copy | 選択プロセスの情報をコピー | 常時 |
| Copy All | 全プロセス情報をコピー | 常時 |
| Debug | デバッガアタッチ | Node.jsプロセス時のみ |

### 4-キーボード操作

| キー | アクション | 説明 |
|-----|----------|------|
| Alt+E | Kill Process | 選択プロセスにSIGTERM送信 |

### 5-デバッガアタッチ

isDebuggable()がtrueのプロセスに対して、以下の処理が実行される。

1. コマンドライン引数から--inspectポートを抽出
2. debug.startFromConfigコマンドでデバッグセッション開始
3. ポートが見つからない場合はPIDでアタッチ試行

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

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

本画面はデータベースを使用しない。ただし、以下のストレージ操作が行われる。

| 操作（イベント） | 対象ストレージ | 操作種別 | 概要 |
|----------------|---------------|---------|------|
| ウィンドウ閉じる | StorageService | UPDATE | ウィンドウ位置・サイズの保存 |
| 画面表示 | StorageService | SELECT | ウィンドウ位置・サイズの復元 |

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

#### StorageService (workbench.processExplorerWindowState)

| 操作 | 項目（キー名） | 更新値・取得条件 | 備考 |
|-----|---------------|-----------------|------|
| UPDATE | bounds.width | ウィンドウ幅 | ピクセル値 |
| UPDATE | bounds.height | ウィンドウ高さ | ピクセル値 |
| UPDATE | bounds.x | ウィンドウX座標 | 画面上の位置 |
| UPDATE | bounds.y | ウィンドウY座標 | 画面上の位置 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|----------|
| processExplorer | アクセシビリティ | "Process Explorer" | スクリーンリーダー用ラベル |
| processName | ヘッダー | "Process Name" | テーブルヘッダー |
| processCpu | ヘッダー | "CPU (%)" | テーブルヘッダー |
| processPid | ヘッダー | "PID" | テーブルヘッダー |
| processMemory | ヘッダー | "Memory (MB)" | テーブルヘッダー |
| killProcess | メニュー | "Kill Process" | コンテキストメニュー |
| forceKillProcess | メニュー | "Force Kill Process" | コンテキストメニュー |
| copy | メニュー | "Copy" | コンテキストメニュー |
| copyAll | メニュー | "Copy All" | コンテキストメニュー |
| debug | メニュー | "Debug" | コンテキストメニュー |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| リモート接続なし（Web版） | 空のプロセスリストを返す |
| リモート診断エラー | IRemoteDiagnosticErrorとしてツリーに表示 |
| プロセス終了失敗 | 特別な処理なし（Promiseでハンドリング） |

## 備考

- 本画面は`EditorPane`を継承しており、エディタとして表示される
- デフォルトウィンドウサイズ: 800x500ピクセル
- Auxiliaryウィンドウオプション: compact=true, alwaysOnTop=true
- Singletonパターンで実装（同時に1つのインスタンスのみ）
- Web版ではプロセス終了機能（Kill Process）は利用不可
- デバッグ可能条件: --inspectフラグがある、または `node ` を含むコマンドライン

---

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

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

### 推奨読解順序

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

まず、プロセス情報のデータ構造とモデルを理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | processExplorerControl.ts | `src/vs/workbench/contrib/processExplorer/browser/processExplorerControl.ts` | IProcessTree, IProcessInformation, IMachineProcessInformation, ProcessItemインターフェースの構造を確認（42-71行目） |
| 1-2 | processes.ts | `src/vs/base/common/processes.ts` | ProcessItem基本型の定義を確認 |

**読解のコツ**: TypeScriptのtype guard関数（isMachineProcessInformation, isProcessItem等）に注目すると、各データ型の判別条件が明確になる。

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

処理の起点となるcontributionファイルとアクションを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | processExplorer.contribution.ts | `src/vs/workbench/contrib/processExplorer/browser/processExplorer.contribution.ts` | OpenProcessExplorerアクション、エディタ登録、シリアライザを確認 |
| 2-2 | processExplorerEditorInput.ts | `src/vs/workbench/contrib/processExplorer/browser/processExplorerEditorInput.ts` | Singletonパターン実装、URI定義を確認 |

**主要処理フロー**:
1. **89-104行目**: OpenProcessExplorerアクション定義（preconditionでWeb環境制御）
2. **106-131行目**: run()メソッドでAuxiliaryウィンドウとしてエディタを開く
3. **133-158行目**: ウィンドウ状態の保存・復元ロジック

#### Step 3: エディタペインを理解する

エディタとしての画面実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | processExplorerEditor.ts | `src/vs/workbench/contrib/processExplorer/browser/processExplorerEditor.ts` | EditorPaneを継承したProcessExplorerEditor |

**主要処理フロー**:
- **31-33行目**: createEditor()でBrowserProcessExplorerControlを生成
- **35-37行目**: focus()でツリーにフォーカス
- **39-41行目**: layout()でサイズ調整

#### Step 4: プロセスツリーUIを理解する

ツリービューの詳細実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | processExplorerControl.ts | `src/vs/workbench/contrib/processExplorer/browser/processExplorerControl.ts` | ProcessExplorerControl抽象クラスとBrowserProcessExplorerControl実装 |

**主要処理フロー**:
- **330-349行目**: ProcessExplorerControlコンストラクタ
- **354-358行目**: create()でツリー生成とupdate開始
- **360-390行目**: createProcessTree()でWorkbenchDataTree構築
- **503-512行目**: update()で定期更新処理
- **460-468行目**: isDebuggable()でデバッグ可能判定
- **470-491行目**: attachTo()でデバッガアタッチ処理

#### Step 5: レンダラーを理解する

ツリーの各行レンダリング処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | processExplorerControl.ts | `src/vs/workbench/contrib/processExplorer/browser/processExplorerControl.ts` | ProcessHeaderTreeRenderer, MachineRenderer, ProcessRenderer, ErrorRendererの実装（168-284行目） |

**主要処理フロー**:
- **246-284行目**: ProcessRendererでプロセス行のレンダリング
- **267-279行目**: renderElement()でCPU、メモリ、PID表示

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

```
OpenProcessExplorer.run()
    │
    ├─ IEditorService.openEditor()
    │      ├─ ProcessExplorerEditorInput.instance (Singleton)
    │      └─ AUX_WINDOW_GROUP指定
    │
    └─ ProcessExplorerEditor.createEditor()
           │
           └─ BrowserProcessExplorerControl.create()
                  │
                  ├─ createProcessTree()
                  │      ├─ WorkbenchDataTree構築
                  │      ├─ ProcessRenderer
                  │      ├─ ProcessHeaderTreeRenderer
                  │      ├─ MachineRenderer
                  │      └─ ErrorRenderer
                  │
                  └─ update() [定期実行]
                         │
                         ├─ resolveProcesses()
                         │      └─ IRemoteAgentService.getDiagnosticInfo()
                         │
                         ├─ ProcessExplorerModel.update()
                         │
                         └─ Delayer.trigger() [1秒後に再帰]
```

### データフロー図

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

IRemoteAgentService ───▶ resolveProcesses() ───▶ IMachineProcessInformation[]
       │                        │
       │                        ▼
       │               ProcessExplorerModel.update() ───▶ IProcessTree
       │                        │
       │                        ▼
       │               WorkbenchDataTree.updateChildren() ───▶ ツリービュー
       │                        │
       │                        ▼
       │               ProcessRenderer.renderElement() ───▶ 各行表示
       │
       └── 1秒間隔 ──▶ Delayer ───▶ update() [ループ]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| processExplorer.contribution.ts | `src/vs/workbench/contrib/processExplorer/browser/processExplorer.contribution.ts` | ソース | アクション登録、エディタ登録、メニュー登録 |
| processExplorerEditor.ts | `src/vs/workbench/contrib/processExplorer/browser/processExplorerEditor.ts` | ソース | エディタペイン実装 |
| processExplorerControl.ts | `src/vs/workbench/contrib/processExplorer/browser/processExplorerControl.ts` | ソース | ツリービューとモデル実装 |
| processExplorerEditorInput.ts | `src/vs/workbench/contrib/processExplorer/browser/processExplorerEditorInput.ts` | ソース | エディタ入力（Singleton） |
| processExplorer.web.contribution.ts | `src/vs/workbench/contrib/processExplorer/browser/processExplorer.web.contribution.ts` | ソース | Web版固有の登録 |
| processExplorer.contribution.ts | `src/vs/workbench/contrib/processExplorer/electron-browser/processExplorer.contribution.ts` | ソース | デスクトップ版固有の登録 |
| processExplorerEditor.ts | `src/vs/workbench/contrib/processExplorer/electron-browser/processExplorerEditor.ts` | ソース | デスクトップ版エディタペイン |
| processExplorerControl.ts | `src/vs/workbench/contrib/processExplorer/electron-browser/processExplorerControl.ts` | ソース | デスクトップ版コントロール（killProcess対応） |
| processExplorer.css | `src/vs/workbench/contrib/processExplorer/browser/media/processExplorer.css` | スタイル | 画面スタイル定義 |
| processes.ts | `src/vs/base/common/processes.ts` | ソース | ProcessItem基本型定義 |
