
Archon
- 157 installs
- 18 repo stars
- Updated May 3, 2026
- coleam00/archon-video-generation-workflow
Runs, creates, and configures Archon AI workflows that execute in isolated git worktrees for parallel development via the archon CLI.
About
Routes user intent to run Archon workflows, author workflow/command YAML, or manage Archon setup and config, delegating work to the archon CLI. A developer uses it to run or build agentic coding workflows.
- Runs AI workflows in isolated git worktrees
- Intent-routing table to setup, config, and authoring guides
Archon by the numbers
- 157 all-time installs (skills.sh)
- Ranked #3,243 of 16,556 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Jul 29, 2026 (Skillselion catalog sync)
npx skills add https://github.com/coleam00/archon-video-generation-workflow --skill archonAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 157 |
|---|---|
| repo stars | ★ 18 |
| Last updated | May 3, 2026 |
| Repository | coleam00/archon-video-generation-workflow ↗ |
What it does
Runs, creates, and configures Archon AI workflows that execute in isolated git worktrees for parallel development via the archon CLI.
Files
Archon CLI Skill
Archon is a remote agentic coding platform that runs AI workflows in isolated git worktrees. This skill teaches you how to run workflows, create new workflows and commands, and manage Archon configuration.
Available Workflows (live)
!archon workflow list 2>&1 || echo "Archon CLI not installed. Read guides/setup.md to set it up."
Routing
Determine the user's intent and dispatch to the appropriate guide:
| Intent | Action |
|---|---|
| Setup / install / "how to use" | Read guides/setup.md — interactive setup wizard |
| Config / settings | Read guides/config.md — interactive config editor |
| Initialize .archon/ in a repo | Read references/repo-init.md |
| Create a workflow | Read references/workflow-dag.md — the complete workflow authoring guide |
| Advanced features (hooks/MCP/skills) | Read references/dag-advanced.md |
| Create a command file | Read references/authoring-commands.md |
| Variable substitution reference | Read references/variables.md |
| CLI command reference | Read references/cli-commands.md |
| Run an interactive workflow | Read references/interactive-workflows.md — transparent relay protocol |
| Run a workflow (default) | Continue with "Running Workflows" below |
If the intent is ambiguous, ask the user to clarify.
---
Running Workflows
Core Command
archon workflow run <workflow-name> --branch <branch-name> "<message>"CRITICAL RULES:
1. Always run in background — Archon workflows are long-running. Always invoke the Bash tool with run_in_background: true. Use /tasks or the TaskOutput tool to check on progress.
2. Always use worktree isolation — Use the --branch flag unless the user explicitly requests otherwise. This creates an isolated environment so Archon works without affecting the main branch.
3. One workflow per shell — Each workflow blocks its shell. Run multiple workflows as separate background tasks.
Isolation Modes
| Mode | Flag | When to Use |
|---|---|---|
| Worktree (Default) | --branch <name> | Always use this unless told otherwise |
| Custom start-point | --branch <name> --from <base> | Start from a specific branch |
| Direct checkout | --no-worktree | Only if user explicitly requests no isolation |
| Resume failed run | --resume | Resume from the last failure point |
Workflow Selection
Match the user's intent to a workflow from the live list above. Common patterns:
| User Intent | Typical Workflow | Branch Pattern |
|---|---|---|
| "Fix issue #X" / "Resolve bug" | archon-fix-github-issue | fix/issue-{N} |
| "Review PR #X" / "Full review" | archon-comprehensive-pr-review | review/pr-{N} |
| "Quick review PR #X" | archon-smart-pr-review | review/pr-{N} |
| "Validate PR #X" / "Check PR" | archon-validate-pr | review/pr-{N} |
| "Implement from plan" | archon-feature-development | feat/{name} |
| "Plan and implement feature" | archon-idea-to-pr | feat/{name} |
| "Execute plan file" | archon-plan-to-pr | feat/{name} |
| "Run ralph" / "Implement PRD" | archon-ralph-dag | feat/{name} |
| "Resolve conflicts" | archon-resolve-conflicts | resolve/pr-{N} |
| "Create issue" / "File a bug" | archon-create-issue | issue/{name} |
| "Review issue #X fully" | archon-issue-review-full | review/issue-{N} |
| "Refactor safely" | archon-refactor-safely | refactor/{name} |
| "Architecture review" | archon-architect | review/{name} |
| "PIV loop" / "guided dev" | archon-piv-loop ⚡ | piv/{name} |
| "Create a PRD" / "interactive PRD" | archon-interactive-prd ⚡ | prd/{name} |
| General / debugging | archon-assist | assist/{description} |
⚡ = Interactive workflow — requires the transparent relay protocol. Read references/interactive-workflows.md before running.
If no specific workflow matches, use archon-assist as the fallback. The live workflow list above is always authoritative — it may include workflows not in this table.
Multi-Issue Invocation
When the user mentions multiple issues, PRs, or tasks — run each as a separate background task:
# Each gets its own worktree — they won't conflict
archon workflow run archon-fix-github-issue --branch fix/issue-10 "Fix issue #10"
archon workflow run archon-fix-github-issue --branch fix/issue-11 "Fix issue #11"
archon workflow run archon-fix-github-issue --branch fix/issue-12 "Fix issue #12"Never combine multiple issues into a single command.
---
Other CLI Commands
archon workflow list # List all available workflows
archon workflow list --json # Machine-readable JSON
archon isolation list # Show active worktree environments
archon isolation cleanup # Remove stale worktrees (default: 7 days)
archon isolation cleanup --merged # Remove branches merged into main
archon complete <branch> # Complete branch lifecycle (remove worktree + branches)
archon version # Show version infoFor the full CLI reference with all flags: Read references/cli-commands.md
---
Authoring Quick Start
Archon uses a single workflow format: nodes (DAG). Workflows are YAML files in .archon/workflows/.
IMPORTANT: The examples below are starting points. Always design the workflow around what the user actually needs — the number of nodes, their types, dependencies, and configuration should match the user's requirements, not these templates.
Workflow Structure
name: my-workflow
description: What this workflow does
provider: claude # Optional: 'claude' or 'codex'
model: sonnet # Optional: model override
nodes:
- id: first-node
command: my-command # Loads .archon/commands/my-command.md
- id: second-node
prompt: "Use the output: $first-node.output"
depends_on: [first-node]Four Node Types
Each node has exactly ONE of: command, prompt, bash, or loop.
Command node — runs a .archon/commands/*.md file:
- id: investigate
command: investigate-issuePrompt node — inline AI prompt:
- id: classify
prompt: "Classify this issue: $ARGUMENTS"
model: haiku
allowed_tools: []Bash node — shell script, no AI, stdout captured as output:
- id: fetch-data
bash: "gh issue view 42 --json title,body"
timeout: 15000Loop node — iterates AI prompt until completion:
- id: implement
loop:
prompt: "Implement next story. When done: <promise>COMPLETE</promise>"
until: COMPLETE
max_iterations: 10
fresh_context: true
until_bash: "bun run test" # Optional: exit 0 = doneFor the full authoring guide with all fields, conditions, trigger rules, and patterns: Read references/workflow-dag.md
Creating a Command File
Commands are .md files in .archon/commands/ containing AI prompt templates:
---
description: What this command does
argument-hint: <expected arguments>
---
# My Command
User request: $ARGUMENTS
Workflow artifacts: $ARTIFACTS_DIR
[Instructions for the AI agent]For the full command authoring guide: Read references/authoring-commands.md
Key Variables
| Variable | Description |
|---|---|
$ARGUMENTS | User's input message |
$ARTIFACTS_DIR | Pre-created directory for workflow artifacts |
$BASE_BRANCH | Base branch (auto-detected from git) |
$WORKFLOW_ID | Unique workflow run ID |
$nodeId.output | Output from upstream node |
Full variable reference: Read references/variables.md
Advanced Features (Command/Prompt Nodes, Claude Only)
hooks (tool interception), mcp (external tool servers), skills (domain knowledge injection), output_format (structured JSON output), allowed_tools/denied_tools (tool restrictions).
For details: Read references/dag-advanced.md
Example Files
examples/dag-workflow.yaml— workflow with conditions, bash nodes, structured outputexamples/command-template.md— Command file skeleton with all variables
---
Example Interactions
User: "Use Archon to fix issue #42"
archon workflow run archon-fix-github-issue --branch fix/issue-42 "Fix issue #42"User: "Have Archon review PR #15"
archon workflow run archon-comprehensive-pr-review --branch review/pr-15 "Review PR #15"User: "Create a workflow that reviews code and runs tests" → Read references/workflow-dag.md and create a workflow with parallel review nodes.
User: "Make a workflow with conditional routing" → Read references/workflow-dag.md and create nodes with when: conditions and output_format.
User: "Write a command file for investigating bugs" → Read references/authoring-commands.md and create an .md file in .archon/commands/.
User: "Set up Archon in this repo" → Read references/repo-init.md to create the .archon/ directory structure.
User: "Initialize .archon and create a custom workflow" → First read references/repo-init.md, then the appropriate workflow reference.
Command Name
Workflow ID: $WORKFLOW_ID
---
Phase 1: LOAD
Gather context and inputs for this command.
- User request: $ARGUMENTS
- Read any artifacts from previous steps:
$ARTIFACTS_DIR/ - Base branch: $BASE_BRANCH
PHASE_1_CHECKPOINT
- [ ] User request understood
- [ ] Prior artifacts loaded (if any)
- [ ] Codebase context gathered
Phase 2: EXECUTE
Do the main work of this command.
[Replace this section with specific instructions for what the AI should do. Be precise about which tools to use, what files to examine, and what actions to take.]
PHASE_2_CHECKPOINT
- [ ] Main work completed
- [ ] Changes validated (type-check, lint, tests as appropriate)
Phase 3: GENERATE
Write artifacts for downstream steps.
Write your output to $ARTIFACTS_DIR/output.md with:
- Summary of what was done
- Key decisions made
- Any issues encountered
PHASE_3_CHECKPOINT
- [ ] Artifact written to
$ARTIFACTS_DIR/output.md - [ ] Artifact contains actionable information for the next step
Phase 4: REPORT
Provide a concise summary to the user:
1. What was accomplished 2. Key findings or decisions 3. Any blockers or warnings 4. Next steps (if part of a multi-step workflow)
# Example: Workflow with all four node types
#
# Demonstrates: bash nodes, structured output, when: conditions,
# trigger_rule, per-node model, context: fresh, loop nodes, and output substitution.
#
# IMPORTANT: This is a reference example. Design your actual workflow
# around the user's specific needs — the number of nodes, their types,
# dependencies, and configuration should match what the user requests.
#
# Run with:
# archon workflow run smart-issue-fix --branch fix/issue-42 "Fix issue #42"
name: smart-issue-fix
description: |
Classify a GitHub issue, then route to the appropriate handler.
Bugs get investigated; features get planned. Both paths merge at implementation.
provider: claude
nodes:
# ── BASH NODE: Shell script, no AI, stdout captured as output ──
- id: fetch-issue
bash: |
issue_num=$(echo "$ARGUMENTS" | grep -oE '/issues/[0-9]+' | grep -oE '[0-9]+' | head -1)
# Fallback: extract first number if no URL path found (e.g., "Fix issue #42")
if [ -z "$issue_num" ]; then
issue_num=$(echo "$ARGUMENTS" | grep -oE '[0-9]+' | head -1)
fi
if [ -n "$issue_num" ]; then
gh issue view "$issue_num" --json title,body,labels,comments
else
echo "No issue number found in: $ARGUMENTS"
exit 1
fi
timeout: 15000
- id: fetch-pr-template
bash: |
if [ -f .github/PULL_REQUEST_TEMPLATE.md ]; then
cat .github/PULL_REQUEST_TEMPLATE.md
else
echo "No PR template found"
fi
timeout: 5000
# ── PROMPT NODE: Inline AI prompt with structured output ──
- id: classify
prompt: |
Classify this GitHub issue:
$fetch-issue.output
Determine if this is a bug fix or a new feature.
depends_on: [fetch-issue]
model: haiku
allowed_tools: []
output_format:
type: object
properties:
issue_type:
type: string
enum: [bug, feature]
title:
type: string
severity:
type: string
enum: [low, medium, high, critical]
required: [issue_type, title]
# ── COMMAND NODE: Loads .archon/commands/<name>.md ──
- id: investigate
command: investigate-bug
depends_on: [classify]
when: "$classify.output.issue_type == 'bug'"
context: fresh
- id: plan
command: plan-feature
depends_on: [classify]
when: "$classify.output.issue_type == 'feature'"
context: fresh
# ── LOOP NODE: Iterates until completion or max iterations ──
- id: implement
depends_on: [investigate, plan]
trigger_rule: one_success
idle_timeout: 600000
loop:
prompt: |
You are implementing changes for: $classify.output.title
Read the investigation or plan artifacts from $ARTIFACTS_DIR.
Implement the next piece, validate with type-check and tests.
When all changes are complete and validated: <promise>DONE</promise>
until: DONE
max_iterations: 5
fresh_context: false
# ── Final node: create PR using template ──
- id: create-pr
prompt: |
Create a pull request for the changes.
Issue title: $classify.output.title
PR template: $fetch-pr-template.output
Implementation summary: $implement.output
Use `gh pr create` to create the PR. Link to the original issue.
depends_on: [implement, fetch-pr-template]
trigger_rule: none_failed_min_one_success
context: fresh
CLI Setup Guide
Steps to install and configure the Archon CLI. Always run these first.
1. Install Dependencies
cd <archon-repo> && bun installIf bun is not installed, direct the user to https://bun.sh and stop.
2. Link the CLI Globally
cd <archon-repo>/packages/cli && bun linkThis makes archon available as a global command from any directory.
3. Verify Installation
archon versionShould print the version number. If it fails, re-run step 2 and check that Bun's global bin directory is in $PATH.
4. Authenticate Claude
Check if Claude Code is installed:
which claudeIf not installed, direct the user to install Claude Code and stop.
If installed but not authenticated, run:
claude /loginThis stores credentials globally — no .env or API key needed for CLI usage.
Notes
- No `.env` required: CLI-only usage doesn't need any environment variables. If no API keys are in the environment, the CLI auto-defaults to global Claude auth from
claude /login. - Database: SQLite auto-creates at
~/.archon/archon.db— no setup needed for CLI-only use. - Config:
~/.archon/config.yamlis auto-created on first run with sensible defaults. Per-repo config can be added at<repo>/.archon/config.yamlto override the AI assistant or configure command folders. Neither file needs manual creation for basic usage.
Archon Configuration Guide
Interactive guide for viewing and modifying Archon configuration. Use this when the user wants to change, view, or understand their config — at any point, not just during initial setup.
Step 1: Determine Scope
Use AskUserQuestion to determine what the user wants to configure:
Header: "Config scope"
Question: "Which configuration do you want to modify?"
Options:
1. "Repo config" (Recommended) — Settings for a specific repository (.archon/config.yaml in the repo)
2. "Global config" — User-wide settings (~/.archon/config.yaml)
3. "Both" — Review and modify both configsStep 2: Load Current Config
For Global Config (~/.archon/config.yaml)
Read the file:
cat ~/.archon/config.yamlIf it doesn't exist, tell the user it will be auto-created on first Archon run with defaults. Offer to create it now.
For Repo Config (<repo>/.archon/config.yaml)
First determine the target repo. If the current working directory is a git repo (and not the Archon source repo), use it. Otherwise ask:
Header: "Target repo"
Question: "Which repository's config do you want to modify?"
Options:
1. "Current directory" — Use the repo at the current working directory
2. "I'll provide a path" — Type or paste a repo pathThen read the file:
cat <target-repo>/.archon/config.yamlIf it doesn't exist, tell the user: "No repo config found. I can create one — or Archon will use defaults." Offer to create it.
Step 3: Show Current State
Display the current configuration in a clear format. Show both the current values and what the defaults are, so the user knows what's customized vs default.
Format example:
Current repo config (.archon/config.yaml):
assistant: codex (default: claude)
worktree.baseBranch: develop (default: auto-detected)
worktree.copyFiles: [".env"] (default: none)
defaults.loadDefaultCommands: true (default)
defaults.loadDefaultWorkflows: true (default)Step 4: Interactive Modification
Ask the user what they want to change. Use AskUserQuestion based on the scope.
Global Config Options
Header: "Global option"
Question: "What would you like to change in the global config?"
Options:
1. "Bot name" — Display name shown in messages (current: {value}, default: Archon)
2. "Default assistant" — AI assistant for new repos (current: {value}, default: claude)
3. "Streaming modes" — How responses are delivered per platform
4. "Concurrency" — Max concurrent AI conversations (current: {value}, default: 10)If "Streaming modes" is selected, follow up with:
Header: "Platform"
Question: "Which platform's streaming mode do you want to change?"
Options:
1. "Telegram" — Current: {value} (default: stream)
2. "GitHub" — Current: {value} (default: batch)
3. "Slack" — Current: {value} (default: batch)
4. "Discord" — Current: {value} (default: batch)Then for the selected platform:
Header: "Mode"
Question: "Which streaming mode for {platform}?"
Options:
1. "stream" — Send tokens as they arrive (real-time updates)
2. "batch" — Send complete response at once (cleaner for GitHub/Slack)Repo Config Options
Header: "Repo option"
Question: "What would you like to change in the repo config?"
Options:
1. "AI assistant" — Which AI to use for this repo (current: {value}, default: claude)
2. "Worktree settings" — Base branch and file copying
3. "Default loading" — Whether to load bundled commands/workflows
4. "Commands folder" — Custom command folder pathIf "Worktree settings" is selected:
Header: "Worktree"
Question: "Which worktree setting?"
Options:
1. "Base branch" — Branch used as base for worktree creation (current: {value})
2. "Copy files" — Files to copy into new worktrees (current: {value})For "Copy files", let the user add/remove entries. Show current list and ask:
Header: "Copy files"
Question: "Current copyFiles: {list}. What do you want to do?"
Options:
1. "Add a file" — Add a new file to copy into worktrees
2. "Remove a file" — Remove one from the list
3. "Replace all" — Start fresh with a new listRemind the user about the "source -> destination" syntax for renaming (e.g., ".env.example -> .env").
If "Default loading" is selected:
Header: "Defaults"
Question: "Which default loading option?"
Options:
1. "Default commands" — Load bundled command templates at runtime (current: {value})
2. "Default workflows" — Load bundled workflow definitions at runtime (current: {value})Step 5: Apply Changes
After gathering changes, update the YAML file. Use the Edit tool to modify existing values or Write to create the file if it doesn't exist.
Rules:
- Only include non-default values in the file (keep it clean)
- Preserve existing comments
- Preserve any values the user didn't change
- Validate values before writing (e.g., assistant must be "claude" or "codex")
After writing, confirm: "Updated {path}. Changes take effect on the next Archon invocation (no restart needed for CLI)."
If the server is running for non-CLI platforms, note: "Server platforms (Telegram, Slack, GitHub, Discord) require a server restart to pick up config changes."
Step 6: Offer Further Changes
After applying changes, ask if the user wants to modify anything else:
Header: "More changes?"
Question: "Want to change anything else?"
Options:
1. "Done" — All set
2. "Change another option" — Go back to Step 4
3. "View final config" — Show the full config as it stands nowLoop back to Step 4 if they want more changes.
---
Reference: All Configuration Options
Global Config (~/.archon/config.yaml)
| Option | Type | Default | Description |
|---|---|---|---|
botName | string | Archon | Bot display name shown in messages |
defaultAssistant | claude \ | codex | claude |
streaming.telegram | stream \ | batch | stream |
streaming.discord | stream \ | batch | batch |
streaming.slack | stream \ | batch | batch |
paths.workspaces | string | ~/.archon/workspaces | Directory for cloned repositories |
paths.worktrees | string | ~/.archon/worktrees | Directory for git worktrees |
concurrency.maxConversations | number | 10 | Maximum concurrent AI conversations |
Repo Config (<repo>/.archon/config.yaml)
| Option | Type | Default | Description |
|---|---|---|---|
assistant | claude \ | codex | claude |
commands.folder | string | .archon/commands | Custom command folder path (relative to repo root) |
commands.autoLoad | boolean | true | Auto-load commands on clone |
worktree.baseBranch | string | auto-detected | Base branch for worktree creation |
worktree.copyFiles | string[] | [] | Files to copy into new worktrees (supports "source -> dest" renaming) |
defaults.loadDefaultCommands | boolean | true | Load bundled default commands at runtime |
defaults.loadDefaultWorkflows | boolean | true | Load bundled default workflows at runtime |
Precedence Order (highest wins)
1. Environment variables (.env or shell) — always win 2. Repo config (.archon/config.yaml in repo) — project-specific 3. Global config (~/.archon/config.yaml) — user-wide preferences 4. Defaults — hardcoded sensible values
Environment Variable Overrides
These env vars override any config file setting:
| Env Var | Overrides |
|---|---|
BOT_DISPLAY_NAME | botName |
DEFAULT_AI_ASSISTANT | defaultAssistant / assistant |
TELEGRAM_STREAMING_MODE | streaming.telegram |
DISCORD_STREAMING_MODE | streaming.discord |
SLACK_STREAMING_MODE | streaming.slack |
MAX_CONCURRENT_CONVERSATIONS | concurrency.maxConversations |
ARCHON_HOME | Base directory for all Archon paths |
Discord Bot Setup Guide
1. Create a Discord Application
1. Go to the Discord Developer Portal 2. Click New Application 3. Enter a name (e.g., "Archon Bot") and click Create
2. Create a Bot
1. In the left sidebar, click Bot 2. Click Reset Token to generate a new bot token 3. Copy the token — this is your DISCORD_BOT_TOKEN 4. Under Privileged Gateway Intents, enable:
- MESSAGE CONTENT INTENT (required to read message text)
3. Generate Invite URL
1. In the left sidebar, click OAuth2 2. Under OAuth2 URL Generator, select scopes:
bot
3. Under Bot Permissions, select:
- Send Messages
- Read Message History
- Use Slash Commands
4. Copy the generated URL and open it in your browser 5. Select your server and click Authorize
4. Get Your User ID
1. In Discord, go to Settings > Advanced > Developer Mode (enable it) 2. Right-click your username anywhere and click Copy User ID 3. This is your DISCORD_ALLOWED_USER_IDS
5. Add to .env (in the archon repo root)
DISCORD_BOT_TOKEN=<token from step 2>
DISCORD_ALLOWED_USER_IDS=<your user ID>
DISCORD_STREAMING_MODE=batchDISCORD_STREAMING_MODE=batchwaits for the full response (recommended for Discord).DISCORD_STREAMING_MODE=streamshows responses as they're generated.- Multiple user IDs can be comma-separated.
6. Start the Server
Follow the Server Setup Guide to start the server. The Discord adapter auto-starts when DISCORD_BOT_TOKEN is set.
7. Test
In the Discord channel where you invited the bot:
@Archon Bot /helpThe bot should respond with available commands.
GitHub Webhook Setup Guide
GitHub integration lets Archon respond to issue comments, PR comments, and @mentions via webhooks.
IMPORTANT — Freeform input rule: This guide collects URLs, tokens, and usernames. Never use AskUserQuestion for freeform text input (URLs, tokens, usernames, paths). Ask the user directly in plain text — e.g., "Paste the ngrok URL here." Use AskUserQuestion only for multiple-choice decisions.
0. Check Existing .env Values
Before starting, read the existing .env file and check which GitHub-related values are already populated:
cat <archon-repo>/.envCheck these keys: WEBHOOK_SECRET, GITHUB_TOKEN, GH_TOKEN, GITHUB_ALLOWED_USERS.
If all are already filled in: Tell the user "GitHub tokens are already configured in .env. Skipping to webhook setup." Jump to Step 5 (configure the repo webhook).
If some are filled in: Tell the user which values are already set and which are missing. Only collect the missing ones in the steps below.
If none are filled in: Proceed with all steps.
1. Set Up a Public URL (ngrok)
GitHub webhooks need to reach your local server. Check if ngrok is installed:
which ngrokIf not installed, use AskUserQuestion:
Header: "Install ngrok"
Question: "ngrok is not installed. Want me to install it via Homebrew?"
Options:
1. "Yes, install it" (Recommended) — runs `brew install ngrok`
2. "I'll install it myself" — user handles it, wait for confirmationIf yes, run:
brew install ngrokIf ngrok is not authenticated, check and guide:
ngrok config check 2>&1If it needs auth: 1. Tell the user: "Sign up at https://ngrok.com (free tier works), then copy your auth token from the dashboard." 2. Ask the user in plain text to paste the token, then run:
ngrok config add-authtoken <token>2. Start ngrok
Tell the user to run this in a separate terminal (ngrok must stay running):
Run this in another terminal: ngrok http 3090Then ask in plain text (NOT AskUserQuestion):
"Paste the ngrok HTTPS URL here (e.g., https://abc123.ngrok-free.app)."If the user pastes the full ngrok terminal output, parse the URL from the Forwarding line (the https://... URL before the -> arrow).
Store the URL as <ngrok-url>.
3. Generate a Webhook Secret
Only if `WEBHOOK_SECRET` is empty/missing in `.env`.
openssl rand -hex 32Store this as <webhook-secret>.
4. Collect GitHub Token and Username
Only collect values that are missing from `.env`.
Present all missing items together in a single message, then let the user respond. Do not ask one at a time.
For example, if both token and username are missing:
"I need two things from you:
1. GitHub token — Go to github.com/settings/tokens and create a fine-grained token with repository access for <target-repo> and permissions: Issues (R/W), Pull Requests (R/W), Contents (Read).2. GitHub username — Your GitHub username (used for authorization).
>
Paste them here when ready (token first, then username), or tell me you've added them to .env directly."If the user says they've already added values to .env, read the file to confirm and skip to the next step. Do not ask again for values the user says are already there.
5. Write to .env
Write only the missing values to .env. Do not overwrite existing values.
Values to set (if missing):
WEBHOOK_SECRET=<webhook-secret>
GITHUB_TOKEN=<token>
GH_TOKEN=<same token>
GITHUB_ALLOWED_USERS=<username>6. Configure the Repository Webhook
Tell the user to go to their target repo on GitHub > Settings > Webhooks > Add webhook and configure:
- Payload URL:
<ngrok-url>/webhooks/github - Content type:
application/json - Secret:
<webhook-secret>(the value from step 3, or the existing value from.env) - Select events: Issue comments + Pull request review comments (or "Send me everything")
- Click Add webhook
Use AskUserQuestion to confirm when done:
Header: "Webhook"
Question: "Have you added the webhook to your GitHub repo?"
Options:
1. "Done" — webhook is configured
2. "I need help" — walk me through it step by step7. Verify the Webhook
Start the server and test the webhook endpoint:
cd <archon-repo> && bun run dev &
sleep 3
curl -s http://localhost:3090/healthIf health check returns {"status":"ok"}, also verify the ngrok tunnel is forwarding:
curl -s <ngrok-url>/healthBoth should return {"status":"ok"}. If the ngrok check fails, make sure the ngrok terminal is still running.
Stop the background server when done verifying:
kill %1 2>/dev/nullNotes
- Free tier URLs change on restart — you'll need to update the webhook URL in GitHub each time you restart ngrok.
- Persistent URLs: Use a paid ngrok plan, Cloudflare Tunnel, or cloud deployment (see
docs/cloud-deployment.md). - Both the server (
bun run dev) and ngrok must be running for GitHub webhooks to work.
Server Setup Guide
Shared setup for all non-CLI platforms (Telegram, Slack, Discord, GitHub). Run the CLI setup first.
Important: The server runs from the archon repo root — not the target repo. The .env file should already exist there (created in Step 4 of the setup wizard).
1. Verify .env
Make sure .env exists in the archon repo root with the platform tokens from the platform-specific guides:
ls -la <archon-repo>/.envIf it doesn't exist yet:
cd <archon-repo> && cp .env.example .envThen add the platform tokens from the relevant platform guides.
2. Start the Development Server
cd <archon-repo> && bun run devThis starts the Hono server with hot reload. Platform adapters auto-start based on which tokens are present in .env.
3. Verify Server Health
curl http://localhost:3090/healthExpected response: {"status":"ok"}
4. Database
- SQLite (default): Auto-creates at
~/.archon/archon.db. No setup needed. - PostgreSQL (optional): Set
DATABASE_URLin.envand run migrations:
docker-compose --profile with-db up -d postgres
psql $DATABASE_URL < migrations/001_initial_schema.sql5. Running in Background
For persistent operation, choose one:
tmux/screen:
tmux new -s archon
cd <archon-repo> && bun run dev
# Ctrl+B, D to detachDocker (production):
cd <archon-repo> && docker-compose --profile with-db up -d --buildsystemd (Linux): Create a service file at /etc/systemd/system/archon.service pointing to bun run start.
Important Notes
- Only use one instance at a time per set of platform tokens — running multiple instances causes token conflicts.
- The server must be running for Telegram, Slack, Discord, and GitHub platforms to work.
- CLI workflows work independently and do not require the server.
- Configuration:
~/.archon/config.yamlis auto-created on first run with sensible defaults. Environment variables in.envoverride matching config values (e.g.,TELEGRAM_STREAMING_MODEoverridesstreaming.telegram).
Archon Setup Wizard
Interactive setup guide. Follow these steps in order, using AskUserQuestion to gather input.
IMPORTANT — When to use AskUserQuestion vs plain text:
- AskUserQuestion: Use ONLY for multiple-choice decisions (pick A or B).
- Plain text: Use for freeform input (paths, URLs, tokens, usernames). Just ask the user directly in your message — e.g., "Paste the path to your repo here." Never wrap freeform input in AskUserQuestion with an "I'll provide it" option — that creates a pointless double question.
Prerequisites
Run these checks first:
bun --version
git --versionIf `git` is not installed: Try to install it automatically based on the platform:
macOS:
# Try Homebrew first, fall back to Xcode CLI tools
brew install git || xcode-select --installNote: xcode-select --install opens a GUI dialog - tell the user to click "Install" and wait.
Linux (detect package manager):
# Try in order: apt, dnf, pacman, apk
sudo apt-get install -y git 2>/dev/null || \
sudo dnf install -y git 2>/dev/null || \
sudo pacman -S --noconfirm git 2>/dev/null || \
sudo apk add git 2>/dev/nullWindows (PowerShell):
winget install Git.GitIf installation fails (e.g., no sudo access, no package manager), tell the user to install Git manually from https://git-scm.com and run setup again.
If `bun` is not installed: Install it automatically based on the platform:
macOS/Linux:
curl -fsSL https://bun.sh/install | bashThe installer adds Bun to the shell config, but it won't take effect until a new shell starts. For the rest of this setup session, use the full path ~/.bun/bin/bun instead of just bun.
Verify installation:
~/.bun/bin/bun --versionWindows (PowerShell):
irm bun.sh/install.ps1 | iexOn Windows, the installer updates the PATH for the current session, so bun --version should work immediately.
Important: For all bun commands in Steps 3-4, use ~/.bun/bin/bun on macOS/Linux if bun was just installed. After setup is complete and the user opens a new terminal, bun will work without the full path.
Context
The user is inside the remote-coding-agent repository — that's how they have access to this skill. The Archon repo path is the current working directory. Store it as <archon-repo>.
Step 1: Ask for Target Repo
IMPORTANT: The target repo is the user's own project — never the remote-coding-agent (Archon) repo itself. Do not suggest or offer the current directory as an option.
Use AskUserQuestion with a single question:
Header: "Target repo"
Question: "What is the path to the repository you want to work on using Archon? (This should be your own project, not the Archon repo.)"
Options:
1. "Clone from GitHub" — user provides a GitHub URL; clone it to ~/.archon/workspaces/The user will either select "Clone from GitHub" or type a local path via "Other". Do NOT add a second question to collect the path — the "Other" freeform input captures it directly in one step.
Store the result as <target-repo>.
If "Clone from GitHub": ask for the URL in plain text (not AskUserQuestion), then:
archon-repo-path=$(pwd)
mkdir -p ~/.archon/workspaces
cd ~/.archon/workspaces && git clone <url>Set <target-repo> to the cloned directory.
Step 2: Ask for Platforms
Use AskUserQuestion with multiSelect: true:
Header: "Platforms"
Question: "Which platforms do you want to set up? CLI is always included."
Options:
1. "CLI + GitHub" (Recommended) — CLI for local use, GitHub webhooks for issue/PR automation
2. "CLI only" — terminal-only, simplest setup
3. "Telegram" — chat bot via BotFather
4. "Slack" — Socket Mode appDiscord is also available — mention it as the "Other" option text.
Step 3: Run CLI Setup
Always run this. Read and follow guides/cli.md.
If Bun was just installed in Prerequisites (macOS/Linux), use ~/.bun/bin/bun instead of bun:
1. cd <archon-repo> && ~/.bun/bin/bun install (or bun install if bun was already in PATH) 2. cd <archon-repo>/packages/cli && ~/.bun/bin/bun link (or bun link) 3. Verify: archon version 4. Check Claude is installed: which claude, then claude /login if needed
Step 4: Configure Credentials
The CLI loads infrastructure config (database, tokens) from ~/.archon/.env only. This prevents conflicts with project .env files that may contain different database URLs.
Credential configuration runs in a separate terminal so your API keys stay private — the AI assistant won't see them.
4a: Launch the Setup Wizard
Run this command to attempt opening the wizard in a new terminal:
archon setup --spawnCRITICAL: Do NOT run archon setup directly via Bash — it requires interactive input that I cannot provide. The --spawn flag attempts to open a new terminal window where the user can interact directly.
Tell the user:
"Time to configure your credentials. This runs in a separate terminal so your keys stay private — I won't see them.
>
The wizard will walk you through:
1. Database selection (SQLite default or PostgreSQL)
2. AI assistant configuration (Claude and/or Codex)
3. Platform tokens for any integrations you selected
>
It saves configuration to both~/.archon/.envand the repo.env."
If the terminal opened automatically, add:
"Complete the wizard in the new terminal window that just opened."
If the output says to run it manually (common on VPS, WSL, SSH, Docker), add:
"Open a separate terminal or SSH session and run the command shown in the output. Come back here and let me know when you finish so I can continue with validation."
Both paths are normal — the manual path is not an error.
4b: Wait for User Confirmation
Wait for the user to confirm they've completed the setup wizard before proceeding.
5c: Verify Configuration
After the user confirms setup is complete:
archon versionShould show:
Database: sqlite(default, zero setup) orDatabase: postgresql(if DATABASE_URL was configured)- No errors about missing configuration
5d: Run Database Migrations (PostgreSQL only)
SQLite users: skip this step. SQLite is auto-initialized on first run with zero setup.
If the user selected PostgreSQL, run migrations:
test -n "$DATABASE_URL" && psql $DATABASE_URL < migrations/000_combined.sqlTroubleshooting:
| Issue | Cause | Fix |
|---|---|---|
Shows sqlite but expected postgresql | ~/.archon/.env missing or no DATABASE_URL | Run archon setup again in your terminal |
| "relation does not exist" | Tables not created | Run psql $DATABASE_URL < migrations/000_combined.sql |
| Connection refused | Database not running or wrong URL | Check DATABASE_URL and database server status |
Step 5: Platform-Specific Verification
The setup wizard already collected credentials for platforms selected in Step 3. Verify each one:
| Platform | Verification |
|---|---|
| CLI only | Done — skip to Step 6 |
| GitHub | Check GITHUB_TOKEN and WEBHOOK_SECRET are in .env |
| Telegram | Check TELEGRAM_BOT_TOKEN is in .env |
| Slack | Check SLACK_BOT_TOKEN and SLACK_APP_TOKEN are in .env |
| Discord | Check DISCORD_BOT_TOKEN is in .env |
For advanced platform configuration (webhook URLs, bot permissions, etc.), refer to the platform-specific guides:
guides/github.md— GitHub webhook setup detailsguides/telegram.md— BotFather commandsguides/slack.md— Slack app configurationguides/discord.md— Discord bot permissions
Step 6: Defaults (No Copy Needed)
Bundled default commands and workflows are loaded automatically at runtime from the Archon installation — nothing needs to be copied into the target repo.
Tell the user:
- "Default commands and workflows are loaded automatically at runtime — no files are added to your repo."
- "To browse defaults, look in
<archon-repo>/.archon/commands/defaults/and<archon-repo>/.archon/workflows/defaults/." - "To customize a default, copy the specific file into your repo's
.archon/commands/or.archon/workflows/directory with the same filename. Your repo version takes priority over the bundled default."
Step 7: Start the Server (non-CLI platforms only)
Skip if "CLI only" was selected.
After all platform tokens are in .env, read and follow guides/server.md to start the server from the archon repo.
Step 8: Verify from Target Repo
Run a test workflow from the target repo:
cd <target-repo> && archon workflow listIf the CLI is working, also run:
cd <target-repo> && archon workflow run archon-assist "Say hello"Troubleshooting
If verification fails:
| Error | Cause | Fix |
|---|---|---|
archon: command not found | CLI not linked | Re-run cd <archon-repo>/packages/cli && bun link |
Not a git repository | Not in a git repo | cd to the target repo root |
No workflows found | Missing .archon/workflows/ | Default workflows load automatically — check archon version works first |
| Auth errors | Claude not authenticated | Run claude /login |
relation "remote_agent_*" does not exist | DATABASE_URL missing or tables not created | Ensure ~/.archon/.env has DATABASE_URL and run migrations |
Database: sqlite but expected PostgreSQL | ~/.archon/.env missing DATABASE_URL | Add DATABASE_URL to ~/.archon/.env |
Step 9: Copy Skill to Target Repo (Optional)
Use AskUserQuestion to ask:
Header: "Archon skill"
Question: "Would you like to copy the Archon skill into your target repo so Claude Code can invoke Archon workflows from there?"
Options:
1. "Yes, copy the skill" — Copies .claude/skills/archon/ into the target repo. This will appear in git unless you gitignore it.
2. "No, skip" — You can always run Archon workflows from the Archon repo instead.If "Yes, copy the skill":
mkdir -p <target-repo>/.claude/skills
cp -r <archon-repo>/.claude/skills/archon <target-repo>/.claude/skills/archonNote: Do NOT modify the user's .gitignore — let them decide how to handle it.
Step 10: Final Summary
Tell the user what was set up, then give these instructions:
1. Open a new terminal 2. cd <target-repo> 3. Run claude to launch Claude Code 4. The archon skill is now loaded — ask Claude to run workflows, fix issues, review PRs, etc.
Example first command in the target repo:
"Use archon to fix issue #1"Tell the user:
- Default commands and workflows load automatically at runtime — nothing was added to your repo
.claude/skills/archon/— skill for Claude Code integration- To customize a default, copy the specific file from
<archon-repo>/.archon/commands/defaults/or<archon-repo>/.archon/workflows/defaults/into your repo's.archon/commands/or.archon/workflows/with the same filename
Important: End the summary with this message:
"If you want to configure advanced options later — like changing the default AI assistant, customizing worktree behavior, or adjusting which files get copied into isolated environments — just ask me to help you with 'archon config' and I'll walk you through it."
The end state: user is in their target repo with the Archon skill available, defaults loaded at runtime without polluting the repo, using Claude Code as the interface.
Configuration Reference
For advanced users — these are not needed for basic setup:
Environment Files (.env)
Infrastructure config (database URL, platform tokens) is stored in .env files:
| Location | Used by | Purpose |
|---|---|---|
~/.archon/.env | CLI | Global infrastructure config — database, AI tokens |
<archon-repo>/.env | Server | Platform tokens for Telegram/Slack/GitHub/Discord |
Best practice: Use ~/.archon/.env as the single source of truth. Symlink or copy to <archon-repo>/.env if running the server.
Note: The CLI does NOT load .env from the current working directory. This prevents conflicts when running Archon from projects that have their own database configurations.
Config Files (YAML)
Project-specific settings use layered YAML configs:
| Location | Scope | Purpose |
|---|---|---|
~/.archon/config.yaml | Global | Default AI assistant, streaming modes, concurrency |
<repo>/.archon/config.yaml | Per-repo | AI assistant, worktree settings, commands config |
Environment variables in .env override matching config.yaml values.
Repo Config Options Reference
| Option | Type | Default | Description |
|---|---|---|---|
assistant | claude \ | codex | claude |
commands.folder | string | .archon/commands | Custom command folder path (relative to repo root) |
commands.autoLoad | boolean | true | Auto-load commands on clone |
worktree.baseBranch | string | auto-detected | Base branch for worktree creation |
worktree.copyFiles | string[] | [] | Files to copy into new worktrees (supports "source -> dest" syntax) |
defaults.loadDefaultCommands | boolean | true | Load bundled default commands at runtime |
defaults.loadDefaultWorkflows | boolean | true | Load bundled default workflows at runtime |
Slack Bot Setup Guide
Slack setup is more involved than other platforms. A detailed walkthrough is available in the main docs.
Full Guide
Follow the step-by-step instructions in [docs/slack-setup.md](../../../../../docs/slack-setup.md) in this repository.
Summary
1. Create a Slack app at api.slack.com/apps (from scratch) 2. Enable Socket Mode — generates an App-Level Token (xapp-...) for SLACK_APP_TOKEN 3. Add Bot Token Scopes: app_mentions:read, chat:write, channels:history, channels:join, im:history, im:write, im:read 4. Subscribe to Bot Events: app_mention, message.im 5. Install to Workspace — generates a Bot User OAuth Token (xoxb-...) for SLACK_BOT_TOKEN 6. Invite the bot to your channel: /invite @YourBotName
.env Configuration (in the archon repo root)
SLACK_BOT_TOKEN=xoxb-your-bot-token
SLACK_APP_TOKEN=xapp-your-app-token
SLACK_ALLOWED_USER_IDS=<your Slack user ID>
SLACK_STREAMING_MODE=batchTo find your Slack user ID: click your profile > ... > Copy member ID.
Start the Server
Follow the Server Setup Guide to start the server. The Slack adapter auto-starts when both SLACK_BOT_TOKEN and SLACK_APP_TOKEN are set.
Telegram Bot Setup Guide
1. Create a Bot via BotFather
1. Open Telegram and search for @BotFather 2. Send /newbot 3. Choose a display name (e.g., "Archon Bot") 4. Choose a username (must end in bot, e.g., my_archon_bot) 5. Copy the bot token — this is your TELEGRAM_BOT_TOKEN
2. Get Your User ID
1. Search for @userinfobot on Telegram 2. Send any message 3. It replies with your user ID (a number like 123456789) 4. This is your TELEGRAM_ALLOWED_USER_IDS
3. Add to .env (in the archon repo root)
TELEGRAM_BOT_TOKEN=<token from BotFather>
TELEGRAM_ALLOWED_USER_IDS=<your user ID>
TELEGRAM_STREAMING_MODE=streamTELEGRAM_STREAMING_MODE=streamshows responses as they're generated (recommended).TELEGRAM_STREAMING_MODE=batchwaits for the full response before sending.- Multiple user IDs can be comma-separated.
4. Start the Server
Follow the Server Setup Guide to start the server. The Telegram adapter auto-starts when TELEGRAM_BOT_TOKEN is set.
5. Test
Send a message to your bot on Telegram:
/helpThe bot should respond with available commands.
Authoring Command Files
Commands are plain Markdown files containing AI prompt templates. They are the atomic unit of AI instruction — each command file defines what a single AI agent does in one step of a workflow.
File Location
.archon/commands/
├── my-command.md # Custom command
├── review-code.md # Another custom command
└── defaults/ # Optional: override bundled defaults
└── archon-assist.md # Overrides the bundled archon-assistCommands are referenced by name (without .md) in workflow YAML files.
File Format
---
description: One-line description of what this command does
argument-hint: <issue-number> or (no arguments)
---
# Command Title
**Workflow ID**: $WORKFLOW_ID
---
## Phase 1: LOAD
[Instructions for gathering context]
## Phase 2: EXECUTE
[Instructions for doing the work]
## Phase 3: GENERATE
[Instructions for writing artifacts]
### PHASE_3_CHECKPOINT
- [ ] Artifact written to `$ARTIFACTS_DIR/output.md`
- [ ] Summary prepared
## Phase 4: REPORT
[Instructions for the final output message]Frontmatter Fields
| Field | Required | Description |
|---|---|---|
description | Recommended | Human-readable description (shown in listings) |
argument-hint | Optional | Expected arguments hint (e.g., <issue-number>, (no arguments)) |
The frontmatter is metadata for discovery. The entire file content (including frontmatter) becomes the prompt sent to the AI.
Variable Substitution
Variables are replaced at execution time. See references/variables.md for the complete list.
Most commonly used:
$ARGUMENTS— the user's input message$ARTIFACTS_DIR— write artifacts here (pre-created directory)$WORKFLOW_ID— for tracking$BASE_BRANCH— for git operations
Name Validation Rules
Command names must:
- Not contain
/,\, or.. - Not start with
. - Not be empty
Discovery and Priority
When a workflow references command: my-command, Archon searches in this order: 1. .archon/commands/my-command.md (repo custom) 2. .archon/commands/defaults/my-command.md (repo default overrides) 3. Bundled defaults (shipped with Archon)
First match wins. To override a bundled command, create a file with the same name in your repo.
Referencing Commands from Workflows
In workflow YAML, use the command: field on a node:
nodes:
- id: review
command: my-command # Loads .archon/commands/my-command.md
depends_on: [implement]Phase-Based Organization Pattern
The recommended structure for complex commands:
1. LOAD — Read inputs, gather context, load artifacts from previous steps 2. EXPLORE/ANALYZE — Research the codebase, understand the problem 3. EXECUTE/GENERATE — Do the work, write code, create artifacts 4. VALIDATE — Run tests, type-check, verify 5. REPORT — Summarize results for the user
Each phase should have a PHASE_N_CHECKPOINT with a checklist to keep the AI on track.
Artifact Conventions
Artifacts are how steps communicate in multi-step workflows. Write outputs to $ARTIFACTS_DIR/:
| Convention | Purpose |
|---|---|
$ARTIFACTS_DIR/plan.md | Implementation plan |
$ARTIFACTS_DIR/investigation.md | Bug investigation results |
$ARTIFACTS_DIR/implementation.md | Implementation summary |
$ARTIFACTS_DIR/validation.md | Test/lint results |
$ARTIFACTS_DIR/pr-body.md | PR description content |
$ARTIFACTS_DIR/.pr-number | PR number (metadata) |
$ARTIFACTS_DIR/.pr-url | PR URL (metadata) |
$ARTIFACTS_DIR/review/ | Review agent outputs (subdirectory) |
Anti-Patterns
- Vague instructions — "Fix the code" is too vague. Be specific about what to investigate, which tools to use, what output to produce.
- No artifact output — If a command produces no artifacts, downstream steps have nothing to work from.
- Assuming prior context — When
context: freshis set on the calling node, the AI starts fresh. It must read artifacts explicitly. - Giant monolithic commands — Split complex work into focused phases. Each command should have one clear responsibility.
- Hardcoded paths — Use
$ARTIFACTS_DIRinstead of hardcoded paths for portability.
Simple Command Example
---
description: General-purpose AI assistant
argument-hint: <any request>
---
You are a helpful coding assistant working on this project.
**Request**: $ARGUMENTS
Analyze the codebase and help the user with their request. Use Read, Grep, Glob, and Bash tools to explore the code. Provide clear, actionable answers.Complex Command Example
---
description: Validate implementation against the plan
argument-hint: (no arguments - reads from workflow artifacts)
---
# Validate Implementation
**Workflow ID**: $WORKFLOW_ID
---
## Phase 1: LOAD
Read the plan context:
- Read `$ARTIFACTS_DIR/plan-context.md` for the implementation plan
- Read `$ARTIFACTS_DIR/implementation.md` for what was implemented
## Phase 2: VALIDATE
Run the full validation suite:
bun run type-check bun run lint bun run test
Record all failures with file paths and error messages.
### PHASE_2_CHECKPOINT
- [ ] Type-check results recorded
- [ ] Lint results recorded
- [ ] Test results recorded
## Phase 3: REPORT
Write validation results to `$ARTIFACTS_DIR/validation.md` with:
- Pass/fail status for each check
- Specific error details for failures
- Summary recommendation (proceed / needs fixes)Archon CLI Command Reference
All commands must be run from within a git repository (subdirectories work — resolves to repo root). Exceptions: version, setup, chat.
Workflow Commands
archon workflow list
List all discovered workflows (bundled + repo-defined).
archon workflow list # Human-readable table
archon workflow list --json # Machine-readable JSON outputJSON output includes: { workflows: [{ name, description, provider?, model? }], errors: [{ filename, error }] }
archon workflow run <name> [message] [flags]
Execute a workflow.
archon workflow run archon-assist "What does the auth module do?"
archon workflow run archon-fix-github-issue --branch fix/issue-42 "Fix issue #42"
archon workflow run my-workflow --branch feat/dark-mode --from develop "Add dark mode"
archon workflow run quick-fix --no-worktree "Fix the typo in README"
archon workflow run archon-fix-github-issue --resume| Flag | Description |
|---|---|
--branch <name> / -b | Branch name for worktree. Reuses existing worktree if healthy |
--from <name> / --from-branch <name> | Start-point branch for new worktree (default: repo default branch) |
--no-worktree | Skip isolation — run in the live checkout |
--resume | Resume the last failed run of this workflow (skips completed steps/nodes) |
--cwd <path> | Working directory override |
Flag conflicts (errors):
--branch+--no-worktree--from+--no-worktree--resume+--branch
Default behavior (no flags): Auto-creates a worktree with branch name {workflow-name}-{timestamp}.
Isolation Commands
archon isolation list
Show active worktree environments for all codebases.
archon isolation listOutputs: branch name, path, workflow type, platform, last activity age. Ghost entries (deleted worktrees) are auto-reconciled.
archon isolation cleanup [days]
Remove stale worktree environments.
archon isolation cleanup # Default: 7 days
archon isolation cleanup 14 # Custom: 14 days
archon isolation cleanup --merged # Remove branches merged into main (+ remote branches)Validate Commands
archon validate workflows [name]
Validate workflow YAML definitions and their referenced resources.
archon validate workflows # Validate all workflows in the repo
archon validate workflows my-workflow # Validate a single workflow
archon validate workflows my-workflow --json # Machine-readable JSON outputChecks: YAML syntax, DAG structure (cycles, dependency refs), command file existence, MCP config files, skill directories, provider compatibility. Returns actionable error messages with "did you mean?" suggestions for typos.
Exit code: 0 = all valid, 1 = errors found.
archon validate commands [name]
Validate command files (.md) in .archon/commands/.
archon validate commands # Validate all commands
archon validate commands my-command # Validate a single commandChecks: file exists, non-empty, valid name.
Other Commands
archon complete <branch> [flags]
Complete a branch lifecycle — removes worktree + local/remote branches.
archon complete feature-auth
archon complete feature-auth --force # Skip uncommitted-changes check
archon complete branch1 branch2 branch3 # Multiple branchesOther Commands
archon version
archon version
# Archon CLI v0.x.x
# Platform: darwin-arm64
# Build: source (bun)
# Database: sqlitearchon setup [--spawn]
Interactive setup wizard for database, AI providers, and platform connections.
archon setup # Run in current terminal
archon setup --spawn # Open wizard in a new terminal windowarchon chat <message>
Single-shot message to the orchestrator (does not require a git repo).
archon chat "What platforms are configured?"
archon chat "/status"Global Flags
| Flag | Short | Description |
|---|---|---|
--cwd <path> | — | Working directory override |
--quiet | -q | Set log level to warn (errors only) |
--verbose | -v | Set log level to debug |
--json | — | Machine-readable JSON output (workflow list) |
--help | -h | Print usage and exit |
Key Environment Variables
| Variable | Purpose |
|---|---|
CLAUDE_API_KEY | Claude API key (explicit auth) |
CLAUDE_USE_GLOBAL_AUTH | true to use claude /login credentials |
ARCHON_HOME | Override base directory (default: ~/.archon) |
LOG_LEVEL | Pino log level: `fatal\ |
DATABASE_URL | PostgreSQL URL (omit for SQLite default) |
Advanced Features: Hooks, MCP, Skills, Retry
These features are available on command and prompt nodes (hooks, MCP, skills, tool restrictions) and command, prompt, and bash nodes (retry, output_format). Loop nodes do not support these features (retry on loop nodes is a hard error; others are silently ignored).
Provider Compatibility
| Feature | Claude (per-node) | Codex (per-node) | Codex (global) |
|---|---|---|---|
hooks | Supported | Ignored | Not available |
mcp | Supported | Ignored | ~/.codex/config.toml [mcp_servers.*] |
skills | Supported | Ignored | ~/.agents/skills/ or .agents/skills/ |
allowed_tools / denied_tools | Supported | Ignored | enabled_tools / disabled_tools per MCP server in config.toml |
output_format | Supported | Supported | — |
retry | Supported | Supported | — |
model / provider per-node | Supported | Supported | — |
Claude vs Codex: How Each Gets MCP and Skills
Claude: MCP servers and skills are configured per-node in the workflow YAML via mcp: and skills: fields. Each node can have different MCP servers and skills.
Codex: MCP servers and skills are configured globally — they apply to all Codex nodes in the workflow:
- MCP servers: Add to
~/.codex/config.toml(or.codex/config.tomlin the repo):
[mcp_servers.github]
command = "npx"
args = ["-y", "@modelcontextprotocol/server-github"]
env = { GITHUB_TOKEN = "your-token" }Manage with: codex mcp add <name>, codex mcp list
- Skills: Place in
~/.agents/skills/<name>/SKILL.md(user-level) or.agents/skills/<name>/SKILL.md(repo-level). Codex discovers them automatically. - Custom instructions: Place in
~/.codex/AGENTS.md(global) orAGENTS.mdin the repo root.
The Codex CLI picks up all of these automatically because Archon inherits the full process environment when spawning the CLI. No Archon configuration needed — just set up the Codex CLI config once.
Hooks have no Codex equivalent — they are a Claude-only SDK feature for intercepting tool calls.
---
Hooks
Claude only. Codex nodes log a warning and ignore hooks.
Hooks intercept tool calls during a node's AI execution. Use them to approve/deny tools, inject context after tool use, or emergency-stop the agent.
Syntax
- id: analyze
prompt: "Analyze the codebase"
hooks:
PreToolUse:
- matcher: "Bash" # Regex on tool name (optional)
response: # Required: SDK SyncHookJSONOutput
hookSpecificOutput:
hookEventName: PreToolUse # Must match the event key
permissionDecision: deny
permissionDecisionReason: "No shell access in analysis phase"
timeout: 30 # Seconds (optional, default: 60)
PostToolUse:
- matcher: "Read"
response:
systemMessage: "You just read a file. Stay focused on analysis — do not modify anything."
- response: # No matcher = fires on every tool
systemMessage: "Verify this output is relevant."Supported Hook Events
Most commonly used: PreToolUse, PostToolUse, Stop
Full list: PreToolUse, PostToolUse, PostToolUseFailure, Notification, UserPromptSubmit, SessionStart, SessionEnd, Stop, SubagentStart, SubagentStop, PreCompact, PermissionRequest, Setup, TeammateIdle, TaskCompleted, Elicitation, ElicitationResult, ConfigChange, WorktreeCreate, WorktreeRemove, InstructionsLoaded
Matcher Fields
| Field | Type | Required | Description |
|---|---|---|---|
matcher | string | No | Regex pattern to filter by tool name. Omit to match all |
response | object | Yes | The SyncHookJSONOutput returned when hook fires |
timeout | number | No | Timeout in seconds (default: 60) |
Response Fields
| Field | Type | Effect |
|---|---|---|
hookSpecificOutput | object | Event-specific payload. Must include hookEventName matching the outer event key |
systemMessage | string | Inject a message visible to the AI model |
continue | boolean | Set to false to stop the agent |
stopReason | string | Reason when stopping |
decision | approve / block | Top-level approve/block decision |
PreToolUse hookSpecificOutput
| Field | Effect |
|---|---|
permissionDecision | deny / allow / ask |
permissionDecisionReason | Human-readable reason |
updatedInput | Object to replace tool arguments |
additionalContext | Extra context injected into the conversation |
PostToolUse hookSpecificOutput
| Field | Effect |
|---|---|
additionalContext | Context injected after the tool runs |
updatedMCPToolOutput | Replace MCP tool output |
Common Patterns
Deny specific tools:
hooks:
PreToolUse:
- matcher: "Write|Edit|Bash"
response:
hookSpecificOutput:
hookEventName: PreToolUse
permissionDecision: deny
permissionDecisionReason: "Read-only analysis node"Inject guidance after file reads:
hooks:
PostToolUse:
- matcher: "Read"
response:
systemMessage: "Focus on identifying security vulnerabilities in what you just read."Emergency stop on shell access:
hooks:
PreToolUse:
- matcher: "Bash"
response:
continue: false
stopReason: "Shell access not permitted"Hooks vs Tool Restrictions
| Mechanism | Granularity | Effect |
|---|---|---|
allowed_tools | Coarse | Tools not in list are invisible to AI |
denied_tools | Coarse | Listed tools are invisible to AI |
hooks.PreToolUse | Fine | Tool is visible but call can be denied/modified/annotated |
Use allowed_tools/denied_tools for hard restrictions. Use hooks when you want the AI to know the tool exists but have guardrails on how it's used.
---
MCP (Model Context Protocol) Servers
Claude only. Codex nodes log a warning and ignore MCP configuration.
Connect external tool servers to individual nodes.
Syntax
- id: github-analysis
prompt: "Analyze recent PRs using GitHub MCP tools"
mcp: .archon/mcp/github.json # Path relative to repo root
allowed_tools: [] # MCP-only mode (no built-in tools)Config File Format
The JSON file defines one or more MCP servers:
{
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "$GITHUB_TOKEN"
}
}
}Transport types:
stdio (default):
{
"my-server": {
"command": "npx",
"args": ["-y", "@server/package"],
"env": { "API_KEY": "$MY_API_KEY" }
}
}HTTP:
{
"my-server": {
"type": "http",
"url": "https://api.example.com/mcp",
"headers": { "Authorization": "Bearer $API_KEY" }
}
}SSE:
{
"my-server": {
"type": "sse",
"url": "https://api.example.com/sse"
}
}Environment Variable Expansion
$VAR_NAME patterns in env and headers values are expanded from process.env at execution time (not load time). This keeps secrets out of YAML files.
Missing env vars produce a user-visible warning but don't abort the node.
Automatic Tool Wildcards
When MCP servers are loaded, mcp__<serverName>__* wildcards are automatically added to the node's allowed tools. This means MCP tools work without explicit permission.
MCP-Only Nodes
Combine mcp: with allowed_tools: [] for nodes that should ONLY use MCP tools:
- id: notify
prompt: "Send a notification that the workflow completed"
mcp: .archon/mcp/ntfy.json
allowed_tools: [] # No built-in tools, MCP only---
Skills
Claude only. Codex nodes log a warning and ignore skills.
Preload domain knowledge into a node via Claude Code skills.
Syntax
- id: generate
prompt: "Create a Remotion animation for: $ARGUMENTS"
skills:
- remotion-best-practices # Must be installed in .claude/skills/
allowed_tools: [Read, Write, Edit, Glob]How It Works
When skills: is set, the node is wrapped in a Claude SDK AgentDefinition:
- The skill content is injected into the agent's context at startup
- The
Skilltool is automatically added to the node's allowed tools - The agent gets a system prompt listing the preloaded skills
Installing Skills
# From the skills.sh marketplace
npx skills add remotion-dev/skills
# Or create manually
mkdir -p .claude/skills/my-skill
# Write .claude/skills/my-skill/SKILL.md with frontmatterSkills are discovered from:
.claude/skills/(project-level)~/.claude/skills/(user-level, global)
Combining Skills with MCP
Skills provide knowledge (how to do something). MCP provides capability (external tool access). Combine them:
- id: smart-github-agent
prompt: "Triage these issues using GitHub best practices"
skills:
- github-triage-guide
mcp: .archon/mcp/github.json
allowed_tools: [] # MCP tools + skill knowledge---
Retry Configuration
Available on command, prompt, and bash nodes. Not supported on loop nodes (hard error at load time).
- id: deploy
bash: "deploy.sh"
retry:
max_attempts: 3 # 1-5 (required when retry is set)
delay_ms: 5000 # 1000-60000, default 3000. Doubles each attempt
on_error: all # 'transient' (default) or 'all'Error Classification
| Category | Examples | Retried? |
|---|---|---|
| FATAL | unauthorized, forbidden, permission denied, invalid token, authentication failed, auth error, 401, 403, credit balance | Never |
| TRANSIENT | timeout, etimedout, rate limit, too many requests, 429, 502, 503, econnrefused, econnreset, network error, socket hang up, exited with code, claude code crash | By default |
| UNKNOWN | Everything else | Only with on_error: all |
FATAL patterns take priority over TRANSIENT patterns in the same error message.
Two-Layer Retry Stack
1. SDK-level (automatic): Built-in retry for API errors (behavior managed by the Claude/Codex SDK) 2. Node-level (configurable via retry:): Wraps the entire SDK call. Default when retry: is omitted: 2 retries, 3000ms base delay, transient errors only
Idle Timeout
Separate from retry — controls how long a node can be idle (no output) before being aborted:
- id: long-running
command: full-analysis
idle_timeout: 600000 # 10 minutes (default: 5 minutes / 300000ms)For bash nodes, use timeout: instead (controls total script execution time, default: 120000ms).
Interactive Workflow Guide
Interactive workflows use human-in-the-loop approval gates and interactive loops. When you invoke one, you become a transparent relay between the user and the running workflow — not a commentator.
Identifying Interactive Workflows
A workflow is interactive if it has interactive: true in its YAML definition. Key interactive workflows:
archon-piv-loop— Plan-Implement-Validate with iterative feedbackarchon-interactive-prd— Guided PRD creation with approval gates
When the user asks to run one of these, follow the protocol below.
Protocol: Running Interactive Workflows
1. Invoke the workflow
Run it in the background as usual:
archon workflow run <name> "<message>"2. Monitor for pause
Check archon workflow status periodically. When status changes to paused, the workflow is waiting for user input.
3. Fetch and relay the output — BE TRANSPARENT
When the workflow pauses, immediately read the log file to get the AI's output:
# Find the log file
find ~/.archon/workspaces -name "<run-id>.jsonl" 2>/dev/null
# Extract the last assistant messageParse the JSONL log for the last "type":"assistant" entry and display its content field directly to the user. Do not summarize, do not add commentary, do not say "the workflow asked..." — just show the output as if the user is talking to the workflow agent directly.
DO:
## What I Understand
You want to add a --json flag to workflow status...
## Questions
1. Should the output include...
2. Do you want...DON'T:
The workflow has paused and is asking you several questions. Here's what it found:
- It discovered that the --json flag is partially implemented
- It's asking about the output format
You can respond with...4. Collect user response and resume
When the user responds naturally (answers questions, says "ready", gives feedback), pass their response directly:
archon workflow approve <run-id> "<user's exact response>"Do not modify, summarize, or enhance the user's response. Pass it through verbatim.
5. Repeat until workflow completes
The workflow will alternate between running and pausing. Each time it pauses:
- Read the latest output from the log
- Display it directly
- Wait for the user's response
- Resume with their response
When the workflow finishes (status becomes completed or failed), report the final result.
Key Behavior Rules
1. You are a transparent pipe. The user should feel like they're talking directly to the workflow agent. Never insert yourself as a middleman with commentary.
2. Show output verbatim. The workflow agent's questions, findings, and summaries should appear exactly as written — including markdown formatting, code blocks, and structure.
3. Pass input verbatim. The user's responses go directly to the workflow via workflow approve. Don't rewrite or "improve" their input.
4. Don't explain the workflow mechanics. Don't say "the workflow is now in the explore phase" or "it will pause again after this." The user knows they're in a conversation — let it flow naturally.
5. Monitor proactively. Don't wait for the user to ask "what happened?" — check status and relay output as soon as the workflow pauses.
Approval Commands
# Approve with feedback (interactive loops)
archon workflow approve <run-id> "your feedback or answers here"
# Reject (cancels the workflow)
archon workflow reject <run-id> "reason for rejection"Troubleshooting
- Workflow shows `running` for a long time: The AI is doing research/implementation. Be patient — check again in a few minutes.
- Log file not found: The log is at
~/.archon/workspaces/<owner>/<repo>/logs/<run-id>.jsonl - User wants to cancel: Run
archon workflow reject <run-id>orarchon workflow cancel <run-id>
Initializing Archon in a Repository
Set up the .archon/ directory structure in any git repository to enable custom workflows and commands.
Directory Structure
Create the following in your repository root:
.archon/
├── commands/ # Custom command files (.md)
├── workflows/ # Workflow definitions (.yaml)
├── mcp/ # MCP server config files (.json) — optional
└── config.yaml # Repo-specific configuration — optionalmkdir -p .archon/commands .archon/workflowsMinimal config.yaml
Create .archon/config.yaml only if you need to override defaults:
# AI provider for this repo (default: inherited from global config)
assistant: claude # Repo-level key. In ~/.archon/config.yaml, use 'defaultAssistant' instead
# Worktree settings
worktree:
baseBranch: main # Branch to create worktrees from (default: auto-detected)
copyFiles: # Git-ignored files to copy into new worktrees
- .env
- .env.local
# Control whether bundled defaults are loaded
defaults:
loadDefaultCommands: true # Include bundled default commands (default: true)
loadDefaultWorkflows: true # Include bundled default workflows (default: true)How Bundled Defaults Work
Archon ships with built-in commands and workflows (like archon-assist, archon-fix-github-issue). These are loaded at runtime automatically — no files need to be copied into your repo.
- To see bundled workflows:
archon workflow list - To override a default: Create a file with the same name in your repo's
.archon/workflows/or.archon/commands/. Repo files take priority. - To disable defaults: Set
defaults.loadDefaultWorkflows: falseordefaults.loadDefaultCommands: falsein config.
.gitignore Considerations
Add to your .gitignore:
# Archon runtime artifacts (never commit)
.archon/mcp/ # May contain env var referencesThe .archon/commands/ and .archon/workflows/ directories should be committed — they are part of your project's workflow definitions.
Global Configuration
The global config at ~/.archon/config.yaml applies to all repositories. Use guides/config.md for interactive config editing, or create it manually:
botName: Archon
defaultAssistant: claude
assistants:
claude:
model: sonnet
codex:
model: gpt-5.3-codex
modelReasoningEffort: medium
concurrency:
maxConversations: 10Verification
After setting up, verify with:
# Confirm Archon sees your repo
archon workflow list
# Should show bundled workflows + any custom ones you've addedVariable Substitution Reference
Variables are placeholders in command files and workflow prompts that get replaced at execution time.
Variable Table
| Variable | Scope | Description |
|---|---|---|
$ARGUMENTS | All modes | The user's original message passed to the workflow |
$USER_MESSAGE | All modes | Same as $ARGUMENTS — both resolve to the user's message |
$WORKFLOW_ID | All modes | Unique workflow run ID (for tracking and logging) |
$ARTIFACTS_DIR | All modes | Pre-created directory for this workflow run's artifacts. Write outputs here |
$BASE_BRANCH | All modes | Base branch name. Auto-detected from git, or set via worktree.baseBranch in config. Throws if referenced but unresolvable |
$CONTEXT | All modes | GitHub issue/PR context (if available from platform). Empty string if unavailable |
$EXTERNAL_CONTEXT | All modes | Alias for $CONTEXT |
$ISSUE_CONTEXT | All modes | Alias for $CONTEXT |
$nodeId.output | DAG only | Full text output of a completed upstream node |
$nodeId.output.field | DAG only | JSON field access on structured output from upstream node (string/number/boolean) |
Variable Availability
All variables are available in all workflows. The only exception is $nodeId.output / $nodeId.output.field, which is DAG-only (requires an upstream node to reference).
Where Variables Are Substituted
- Command files (
.archon/commands/*.md) — all variables except$nodeId.output - Inline `prompt:` fields — in DAG prompt nodes and loop node prompts
- `bash:` scripts in DAG nodes —
$nodeId.outputreferences are automatically shell-quoted (single-quoted with'escaped)
Substitution Order
1. Standard workflow variables ($WORKFLOW_ID, $ARGUMENTS, $ARTIFACTS_DIR, $BASE_BRANCH, $CONTEXT) 2. Node output references ($nodeId.output, $nodeId.output.field) — DAG mode only
Context Auto-Append
If $CONTEXT / $EXTERNAL_CONTEXT / $ISSUE_CONTEXT is NOT present anywhere in the prompt template but context exists (e.g., from a GitHub issue), it is automatically appended at the end after a --- separator.
Escaped Dollar Signs
Use \$ to produce a literal $ in command files (prevents variable substitution).
Node Output Details (DAG Only)
$nodeId.output resolves to the full text output of the upstream node. If the node used output_format: (structured output), the output is the JSON-stringified result.
$nodeId.output.field parses the output as JSON and extracts the named field. Only works when the upstream node produced structured output via output_format:. Returns the string representation of the field value.
In bash: nodes, $nodeId.output values are automatically shell-escaped before injection to prevent command injection.
Unknown node references resolve to an empty string (with a warning logged).
Workflow Authoring
Archon workflows use a DAG (Directed Acyclic Graph) format: nodes with explicit dependency edges. Independent nodes run in parallel, conditions enable routing, and data flows between nodes via $nodeId.output. This is the only workflow format — there are no other workflow types.
Schema
# Required
name: my-workflow
description: What this workflow does
# Optional — workflow-level provider/model (inherited by all nodes)
provider: claude # 'claude' or 'codex' (default: from config)
model: sonnet # Model override
# Required — the nodes array
nodes:
- id: node-name # Unique identifier
prompt: "Inline AI prompt" # OR command: name OR bash: "script" OR loop: {...}
depends_on: [other-node] # Node IDs that must complete firstFour Node Types (Mutually Exclusive)
Each node must have exactly ONE of these fields:
Command Node
Runs a command file from .archon/commands/:
- id: investigate
command: investigate-issue # Loads .archon/commands/investigate-issue.mdPrompt Node
Runs an inline AI prompt:
- id: classify
prompt: |
Analyze this issue and classify it.
Issue: $ARGUMENTSBash Node
Runs a shell script without AI:
- id: fetch-data
bash: |
gh issue view 123 --json title,body,labels
timeout: 30000 # ms, default: 120000 (2 min)- Script runs via
bash -c - stdout captured as node output (available as
$fetch-data.output) - stderr forwarded as warning, does not fail the node
- No AI invoked — AI-specific fields are ignored
- Use
timeout:(milliseconds) for execution time limit
Loop Node
Iterates an AI prompt until a completion signal or max iterations:
- id: implement
depends_on: [setup]
idle_timeout: 600000 # Per-iteration idle timeout (ms)
loop:
prompt: |
Read the PRD and implement the next unfinished story.
When all stories are done: <promise>COMPLETE</promise>
until: COMPLETE # Completion signal string
max_iterations: 10 # Hard limit — node fails if exceeded
fresh_context: true # true = fresh session each iteration
until_bash: "bun run test" # Optional: exit 0 = completeSee the dedicated Loop Nodes section below for full details.
Node Base Fields
All node types share these fields:
| Field | Type | Default | Description |
|---|---|---|---|
id | string | required | Unique node identifier |
depends_on | string[] | [] | Node IDs that must settle before this node runs |
when | string | — | Condition expression. Node skipped when false |
trigger_rule | string | all_success | Join semantics for multiple dependencies |
idle_timeout | number (ms) | 300000 | Per-node idle timeout. On loop nodes, applies per-iteration |
Command, prompt, and bash nodes (silently ignored on loop nodes, except retry which is a hard error):
| Field | Type | Default | Description |
|---|---|---|---|
model | string | inherited | Per-node model override |
provider | claude / codex | inherited | Per-node provider override |
context | fresh / shared | — | fresh = new session; shared = inherit from prior node. Defaults to fresh for parallel layers, inherited for sequential |
output_format | object | — | JSON Schema for structured output |
allowed_tools | string[] | all | Tool whitelist. [] = disable all. Claude only |
denied_tools | string[] | none | Tool blacklist. Claude only |
retry | object | 2 retries, 3s | Retry config. Hard error on loop nodes |
hooks | object | — | SDK hooks. Claude only. See dag-advanced.md |
mcp | string | — | MCP config path. Claude only. See dag-advanced.md |
skills | string[] | — | Skill names. Claude only. See dag-advanced.md |
Dependencies and Parallel Execution
Nodes are grouped into topological layers. All nodes in the same layer run concurrently.
nodes:
# Layer 0 — run in parallel
- id: fetch-issue
bash: "gh issue view $ARGUMENTS --json title,body"
- id: fetch-template
bash: "cat .github/PULL_REQUEST_TEMPLATE.md 2>/dev/null || echo 'None'"
# Layer 1 — depends on layer 0
- id: classify
prompt: "Classify: $fetch-issue.output"
depends_on: [fetch-issue]Trigger Rules
| Value | Behavior |
|---|---|
all_success | ALL deps succeeded (default) |
one_success | At least ONE dep succeeded |
none_failed_min_one_success | No deps failed AND at least one succeeded (skipped OK) |
all_done | All deps terminal (completed, failed, or skipped) |
Conditions (when:)
- id: investigate
command: investigate-bug
depends_on: [classify]
when: "$classify.output.issue_type == 'bug'"Syntax: $nodeId.output OPERATOR 'value' — operators: ==, != only. Values single-quoted. Invalid expressions skip the node (fail-closed).
Node Output Substitution
- id: analyze
prompt: |
Classification: $classify.output
Type: $classify.output.issue_type$nodeId.output— full text output$nodeId.output.field— JSON field from structured output- In bash scripts, values are auto shell-quoted
- Loop node output = last iteration only
Structured Output (output_format)
Command/prompt nodes only:
- id: classify
prompt: "Classify: $ARGUMENTS"
allowed_tools: []
model: haiku
output_format:
type: object
properties:
issue_type:
type: string
enum: [bug, feature]
required: [issue_type]Enables $classify.output.issue_type field access. Works with Claude and Codex.
Per-Node Provider and Model
Override on command/prompt nodes:
nodes:
- id: classify
prompt: "Quick classification"
model: haiku # Fast model
- id: implement
command: implement-changes # Inherits workflow-level modelLoop nodes accept provider/model without error but ignore them at runtime.
Resume on Failure
When a workflow fails, already-completed nodes are skipped on the next run:
archon workflow run my-workflow --resume---
Loop Nodes
Loop nodes iterate an AI prompt until a completion condition is met. Use them for autonomous multi-step work: implementing stories from a PRD, iterating until tests pass, or refining output.
Configuration
- id: my-loop
loop:
prompt: "..." # Required. Sent each iteration
until: COMPLETE # Required. Completion signal
max_iterations: 10 # Required. Integer >= 1. Fails if exceeded
fresh_context: true # Optional. Default: false
until_bash: "..." # Optional. Exit 0 = complete| Field | Type | Required | Description |
|---|---|---|---|
prompt | string | Yes | Prompt template. Supports all variable substitution ($ARGUMENTS, $nodeId.output, etc.) |
until | string | Yes | Completion signal to detect in AI output |
max_iterations | number | Yes | Hard limit. Node fails if exceeded |
fresh_context | boolean | No | Default false. true = fresh AI session each iteration |
until_bash | string | No | Shell script run after each iteration. Exit 0 = complete |
Completion Detection
Checked after each iteration: 1. AI signal — <promise>SIGNAL</promise> in output (recommended) or plain signal at end 2. `until_bash` — shell script exits 0
Either triggers completion. <promise> tags are stripped from output.
Session Patterns
fresh_context | Behavior | Best for |
|---|---|---|
true | Fresh session each iteration. No memory. State on disk. | Multi-story PRDs, long loops |
false (default) | Sessions thread. AI remembers prior iterations. | Fix-iterate cycles, refinement |
First iteration is always fresh regardless.
What Does NOT Work on Loop Nodes
retry— hard error at parse timehooks,mcp,skills,allowed_tools,denied_tools,output_format— silently ignoredcontext: fresh— ignored (useloop.fresh_contextinstead)provider,model— accepted but ignored at runtime
Loop Output
$nodeId.output = last iteration's output only. Accumulate via files in $ARTIFACTS_DIR.
Patterns
Stateless (Ralph):
- id: implement
depends_on: [setup]
idle_timeout: 600000
loop:
prompt: |
FRESH session — no memory. Read tracking file, implement next story,
validate, commit. When done: <promise>COMPLETE</promise>
Context: $setup.output
until: COMPLETE
max_iterations: 15
fresh_context: trueTest-fix cycle:
- id: fix-tests
loop:
prompt: "Run tests, fix failures. When passing: <promise>PASS</promise>"
until: PASS
max_iterations: 8
until_bash: "bun run test"
fresh_context: false---
Validate Before Finishing
Before declaring a workflow complete, validate it:
archon validate workflows <name>Fix any errors and re-validate until the command returns clean. This checks:
- YAML syntax and required fields
- DAG structure (cycles, missing dependencies, invalid
$nodeId.outputrefs) - All
command:files exist on disk - All
mcp:config files exist and contain valid JSON - All
skills:directories exist
Use --json for machine-readable output. Use archon validate commands <name> to validate individual command files.
Validation Rules (Load Time)
- All node IDs unique
- All
depends_onreference existing IDs - No cycles
$nodeId.outputrefs inwhen:,prompt:,loop.prompt:must point to known IDs- Exactly one of
command,prompt,bash,loopper node retryon loop node = hard errorsteps:format rejected (deprecated — usenodes:only)
Complete Example
name: classify-and-fix
description: Classify a GitHub issue, then route to the appropriate handler
nodes:
- id: fetch-issue
bash: "gh issue view $ARGUMENTS --json title,body,labels"
timeout: 15000
- id: classify
prompt: "Classify this issue: $fetch-issue.output"
depends_on: [fetch-issue]
model: haiku
allowed_tools: []
output_format:
type: object
properties:
issue_type:
type: string
enum: [bug, feature]
required: [issue_type]
- id: investigate
command: investigate-bug
depends_on: [classify]
when: "$classify.output.issue_type == 'bug'"
context: fresh
- id: plan
command: plan-feature
depends_on: [classify]
when: "$classify.output.issue_type == 'feature'"
context: fresh
- id: implement
command: implement-changes
depends_on: [investigate, plan]
trigger_rule: one_success
context: fresh
- id: create-pr
command: create-pull-request
depends_on: [implement]
context: fresh