JA Architecture System Design - aku11i/phantom GitHub Wiki

システム設計

English | 日本語

このドキュメントでは、Phantomの全体的なアーキテクチャ、デザインパターン、アーキテクチャ上の決定事項について説明します。

アーキテクチャ概要

Phantomは明確な関心の分離を持つレイヤードアーキテクチャに従っています:

graph TD
    subgraph "ユーザーインターフェースレイヤー"
        CLI[CLIエントリーポイント]
        Commands[コマンドパーサー]
    end
    
    subgraph "アプリケーションレイヤー"
        Handlers[コマンドハンドラー]
        Output[出力フォーマット]
        ErrorHandler[エラーハンドリング]
    end
    
    subgraph "ドメインレイヤー"
        Worktree[Worktreeドメイン]
        Git[Gitドメイン]
        Process[プロセスドメイン]
    end
    
    subgraph "インフラストラクチャレイヤー"
        GitCLI[Git CLIラッパー]
        FileSystem[ファイルシステム]
        Shell[シェル実行]
    end
    
    CLI --> Commands
    Commands --> Handlers
    Handlers --> Output
    Handlers --> ErrorHandler
    Handlers --> Worktree
    Handlers --> Process
    
    Worktree --> Git
    Process --> Shell
    Git --> GitCLI
    
    style CLI fill:#f9f,stroke:#333
    style Handlers fill:#9ff,stroke:#333
    style Worktree fill:#ff9,stroke:#333
    style GitCLI fill:#9f9,stroke:#333
Loading

設計原則

1. 単一責任の原則(SRP)

ソース: CLAUDE.md#L26-L31

各モジュールには変更する理由が1つだけあります:

  • CLIハンドラー: コマンドインターフェースが変更されたときのみ変更
  • コアロジック: ビジネスルールが変更されたときのみ変更
  • Git操作: Git統合が変更されたときのみ変更
  • プロセス管理: 実行モデルが変更されたときのみ変更

2. 依存関係逆転の原則(DIP)

高レベルモジュールは低レベルモジュールに依存しません:

CLIレイヤー → コアレイヤー → インフラストラクチャ
         ↖             ↙
           インターフェース

3. 開放閉鎖の原則(OCP)

アーキテクチャは拡張に対して開いており、変更に対して閉じています:

  • 既存のコードを変更せずに新しいコマンドを追加可能
  • エグゼキューターに新しいGit操作を追加可能
  • 出力フォーマットを拡張可能

4. インターフェース分離の原則(ISP)

モジュールは使用するインターフェースにのみ依存します:

  • CLIハンドラーはGitの内部を知らない
  • コアロジックはコンソール出力を知らない
  • Git操作はCLIコマンドを知らない

コアデザインパターン

1. Result型パターン

ソース: src/core/types/result.ts

例外なしの関数型エラーハンドリング:

type Result<T, E = Error> = 
  | { ok: true; value: T }
  | { ok: false; error: E }

利点:

  • 明示的なエラーハンドリング
  • 型安全なエラー伝播
  • 構成可能な操作
  • 隠れた制御フローなし

使用例:

function createWorktree(name: string): Result<WorktreeInfo> {
  const validation = validateName(name);
  if (!validation.ok) {
    return validation;
  }
  
  const creation = git.addWorktree(name);
  if (!creation.ok) {
    return creation;
  }
  
  return Result.ok(creation.value);
}

2. コマンドパターン

各CLIコマンドはハンドラーとしてカプセル化されます:

interface CommandHandler {
  execute(args: ParsedArgs): Promise<void>;
}

配置場所: src/cli/handlers/

利点:

  • コマンドロジックの分離
  • テストが簡単
  • 新しいコマンドの追加が簡単
  • 一貫したインターフェース

3. ファサードパターン

Git操作は簡素化されたインターフェースでラップされます:

ソース: src/core/git/executor.ts

class GitExecutor {
  execute(args: string[]): Result<string>;
}

これにより以下の複雑さが隠蔽されます:

  • プロセス生成
  • エラーハンドリング
  • 出力解析
  • 環境セットアップ

4. ストラテジーパターン

プロセスの異なる実行戦略:

ソース: src/core/process/

  • exec.ts: 一回限りのコマンド実行
  • shell.ts: インタラクティブシェルセッション
  • spawn.ts: コア生成ロジック

アーキテクチャレイヤー

1. CLIレイヤー(src/cli/

責任:

  • コマンドライン引数の解析
  • 適切なハンドラーへのルーティング
  • ユーザー向けの出力フォーマット
  • プロセス終了コードの処理

主要コンポーネント:

  • コマンドハンドラー
  • 出力フォーマッター
  • エラーハンドラー

設計決定:

  • ビジネスロジックなし
  • 薄いオーケストレーションレイヤー
  • コアに委譲

2. コアレイヤー(src/core/

責任:

  • ビジネスロジックの実装
  • ドメインモデル管理
  • 検証ルール
  • コアアルゴリズム

主要モジュール:

Worktreeモジュール

ソース: src/core/worktree/

  • phantomライフサイクルの管理
  • phantom名の検証
  • Git操作の調整

Gitモジュール

ソース: src/core/git/

  • Git CLIコマンドのラップ
  • Git出力の解析
  • Gitエラーの処理

Processモジュール

ソース: src/core/process/

  • 子プロセスの生成
  • プロセスライフサイクルの管理
  • I/Oストリームの処理

3. インフラストラクチャレイヤー

責任:

  • システムとのインタラクション
  • 外部ツール統合
  • I/O操作

コンポーネント:

  • ファイルシステムアクセス
  • プロセス生成
  • Git CLI実行

データフローアーキテクチャ

コマンド実行フロー

sequenceDiagram
    participant User
    participant CLI
    participant Handler
    participant Core
    participant Git
    participant FS
    
    User->>CLI: phantom create feature
    activate CLI
    
    CLI->>Handler: route(command, args)
    activate Handler
    
    Handler->>Core: validateWorktreeName(name)
    activate Core
    Core-->>Handler: Result<void>
    deactivate Core
    
    alt 検証失敗
        Handler->>CLI: formatError(error)
        CLI->>User: エラーを表示
    else 検証成功
        Handler->>Core: createWorktree(name, branch)
        activate Core
        
        Core->>Git: getCurrentBranch()
        activate Git
        Git->>FS: git branch --show-current
        FS-->>Git: ブランチ名
        Git-->>Core: Result<string>
        deactivate Git
        
        Core->>Git: addWorktree(name, branch)
        activate Git
        Git->>FS: git worktree add
        FS-->>Git: 成功
        Git-->>Core: Result<WorktreeInfo>
        deactivate Git
        
        Core-->>Handler: Result<WorktreeInfo>
        deactivate Core
        
        Handler->>CLI: formatSuccess(info)
        CLI->>User: 成功を表示
    end
    
    deactivate Handler
    deactivate CLI
Loading

エラー伝播フロー

graph TB
    A[Gitコマンド失敗] --> B[エラーResultを作成]
    B --> C[コアに伝播]
    C --> D[ドメインエラーに変換]
    D --> E[ハンドラーに返す]
    E --> F[ユーザーメッセージをフォーマット]
    F --> G[終了コードを設定]
    G --> H[ユーザーに表示]
    
    style A fill:#f99
    style H fill:#9f9
Loading

モジュールアーキテクチャ

依存関係グラフ

graph TD
    subgraph "エントリーポイント"
        bin[bin/phantom.ts]
    end
    
    subgraph "CLIレイヤー"
        handlers[handlers/*]
        output[output.ts]
        errors[errors.ts]
    end
    
    subgraph "コアレイヤー"
        worktree[worktree/*]
        git[git/*]
        process[process/*]
        paths[paths.ts]
        types[types/*]
    end
    
    bin --> handlers
    handlers --> output
    handlers --> errors
    handlers --> worktree
    handlers --> process
    
    worktree --> git
    worktree --> paths
    worktree --> types
    
    process --> types
    git --> types
    
    style bin fill:#f9f
    style handlers fill:#9ff
    style worktree fill:#ff9
Loading

モジュール境界

  1. 上向き依存なし: コアはCLIからインポートしない
  2. インターフェース境界: モジュールは定義されたインターフェースを通じて通信
  3. 共有型: types/モジュールの共通型
  4. 循環依存なし: モジュール構造により強制

状態管理

ステートレス設計

Phantomはステートレスになるよう設計されています:

  • デーモンプロセスなし
  • 永続的な設定なし
  • バックグラウンドサービスなし
  • 各呼び出しは独立

利点:

  • シンプルなメンタルモデル
  • 推論が簡単
  • 状態破損なし
  • 並列実行が安全

状態ストアとしてのGit

すべての状態はGitに保存されます:

  • .git/worktrees/のWorktree情報
  • Git refsのブランチ情報
  • カスタム状態ファイルなし

エラーハンドリングアーキテクチャ

エラーカテゴリー

  1. 検証エラー

    • 無効なphantom名
    • 引数の欠落
    • 無効なブランチ
  2. Gitエラー

    • リポジトリが見つからない
    • ブランチが存在しない
    • Worktreeの競合
  3. システムエラー

    • アクセス拒否
    • ディスクフル
    • プロセス失敗

エラーリカバリー戦略

graph LR
    A[操作] --> B{回復可能?}
    B -->|はい| C[リトライ/修正提案]
    B -->|いいえ| D[クリーンな失敗]
    C --> E[ユーザーアクション]
    D --> F[コードで終了]
    E --> A
Loading

パフォーマンスアーキテクチャ

最適化戦略

  1. 依存関係ゼロ: 高速起動
  2. バンドルされた実行可能ファイル: 単一ファイル配布
  3. 遅延読み込み: 必要なものだけをロード
  4. 直接Git CLI: 抽象化オーバーヘッドなし

スケーラビリティの考慮事項

  • n個のworktreeに対してO(n)操作
  • 指数関数的アルゴリズムなし
  • 効率的なGitコマンド使用
  • 最小限のメモリフットプリント

セキュリティアーキテクチャ

入力検証

すべてのユーザー入力が検証されます:

function validateWorktreeName(name: string): Result<void> {
  // パストラバーサルをチェック
  if (name.includes('..') || name.includes('/')) {
    return Result.error(new Error('無効な文字'));
  }
  // 追加の検証...
}

プロセス実行

安全なコマンド実行:

  • デフォルトでシェル補間なし
  • インタラクティブセッション用の明示的なシェルモード
  • 制御された環境変数

将来のアーキテクチャに関する考慮事項

拡張ポイント

  1. プラグインシステム

    • コマンドプラグイン
    • 出力フォーマットプラグイン
    • Gitプロバイダープラグイン
  2. 設定システム

    • ユーザー設定
    • リポジトリ設定
    • グローバル設定
  3. イベントシステム

    • ライフサイクルフック
    • 進行状況レポート
    • テレメトリー

アーキテクチャの不変条件

これらは維持されなければなりません:

  1. ランタイム依存関係ゼロ
  2. ステートレス操作
  3. 単一の真実の源としてのGit
  4. クリーンなレイヤー分離
  5. 関数型エラーハンドリング

まとめ

Phantomのアーキテクチャは以下のために設計されています:

  1. シンプルさ: 理解と保守が簡単
  2. パフォーマンス: 最小限のオーバーヘッドで高速実行
  3. 信頼性: 予測可能な動作とエラーハンドリング
  4. 拡張性: 新機能の追加が簡単
  5. テスト可能性: 明確な境界と純粋関数

関数型パターンを持つレイヤードアーキテクチャは、Gitワークフローの生産性を向上させる堅牢で保守可能なシステムを作成します。

⚠️ **GitHub.com Fallback** ⚠️