feat(cli): setup overhaul + archon doctor + complete bundled skill#1566
feat(cli): setup overhaul + archon doctor + complete bundled skill#1566
Conversation
…1494) Make binary installs the official primary path. Setup wizard becomes a dead-simple "AI + skippable adapters" flow, the embedded skill ships all 21 files, and `archon doctor` provides a canonical "is my setup OK?" checklist. Changes: - bundled-skill.ts: embed all 21 .claude/skills/archon/ files (was 18, missing good-practices.md, parameter-matrix.md, troubleshooting.md) - scripts/check-bundled-skill.ts: CI guard that fails when bundled-skill.ts drifts from .claude/skills/archon/; wired into `bun run validate` - setup.ts: remove database prompt (SQLite implicit), remove Discord, validate Claude binary via spawn test, probe `gh auth status` and optionally run `gh auth login`, add Telegram security note + empty- allowlist warning, append update instructions and offer to run `archon doctor` at the end - doctor.ts: new `archon doctor` command — green/red checklist for Claude binary, gh auth, database, workspace writability, bundled defaults, and adapter token pings (best-effort) - cli.ts: register `doctor` and add to noGitCommands - doctor.test.ts: spyOn-based tests for individual check functions - setup.test.ts: drop SetupConfig.database and platforms.discord references, anchor DATABASE_URL assertion to line start Closes #1494
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (13)
📝 WalkthroughWalkthroughThis PR implements the setup overhaul from issue ChangesSetup Overhaul & Doctor Command
Sequence DiagramsequenceDiagram
actor User
participant CLI as archon CLI
participant Doctor as doctorCommand()
participant Checks as Check Functions
participant Claude as Claude Binary
participant Git as gh CLI
participant DB as Database
participant FS as Filesystem
participant Slack as Slack API
participant Telegram as Telegram API
User ->> CLI: archon doctor
CLI ->> Doctor: dispatch to doctorCommand()
Doctor ->> Checks: start Promise.allSettled([<br/> checkClaudeBinary,<br/> checkGhAuth,<br/> checkDatabase,<br/> checkWorkspaceWritable,<br/> checkBundledDefaults,<br/> checkSlack,<br/> checkTelegram<br/>])
par Parallel Check Execution
Checks ->> Claude: execute --version (5s timeout)
Claude -->> Checks: pass/fail result
and
Checks ->> Git: gh auth status (10s timeout)
Git -->> Checks: pass/fail/skip result
and
Checks ->> DB: SELECT 1 query
DB -->> Checks: pass/fail result
and
Checks ->> FS: write/delete temp file
FS -->> Checks: pass/fail result
and
Checks ->> Slack: POST auth.test (5s timeout)
Slack -->> Checks: pass/fail/skip result
and
Checks ->> Telegram: POST getMe (5s timeout)
Telegram -->> Checks: pass/fail/skip result
end
Checks -->> Doctor: [CheckResult, CheckResult, ...]
Doctor ->> Doctor: render all checks (✓/✗/○ icons)
Doctor ->> Doctor: count failures + rejected promises
Doctor ->> User: print summary + exit code
User ->> User: exit 0 (pass) or 1 (fail)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.Comment |
Comprehensive PR ReviewPR: #1566 — feat(cli): setup overhaul + archon doctor + complete bundled skill SummaryClean delivery of Verdict:
🟠 High Issues (Should Fix Before Merge)H1: Orphaned JSDoc Blocks —
|
- Fix checkWorkspaceWritable false negative: separate try/catch for rmSync
so a cleanup failure never reports the directory as unwritable
- Fix collectGitHubConfig empty catch: distinguish gh-not-installed (ENOENT)
from gh-not-authenticated with actionable error messages
- Check spawnSync('gh', ['auth', 'login']) return value and warn if spawn fails
- Fix three stacked JSDoc blocks in setup.ts: restore orphaned JSDoc to
collectClaudeBinaryPath and collectClaudeAuth, keep only correct block
above probeClaudeBinarySpawns
- Fix doctorCommand allSettled rejection handler: use String(s.reason) for
non-Error rejections instead of producing "undefined" output; add log.error
- Fix checkSlack/checkTelegram catch label: drop "network error: " prefix
so JSON parse failures aren't mischaracterized
- Fix "Skip silently" wording in doctor.ts: visible output contradicted "silently"
- Fix doctor.test.ts module comment: BUNDLED_IS_BINARY is not spied, clarify
- Add checkBundledDefaults test: passes in dev mode without mocks
- Update CLAUDE.md: fix validate description "five" → "six" checks, add
check:bundled-skill; add archon doctor to CLI section
- Update docs-web cli.md: add doctor command section after setup
- Add comment to check-bundled-skill.ts documenting substring check limitation
⚡ Self-Fix Report (Aggressive)Status: COMPLETE Fixes Applied (13 total)
View all fixesHIGH
MEDIUM
LOW
Tests Added
Skipped (0)(none — all findings addressed) Validation✅ Type check | ✅ Lint | ✅ Tests (9 passed in doctor.test.ts, 0 failures across full suite) Self-fix · aggressive mode · fixes pushed to |
- Remove 12-line file JSDoc that restated the obvious; keep only the non-obvious setup-invocation note - Drop existsSync() guard before execFileAsync() — TOCTOU-prone and redundant since the catch block already produces a clear error - Collapse verbose allSettled comment to one line
…stall `archon setup` previously copied the Claude skill into the user's project but did not create a `.archon/` directory or a project config there. A fresh user who wanted any project-scoped override (per-project assistant defaults, custom docs path, etc.) had to `mkdir -p .archon` and create config.yaml by hand — exactly the friction the v0.3.11 setup overhaul was meant to remove. Add `bootstrapProjectConfig(projectPath)` and call it after the skill install. Writes a commented-out starter `.archon/config.yaml` with example keys and a link to the configuration reference. Idempotent on re-run (skips if the file already exists). Workflows/commands/scripts subdirectories are intentionally not created — empty dirs would clutter users' trees and the loaders handle their absence cleanly. The wizard's final summary now shows the created config path so the user knows where to put per-project overrides. Tests: - creates `.archon/config.yaml` when missing - creates the `.archon` directory if absent - is idempotent — leaves an existing user config untouched - returns failed state without throwing on unwritable target
PR Review Summary — multi-agent (#1566)Six specialized agents reviewed the diff (code, docs, tests, errors, types, comments). Findings below. Critical IssuesNone — no data-loss or unsafe-fallback issues. Important Issues (10 found)
Suggestions (6 found)
Comment cleanup (4 noise comments)
Strengths
VerdictNEEDS FIXES — no critical blockers, but 10 important issues. The Recommended Actions (in order)
|
Production correctness:
- setup.ts: gh auth login now checks .status !== 0 so a non-zero exit
(cancelled OAuth, failed callback) is surfaced instead of silently
succeeding.
- setup.ts: probeClaudeBinarySpawns returns {ok, reason}; the warning
now includes the actual spawn error (ENOENT/timeout/permissions).
- setup.ts: bootstrapProjectConfig uses writeFileSync flag 'wx' and
catches EEXIST, eliminating the TOCTOU window between existsSync
and the write.
- doctor.ts: split checkDatabase into module-load vs query try-catches
so a missing @archon/core stops masquerading as "Database not
reachable". Both branches now log structured errors.
- doctor.ts: checkWorkspaceWritable rmSync catch logs warn so repeated
delete failures leave a diagnostic trace.
- cli.ts: doctor case uses a static import to match every other peer
command.
Tests:
- checkClaudeBinary covers all four branches via an injected isBinary
parameter (skip / no-path / spawn-pass / spawn-fail).
- checkDatabase covers sqlite + postgres pass, query failure, and
module-load failure via injectable loadDeps.
- checkSlack / checkTelegram cover pass / fail / network-error->skip
via spyOn(globalThis, 'fetch').
- checkGhAuth gains an explicit GH_TOKEN-only branch.
- doctorCommand asserts the exit-code contract (0 on all-pass, 1 on
any fail, thrown checks counted) and Promise.allSettled non-short-
circuit, via injectable check thunks.
Docs:
- cli.md: doctor added to the no-git command list.
- CLAUDE.md: validate now mentions check:bundled-skill alongside
check:bundled.
- overview.md: archon doctor row added to the CLI command table.
- troubleshooting.md: points users at archon doctor after setup.
… 6 (#11) * docs/skill: general hardening — fix inaccuracies, fill workflow/CLI/env gaps, add good-practices + troubleshooting (coleam00#1363) * fix(skill/when): document the full `when:` operator set and compound expressions The skill reference previously stated "operators: ==, != only" which is materially wrong — the condition evaluator supports ==, !=, <, >, <=, >= plus && / || compound expressions with && binding tighter than ||, plus dot-notation JSON field access. An agent authoring a workflow from the skill would think half the operators don't exist. Replaces the single-sentence section with a structured reference covering: - All six comparison operators (string and numeric modes) - Compound expressions with precedence rules and short-circuit eval - JSON dot notation semantics and failure modes - The fail-closed rules in full (invalid expression, non-numeric side, missing field, skipped upstream) Grounded in packages/workflows/src/condition-evaluator.ts. * feat(skill): document Approval and Cancel node types Approval and cancel nodes are first-class DAG node types (approval since the workflow lifecycle work in coleam00#871, cancel as a guarded-exit primitive) but the skill never described either one. An agent reading the skill and asked to "add a review gate before implementation" or "stop the workflow if the input is unsafe" would fall back to bash + exit 1, losing the proper semantics (cancelled vs. failed, on_reject AI rework, web UI auto-resume). Approval node coverage (references/workflow-dag.md, SKILL.md): - Full configuration block with message, capture_response, on_reject - The interactive: true workflow-level requirement for web UI delivery - Approve/reject commands across all platforms (CLI, slash, natural language) and the capture_response → $node-id.output flow - Ignored-fields list + the on_reject.prompt AI sub-node exception Cancel node coverage (references/workflow-dag.md, SKILL.md): - Single-field schema (cancel: "<reason>") - Lifecycle: cancelled (not failed); in-flight parallel nodes stopped; no DAG auto-resume path - The "cancel: vs bash-exit-1" decision rule (expected precondition miss vs. check itself failing) - Two canonical patterns — upstream-classification gate, pre-expensive-step gate Validation-rules list updated to enumerate approval/cancel constraints (message non-empty, on_reject.max_attempts range 1-10, cancel reason non-empty), plus a forward note that script: joins the mutually-exclusive set once PR coleam00#1362 lands. Placement in both files is after the Loop section and before the validation section, so this commit stays additive with respect to PR coleam00#1362's Script node insertion between Bash and Loop — rebase is clean. * feat(skill): document workflow-level fields beyond name/provider/model The skill's Schema section previously showed only name, description, provider, and model at the workflow level — which is most of a stub. Agents asked to "use the 1M-context Claude beta" or "run this under a network sandbox" or "add a fallback model in case Opus rate-limits" had no way to discover that any of these fields existed at the workflow level. Adds a comprehensive Workflow-Level Fields section covering: - Core: name, description, provider, model, interactive (with explicit callout that interactive: true is REQUIRED for approval/loop gates on web UI — a common footgun) - Isolation: worktree.enabled for pin-on/pin-off (the only worktree field at workflow level; baseBranch/copyFiles/path/initSubmodules are config.yaml only, so a cross-reference points there) - Claude SDK advanced: effort, thinking, fallbackModel, betas, sandbox, with explicit per-node-only exceptions (maxBudgetUsd, systemPrompt) - Codex-specific: modelReasoningEffort (with note that it's NOT the same as Claude's effort — this has confused users), webSearchMode, additionalDirectories - A complete worked example combining sandbox + approval + interactive All fields cross-referenced against packages/workflows/src/schemas/workflow.ts and packages/workflows/src/schemas/dag-node.ts. * feat(skill/loop): document interactive loops and gate_message Interactive loop nodes pause between iterations for human feedback via /workflow approve — used by archon-piv-loop and archon-interactive-prd. The skill's Loop Nodes section previously omitted both interactive: true and gate_message entirely, so an agent writing a guided-refinement workflow wouldn't know the feature exists or that gate_message is required at parse time. Adds: - interactive and gate_message rows to the config table (marking gate_message as required when interactive: true — enforced by the loader's superRefine) - A dedicated "Interactive Loops" subsection explaining the 6-step iterate-pause-approve-resume flow - Explicit call-out that $LOOP_USER_INPUT populates ONLY on the first iteration of a resumed session — easy to miss and a common surprise - Workflow-level interactive: true requirement for web UI delivery (loader warning otherwise) so the full-flow example is complete - Note that until_bash substitution DOES shell-quote $nodeId.output (unlike script bodies) — called out since the audit surfaced this inconsistency * fix(skill/cli): complete the CLI command reference with missing lifecycle commands The CLI reference previously documented only list, run, cleanup, validate, complete, version, setup, and chat — missing nearly every workflow lifecycle command an agent needs to operate a paused, failed, or stuck run. The interactive-workflows reference assumed these commands existed without actually documenting them. Adds full documentation for: - archon workflow status — show running workflow(s) - archon workflow approve <run-id> [comment] — resume approval gate (also populates $LOOP_USER_INPUT on interactive loops and the gate node's output when capture_response: true) - archon workflow reject <run-id> [reason] — reject gate; cancels or triggers on_reject rework depending on node config - archon workflow cancel <run-id> — terminate running/paused with in-flight subprocess kill - archon workflow abandon <run-id> — mark stuck row cancelled without subprocess kill (for orphan-cleanup after server crashes — matches the coleam00#1216 precedent) - archon workflow resume <run-id> [message] — force-resume specific run (auto-resume is default; this is for explicit override) - archon workflow cleanup [days] — disk hygiene for old terminal runs (with explicit callout that it does NOT transition 'running' rows, a common confusion) - archon workflow event emit — used inside loop prompts for state signalling; documented so agents don't invent their own mechanism - archon continue <branch> [flags] [msg] — iterative-session entry point with --workflow and --no-context flags Also: - Adds --allow-env-keys flag to the `workflow run` flag table with audit-log context and the env-leak-gate remediation use case - Adds an "Auto-resume without --resume" note disambiguating when --resume is needed vs. when auto-resume handles it - Adds --include-closed flag to `isolation cleanup`, which was previously missing; converts the flag list to a structured table - Explains the cancel/abandon distinction (live subprocess vs. orphan) All grounded in packages/cli/src/commands/workflow.ts, continue.ts, and isolation.ts. * feat(skill/repo-init): add scripts/ and state/, three-path env model, per-project env injection The repo-init reference was missing two first-class .archon/ directories (scripts/ since v0.3.3, state/ since the workflow-state feature) and had nothing to say about env — the #1 thing a user hits on first-run when their repo has a .env file with API keys. Directory tree updates: - Adds .archon/scripts/ with the extension->runtime rule (.ts/.js -> bun, .py -> uv) so agents know where to put named scripts referenced by script: nodes. - Adds .archon/state/ with explicit "always gitignore" callout — these are runtime artifacts, not source. Previously undocumented in the skill. - Adds .archon/.env (repo-scoped Archon env) and distinguishes it from the target repo's top-level .env. - Adds a "What each directory is for" list so the structure isn't just a tree with no narrative. .gitignore guidance: - state/ and .env added as must-gitignore (state/ matches CLAUDE.md and reference/archon-directories.md — skill was lagging). - mcp/ demoted to conditional — gitignore only if you hardcode secrets. New "Three-Path Env Model" section: - ~/.archon/.env (trusted, user), <cwd>/.archon/.env (trusted, repo), <cwd>/.env (UNTRUSTED, target project — stripped from subprocess env). - Precedence (override: true across archon-owned paths) and the observable [archon] loaded N keys / stripped K keys log lines so operators can verify what actually happened. - Decision tree for where to put API keys vs. target-project env vs. things Archon shouldn't touch. - Links to archon setup --scope home|project with --force for writing to the right file with timestamped backups. New "Per-Project Env Injection" section: - Documents both managed surfaces: .archon/config.yaml env: block (git-committed, $REF expansion) and Web UI Settings → Projects → Env Vars (DB-stored, never returned over API). - Names every execution surface that receives the injected vars: Claude/Codex/Pi subprocess, bash: nodes, script: nodes, and direct codebase-scoped chat. - Documents the env-leak gate with all 5 remediation paths so an agent hitting "Cannot register: env has sensitive keys" knows the options. Grounded in CHANGELOG v0.3.7 (three-path env + setup flags), v0.3.0 (env-leak gate), and reference/security.md on the docs site. * fix(skill/authoring-commands): correct override paths and add home-scoped commands The file-location and discovery sections described an override layout that does not match the actual resolver. It showed: .archon/commands/defaults/archon-assist.md # Overrides the bundled and claimed `.archon/commands/defaults/` was where repo-level overrides lived. In fact the resolver (executor-shared.ts:152-200 + command- validation.ts) walks `.archon/commands/` 1 level deep and uses basename matching — putting `archon-assist.md` at the top of `.archon/commands/` is the canonical way to override the bundled version. The `defaults/` subfolder is a Archon-internal convention for shipping bundled defaults, not a user-facing override pattern. Also, home-scoped commands (`~/.archon/commands/`, shipped in v0.3.7) were completely absent — agents authoring personal helpers wouldn't know they could live at the user level and be shared across every repo. Changes: - File Location section now shows all three discovery scopes (repo, home, bundled) with precedence ordering and 1-level subfolder rules - Duplicate-basename rule documented as a user error surface - Discovery and Priority section rewritten with accurate 3-step lookup order — no more references to the nonexistent defaults/ override path - Adds the Web UI "Global (~/.archon/commands/)" palette label note so users authoring helpers for the builder know what to expect No code changes — this is a pure fix of stale/incorrect skill reference material. * feat(skill): add workflow good-practices and troubleshooting reference pages Closes two gaps from the audit. The skill previously had zero guidance on designing multi-node workflows (what to avoid, what to reach for first, how to structure artifact chains) and zero guidance on where to look when things go wrong (log paths, env-leak gate remediations, orphan-row cleanup, resume semantics). New references/good-practices.md (9 Good Practices + 7 Anti-Patterns): - Use deterministic nodes (bash:/script:) for deterministic work, AI for reasoning — the single biggest quality lever - output_format required whenever downstream when: reads a field — the most common source of "workflow silently routes wrong" - trigger_rule: none_failed_min_one_success after conditional branches — the classic bug where all_success fails because a skipped when:-gated branch doesn't count as a success - context: fresh requires artifacts for state passing — commands must explicitly "read $ARTIFACTS_DIR/..." when downstream of fresh - Cheap models (haiku) for glue, strong for substance - Workflow descriptions as routing affordances - Validate (archon validate workflows) + smoke-run before shipping - Artifact-chain-first design - worktree.enabled: true for code-changing workflows (reversibility) - Anti-patterns with before/after YAML examples for each (AI-for-tests, free-form when: matching, context: fresh without artifacts, long flat AI-node layers, secrets in YAML, retry on loop nodes, tiny max_iterations, missing workflow-level interactive:, tool-restricted MCP nodes) New references/troubleshooting.md: - Log location (~/.archon/workspaces/<owner>/<repo>/logs/<run-id>.jsonl) with jq recipes for common queries (last assistant message, failed events, full stream) - Artifact location for cross-node handoff debugging - 9 Common Failure Modes, each with root cause + concrete fix: - $BASE_BRANCH unresolvable - Env-leak gate (5 remediations) - Claude/Codex binary not found (compiled-binary-only) - "running" forever (AI working / orphan / idle_timeout) - Mid-workflow failure and auto-resume semantics - Approval gate missing on web UI (workflow-level interactive:) - MCP plugin connection noise (filtered by design) - Empty $nodeId.output / field access (4 causes) - Diagnostic command cheat sheet (list, status, isolation list, validate, tail-log, --verbose, LOG_LEVEL=debug) - Escalation protocol (version + validate + log tail + CHANGELOG + issue) SKILL.md routing table now dispatches "Workflow good practices / anti-patterns" and "Troubleshoot a failing / stuck workflow" to the new references so an agent can find them without having to know they exist. * docs(book): update node-types coverage from four to all seven The book is the curated first-contact reading path (landing page → "Get Started" → /book/). Both dag-workflows.md and quick-reference.md were stuck on "four node types" — missing script, approval, and cancel. A user reading the book as their first introduction would form an incomplete mental model, then find three more node types in the reference section later with no explanation of when they arrived. book/dag-workflows.md: - "four node types" → "seven node types. Exactly one mode field is required per node" - Table now lists Command, Prompt, Bash, Script, Loop, Approval, Cancel with one-line "when to use" for each, and cross-links to the dedicated guide pages for Script / Loop / Approval - New sections below the table for Script (inline + named examples with runtime and deps), Approval (with the interactive: true workflow-level note that's easy to miss), and Cancel (guarded-exit pattern) — keeping the existing narrative shape for Bash and Loop book/quick-reference.md: - Node Options table now includes script, approval, cancel rows - agents row added (inline sub-agents, Claude-only) - New "Script-specific fields" and "Approval-specific fields" subsections so the cheat-sheet is actually complete rather than pointing users elsewhere for the required constraints - Retry row callout that loop nodes hard-error on retry — previously omitted - bash timeout note widened to cover script timeout (same semantics) Both files are docs-web content; the CI build on the docs-script-nodes PR (coleam00#1362) previously validated the Starlight build path with a similar table addition, so this should render clean. * fix(skill/cli): remove nonexistent \`archon workflow cancel\`, fix workflow status jq recipe Two accuracy issues from the PR code-reviewer (comment 4311243858). C1: \`archon workflow cancel <run-id>\` does NOT exist as a CLI subcommand. The switch at packages/cli/src/cli.ts:318-485 dispatches on list / run / status / resume / abandon / approve / reject / cleanup / event — running \`archon workflow cancel\` hits the default case and exits with "Unknown workflow subcommand: cancel" (cli.ts:478-484). Active cancellation is only available via: - /workflow cancel <run-id> chat slash command (all platforms) - Cancel button on the Web UI dashboard - POST /api/workflows/runs/{runId}/cancel REST endpoint cli-commands.md: removed the \`### archon workflow cancel <run-id>\` subsection; kept the \`abandon\` subsection but made it explicit that abandon does NOT kill a subprocess. Added a call-out box at the bottom of the abandon section explaining where to go for actual cancellation. troubleshooting.md "running forever" section: split the original cancel-vs-abandon advice into three bullets — Web UI / CLI abandon (for orphans, no subprocess kill) / chat \`/workflow cancel\` (for live runs that need interruption). Added an explicit "there is no archon workflow cancel CLI subcommand" parenthetical since the wrong command was being suggested in flow. I1: the \`archon workflow list --json\` diagnostic used an incorrect jq filter. workflow list's --json output (workflow.ts:185-219) has shape { workflows: [{ name, description, provider?, model?, ... }], errors: [...] } with no \`runs\` field — \`jq '.workflows[] | select(.runs)'\` returns empty unconditionally. Replaced with \`archon workflow status --json | jq '.runs[]'\`, which matches the actual shape of workflowStatusCommand at workflow.ts:852+ ({ runs: WorkflowRun[] }). Also tightened the narration to distinguish JSON from human-readable status output. No change to the commit history in this PR — these are follow-up fixes to claims I introduced in earlier commits of this branch (f10b989 for C1, 66d2b86 for I1). * fix(skill): remove env-leak gate references (feature was removed in provider extraction) C2 from the PR code-reviewer (comment 4311243858). The pre-spawn env-leak gate was removed from the codebase during the provider-extraction refactor — see TODO(coleam00#1135) at packages/providers/src/claude/provider.ts:908. Zero hits for --allow-env-keys / allowEnvKeys / allow_env_keys / allow_target_repo_keys across packages/. The CLI's parseArgs (cli.ts:182-208) has no --allow-env-keys option, and because parseArgs uses strict: false, an unknown --allow-env-keys would be silently ignored rather than error. What remains accurate and is NOT touched: - Three-Path Env Model section (user/repo archon-owned envs are loaded; target repo <cwd>/.env keys are stripped from process.env at boot) still correctly describes current behavior, grounded in packages/paths/src/strip-cwd-env.ts + env-integration.test.ts - Per-Project Env Injection section (Option 1: .archon/config.yaml env: block; Option 2: Web UI Settings → Projects → Env Vars) is unchanged — both remain the sanctioned way to get env vars into subprocesses Removed claims (all three files): - cli-commands.md: --allow-env-keys flag row in the workflow run flags table - repo-init.md: the "Env-leak gate" subsection at the end of Per-Project Env Injection listing 5 remediations (all of which reference UI/CLI/ config surfaces that don't exist). Replaced with a succinct callout that explains the actual current behavior — target repo .env keys are stripped, workflows that need those values should use managed injection — so the reader still gets the "where to put my env vars" answer - troubleshooting.md: the "Cannot register: codebase has sensitive env keys" section (error message that can no longer be emitted) If the env-leak gate is ever resurrected per TODO(coleam00#1135), the docs can be re-added then. The CHANGELOG v0.3.0 entry describing the gate is a historical record of past behavior and does not need to be rewritten. * fix(skill/troubleshooting): correct JSONL event type names and field name C3 from the PR code-reviewer (comment 4311243858). The troubleshooting reference's event-types table used _started / _completed / _failed suffixes, but packages/workflows/src/logger.ts:19-30 shows the actual WorkflowEvent.type enum is: workflow_start | workflow_complete | workflow_error | assistant | tool | validation | node_start | node_complete | node_skipped | node_error The second jq recipe also queried `.event` but the discriminator is `.type`. Fixes: - Event table: renamed columns (_started → _start, _completed → _complete, _failed → _error). Explicitly called out the field name as `type` so the reader knows what jq selector to use - Replaced the "tool_use / tool_result" row with a single `tool` row and listed its actual payload fields (tool_name, tool_input, duration_ms, tokens) — tool_use/tool_result are SDK message kinds that appear within the AI stream, not top-level log event types - Added a `validation` row (was missing; it's emitted by workflow-level validation calls with `check` and `result` fields) - Removed `retry_attempt` row — this event type is not emitted to the JSONL file. Retry bookkeeping goes through pino logs, not the workflow log file - Added an explicit callout that loop_iteration_started / loop_iteration_completed (and other emitter-only events) go through the workflow event emitter + DB workflow_events table, NOT the JSONL file. Pointed readers to the DB or Web UI for loop-level detail. This distinguishes the two parallel event systems — easy to conflate (store.ts:11-17 uses _started/_completed/_failed for the DB side, logger.ts uses _start/_complete/_error for JSONL) - Fixed the "all failed events" jq recipe: .event → .type and _failed → _error - Minor cleanup: the inline "tool_use events" mention in the "running forever" section said the wrong event name — updated to "tool or assistant events in the tail" Grounded in packages/workflows/src/logger.ts (canonical JSONL event shape) and packages/workflows/src/store.ts (the parallel DB event naming, which the reviewer correctly flagged as different and worth keeping distinct). * fix(skill): two stragglers from the code-reviewer audit Cleanup of two references that slipped through the earlier C1 and C3 fixes: - references/troubleshooting.md:126: \`node_failed\` → \`node_error\` (the "Node output is empty" diagnostics section references the JSONL log, which uses the logger.ts enum — not the DB workflow_events table which does use \`node_failed\`). The C3 fix corrected the event table and one jq recipe but missed this inline mention. - references/interactive-workflows.md:106: removed \`archon workflow cancel <run-id>\` (nonexistent CLI subcommand) from the troubleshooting bullet. This was pre-existing before the hardening PR but fell within the C1 remediation scope. Replaced with the correct triage: reject (approval gate only) vs abandon (orphan cleanup, no subprocess kill) vs chat /workflow cancel (actual subprocess termination). Grounded in the same sources as the earlier C1/C3 commits: packages/cli/src/cli.ts:318-485 (no cancel case) and packages/workflows/src/logger.ts:19-30 (JSONL type enum). * feat(skill): point to archon.diy as the canonical docs source The skill had no reference to archon.diy (the live docs site built from packages/docs-web/). Several reference files said "see the docs site" without naming the URL, leaving the agent to guess or grep the repo for the hostname. An agent with the skill loaded should know that when the distilled reference pages don't cover a case, the full canonical docs are one WebFetch away. SKILL.md: new "Richer Context: archon.diy" section between Routing and Running Workflows. Covers: - When to reach for the live docs (longer examples, tutorial framing, features the skill only mentions in passing, "where's that documented?" user questions) - URL map — 13 starting points covering getting-started, book (tutorial series), guides/ (authoring + per-node-type + per-node-feature), reference/ (variables, CLI, security, architecture, configuration, troubleshooting), adapters/, deployment/ - Precedence: skill refs first (context-cheap, tuned for agents), docs site as escalation. Prevents agents defaulting to WebFetch when a local skill ref already covers the answer Also upgrades the 5 existing generic "docs site" mentions across reference files to concrete archon.diy URLs with anchor fragments where helpful: - good-practices.md: Inline sub-agents pattern → archon.diy/guides/ authoring-workflows/#inline-sub-agents - troubleshooting.md: "Install page on the docs site" → archon.diy/ getting-started/installation/ - workflow-dag.md: "Workflow Description Best Practices" → anchor link; sandbox schema reference → archon.diy/guides/authoring-workflows/ #claude-sdk-advanced-options - repo-init.md: Security Model reference → archon.diy/reference/ security/#target-repo-env-isolation (deep-link into the section that covers the <cwd>/.env strip behavior) URL source of truth: astro.config.mjs:5 (site: 'https://archon.diy'). URL structure mirrors packages/docs-web/src/content/docs/<section>/ <page>.md — verified by the 62 pages the docs build produces. * docs/skill: add parameter-matrix.md quick-lookup reference New reference for the archon skill: a single-glance lookup of which parameter works on which node type, an intent-based "how do I..." table, a consolidated silent-failure catalog, and an inline agents: section (previously only referenced via archon.diy). Purpose is complementary, not duplicative: - workflow-dag.md remains the authoring guide - dag-advanced.md remains the hooks/MCP/skills/retry deep-dive - good-practices.md remains the patterns and anti-patterns - parameter-matrix.md is the grep-this-first lookup when you know the outcome you want but not which field gets you there Also registers the new reference in SKILL.md routing table. * feat(cli): setup overhaul + archon doctor + complete bundled skill (coleam00#1566) * feat(cli): setup overhaul + archon doctor + complete bundled skill (coleam00#1494) Make binary installs the official primary path. Setup wizard becomes a dead-simple "AI + skippable adapters" flow, the embedded skill ships all 21 files, and `archon doctor` provides a canonical "is my setup OK?" checklist. Changes: - bundled-skill.ts: embed all 21 .claude/skills/archon/ files (was 18, missing good-practices.md, parameter-matrix.md, troubleshooting.md) - scripts/check-bundled-skill.ts: CI guard that fails when bundled-skill.ts drifts from .claude/skills/archon/; wired into `bun run validate` - setup.ts: remove database prompt (SQLite implicit), remove Discord, validate Claude binary via spawn test, probe `gh auth status` and optionally run `gh auth login`, add Telegram security note + empty- allowlist warning, append update instructions and offer to run `archon doctor` at the end - doctor.ts: new `archon doctor` command — green/red checklist for Claude binary, gh auth, database, workspace writability, bundled defaults, and adapter token pings (best-effort) - cli.ts: register `doctor` and add to noGitCommands - doctor.test.ts: spyOn-based tests for individual check functions - setup.test.ts: drop SetupConfig.database and platforms.discord references, anchor DATABASE_URL assertion to line start Closes coleam00#1494 * fix: address review findings from PR coleam00#1566 - Fix checkWorkspaceWritable false negative: separate try/catch for rmSync so a cleanup failure never reports the directory as unwritable - Fix collectGitHubConfig empty catch: distinguish gh-not-installed (ENOENT) from gh-not-authenticated with actionable error messages - Check spawnSync('gh', ['auth', 'login']) return value and warn if spawn fails - Fix three stacked JSDoc blocks in setup.ts: restore orphaned JSDoc to collectClaudeBinaryPath and collectClaudeAuth, keep only correct block above probeClaudeBinarySpawns - Fix doctorCommand allSettled rejection handler: use String(s.reason) for non-Error rejections instead of producing "undefined" output; add log.error - Fix checkSlack/checkTelegram catch label: drop "network error: " prefix so JSON parse failures aren't mischaracterized - Fix "Skip silently" wording in doctor.ts: visible output contradicted "silently" - Fix doctor.test.ts module comment: BUNDLED_IS_BINARY is not spied, clarify - Add checkBundledDefaults test: passes in dev mode without mocks - Update CLAUDE.md: fix validate description "five" → "six" checks, add check:bundled-skill; add archon doctor to CLI section - Update docs-web cli.md: add doctor command section after setup - Add comment to check-bundled-skill.ts documenting substring check limitation * simplify: trim doctor.ts JSDoc and remove redundant existsSync check - Remove 12-line file JSDoc that restated the obvious; keep only the non-obvious setup-invocation note - Drop existsSync() guard before execFileAsync() — TOCTOU-prone and redundant since the catch block already produces a clear error - Collapse verbose allSettled comment to one line * feat(setup): bootstrap project-scoped .archon/config.yaml on skill install `archon setup` previously copied the Claude skill into the user's project but did not create a `.archon/` directory or a project config there. A fresh user who wanted any project-scoped override (per-project assistant defaults, custom docs path, etc.) had to `mkdir -p .archon` and create config.yaml by hand — exactly the friction the v0.3.11 setup overhaul was meant to remove. Add `bootstrapProjectConfig(projectPath)` and call it after the skill install. Writes a commented-out starter `.archon/config.yaml` with example keys and a link to the configuration reference. Idempotent on re-run (skips if the file already exists). Workflows/commands/scripts subdirectories are intentionally not created — empty dirs would clutter users' trees and the loaders handle their absence cleanly. The wizard's final summary now shows the created config path so the user knows where to put per-project overrides. Tests: - creates `.archon/config.yaml` when missing - creates the `.archon` directory if absent - is idempotent — leaves an existing user config untouched - returns failed state without throwing on unwritable target * fix: address multi-agent review findings from PR coleam00#1566 Production correctness: - setup.ts: gh auth login now checks .status !== 0 so a non-zero exit (cancelled OAuth, failed callback) is surfaced instead of silently succeeding. - setup.ts: probeClaudeBinarySpawns returns {ok, reason}; the warning now includes the actual spawn error (ENOENT/timeout/permissions). - setup.ts: bootstrapProjectConfig uses writeFileSync flag 'wx' and catches EEXIST, eliminating the TOCTOU window between existsSync and the write. - doctor.ts: split checkDatabase into module-load vs query try-catches so a missing @archon/core stops masquerading as "Database not reachable". Both branches now log structured errors. - doctor.ts: checkWorkspaceWritable rmSync catch logs warn so repeated delete failures leave a diagnostic trace. - cli.ts: doctor case uses a static import to match every other peer command. Tests: - checkClaudeBinary covers all four branches via an injected isBinary parameter (skip / no-path / spawn-pass / spawn-fail). - checkDatabase covers sqlite + postgres pass, query failure, and module-load failure via injectable loadDeps. - checkSlack / checkTelegram cover pass / fail / network-error->skip via spyOn(globalThis, 'fetch'). - checkGhAuth gains an explicit GH_TOKEN-only branch. - doctorCommand asserts the exit-code contract (0 on all-pass, 1 on any fail, thrown checks counted) and Promise.allSettled non-short- circuit, via injectable check thunks. Docs: - cli.md: doctor added to the no-git command list. - CLAUDE.md: validate now mentions check:bundled-skill alongside check:bundled. - overview.md: archon doctor row added to the CLI command table. - troubleshooting.md: points users at archon doctor after setup. * chore(changelog): document Tier 5 setup overhaul cherry-pick batch (3 commits) Adds CHANGELOG entries under [Unreleased]: - Changed: setup wizard simplified to AI + skippable adapters (notes Discord/Postgres still runtime-supported via .env, just dropped from the interactive wizard). - Fixed: 3 commits picked - 2c15439 — skill docs hardening (good-practices.md, troubleshooting.md, expanded workflow-dag.md) - 9122673 — parameter-matrix.md reference - 5e61faf — archon doctor + setup overhaul + complete bundled skill (coleam00#1566, deferred from PR #4) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Rasmus Widing <152263317+Wirasm@users.noreply.github.com> Co-authored-by: Cole Medin <cole@dynamous.ai> Co-authored-by: cjnprospa <sirhcle.j23@gmail.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
bundled-skill.tsonly embeds 18 of 21 skill files; no CI check catches regressions. The setup wizard presents a database prompt (irrelevant — SQLite only), Discord (community-gated), and all platform adapters as mandatory, inflating setup from ~2 required steps to 8+. Noarchon doctorcommand exists.bundled-skill.tsto embed all 21 files + addedcheck:bundled-skillCI guard. Rewrotearchon setupto remove DB step, remove Discord, make each adapter skippable with explicit "Archon works without this" messaging, validate Claude binary via spawn test, addgh auth statuscheck for GitHub, add security note for Telegram, and show update instructions + doctor offer at the end. Addedarchon doctorcommand with a green/red checklist.UX Journey
Before
After
Architecture Diagram
Before
After
Connection inventory:
cli.tscommands/doctor.tscase 'doctor':commands/setup.tscommands/doctor.tscommands/doctor.ts@archon/pathsBUNDLED_IS_BINARY,getArchonHomecommands/doctor.ts@archon/gitexecFileAsyncfor binary + gh probescommands/doctor.ts@archon/core/dbcommands/setup.ts@archon/gitexecFileAsyncfor spawn test + gh authscripts/check-bundled-skill.ts.claude/skills/archon/package.jsonvalidate scriptcheck-bundled-skillLabel Snapshot
risk: lowsize: Mclicli:setup,cli:doctor,cli:bundled-skillChange Metadata
featurecliLinked Issue
Validation Evidence (required)
All five checks passed (EXIT=0):
bun run check:bundledbun run check:bundled-skillbun run type-check(all 10 packages)bun run lint --max-warnings 0bun run format:checkbun run test(all packages)Smoke test:
bun --cwd packages/cli src/cli.ts doctor # Output: 5 ✓ checks, 4 ○ skips, 0 ✗ failuresbun run validaterun with exit 0; smoke test ofarchon doctorin dev modeSecurity Impact (required)
archon doctormakes optional network probes (Slackauth.test, TelegramgetMe) using existing configured tokens. No new token collection.archon doctoroptionally pings Slack/Telegram APIs (best-effort, degrade toskipon failure; only run when tokens are already in env)ARCHON_HOMEthen immediately deletes it (writable check)Promise.allSettled— network failures produceskipnotfail.gh auth loginis TTY-gated (process.stdout.isTTY) to prevent hangs in CI.Compatibility / Migration
.envfiles are untouched.check:bundled-skillis a new script but not user-facing config.Human Verification (required)
bun run cli doctorin dev context (5 ✓ checks, 4 ○ skips); fullbun run validatesuite passing; type-check across all 10 packagesBUNDLED_IS_BINARY = false→ Claude check skips cleanly;GITHUB_TOKENnot set → gh auth check skips; empty Telegram allowlist path in setup confirmed to show warning via code reviewarchon setupend-to-end in a fresh install (requires a real binary build);gh auth logininteractive flow (TTY-gated code path)Side Effects / Blast Radius (required)
@archon/cli(setup, doctor, bundled-skill), rootpackage.json,scripts/bun run validatenow takes slightly longer due tocheck:bundled-skillstep (negligible — file scan only). RemovingcollectDatabaseConfigfrom setup means any code path that relied onSetupConfig.databasewill fail to compile — all such paths were updated.check:bundled-skillin CI catches any futurebundled-skill.tsdrift immediatelyRollback Plan (required)
git revert b1c49a53— reverts all changes in this PR atomicallyarchon setupshowing database prompt or Discord = rollback needed;check:bundled-skillexiting 2 = bundled-skill.ts out of syncRisks and Mitigations
Risk:
setup.tstype errors after removingdatabasefromSetupConfigcascade togenerateEnvContentandcheckExistingConfigbun run type-checkpasses clean across all 10 packagesRisk:
spawnSync('gh', ['auth', 'login'])hangs in non-TTY environments (CI, piped shells)process.stdout.isTTY— thegh auth logincall is never reached in non-TTY contextsRisk: Adapter pings (Slack, Telegram) fail in environments with restricted outbound network access
Promise.allSettled; network errors produceskipnotfailin doctor outputSummary by CodeRabbit
New Features
archon doctorcommand to diagnose environment setup (Claude binary, authentication, database, adapters).Documentation
doctorcommand details.