# 機能設計書 124-ColorTool

## 概要

本ドキュメントは、Windows Terminalプロジェクトに含まれるColorToolの設計を記述する。ColorToolは、コンソールのカラースキームを変更するためのコマンドラインツールであり、複数のスキーム形式の読み込みと複数の適用先への出力をサポートする。

### 本機能の処理概要

ColorToolは、.ini、.itermcolors（XML）、.json形式のカラースキームファイルを読み込み、Windowsコンソールの16色カラーテーブルおよび前景色・背景色・カーソル色を変更するスタンドアロンのコマンドラインツールである。現在のコンソール、レジストリ（システムデフォルト）、VTシーケンス経由、Windows Terminal設定JSONの4つの適用先をサポートする。

**業務上の目的・背景**：Windowsコンソールのカラースキームを簡単に変更・カスタマイズしたいという開発者のニーズに応えるツールである。従来、コンソールの色設定はレジストリの直接編集やコンソールプロパティダイアログでの手動変更が必要だったが、ColorToolにより、既存のカラースキームファイルを指定するだけでコマンド一つで変更できるようになった。iTerm2のカラースキームファイルとの互換性により、macOS/Linux向けに作成されたスキームも利用可能である。

**機能の利用シーン**：
- 開発者がコンソールの配色を変更したい場合
- チーム内でカラースキームを統一したい場合（スキームファイルの共有）
- iTerm2等の他のターミナルエミュレータで使用していたカラースキームをWindowsコンソールに適用したい場合
- Windows Terminalのsettings.jsonに新しいスキームを追加したい場合

**主要な処理内容**：
1. コマンドライン引数の解析（スキーム名、動作モードの決定）
2. スキームファイルの検索と読み込み（.ini / .itermcolors / .json形式に対応）
3. カラースキームの適用（現在のコンソール / レジストリデフォルト / VTシーケンス / Windows Terminal JSON形式）
4. 現在のカラーテーブルの表示（-c / --currentオプション）
5. 利用可能なスキーム一覧の表示（-s / --schemesオプション）
6. 現在のスキームのエクスポート（-o / --outputオプション）
7. Windows Terminal向けJSONスキーマの出力（-t / --terminalオプション）

**関連システム・外部連携**：
- Windows Console API（kernel32.dll: GetConsoleScreenBufferInfoEx / SetConsoleScreenBufferInfoEx）
- Windowsレジストリ（HKCU\Console）
- VTシーケンス出力（OSCシーケンスによる色設定）

**権限による制御**：レジストリへの書き込み（-d / --defaultsオプション）にはHKCU\Consoleへの書き込み権限が必要。現在のコンソールへの適用は通常権限で可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| なし | （コマンドラインツール） | 主画面 | コマンドプロンプトまたはPowerShell上で実行される |

## 機能種別

コマンドラインツール / カラースキーム管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| schemeName | string | Yes（一部オプション除く） | 適用するカラースキームのファイル名またはパス | ファイル検索で見つからない場合はエラーメッセージ表示 |
| -c / --current | flag | No | 現在のコンソールカラーテーブルを表示する | - |
| -d / --defaults | flag | No | レジストリのデフォルト値にスキームを適用する | - |
| -b / --both | flag | No | 現在のコンソールとレジストリの両方に適用する | - |
| -x / --xterm | flag | No | VTシーケンス経由でスキームを適用する | - |
| -t / --terminal | flag | No | Windows Terminal向けJSON形式で出力する | - |
| -q / --quiet | flag | No | カラーテーブルのプレビュー表示を抑制する | - |
| -e / --errors | flag | No | スキームパース時のエラーを表示する | - |
| -s / --schemes | flag | No | 利用可能なスキーム一覧を表示する | - |
| -l / --location | flag | No | スキームファイルディレクトリのパスを表示する | - |
| -o / --output | string | No | 現在のスキームを指定ファイル名でINI形式にエクスポートする | - |
| -a / --allcolors | flag | No | カラーテーブルを全色表示モードにする | - |
| -v / --version | flag | No | バージョン情報を表示する | - |

### 入力データソース

- コマンドライン引数
- カラースキームファイル（.ini / .itermcolors / .json）
  - 検索順序：カレントディレクトリ → ./schemes/ → 実行ファイルのschemes/ → 絶対パス
- 現在のコンソールスクリーンバッファ情報（GetConsoleScreenBufferInfoEx）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| カラーテーブル変更 | Console API | 現在のコンソールの16色カラーテーブル・属性を変更 |
| レジストリ変更 | Registry | HKCU\ConsoleのColorTable00-15、CursorColor、ScreenColors、DefaultForeground/Background |
| VTシーケンス出力 | stdout | OSC 4/10/11/12シーケンスによる色設定 |
| Windows Terminal JSON | stdout | settings.jsonのschemesに追加可能なJSON出力 |
| カラーテーブルプレビュー | stdout | 前景色×背景色のマトリクス表示 |

### 出力先

- 現在のコンソールウィンドウ（Console API経由）
- Windowsレジストリ（HKCU\Console）
- 標準出力（VTシーケンス / JSON / カラーテーブル表示）

## 処理フロー

### 処理シーケンス

```
1. コマンドライン引数の解析
   └─ フラグの設定（quietMode, setDefaults, setProperties, setUnixStyle等）
2. 特殊オプションの処理
   └─ --current: カラーテーブル表示して終了
   └─ --schemes: スキーム一覧表示して終了
   └─ --location: スキームディレクトリ表示して終了
   └─ --output: 現在のスキームをINIエクスポートして終了
   └─ --version: バージョン表示して終了
3. スキーム名の取得（最後の引数）
4. SchemeManager.GetSchemeでスキーム検索・パース
   └─ 全パーサー（IniSchemeParser, XmlSchemeParser, JsonParser）で順番に試行
   └─ 検索パス順にファイルを探索
5. ConsoleTargetの決定と適用
   └─ --defaults: DefaultConsoleTarget（レジストリ書き込み）
   └─ --xterm: VirtualTerminalConsoleTarget（VTシーケンス出力）
   └─ --terminal: TerminalSchemeConsoleTarget（JSON出力）
   └─ デフォルト: CurrentConsoleTarget（Console API）
```

### フローチャート

```mermaid
flowchart TD
    A[ColorTool起動] --> B[コマンドライン引数解析]
    B --> C{特殊オプション?}
    C -->|--current| D[カラーテーブル表示]
    C -->|--schemes| E[スキーム一覧表示]
    C -->|--output| F[INIエクスポート]
    C -->|--version| G[バージョン表示]
    C -->|なし| H[スキーム名取得]
    H --> I[SchemeManager.GetScheme]
    I --> J{スキーム見つかった?}
    J -->|No| K[エラーメッセージ表示]
    J -->|Yes| L{適用先の決定}
    L -->|--defaults| M[DefaultConsoleTarget: レジストリ]
    L -->|--xterm| N[VirtualTerminalConsoleTarget: VT]
    L -->|--terminal| O[TerminalSchemeConsoleTarget: JSON]
    L -->|デフォルト| P[CurrentConsoleTarget: Console API]
    M --> Q[ApplyColorScheme実行]
    N --> Q
    O --> Q
    P --> Q
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-124-01 | スキーム検索順序 | カレントディレクトリ → ./schemes/ → 実行ファイルのschemes/ → 絶対パスの順で検索 | GetSearchPaths実行時 |
| BR-124-02 | パーサー自動選択 | 全てのISchemeParser実装を順番に試行し、最初にnull以外を返したものを使用 | GetScheme実行時 |
| BR-124-03 | 拡張子付き検索 | スキーム名に加えて「スキーム名+拡張子」でも検索する | GetSearchPaths実行時 |
| BR-124-04 | 色インデックス計算 | 前景色・背景色は16色カラーテーブル内の最も近い色のインデックスを使用 | ScreenColorAttributes/PopupColorAttributes計算時 |
| BR-124-05 | 加重RGB距離 | 色の近似計算にはWeightedRGBSimilarityヒューリスティックを使用 | CalculateIndex実行時 |
| BR-124-06 | COLORREF形式 | 色値はWin32 COLORREF形式（BGR順、uint）で管理される | 全体 |
| BR-124-07 | VTモード切替 | VTシーケンス出力時は一時的にENABLE_VIRTUAL_TERMINAL_PROCESSINGを有効にし、処理後に元に戻す | DoInVTMode実行時 |
| BR-124-08 | VTインデックス変換 | Console APIの色インデックスとVTの色インデックスは並び順が異なるため、VirtualTerminalIndicesで変換する | VirtualTerminalConsoleTarget実行時 |

### 計算ロジック

**加重RGB色距離（WeightedRGBSimilarity）**：
```
rbar = (r1 + r2) / 2.0
distance = sqrt(dr^2 * (2 + rbar/256) + dg^2 * 4 + db^2 * (2 + (255-rbar)/256))
```
ここで dr, dg, db は各チャネルの差分。人間の色知覚に近い重み付けを行う。

**色インデックス計算（CalculateIndex）**：
- 16色カラーテーブル全体に対してWeightedRGBSimilarityを計算し、最も距離の小さいインデックスを返す

**画面属性計算（ScreenColorAttributes）**：
- attributes = foregroundIndex | (backgroundIndex << 4)

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

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

データベース操作は存在しない。ただし、Windowsレジストリへの書き込みを行う。

### テーブル別操作詳細

#### Windowsレジストリ（HKCU\Console）

| 操作 | 項目（キー名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | ColorTable00-15 | カラースキームの16色（DWORD） | --defaults指定時 |
| UPDATE | CursorColor | カーソル色（DWORD、-1でデフォルト） | --defaults指定時 |
| UPDATE | ScreenColors | 前景色・背景色のインデックス組み合わせ（DWORD） | --defaults指定時 |
| UPDATE | DefaultForeground | 前景色のRGB値（DWORD、-1でデフォルト） | カラーテーブルと一致しない場合のみ |
| UPDATE | DefaultBackground | 背景色のRGB値（DWORD、-1でデフォルト） | カラーテーブルと一致しない場合のみ |
| UPDATE | PopupColors | ポップアップの色属性（DWORD） | --defaults指定時 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| なし | スキーム未発見 | 指定スキーム名に一致するファイルが見つからない | "Could not find {schemeName}" メッセージ表示 |
| InvalidOperationException | コンソール情報取得失敗 | GetConsoleScreenBufferInfoExが失敗した場合 | 例外をスロー |
| なし | 引数不足 | 引数なしで実行した場合 | Usage表示 |
| なし | --output引数不足 | -oオプション後にファイル名が指定されていない | OutputUsage表示 |

### リトライ仕様

リトライが必要な処理は存在しない。

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

レジストリ書き込みはトランザクション制御されない。部分的な書き込みが発生する可能性がある。

## パフォーマンス要件

コマンドラインツールであり、即座に実行・完了する。特段のパフォーマンス要件は設けていない。

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

- レジストリへの書き込み（--defaultsオプション）はHKCU\Consoleに限定されており、管理者権限は不要
- ファイルシステムからのスキームファイル読み込みは、実行ユーザーの権限範囲内でのみ動作する
- VTシーケンス出力はコンソールの色設定を変更するのみであり、セキュリティリスクは低い

## 備考

- ColorToolはWindows Terminalプロジェクト内のスタンドアロンツールであり、ターミナル本体とは独立して動作する
- 対応するスキームファイル形式は以下の3つ：
  - INI形式（.ini）：Windowsコンソール固有の形式
  - XML形式（.itermcolors）：iTerm2互換のplist形式
  - JSON形式（.json）：Windows Terminal互換のJSON形式
- 同梱スキーム：campbell, cmd-legacy, campbell-legacy, campbell-absolute, OneHalfDark, OneHalfLight, solarized_dark, solarized_light, tango_dark, tango_light, deuteranopia
- Console APIとVTシーケンスでは色インデックスの並び順が異なるため、VirtualTerminalIndicesによる変換が必要

---

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

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

### 推奨読解順序

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

カラースキームとコンソール属性のデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ConsoleAttributes.cs | `src/tools/ColorTool/ColorTool/ConsoleAttributes.cs` | コンソール属性構造体。Foreground/Background/PopupForeground/PopupBackground/Cursor（すべてnullable uint） |
| 1-2 | ColorScheme.cs | `src/tools/ColorTool/ColorTool/ColorScheme.cs` | カラースキームクラス。16色ColorTable、ConsoleAttributes、色距離計算、インデックス計算 |
| 1-3 | ConsoleAPI.cs | `src/tools/ColorTool/ColorTool/ConsoleAPI.cs` | Console APIのP/Invoke宣言。CONSOLE_SCREEN_BUFFER_INFO_EX構造体、ConsoleOutputModes列挙型 |

**読解のコツ**: `uint`で表現される色はWin32 COLORREF形式（0x00BBGGRR、BGR順）である点に注意。ColorScheme.RGB()メソッドで各チャネルを抽出する。ConsoleAttributesの各プロパティはnullableで、スキームファイルに該当項目が含まれない場合はnullとなる。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Program.cs | `src/tools/ColorTool/ColorTool/Program.cs` | Mainメソッド。引数解析、フラグ設定、スキーム読み込み、ConsoleTarget適用 |

**主要処理フロー**:
1. **26-126行目**: Main関数全体。引数を順に解析し、フラグを設定
2. **28-32行目**: 引数なしの場合にUsage表示
3. **33-104行目**: 引数解析ループ。各フラグの設定
4. **105-110行目**: --current指定時のカラーテーブル表示分岐
5. **112行目**: スキーム名の取得（最後の引数）
6. **114行目**: SchemeManager.GetSchemeでスキーム検索
7. **122-125行目**: GetConsoleTargets()で適用先を取得し、ApplyColorSchemeを呼び出し
8. **139-155行目**: DoInVTMode。VTモードを一時有効化しアクション実行後に元に戻す
9. **168-189行目**: GetConsoleTargets。フラグに応じてIConsoleTargetの列挙を返す

#### Step 3: スキーム管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | SchemeManager.cs | `src/tools/ColorTool/ColorTool/SchemeManager.cs` | スキーム検索・一覧・取得の管理クラス |
| 3-2 | ISchemeParser.cs | `src/tools/ColorTool/ColorTool/SchemeParsers/ISchemeParser.cs` | スキームパーサーインターフェース。Name/FileExtension/ParseScheme |
| 3-3 | SchemeParserBase.cs | `src/tools/ColorTool/ColorTool/SchemeParsers/SchemeParserBase.cs` | パーサー基底クラス。ExtractSchemeName補助メソッド |

**主要処理フロー**:
- **17-43行目（SchemeManager.cs）**: GetSearchPaths。7段階の検索パス生成（カレント→./schemes/→exe/schemes/→絶対パス）
- **89-94行目**: GetScheme。全パーサーで順番にParseSchemeを試行し最初の非nullを返す
- **96-101行目**: GetParsers。リフレクションでISchemeParser実装クラスを自動検出

#### Step 4: 適用先（ConsoleTarget）を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | IConsoleTarget.cs | `src/tools/ColorTool/ColorTool/ConsoleTargets/IConsoleTarget.cs` | 適用先インターフェース。ApplyColorScheme |
| 4-2 | CurrentConsoleTarget.cs | `src/tools/ColorTool/ColorTool/ConsoleTargets/CurrentConsoleTarget.cs` | 現在のコンソールへの適用。Console API使用 |
| 4-3 | DefaultConsoleTarget.cs | `src/tools/ColorTool/ColorTool/ConsoleTargets/DefaultConsoleTarget.cs` | レジストリ（HKCU\Console）への書き込み |
| 4-4 | VirtualTerminalConsoleTarget.cs | `src/tools/ColorTool/ColorTool/ConsoleTargets/VirtualTerminalConsoleTarget.cs` | VTシーケンス（OSC 4/10/11/12）による適用 |
| 4-5 | TerminalSchemeConsoleTarget.cs | `src/tools/ColorTool/ColorTool/ConsoleTargets/TerminalSchemeConsoleTarget.cs` | Windows Terminal settings.json向けJSON出力 |

**主要処理フロー**:
- **16-45行目（CurrentConsoleTarget.cs）**: GetConsoleScreenBufferInfoExで現在の情報取得、ColorTable上書き、SetConsoleScreenBufferInfoExで適用
- **16-62行目（DefaultConsoleTarget.cs）**: Registry.CurrentUser.OpenSubKey("Console")で16色+属性をレジストリに書き込み
- **39-74行目（VirtualTerminalConsoleTarget.cs）**: OSCシーケンス出力。前景色=OSC 10、背景色=OSC 11、カーソル色=OSC 12、カラーテーブル=OSC 4
- **10-62行目（TerminalSchemeConsoleTarget.cs）**: settings.json用のJSON文字列を標準出力に出力

#### Step 5: カラーテーブル表示を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | ColorTable.cs | `src/tools/ColorTool/ColorTool/ColorTable.cs` | カラーテーブルのマトリクス表示。Console API版とVT版の2種類 |

**主要処理フロー**:
- **97-149行目**: PrintTable。Console.ForegroundColor/BackgroundColorを使用した表示
- **151-196行目**: PrintTableWithVt。VTエスケープシーケンスを使用した表示

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

```
Program.Main (Program.cs:26)
    |
    +-- [引数解析] フラグ設定
    |
    +-- [--current] ColorTable.PrintTable / PrintTableWithVt (ColorTable.cs)
    |       |
    |       +-- DoInVTMode (VT版の場合)
    |
    +-- [--schemes] SchemeManager.PrintSchemes (SchemeManager.cs:51)
    |       |
    |       +-- SchemeManager.GetScheme → 各スキームの色をプレビュー
    |
    +-- [--output] IniSchemeWriter.ExportCurrentAsIni
    |
    +-- [スキーム適用]
            |
            +-- SchemeManager.GetScheme (SchemeManager.cs:89)
            |       |
            |       +-- SchemeManager.GetParsers()  → リフレクションでパーサー取得
            |       +-- ISchemeParser.ParseScheme()
            |               |
            |               +-- IniSchemeParser / XmlSchemeParser / JsonParser
            |
            +-- GetConsoleTargets() (Program.cs:168)
                    |
                    +-- DefaultConsoleTarget.ApplyColorScheme  (レジストリ)
                    +-- CurrentConsoleTarget.ApplyColorScheme  (Console API)
                    +-- VirtualTerminalConsoleTarget.ApplyColorScheme  (VT)
                    +-- TerminalSchemeConsoleTarget.ApplyColorScheme  (JSON)
```

### データフロー図

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

コマンドライン引数      ───>  Program.Main               ───>  フラグ設定
                               |
スキームファイル        ───>  SchemeManager.GetScheme     ───>  ColorScheme
(.ini/.itermcolors/.json)      |                                  |
                               +-- ISchemeParser.ParseScheme      +-- ColorTable[16]
                                                                  +-- ConsoleAttributes

ColorScheme             ───>  IConsoleTarget               ───>  色設定の適用
                               |
                               +-- CurrentConsoleTarget    ───>  Console API (即時)
                               +-- DefaultConsoleTarget    ───>  レジストリ (永続)
                               +-- VTConsoleTarget         ───>  VT OSCシーケンス
                               +-- TerminalSchemeTarget    ───>  JSON (stdout)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Program.cs | `src/tools/ColorTool/ColorTool/Program.cs` | ソース | エントリーポイント。引数解析、スキーム適用 |
| ColorScheme.cs | `src/tools/ColorTool/ColorTool/ColorScheme.cs` | ソース | カラースキームデータクラス。色距離計算 |
| ConsoleAttributes.cs | `src/tools/ColorTool/ColorTool/ConsoleAttributes.cs` | ソース | コンソール属性構造体 |
| SchemeManager.cs | `src/tools/ColorTool/ColorTool/SchemeManager.cs` | ソース | スキーム検索・一覧・取得の管理 |
| ColorTable.cs | `src/tools/ColorTool/ColorTool/ColorTable.cs` | ソース | カラーテーブル表示 |
| ConsoleAPI.cs | `src/tools/ColorTool/ColorTool/ConsoleAPI.cs` | ソース | Console APIのP/Invoke宣言 |
| ISchemeParser.cs | `src/tools/ColorTool/ColorTool/SchemeParsers/ISchemeParser.cs` | ソース | スキームパーサーインターフェース |
| SchemeParserBase.cs | `src/tools/ColorTool/ColorTool/SchemeParsers/SchemeParserBase.cs` | ソース | パーサー基底クラス |
| IniSchemeParser.cs | `src/tools/ColorTool/ColorTool/SchemeParsers/IniSchemeParser.cs` | ソース | INI形式パーサー |
| XmlSchemeParser.cs | `src/tools/ColorTool/ColorTool/SchemeParsers/XmlSchemeParser.cs` | ソース | XML（itermcolors）形式パーサー |
| JsonParser.cs | `src/tools/ColorTool/ColorTool/SchemeParsers/JsonParser.cs` | ソース | JSON形式パーサー |
| IConsoleTarget.cs | `src/tools/ColorTool/ColorTool/ConsoleTargets/IConsoleTarget.cs` | ソース | 適用先インターフェース |
| CurrentConsoleTarget.cs | `src/tools/ColorTool/ColorTool/ConsoleTargets/CurrentConsoleTarget.cs` | ソース | 現在のコンソールへの適用 |
| DefaultConsoleTarget.cs | `src/tools/ColorTool/ColorTool/ConsoleTargets/DefaultConsoleTarget.cs` | ソース | レジストリへの適用 |
| VirtualTerminalConsoleTarget.cs | `src/tools/ColorTool/ColorTool/ConsoleTargets/VirtualTerminalConsoleTarget.cs` | ソース | VTシーケンスによる適用 |
| TerminalSchemeConsoleTarget.cs | `src/tools/ColorTool/ColorTool/ConsoleTargets/TerminalSchemeConsoleTarget.cs` | ソース | Windows Terminal JSON出力 |
| IniSchemeWriter.cs | `src/tools/ColorTool/ColorTool/SchemeWriters/IniSchemeWriter.cs` | ソース | INI形式エクスポート |
| schemes/ | `src/tools/ColorTool/schemes/` | スキーム | 同梱カラースキームファイル群 |
| ColorTool.csproj | `src/tools/ColorTool/ColorTool/ColorTool.csproj` | プロジェクト | C#プロジェクトファイル |
| Resources.resx | `src/tools/ColorTool/ColorTool/Resources.resx` | リソース | メッセージ文字列リソース |
