CLI Internals
Technical reference for understanding CLI internals.
Package Structure
Section titled βPackage Structureβpackages/cli/βββ src/β βββ cli.ts # Entry point, argument parsing, routingβ βββ commands/β β βββ workflow.ts # workflow list/run (approve/reject/status/resume/abandon delegate to @archon/core/operations)β β βββ isolation.ts # isolation list/cleanup (list/merged-cleanup delegate to @archon/core/operations)β β βββ setup.ts # setup command implementationβ β βββ chat.ts # chat command implementationβ β βββ validate.ts # validate command implementationβ β βββ version.ts # version commandβ βββ adapters/β βββ cli-adapter.ts # IPlatformAdapter for stdoutβββ package.json # Defines "archon" binaryEntry Point Flow
Section titled βEntry Point Flowβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ archon <command> [subcommand] [options] [arguments] ββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ β βΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ strip-cwd-env-boot (first import, side-effect) ββ stripCwdEnv(): deletes Bun-auto-loaded <cwd>/.env* keys from ββ process.env + CLAUDE_CODE_* session markers. Emits ββ [archon] stripped N keys from <cwd> (...) when N > 0. ββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ β βΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ loadArchonEnv(cwd) β both loads use override: true ββ 1. ~/.archon/.env (home scope) ββ 2. <cwd>/.archon/.env (repo scope, wins over home) ββ Emits one [archon] loaded N keys from <path> line per file ββ when N > 0 and ARCHON_VERBOSE_BOOT=1 or LOG_LEVEL=debug/trace.ββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ β βΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ cli.ts Parse arguments ββ --cwd, --branch, --no-worktree, --help ββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ β βΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ cli.ts Git repository check ββ Skip for version/help, validate and resolve to ββ repo root for workflow/isolation commands ββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ β βΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ cli.ts Route to command handler ββ switch(command) β workflow | isolation | versionββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ β βΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ cli.ts Exit with code, always closeDatabase() ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββCode: packages/cli/src/cli.ts
Git repository check:
- Commands
workflow,isolation, andcompleterequire running from a git repository - Commands
version,help,setup, andchatbypass this check - When in a subdirectory, automatically resolves to repository root
- Exit code 1 if not in a git repository
workflow list Flow
Section titled βworkflow list Flowββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ archon workflow list [--json] βββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ β βΌβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ workflow.ts workflowListCommand(cwd, json?) βββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ β βΌβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ @archon/workflows/workflow-discovery ββ discoverWorkflowsWithConfig(cwd, config) ββ - Loads bundled defaults ββ - Searches .archon/workflows/ recursively ββ - Merges (repo overrides defaults by name) βββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ β βββββββββββββββββ΄ββββββββββββββββ β json=true β json=false βΌ βΌββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββββββ JSON output to stdout β β Human-readable list to stdout ββ { workflows, errors } β β name, description, type, options βββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββββββββCode: packages/cli/src/commands/workflow.ts
workflow run Flow
Section titled βworkflow run Flowβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ archon workflow run <name> [message] [--branch X] [--from X] [--no-worktree]ββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ β βΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ workflow.ts:78-92 Discover & find workflow by name ββ Error if not found (lists available) ββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ β βΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ workflow.ts:99 Create CLIAdapter for stdout ββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ β βΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ workflow.ts:104-133 Database setup ββ - Create conversation: cli-{timestamp}-{random} ββ - Lookup codebase from directory (warn if fails) ββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ β βΌ βββββββββββββββ΄ββββββββββββββ β β no --branch --branch β β βΌ βΌβββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββββββ Use cwd as-is β β workflow.ts:152-168 ββ β β Auto-detect git repo ββ β β Auto-register codebase if needed ββββββββββββββββ¬ββββββββββββββ βββββββββββββββββ¬ββββββββββββββββββββ β β β βββββββββββββββ΄ββββββββββββββ β β β β --no-worktree (default) β β β β βΌ βΌ β βββββββββββββββββββββββββββ βββββββββββββββββββββββββββ β β workflow.ts:171-175 β β workflow.ts:177-219 β β β git.checkout(cwd, branch)β β Check existing worktree β β β β β If healthy β reuse β β β β β Else β provider.create()β β β β β Track in DB β β ββββββββββββββ¬βββββββββββββ ββββββββββββββ¬βββββββββββββ β β β ββββββββββββββββββ΄ββββββββββββββ¬ββββββββββββββ β βΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ workflow.ts:235-243 executeWorkflow() ββ - Pass adapter, conversation, workflow, cwd, message ββ - Stream AI responses to stdout ββ - Return success/failure ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββCode: packages/cli/src/commands/workflow.ts:72-251
Worktree Provider: packages/isolation/src/providers/worktree.ts
workflow event emit Flow
Section titled βworkflow event emit Flowββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ archon workflow event emit --run-id <uuid> --type <type> [...] βββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ β βΌβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ cli.ts Validate --run-id, --type (required) ββ Validate --type against WORKFLOW_EVENT_TYPES ββ Parse --data as JSON (warn + skip if invalid) βββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ β βΌβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ workflow.ts workflowEventEmitCommand(runId, eventType, data?) ββ createWorkflowStore().createWorkflowEvent(...) ββ Non-throwing (fire-and-forget) βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββCode: packages/cli/src/cli.ts (case βeventβ), packages/cli/src/commands/workflow.ts:workflowEventEmitCommand
Contract: Event persistence is best-effort. createWorkflowEvent catches all errors internally β the CLI prints a confirmation but cannot guarantee the event was stored.
isolation list Flow
Section titled βisolation list Flowβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ archon isolation list ββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ β βΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ isolation.ts:19-57 isolationListCommand() ββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ β βΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ @archon/core isolationDb.listAllActiveWithCodebase() ββ - Joins isolation_environments with codebases ββ - Returns: path, branch, workflow_type, codebase_name, ββ platform, days_since_activity ββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ β βΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ isolation.ts:30-55 Group by codebase, print table ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββCode: packages/cli/src/commands/isolation.ts:19-57
isolation cleanup Flow
Section titled βisolation cleanup Flowβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ archon isolation cleanup [days] ββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ β βΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ isolation.ts:62-99 isolationCleanupCommand(daysStale) ββ default: 7 days ββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ β βΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ @archon/core isolationDb.findStaleEnvironments(days) ββ - WHERE last_activity_at < now - days ββ - Excludes telegram platform ββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ β βΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ For each stale environment: ββ 1. provider.destroy(path, options) ββ 2. Update DB status β 'destroyed' ββ 3. Log result ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββCode: packages/cli/src/commands/isolation.ts:62-99
isolation cleanup --merged Flow
Section titled βisolation cleanup --merged Flowβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ archon isolation cleanup --merged [--include-closed] ββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ β βΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ isolation.ts isolationCleanupMergedCommand({ includeClosed }) ββ For each codebase β cleanupMergedWorktrees(codebaseId, path) ββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ β For each active environment β βΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ isSafeToRemove() β three-signal union ββ (a) isBranchMerged() git ancestry (fast-forward/merge) ββ (b) isPatchEquivalent() git cherry (squash-merge) ββ (c) getPrState() gh CLI (MERGED/CLOSED/OPEN/NONE) ββ ββ OPEN β always skip ββ CLOSED β skip unless includeClosed=true ββ MERGED or any git-signal β proceed to remove ββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ β safe=true βΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Guard checks: no uncommitted changes, no active conversations ββ provider.destroy() β remove worktree + delete remote branch ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββSignals are evaluated in order β the first positive match short-circuits to avoid
unnecessary gh API calls. The gh CLI is a soft dependency: if missing or failing,
only git signals are used and the result degrades gracefully to NONE.
Code: packages/core/src/services/cleanup-service.ts β isSafeToRemove(), cleanupMergedWorktrees()
Code: packages/isolation/src/pr-state.ts β getPrState()
Code: packages/git/src/branch.ts β isPatchEquivalent()
CLI Adapter
Section titled βCLI AdapterβImplements IPlatformAdapter for terminal output.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ CLIAdapter ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€β sendMessage(convId, msg) β Output to stdout ββ getStreamingMode() β 'batch' ββ getPlatformType() β 'cli' ββ ensureThread() β passthrough ββ start() / stop() β no-op ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββCode: packages/cli/src/adapters/cli-adapter.ts:13-47
Key Dependencies
Section titled βKey Dependenciesβ| Function | Package | Location | Purpose |
|---|---|---|---|
discoverWorkflowsWithConfig(cwd, config) | @archon/workflows/workflow-discovery | workflows/src/workflow-discovery.ts | Find and parse workflow YAML |
executeWorkflow(...) | @archon/workflows/executor | workflows/src/executor.ts | Run workflow steps |
getIsolationProvider() | @archon/isolation | isolation/src/factory.ts | Get WorktreeProvider singleton |
conversationDb.* | @archon/core | core/src/db/conversations.ts | Conversation CRUD |
codebaseDb.* | @archon/core | core/src/db/codebases.ts | Codebase CRUD |
isolationDb.* | @archon/core | core/src/db/isolation-environments.ts | Worktree tracking |
git.* | @archon/git | packages/git/src/ | Git operations |
closeDatabase() | @archon/core | core/src/db/connection.ts | Clean shutdown |
Conversation ID Format
Section titled βConversation ID FormatβCLI conversations use ID format: cli-{timestamp}-{random}
Example: cli-1705932847321-a7f3b2
Generated at: packages/cli/src/commands/workflow.ts
Worktree Reuse Logic
Section titled βWorktree Reuse LogicβWhen --branch is provided:
- Lookup:
isolationDb.findActiveByWorkflow(codebaseId, 'task', branchName) - Health check:
provider.healthCheck(path)on existing - Reuse: If found and healthy (warns if
--fromwas specified but not applied) - Create: If not found or unhealthy β passes
fromBranchto provider if specified via--from
Worktrees stored at: ~/.archon/workspaces/<owner>/<repo>/worktrees/<branch-slug>/
Code: packages/cli/src/commands/workflow.ts:177-219
Exit Codes
Section titled βExit Codesβ| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Error (logged to stderr, including not in git repo) |
Database Connection
Section titled βDatabase Connectionβ- Connection opened on first database call
- Always closed in
finallyblock after command completes - Default: SQLite at
~/.archon/archon.db(zero setup, auto-initialized) - Optional: PostgreSQL when
DATABASE_URLis set (for cloud/advanced deployments)
Code: packages/cli/src/cli.ts