arial
GitHub

Architecture Overview

Arial is a lightweight Claude Code orchestrator that runs parallel AI workstreams with great observability. This document provides a high-level overview of the system architecture.

Design Principles

Arial follows several core design principles:

  • Functional programming - Pure functions over classes, immutable data structures
  • Type safety - Strict TypeScript with compile-time guarantees
  • Result types - Error handling via Result<T, E> instead of exceptions
  • Adapter pattern - Pluggable AI backends for flexibility
  • Git isolation - Each workstream runs in its own branch and worktree

System Overview

User Command
    |
    v
Command Handler (commands/*.ts)
    |
    v
State Management (state.ts) <-- Load/Save
    |
    v
Orchestrator (orchestrator.ts)
    |
    +---> WorkstreamExecutor (x N in parallel)
    |         |
    |         +---> Adapter Selection
    |         +---> Git Worktree Setup
    |         +---> Agent Runner
    |         +---> Output Buffering
    |
    +---> Merge Logic (sequential)
    |
    +---> Event Logging (Axiom)
    |
    v
TUI (ui/tui.ts)

Core Components

Entry Point

The CLI entry point (index.ts) bootstraps Commander.js and parses commands. The program definition is extracted to program.ts to allow testing without triggering parse().

Commands

Five main commands in commands/:

CommandPurpose
`init`Initialize Arial in a Git repository
`plan`Create workstreams from spec files
`run`Execute all workstreams in parallel
`status`Show current run status
`cleanup`Remove stale worktrees and branches

Orchestrator

The orchestrator (lib/orchestrator.ts) is the central coordination engine:

  1. Creates a WorkstreamExecutor for each pending workstream
  2. Starts all executors in parallel
  3. Queues completed workstreams for merge
  4. Processes merges sequentially to avoid conflicts
  5. Emits events for observability

Workstream Executor

Each workstream runs in its own WorkstreamExecutor (lib/workstream-executor.ts):

  1. Resolve adapter (from spec preference or default)
  2. Validate adapter capabilities
  3. Create Git worktree on a dedicated branch
  4. Load spec content and shared context
  5. Build the execution prompt
  6. Stream tool execution via the adapter
  7. On success: stage changes and commit
  8. On failure: mark failed and save state

Adapters

The adapter system (adapters/) provides a pluggable interface for AI backends:

  • types.ts - Core Adapter interface
  • registry.ts - Factory and configuration loading
  • claude/ - Claude-specific implementation

See Adapters for details.

State Management

State is managed through pure functions in lib/state.ts:

  • Atomic writes via temp file + rename
  • JSON serialization with version field
  • State stored in .arial/state.json

See State Management for details.

Git Operations

All Git operations are wrapped in lib/git.ts:

  • Worktree management (create, remove, list)
  • Branch operations (create, checkout, delete)
  • Merge operations with conflict detection
  • Commit and push operations

See Git Operations for details.

TUI

The terminal UI (ui/tui.ts) provides real-time feedback:

  • Lane-based display with workstream list
  • Activity and output display for selected workstream
  • Spinner animation and status icons
  • Keyboard navigation

See TUI for details.

Data Flow

Plan Phase

Spec Files (markdown)
    |
    v
specs.ts (parsing)
    |
    v
suggest-workstreams.ts (optional AI planning)
    |
    v
state.ts (create ArialState)
    |
    v
.arial/state.json

Run Phase

.arial/state.json
    |
    v
Orchestrator
    |
    +---> Executor 1 ---> Worktree 1 ---> Agent ---> Commit
    +---> Executor 2 ---> Worktree 2 ---> Agent ---> Commit
    +---> Executor N ---> Worktree N ---> Agent ---> Commit
    |
    v
Merge Queue (sequential)
    |
    v
Base Branch (with all changes merged)

File Structure

apps/cli/src/
├── index.ts              # Entry point
├── program.ts            # CLI definition
├── commands/             # Command implementations
├── adapters/             # AI backend abstraction
│   ├── types.ts          # Core interface
│   ├── registry.ts       # Factory & config
│   └── claude/           # Claude implementation
├── lib/                  # Core logic (pure functions)
│   ├── orchestrator.ts   # Main orchestration
│   ├── workstream-executor.ts
│   ├── state.ts          # State management
│   ├── specs.ts          # Spec parsing
│   ├── git.ts            # Git operations
│   ├── merge.ts          # Merge with AI conflict resolution
│   └── ...
├── types/                # Domain types
├── ui/                   # Terminal UI
└── prompts/              # Agent prompt templates

Key Patterns

Result Type

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

Used throughout instead of throwing exceptions.

Factory Functions

All major components use factory functions:

createAdapter(config)
createOrchestrator(state, options)
createWorkstreamExecutor(workstream, options)

Callback-Based Events

Executors emit events via callbacks:

interface ExecutorCallbacks {
  onStatusChange: (status: WorkstreamStatus) => void
  onActivity: (activity: string) => void
  onOutput: (line: string) => void
}

The TUI and logging systems consume these events.