* 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.
41 KiB
Phase 5: CLI Binary Distribution
Overview
Phase 5 creates standalone binary distributions of the Archon CLI for macOS and Linux. This enables users to install and run Archon without needing Bun, Node.js, or any other runtime installed. Windows users will use a documented manual installation process via cloning the repository.
Why this matters:
- Zero-dependency installation for end users
- Single binary download (no
npm install, nobun install) - Works immediately after install (
archon workflow list) - Leverages Phase 3's SQLite support (no PostgreSQL required)
Prerequisites
- Phase 1 complete: Monorepo structure with
@archon/coreextracted - Phase 2 complete: CLI entry point and basic commands working
- Phase 3 complete: Database abstraction (SQLite + PostgreSQL auto-detection)
- Phase 4 complete: Express → Hono migration
- Issue #322 complete: Default commands/workflows loaded at runtime (not copied) - PR #324 merged
Critical dependency from Phase 3: The CLI uses SQLite by default when DATABASE_URL is not set. This is essential for standalone binary distribution - users don't need a database server.
Critical dependency from Issue #322: Default commands and workflows must be bundled into the binary. See "Bundled Defaults" section below.
Current State
The CLI exists at packages/cli/ with:
- Entry point:
src/cli.ts(shebang:#!/usr/bin/env bun) - Commands:
workflow list/run/status,isolation list/cleanup,version - Package name:
@archon/cli - Current invocation:
bun run cliorbun packages/cli/src/cli.ts
Existing GitHub Actions:
publish.yml- Docker image publishing (triggers on tags/releases)test.yml- CI testing
Desired End State
Users can install Archon CLI with a single command:
# macOS/Linux - Primary method
curl -fsSL https://raw.githubusercontent.com/dynamous-community/remote-coding-agent/main/scripts/install.sh | bash
# Homebrew - Alternative for Homebrew users
brew install https://raw.githubusercontent.com/dynamous-community/remote-coding-agent/main/Formula/archon.rb
# Then use immediately
archon workflow list
archon workflow run assist "Hello world"
Note: This repository is currently at dynamous-community/remote-coding-agent and will be moved to a public repository (likely archon-cli/archon or similar) before the first release. All URLs in this plan use a REPO variable that will be updated at that time.
Platform support:
| Platform | Architecture | Distribution Method |
|---|---|---|
| macOS | ARM64 (Apple Silicon) | curl script, Homebrew, direct download |
| macOS | x64 (Intel) | curl script, Homebrew, direct download |
| Linux | x64 | curl script, direct download |
| Linux | ARM64 | curl script, direct download |
| Windows | x64 | Manual: clone repo + bun run cli |
Verification:
- Downloaded binary runs without Bun installed
archon versionshows correct versionarchon workflow listworks (uses SQLite, no DATABASE_URL needed)- curl script detects OS/arch and downloads correct binary
- GitHub Releases contains all platform binaries
What We're NOT Doing
- NOT creating a separate Homebrew tap repository (deferred to Phase 6)
- NOT publishing to npm
- NOT creating Windows binary (users clone + run with Bun)
- NOT setting up custom domain (using GitHub URLs)
- NOT adding new CLI features (distribution only)
- NOT changing CLI behavior
Repository Location
Current: dynamous-community/remote-coding-agent (private)
Future: Will be moved to a public repository before the first binary release. When this happens:
- Update the
REPOvariable inscripts/install.sh - Update the URLs in
Formula/archon.rb - Update the README.md installation instructions
All scripts use variables ($REPO, ${{ github.repository }}) to make this transition easier.
Bundled Defaults (Critical for Binary Distribution)
The Problem
When the CLI is compiled into a standalone binary, it has no access to filesystem defaults. The binary is just compiled TypeScript—it cannot read the loose .archon/commands/defaults/ and .archon/workflows/defaults/ files that exist in the source repository.
Without bundling:
| Scenario | Result |
|---|---|
| User installs standalone binary | 0 commands, 0 workflows available |
User runs archon workflow list |
Empty list |
User runs archon workflow run assist "Hello" |
"Workflow not found" error |
The Solution
Bundle default commands and workflows into the compiled binary at build time using Bun's static imports:
// packages/core/src/defaults/bundled-defaults.ts
import assistCommand from '../../../.archon/commands/defaults/assist.md' with { type: 'text' };
import fixGithubIssueWorkflow from '../../../.archon/workflows/defaults/fix-github-issue.yaml' with { type: 'text' };
// ... all other defaults
export const BUNDLED_COMMANDS = {
assist: assistCommand,
implement: implementCommand,
// ... 16 total commands
};
export const BUNDLED_WORKFLOWS = {
'fix-github-issue': fixGithubIssueWorkflow,
assist: assistWorkflow,
// ... 8 total workflows
};
These imports are resolved at compile time and embedded directly into the binary. At runtime, the CLI reads from the embedded content.
How It Works With Issue #322
Issue #322 changes the loading behavior to:
- Load app's defaults at runtime (from filesystem when running with Bun)
- Load target repo's project-specific commands (additive)
For the standalone binary, we extend this:
- If running as binary: Load from
BUNDLED_COMMANDSandBUNDLED_WORKFLOWS - If running with Bun: Load from filesystem (existing behavior)
- Load target repo's project-specific commands (additive, same either way)
// packages/core/src/workflows/loader.ts
import { BUNDLED_WORKFLOWS } from '../defaults/bundled-defaults';
function isBinaryBuild(): boolean {
return !process.execPath.toLowerCase().includes('bun');
}
async function discoverWorkflows(targetRepoPath: string): Promise<Workflow[]> {
const workflows: Workflow[] = [];
// 1. Load defaults (bundled for binary, filesystem for bun)
if (isBinaryBuild()) {
// Binary: use embedded defaults
for (const [name, content] of Object.entries(BUNDLED_WORKFLOWS)) {
workflows.push(parseWorkflow(name, content));
}
} else {
// Bun: load from filesystem (existing behavior)
const appDefaultsPath = join(getAppArchonBasePath(), 'workflows', 'defaults');
workflows.push(...(await loadWorkflowsFrom(appDefaultsPath)));
}
// 2. Load repo's project-specific workflows (additive)
const repoWorkflowsPath = join(targetRepoPath, '.archon', 'workflows');
workflows.push(...(await loadWorkflowsFrom(repoWorkflowsPath)));
return dedupeByName(workflows);
}
Binary Size Impact
The defaults are just text files (~150KB total). This adds negligible size to the ~50-100MB binary.
Implementation Note
Issue #322 must be completed first. It establishes:
- Runtime loading architecture (no more copying)
- Multi-source discovery (app defaults + repo-specific)
- Opt-out configuration
Phase 5 then adds:
- The
bundled-defaults.tsfile with static imports - Detection of binary vs Bun runtime
- Conditional loading from bundled content
Implementation Plan
Phase 5.0: Bundle Defaults for Binary Distribution
Goal: Create the bundled defaults module so default commands and workflows are embedded in the compiled binary.
Prerequisite: Issue #322 must be merged first (runtime loading architecture).
Files Created:
packages/core/src/defaults/bundled-defaults.ts- Static imports of all defaultspackages/core/src/defaults/index.ts- Exports for the defaults module
Changes:
5.0.1: Create bundled-defaults.ts
// packages/core/src/defaults/bundled-defaults.ts
// Static imports - resolved at compile time and embedded in binary
// Commands (16 total)
import assistCmd from '../../../../.archon/commands/defaults/assist.md' with { type: 'text' };
import implementCmd from '../../../../.archon/commands/defaults/implement.md' with { type: 'text' };
import planCmd from '../../../../.archon/commands/defaults/plan.md' with { type: 'text' };
import investigateCmd from '../../../../.archon/commands/defaults/investigate.md' with { type: 'text' };
import debugCmd from '../../../../.archon/commands/defaults/debug.md' with { type: 'text' };
import reviewCmd from '../../../../.archon/commands/defaults/review.md' with { type: 'text' };
import commitCmd from '../../../../.archon/commands/defaults/commit.md' with { type: 'text' };
import prCmd from '../../../../.archon/commands/defaults/pr.md' with { type: 'text' };
// ... import all 16 commands
// Workflows (8 total)
import fixGithubIssueWf from '../../../../.archon/workflows/defaults/fix-github-issue.yaml' with { type: 'text' };
import assistWf from '../../../../.archon/workflows/defaults/assist.yaml' with { type: 'text' };
import implementWf from '../../../../.archon/workflows/defaults/implement.yaml' with { type: 'text' };
import planWf from '../../../../.archon/workflows/defaults/plan.yaml' with { type: 'text' };
// ... import all 8 workflows
export const BUNDLED_COMMANDS: Record<string, string> = {
assist: assistCmd,
implement: implementCmd,
plan: planCmd,
investigate: investigateCmd,
debug: debugCmd,
review: reviewCmd,
commit: commitCmd,
pr: prCmd,
// ... all 16 commands
};
export const BUNDLED_WORKFLOWS: Record<string, string> = {
'fix-github-issue': fixGithubIssueWf,
assist: assistWf,
implement: implementWf,
plan: planWf,
// ... all 8 workflows
};
Note: The actual file will need to import ALL defaults. Generate this file by listing .archon/commands/defaults/ and .archon/workflows/defaults/.
5.0.2: Update workflow loader to use bundled defaults
Modify packages/core/src/workflows/loader.ts:
import { BUNDLED_WORKFLOWS } from '../defaults/bundled-defaults';
/**
* Detect if running as compiled binary (vs running with bun)
*/
function isBinaryBuild(): boolean {
return !process.execPath.toLowerCase().includes('bun');
}
/**
* Load bundled workflows (for binary distribution)
*/
function loadBundledWorkflows(): Workflow[] {
return Object.entries(BUNDLED_WORKFLOWS).map(([name, content]) => {
return parseWorkflowYaml(name, content);
});
}
// Update discoverWorkflows to check isBinaryBuild()
5.0.3: Update command handler to use bundled defaults
Similar changes to packages/core/src/handlers/command-handler.ts for commands.
Success Criteria (5.0):
Automated Verification:
bun run type-checkpassesbun testpasses- All default commands and workflows are imported in
bundled-defaults.ts
Manual Verification:
- Build a test binary:
bun build --compile packages/cli/src/cli.ts --outfile=test-archon - Run
./test-archon workflow list- should show all default workflows - Run
./test-archon workflow run assist "Hello"- should work (deferred - requires database) - Compare output to
bun run cli workflow list- should be identical
Implementation Note: This phase must be completed before Phase 5.1 (build scripts). The bundled defaults are essential for the binary to be useful.
Phase 5.1: Build Scripts for Binary Compilation
Goal: Create scripts to compile the CLI into standalone binaries for all target platforms.
Files Created:
scripts/build-binaries.sh- Main build scriptscripts/checksums.sh- Generate SHA256 checksums
Changes:
5.1.1: Create build-binaries.sh
#!/usr/bin/env bash
# scripts/build-binaries.sh
# Build standalone CLI binaries for all supported platforms
set -euo pipefail
# Get version from package.json or git tag
VERSION="${VERSION:-$(grep '"version"' package.json | head -1 | cut -d'"' -f4)}"
echo "Building Archon CLI v${VERSION}"
# Output directory
DIST_DIR="dist/binaries"
mkdir -p "$DIST_DIR"
# Define build targets
# Format: bun-target output-name
TARGETS=(
"bun-darwin-arm64:archon-darwin-arm64"
"bun-darwin-x64:archon-darwin-x64"
"bun-linux-x64:archon-linux-x64"
"bun-linux-arm64:archon-linux-arm64"
)
# Build each target
for target_pair in "${TARGETS[@]}"; do
IFS=':' read -r target output_name <<< "$target_pair"
echo "Building for $target..."
bun build \
--compile \
--target="$target" \
--outfile="$DIST_DIR/$output_name" \
packages/cli/src/cli.ts
echo " → $DIST_DIR/$output_name"
done
echo ""
echo "Build complete! Binaries in $DIST_DIR:"
ls -lh "$DIST_DIR"
5.1.2: Create checksums.sh
#!/usr/bin/env bash
# scripts/checksums.sh
# Generate SHA256 checksums for release binaries
set -euo pipefail
DIST_DIR="${1:-dist/binaries}"
CHECKSUM_FILE="$DIST_DIR/checksums.txt"
echo "Generating checksums for binaries in $DIST_DIR"
cd "$DIST_DIR"
shasum -a 256 archon-* > checksums.txt
echo "Checksums written to $CHECKSUM_FILE:"
cat checksums.txt
5.1.3: Update root package.json
Add build scripts:
{
"scripts": {
"build:binaries": "bash scripts/build-binaries.sh",
"build:checksums": "bash scripts/checksums.sh"
}
}
Success Criteria (5.1):
Automated Verification:
bun run build:binariescompletes without errors- Four binaries exist in
dist/binaries/:archon-darwin-arm64archon-darwin-x64archon-linux-x64archon-linux-arm64
bun run build:checksumsgeneratesdist/binaries/checksums.txt- Each binary is executable:
chmod +xand file shows correct architecture
Manual Verification:
- On macOS ARM64:
./dist/binaries/archon-darwin-arm64 versionworks - Binary runs without Bun installed (test in clean environment or Docker) (deferred - manual verification)
Implementation Note: Complete this phase before proceeding. The build scripts are the foundation for all distribution methods.
Phase 5.2: GitHub Actions Release Workflow
Goal: Automate binary building and release on git tags.
Files Created:
.github/workflows/release.yml- Build and release binaries
Changes:
5.2.1: Create release.yml
name: Release
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
tag:
description: 'Tag to release (e.g., v0.3.0)'
required: true
permissions:
contents: write
jobs:
build:
name: Build binaries
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Build binaries
run: bun run build:binaries
- name: Generate checksums
run: bun run build:checksums
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: binaries
path: dist/binaries/*
retention-days: 7
release:
name: Create GitHub Release
needs: build
runs-on: ubuntu-latest
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: binaries
path: dist/binaries
- name: Get version
id: version
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "version=${{ inputs.tag }}" >> $GITHUB_OUTPUT
else
echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
fi
- name: Create Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.version.outputs.version }}
name: Archon ${{ steps.version.outputs.version }}
draft: false
prerelease: ${{ contains(steps.version.outputs.version, '-') }}
files: |
dist/binaries/archon-darwin-arm64
dist/binaries/archon-darwin-x64
dist/binaries/archon-linux-x64
dist/binaries/archon-linux-arm64
dist/binaries/checksums.txt
body: |
## Installation
### Quick Install (macOS/Linux)
```bash
curl -fsSL https://raw.githubusercontent.com/${{ github.repository }}/main/scripts/install.sh | bash
```
### Manual Download
Download the appropriate binary for your platform below, then:
```bash
chmod +x archon-*
sudo mv archon-* /usr/local/bin/archon
```
### Verify Checksums
```bash
shasum -a 256 -c checksums.txt
```
## What's New
See [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/main/CHANGELOG.md) for details.
Success Criteria (5.2):
Automated Verification:
- Workflow file created at
.github/workflows/release.yml - Push a test tag (e.g.,
v0.2.1-test) triggers the workflow (deferred - manual test) - Workflow completes successfully (deferred - requires push)
- GitHub Release is created with all 5 files (4 binaries + checksums) (deferred - requires push)
Manual Verification:
- Download a binary from the release and verify it runs (deferred - requires release)
- Checksums match:
shasum -a 256 -c checksums.txt(deferred - requires release) - Delete test release and tag after verification (deferred - requires release)
Implementation Note: Test with a pre-release tag first before creating a real release.
Phase 5.3: Curl Install Script
Goal: Create an install script that detects OS/architecture and installs the correct binary.
Files Created:
scripts/install.sh- Universal install script
Changes:
5.3.1: Create install.sh
#!/usr/bin/env bash
# scripts/install.sh
# Install Archon CLI - downloads the correct binary for your platform
#
# Usage:
# curl -fsSL https://raw.githubusercontent.com/dynamous-community/remote-coding-agent/main/scripts/install.sh | bash
#
# Environment variables:
# ARCHON_VERSION - Specific version to install (default: latest)
# ARCHON_INSTALL_DIR - Installation directory (default: /usr/local/bin)
set -euo pipefail
# Configuration
# NOTE: Update this when repository moves to public location
REPO="${ARCHON_REPO:-dynamous-community/remote-coding-agent}"
INSTALL_DIR="${ARCHON_INSTALL_DIR:-/usr/local/bin}"
BINARY_NAME="archon"
# Colors for output (if terminal supports it)
if [[ -t 1 ]]; then
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
else
RED=''
GREEN=''
YELLOW=''
BLUE=''
NC=''
fi
info() { echo -e "${BLUE}[INFO]${NC} $1"; }
success() { echo -e "${GREEN}[OK]${NC} $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1" >&2; exit 1; }
# Detect OS
detect_os() {
local os
os="$(uname -s)"
case "$os" in
Darwin) echo "darwin" ;;
Linux) echo "linux" ;;
MINGW* | MSYS* | CYGWIN*)
error "Windows is not supported via this script. Please see: https://github.com/$REPO#windows-installation"
;;
*) error "Unsupported operating system: $os" ;;
esac
}
# Detect architecture
detect_arch() {
local arch
arch="$(uname -m)"
case "$arch" in
x86_64 | amd64) echo "x64" ;;
arm64 | aarch64) echo "arm64" ;;
*) error "Unsupported architecture: $arch" ;;
esac
}
# Get latest version from GitHub releases
get_latest_version() {
curl -fsSL "https://api.github.com/repos/$REPO/releases/latest" |
grep '"tag_name"' |
head -1 |
cut -d'"' -f4
}
# Download and install
main() {
info "Archon CLI Installer"
echo ""
# Detect platform
local os arch
os="$(detect_os)"
arch="$(detect_arch)"
info "Detected platform: $os-$arch"
# Get version
local version
version="${ARCHON_VERSION:-$(get_latest_version)}"
if [[ -z "$version" ]]; then
error "Could not determine version to install. Set ARCHON_VERSION or check GitHub releases."
fi
info "Installing version: $version"
# Construct download URL
local binary_name="archon-${os}-${arch}"
local download_url="https://github.com/$REPO/releases/download/${version}/${binary_name}"
# Create temp directory
local tmp_dir
tmp_dir="$(mktemp -d)"
trap 'rm -rf "$tmp_dir"' EXIT
# Download binary
info "Downloading $binary_name..."
if ! curl -fsSL "$download_url" -o "$tmp_dir/archon"; then
error "Failed to download binary from: $download_url"
fi
# Make executable
chmod +x "$tmp_dir/archon"
# Verify binary works
info "Verifying binary..."
if ! "$tmp_dir/archon" version > /dev/null 2>&1; then
error "Binary verification failed. The downloaded file may be corrupted."
fi
# Install to destination
info "Installing to $INSTALL_DIR..."
if [[ -w "$INSTALL_DIR" ]]; then
mv "$tmp_dir/archon" "$INSTALL_DIR/$BINARY_NAME"
else
warn "Need sudo to install to $INSTALL_DIR"
sudo mv "$tmp_dir/archon" "$INSTALL_DIR/$BINARY_NAME"
fi
echo ""
success "Archon CLI $version installed successfully!"
echo ""
info "Run 'archon help' to get started"
info "Documentation: https://github.com/$REPO"
}
main "$@"
Success Criteria (5.3):
Automated Verification:
- Script syntax is valid:
bash -n scripts/install.sh - Script is executable:
chmod +x scripts/install.sh shellcheck scripts/install.shpasses (optional - shellcheck not installed)
Manual Verification:
- Test on macOS (after releasing binaries) (deferred - requires release):
curl -fsSL https://raw.githubusercontent.com/dynamous-community/remote-coding-agent/main/scripts/install.sh | bash archon version - Test on Linux (Docker) (deferred - requires release):
docker run --rm -it ubuntu:22.04 bash -c " apt-get update && apt-get install -y curl curl -fsSL https://raw.githubusercontent.com/dynamous-community/remote-coding-agent/main/scripts/install.sh | bash /usr/local/bin/archon version " - Verify correct binary is downloaded for each platform/architecture (deferred - requires release)
- Verify error message shows for Windows detection (deferred - requires Windows)
Implementation Note: The install script must be committed to main before it can be used via raw.githubusercontent.com URL.
Phase 5.4: Homebrew Formula (Main Repo)
Goal: Create a Homebrew formula in the main repository for users who prefer Homebrew.
Files Created:
Formula/archon.rb- Homebrew formula
Changes:
5.4.1: Create Formula directory and formula
# Formula/archon.rb
# Homebrew formula for Archon CLI
# Install: brew install --HEAD https://raw.githubusercontent.com/dynamous-community/remote-coding-agent/main/Formula/archon.rb
class Archon < Formula
desc "AI-powered coding assistant CLI - run workflows from the command line"
homepage "https://github.com/dynamous-community/remote-coding-agent"
license "MIT"
# Version-specific bottles (populated by release workflow)
# For now, we use HEAD installation which downloads from releases
on_macos do
on_arm do
url "https://github.com/dynamous-community/remote-coding-agent/releases/latest/download/archon-darwin-arm64"
sha256 :no_check # Will be populated in versioned releases
def install
bin.install "archon-darwin-arm64" => "archon"
end
end
on_intel do
url "https://github.com/dynamous-community/remote-coding-agent/releases/latest/download/archon-darwin-x64"
sha256 :no_check # Will be populated in versioned releases
def install
bin.install "archon-darwin-x64" => "archon"
end
end
end
on_linux do
on_arm do
url "https://github.com/dynamous-community/remote-coding-agent/releases/latest/download/archon-linux-arm64"
sha256 :no_check # Will be populated in versioned releases
def install
bin.install "archon-linux-arm64" => "archon"
end
end
on_intel do
url "https://github.com/dynamous-community/remote-coding-agent/releases/latest/download/archon-linux-x64"
sha256 :no_check # Will be populated in versioned releases
def install
bin.install "archon-linux-x64" => "archon"
end
end
end
test do
assert_match "Archon CLI", shell_output("#{bin}/archon version")
end
end
Note: This formula uses sha256 :no_check which Homebrew allows but warns about. For production, we'll want to either:
- Create versioned formulas with actual checksums (Phase 6 with Homebrew tap)
- Or use the curl script as the primary installation method
5.4.2: Alternative - Simple HEAD formula
If the above approach has issues, here's a simpler HEAD-only formula:
# Formula/archon.rb
class Archon < Formula
desc "AI-powered coding assistant CLI"
homepage "https://github.com/dynamous-community/remote-coding-agent"
head "https://github.com/dynamous-community/remote-coding-agent.git", branch: "main"
license "MIT"
depends_on "oven-sh/bun/bun" => :build
def install
system "bun", "install", "--frozen-lockfile"
system "bun", "build", "--compile", "--outfile=archon", "packages/cli/src/cli.ts"
bin.install "archon"
end
test do
assert_match "Archon CLI", shell_output("#{bin}/archon version")
end
end
This builds from source, which works but is slower. Recommend using the first approach with pre-built binaries.
Success Criteria (5.4):
Automated Verification:
- Formula file created at
Formula/archon.rb - Formula syntax is valid:
brew audit Formula/archon.rb(deferred - requires release with binaries) brew style Formula/archon.rbpasses (deferred - requires release with binaries)
Manual Verification:
- Install works (deferred - requires release with binaries):
brew install --HEAD Formula/archon.rb archon version - Or via URL (deferred - requires release with binaries):
brew install https://raw.githubusercontent.com/dynamous-community/remote-coding-agent/main/Formula/archon.rb
Implementation Note: Homebrew formula with pre-built binaries is the preferred approach. The HEAD formula (building from source) is a fallback.
Phase 5.5: Windows Documentation
Goal: Document the Windows installation process clearly for Windows users.
Files Modified:
README.md- Add installation section
Changes:
5.5.1: Add Installation section to README.md
Add the following section to the README (adjust location as appropriate):
## Installation
### macOS / Linux (Recommended)
Install with a single command:
```bash
curl -fsSL https://raw.githubusercontent.com/dynamous-community/remote-coding-agent/main/scripts/install.sh | bash
```
Or download directly from GitHub Releases.
macOS with Homebrew
brew install https://raw.githubusercontent.com/dynamous-community/remote-coding-agent/main/Formula/archon.rb
Windows
Windows binary distribution is not yet available. To use Archon on Windows:
-
Install Bun (required):
powershell -c "irm bun.sh/install.ps1 | iex" -
Clone the repository:
git clone https://github.com/dynamous-community/remote-coding-agent.git cd archon -
Install dependencies:
bun install -
Run the CLI:
bun run cli workflow list bun run cli workflow run assist "Hello world"
Tip: Create an alias for easier usage:
# Add to your PowerShell profile ($PROFILE)
function archon { bun run cli $args }
Verify Installation
After installation, verify it works:
archon version
archon help
Updating
macOS/Linux (curl install):
curl -fsSL https://raw.githubusercontent.com/dynamous-community/remote-coding-agent/main/scripts/install.sh | bash
Homebrew:
brew upgrade archon
Windows:
cd archon
git pull
bun install
### Success Criteria (5.5):
#### Automated Verification:
- [x] README.md updated with CLI Installation section
- [x] All code blocks have language specified
#### Manual Verification:
- [x] Instructions are clear and follow correctly
- [ ] Links to releases and repository work (deferred - requires release)
- [ ] Windows instructions work on a Windows machine (or VM) (deferred - requires Windows)
---
### Phase 5.6: Version Command Update
**Goal**: Ensure the version command shows useful information for installed binaries.
**Files Modified:**
- `packages/cli/src/commands/version.ts`
**Changes:**
#### 5.6.1: Enhance version command
The version command should show:
- CLI version (from package.json)
- Platform and architecture
- Installation method hint (binary vs bun)
- Database backend in use
```typescript
// packages/cli/src/commands/version.ts
import { readFileSync } from 'fs';
import { dirname, join } from 'path';
import { fileURLToPath } from 'url';
import { getDatabaseType } from '@archon/core';
/**
* Get version from package.json
*/
function getVersion(): string {
try {
// Try to read from package.json (works in development)
const __dirname = dirname(fileURLToPath(import.meta.url));
const pkgPath = join(__dirname, '..', '..', 'package.json');
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
return pkg.version ?? 'unknown';
} catch {
// Fallback for compiled binary
return process.env.ARCHON_VERSION ?? '0.2.0';
}
}
/**
* Detect if running as compiled binary
*/
function isBinaryBuild(): boolean {
// Bun compiled binaries don't have Bun.main set the same way
// A simple heuristic: if process.execPath doesn't contain 'bun', it's a binary
return !process.execPath.toLowerCase().includes('bun');
}
/**
* Display version information
*/
export async function versionCommand(): Promise<void> {
const version = getVersion();
const platform = process.platform;
const arch = process.arch;
const dbType = getDatabaseType();
const buildType = isBinaryBuild() ? 'binary' : 'source (bun)';
console.log(`Archon CLI v${version}`);
console.log(` Platform: ${platform}-${arch}`);
console.log(` Build: ${buildType}`);
console.log(` Database: ${dbType}`);
}
5.6.2: Add getDatabaseType to core exports
In packages/core/src/index.ts, ensure getDatabaseType is exported:
export { getDatabaseType } from './db/connection';
In packages/core/src/db/connection.ts, add:
/**
* Get the current database type
*/
export function getDatabaseType(): 'postgresql' | 'sqlite' {
return process.env.DATABASE_URL ? 'postgresql' : 'sqlite';
}
Success Criteria (5.6):
Automated Verification:
bun run type-checkpassesbun run testpasses (tests updated for new version output format)
Manual Verification:
bun run cli versionshows correct info:Archon CLI v0.2.0 Platform: darwin-arm64 Build: source (bun) Database: sqlite- Compiled binary shows
Build: binary(deferred - tested locally earlier)
Phase 5.7: Developer Release Guide
Goal: Document the release process for maintainers so anyone can create a release.
Files Created:
docs/releasing.md- Developer guide for creating releases
Changes:
5.7.1: Create docs/releasing.md
# Releasing Archon CLI
This guide explains how to create new releases of the Archon CLI binary.
## Overview
Archon CLI releases are automated via GitHub Actions. When you push a version tag (e.g., `v0.3.0`), the workflow:
1. Builds binaries for all supported platforms (macOS ARM64/x64, Linux ARM64/x64)
2. Generates SHA256 checksums
3. Creates a GitHub Release with all artifacts
4. Updates the release notes
## Prerequisites
- Push access to the repository
- Git configured with your credentials
## Release Process
### 1. Prepare the Release
Before releasing, ensure:
```bash
# All tests pass
bun run validate
# You're on the main branch with latest changes
git checkout main
git pull origin main
```
2. Update Version Number
Update the version in package.json (root):
# Edit package.json and update "version" field
# Example: "0.2.0" → "0.3.0"
Also update packages/cli/package.json if it has its own version.
3. Update CHANGELOG.md
Add a new section for the release:
## [0.3.0] - 2026-01-21
### Added
- New feature X
- New feature Y
### Changed
- Improved Z
### Fixed
- Bug fix A
4. Commit Version Bump
git add package.json packages/cli/package.json CHANGELOG.md
git commit -m "chore: bump version to 0.3.0"
git push origin main
5. Create and Push Tag
# Create annotated tag
git tag -a v0.3.0 -m "Release v0.3.0"
# Push tag to trigger release workflow
git push origin v0.3.0
6. Monitor Release Workflow
- Go to Actions tab in GitHub
- Watch the "Release" workflow
- Verify all jobs complete successfully
7. Verify Release
Once the workflow completes:
- Check GitHub Releases for the new release
- Verify all 5 files are attached:
archon-darwin-arm64archon-darwin-x64archon-linux-arm64archon-linux-x64checksums.txt
- Test installation:
curl -fsSL https://raw.githubusercontent.com/dynamous-community/remote-coding-agent/main/scripts/install.sh | bash archon version
Manual Release (If Workflow Fails)
If the GitHub Actions workflow fails, you can build and release manually:
Build Binaries Locally
# Build all platform binaries
bun run build:binaries
# Generate checksums
bun run build:checksums
# Verify binaries exist
ls -la dist/binaries/
Create Release Manually
- Go to Releases → Draft a new release
- Choose the tag you created
- Set release title:
Archon v0.3.0 - Upload all files from
dist/binaries/ - Add release notes (copy from CHANGELOG.md)
- Publish release
Pre-release / Beta Releases
For pre-release versions:
# Use semantic versioning pre-release format
git tag -a v0.3.0-beta.1 -m "Beta release v0.3.0-beta.1"
git push origin v0.3.0-beta.1
Pre-releases (tags containing -) are automatically marked as pre-release in GitHub.
Hotfix Releases
For urgent fixes:
# Create hotfix branch from the release tag
git checkout -b hotfix/0.3.1 v0.3.0
# Make fixes, commit
git commit -m "fix: critical bug"
# Merge to main
git checkout main
git merge hotfix/0.3.1
# Tag and release
git tag -a v0.3.1 -m "Hotfix release v0.3.1"
git push origin main v0.3.1
Rollback a Release
If a release has critical issues:
- Do NOT delete the release (users may have already downloaded it)
- Create a new patch release with the fix
- Mark the broken release as pre-release (edit in GitHub UI)
- Update release notes to warn about the issue
Versioning Guidelines
We follow Semantic Versioning:
- MAJOR (1.0.0): Breaking changes to CLI interface or behavior
- MINOR (0.1.0): New features, backward compatible
- PATCH (0.0.1): Bug fixes, backward compatible
Examples:
- Adding a new command: MINOR
- Changing command output format: MAJOR (if scripts depend on it)
- Fixing a bug: PATCH
- Adding new optional flags: MINOR
Troubleshooting
Workflow fails on "Build binaries"
Check if Bun can compile for all targets:
bun build --compile --target=bun-darwin-arm64 packages/cli/src/cli.ts --outfile=test
Binary doesn't run on target platform
Ensure you're using the correct target. Test in Docker for Linux:
docker run --rm -v $(pwd)/dist/binaries:/bins ubuntu:22.04 /bins/archon-linux-x64 version
Checksums don't match
Regenerate checksums and re-upload:
cd dist/binaries
shasum -a 256 archon-* > checksums.txt
### Success Criteria (5.7):
#### Automated Verification:
- [x] `docs/releasing.md` exists and is valid markdown
- [x] All commands in the guide are correct (test locally)
#### Manual Verification:
- [x] Guide is clear and complete enough for a new maintainer to follow
- [ ] All links work (GitHub releases, repository URLs) (deferred - requires release)
---
## Testing Strategy
### Unit Tests
- Update version command tests if output format changed
- No other new unit tests needed (distribution doesn't change behavior)
### Integration Tests
Test the full installation flow:
```bash
# 1. Build binaries locally
bun run build:binaries
# 2. Test each binary on appropriate platform
./dist/binaries/archon-darwin-arm64 version
./dist/binaries/archon-darwin-arm64 help
./dist/binaries/archon-darwin-arm64 workflow list
# 3. Test without DATABASE_URL (should use SQLite)
unset DATABASE_URL
./dist/binaries/archon-darwin-arm64 workflow list
# 4. Test curl script (after first release)
curl -fsSL https://raw.githubusercontent.com/dynamous-community/remote-coding-agent/main/scripts/install.sh | bash
archon version
Manual Testing Steps
-
Local binary test (before release):
- Build all binaries:
bun run build:binaries - Test on current machine
- Test in Docker container (for Linux)
- Build all binaries:
-
Release test:
- Create pre-release tag:
git tag v0.2.1-test && git push --tags - Verify GitHub Actions workflow runs
- Download binary from release
- Test on fresh machine (VM or Docker)
- Create pre-release tag:
-
Install script test:
- Run curl script on macOS
- Run curl script in Ubuntu Docker container
- Run curl script in Alpine Docker container
- Verify correct binary downloaded for each platform
-
Homebrew test:
- Install formula on macOS
- Verify binary works after install
Risk Mitigation
| Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|
| Bun compile fails for some target | Low | High | Test build for all targets locally before workflow |
| Binary too large (>100MB) | Medium | Low | Accept size; Bun runtime is included. Can optimize later |
| curl script fails on some shells | Low | Medium | Use POSIX-compatible bash; test on zsh, bash, sh |
| Homebrew formula rejected by audit | Medium | Low | Use HEAD build as fallback; proper tap in Phase 6 |
| Install script permission issues | Low | Medium | Detect and prompt for sudo when needed |
| Old releases linger | Low | Low | Document upgrade process clearly |
Performance Considerations
Binary size: Expect 50-100MB per binary. This includes:
- JavaScriptCore runtime (Bun's JS engine)
- All bundled dependencies
- Source code
This is standard for Bun-compiled binaries and acceptable for the benefit of zero-dependency installation.
Startup time: Compiled binaries start faster than bun run cli since there's no dependency resolution at runtime.
Migration Notes
For existing users running from source:
- No migration needed -
bun run clicontinues to work - Can optionally switch to binary for convenience
For new users:
- Use curl script or Homebrew for easiest installation
- Binary uses SQLite by default (no database setup required)
Future Work (Phase 6+)
- Homebrew tap: Create
homebrew-archonrepository for cleaner install experience (brew install archon/archon/archon) - Windows binary: Investigate Windows binary distribution (PowerShell install script, Scoop/Chocolatey)
- npm package: Publish to npm for Node.js ecosystem users
- Custom domain: Set up
get.archon.devfor shorter curl URL - Auto-update: Add
archon updatecommand to self-update binary
References
- Research document:
thoughts/shared/research/2026-01-20-cli-first-refactor-feasibility.md - Phase 3 plan (SQLite):
thoughts/shared/plans/2026-01-20-phase-3-database-abstraction-cli-isolation.md - Phase 4 plan (Hono):
thoughts/shared/plans/2026-01-21-phase-4-express-to-hono-migration.md - Bun compile documentation: https://bun.sh/docs/bundler/executables
- GitHub Actions release: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#release
- Homebrew formula cookbook: https://docs.brew.sh/Formula-Cookbook
Estimated Effort
| Phase | Task | Estimate |
|---|---|---|
| 5.0 | Bundle defaults for binary | 2-3 hours |
| 5.1 | Build scripts | 1-2 hours |
| 5.2 | GitHub Actions workflow | 2-3 hours |
| 5.3 | Curl install script | 1-2 hours |
| 5.4 | Homebrew formula | 1 hour |
| 5.5 | Windows documentation | 30 minutes |
| 5.6 | Version command update | 30 minutes |
| 5.7 | Developer release guide | 30 minutes |
| Testing | End-to-end verification | 2-3 hours |
Total: 1.5-2.5 days
Note: Phase 5.0 depends on Issue #322 being completed first. The issue establishes runtime loading architecture; Phase 5.0 adds the bundled defaults for binary distribution.