* fix(bundled-defaults): auto-generate import list, emit inline strings
Root-cause fix for bundle drift (15 commands + 7 workflows previously
missing from binary distributions) and a prerequisite for packaging
@archon/workflows as a Node-loadable SDK.
The hand-maintained `bundled-defaults.ts` import list is replaced by
`scripts/generate-bundled-defaults.ts`, which walks
`.archon/{commands,workflows}/defaults/` and emits a generated source
file with inline string literals. `bundled-defaults.ts` becomes a thin
facade that re-exports the generated records and keeps the
`isBinaryBuild()` helper.
Inline strings (via JSON.stringify) replace Bun's
`import X from '...' with { type: 'text' }` attributes. The binary build
still embeds the data at compile time, but the module now loads under
Node too — removing SDK blocker #2.
- Generator: `scripts/generate-bundled-defaults.ts` (+ `--check` mode for CI)
- `package.json`: `generate:bundled`, `check:bundled`; wired into `validate`
- `build-binaries.sh`: regenerates defaults before compile
- Test: `bundle completeness` now derives expected set from on-disk files
- All 56 defaults (36 commands + 20 workflows) now in the bundle
* fix(bundled-defaults): address PR review feedback
Review: https://github.com/coleam00/Archon/pull/1263#issuecomment-4262719090
Generator:
- Guard against .yaml/.yml name collisions (previously silent overwrite)
- Add early access() check with actionable error when run from wrong cwd
- Type top-level catch as unknown; print only message for Error instances
- Drop redundant /* eslint-disable */ emission (global ignore covers it)
- Fix misleading CI-mechanism claim in header comment
- Collapse dead `if (!ext) continue` guard into a single typed pass
Scripts get real type-checking + linting:
- New scripts/tsconfig.json extending root config
- type-check now includes scripts/ via `tsc --noEmit -p scripts/tsconfig.json`
- Drop `scripts/**` from eslint ignores; add to projectService file scope
Tests:
- Inline listNames helper (Rule of Three)
- Drop redundant toBeDefined/typeof assertions; the Record<string, string>
type plus length > 50 already cover them
- Add content-fidelity round-trip assertion (defense against generator
content bugs, not just key-set drift)
Facade comment: drop dead reference to .claude/rules/dx-quirks.md.
CI: wire `bun run check:bundled` into .github/workflows/test.yml so the
header's CI-verification claim is truthful.
Docs: CLAUDE.md step count four→five; add contributor bullet about
`bun run generate:bundled` in the Defaults section and CONTRIBUTING.md.
* chore(e2e): bump Codex model to gpt-5.2
gpt-5.1-codex-mini is deprecated and unavailable on ChatGPT-account Codex
auth. Plain gpt-5.2 works. Verified end-to-end:
- e2e-codex-smoke: structured output returns {category:'math'}
- e2e-mixed-providers: claude+codex both return expected tokens
Removes feat/e2e-smoke-tests from E2E workflow triggers. CI failure
detection verified: red X on run 24522356737 (deliberate bash exit 1),
green on run 24522484762 (reverted), and credit-exhaustion failure also
correctly produced exit 1.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reverts the injected exit 1 in bash-echo (CI red X confirmed in run
24522356737). Removes feat/e2e-smoke-tests from branch triggers — ready
to merge to dev.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Injects exit 1 into e2e-deterministic bash-echo node to prove the engine
fix (failWorkflowRun on anyFailed) propagates to a non-zero CLI exit code
and a red X in GitHub Actions. Will be reverted in the next commit.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Claude CLI is extremely slow with structured output (~4 min) and tool use
(~2 min) in CI, making the previous multi-workflow approach take 10+ min.
Radical simplification:
- Remove e2e-all-nodes (redundant with deterministic + claude-smoke)
- Remove e2e-skills-mcp (advanced features too slow for per-commit smoke)
- Remove structured output and tool use from Claude smoke test (too slow)
- Strip Claude smoke to: 1 prompt + 1 command + 1 bash verify node
- Keep mixed providers (simplified: 1 Claude + 1 Codex + bash verify)
- All timeouts reduced to 30s, all job timeouts to 5 min
- Remove MCP test fixtures and e2e-test-skill (no longer needed)
Expected: Claude job ~15s of AI time, Codex ~5s, mixed ~10s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Claude CLI is slow with structured output and tool use in CI (~4 min for
structured output, ~2 min for tool use). With 3 sequential workflow runs
(claude-smoke, all-nodes, skills-mcp), 10 minutes is insufficient.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Rename echo-args.py → echo-py.py to avoid duplicate script name conflict
with echo-args.js (script discovery uses base name, not extension)
- Add CODEX_API_KEY env var to codex and mixed CI jobs (Codex CLI requires
this, not OPENAI_API_KEY, for headless auth)
- Sequentialize all Claude AI nodes via depends_on chains to prevent
concurrent CLI subprocess idle timeouts in CI
- Increase idle_timeout from 60s to 120s on all AI nodes for CI headroom
- Override MCP test node to model: sonnet (Haiku doesn't support MCP tool search)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds real workflow execution to CI, verifying the full engine works
end-to-end with both providers. Organized into 4 tiers: deterministic
(0 API calls), Claude, Codex, and mixed-provider tests.
New workflows:
- e2e-deterministic: bash, script (bun/uv), conditions, trigger rules
- e2e-skills-mcp: skills injection, MCP server, effort, systemPrompt
- Enhanced existing e2e-claude-smoke, e2e-codex-smoke, e2e-mixed-providers
- Fixed e2e-all-nodes (was broken due to script node syntax)
Supporting files:
- e2e-echo-command.md (test command file)
- echo-args.py (Python script for uv runtime test)
- e2e-test-skill/SKILL.md (minimal skill for injection test)
- e2e-filesystem.json (MCP config for filesystem server test)
GitHub Actions: .github/workflows/e2e-smoke.yml
- Runs on push to main/dev only (no PR trigger to avoid API cost abuse)
- Uses haiku (Claude) and gpt-5.1-codex-mini (Codex) for cost efficiency
Closes#1254
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(providers): replace Claude SDK embed with explicit binary-path resolver
Drop `@anthropic-ai/claude-agent-sdk/embed` and resolve Claude Code via
CLAUDE_BIN_PATH env → assistants.claude.claudeBinaryPath config → throw
with install instructions. The embed's silent failure modes on macOS
(#1210) and Windows (#1087) become actionable errors with a documented
recovery path.
Dev mode (bun run) remains auto-resolved via node_modules. The setup
wizard auto-detects Claude Code by probing the native installer path
(~/.local/bin/claude), npm global cli.js, and PATH, then writes
CLAUDE_BIN_PATH to ~/.archon/.env. Dockerfile pre-sets CLAUDE_BIN_PATH
so extenders using the compiled binary keep working. Release workflow
gets negative and positive resolver smoke tests.
Docs, CHANGELOG, README, .env.example, CLAUDE.md, test-release and
archon skills all updated to reflect the curl-first install story.
Retires #1210, #1087, #1091 (never merged, now obsolete).
Implements #1176.
* fix(providers): only pass --no-env-file when spawning Claude via Bun/Node
`--no-env-file` is a Bun flag that prevents Bun from auto-loading
`.env` from the subprocess cwd. It is only meaningful when the Claude
Code executable is a `cli.js` file — in which case the SDK spawns it
via `bun`/`node` and the flag reaches the runtime.
When `CLAUDE_BIN_PATH` points at a native compiled Claude binary (e.g.
`~/.local/bin/claude` from the curl installer, which is Anthropic's
recommended default), the SDK executes the binary directly. Passing
`--no-env-file` then goes straight to the native binary, which
rejects it with `error: unknown option '--no-env-file'` and the
subprocess exits code 1.
Emit `executableArgs` only when the target is a `.js` file (dev mode
or explicit cli.js path). Caught by end-to-end smoke testing against
the curl-installed native Claude binary.
* docs: record env-leak validation result in provider comment
Verified end-to-end with sentinel `.env` and `.env.local` files in a
workflow CWD that the native Claude binary (curl installer) does not
auto-load `.env` files. With Archon's full spawn pathway and parent
env stripped, the subprocess saw both sentinels as UNSET. The
first-layer protection in `@archon/paths` (#1067) handles the
inheritance leak; `--no-env-file` only matters for the Bun-spawned
cli.js path, where it is still emitted.
* chore(providers): cleanup pass — exports, docs, troubleshooting
Final-sweep cleanup tied to the binary-resolver PR:
- Mirror Codex's package surface for the new Claude resolver: add
`./claude/binary-resolver` subpath export and re-export
`resolveClaudeBinaryPath` + `claudeFileExists` from the package
index. Renames the previously single `fileExists` re-export to
`codexFileExists` for symmetry; nothing outside the providers
package was importing it.
- Add a "Claude Code not found" entry to the troubleshooting reference
doc with platform-specific install snippets and pointers to the
AI Assistants binary-path section.
- Reframe the example claudeBinaryPath in reference/configuration.md
away from cli.js-only language; it accepts either the native binary
or cli.js.
* test+refactor(providers, cli): address PR review feedback
Two test gaps and one doc nit from the PR review (#1217):
- Extract the `--no-env-file` decision into a pure exported helper
`shouldPassNoEnvFile(cliPath)` so the native-binary branch is unit
testable without mocking `BUNDLED_IS_BINARY` or running the full
sendQuery pathway. Six new tests cover undefined, cli.js, native
binary (Linux + Windows), Homebrew symlink, and suffix-only matching.
Also adds a `claude.subprocess_env_file_flag` debug log so the
security-adjacent decision is auditable.
- Extract the three install-location probes in setup.ts into exported
wrappers (`probeFileExists`, `probeNpmRoot`, `probeWhichClaude`) and
export `detectClaudeExecutablePath` itself, so the probe order can be
spied on. Six new tests cover each tier winning, fall-through
ordering, npm-tier skip when not installed, and the
which-resolved-but-stale-path edge case.
- CLAUDE.md `claudeBinaryPath` placeholder updated to reflect that the
field accepts either the native binary or cli.js (the example value
was previously `/absolute/path/to/cli.js`, slightly misleading now
that the curl-installer native binary is the default).
Skipped from the review by deliberate scope decision:
- `resolveClaudeBinaryPath` async-with-no-await: matches Codex's
resolver signature exactly. Changing only Claude breaks symmetry;
if pursued, do both providers in a separate cleanup PR.
- `isAbsolute()` validation in parseClaudeConfig: Codex doesn't do it
either. Resolver throws on non-existence already.
- Atomic `.env` writes in setup wizard: pre-existing pattern this PR
touched only adjacently. File as separate issue if needed.
- classifyError branch in dag-executor for setup errors: scope creep.
- `.env.example` "missing #" claim: false positive (verified all
CLAUDE_BIN_PATH lines have proper comment prefixes).
* fix(test): use path.join in Windows-compatible probe-order test
The "tier 2 wins (npm cli.js)" test hardcoded forward-slash path
comparisons, but `path.join` produces backslashes on Windows. Caused
the Windows CI leg of the test suite to fail while macOS and Linux
passed. Use `path.join` for both the mock return value and the
expectation so the separator matches whatever the platform produces.
* Investigate issue #978: one-command web UI install via archon serve
* feat: add `archon serve` command for one-command web UI install (#978)
Extract `startServer(opts)` from server's monolithic `main()` into an
exported function with `ServerOptions` (webDistPath, port,
skipPlatformAdapters). Add `import.meta.main` guard so the file still
works as a standalone script for `bun dev`.
Create `archon serve` CLI command that lazily downloads a pre-built
web UI tarball from GitHub releases on first run, verifies SHA-256
checksum, extracts atomically, then starts the full server. Cached
per version in `~/.archon/web-dist/<version>/`.
Update release CI to build the web UI, package it as
`archon-web.tar.gz`, and include in release checksums.
* fix: address review findings for archon serve command
- Validate --port range (1-65535) and reject NaN before any other checks
- Capture tar stderr for actionable extraction error messages
- Add structured logging (download_started/download_failed/server_start_failed)
- Post-extraction sanity check for index.html
- Wrap renameSync with error context and tmpDir cleanup
- Wrap fetch() calls to preserve URL context on network errors
- Validate parseChecksum returns 64 hex chars
- Set skipPlatformAdapters: true for standalone web UI mode
- Improve ServerOptions/ServeOptions JSDoc
- Move consoleErrorSpy cleanup to afterEach in tests
- Add tests for port validation and malformed hash rejection
- Update CLAUDE.md: CLI section, directory tree, package descriptions
- Update README.md: mention archon serve for binary installs
- Update docs-web: CLI reference, archon-directories
* refactor: simplify serve command implementation
- Use BUNDLED_IS_BINARY directly instead of version === 'dev' sentinel
- Extract toError() helper for repeated error normalization
- Use dirname() instead of manual substring/lastIndexOf
- Extract cleanupAndThrow() for repeated rmSync + throw pattern
- Add missing assertion on port 0 test for consistency
* Investigate issue #986: release workflow bypasses build-binaries.sh
* fix(release): wire release workflow to scripts/build-binaries.sh (#986)
The release workflow called `bun build --compile` inline, bypassing the
build-time-constants rewrite in scripts/build-binaries.sh. Released binaries
shipped with BUNDLED_IS_BINARY=false, causing `archon version` to crash with
"package.json not found (bad installation?)" on v0.2.13 and v0.3.0.
Changes:
- Refactor scripts/build-binaries.sh to support single-target mode via
TARGET/OUTFILE env vars; preserve multi-target local-dev mode unchanged.
Always --minify; skip --bytecode for Windows targets.
- Update .github/workflows/release.yml to call the script with the matrix
target/outfile, stripping the 'v' prefix and shortening the SHA.
- Add a post-build smoke test on bun-linux-x64 that asserts the binary
reports "Build: binary" and the tag version (would have caught both
broken releases).
- Document local CI-equivalent build invocation in the test-release skill.
Fixes#986
* chore: archive investigation for issue #986
* skill(release): document Homebrew formula SHA sync and verification
The release skill previously stopped at tag creation and GitHub release
creation. Formula updates were happening manually outside the skill and
consistently drifting — v0.3.0's homebrew/archon.rb had the correct
version string but SHAs from v0.2.13, because whoever updated it did so
before the release workflow had built the v0.3.0 binaries.
Add three new steps to close the gap:
- Step 10: wait for release workflow, fetch checksums.txt, update
homebrew/archon.rb atomically with new version AND new SHAs in a
single commit. The formula is regenerated from a template rather
than edited in place, eliminating the risk of partial updates.
- Step 11: sync the rewritten formula to coleam00/homebrew-archon
tap repo (the file users actually install from). Fails loudly if
push access is missing instead of silently skipping.
- Step 12: run /test-release brew and /test-release curl-mac to
verify the install path actually works end-to-end before announcing
the release. A release that installs but crashes is worse than no
release at all.
Also:
- Add a prominent warning at the top about the chicken-and-egg
relationship between version and SHAs (they must move atomically,
and SHAs can only be known after binaries exist).
- Add three new rules to "Important Rules":
* never update version without also updating SHAs
* never skip the tap sync (main repo formula is just a template)
* never announce a release that failed /test-release
Related to #986 (release workflow bypasses build-binaries.sh) — both
bugs block the next working release; fixing only one leaves the
install path broken.
* fix(release): address review feedback on smoke test and restore trap
- release.yml: use inputs.version on workflow_dispatch so the build step
doesn't embed the branch name as the binary version
- release.yml: compare smoke-test version against the stripped semver
instead of the raw ref, so the check doesn't rely on the CLI re-adding
a 'v' prefix
- release.yml: fail fast if the binary crashes on first invocation
instead of falling through to the 'wrong build type' branch
- release.yml: add a second smoke step that runs 'workflow list' in a
temp repo to catch the class of bug where bundled defaults fail to
embed in the binary
- build-binaries.sh: drop '2>/dev/null' on the EXIT trap so restore
failures surface in the log with a clear WARNING
- test-release skill: fix the single-target verification path
Astro 6 requires Node.js >= 22.12.0. Bun bundles Node 20.x which
is too old. Add actions/setup-node@v4 step before the build.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The server fatally exits when no AI credentials are configured.
The smoke test only needs to verify the container starts and serves
HTTP, not process AI requests. Pass CLAUDE_USE_GLOBAL_AUTH=true to
satisfy the credential check.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When the smoke test fails, capture docker logs to diagnose container
startup crashes before the cleanup step removes the container.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Windows: `env.PATH` is undefined on Windows CI (uses `Path` instead).
Use `env.PATH ?? env.Path` for cross-platform compatibility.
Docker: smoke test hit wrong endpoint (`/health` vs `/api/health`),
and `--retry-connrefused` doesn't catch connection-reset errors (code 56).
Fix URL to `/api/health`, add `sleep 5` for container startup,
and use `--retry-all-errors` for robust retries.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds an update-homebrew job to release.yml that runs after the
GitHub release is created. Downloads checksums from the release,
updates homebrew/archon.rb via the existing update-homebrew.sh
script, and commits the result back to dev.
Relates to #980
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(docker): update Bun base image from 1.2 to 1.3
The lockfile was generated with Bun 1.3.x locally but the Docker image
used oven/bun:1.2-slim. Bun 1.3 changed the lockfile format, causing
--frozen-lockfile to fail during docker build.
* fix(docker): pin Bun to exact version 1.3.9 matching lockfile
Floating tag 1.3-slim resolved to 1.3.11 which has a different lockfile
format than 1.3.9 used to generate bun.lock. Pin to exact patch version
to prevent --frozen-lockfile failures.
* fix(docker): add missing docs-web workspace package.json
The docs-web package was added as a workspace member but its
package.json was never added to the Dockerfile COPY steps. This caused
bun install --frozen-lockfile to fail because the workspace layout
in Docker didn't match the lockfile.
* fix(docker): use hoisted linker for Vite/Rollup compatibility
Bun's default "isolated" linker stores packages in node_modules/.bun/
with symlinks that Vite's Rollup bundler cannot resolve during
production builds (e.g., remark-gfm → mdast-util-gfm chain).
Using --linker=hoisted gives the classic flat node_modules layout
that Rollup expects. Local dev is unaffected (Vite dev server handles
the isolated layout fine).
* ci: pin Bun version to 1.3.9 and add Docker build check
- Align CI Bun version (was 1.3.11) with Dockerfile and local dev
(1.3.9) to prevent lockfile format mismatches between environments
- Add docker-build job to test.yml that builds the Docker image on
every PR — catches Dockerfile regressions (missing workspace
packages, linker issues, build failures) before they reach deploy
* fix(ci): add permissions for GHA cache and tighten Bun engine
- Add actions: write permission to docker-build job so GHA layer cache
writes succeed on PRs from forks
- Tighten package.json engines.bun from >=1.0.0 to >=1.3.9 to document
the minimum version that matches the lockfile format
* fix(ci): add smoke test, align Bun version across all workflows
Review fixes:
- Add load: true + health endpoint smoke test to docker-build CI job
so we verify the image actually starts, not just compiles
- Align Bun 1.3.9 in deploy-docs.yml and release.yml (were still 1.3.11)
- Document why docs-web source is intentionally omitted from Docker
* chore: float Docker to bun:1.3 and align CI to 1.3.11
- Dockerfile: oven/bun:1.3-slim (auto-tracks latest 1.3.x patches)
- CI workflows: bun-version 1.3.11 (current latest, reproducible)
- engines.bun: >=1.3.9 (minimum for local devs)
Lockfile format is stable across 1.3.x patches, so this is safe.
* fix(docker,ci): pin Docker to 1.3.11, loosen engines, harden smoke test
- Dockerfile: pin oven/bun:1.3.11-slim (was floating 1.3-slim) so Docker
builds are reproducible and match CI exactly.
- package.json: loosen engines to ^1.3.0 so end users on any 1.3.x can
run the CLI; CI/Docker remain pinned to the canonical latest.
- CI smoke test: replace 'sleep 5' with curl --retry-connrefused, and
move container cleanup to an 'if: always()' step so a failed health
check no longer leaks the named container.
---------
Co-authored-by: Rasmus Widing <rasmus.widing@gmail.com>
- Move website/ → packages/docs-web/ as @archon/docs-web
- Remove npm package-lock.json, use shared bun.lock
- Update deploy-docs.yml to use bun instead of npm
- Add dev:docs and build:docs workspace scripts
- Update prettierignore and eslint ignores
- Update Starlight edit link base URL
- 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>
CI was running raw bun test with hardcoded package paths, bypassing
per-package test batching and causing mock.module() pollution (55
failures) while completely skipping 32 test files across 6 packages.
Changes:
- Replace 5-command hardcoded test block with single `bun run test`
- Remove obsolete coverage upload step (no --coverage flag in bun run test)
bun run test delegates to bun --filter '*' test, which runs each
package's properly-batched test scripts in isolated processes.
Fixes#643
* feat(skills): overhaul archon-dev skill with PRP-inspired improvements
Rewrote all 9 cookbooks (split research into research + investigate) with
battle-tested patterns from PRP workflows. Key improvements:
- research: pure codebase cartography with query classification and follow-up
- investigate: new cookbook for strategic research + feasibility assessment
- prd: 3-round interactive interview with MoSCoW, JTBD, implementation phases
- plan: PRD phase auto-detection, UX diagrams, confidence score, prior-knowledge test
- implement: env detection, base branch auto-detect, git state decision tree
- review: PR checkout, state handling, plan deviation awareness, GitHub posting
- debug: hypothesis-driven methodology, quick/deep modes, 3-test validation
- commit: natural language file targeting while keeping safety checks
- pr: template detection, existing PR check, draft support, base branch auto-detect
Updated SKILL.md description with project-anchored triggers and concrete
examples per cookbook to improve routing accuracy.
* fix(skills): add missing routing keywords for investigate cookbook
Add "can we" and "best approach" to investigate keywords — both are
common phrasings for feasibility questions that weren't being matched.
* fix(skills): broaden PR template search in pr cookbook
Scan .github folder and subfolders more thoroughly before concluding
no PR template exists.
* feat: overhaul PR template with comprehensive engineering sections
Replace minimal 5-section template with structured template covering
UX journey, architecture diagrams, security impact, blast radius,
rollback plan, and validation evidence. Adapted for the Archon
monorepo with project-specific scopes and validation commands.
* feat: improve bug report and feature request issue templates
Add structured sections for user flow diagrams, scope identification,
impact assessment, security considerations, and definition of done.
Adapted for the Archon monorepo with project-specific packages and
platform options.
* feat(skills): add issue cookbook for GitHub bug/feature reporting
New cookbook that classifies bug vs feature, finds the repo's issue
template, validates with a subagent, and submits via gh CLI. Updated
SKILL.md routing table and workflow chain diagram.
* 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.
* feat: Enforce ESLint zero-warnings policy in CI
- Update ESLint config to turn off false-positive rules (restrict-template-expressions,
no-unnecessary-condition, prefer-nullish-coalescing) and keep no-non-null-assertion as error
- Fix all 11 no-non-null-assertion errors in loader.ts, executor.ts, and command-handler.ts
- Add --max-warnings 0 to CI lint step and format:check step
- Update lint-staged to run ESLint with --fix on staged .ts files
- Update validate script to run type-check, lint --max-warnings 0, and format:check
- Document ESLint guidelines and pre-PR validation in CLAUDE.md
* test: Add file with lint error to verify CI failure
* Revert "test: Add file with lint error to verify CI failure"
This reverts commit f29d582cca24dedb51113202c8aed5cd5f6d0c9b.
* fix: Address PR review feedback for ESLint zero-warnings policy
- Restore tests to validate script (was accidentally removed)
- Update CLAUDE.md: fix "0 errors" → "0 warnings" terminology
- Update CLAUDE.md: replace eslint-disable example with guard clause pattern
- Update CLAUDE.md: expand disabled rules list with categories
- Organize eslint.config.mjs disabled rules by category with rationales
- Fix loader.ts error message to be more accurate about step validation
- Fix executor.ts comment to clarify the guard is meaningful (not just for TS)
* feat: Add workspace root configuration for Bun monorepo
Configure the root package.json, tsconfig.json, and eslint.config.mjs
for a Bun workspaces monorepo structure with packages/* workspace pattern.
- Convert root package.json to workspace root with workspaces: ["packages/*"]
- Update scripts to use bun --filter for cross-package commands
- Update tsconfig.json to serve as base config for packages to extend
- Update eslint.config.mjs for monorepo paths (packages/*/src/**)
- Update .gitignore for packages/*/node_modules and dist directories
* feat: Create @archon/core package with shared business logic
Extract all shared business logic into @archon/core package:
- types/ - Core TypeScript interfaces (IPlatformAdapter, IAssistantClient, etc.)
- utils/ - Shared utilities (git, auth, formatting, paths, etc.)
- config/ - YAML config loading (loadConfig, loadGlobalConfig, loadRepoConfig)
- state/ - Session state machine (TransitionTrigger, session transitions)
- db/ - PostgreSQL operations (conversations, codebases, sessions, etc.)
- clients/ - AI SDK wrappers (ClaudeClient, CodexClient, factory)
- isolation/ - Git worktree management (WorktreeProvider)
- workflows/ - YAML workflow engine (loader, executor, router, logger)
- services/ - Background services (cleanup-service)
- orchestrator/ - Message orchestration (handleMessage)
- handlers/ - Slash command processing (handleCommand, parseCommand)
- test/ - Test mocks and setup utilities
Package exports are organized with submodule paths for tree-shaking:
- @archon/core - Main exports
- @archon/core/db/* - Database operations
- @archon/core/utils/* - Utility functions
- @archon/core/workflows - Workflow types and functions
All 924 tests pass with the new structure.
* feat: Create @archon/server package with platform adapters
Extract platform-specific code into @archon/server package:
- adapters/ - Platform integrations (Telegram, Slack, Discord, GitHub, Test)
- index.ts - Express server entry point with health checks and webhook handlers
- scripts/ - Setup utilities (setup-auth.ts)
The server package depends on @archon/core via workspace:* reference
and imports shared business logic using @archon/core package paths.
Imports updated to use @archon/core:
- Types: import type { IPlatformAdapter } from '@archon/core'
- DB: import * as conversationDb from '@archon/core/db/conversations'
- Utils: import { handleMessage, ConversationLockManager } from '@archon/core'
Added .env symlink to packages/server/.env for dotenv compatibility.
* chore: Update bun.lock for workspace dependencies
Regenerated lockfile after restructuring to Bun workspaces with
@archon/core and @archon/server packages.
* docs: Update documentation for monorepo structure
Update CLAUDE.md, docs/architecture.md, and docs/new-developer-guide.md to reflect the new Bun monorepo structure introduced in PR #311.
Changes:
- Updated directory structure to show packages/core and packages/server
- Added import patterns section showing @archon/core and @archon/server usage
- Updated all file path references from src/* to packages/*/src/*
- Updated test command examples
- Clarified package split (core: business logic, server: adapters + HTTP)
* fix: Address PR review feedback - imports and auth naming
CLAUDE.md:
- Add typed imports guidance (always use `import type` for types,
specific named imports for values, avoid generic `import *`)
packages/core/src/index.ts:
- Alias all auth parseAllowedUserIds functions with platform prefix:
- parseTelegramAllowedUserIds (returns number[])
- parseSlackAllowedUserIds (returns string[])
- parseDiscordAllowedUserIds (returns string[])
- parseGitHubAllowedUsers (already aliased)
- Alias isUserAuthorized as isTelegramUserAuthorized for consistency
- Update JSDoc to mention isolation is extensible for containers/VMs
packages/core/src/db/index.ts:
- Update JSDoc to not overstate naming conflicts (db modules have
distinct function names)
packages/core/src/clients/index.ts:
- Clarify when to use submodule path vs main package
packages/server/src/adapters/telegram.ts:
- Update to use new aliased auth function names
* fix: Update CI and bunfig.toml for monorepo structure
- Update bunfig.toml test root from ./src to ./packages
- Update preload path to packages/core/src/test/setup.ts
- Update CI workflow test paths for packages/core and packages/server
* fix: Run factory tests in isolation to avoid mock.module pollution
Bun's mock.module() pollutes the global module registry, causing factory tests
to fail when run after claude.test.ts or codex.test.ts (which mock the clients).
Test execution order now:
1. Factory tests first (before any mock.module calls)
2. Client tests (claude, codex) that use mock.module
3. All other tests (db, utils, handlers, etc.)
4. Orchestrator tests last (also uses mock.module)
* fix: Run command-handler tests in isolation to avoid mock pollution
The command-handler tests use mock.module() for database mocks, which causes
test isolation issues when run in the same Bun process as other tests.
Test execution order now:
1. Factory tests (no mocks)
2. Client tests (claude, codex) with mock.module
3. Command-handler tests with mock.module (isolated from step 2)
4. All other tests (db, utils, config, etc.)
5. Orchestrator tests last (also uses mock.module)
* Add Archon distribution config and directory structure
- Create centralized path resolution in src/utils/archon-paths.ts
- Add YAML configuration system (src/config/) with layered loading
- Update Dockerfile and docker-compose for /.archon/ directory
- Add GHCR publish workflow for multi-arch Docker builds
- Create deploy/ directory with end-user docker-compose
- Add /init command to create .archon structure in repos
- Add docs/configuration.md reference guide
- Update README with Quick Start section
- Add bun run validate script
- Update tests for new path defaults (~/.archon/)
Directory structure:
- Local: ~/.archon/{workspaces,worktrees,config.yaml}
- Docker: /.archon/{workspaces,worktrees}
- Repo: .archon/{commands,workflows,config.yaml}
Legacy WORKSPACE_PATH and WORKTREE_BASE env vars still supported.
* Complete Archon distribution config implementation
- Wire up config system in src/index.ts (Task 3.5)
- Remove legacy WORKSPACE_PATH and WORKTREE_BASE support
- Add logConfig() function to config-loader.ts
- Update docker-compose.yml to use ARCHON_DOCKER env var
- Remove legacy env vars from .env.example
- Update all documentation to reference ARCHON_HOME
- Create scripts/validate-setup.sh for setup validation
- Add setup:check script to package.json
- Create docs/getting-started.md guide
- Create docs/archon-architecture.md technical docs
- Update tests to use ARCHON_HOME instead of legacy vars
- Fix validate.md command template for new paths
All plan phases now complete:
- Phase 1: Archon Directory Structure
- Phase 2: Docker Distribution
- Phase 3: YAML Configuration System
- Phase 4: Developer Experience
- Phase 5: Documentation
* Migrate from Node.js/npm/Jest to Bun runtime
- Replace npm with bun for package management (bun.lock)
- Replace Jest with bun:test for testing
- Update tsconfig for Bun (ESNext module, bundler resolution)
- Update Dockerfile to use oven/bun:1-slim
- Update CI workflow to use oven-sh/setup-bun@v2
- Remove dynamic import hack from codex.ts (direct ESM imports)
- Fix test mocking for Bun (export execFileAsync, use spyOn)
- Update all documentation (CLAUDE.md, README.md, CONTRIBUTING.md)
All 395 tests pass, type-check passes, E2E validated with curl.
* ci: retrigger CI build
* fix: make execFileAsync a function for better Bun mockability
* fix: ensure execFileAsync returns string not Buffer
* fix: rename _execFileAsync to comply with naming convention
* fix: make mkdirAsync mockable for Bun tests
* fix: update engines to bun>=1.0.0 and add mkdirAsync mock
* fix: pin Bun to 1.3.4 in CI to fix mock.module test failures
Newer Bun versions have different mock.module() behavior that causes
cross-test module pollution, resulting in 71 test failures in CI while
tests pass locally. Pinning to 1.3.4 ensures consistent behavior.
* fix: run orchestrator tests last to avoid mock.module pollution
Bun's mock.module() pollutes the global module cache, causing tests to
fail when orchestrator.test.ts (which mocks command-handler and factory)
runs before those modules' own test files.
Fix by running tests in two batches:
1. All tests except orchestrator
2. Orchestrator tests last
This ensures orchestrator's mocks don't affect other test files.
* docs: add PRP for improving test coverage
- Create comprehensive PRP documenting test infrastructure improvements
- Add coverage directory to .gitignore
- Plan covers 6 phases: infrastructure, utilities, database, adapters, orchestrator, CI/CD
- Target: increase coverage from 15.98% to 80%+
* test: add comprehensive unit test coverage
- Add test infrastructure: setup.ts, mock utilities for database, platform, and streaming
- Add tests for all database modules (conversations, codebases, sessions)
- Add tests for test adapter, client factory, orchestrator
- Expand Claude and Codex client tests with full mock coverage
- Add tool-formatter tests
- Configure Jest with coverage thresholds (30% branches, 40% functions/lines/statements)
- Add CI workflow for automated testing on push/PR
- Add test:coverage and test:ci npm scripts
Coverage: 170 tests passing, 53% lines, 48% branches, 65% functions
Co-Authored-By: Claude <noreply@anthropic.com>
* chore: improve test coverage and fix type issues
- Fix type annotations across multiple files
- Improve test mocks for streaming and database operations
- Update jest config for better coverage reporting
- Fix minor type issues in orchestrator, sessions, and adapters
- Update documentation for architecture and cloud deployment
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>