# 機能設計書 78-ConPTY接続

## 概要

本ドキュメントは、Windows TerminalにおけるConPTY（Pseudo Console）接続機能の設計を記述する。ConPTYを使用してシェルプロセス（cmd.exe, PowerShell, WSL等）との双方向通信を管理する接続レイヤーである。

### 本機能の処理概要

ConptyConnectionは、Windows Pseudo Console API（ConPTY API）をラップし、ターミナルコントロールとシェルプロセス間の入出力パイプを管理する接続クラスである。プロセスの起動、入力の書き込み、出力の読み取り、リサイズ、クローズなどのライフサイクル全体を管理する。

**業務上の目的・背景**：Windows TerminalがCUI（Character User Interface）プロセスと通信するための基盤機能である。ConPTY APIにより、従来のコンソールウィンドウを使用せずに、VTシーケンスベースのI/Oでシェルプロセスを制御できる。これにより、モダンなターミナルUI上で従来のWindowsコンソールアプリケーションを動作させることが可能になる。

**機能の利用シーン**：新しいタブやペインの作成時にシェルプロセスを起動する場合、ターミナルへの入力をシェルに転送する場合、シェルの出力をターミナルに表示する場合、ウィンドウリサイズ時にPTYのサイズを変更する場合に使用される。

**主要な処理内容**：
1. ConptyCreatePseudoConsole によるPseudo Console作成
2. CreateProcessW によるシェルプロセスの起動
3. 出力スレッドによるPTY出力の読み取りとTerminalOutputイベント発行
4. WriteInput によるユーザー入力のPTYへの書き込み
5. Resize によるPTYサイズの変更
6. Close によるPseudo Consoleとプロセスの終了

**関連システム・外部連携**：Windows ConPTY API（conpty-static.h）、シェルプロセス（cmd.exe, PowerShell, WSL等）、環境変数管理（til::env）。

**権限による制御**：プロセス起動には適切な実行権限が必要。昇格実行が必要なプロセスの場合はERROR_ELEVATION_REQUIREDエラーが発生する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | TermControl（ターミナル表示） | 主画面 | ConPTYを使用したシェルプロセスとの接続管理 |

## 機能種別

プロセス管理 / 接続管理 / I/O制御

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| commandline | hstring | Yes | 実行するコマンドライン | 空文字でないこと |
| startingDirectory | hstring | No | 起動ディレクトリ | 有効なディレクトリパスであること |
| startingTitle | hstring | No | 初期ウィンドウタイトル | - |
| initialRows | uint32_t | Yes | 初期行数 | 正の整数 |
| initialCols | uint32_t | Yes | 初期列数 | 正の整数 |
| reloadEnvironmentVariables | bool | No | 環境変数を再読み込みするかどうか | - |
| initialEnvironment | hstring | No | 初期環境変数ブロック | - |
| environmentOverrides | IMapView<hstring, hstring> | No | 環境変数のオーバーライド | - |
| guid | guid | Yes | セッションGUID | 有効なGUID |
| profileGuid | guid | Yes | プロファイルGUID | 有効なGUID |
| inheritCursor | bool | No | カーソル位置を引き継ぐかどうか | - |
| textMeasurement | hstring | No | テキスト測定方式（graphemes/wcswidth/console） | 列挙値の範囲内 |

### 入力データソース

プロファイル設定（settings.json）、TerminalSettingsからの接続パラメータ。Default Terminal ハンドオフからの接続パラメータ。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| TerminalOutput | イベント | PTYから読み取った出力データ（VTシーケンスを含む） |
| ConnectionState | ConnectionState | 接続状態（Connecting/Connected/Closing/Closed/Failed） |
| Commandline | hstring | 実行中のコマンドライン |
| StartingTitle | hstring | 初期タイトル |

### 出力先

TerminalOutputイベント経由でTerminalControlへ

## 処理フロー

### 処理シーケンス

```
1. ConptyConnection コンストラクタ
   └─ _writeOverlappedEvent 初期化
2. Initialize(ValueSet settings)
   └─ パラメータの読み取りと環境変数の設定
3. Start()
   ├─ ConnectionState → Connecting
   ├─ パイプ作成（Utils::CreateOverlappedPipe）
   ├─ ConptyCreatePseudoConsole() によるPTY作成
   ├─ _LaunchAttachedClient() によるプロセス起動
   ├─ 出力スレッドの作成
   └─ ConnectionState → Connected
4. WriteInput(buffer)
   └─ WinHttpWriteData的なPTYへの書き込み
5. Resize(rows, columns)
   └─ ConptyResizePseudoConsole() によるサイズ変更
6. _OutputThread()
   └─ パイプからの読み取りとTerminalOutput.raise()
7. Close()
   └─ Pseudo Console のクローズとリソース解放
```

### フローチャート

```mermaid
flowchart TD
    A[ConptyConnection作成] --> B[Initialize]
    B --> C[Start]
    C --> D[パイプ作成]
    D --> E[ConptyCreatePseudoConsole]
    E --> F{既存ハンドオフ?}
    F -->|No| G[_LaunchAttachedClient]
    F -->|Yes| H[ConptyResizePseudoConsole]
    G --> I[出力スレッド作成]
    H --> I
    I --> J[Connected状態]
    J --> K{イベント待ち}
    K -->|WriteInput| L[PTYへ書き込み]
    K -->|Resize| M[ConptyResizePseudoConsole]
    K -->|Output| N[TerminalOutput発行]
    K -->|Close| O[Pseudo Console クローズ]
    L --> K
    M --> K
    N --> K
    O --> P[リソース解放]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-78-01 | 環境変数設定 | WT_SESSIONとWT_PROFILE_IDを環境変数に設定 | プロセス起動時 |
| BR-78-02 | WSLENV連携 | WSL環境変数転送リスト（WSLENV）にWT変数を追加 | WSLプロセス起動時 |
| BR-78-03 | カーソル継承 | inheritCursorフラグでPSEUDOCONSOLE_INHERIT_CURSORを設定 | 接続再起動時 |
| BR-78-04 | テキスト測定 | textMeasurementに応じたPseudo Consoleフラグを設定 | graphemes/wcswidth/consoleの指定時 |
| BR-78-05 | ハンドオフ | Default Terminal機能による外部プロセスからのPTYハンドオフ | InitializeFromHandoff使用時 |
| BR-78-06 | 終了ステータス表示 | プロセス終了時にステータスコードを表示 | _indicateExitWithStatus |

### 計算ロジック

特になし。

## データベース操作仕様

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

本機能にデータベース操作はない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ERROR_DIRECTORY | パスエラー | 起動ディレクトリが無効 | BadPathTextメッセージを表示 |
| ERROR_ELEVATION_REQUIRED | 権限エラー | 昇格実行が必要 | ElevationRequiredメッセージを表示 |
| ERROR_FILE_NOT_FOUND | ファイルエラー | 実行ファイルが見つからない | FileNotFoundメッセージを表示 |
| - | プロセス起動失敗 | CreateProcessW失敗 | ProcessFailedToLaunchメッセージとステータスコードを表示 |

### リトライ仕様

接続再起動機能（No.80）により、失敗した接続を再試行可能。

## トランザクション仕様

本機能にトランザクション処理はない。接続の終了は段階的に行われ、パイプクローズ→プロセス終了→リソース解放の順序で実行される。

## パフォーマンス要件

出力スレッドは専用スレッドで実行され、PTYからの出力を即座にTerminalOutputイベントとして発行する。書き込みはオーバーラップI/O（_writeOverlapped）で非同期実行される。

## セキュリティ考慮事項

- プロセス起動にはPROC_THREAD_ATTRIBUTE_PSEUDOCONSOLEを使用し、PTYとプロセスを安全に関連付ける
- 環境変数にはセッションGUIDとプロファイルGUIDが設定される
- Default Terminal ハンドオフ時はDuplicateHandleで安全にハンドルを複製する

## 備考

- ConPTYはWindows 10 Version 1809以降で利用可能
- パイプサイズは128KBに設定されている
- 出力スレッドの終了はConPTYのクローズまたはプロセス終了時に自動的に行われる
- テレメトリ: ConPtyConnected/ConPtyConnectedToDefterm イベントが送信される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ConptyConnection.h | `src/cascadia/TerminalConnection/ConptyConnection.h` | クラス定義（15-106行目）: _rows/_cols, _commandline, _pipe, _hPC, _piClient, _writeLock等のメンバー |
| 1-2 | ConptyConnection.idl | `src/cascadia/TerminalConnection/ConptyConnection.idl` | WinRTインターフェース定義 |
| 1-3 | BaseTerminalConnection.h | `src/cascadia/TerminalConnection/BaseTerminalConnection.h` | 基底クラス: ConnectionState管理、_transitionToState |

**読解のコツ**: ConptyConnectionはBaseTerminalConnectionを継承し、CRTP（Curiously Recurring Template Pattern）を使用している。_hPCはHPCON型でPseudo Consoleハンドルを管理し、closePseudoConsoleAsyncでカスタムデリータが設定されている。

#### Step 2: 初期化とプロセス起動を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ConptyConnection.cpp | `src/cascadia/TerminalConnection/ConptyConnection.cpp` | CreateSettings（206-243行目）、Initialize（245-319行目）、Start（395-499行目）、_LaunchAttachedClient（32-193行目） |

**主要処理フロー**:
1. **206-243行目**: CreateSettings - ValueSet作成ヘルパー
2. **245-319行目**: Initialize - パラメータ読み取り、環境変数設定、フラグ設定
3. **395-444行目**: Start - パイプ作成、PTY作成、プロセス起動
4. **32-193行目**: _LaunchAttachedClient - STARTUPINFOEX設定、環境変数構築、CreateProcessW

#### Step 3: I/O処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ConptyConnection.cpp | `src/cascadia/TerminalConnection/ConptyConnection.cpp` | _OutputThread、WriteInput、Resize、Close |

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

```
ConptyConnection::Initialize (settings ValueSet)
    │
    ├─ パラメータ解析 (_commandline, _startingDirectory, _rows, _cols, ...)
    ├─ 環境変数構築 (til::env)
    └─ フラグ設定 (PSEUDOCONSOLE_INHERIT_CURSOR, GLYPH_WIDTH_*)

ConptyConnection::Start
    │
    ├─ Utils::CreateOverlappedPipe() [パイプ作成]
    │
    ├─ ConptyCreatePseudoConsole() [PTY作成]
    │
    ├─ _LaunchAttachedClient()
    │      │
    │      ├─ InitializeProcThreadAttributeList()
    │      ├─ UpdateProcThreadAttribute(PSEUDOCONSOLE)
    │      ├─ 環境変数構築 (WT_SESSION, WT_PROFILE_ID, WSLENV)
    │      └─ CreateProcessW()
    │
    ├─ ConptyReleasePseudoConsole() [PTYリリース]
    │
    └─ _hOutputThread [出力スレッド作成]
           │
           └─ _OutputThread()
                  └─ ReadFile → TerminalOutput.raise()
```

### データフロー図

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

ユーザー入力 ───────────▶ WriteInput ─────────▶ PTY パイプ
(VTシーケンス)                                       │
                                                     ▼
                                              シェルプロセス
                                              (cmd/PowerShell/WSL)
                                                     │
                                                     ▼
                                              PTY パイプ ──▶ _OutputThread
                                                                │
                                                                ▼
                                                         TerminalOutput
                                                         イベント
                                                                │
                                                                ▼
                                                         TermControl
                                                         (画面描画)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ConptyConnection.h | `src/cascadia/TerminalConnection/ConptyConnection.h` | ヘッダー | ConptyConnectionクラス定義 |
| ConptyConnection.cpp | `src/cascadia/TerminalConnection/ConptyConnection.cpp` | ソース | ConptyConnection実装 |
| ConptyConnection.idl | `src/cascadia/TerminalConnection/ConptyConnection.idl` | IDL | WinRTインターフェース定義 |
| BaseTerminalConnection.h | `src/cascadia/TerminalConnection/BaseTerminalConnection.h` | ヘッダー | 基底接続クラス |
| CTerminalHandoff.h | `src/cascadia/TerminalConnection/CTerminalHandoff.h` | ヘッダー | Default Terminal ハンドオフ |
| ITerminalHandoff.h | `src/cascadia/TerminalConnection/ITerminalHandoff.h` | ヘッダー | ハンドオフインターフェース |
| TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | ソース | 接続作成（_CreateConnectionFromSettings） |
| Profile.cpp | `src/cascadia/TerminalSettingsModel/Profile.cpp` | ソース | プロファイル設定からのConPTY設定取得 |
