Commit graph

67 commits

Author SHA1 Message Date
Cole Medin
f80d187d24 docs: add Archon logo and polish README header
Add logo to assets/ and update README with centered header,
tagline, and badges for a professional open-source presentation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 13:01:25 -05:00
Cole Medin
32d4787e96 docs: replace em dashes and move previous version section higher
Replace all em dashes with regular dashes in README. Move the
"Previous Version" section to right before Quickstart so existing
users find it immediately.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 12:20:17 -05:00
Cole Medin
41067c475d docs: add link to archived previous version of Archon
Points users to the archive/v1-task-management-rag branch for
the original Python-based Archon (task management + RAG tool).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 12:16:16 -05:00
Cole Medin
c291f6f97a chore: fix remaining references and update README for open-source launch
- Update Dockerfile.user.example image refs (dynamous → coleam00/archon)
- Update docker-compose.yml image name (remote-coding-agent → archon)
- Fix clone URL and dir name in Book of Archon first-five-minutes
- Update prompt-builder example project name
- Add elevator pitch to README intro
- Fix all README doc links to point to archon.diy (old docs/ dir was deleted)
- Add install scripts to docs-web public dir for GitHub Pages serving

Relates to #980

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 08:03:13 -05:00
Cole Medin
ae346c2a67 feat: prepare for open-source migration to coleam00/Archon
- Replace all dynamous-community/remote-coding-agent references with coleam00/Archon
- Replace all ghcr.io/dynamous-community/remote-coding-agent with ghcr.io/coleam00/archon
- Change license from proprietary Dynamous to MIT
- Fix cd directory name in docs (remote-coding-agent → Archon)
- Remove hardcoded local paths from skills and docs
- Add Windows x64 binary to release pipeline (cross-compiled from Linux)
- Add --minify --bytecode flags to binary compilation
- Create PowerShell install script (scripts/install.ps1)
- Fix isBinaryBuild() detection for Bun 1.3.5+ (use import.meta.dir virtual FS check)
- Scaffold Astro Starlight docs site at website/ (Astro 6 + Starlight 0.38)
- Add deploy-docs.yml workflow for GitHub Pages
- Update test.yml branch triggers (develop → dev)
- Add install section with curl/PowerShell/Homebrew/Docker to README
- Add badges and archon.diy docs link to README
- Create SECURITY.md with vulnerability disclosure policy
- Update CONTRIBUTING.md for public audience
- Add website/ and eslint ignores for Astro-generated files

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 10:47:22 -05:00
Cole Medin
51a2702699 fix: address PR #938 review findings — interactive loop correctness and coverage
Fixed:
- H1: Return 'completed' (not 'failed') from interactive loop gate to prevent
  false "Some DAG nodes failed" warnings in multi-node workflows
- H2: Check safeSendMessage return value before pausing — fail the node with a
  clear error if the gate message failed to deliver, preventing orphaned paused runs
- H3: Extend isApprovalTransition guard in updateWorkflowRun to cover loop_user_input
  metadata key, preventing completed_at from being stamped on resumable loop runs
- M1: Add isApprovalContext() type guard in workflow-run.ts; replace unsafe casts
  in dag-executor.ts and command-handler.ts
- M4/L3: Update comments to accurately reflect completed-return semantics and
  metadata merge requirement
- L1: Pass '' instead of undefined for $LOOP_USER_INPUT on iterations after first
- L4: Update $LOOP_USER_INPUT docstring to clarify first-iteration-only scoping
- Gap6: Add archon-piv-loop to bundled-defaults.ts so it's available in binary builds

Tests added:
- H4: /workflow approve interactive_loop branch tests in command-handler.test.ts
  (routing, approval_received event, no node_completed, error cases)
- M2: superRefine validation tests in loader.test.ts (reject interactive without
  gate_message; accept valid interactive loop)
- M3: loader warning test for interactive loop in non-interactive workflow

Docs updated:
- H5: docs/loop-nodes.md — add interactive/gate_message fields, $LOOP_USER_INPUT
  variable, and interactive loop pattern section
- M5: docs/authoring-workflows.md — note interactive loops require workflow-level
  interactive: true
- L5: README.md — add archon-piv-loop row, update count 16→17
- L6: docs/authoring-workflows.md — update count 16→17
- L7: CLAUDE.md — add $LOOP_USER_INPUT to variable substitution table

Bundled defaults test updated: count 10→11 to reflect archon-piv-loop addition

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 11:17:56 -05:00
Cole Medin
d5976802fd
docs: consolidate QUICKSTART.md and getting-started-cli.md into single guide (#878)
* docs: consolidate QUICKSTART.md and getting-started-cli.md into single guide (#806)

Two overlapping getting-started docs (QUICKSTART.md for Web UI, getting-started-cli.md
for CLI) created confusion for new users. Neither was complete alone.

Changes:
- Merged both docs into docs/getting-started.md with "Choose Your Path" (Web UI vs CLI)
- Deleted QUICKSTART.md (content preserved in unified guide)
- Renamed docs/getting-started-cli.md to docs/getting-started.md
- Updated all references in README.md, adapter docs, and new-developer-guide.md
- Added troubleshooting section from QUICKSTART.md (previously missing from CLI guide)
- Added .env setup section with note about CLI-only vs server usage

Fixes #806

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: format files and fix test imports from validation

- Auto-format workflows.test.ts and api.ts (Prettier)
- Fix api.conversations.test.ts: Hono() → OpenAPIHono({ defaultHook: validationErrorHook })

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: restore removed dependencies and scripts in @archon/web

Restores zustand, react-resizable-panels, openapi-typescript, and
generate:types script that were accidentally removed. Removes
@archon/workflows dep that violates CLAUDE.md architectural boundary.
Restores src/stores/ test batch in test script.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: remove spurious non-docs changes from PR

Revert bun.lock, packages/web/package.json, packages/core/src/db/workflows.test.ts,
packages/server/src/routes/api.conversations.test.ts, and packages/server/src/routes/api.ts
to match dev. This docs-only PR should contain no code or dependency changes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: restore formatting of non-docs files to exactly match dev

These files were reformatted by the pre-commit prettier hook in the previous commit.
Restore them byte-for-byte from dev so this docs-only PR has zero code changes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): correct broken anchor links in getting-started guide

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 14:25:58 -07:00
Cole Medin
9244fd80df
docs: document agent-browser as optional dependency for E2E workflows (#876)
* docs: document agent-browser as optional dependency for E2E workflows (#787)

agent-browser is used by archon-validate-pr, validate-ui skill, and replicate-issue
skill but installation requirements were not documented. Users hitting these workflows
got confusing errors.

Changes:
- Added installation section to .claude/skills/agent-browser/SKILL.md
- Created docs/e2e-testing.md general cross-platform setup guide
- Added agent-browser as optional dependency in README.md prerequisites
- Added E2E troubleshooting section to docs/troubleshooting.md
- Added cross-reference from docs/e2e-testing-wsl.md to general guide

Fixes #787

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: format + fix test references for OpenAPIHono migration

Prettier auto-formatted two files and fixed 5 test cases that referenced
`Hono` instead of `OpenAPIHono` after the OpenAPI route refactor.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(docs): accurately describe agent-browser fallback as prompt instruction

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 16:24:46 -05:00
Cole Medin
dafa0f9082
docs: restructure setup flow, fix workflow tables, rename getting-started (#820)
* docs: update README, getting-started, and authoring-workflows for default workflows (#789)

Documentation was stale: workflow count was wrong (16→17), several workflows
were missing from tables, router auto-selection was undocumented, and examples
used deprecated sequential/loop syntax instead of DAG nodes.

Changes:
- README.md: Fix workflow count to 17, update table with all key workflows,
  add defaults-as-templates guidance, mention router auto-selection
- docs/getting-started.md: Complete workflow table (all 17), add auto-selection
  explanation, convert custom workflow example to DAG syntax
- docs/authoring-workflows.md: Remove sequential (steps:) and standalone loop
  sections, convert all examples to DAG nodes: syntax, add deprecation notice,
  add "Using defaults as templates" guidance, update summary

Fixes #789

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(docs): address review findings — complete workflow table and fix stale step refs

- Add 6 missing workflows to README table (now lists all 17)
- Replace stale "step" references with "node" terminology in authoring-workflows.md
- Update retry notification example to match DAG executor output
- Fix artifact chain table to reference node name instead of "step 1"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(readme): remove Option A (run from Archon repo) — only target repo usage

* docs: restructure setup flow — wizard-first, rename getting-started

- README: Make the setup wizard the primary path (clone → claude → "set up archon")
- README: Add clear "Start Using Archon" section with exit/cd/claude steps
- README: Add note to always run from target repo, not Archon repo
- README: Link to CLI and Web UI guides as alternative paths
- Rename docs/getting-started.md → docs/getting-started-cli.md
- Update all cross-references (7 files) to new filename

* docs: fix workflow count (17 → 16) in authoring-workflows.md

* docs: fix loop node YAML nesting and add fresh_context in authoring-workflows

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Rasmus Widing <rasmus.widing@gmail.com>
2026-03-26 12:54:04 +02:00
Rasmus Widing
ef04321eef
refactor(workflows)!: remove sequential execution mode, DAG becomes sole format (#805)
* refactor(workflows)!: remove sequential execution mode, DAG becomes sole format

Remove the steps-based (sequential) workflow execution mode entirely.
All workflows now use the nodes-based (DAG) format exclusively.

- Convert 8 sequential default workflows to DAG format
- Delete archon-fix-github-issue sequential (DAG version absorbs triggers)
- Remove SingleStep, ParallelBlock, StepWorkflow types and guards
- Gut executor.ts from ~2200 to ~730 lines (remove sequential loop)
- Remove step_started/completed/failed and parallel_agent_* events
- Remove logStepStart/Complete and logParallelBlockStart/Complete
- Delete SequentialEditor, StepProgress, ParallelBlockView components
- Remove sequential mode from workflow builder and execution views
- Delete executor.test.ts (4395 lines), update ~45 test fixtures
- Update CLAUDE.md and docs to reflect DAG-only format

BREAKING CHANGE: Workflows using `steps:` format are no longer supported.
Convert to `nodes:` (DAG) format. The loader provides a clear error message
directing users to the migration guide.

* fix: address review findings — guard errors, remove dead code, add tests

- Guard logNodeSkip/logWorkflowError against filesystem errors in dag-executor
- Move mkdir(artifactsDir) inside try-catch with user-friendly error
- Remove startFromStep dead parameter from executeWorkflow signature
- Remove isDagWorkflow() tautology and all callers (20+ sites)
- Remove dead BuilderMode/mode state from frontend components
- Remove vestigial isLoop, selectedStep, stepIndex, step_index fields
- Remove "DAG" prefix from user-facing resume/error messages
- Fix 5 stale docs (README, getting-started, authoring-commands, web adapter)
- Update event-emitter tests to use node events instead of removed step events
- Add executor-shared.test.ts (12 tests) for substituteWorkflowVariables
- Add executor.test.ts (11 tests) for concurrent-run, model resolution, resume

* fix(workflows): add migration guide, port preamble tests, improve error message

- Add docs/sequential-dag-migration-guide.md with 3 conversion patterns
  (single step, chain with clearContext, parallel block) and a Claude Code
  migration command for automated conversion
- Update loader error message to point to migration guide and include
  ready-to-run claude command
- Port 8 preamble tests from deleted executor.test.ts to new
  executor-preamble.test.ts: staleness detection (3), concurrent-run
  guard (3), DAG resume (2)

Addresses review feedback from #805.

* fix(workflows): update loader test to match new error message wording

* fix: address review findings — fail stuck runs, remove dead code, fix docs

- Mark workflow run as failed when artifacts mkdir fails (prevents
  15-min concurrent-run guard block)
- Remove vestigial totalSteps from WorkflowStartedEvent and executor
- Delete dead WorkflowToolbar.tsx (369 lines, no importers)
- Remove stepIndex prop from StepLogs (always 0, label now "Node logs")
- Restore cn() in StatusBar for consistent conditional classes
- Promote resume-check log to error, add errorType to failure logs
- Remove ghost $PLAN/$IMPLEMENTATION_SUMMARY from docs (never implemented)
- Update workflows.md rules to DAG-only format
- Fix migration guide trigger_rule example
- Clean up blank-line residues and stale comments

* fix: resolve rebase conflicts with #729 (forkSession) and #730 (dashboard)

- Remove sequential forkSession/persistSession code from #729 (dead after
  sequential removal)
- Fix loader type narrowing for DagNode context field
- Update dashboard components from #730 to use dagNodes instead of steps
- Remove WorkflowStepEvent/ParallelAgentEvent from dashboard SSE hook
2026-03-26 11:27:34 +02:00
Cole Medin
671004528b docs: add prerequisites section to README quickstart
Add collapsible prerequisites with install commands for Node.js,
GitHub CLI, and Claude Code above the quickstart section.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 08:49:05 -05:00
Cole Medin
f6680248bc docs: add "Using Archon on Your Project" and "Web UI" sections to README
- Add section bridging installation to usage: two paths (from Archon repo
  or copy skill to your repo), auto-registration, agent-first philosophy
- Add standalone Web UI section with key pages (Chat, Dashboard, Workflow
  Builder, Execution) and monitoring hub callout (all-platform visibility)
- Add workflow count note (16 total) to "What Can You Automate?" table

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 17:13:22 -05:00
Rasmus Widing
392a13ab90 fix(docs): address review findings from PR #734
- Fix stale port 3000 → 3090 in ngrok/Cloudflare tunnel commands
- Fix workflow names to use actual archon- prefixed names throughout README
- Split ralph into ralph-fresh and ralph-stateful variants
- Fix "Future: workflow definitions" → actual shipped feature label
- Fix directory structure to show project-centric layout (not legacy)
- Add missing TELEGRAM_ALLOWED_USER_IDS documentation
- Add docs/adapters/slack.md for consistent adapter doc pattern
- Update README platform table to link to new slack adapter doc
2026-03-19 09:02:42 +01:00
Rasmus Widing
f8661677e8 refactor(docs): restructure README and extract content to /docs
Slim README from 1576 to 200 lines. Focus on value prop (deterministic
AI coding workflows), quickstart paths (AI-assisted, CLI, Web UI), and
bundled workflow showcase.

All reference content moved to dedicated docs:
- docs/adapters/ — per-platform setup guides
- docs/ai-assistants.md — Claude/Codex auth details
- docs/database.md — SQLite/PostgreSQL guide + schema
- docs/deployment.md — Docker + local dev setup
- docs/commands-reference.md — all slash commands
- docs/troubleshooting.md — common issues and fixes
- docs/windows.md — Windows/WSL2 guide
- docs/configuration.md — added streaming, concurrency, health endpoints
2026-03-19 09:02:42 +01:00
Rasmus Widing
845c816226
feat: default worktree isolation for CLI + auto-detect base branch (#692)
* feat: default worktree isolation for CLI + auto-detect base branch

- CLI now creates a worktree by default (matching all other adapters)
- Branch names auto-generated as {workflowName}-{timestamp}
- --no-worktree opts out of isolation (standalone flag, no longer requires --branch)
- All generated branch names prefixed with archon/ for clear namespace
- Base branch auto-detected from git (symbolic-ref → origin/main → origin/master)
- Config worktree.baseBranch still overrides auto-detection
- $BASE_BRANCH in workflow prompts auto-resolves without config
- Ignore .claude/skills/ from ESLint

* fix: address PR review findings — error handling, tests, docs

- Add warn log for silent getDefaultBranch catch in executor.ts
- Fix branchToSync bug: don't pass fromBranch as sync target
  (fromBranch is the worktree start-point, not the base to sync)
- Add user-facing warning when isolation is silently skipped
- Add errorType to codebase_auto_registration_failed log
- Consolidate all validation guards in workflowRunCommand
  (cli.ts keeps them for UX fast-path, workflowRunCommand is
  the authoritative boundary for programmatic callers)
- Add tests: validation guards, default isolation, --no-worktree
  skip, isolation-skipped warning, auto-detect $BASE_BRANCH success
- Add loadRepoConfig to @archon/core mock in workflow tests
- Update docs: CLAUDE.md, cli-user-guide, configuration,
  authoring-workflows, worktree-orchestration, README, cli.md rule
  — all updated for default isolation, archon/ prefix, optional
  baseBranch with auto-detection

* refactor: simplify isolation branch logic and fix log naming

- Split shouldIsolate into wantsIsolation + codebase check to
  eliminate redundant double-check of codebase
- Simplify else-if chain: use wantsIsolation instead of re-testing
  already-false conditions
- Deduplicate isolation-skipped warning messages
- Fix log event: base_branch.auto_detect_failed →
  workflow.base_branch_auto_detect_failed (project naming convention)

* fix: fail fast when isolation cannot be created instead of silent fallback

When the user hasn't opted out with --no-worktree, failing to create
a worktree (DB error or not in a git repo) now throws instead of
silently running in the live checkout. This prevents AI from making
unprotected changes to the working tree.

* chore: Auto-commit workflow artifacts (archon-assist)
2026-03-17 13:39:41 +02:00
Rasmus Widing
5901defc93
feat: add per-node skills for DAG workflows (#446) (#689)
* feat: add per-node skills for DAG workflows (#446)

Add `skills: [name, ...]` field to DAG workflow nodes. When a node has
skills, the executor wraps it in an AgentDefinition that preloads those
skills into the subagent context. 'Skill' is auto-added to allowedTools.

- Add skills field to DagNodeBase type and loader validation
- Add agents + agent fields to WorkflowAssistantOptions and
  AssistantRequestOptions for AgentDefinition wrapping
- Pass agents/agent through ClaudeClient to SDK Options
- Build AgentDefinition with preloaded skills in dag-executor
- Add Codex warning (per-node skills not supported)
- Add skills comma-separated input in Web UI NodeInspector
- Add skills to WorkflowCanvas reactFlowToDagNodes conversion
- Add 5 unit tests for skills parsing validation

* feat: add Remotion video generation workflow and skills/MCP docs

Add archon-remotion-generate as a bundled default workflow that uses
per-node skills (remotion-best-practices) to generate Remotion video
compositions with AI, then renders preview stills and full video via
deterministic bash nodes.

- Add archon-remotion-generate.yaml to defaults
- Add docs/remotion-workflow.md with setup guide and examples
- Add docs/skills.md documenting per-node skills feature (#446)
- Register workflow in bundled-defaults.ts for binary builds

* chore: gitignore skills-lock.json

* fix: address review feedback for per-node skills (#446)

- Always pass ['Skill'] in AgentDefinition.tools instead of undefined
- Surface buildPromptWithContext errors to user via safeSendMessage
- Use AgentDefinition from SDK in AssistantRequestOptions (remove cast)
- Warn and skip non-object MCP server configs instead of silent passthrough
- Include JSON parse error detail in loadMcpConfig error messages
- Add 3 executor-level tests for skills options construction
- Update bundled-defaults test count for remotion workflow
- Add skills to CLAUDE.md, authoring-workflows.md, README.md, hooks.md
- Clean up loader skills validation with type predicate
2026-03-17 09:21:47 +02:00
Rasmus Widing
7af8745ddb
feat: add per-node MCP servers for DAG workflows (#445) (#688)
* feat: add per-node MCP servers for DAG workflows (#445)

Add `mcp: path/to/config.json` field to DAG workflow nodes. At execution
time, the executor reads the MCP config JSON, expands $VAR_NAME env
references in env/headers values, and passes the loaded servers to the
Claude Agent SDK via Options.mcpServers. MCP tool wildcards are auto-
added to allowedTools.

- Add mcp field to DagNodeBase type and loader validation
- Add mcpServers + allowedTools to WorkflowAssistantOptions and
  AssistantRequestOptions
- Pass mcpServers/allowedTools through ClaudeClient to SDK Options
- Handle system/init message to detect MCP connection failures
- Add Codex warning (per-node MCP not supported)
- Add Haiku warning (tool search not supported)
- Add MCP config path input in Web UI NodeInspector
- Add mcp to WorkflowCanvas reactFlowToDagNodes conversion
- Add 12 unit tests for loadMcpConfig and env var expansion

* fix: address review findings for per-node MCP servers

Type safety:
- Use SDK McpServerConfig type in AssistantRequestOptions (eliminates unsafe cast)
- Update WorkflowAssistantOptions.mcpServers to proper discriminated union
- Remove redundant cast in claude.ts

Error handling:
- Warn users when MCP config references undefined env vars
- Check safeSendMessage return value for MCP connection failures
- Check safeSendMessage return value for Haiku MCP warning
- Log unhandled system messages at debug level in both claude.ts and dag-executor.ts
- Coerce non-string env/header values with warning instead of silent passthrough

Code quality:
- Fix log event naming: dag_node_mcp_* → dag.mcp_* (domain.action_state format)
- Replace IIFE in loader mcp validation with plain if/else
- Extract duplicated env expansion logic into expandEnvVarsInRecord helper
- Merge split import from ./deps into single statement
- Return missingVars from loadMcpConfig/expandEnvVars for caller awareness

Documentation:
- Add mcp field to Node Fields table in docs/authoring-workflows.md
- Add mcp to DAG schema example, allowed_tools section, and summary list
- Add mcp to CLAUDE.md DAG feature list
- Add per-node MCP servers paragraph to README.md tool restrictions section

* docs: add MCP servers guide (docs/mcp-servers.md)

Comprehensive guide covering config file format (stdio/HTTP/SSE), env var
expansion, automatic tool wildcards, MCP-only nodes, connection failure
handling, workflow examples, troubleshooting, and popular server list.
Cross-referenced from authoring-workflows.md and CLAUDE.md.

* feat: add optional ntfy push notification to smart PR review

Add conditional notify node to archon-smart-pr-review workflow that sends
a push notification when the review completes. Gated behind a bash node
that checks for .archon/mcp/ntfy.json — silently skipped if not configured.

- Add check-ntfy bash node + notify MCP node to smart PR review workflow
- Add .archon/mcp/ to .gitignore (per-user MCP configs may contain secrets)
- Add "Push Notifications" setup guide to docs/mcp-servers.md
2026-03-16 20:24:45 +02:00
Rasmus Widing
4054ff18c5
fix: require explicit base branch config for worktree creation (#686)
* fix: require explicit base branch config for worktree creation

When no `worktree.baseBranch` is configured in .archon/config.yaml,
the system silently fell back to `getDefaultBranch()` which always
resolved to `main`. This caused worktrees to branch from main instead
of the intended branch (e.g., dev), producing merge conflicts.

Now errors with actionable message when no base branch is set:
"Set worktree.baseBranch in .archon/config.yaml or use --from flag"

The --from flag continues to work as an override for one-off cases.
Cleanup service still uses getDefaultBranch for merge checks.

Also adds .archon/config.yaml with baseBranch: dev for this project.

* fix: scope $BASE_BRANCH validation and improve error handling

- Make $BASE_BRANCH resolution lazy: only fail when a workflow step
  actually references the variable, not on every workflow execution
- Surface config load errors distinctly from missing-value errors in
  worktree provider (was masking real cause behind generic message)
- Add 'no base branch configured' to known isolation error patterns
  so the error is classified and shown to users properly
- Add tests for baseBranch/fromBranch precedence and non-task
  workflowType behavior
- Update stale docs referencing removed auto-detection fallback
  across CLAUDE.md, README.md, and docs/

* fix: configure isolation loader in CLI workflow command

The CLI was calling getIsolationProvider() without first calling
configureIsolation(), so the worktree provider had no way to load
.archon/config.yaml — all worktree creation failed with "No base
branch configured" even when config existed.
2026-03-16 15:05:16 +02:00
Rasmus Widing
33c329f6db
feat: visual workflow builder with React Flow (#471)
* feat: add visual workflow builder with React Flow

Replace the "Coming Soon" stub at /workflows/builder with a full visual
workflow editor supporting all three modes:

- DAG mode: React Flow canvas with drag-and-drop from command palette,
  edge drawing between nodes, Dagre auto-layout, and full node inspector
- Sequential mode: sortable step list with parallel block grouping
- Loop mode: config panel for prompt/until/max_iterations/fresh_context

Toolbar provides validate, save, and run actions using existing backend
APIs. Existing workflows can be loaded for editing via dropdown or
?edit= URL param. Mode switching with unsaved changes shows confirmation.

Also exports DagNode types from @archon/core, adds 5 new API client
functions (getWorkflow, saveWorkflow, deleteWorkflow, validateWorkflow,
listCommands), and fixes WorkflowDefinitionResponse to use the real
WorkflowDefinition type.

* docs: update docs for visual workflow builder

- Fix directory structure: pages/ → routes/, add workflows to components
- Add visual workflow builder to Web UI features in README

* fix: address review findings in workflow builder

- Move auto-load from render-time side effect to useEffect
- Add fallthrough handling for unrecognized workflow types
- Add promptText as explicit property on DagNodeData, remove double casts
- Consolidate DagFlowNode type alias to single export
- Replace Date.now() node IDs with crypto.randomUUID()
- Use node.id instead of node.data.id in reactFlowToDagNodes
- Remove as WorkflowDefinition casts, inline properties for union safety
- Add try-catch around dagre.layout() and guard undefined pos
- Surface useQuery errors in NodePalette and WorkflowToolbar
- Separate JSON.parse from onUpdate in catch block, show parse details
- Add separate runError state, clear stale errors, handle orphaned conversations

* feat: add parallel block inspector, editing, and ungrouping

- Add ParallelBlockInspector component with sub-step editing
  (command, clearContext, allowed/denied tools)
- Add/remove sub-steps within a parallel block
- Auto-ungroup when fewer than 2 sub-steps remain
- Ungroup button in both inspector panel and step row
- Delete block action in inspector

* fix: address PR review findings in workflow builder

- Fix prompt text data loss: map prompt → promptText in dagNodesToReactFlow
- Add key prop to NodeInspector to prevent stale state on node switch
- Log dagre layout errors instead of silently swallowing
- Surface listCommands query errors with visible banner
- Block run when unsaved changes; don't navigate on failure
- Validate before save to avoid raw server error messages
- Add console.error to loadWorkflow and validation catch blocks
- Surface workflow list load error in feedback row
- Differentiate network errors from validation errors
- Add readonly to SequentialEditor steps prop
- Add JSDoc on DagNodeData, ParallelBlockInspectorProps, WorkflowCanvasProps

* feat: add Beta badge to Workflow Builder nav link

* feat: add bash node type and smart PR review DAG workflow

Add a `bash` node type for DAG workflows that runs shell scripts without
AI, capturing stdout as node output. This enables free/deterministic
operations like gathering stats or running git commands within DAG
workflows.

- BashNode type with `bash` script field and optional `timeout`
- Three-way mutual exclusivity in parser (command/prompt/bash)
- executeBashNode with variable substitution, stderr logging, timeout
- Web UI: BASH badge, script editor, timeout input, draggable palette item

Also add archon-smart-pr-review DAG workflow that classifies PR complexity
first (via haiku), then routes to only the relevant review agents based
on the classification. Saves AI calls on trivial/small PRs.

* docs: document bash node type in DAG workflow section

The bash: node type added in this PR was missing from the workflow
documentation. Users writing DAG workflows need to know the three
available node types: command:, prompt:, and bash:.

* fix: address review findings in workflow builder

- Add console.error to handleSave/handleRun catch blocks (was silently swallowing errors)
- Fix allowed_tools/denied_tools using || instead of ?? (empty array [] was converted to undefined, changing semantics)
- Remove unnecessary type assertions in resolveNodeDisplay that bypass TS narrowing
- Add justification comments to as DagNode casts (required by project guidelines)
- Add error details to NodePalette failed commands message
- Use exhaustive switch in buildDefinition with never check
- Fix NodeInspector comments: "AI-only fields" was incomplete, "Output Format" guard was misleading
- Separate serialize/parse try-catch in validate endpoint for clearer error messages
- Classify ENOENT/EACCES errors in executeBashNode for user-friendly messages
- Document intentional Dagre layout fallback per project guidelines
2026-02-25 14:09:53 +02:00
Rasmus Widing
9def2a5ebd
feat: per-node and per-step tool restrictions (allowed_tools, denied_tools) (#454)
* feat: add per-node and per-step tool restrictions (allowed_tools, denied_tools)

Add `allowed_tools` (whitelist) and `denied_tools` (blacklist) fields to DAG
nodes and sequential steps, enforced at the Claude SDK level via Options.tools
and Options.disallowedTools.

- Extend AssistantRequestOptions with disallowedTools field
- Add allowed_tools/denied_tools to DagNodeBase and SingleStep types
- Parse and validate the arrays in parseDagNode and parseSingleStep
- Spread disallowedTools into Claude SDK Options in claude.ts
- Apply per-node restrictions in resolveNodeProviderAndModel (dag-executor)
- Merge per-step restrictions in executeStepInternal (executor)
- Emit Codex warning when these fields are set (unsupported per-call)
- Preserve empty allowed_tools: [] distinct from absent (disables all tools)

* docs: document allowed_tools and denied_tools for workflow tool restrictions

Add allowed_tools/denied_tools to the Step Options and Node Fields tables
in authoring-workflows.md, add a dedicated section with examples, update
the Summary list, and add a brief mention in README.md and CLAUDE.md.

* refactor: extract parseToolList helper, simplify tool restriction parsing

Extract duplicated allowed_tools/denied_tools parsing logic from
parseSingleStep and parseDagNode into a shared parseToolList helper.
Replaces nested ternaries and IIFE patterns with straightforward
conditionals. Simplify stepOptions construction in executor.ts to
use explicit if-statements instead of nested spreads.

* fix: address PR review issues in tool restriction validation and delivery

- parseSingleStep: add error propagation for non-array allowed_tools/denied_tools (return null on failure)
- parseDagNode: return null when tool field validation adds errors (errorsBeforeToolFields guard)
- parseToolList: warn on non-string entries for steps (id always passed now)
- Add warning when denied_tools is set alongside allowed_tools: []
- executor.ts: make Codex and Claude paths mutually exclusive (no dead tool fields built for Codex)
- dag-executor.ts: check safeSendMessage return for both output_format and tool restriction warnings, log error on delivery failure
- Add tests: denied_tools-only Codex warning, both tools on same step, merged options with model, DAG execution-level tool restriction tests
2026-02-19 14:48:27 +02:00
Rasmus Widing
a315617b73
feat: DAG workflow engine with parallel execution and conditional branching (#450)
* feat: add DAG workflow engine with parallel execution and conditional branching

Adds a third workflow execution mode (`nodes:`) alongside `steps:` and `loop:`.
DAG workflows support explicit dependency edges, parallel layer execution via
Promise.allSettled, conditional branching with `when:` expressions, join semantics
via `trigger_rule`, structured JSON output via Claude SDK `outputFormat`, and
upstream output capture via `$node_id.output` substitution.

- New: `DagNode`, `DagWorkflow`, `TriggerRule`, `NodeOutput`, `NodeState` types
- New: `condition-evaluator.ts` — pure `evaluateCondition` for `when:` expressions
- New: `dag-executor.ts` — topological sort, Promise.allSettled parallel layers,
  output capture, trigger rule evaluation, per-node provider/model resolution
- Updated: `loader.ts` — detect `nodes:` key, validate node graph, Kahn cycle detection
- Updated: `executor.ts` — route DAG workflows to dag-executor before loop dispatch
- Updated: `logger.ts` / `event-emitter.ts` — node_start/complete/skip/error events
- Updated: `workflow-bridge.ts` — SSE events for dag_node state changes
- Updated: `AssistantRequestOptions` — added `outputFormat` for Claude structured output
- Updated: `claude.ts` — thread `outputFormat` into SDK Options
- Tests: 37 new tests (condition-evaluator + dag-executor topological sort, trigger
  rules, loader cycle detection, invalid DAG rejection, valid DAG parsing)

* docs: document DAG workflow mode (nodes:) added in phase 1

Add full documentation for the new `nodes:` execution mode:
- docs/authoring-workflows.md: add third workflow type section,
  full DAG schema reference (node fields, trigger_rule, when:
  conditions, output_format, $nodeId.output substitution), a
  DAG example workflow, and update the variable table and summary
- CLAUDE.md: add nodes:/DAG bullet points to the Workflows section
- README.md: add nodes: example alongside steps: and loop:, update
  key design patterns to mention DAG mode

* fix: address DAG workflow engine review findings

Critical bugs:
- DB workflow status never updated after DAG completion (completeWorkflowRun/failWorkflowRun now called)
- resolveNodeProviderAndModel throws silently swallowed by Promise.allSettled — now caught and returned as failed node outputs
- substituteNodeOutputRefs JSON parse failure was silent — now logged as warn

Important fixes:
- Surface unparseable when: conditions to user via safeSendMessage (fail-open preserved)
- Missing upstream nodes treated as failed in checkTriggerRule instead of silently filtered out
- Config load failure in loadCommandPrompt upgraded from warn to error
- Circular import executor ↔ dag-executor broken via new command-validation.ts module
- Remove defensive "should never happen" else branch in executeNodeInternal (DagNode discriminated union guarantees it)

Type improvements:
- DagNode → CommandNode | PromptNode discriminated union (command/prompt mutually exclusive at type level)
- NodeOutput → discriminated union (error: string required on failed, absent on others)
- TRIGGER_RULES constant and isTriggerRule() added to types.ts, deduplicating loader.ts local definitions
- isDagWorkflow simplified to Array.isArray(workflow.nodes)
- output_format array guard in parseDagNode now rejects arrays and null values

Code quality:
- Replace all void workflowEventDb.createWorkflowEvent() with .catch() error logging
- Fix o.error ?? 'unknown' to o.state === 'failed' ? o.error : 'unknown' (type-safe)
- Export substituteNodeOutputRefs for unit testing

Tests (7 new):
- condition-evaluator: number and boolean JSON field coercion
- dag-executor: none_failed_min_one_success with all-skipped deps, nodes+loop conflict,
  invalid trigger_rule rejection, substituteNodeOutputRefs (3 cases), all-nodes-skipped mechanism

* docs: fix two inaccuracies in DAG workflow documentation

- README: "Nodes without depends_on run in parallel" was misleading —
  root nodes run concurrently with each other in the same layer, but a
  single root node doesn't run "in parallel" with anything. Reworded to
  "are in the first layer and run concurrently with each other".

- authoring-workflows.md: Variable Substitution section intro said
  "Loop prompts and DAG node prompts/commands support these variables"
  but step-based workflows also support the same variables via
  substituteWorkflowVariables in executor.ts. Updated to say all
  workflow types.

* fix: address PR #450 review findings in DAG workflow engine

Correctness:
- Remove throw from !anyCompleted path to prevent double workflow_failed
  emission; add safeSendMessage and return instead
- Guard lastSequentialSessionId assignment against undefined overwrite

Type safety:
- Narrow workflowProvider from string to 'claude' | 'codex' in
  resolveNodeProviderAndModel and executeDagWorkflow signatures
- Remove unsafe 'as claude | codex' cast
- Add compile-time assertion that NodeOutput covers all NodeState values

Silent failure surfacing:
- Pre-execution node failure now notifies user via safeSendMessage
- Unexpected Promise.allSettled rejection notifies user and logs layerIdx
- completeWorkflowRun DB failure notifies user of potential inconsistency
- Codex node with output_format now warns user (not just server log)
- Make resolveNodeProviderAndModel async to support the above

Dead code:
- Remove unused 'export type { MergedConfig }' re-export

Comments:
- Update safeSendMessage/substituteWorkflowVariables/loadCommandPrompt
  TODOs to reflect Rule of Three is now met
- Fix executeNodeInternal docstring to mention context:'fresh' nodes
- Fix evaluateCondition @param: "settled" not "completed" upstreams
- Fix NodeOutput doc: "JSON-encoded string from the SDK"

Tests (7 new):
- substituteNodeOutputRefs: unknown node ref resolves to empty string
- checkTriggerRule: absent upstream synthesised as failed (x2)
- buildTopologicalLayers: two independent chains share layers correctly
- evaluateCondition: valid expression returns parsed: true
2026-02-18 15:13:22 +02:00
Rasmus Widing
d7a6335fa6
fix: prevent router bypass when AI uses tools instead of /invoke-workflow (#449)
* fix: prevent router bypass when AI uses tools instead of /invoke-workflow (#291)

When routing natural language messages to workflows, Claude sometimes used
tools directly instead of outputting `/invoke-workflow {name}`. This left
no fallback — the raw AI response (often with tool output) was sent to the
platform and the expected workflow never ran.

- Pass `tools: []` to the Claude SDK for routing calls (hard SDK constraint,
  not just a prompt instruction) so tools are unavailable during routing
- Add tool-avoidance instruction to the router prompt as belt-and-suspenders
- Detect Codex tool bypass in the stream/batch loop and suppress tool events
  from the platform during routing
- Fall back to `archon-assist` in `tryWorkflowRouting` when no
  `/invoke-workflow` is found — covers both Claude prompt misses and Codex
  tool bypass (where no assistant text is produced at all)
- Log distinct events: `router.tool_bypass_detected`,
  `router.codex_tool_bypass_fallback`, `router.fallback_to_assist`,
  `router.assist_workflow_not_found`

Tests: tools:[] assertion, archon-assist fallback, raw response fallback,
Codex all-tool path

* docs: document router fallback behavior and tool restriction

Update CLAUDE.md and README.md to reflect the new routing behavior:
- Router falls back to archon-assist when no /invoke-workflow is produced
- Claude routing calls pass tools: [] to prevent tool use at the API level
- Codex tool bypass is detected and triggers the same archon-assist fallback

* fix: address review findings from PR #449

- Fix silent failure: send error message when Codex uses tools during
  routing but no archon-assist fallback exists (both stream and batch mode)
- Remove mutable hadTool field from WorkflowRoutingContext; pass as
  explicit parameter to tryWorkflowRouting instead
- Downgrade router.assist_workflow_not_found from warn to debug since
  it fires on every normal routing response without archon-assist
- Add conversationId to router.tool_bypass_detected log for correlation
- Add JSDoc to AssistantRequestOptions.tools documenting undefined vs []
  semantics and Codex no-op behavior
- Add batch-mode Codex tool-bypass test (hadToolBatch path was untested)
- Add test for Codex not receiving tools: [] (documents SDK contract)
- Add test for silent failure case when no archon-assist and tool bypass
2026-02-18 13:16:14 +02:00
Cole Medin
f2a0d029e7 SQLite-first docs, fix Postgres workflow_runs default, rebuild combined schema
- Fix workflow_runs.status DEFAULT from 'running' to 'pending' in Postgres
  (migration 018) to match SQLite and actual code flow
- Rebuild 000_combined.sql as clean final schema (7 tables, no stale columns,
  correct defaults, all indexes)
- Update all docs to present SQLite as the default, zero-setup option
- Mark PostgreSQL as optional/advanced in README, CLAUDE.md, and guides

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 11:23:59 -06:00
Rasmus Widing
7dc2e444f9
Deprecate database command templates (#425)
* Fix: Deprecate database command templates (#231)

Database command templates still influenced routing and /command-invoke, preventing file-based commands from fully replacing them.

Changes:
- Remove template routing, handlers, and DB module
- Add .archon/commands fallback for /command-invoke
- Drop template table from schema/migrations and update docs/tests

Fixes #231

* docs: update CLAUDE.md and README.md for template deprecation

Remove all references to deprecated database command templates:
- Update table count from 8 to 7 tables
- Remove command_templates table from database schema sections
- Remove "Command Templates (Global)" section from README
- Remove /template-add, /template-delete, /templates command docs
- Update "Custom command templates" to "Custom commands"
- Remove references to global templates stored in database

* Fix review findings: error handling, tests, migration guidance

- Fix commandFileExists to only catch ENOENT, throw on unexpected
  errors (permissions, I/O) instead of silently returning false
- Add test for file read failure after successful existence check
- Add test for path traversal rejection via isValidCommandName
- Add test for registered command taking precedence over fallback
- Add migration guidance comments for users with existing templates
2026-02-17 16:55:17 +02:00
Rasmus Widing
7c9e14e533
Fix documentation gaps and stale code examples (#246, #367) (#403)
* Fix documentation gaps and stale code examples (#246, #367)

README assumed psql on host for Docker setups (schema auto-inits via
docker-entrypoint-initdb.d). CLAUDE.md had an empty Git Operation Errors
section. architecture.md showed old inline-concatenation pattern for
context injection. executor.ts had an orphaned JSDoc block.

Changes:
- Remove misleading psql command from README, add auto-init note
- Fill Git Operation Errors section with classifyIsolationError pattern
- Update Context Injection docs to match current contextToAppend approach
- Remove duplicate JSDoc on executeStepInternal

Fixes #246
Fixes #367

* Address self-review findings

- Remove broken #database-migrations anchor link from README note
- Use generic comment placeholder instead of fictional worktreeProvider API in CLAUDE.md
2026-02-17 13:04:19 +02:00
DIY Smart Code
2c378b9f14
Fix: Remove misleading psql command from Docker setup (#246) (#405)
README.md instructs users to run `psql $DATABASE_URL < migrations/000_combined.sql`
for Docker-based PostgreSQL setup, but this requires a locally-installed psql client
that Docker-only users don't have. The migration is already auto-executed on first
container startup via the init.d mount in docker-compose.yml.

Changes:
- Removed unnecessary psql command from README Optional PostgreSQL section
- Added note clarifying that schema is created automatically for Docker installs

Fixes #246

Co-authored-by: leex279 <leex279@users.noreply.github.com>
2026-02-17 13:03:08 +02:00
Rasmus Widing
bc581ff2a8
Fix PRs targeting wrong base branch instead of configured one (#387)
* Investigate issue #377: PRs hardcoded to main instead of configured base branch

* Fix PRs targeting wrong base branch instead of configured one (#377)

Workflow command templates hardcoded `main` as the base branch for PR creation,
git diffs, rebases, and output display. The `baseBranch` config from
`.archon/config.yaml` was correctly used for worktree creation but never
passed through to these workflow command templates.

Changes:
- Add base branch detection (config -> repo default fallback) to archon-finalize-pr, archon-create-pr, and archon-plan-setup
- Add --base flag to gh pr create in archon-finalize-pr
- Replace hardcoded origin/main references with $BASE_BRANCH variable
- Fix output templates to show actual base branch instead of hardcoded "main"
- Fix conflict resolution instructions in archon-pr-review-scope to use {base} variable

Fixes #377

* Fix remaining hardcoded main references caught in self-review

- archon-create-pr.md: Fix alternative gh pr create --fill to use $BASE_BRANCH
- archon-create-pr.md: Fix error handling rebase instruction to use $BASE_BRANCH
- archon-plan-setup.md: Fix error handling merge conflict message to use $BASE_BRANCH

* Fix hardcoded main references in remaining command templates

Extends the base branch fix to all command templates:
- archon-implement.md: Add base branch detection, fix rebase and decision table
- archon-implement-issue.md: Add base branch detection, fix rebase and checkpoint
- archon-implement-review-fixes.md: Fix branch check text
- archon-plan-setup.md: Fix decision table and error message text
- archon-pr-review-scope.md: Fix "Behind Main" labels and comments

* Add $BASE_BRANCH as a system variable for workflow commands

Resolve base branch in TypeScript (from config or git auto-detection)
and substitute $BASE_BRANCH in command templates, replacing the
duplicated 7-line shell detection snippet across 5 templates.

- Add baseBranch field to MergedConfig, propagate from repo config
- Resolve baseBranch once per workflow in executor via
  config.baseBranch ?? getDefaultBranch(cwd)
- Thread baseBranch through substituteWorkflowVariables and all
  execution paths (step, parallel, loop)
- Remove shell detection blocks from archon-finalize-pr,
  archon-create-pr, archon-plan-setup, archon-implement, and
  archon-implement-issue templates
- Add test for $BASE_BRANCH substitution following $ARTIFACTS_DIR
  test pattern

* docs: Add $BASE_BRANCH variable to documentation

* Fix $BASE_BRANCH shell variable collision and add error handling

- Rename shell variables BASE_BRANCH→PR_BASE in 3 templates
  (pr-review-scope, resolve-merge-conflicts, sync-pr-with-main)
  to avoid collision with Archon-level $BASE_BRANCH substitution
- Wrap getDefaultBranch() in try-catch with user notification
- Add baseBranch resolution logging matching provider pattern
- Restore user override capability in archon-create-pr
- Add .trim() validation for whitespace-only baseBranch config
- Improve MergedConfig.baseBranch docstring with fallback info
- Add tests for config-driven baseBranch precedence
- Add config-loader tests for baseBranch extraction and trimming
2026-02-16 14:41:09 +02:00
Cole Medin
352171474b
Archon Web UI: React frontend, web adapter, API routes, workflow events
* Archon UI PRD and phase 1 plan

* Initial Archon UI

* Workflow tracking

* UI improvements (with a couple schema changes)

* Message history for web adapter and UI adjustments

* Chat/Project/Tasks in Archon UI

* UI fixes

* UI fixes

* UI improvements

* Fix PR review issues: type safety, error handling, cleanup, docs

- Convert MessageChunk to discriminated union with workflow_dispatch variant
- Add IWebPlatformAdapter interface and isWebAdapter() type guard
- Replace unsafe 'in' type guards with proper type narrowing in orchestrator
- Add logging to silent catch blocks in api.ts, web.ts
- Add WebAdapter buffer cleanup with 60s delayed cleanup on disconnect
- Wrap SQLite migration ALTER TABLE groups in try/catch
- Log SSE parse errors in useSSE.ts
- Truncate API error bodies to 200 chars, include URL path
- Surface background workflow errors to parent conversation
- Fix getWorkflowRunByWorker to only swallow 404s, re-throw 500s
- Add documentation comments to ChatMessage and SSEEvent types
- Update table counts from 3/5/6 to 8 across all docs

* Remove agent plan files from PR, gitignore .agents/plans/

These are local development artifacts that shouldn't be in the repo.

* Gitignore .claude/PRPs/

* Fix PR review issues: error handling, type safety, silent failures

- Fix acquireLock error swallowing: wrap handler in try/catch/finally to
  always release UI lock and surface errors to SSE stream
- Restrict CORS to configurable origin (WEB_UI_ORIGIN env var)
- Validate status query param instead of unsafe `as` cast
- Add per-codebase JSON.parse error isolation for corrupted commands
- Type request body in POST /api/conversations
- Return 404 for missing conversation instead of empty array
- Add warning log when flushAssistantMessage has no DB ID mapping
- Add debug logging to 6 SSE catch blocks (was silently swallowing)
- Replace 17x .catch(() => undefined) with void on fire-and-forget calls
- Make workflow status='running' update a blocking error
- Split MessageChunk into proper per-type discriminated union
- Add hidden field to Conversation interface
- Add guard in addMessage for undefined row
- Extract WorkflowRunStatus/WorkflowStepStatus type aliases
- Fix WorkflowArtifact.type to use literal union
- Separate SSE parse errors from handler errors in useSSE hook
- Gitignore e2e testing session artifact

* Wire up dead endpoints: workflow run UI, health display, worker→run link

- Extract dispatchToOrchestrator() helper to deduplicate lock/dispatch
  logic between message send and workflow run endpoints
- Fix workflow run endpoint to construct /workflow run <name> <msg>
  from URL param + body, with name validation
- Add run panel to WorkflowList with message input, error display,
  and navigation to chat on success
- Add System Health section to SettingsPage with independent query
  and actionable error messages
- Add worker→run navigation link in WorkflowExecution header
- Regenerate 000_combined.sql to include migrations 001-015
- Fix silent .catch() patterns: log errors instead of swallowing
- Wrap emitSSE in catch block, log full error objects

* Fix routing for conversation IDs with special characters

GitHub issue conversation IDs like "user/repo#42" contain / and #
which break React Router's :param matching. Fix by:
- Use /chat/* splat route instead of /chat/:conversationId
- encodeURIComponent() all platform_conversation_id values in URLs
- decodeURIComponent() in ChatPage when reading the splat param

* Restructure sidebar: project selector nav, remove dead components

Replace multi-view sidebar (ChatView, ProjectView, TaskView, ViewSwitcher)
with a simpler project-scoped navigation. Add ProjectSelector component
for switching between codebases. Remove unused ConversationsList,
useNotifications hook, and related dead code.

* Add project CRUD: clone/register from UI, delete with cleanup

Extract clone logic from command-handler into standalone clone.ts module
with cloneRepository() and registerRepository() entry points. Add REST
endpoints POST /api/codebases (clone URL or register local path) and
DELETE /api/codebases/:id (destroy worktrees, unlink DB, remove workspace).

Update sidebar with "+" button for inline project add input that auto-detects
URL vs local path, and hover-to-delete with AlertDialog confirmation on each
project in ProjectSelector.

* Harden backend guard rails, polish UX, remove dead project pages

Backend:
- Guard output callback and cleanup timer with try-catch
- Add zombie stream reaper (5min interval) with proper cleanup
- Force-flush assistant buffer at 50 segments to prevent unbounded growth
- Log warning on message buffer overflow
- Emit SSE warning when user message persistence fails

Frontend:
- Show spinner on send button while processing
- Add native tooltip on truncated conversation titles
- Make sidebar resize handle visible with subtle background

Dead code:
- Delete orphaned ProjectDetail, ProjectsList, ProjectsPage
- Remove /projects/:id route from App.tsx

* Dashboard landing page, chat empty state, API error quality, SQLite indexes

- Replace DashboardPage redirect with landing page showing recent
  conversations and workflow runs in a two-column grid
- Fix /chat empty state to render ChatInterface in new-chat mode
  instead of a static placeholder
- Add proper HTTP status codes to API: 404 for missing conversations,
  400 for invalid codebase IDs, empty array for failed workflow discovery
- Add 3 missing indexes to SQLite schema from PG migrations 009/010
  (workflow run staleness, session parent, session conversation lookup)

* Scope workflow runs to selected project

Pass the selected project's codebaseId when creating a conversation
for workflow execution. Show which project the workflow will target,
and disable the run controls when no project is selected.

* Inline project selector in workflow invocation panel

Replace static "Running on {project}" text with a <select> dropdown
so users can pick a project without leaving the workflow view.

* Fix chat header showing "No project" and new chat missing project

Header now resolves project name from codebase_id when cwd is absent.
Dashboard "New Chat" creates conversation with selected project instead
of navigating to an orphaned /chat route. Buttons disabled when no
project is selected.

* Sidebar nav, workflow builder route, workflow invoker in project detail

Add Workflows and Workflow Builder nav links to sidebar, extract
navLinkClass helper. Wire WorkflowInvoker into ProjectDetail. Add
WorkflowBuilderPage route. Remove dead redirect routes and unused
Header from pages that don't need it.

* Fix review issues: guard rm-rf, error handling, Error Boundary, dedup utility

- Guard DELETE /api/codebases/:id to only rm-rf paths under ~/.archon/workspaces/
  (externally registered repos only get DB record deleted)
- Remove accidental e2e-testing-findings-session2.md
- Replace 3x .catch(() => undefined) with proper error logging
- Add React Error Boundary at app root to prevent white-screen crashes
- Wrap JSON.parse(metadata) in try-catch in ChatInterface and WorkflowLogs
- Upgrade SSE write failure logging from debug to warn, add missing logging
- Fix bare catch in SSE heartbeat to only swallow disconnect errors
- Remove unused _createErrorHandler parameter from registerApiRoutes
- Extract shared findMarkdownFilesRecursive to packages/core/src/utils/commands.ts
- Convert boolean to integer explicitly for SQLite hidden column
- Surface workflow discovery errors as warning in API response

* Address PR review: error handling, SSE resilience, test coverage

- Fix path traversal in codebase deletion (use normalizedCwd)
- Buffer SSE write failures for reconnect delivery (3 catch blocks)
- Extract flushBufferedMessages helper with partial-failure recovery
- Add defensive outer catch to background workflow dispatch
- Surface API/load errors to users (history, metadata, React Query)
- Add SSE parse validation and handler error surfacing
- Show stale indicator when workflow polling loses connection
- Add delete error handling to ConversationItem dialog
- Import shared types from @archon/core instead of duplicating
- Lower activity update failure threshold from 5 to 3
- Add test coverage for messages.ts and workflow-events.ts (100%)

* docs: Update documentation for Web UI, workflow events, and message persistence

- Update database schema description (workflow_events detail, messages metadata)
- Add Web UI platform adapter to architecture docs
- Document REST API endpoints for Web UI
- Add SSE streaming pattern documentation
- Update conversation schema (title, deleted_at columns)
- Expand Web UI feature list (workflow invocation, message persistence)

* Address PR review: error handling, type safety, SSE resilience

- Add null check on createWorkflowRun INSERT return
- Narrow catch in registerRepoAtPath to not swallow command loading errors
- Add SSE onerror logging and user notification on permanent close
- Add WarningEvent to SSE union and surface warnings in ChatInterface
- Fix WorkflowEventRow.data SQLite type mismatch (parse JSON string)
- Separate conversation lookup from auto-titling error handling
- Fix log levels for data loss scenarios (warn/debug → error)
- Emit SSE warning to user on flushAssistantMessage failure
- Set workflow run parent link regardless of success/failure
- Cap total buffered conversations at 200
- Define ArtifactType once in core, use everywhere
- Use imported status types in SSE event interfaces
- Add exhaustiveness checks in switch statements
- Preserve original git error in registerRepository
- Remove unused recoverable field from ErrorEvent

---------

Co-authored-by: Rasmus Widing <rasmus.widing@gmail.com>
2026-02-16 09:03:44 +02:00
Rasmus Widing
d5c03a29b7 fix: Address review findings (HIGH + MEDIUM)
- Use native SQLite RETURNING (.all()) instead of lastInsertRowid
  emulation, which returned wrong row on ON CONFLICT DO UPDATE
- Remove unused extractInsertTableName method (dead code after fix)
- Fix trailing comma in SQLite schema causing syntax error on fresh init
- Update create() JSDoc to reflect upsert behavior
- Add migration 011 to README upgrade instructions (3 locations)
- Add SQLite adapter tests for INSERT RETURNING + ON CONFLICT

Review artifacts: .archon/artifacts/runs/14ad0f4c-daa1-4fa2-babb-92822620ac7b/review/
2026-01-30 17:29:53 +02:00
Rasmus Widing
9634167911 docs: Document how commands/workflows are loaded (CLI vs server)
Commands and workflows are loaded at runtime from the working directory.
The CLI reads from disk (sees uncommitted changes), while the server reads
from the workspace clone which only syncs from origin before worktree
creation. Added notes to README, getting-started, authoring guides, and
CLI user guide so users understand they need to push changes for the
server to pick them up.
2026-01-30 12:14:17 +02:00
Rasmus Widing
133a3ccc69 feat: Add interactive setup wizard and config editor to Archon skill
Add a complete setup wizard that guides users through first-time Archon
installation on a target repository. The wizard covers CLI installation,
platform selection (GitHub, Telegram, Slack, Discord), .env configuration,
and copying default commands/workflows to the target repo.

Key additions:
- Setup wizard with quick/guided modes (guides/setup.md)
- Interactive config editor for global and repo config (guides/config.md)
- Platform-specific setup guides (GitHub, Telegram, Slack, Discord)
- Config routing in SKILL.md for "change my config" intent
- Freeform input guidelines to prevent double-question UX issues
- .env detection to skip already-configured values
- Move commands/workflows to defaults/ subdirectory
- Clean up old artifacts and SDLC examples
- Add docs/running-on-a-target-repo.md
2026-01-30 10:41:21 +02:00
Rasmus Widing
c142dbbc54
feat(cli): Add git repository safety check (#328)
* feat(cli): Add git repository safety check

Add validation to ensure CLI workflows only run from within a git
repository. If the user runs from a subdirectory, the CLI resolves
to the repo root. Running from a non-git directory produces a clear
error message with guidance.

- Add git.findRepoRoot() check before workflow commands
- Bypass check for version/help commands
- Add tests for git repo validation behavior

* docs: Update CLI documentation for git repository requirement

* fix(cli): Improve error handling and tests for git repo check

- Move git.findRepoRoot() inside try-catch block to ensure proper error
  handling and database cleanup on unexpected errors
- Add path existence validation before git check for clearer error messages
- Improve tests: test real git.findRepoRoot behavior instead of mocks
- Add tests for path validation and command categorization logic
2026-01-22 10:00:12 +02:00
Rasmus Widing
2c5cb65619
docs: Add CLI user guide and developer guide (#326)
* docs: Add CLI user guide and developer guide

- Add docs/cli-user-guide.md with command reference, flags, and examples
- Add docs/cli-developer-guide.md with architecture and ASCII flow diagrams
- Update README CLI section with proper setup order (install → auth → run)
- Link README to user guide, user guide to developer guide

* docs: Update CLI docs to reflect source-based usage

Binary distribution not yet available. Update all docs to use
`bun run cli` from cloned repo instead of `archon` binary.

* docs: Add bun link for global CLI availability

- Add step to run `bun link` from packages/cli for global `archon` command
- Update all examples to use `archon` instead of `bun run cli`
- Update Windows WSL2 section with bun link step
2026-01-22 09:03:12 +02:00
Rasmus Widing
0e57b2f788 fix: Update all repo URLs from raswonders to dynamous-community 2026-01-22 00:20:27 +02:00
Rasmus Widing
68e7db0466
feat: Phase 5 - CLI binary distribution (#325)
* docs: Add Phase 5 CLI binary distribution plan

- Create detailed implementation plan for binary distribution
- Add Phase 5.0: Bundle defaults for binary (depends on #322)
- Add Phase 5.1-5.7: Build scripts, GitHub Actions, curl install,
  Homebrew formula, Windows docs, version command, release guide
- Update research doc with Phase 6 (auto-update command)
- Renumber dashboard to Phase 7, workflow builder to Phase 8
- Mark Phases 1-4 as complete in research doc

* feat: Phase 5 - CLI binary distribution

Implement standalone binary distribution for Archon CLI:

- Bundle default commands and workflows into binaries at compile time
- Add build scripts for cross-platform compilation (macOS/Linux, ARM64/x64)
- Create GitHub Actions release workflow triggered on version tags
- Add curl install script with checksum verification
- Create Homebrew formula for macOS/Linux installation
- Update version command to show platform, build type, and database info
- Add developer release guide documentation
- Update README with CLI installation instructions

Binary compilation uses Bun's --compile flag to create standalone
executables that include the Bun runtime and all dependencies.
Default workflows and commands are imported as text at compile time
and embedded directly into the binary.

* fix: Pin Dockerfile to Bun 1.3.4 to match lockfile version

The Docker build was failing because oven/bun:1-slim resolved to 1.3.6
while the lockfile was created with 1.3.4, causing --frozen-lockfile to fail.

* docs: Clarify binary vs source builds for default commands/workflows

* fix: Address PR review issues for CLI binary distribution

Security fixes:
- install.sh: Require SKIP_CHECKSUM=true to bypass checksum verification
  instead of silently skipping (addresses security vulnerability)
- install.sh: Show actual error output when version check fails instead
  of falsely reporting success

Validation improvements:
- checksums.sh: Validate all 4 expected binaries exist before generating
  checksums to prevent releasing incomplete builds
- build-binaries.sh: Verify binary exists and has reasonable size (>1MB)
  after each build step
- update-homebrew.sh: Validate extracted checksums are non-empty and
  look like valid SHA256 hashes (64 hex chars)
- update-homebrew.sh: Fix sed patterns to use URL context for updating
  checksums on subsequent runs

Bug fixes:
- homebrew/archon.rb: Fix test to expect exit code 0 (success) instead
  of 1 for `archon version`
- loader.ts: Log error when bundled workflow fails to parse (indicates
  build-time corruption)

Test coverage:
- Add bundled-defaults.test.ts for isBinaryBuild() and content validation
- Add connection.test.ts for getDatabaseType() function
- Add binary build bundled workflow tests to loader.test.ts
- Add binary build bundled command tests to executor.test.ts

All 959 tests pass.
2026-01-21 23:51:51 +02:00
Rasmus Widing
090e5fd812
feat: Runtime loading of default commands/workflows (#324)
* feat: Runtime loading of default commands/workflows

Instead of copying default commands and workflows to target repos on
clone, load them at runtime from the app's bundled defaults directory.

Changes:
- Fix getAppArchonBasePath() to resolve to repo root (not packages/core)
- Add loadDefaultCommands and loadDefaultWorkflows config options
- Update workflow loader to search app defaults then repo (repo wins)
- Update command executor to search app defaults after repo paths
- Remove copyDefaultsToRepo() calls from /clone and GitHub adapter
- Fix lint-staged to not warn on ignored test files

Benefits:
- Defaults always up-to-date (no sync issues)
- Clean repos (no 24+ files copied per clone)
- User's local clone stays in sync with what Archon uses

Closes #322

* docs: Update documentation for runtime loading of defaults

- Update CLAUDE.md to explain runtime loading behavior
- Fix README.md example output and note about defaults
- Update docs/configuration.md with new config options
- Mark copyDefaults as deprecated in favor of loadDefaultCommands/loadDefaultWorkflows

* fix: Address PR review findings for runtime loading

- Fix silent error swallowing in loadConfig catch blocks (loader.ts, executor.ts)
  - Now logs warning with context before falling back to defaults
  - Users will know when their config has syntax errors

- Fix config merging bug in mergeRepoConfig
  - Now includes loadDefaultCommands and loadDefaultWorkflows in merge
  - Repo config opt-out now works correctly

- Add consistent empty file handling for app defaults
  - Returns explicit empty_file error instead of falling through

- Add debug logging for ENOENT cases
  - Helps troubleshoot when app defaults aren't found

- Add startup validation for app defaults paths
  - validateAppDefaultsPaths() checks and logs verification status
  - Called during server startup after logArchonPaths()

- Add comprehensive tests for app defaults command loading
  - Test loading from app defaults when not in repo
  - Test repo commands override app defaults
  - Test loadDefaultCommands: false opt-out
  - Test empty file handling
  - Test graceful handling of missing paths
  - Test config error fallback behavior

* fix: Use namespace imports for archonPaths to fix test mocking in CI

The loader.ts used destructured imports for getDefaultWorkflowsPath and
getWorkflowFolderSearchPaths, but the tests use spyOn which only works
with namespace imports (import * as). This caused the mocks to not work
in CI where tests run in parallel, causing 48 test failures.

* fix: Restore spyOn approach with namespace imports for loader tests

The key fix is that loader.ts uses namespace imports (import * as archonPaths)
which shares the same module instance with the test file. This allows spyOn
to work correctly without using mock.module() which pollutes other tests.

* fix: Use loadDefaultWorkflows: false to avoid app defaults in tests

Instead of mocking archon-paths (which pollutes other tests), we:
1. Only mock config-loader with loadDefaultWorkflows: false by default
2. This prevents app defaults from being loaded during tests
3. For multi-source loading tests, enable loadDefaultWorkflows: true
   and use spyOn to set the path to a temp directory

* fix: Use namespace imports and spyOn for all loader dependencies

Key changes:
1. loader.ts now uses namespace imports for both archonPaths and configLoader
2. loader.test.ts uses spyOn instead of mock.module
3. This avoids polluting other test files (archon-paths.test.ts, config-loader.test.ts)

The spyOn approach works because:
- Both loader.ts and loader.test.ts import the modules as namespaces
- They share the same module instance in Bun's module cache
- spyOn modifies the shared namespace object

* fix: Use namespace imports in executor.ts for test mocking

Change executor.ts to use namespace imports for archon-paths and
config-loader, matching the fix already applied to loader.ts.

The previous fix commits (491fa94, c3a68dd) only updated loader.ts
but missed executor.ts, which has the same pattern of tests using
spyOn() that requires namespace imports to work correctly.

Changes:
- import * as archonPaths from '../utils/archon-paths'
- import * as configLoader from '../config/config-loader'
- Update all usage sites to use namespace prefix

* refactor: Prefix app defaults with archon-* and simplify override logic

Changes:
- Rename all default workflow files to archon-*.yaml
- Rename all default command files to archon-*.md
- Update workflow name: fields to match filenames
- Update command references in workflows to use archon-* names
- Simplify loader.ts to use exact filename match for overrides (not workflow name)
- Remove path mocking from tests - use real app defaults instead
- Simplify tests to be more reliable in CI

Benefits:
- No accidental collisions with user workflows/commands
- Clear intent when users override (must use exact filename)
- Simpler deduplication logic (filename-based)
- More reliable tests (no spyOn issues in CI parallel execution)

* feat: Add deprecation warning for old defaults and update docs

- Add warning in loader.ts when old non-prefixed defaults found in repo
- Update CLAUDE.md with migration instructions for old repos
- Document the archon-* prefix naming convention
- Document exact filename match override behavior

* docs: Move migration docs to docs/migration-guide.md

- Revert CLAUDE.md changes (keep it focused on development)
- Create dedicated migration guide for version upgrades
- Document runtime loading defaults migration steps
- Add commands for full fresh start cleanup

* docs: Add getting started section after cleanup

* docs: Fix stale references to command loading behavior

- Update CLAUDE.md to say 'auto-detected' instead of 'loaded via /clone (auto)'
- Clarify in architecture.md that defaults are loaded at runtime, not copied
- Update GitHub webhook flow to say 'detect and register' instead of 'load commands'

* refactor: Use early return in validateAppDefaultsPaths for cleaner flow

* fix: Improve error handling for silent failure cases

- Add ENOENT check to empty catch block in loader.ts (critical)
- Distinguish between 'not found' and other errors in validateAppDefaultsPaths
- Add errorType to config load fallback logging in loader.ts and executor.ts
2026-01-21 23:08:23 +02:00
Rasmus Widing
7fc0e2e837 docs: Add guide for adding webhooks to additional GitHub repos 2026-01-21 14:23:53 +02:00
Rasmus Widing
3b6b7ab69f
feat: Phase 4 - Express to Hono migration (#318)
* feat: Phase 4 - Express to Hono migration

Replace Express with Hono in @archon/server for improved performance
and better Bun integration. This is a focused HTTP layer migration
that preserves all existing API functionality.

Changes:
- Replace express with hono dependency
- Migrate all endpoints to Hono context-based handlers
- Use Bun.serve() for native Bun server integration
- Update optional parameter syntax from Express 5 to Hono style
- Remove express.json()/express.raw() middleware (Hono handles natively)
- Change default port from 3000 to 3090
- Update log prefixes from [Express] to [Hono]
- Update CLAUDE.md documentation references

All endpoints verified working:
- GET /health, /health/db, /health/concurrency
- POST /test/message, GET /test/messages/:id
- DELETE /test/messages/:id?, PUT /test/mode
- POST /webhooks/github (signature verification)

* refactor: Simplify Hono endpoint handlers

- Remove unnecessary try/catch from /health/concurrency endpoint
  (getStats() is a simple sync operation that doesn't need error handling)
- Remove outer try/catch from /test/message endpoint
  (validation returns early, processing is fire-and-forget with its own error handler)
- Consolidate validation checks with clearer error messages
- Reduce nesting depth for improved readability

Total: 12 lines removed while maintaining identical functionality

* docs: Update port references from 3000 to 3090 after Hono migration

* fix: Improve error handling in Hono endpoints

- Add global app.onError() handler for consistent unhandled exception responses
- Add explicit JSON parsing error handling to /test/message endpoint (returns 400 instead of 500)
- Add explicit JSON parsing error handling to /test/mode endpoint (was completely unhandled)
- Fix CLAUDE.md worktree port example to use correct port (3637 with base 3090)
2026-01-21 13:23:34 +02:00
Rasmus Widing
a28e695aee
feat: Phase 3 - Database abstraction layer and CLI isolation (#314)
* feat: Phase 3 - Database abstraction layer and CLI isolation

Part A: Database Abstraction Layer
- Add IDatabase interface supporting PostgreSQL and SQLite
- Create PostgresAdapter wrapping pg Pool with same interface
- Create SqliteAdapter using bun:sqlite with auto-schema init
- Add SqlDialect helpers for database-specific SQL generation
- Update connection.ts with auto-detection (DATABASE_URL → Postgres, else SQLite)
- Update isolation-environments.ts to use dialect helpers
- CLI now works without DATABASE_URL (uses ~/.archon/archon.db)

Part B: CLI Isolation Integration
- Add --branch/-b flag to create/reuse worktrees for workflows
- Add --no-worktree flag to run on branch directly without isolation
- Add isolation list command to show all active worktrees
- Add isolation cleanup command to remove stale environments
- Auto-register codebase when using --branch from git repo

New git utilities:
- findRepoRoot: Find git repository root from any path
- getRemoteUrl: Get origin remote URL
- checkout: Checkout branch (creating if needed)

* docs: Update documentation for Phase 3 - SQLite support and CLI isolation

* fix: Address all PR review issues for database abstraction

Critical fixes:
- Use dialect helpers (now(), jsonMerge, jsonArrayContains) in all DB operations
- Replace hardcoded PostgreSQL NOW(), ::jsonb, and JSON operators
- Add rowCount validation to updateStatus() and updateMetadata()
- Improve PostgreSQL pool error logging with structured context

Important fixes:
- Add explicit null check in getDialect() instead of non-null assertion
- Add warning for unsupported UPDATE/DELETE RETURNING in SQLite
- Throw error in extractTableName() on parse failure instead of empty string
- Track codebaseLookupError to provide clearer errors when --branch fails
- Couple IDatabase with SqlDialect via readonly sql property

Code simplifications:
- Extract loadWorkflows() helper to DRY duplicate error handling
- Fix N+1 query in getCodebases() by including repository_url in JOIN
- Cache sql.toUpperCase() to avoid redundant calls

All changes verified with:
- Type-check passes
- All 1082 tests pass
- CLI commands tested with both SQLite and PostgreSQL

* docs: Add SQLite support to getting-started, configuration, and architecture guides

* refactor: Simplify Phase 3 code for clarity and maintainability

- sqlite.ts: Remove unused UPDATE branch from extractTableName, consolidate
  RETURNING clause handling into single condition
- isolation.ts: Extract CodebaseInfo interface to reduce type duplication
- workflow.ts: Extract actualBranchName variable for clearer intent
- isolation-environments.ts: Rename variables for semantic clarity
  (staleActivityThreshold/staleCreationThreshold vs nowMinusDays1/2)

* fix: Address all remaining PR review issues

- SQLite: Throw error for UPDATE/DELETE RETURNING instead of warning
- SQLite: Replace deprecated db.exec() with db.run()
- Worktree: Throw for fatal errors (permission denied, not a git repo)
- Types: Add import type for type-only imports in 4 db modules
- Codebases: Add null check validation to createCodebase return
- WorkflowRunOptions: Add JSDoc documenting constraint behavior
- QueryResult: Add comment noting fields should be treated as readonly
- Connection: Improve getDialect() error message with actionable details

* fix: Complete type safety improvements for Phase 3

- QueryResult: Make rows and rowCount readonly to prevent mutation
- WorkflowRunOptions: Use discriminated union to prevent invalid states
  (noWorktree can only be set when branchName is provided)
- Update all database functions to return readonly arrays
- Fix CLI call site to properly construct options object

* fix: Add getDialect mock to database tests

Tests were failing because they expected hardcoded PostgreSQL SQL
(NOW(), metadata || $1::jsonb) but the code now uses dialect helpers.

- Add mockPostgresDialect to test/mocks/database.ts
- Update all db test files to mock getDialect() returning PostgreSQL dialect
- Tests now properly verify the SQL generated by dialect helpers
2026-01-21 10:38:57 +02:00
Rasmus Widing
cf06128e14
feat: Add workflow status visibility (#233) (#256)
* Investigate issue #233: Workflow state management visibility

* feat: Add workflow status visibility to /status and /workflow status (#233)

Users had no visibility into running workflows - they could only see "already running"
errors when attempting to start new workflows. This made it impossible to know what
was running, how long it had been active, or whether it was stuck.

Changes:
- Add workflow info to /status command (name, step, duration, activity)
- Add /workflow status subcommand for detailed workflow state
- Show staleness warnings (>5 min) and stale indicators (>15 min)
- Update help text to document new command

Fixes #233

* Archive investigation for issue #233

* docs: Add /workflow status command to documentation

* refactor: Improve workflow status error handling and code quality

- Extract calculateWorkflowTiming() helper to eliminate code duplication
- Add try-catch around workflow DB queries for graceful degradation
- Define WORKFLOW_SLOW_THRESHOLD_MS and WORKFLOW_STALE_THRESHOLD_MS constants
- Handle invalid date data gracefully (shows "timing unavailable")
- Prevent negative durations with Math.max(0, ...)
- Remove unnecessary String() wrappers in template literals
- Add tests for database error handling and invalid date scenarios
- Add test for /workflow help text including status subcommand
2026-01-19 16:06:58 +02:00
Rasmus Widing
f25994248d
fix: Add Codex sandbox/network settings and progress logging (#290)
* fix: Add Codex sandbox/network settings and progress logging (#288)

The Codex provider was missing critical configuration options, causing it to:
- Run in read-only sandbox mode (couldn't write files)
- Have no network access (couldn't run gh commands)
- Show no progress during execution (appeared to hang)

This commit adds:
- sandboxMode: 'workspace-write' to allow file operations
- networkAccessEnabled: true to allow network calls (gh, curl)
- approvalPolicy: 'never' to auto-approve operations (like Claude's bypassPermissions)
- Progress logging for item.started and item.completed events

Applied to all three thread creation points:
- resumeThread (line 50-56)
- fallback startThread in catch block (line 63-69)
- new startThread (line 74-80)

Fixes #288

* fix: Address PR review feedback for Codex sandbox/network settings

- Remove stale README warning about Codex read-only mode (issue #288 is now fixed)
- Extract thread options to shared helper function (DRY violation fix)
- Add user notification when session resume fails (no longer silent fallback)
- Consolidate item.completed logging with context (command details included)
- Improve comments to be self-contained (remove unverified default claims)
- Strengthen test assertions for fallback path and progress logging
2026-01-19 14:56:07 +02:00
Rasmus Widing
d98d329d59 docs: Add Codex read-only limitation warning
Codex currently runs in read-only sandbox mode due to missing
sandboxMode and networkAccessEnabled settings in the client.

Until #288 is fixed, Codex can only analyze code but cannot
write files or make network calls.

References #288
2026-01-19 14:08:17 +02:00
Rasmus Widing
2a76165305
Fix stale workspace: sync before worktree creation (#287)
* Investigate issue #285: stale workspace causes outdated worktrees

Analyzed root cause and created implementation plan for fixing the
workspace sync issue where new worktrees are created from outdated code
after PRs are merged.

* Fix stale workspace: sync before worktree creation

When a PR is merged, subsequent worktrees were created from outdated
code because the workspace was never synced after the initial clone.

Changes:
- Add syncWorkspace() and getDefaultBranch() helpers in git.ts
- Call syncWorkspaceBeforeCreate() in WorktreeProvider before creating
  new worktrees
- Make sync non-fatal to handle offline/permission edge cases gracefully

The sync happens at the natural boundary of starting new work, ensuring
new issues/PRs always start from the latest code without disrupting
existing in-progress worktrees.

Fixes #285

* Address PR review feedback: data safety and test coverage

- Add uncommitted changes check in syncWorkspace() before git reset --hard
  to prevent accidental data loss (returns false if changes detected)
- Add logging to getDefaultBranch() fallback paths for better debugging
  when symbolic-ref fails and fallback to main/master is used
- Add integration tests verifying sync is called during worktree creation
- Add tests for sync failure scenarios (non-fatal behavior)
- Add test for checkout failure in syncWorkspace()
- Update worktree.ts to handle new boolean return from syncWorkspace()

* simplify: flatten getDefaultBranch fallback logic

Remove verbose logging in getDefaultBranch function. The fallback from
symbolic-ref to checking origin/main to defaulting to master is expected
behavior that doesn't need logging at the info level. Flatten nested
try-catch into sequential blocks for better readability.

* docs: document workspace sync behavior before worktree creation

* Address PR review feedback: error handling and test coverage

- Add logging to empty catch blocks in getDefaultBranch() (critical)
- Add operation context to syncWorkspace() error messages
- Differentiate error severity in syncWorkspaceBeforeCreate():
  - Permission errors and corruption logged at ERROR level
  - Network/timeout errors logged at WARN level
- Update syncWorkspace JSDoc with reset --hard warning
- Remove redundant inline comment before sync call
- Add tests for:
  - Non-standard branch names (develop, trunk)
  - Timeout parameter verification
  - Operation context in error messages
  - Sync skipped when adopting existing worktree
2026-01-19 13:07:56 +02:00
Rasmus Widing
3aff6e3309
feat: Config-based provider selection for workflows (#283)
* feat: Use config-based provider selection for workflows

- Workflow executor now uses config.assistant as fallback instead of
  hardcoded 'claude' when workflow doesn't specify provider
- Remove provider: claude from all default workflow files so they
  inherit from config
- Add assistant: codex to repo config for testing
- Add implementation plan for model validation feature (#281)

This allows users to switch default provider via config without
modifying workflow files. Workflows can still override by specifying
provider explicitly.

* feat: Add logging for resolved provider and model at workflow execution

Log which provider and model is being used at:
- Each workflow step execution
- Each loop workflow iteration

This helps debug config-based provider selection and verify the
correct provider/model combination is being used.

Related to #281

* docs: Document config-based workflow provider inheritance

* refactor: Hoist config loading outside of loops in workflow executor

- Load config once at workflow start instead of on each step/iteration
- Pass resolvedProvider and resolvedModel as parameters to internal functions
- Remove now-unused workflow parameter from executeStepInternal and executeParallelBlock
- Eliminates redundant filesystem reads during workflow execution

* fix: Add provider source tracking and enhanced error context

- Add source tracking to provider log messages (shows "from workflow
  definition" vs "from config") for easier debugging
- Wrap getAssistantClient calls with try-catch that provides actionable
  error messages pointing users to check their workflow YAML or
  .archon/config.yaml assistant setting

Addresses review feedback from PR #283
2026-01-19 11:08:02 +02:00
Rasmus Widing
62a06a834d
Fix: Show repo identifier instead of server filesystem path (#152) (#175)
* Investigate issue #152: GitHub UX - Show repo identifier instead of filesystem path

* Fix: Show repo identifier instead of server filesystem path (#152)

Commands were exposing server's internal filesystem paths (e.g.,
/Users/rasmus/.archon/workspaces/owner/repo) to users, which is a security
concern and provides no value. Users need to know what repo and branch they're
working in, not the server's internal directory structure.

Changes:
- Added formatRepoContext() helper to show "owner/repo @ branch" format
- Updated /status to display "Repository: owner/repo @ branch (worktree)"
- Updated /getcwd to show repo context instead of filesystem path
- Updated /setcwd response to show repo context with fallback to path
- Updated /clone response to remove "Path:" line entirely
- Updated tests to match new output format

Fixes #152

* Archive investigation for issue #152

* Simplify formatRepoContext by extracting getCurrentBranch helper

- Extract git branch lookup into standalone getCurrentBranch() function
- Remove mutable variables (branchName, isWorktree)
- Simplify control flow with early returns
- Reduce JSDoc verbosity (function signature is self-documenting)
- Comment now explains WHY git failures fallback to 'main'

All 84 tests pass. No functional changes.

* docs: Update command output examples to show repo identifier instead of filesystem paths

* Address PR review feedback: improve error handling and simplify code

- Fix duplicate "Repository:" label in /status - now shows "URL:" for repo URL
- Add error logging to getCurrentBranch() when git fails
- Handle detached HEAD state explicitly (shows "detached HEAD" not "HEAD")
- Add try-catch around DB call in formatRepoContext() with logging
- Remove unnecessary isolationDb parameter (uses already-imported module)
- Fix /setcwd fallback to show folder name only, not full filesystem path
- Update tests to match new output format

* Add warning log for orphaned isolation envs and improve test coverage

- Add console.warn() when isolation_env_id exists but DB record not found
- Document no-throw guarantees in getCurrentBranch() and formatRepoContext()
- Add tests for worktree branch lookup and orphaned isolation env fallback
2026-01-18 14:29:20 +02:00
Rasmus Widing
8c27f7759a docs: Update prerequisites to list Bun instead of Node.js
Fixes #247
2026-01-17 22:25:28 +02:00
DIY Smart Code
e1b4db97f3
fix: Auto-detect Claude auth when CLAUDE_USE_GLOBAL_AUTH not set (#236)
* fix: Auto-detect Claude auth when CLAUDE_USE_GLOBAL_AUTH not set

Previously, if CLAUDE_USE_GLOBAL_AUTH was not explicitly set, the code
defaulted to filtering out auth tokens. This broke backwards compatibility
for users who had explicit tokens in their .env files.

New behavior:
- CLAUDE_USE_GLOBAL_AUTH=true: Filter tokens, use global auth
- CLAUDE_USE_GLOBAL_AUTH=false: Use explicit tokens from env
- Not set: Auto-detect - if tokens exist in env, use them

This ensures existing deployments with tokens in .env continue to work
without requiring configuration changes.

* docs: Document auto-detect behavior for Claude authentication

Updated documentation to reflect the new three-way authentication behavior:
- CLAUDE_USE_GLOBAL_AUTH=true: Use global auth from claude /login
- CLAUDE_USE_GLOBAL_AUTH=false: Use explicit tokens from env
- Not set: Auto-detect (use tokens if present, otherwise global auth)

This ensures users understand the backwards-compatible auto-detect feature
that prevents breaking existing deployments with explicit tokens.

* fix: Add comprehensive logging for Claude auth detection

- Log confirmation for explicit CLAUDE_USE_GLOBAL_AUTH=true/false settings
- Log when auto-detect falls back to global auth (no tokens found)
- Warn about empty string token values (common misconfiguration)
- Warn about unrecognized boolean values (e.g., 'yes', '1')

This makes debugging auth issues straightforward by logging every path.

---------

Co-authored-by: Rasmus Widing <rasmus.widing@gmail.com>
2026-01-17 21:46:01 +02:00
Rasmus Widing
1d6768d184 docs: Add missing bun install to setup guide 2026-01-17 21:03:40 +02:00
DIY Smart Code
e6217ec561
Update README.md 2026-01-17 12:33:35 +01:00
Rasmus Widing
3d6c460589
feat: Auto-copy default commands/workflows on clone (#243)
* feat: Auto-copy default commands/workflows on clone

Automatically copy bundled default commands and workflows to newly cloned
repositories. The defaults are stored in `.archon/commands/defaults/` and
`.archon/workflows/defaults/` within the app repository.

These defaults serve dual purpose:
1. They're loaded and usable by this repo itself (recursive loading)
2. They get copied to target repos on `/clone` (flat, not nested)

Key changes:
- Move existing commands/workflows to defaults/ subdirectories
- Add getDefaultCommandsPath/getDefaultWorkflowsPath to archon-paths.ts
- Add defaults.copyDefaults config option (opt-out via config.yaml)
- Create defaults-copy.ts utility for copying files
- Update /clone handler to copy defaults before loading commands
- Update GitHub adapter to copy defaults for new codebases
- Add unit tests for defaults-copy.ts

To opt out: Set `defaults.copyDefaults: false` in target's .archon/config.yaml

Closes #241

* docs: Update documentation for default commands feature

* refactor: Simplify defaults-copy.ts by extracting common copy logic

- Extract duplicated code from copyDefaultCommands and copyDefaultWorkflows
  into a single generic copyFiles helper function
- Add directoryExists helper to replace try/catch for access checks
- Define CopyFilesOptions interface for cleaner parameter passing
- Reduce code from 156 to 137 lines while preserving all functionality

* fix: Improve error handling and test coverage for defaults copy

- Add commandsFailed/workflowsFailed to CopyDefaultsResult interface
- Make copyDefaultsToRepo non-fatal in both command-handler and github adapter
- Surface partial failures to users (warning messages)
- Handle mkdir and readdir errors gracefully
- Use specific ENOENT check instead of catching all errors
- Fix template literal number warnings with String()
- Add tests for mkdir failure, combined copy, and empty directory case

* style: Fix ESLint quote errors in defaults-copy.ts
2026-01-16 01:06:20 +02:00