From 40e63218553be5ae8485e1c7e1ec11efbdc739b4 Mon Sep 17 00:00:00 2001 From: "Leo A. D'Angelo" Date: Wed, 25 Mar 2026 14:22:32 -0500 Subject: [PATCH 1/2] =?UTF-8?q?docs:=20restructure=20README=20install=20in?= =?UTF-8?q?structions=20=E2=80=94=20lead=20with=20package=20install?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Moved Installation section above Quick Start with recommended methods: Homebrew, npm, curl, PowerShell. Quick Start now assumes foreman is already installed. Build-from-source moved to Development section as contributor workflow. Removed duplicate binary install section. Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 118 ++++++++++++++++++++++++++---------------------------- 1 file changed, 56 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index a00349ec..075a933f 100644 --- a/README.md +++ b/README.md @@ -193,29 +193,61 @@ flowchart TD - **[Pi](https://pi.dev)** _(installed as npm dependency)_ — agent runtime via `@mariozechner/pi-coding-agent` SDK. No separate binary needed. - **Anthropic API key** — `export ANTHROPIC_API_KEY=sk-ant-...` or log in via Pi: `pi /login` -## Quick Start +## Installation + +### Homebrew (macOS / Linux — recommended) ```bash -# 1. Install Foreman -git clone https://github.com/ldangelo/foreman -cd foreman -npm install && npm run build +brew tap oftheangels/tap +brew install foreman +``` + +### npm + +```bash +npm install -g @oftheangels/foreman +``` + +### curl (macOS / Linux) + +```bash +curl -fsSL https://raw.githubusercontent.com/ldangelo/foreman/main/install.sh | sh +``` + +### PowerShell (Windows) + +```powershell +irm https://raw.githubusercontent.com/ldangelo/foreman/main/install.ps1 | iex +``` + +### Verify installation + +```bash +foreman --version +foreman doctor # Check dependencies (br, API key, etc.) +``` + +> **Also required:** [beads_rust](https://github.com/Dicklesworthstone/beads_rust) (`br`) for task tracking: +> `cargo install beads_rust` or download the binary to `~/.local/bin/br` + +## Quick Start -# 2. Initialize in your project +```bash +# 1. Initialize in your project cd ~/your-project foreman init --name my-project -# 3. Create tasks (beads) +# 2. Create tasks (beads) br create --title "Add user auth" --description "Implement JWT-based auth" --type feature --priority 1 br create --title "Write auth tests" --type task --priority 2 -# 4. Dispatch agents to ready tasks +# 3. Dispatch agents to ready tasks foreman run -# 5. Monitor progress +# 4. Monitor progress foreman status -# 6. Merge completed branches (runs automatically in foreman run loop) +# 5. Merge completed branches (runs automatically in foreman run loop) foreman merge ``` @@ -630,67 +662,29 @@ git push origin v1.0.0 Or trigger manually from the Actions tab with optional dry-run mode. -### Installation from Binary Release - -#### Homebrew (macOS / Linux — recommended) - -```bash -brew tap oftheangels/tap -brew install foreman -``` - -After installation, run `brew info foreman` to see post-install setup instructions, or run `foreman doctor` to verify your configuration. - -#### Quick install script (macOS / Linux) - -```bash -curl -fsSL https://raw.githubusercontent.com/ldangelo/foreman/main/install.sh | sh -``` - -The installer automatically: -- Detects your OS (macOS/Linux) and architecture (arm64/x86_64) -- Downloads the correct binary from the [latest GitHub Release](https://github.com/ldangelo/foreman/releases/latest) -- Installs to `/usr/local/bin/foreman` (with sudo) or `~/.local/bin/foreman` (without) -- Places `better_sqlite3.node` alongside the binary (required side-car) -- Verifies the install with `foreman --version` +### Advanced Installation Options -**Options:** +For additional install options (specific versions, custom directories, manual binary download), see the [CLI Reference](docs/cli-reference.md) and [Troubleshooting Guide](docs/troubleshooting.md). -```bash -# Install a specific version -FOREMAN_VERSION=v1.2.3 curl -fsSL https://raw.githubusercontent.com/ldangelo/foreman/main/install.sh | sh - -# Install to a custom directory -FOREMAN_INSTALL=/opt/bin curl -fsSL https://raw.githubusercontent.com/ldangelo/foreman/main/install.sh | sh - -# Avoid GitHub API rate limiting (60 req/hr unauthenticated) -GITHUB_TOKEN=ghp_yourtoken curl -fsSL https://raw.githubusercontent.com/ldangelo/foreman/main/install.sh | sh -``` +## Development -**Manual installation:** +If you want to contribute or build from source: ```bash -# macOS / Linux — download the archive for your platform -TAG=v1.0.0 -PLATFORM=$(uname -s | tr A-Z a-z) # darwin or linux -ARCH=$(uname -m | sed 's/x86_64/x64/;s/aarch64/arm64/') # x64 or arm64 -curl -fsSL "https://github.com/ldangelo/foreman/releases/download/${TAG}/foreman-${TAG}-${PLATFORM}-${ARCH}.tar.gz" | tar xz - -# Both the binary and better_sqlite3.node must reside in the same directory -chmod +x foreman-${PLATFORM}-${ARCH} -sudo cp better_sqlite3.node /usr/local/bin/ -sudo mv foreman-${PLATFORM}-${ARCH} /usr/local/bin/foreman -``` - -> **Windows:** Use `install.ps1` (see [bd-8ovc](https://github.com/ldangelo/foreman/issues)). +# Clone and build +git clone https://github.com/ldangelo/foreman +cd foreman +npm install && npm run build -## Development +# Link for local development +npm link -```bash -npm run build # TypeScript compile -npm test # vitest run (128 test files) +# Development commands +npm run build # TypeScript compile (atomic — safe while foreman is running) +npm test # vitest run (159 test files, ~2800 tests) npm run dev # tsx watch mode npx tsc --noEmit # Type check only +npm run bundle # esbuild single-file bundle ``` **Rules:** From e9ac931f67662b9b79e692163ac5eed659aa2d06 Mon Sep 17 00:00:00 2001 From: "Leo A. D'Angelo" Date: Wed, 25 Mar 2026 14:27:38 -0500 Subject: [PATCH 2/2] chore: sync beads JSONL --- .beads/issues.jsonl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index d1f33f48..31a127d9 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -289,7 +289,7 @@ {"id":"bd-krew","title":"doctor: zombie run detection is broken for SDK-based agent workers","description":"In src/orchestrator/doctor.ts, extractPid() uses regex /pid-(\\d+)/ to extract a PID from the session_key. However, SDK-based agent workers use session_key format 'foreman:sdk::' which contains no PID. extractPid() returns null for all SDK runs, so isProcessAlive() is called with null which makes isAlive=false, causing ALL SDK-based running runs to be reported as zombies — even when live agent-worker.ts processes are actively running them. The fix must detect liveness differently for SDK runners, e.g. by checking for a running agent-worker.ts process whose worker JSON file contains the run ID, or by storing the actual PID in a separate column.","status":"closed","priority":0,"issue_type":"bug","created_at":"2026-03-18T03:58:33.651572Z","created_by":"ldangelo","updated_at":"2026-03-20T04:42:32.293139Z","closed_at":"2026-03-20T04:42:32.291436Z","close_reason":"Completed via pipeline","source_repo":".","compaction_level":0,"original_size":0} {"id":"bd-krv","title":"[trd:seeds-to-br-bv-migration:task:TRD-012-TEST] Unit tests for dispatcher prompt content","description":"## Test Task: TRD-012-TEST\nTRD Reference: docs/TRD/seeds-to-br-bv-migration.md#trd-012-test\nPRD Reference: docs/PRD/PRD-2026-001-seeds-to-br-bv-migration.md#req-016\nVerifies: TRD-012\nSatisfies: REQ-016\nTarget Files: src/orchestrator/__tests__/dispatcher.test.ts\nActions:\n1. Test spawnAgent prompt contains \"br close\" when backend=br\n2. Test resumeAgent prompt contains \"br close\" when backend=br\n3. Test no \"sd close\" in prompts when backend=br\nDependencies: TRD-012","status":"closed","priority":2,"issue_type":"task","created_at":"2026-03-16T13:23:25.285445Z","created_by":"ldangelo","updated_at":"2026-03-16T17:11:15.750338Z","closed_at":"2026-03-16T17:11:15.750015Z","close_reason":"Tests implemented and passing — 12 tests in dispatcher-prompts.test.ts","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-krv","depends_on_id":"bd-18m","type":"blocks","created_at":"2026-03-16T13:23:25.564508Z","created_by":"ldangelo","metadata":"{}","thread_id":""}]} {"id":"bd-ksbk","title":"doctor: checkFailedStuckRuns has no --fix path; 155 failed runs accumulate indefinitely","description":"checkFailedStuckRuns() in doctor.ts:496 only warns about failed/stuck runs but has no fix logic — it takes no opts parameter and never cleans anything up. Running 'foreman doctor --fix' leaves the warning unchanged.\n\nAfter the bd-qtqs retry loop bug (bd-zwtr), 155 failed runs accumulated in the DB. doctor --fix cannot remove them. They persist indefinitely and noise the doctor output.\n\nTwo fixes needed:\n1. Add fix option to checkFailedStuckRuns() to purge/archive failed runs older than N days (e.g. 7 days) for seeds that are now closed or have a successful later run.\n2. Or: filter getRunsByStatus('failed') to exclude runs where the seed has a subsequent 'completed' or 'merged' run — these are historical retries, not actionable failures.\n\nThe check should also distinguish between:\n- Seeds with ONLY failed runs (actionable — needs attention)\n- Seeds with failed runs BUT ALSO a later completed/merged run (noise — historical retries)","notes":"[FAILED] [DEVELOPER] ","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-03-19T15:27:26.999025Z","created_by":"ldangelo","updated_at":"2026-03-23T20:12:01.296252Z","closed_at":"2026-03-23T20:12:01.295511Z","close_reason":"done","source_repo":".","compaction_level":0,"original_size":0} -{"id":"bd-kx19","title":"Test: Verify release workflow with dry-run","description":"Run the release workflow in dry-run mode. Verify version detection from commit history. Verify npm pack produces correct package. Verify binary build matrix produces all 5 targets. Test on a non-main branch first.","notes":"Post-merge tests failed (attempt 2/3). Will retry after the developer addresses the failures. \nFirst failure:\n\n> @oftheangels/foreman@0.1.0 test\n> vitest run\n\n\n\u001b[1m\u001b[46m RUN \u001b[49m\u001b[22m \u001b[36mv4.0.18 \u001b[39m\u001b[90m/Users/ldangelo/Development/Fortium/foreman\u001b[39m\n\n \u001b[31m❯\u001b[39m src/orchestrator/__tests__/task-backend-ops.test.ts \u001b[2m(\u001b[22m\u001b[2m48 tests\u001b[22m\u001b[2m | \u001b[22m\u001b[31m1 failed\u001b[39m\u001b[2m)\u001b[22m\u001b[32m 14\u001b[2mms\u001b[22m\u001b[39m\n \u001b[32m✓\u001b[39m calls br close --no-db --force with seedId (beads_rust#204 workaround)\u001b[32m 2\u001b[2mms\u001b[22m\u001b[39m\n \u001b[32m✓\u001b[39m uses ~/.local/bin/br path for br backend\u001b[32m 0\u001b[2mms\u001b[22m\u001b[39m\n ","status":"blocked","priority":2,"issue_type":"task","created_at":"2026-03-24T02:29:32.471349Z","created_by":"ldangelo","updated_at":"2026-03-25T12:34:30.617502Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["phase:developer","phase:finalize","phase:qa","phase:reviewer"],"dependencies":[{"issue_id":"bd-kx19","depends_on_id":"bd-i3c9","type":"blocks","created_at":"2026-03-24T02:29:50.791655Z","created_by":"ldangelo","metadata":"{}","thread_id":""}]} +{"id":"bd-kx19","title":"Test: Verify release workflow with dry-run","description":"Run the release workflow in dry-run mode. Verify version detection from commit history. Verify npm pack produces correct package. Verify binary build matrix produces all 5 targets. Test on a non-main branch first.","notes":"Post-merge tests failed (attempt 2/3). Will retry after the developer addresses the failures. \nFirst failure:\n\n> @oftheangels/foreman@0.1.0 test\n> vitest run\n\n\n\u001b[1m\u001b[46m RUN \u001b[49m\u001b[22m \u001b[36mv4.0.18 \u001b[39m\u001b[90m/Users/ldangelo/Development/Fortium/foreman\u001b[39m\n\n \u001b[31m❯\u001b[39m src/orchestrator/__tests__/task-backend-ops.test.ts \u001b[2m(\u001b[22m\u001b[2m48 tests\u001b[22m\u001b[2m | \u001b[22m\u001b[31m1 failed\u001b[39m\u001b[2m)\u001b[22m\u001b[32m 14\u001b[2mms\u001b[22m\u001b[39m\n \u001b[32m✓\u001b[39m calls br close --no-db --force with seedId (beads_rust#204 workaround)\u001b[32m 2\u001b[2mms\u001b[22m\u001b[39m\n \u001b[32m✓\u001b[39m uses ~/.local/bin/br path for br backend\u001b[32m 0\u001b[2mms\u001b[22m\u001b[39m\n ","status":"closed","priority":2,"issue_type":"task","created_at":"2026-03-24T02:29:32.471349Z","created_by":"ldangelo","updated_at":"2026-03-25T13:33:32.258273Z","closed_at":"2026-03-25T13:33:32.257815Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["phase:developer","phase:explorer","phase:finalize","phase:qa","phase:reviewer"]} {"id":"bd-l0w","title":"Rename 'seed' terminology to 'bead' throughout codebase","description":"The codebase inconsistently uses 'seed' and 'bead' to refer to the same concept (a br/beads task ID). The user-facing CLI uses --seed flags and 'seed_id' internally, but the underlying task tracker is called 'beads' (br). This creates confusing UX and inconsistent naming.\n\n## Scope of Changes\n\n### CLI flags\n- foreman run --seed → foreman run --bead \n- foreman merge --seed → foreman merge --bead \n- foreman reset --seed → foreman reset --bead \n- foreman status --seed → foreman status --bead \n- Any other --seed flags in CLI commands\n\n### Internal naming (TypeScript)\n- seed_id column references in SQLite queries → bead_id (or rename column via migration)\n- Run.seed_id field → Run.bead_id\n- opts.seed → opts.bead\n- seedId variables → beadId\n- getRunsByStatus / getRunsBySeed → update param names\n- MergeQueueEntry.seed_id → bead_id\n- mergeCompleted({ seedId }) → mergeCompleted({ beadId })\n- getCompletedRuns(projectId, seedId) → getCompletedRuns(projectId, beadId)\n- resetForRetry(seedId) → resetForRetry(beadId)\n- All other internal seed_id / seedId references\n\n### Worker config / agent-worker\n- WorkerConfig.seed_id → WorkerConfig.bead_id\n- All references in dispatcher.ts, agent-worker.ts, monitor.ts\n\n### Store schema migration\n- Add SQLite migration: ALTER TABLE runs RENAME COLUMN seed_id TO bead_id\n- Add SQLite migration: ALTER TABLE merge_queue RENAME COLUMN seed_id TO bead_id\n- Ensure migration runs on first open of existing databases\n\n### Tests\n- Update all test fixtures, mocks, and assertions that reference seed_id / seedId / opts.seed\n\n### Backwards compatibility\n- Accept --seed as a deprecated alias for --bead with a deprecation warning during a transition period\n\n## Acceptance Criteria\n- foreman run --bead dispatches the correct task\n- foreman merge --bead merges the correct branch\n- Internal code uses beadId/bead_id consistently\n- All existing tests pass with updated naming\n- --seed still works but prints deprecation warning","status":"closed","priority":2,"issue_type":"chore","created_at":"2026-03-17T18:01:59.244732Z","created_by":"ldangelo","updated_at":"2026-03-17T18:35:07.961623Z","closed_at":"2026-03-17T18:35:07.961252Z","close_reason":"Completed via pipeline","source_repo":".","compaction_level":0,"original_size":0} {"id":"bd-l5r9","title":"[trd:trd-2026-002-pi-agent-mail-rpc-migration:task:TRD-017] Pi Extension Health Check","description":"TRD Reference: docs/TRD/TRD-2026-002-pi-agent-mail-rpc-migration.md#trd-017\\nSatisfies: REQ-018\\nValidates PRD ACs: AC-018-3\\nTarget File: src/orchestrator/pi-rpc-spawn-strategy.ts\\nActions:\\n1. Send health check RPC command after Pi session initialized\\n2. Verify foreman-tool-gate is in loaded extension list\\n3. Refuse to start pipeline and log actionable error if not loaded\\nDependencies: TRD-012\\nEst: 2h","status":"closed","priority":3,"issue_type":"task","created_at":"2026-03-19T23:52:37.310074Z","created_by":"ldangelo","updated_at":"2026-03-20T02:34:59.172087Z","closed_at":"2026-03-20T02:34:59.171628Z","close_reason":"done","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-l5r9","depends_on_id":"bd-kkw0","type":"blocks","created_at":"2026-03-19T23:53:44.352120Z","created_by":"ldangelo","metadata":"{}","thread_id":""}]} {"id":"bd-l72","title":"Move bead lifecycle ownership to agent-worker — eliminate dispatcher/worker split","description":"Currently bead status management is split: dispatcher.ts marks in_progress at line 186, agent-worker.ts finalizes via br close, and reset.ts resets to open. This causes race conditions (bd-ng9) and missing updates (bd-7wa). Consolidate: 1) Remove seeds.update(in_progress) from dispatcher.ts — instead pass seeds/br client config to agent-worker via WorkerConfig, 2) agent-worker marks in_progress when starting (before explorer phase), 3) agent-worker resets to open on failure/stuck (currently it only updates SQLite), 4) agent-worker calls br close on success (already does this in finalize). This makes agent-worker the single owner of bead lifecycle, eliminating the race condition.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-03-17T21:31:18.293001Z","created_by":"ldangelo","updated_at":"2026-03-20T04:42:47.980916Z","closed_at":"2026-03-20T04:42:47.979525Z","close_reason":"Completed via pipeline","source_repo":".","compaction_level":0,"original_size":0}