agent-loop

📁 joelhooks/joelclaw 📅 1 day ago
4
总安装量
2
周安装量
#49490
全站排名
安装命令
npx skills add https://github.com/joelhooks/joelclaw --skill agent-loop

Agent 安装分布

opencode 2
gemini-cli 2
codebuddy 2
github-copilot 2
codex 2
kimi-cli 2

Skill 文档

Agent Loop

Run durable PLANNER→IMPLEMENTOR→REVIEWER→JUDGE coding loops via Inngest. Each story in a PRD gets independently implemented, tested, and judged. Survives crashes. Every step is a traceable Inngest run.

After starting a loop, use the loop-nanny skill for monitoring, triage, post-loop cleanup, and knowing when to intervene.

Quick Start

# Start a loop
joelclaw loop start --project /path/to/project --prd prd.json --max-retries 2

# Check status
joelclaw loop status [LOOP_ID]

# Cancel
joelclaw loop cancel LOOP_ID

The joelclaw CLI is the primary interface (igs is a legacy alias). Run with bun run src/cli.ts loop start ... from the joelclaw package.

PRD Format

Create a prd.json in the project root:

{
  "title": "Feature Name",
  "description": "What we're building",
  "stories": [
    {
      "id": "S1",
      "title": "Short title",
      "description": "What to implement. Be specific about files, patterns, behavior.",
      "acceptance_criteria": [
        "Criterion 1 — must be verifiable by automated test",
        "Criterion 2 — must be checkable by typecheck/lint"
      ],
      "priority": 1,
      "passes": false
    }
  ]
}

Story writing tips:

  • Acceptance criteria must be machine-verifiable (tests, typecheck, lint)
  • Lower priority number = runs first
  • Keep stories small and atomic — one concern per story
  • Include file paths in descriptions when possible
  • passes flips to true when JUDGE approves; skipped: true added on max retry exhaustion

Pipeline Flow

joelclaw loop start → agent/loop.start event
  → PLANNER reads prd.json, finds next unpassed story
    → IMPLEMENTOR spawns codex/claude/pi, commits changes
      → REVIEWER writes tests from acceptance criteria (independently — does NOT read implementation)
        → JUDGE: all green? → mark passed, next story
                 failing?   → retry with feedback (up to maxRetries)
                 exhausted? → skip, flag for human review, next story
  → All done → agent/loop.complete

progress.txt

Create a progress.txt in the project root with a ## Codebase Patterns section at the top. This is read by the implementor for project context and appended by the judge after each story. Defends against context loss across fresh agent instances.

## Codebase Patterns

- Runtime: Bun, not Node
- Tests: bun test
- Key files: src/index.ts, src/lib/...

## Progress

(stories will be appended here)

Infrastructure

  • Canonical source: ~/Code/joelhooks/joelclaw/packages/system-bus/ (monorepo)
  • Worker clone: ~/Code/system-bus-worker/ (deployed copy, auto-synced)
  • Inngest functions: agent-loop-plan, agent-loop-implement, agent-loop-review, agent-loop-judge, agent-loop-complete, agent-loop-retro
  • Inngest server: k8s StatefulSet at localhost:8288
  • Loop –project target: Always use ~/Code/joelhooks/joelclaw/packages/system-bus (the monorepo). complete.ts auto-syncs the worker clone after merge + restarts the worker. Never target the worker clone directly.
  • Restart worker: launchctl kickstart -k gui/$(id -u)/com.joel.system-bus-worker
  • Verify functions: joelclaw functions
  • View runs: joelclaw runs -c
  • Inspect a run: joelclaw run RUN_ID

Two-clone architecture

The worker runs from a separate clone (~/Code/system-bus-worker/) so that editing the monorepo mid-session doesn’t break the running worker. After a loop merges to monorepo, complete.ts auto-syncs:

  1. git pull --ff-only in worker clone (falls back to git reset --hard origin/main)
  2. bun install for new deps
  3. launchctl kickstart to restart worker

Never manually sync — complete.ts handles it. If you need to force-sync: cd ~/Code/system-bus-worker && git fetch origin && git reset --hard origin/main.

Event Schema

All events carry loopId for tracing. Key events:

Event Purpose
agent/loop.start Kick off loop (loopId, project, prdPath, maxRetries, maxIterations)
agent/loop.plan Planner re-entry (find next story)
agent/loop.implement Dispatch to implementor (storyId, tool, attempt, feedback?)
agent/loop.review Dispatch to reviewer (storyId, commitSha, attempt)
agent/loop.judge Dispatch to judge (testResults, feedback, attempt)
agent/loop.complete Loop finished (summary, counts)
agent/loop.cancel Stop the loop
agent/loop.story.pass Story passed
agent/loop.story.fail Story skipped after max retries

Tool Assignment

Default: codex for implementation, claude for review. Override per-story via toolAssignments in the start event:

{
  "toolAssignments": {
    "S1": { "implementor": "claude", "reviewer": "claude" },
    "S2": { "implementor": "codex", "reviewer": "pi" }
  }
}

Known Gotchas

  • Concurrency keys use CEL expressions (event.data.project), not {{ }} templates
  • loop is reserved in CEL — don’t use in concurrency key strings
  • codex exec --full-auto PROMPT (no -q flag)
  • Worker must be restarted after function code changes (launchctl kickstart)
  • Docker must be running for Inngest server (open -a OrbStack)
  • Large tool output uses claim-check pattern (written to /tmp/agent-loop/{loopId}/)

Logging

Every story attempt is logged via slog:

slog write --action "story-pass" --tool "agent-loop" --detail "Story title (ID) passed on attempt N" --reason "details"

Actions: story-pass, story-retry, story-skip, build-complete

Source Files

File Purpose
~/Code/joelhooks/joelclaw/packages/system-bus/src/inngest/client.ts Event type definitions
~/Code/joelhooks/joelclaw/packages/system-bus/src/inngest/functions/agent-loop/utils.ts PRD parsing, git, cancellation, claim-check
~/Code/joelhooks/joelclaw/packages/system-bus/src/inngest/functions/agent-loop/plan.ts PLANNER
~/Code/joelhooks/joelclaw/packages/system-bus/src/inngest/functions/agent-loop/implement.ts IMPLEMENTOR
~/Code/joelhooks/joelclaw/packages/system-bus/src/inngest/functions/agent-loop/review.ts REVIEWER
~/Code/joelhooks/joelclaw/packages/system-bus/src/inngest/functions/agent-loop/judge.ts JUDGE
~/Code/joelhooks/joelclaw/packages/system-bus/src/serve.ts Worker registration
~/Code/joelhooks/joelclaw/src/cli.ts joelclaw CLI (loop subcommands)