Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .beads/issues.jsonl
Original file line number Diff line number Diff line change
Expand Up @@ -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:<model>:<uuid>' 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 <id> → foreman run --bead <id>\n- foreman merge --seed <id> → foreman merge --bead <id>\n- foreman reset --seed <id> → foreman reset --bead <id>\n- foreman status --seed <id> → foreman status --bead <id>\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 <id> dispatches the correct task\n- foreman merge --bead <id> 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}
Expand Down
118 changes: 56 additions & 62 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```

Expand Down Expand Up @@ -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:**
Expand Down
Loading