Architecture System Design - aku11i/phantom GitHub Wiki

System Design

This document describes Phantom's overall architecture, design patterns, and architectural decisions.

Architectural Overview

Phantom follows a layered architecture with clear separation of concerns:

graph TD
    subgraph "User Interface Layer"
        CLI[CLI Entry Point]
        Commands[Command Parser]
    end
    
    subgraph "Application Layer"
        Handlers[Command Handlers]
        Output[Output Formatting]
        ErrorHandler[Error Handling]
    end
    
    subgraph "Domain Layer"
        Worktree[Worktree Domain]
        Git[Git Domain]
        Process[Process Domain]
    end
    
    subgraph "Infrastructure Layer"
        GitCLI[Git CLI Wrapper]
        FileSystem[File System]
        Shell[Shell Execution]
    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

Design Principles

1. Single Responsibility Principle (SRP)

Source: CLAUDE.md#L26-L31

Each module has exactly one reason to change:

  • CLI Handlers: Only change when command interface changes
  • Core Logic: Only change when business rules change
  • Git Operations: Only change when Git integration changes
  • Process Management: Only change when execution model changes

2. Dependency Inversion Principle (DIP)

High-level modules don't depend on low-level modules:

CLI Layer → Core Layer → Infrastructure
         ↖             ↙
           Interfaces

3. Open/Closed Principle (OCP)

The architecture is open for extension but closed for modification:

  • New commands can be added without changing existing code
  • New Git operations can be added to the executor
  • Output formats can be extended

4. Interface Segregation Principle (ISP)

Modules depend only on interfaces they use:

  • CLI handlers don't know about Git internals
  • Core logic doesn't know about console output
  • Git operations don't know about CLI commands

Core Design Patterns

1. Result Type Pattern

Source: src/core/types/result.ts

Functional error handling without exceptions:

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

Benefits:

  • Explicit error handling
  • Type-safe error propagation
  • Composable operations
  • No hidden control flow

Usage example:

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. Command Pattern

Each CLI command is encapsulated as a handler:

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

Located in: src/cli/handlers/

Benefits:

  • Decoupled command logic
  • Easy to test
  • Simple to add new commands
  • Consistent interface

3. Facade Pattern

Git operations are wrapped in a simplified interface:

Source: src/core/git/executor.ts

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

This hides the complexity of:

  • Process spawning
  • Error handling
  • Output parsing
  • Environment setup

4. Strategy Pattern

Different execution strategies for processes:

Source: src/core/process/

  • exec.ts: One-time command execution
  • shell.ts: Interactive shell sessions
  • spawn.ts: Core spawning logic

Architectural Layers

1. CLI Layer (src/cli/)

Responsibilities:

  • Parse command-line arguments
  • Route to appropriate handlers
  • Format output for users
  • Handle process exit codes

Key Components:

  • Command handlers
  • Output formatter
  • Error handler

Design Decisions:

  • No business logic
  • Thin orchestration layer
  • Delegates to core

2. Core Layer (src/core/)

Responsibilities:

  • Business logic implementation
  • Domain model management
  • Validation rules
  • Core algorithms

Key Modules:

Worktree Module

Source: src/core/worktree/

  • Manages phantom lifecycle
  • Validates phantom names
  • Coordinates Git operations

Git Module

Source: src/core/git/

  • Wraps Git CLI commands
  • Parses Git output
  • Handles Git errors

Process Module

Source: src/core/process/

  • Spawns child processes
  • Manages process lifecycle
  • Handles I/O streams

3. Infrastructure Layer

Responsibilities:

  • System interaction
  • External tool integration
  • I/O operations

Components:

  • File system access
  • Process spawning
  • Git CLI execution

Data Flow Architecture

Command Execution Flow

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 Validation Failed
        Handler->>CLI: formatError(error)
        CLI->>User: Display error
    else Validation Passed
        Handler->>Core: createWorktree(name, branch)
        activate Core
        
        Core->>Git: getCurrentBranch()
        activate Git
        Git->>FS: git branch --show-current
        FS-->>Git: branch name
        Git-->>Core: Result<string>
        deactivate Git
        
        Core->>Git: addWorktree(name, branch)
        activate Git
        Git->>FS: git worktree add
        FS-->>Git: success
        Git-->>Core: Result<WorktreeInfo>
        deactivate Git
        
        Core-->>Handler: Result<WorktreeInfo>
        deactivate Core
        
        Handler->>CLI: formatSuccess(info)
        CLI->>User: Display success
    end
    
    deactivate Handler
    deactivate CLI
Loading

Error Propagation Flow

graph TB
    A[Git Command Fails] --> B[Create Error Result]
    B --> C[Propagate to Core]
    C --> D[Transform to Domain Error]
    D --> E[Return to Handler]
    E --> F[Format User Message]
    F --> G[Set Exit Code]
    G --> H[Display to User]
    
    style A fill:#f99
    style H fill:#9f9
Loading

Module Architecture

Dependency Graph

graph TD
    subgraph "Entry Points"
        bin[bin/phantom.ts]
    end
    
    subgraph "CLI Layer"
        handlers[handlers/*]
        output[output.ts]
        errors[errors.ts]
    end
    
    subgraph "Core Layer"
        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

Module Boundaries

  1. No Upward Dependencies: Core never imports from CLI
  2. Interface Boundaries: Modules communicate through defined interfaces
  3. Shared Types: Common types in types/ module
  4. No Circular Dependencies: Enforced by module structure

State Management

Stateless Design

Phantom is designed to be stateless:

  • No daemon processes
  • No persistent configuration
  • No background services
  • Each invocation is independent

Benefits:

  • Simple mental model
  • Easy to reason about
  • No state corruption
  • Parallel execution safe

Git as State Store

All state is stored in Git:

  • Worktree information in .git/worktrees/
  • Branch information in Git refs
  • No custom state files

Error Handling Architecture

Error Categories

  1. Validation Errors

    • Invalid phantom names
    • Missing arguments
    • Invalid branches
  2. Git Errors

    • Repository not found
    • Branch doesn't exist
    • Worktree conflicts
  3. System Errors

    • Permission denied
    • Disk full
    • Process failures

Error Recovery Strategy

graph LR
    A[Operation] --> B{Recoverable?}
    B -->|Yes| C[Retry/Suggest Fix]
    B -->|No| D[Clean Failure]
    C --> E[User Action]
    D --> F[Exit with Code]
    E --> A
Loading

Performance Architecture

Optimization Strategies

  1. Zero Dependencies: Fast startup
  2. Bundled Executable: Single file distribution
  3. Lazy Loading: Load only what's needed
  4. Direct Git CLI: No abstraction overhead

Scalability Considerations

  • O(n) operations for n worktrees
  • No exponential algorithms
  • Efficient Git command usage
  • Minimal memory footprint

Security Architecture

Input Validation

All user input is validated:

function validateWorktreeName(name: string): Result<void> {
  // Check for path traversal
  if (name.includes('..') || name.includes('/')) {
    return Result.error(new Error('Invalid characters'));
  }
  // Additional validation...
}

Process Execution

Safe command execution:

  • No shell interpolation by default
  • Explicit shell mode for interactive sessions
  • Controlled environment variables

Future Architecture Considerations

Extensibility Points

  1. Plugin System

    • Command plugins
    • Output format plugins
    • Git provider plugins
  2. Configuration System

    • User preferences
    • Repository settings
    • Global configuration
  3. Event System

    • Lifecycle hooks
    • Progress reporting
    • Telemetry

Architectural Invariants

These must be maintained:

  1. Zero runtime dependencies
  2. Stateless operation
  3. Git as single source of truth
  4. Clean layer separation
  5. Functional error handling

Summary

Phantom's architecture is designed for:

  1. Simplicity: Easy to understand and maintain
  2. Performance: Fast execution with minimal overhead
  3. Reliability: Predictable behavior and error handling
  4. Extensibility: Easy to add new features
  5. Testability: Clear boundaries and pure functions

The layered architecture with functional patterns creates a robust, maintainable system that enhances Git workflow productivity.

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