6.9 KiB
name, description
| name | description |
|---|---|
| run | Execute the generator-evaluator loop interactively inside Claude Code. Dispatches subagents with full visibility and intervention capability. Run /agent-loop:init and /agent-loop:plan first. |
/run — Execute Agent Loop Inside Claude Code
Run the generator-evaluator loop natively in Claude Code using subagents. Unlike loop.sh (headless), this gives you full visibility into each agent's work and the ability to intervene at any point.
Usage
/agent-loop:run # Run until all stories pass or max iterations
/agent-loop:run 3 # Run at most 3 iterations
/agent-loop:run --skip-eval # Skip evaluator (generator marks stories done)
/agent-loop:run --story US-003 # Run only a specific story
Prerequisites
.loop/config.jsonexists (run/agent-loop:initfirst).loop/prd.jsonexists with stories (run/agent-loop:planfirst)
Instructions
When the user invokes /loop-run, follow this orchestration sequence exactly.
Step 0: Parse Arguments
- If a number is provided, use it as max iterations. Otherwise read
maxIterationsfrom.loop/config.json. - If
--skip-evalis provided, skip the evaluator pass. - If
--story <ID>is provided, only work on that specific story.
Step 1: Load State
- Read
.loop/config.json— getmode,maxIterations,evalRetries,scopeBudgets - Read
.loop/prd.json— get the story list and their statuses - Check
.loop/progress.mdexists; if not, create it from.loop/templates/progress.md.template
Report to the user:
Loop Ready
- Mode: {mode}
- Stories: {passed}/{total} complete
- Max iterations: {N}
- Eval: {on/off}
Starting loop. You can interrupt me at any time to adjust course.
Step 2: Iteration Loop
For each iteration (1 to max iterations):
2a. Find Next Story
Find the highest-priority story in prd.json where passes is false and blocked is not true. If --story was specified, use that story instead.
If no actionable story remains:
- If all stories have
passes: true→ report success and stop - If some stories are
blocked: true→ report which are blocked and suggest/agent-loop:triage - Stop the loop
2b. Report Iteration Start
Tell the user:
Iteration {N}/{max} — {story.id}: {story.title}
If the story has [REJECTED] entries in its notes field, summarize the previous feedback so the user has context.
2c. Assemble Generator Prompt
Read these files and concatenate them with --- separators:
.loop/prompts/generator/_base.md.loop/prompts/generator/{mode}.md
Then substitute these template variables in the assembled text:
{{MAX_FILES_TO_READ}}→ fromconfig.scopeBudgets.{mode}.maxFilesToRead{{MAX_LINES_TO_WRITE}}→ fromconfig.scopeBudgets.{mode}.maxLinesToWrite{{MAX_FILES_TO_MODIFY}}→ fromconfig.scopeBudgets.{mode}.maxFilesToModify{{MODE}}→ the mode{{ITERATION}}→ current iteration number{{MAX_ITERATIONS}}→ max iterations{{LOOP_DIR}}→ path to.loop/directory{{PROJECT_ROOT}}→ project root path{{CURRENT_STORY_ID}}→ the story ID being worked on
2d. Capture Pre-Generator Git State
Run git rev-parse HEAD and save it. This is needed for the evaluator's diff.
2e. Dispatch Generator Agent
Use the Agent tool to launch the generator:
Agent(
prompt: <assembled generator prompt>,
description: "Generator: {story.id}",
subagent_type: "general-purpose",
mode: "auto"
)
IMPORTANT: Use mode: "auto" so the user can see tool calls but isn't prompted for every action. If the user has expressed a preference for more control, use mode: "default" instead.
Wait for the agent to complete. The Agent tool returns the generator's final output.
2f. Check for Completion Signal
If the generator output contains <promise>COMPLETE</promise>, report all stories complete and stop.
2g. Skip Evaluator (if configured)
If --skip-eval was specified or config.skipEval is true, skip to step 2j.
2h. Assemble Evaluator Prompt
Read these files and concatenate them:
.loop/prompts/evaluator/_base.md.loop/prompts/evaluator/{mode}.md
Substitute the same template variables as the generator, plus:
{{PRE_GENERATOR_SHA}}→ the git SHA captured in step 2d{{CURRENT_STORY_ID}}→ the story ID
2i. Dispatch Evaluator Agent
Use the Agent tool to launch the evaluator:
Agent(
prompt: <assembled evaluator prompt>,
description: "Evaluator: {story.id}",
subagent_type: "general-purpose",
mode: "auto"
)
Wait for completion. Parse the verdict from the output:
- Look for
<verdict>PASS</verdict>→ story passes - Look for
<verdict>REJECT</verdict>→ story rejected; extract reason from<rejection_reason>...</rejection_reason> - No verdict tag found → treat as REJECT (fail-safe)
2j. Update State Based on Verdict
On PASS (or skip-eval):
- Update
.loop/prd.json— setpasses: truefor the story - Report to user: ✓ {story.id} PASSED
On REJECT:
- Update
.loop/prd.json:- Keep
passes: false - Increment
rejectionscount - Append
[REJECTED] {reason}tonotes
- Keep
- Report to user: ✗ {story.id} REJECTED — {reason}
- Check if
rejections>=evalRetriesfrom config:- If yes: set
blocked: truein prd.json, append[BLOCKED]to notes - Report: ⚠ {story.id} BLOCKED — rejected {N} times, needs human review
- If yes: set
2k. Append Progress Entry
Append to .loop/progress.md:
### {story.id} — {story.title}
Date: {current date and time}
Iteration: {N}
Verdict: {PASS/REJECT/SKIP-EVAL}
---
2l. Report Iteration Summary
Show current story counts: {passed}/{total} stories complete
If there are more iterations and more stories, continue to the next iteration.
Step 3: Loop Exit
When the loop ends (all stories done, max iterations, or all remaining blocked), report:
Loop Complete
- Iterations used: {N}
- Stories: {passed}/{total} complete, {blocked} blocked
- {Suggest
/agent-loop:triageif anything is blocked or incomplete}
Error Handling
- If an Agent subagent fails or returns empty output, log a warning and continue to the next iteration. Do NOT stop the loop for a single agent failure.
- If
prd.jsoncannot be parsed, stop immediately and report the error. - If the user interrupts (denies a tool call, says "stop", etc.), gracefully end the loop and report current status.
Key Differences from loop.sh
| Feature | loop.sh | /loop-run |
|---|---|---|
| Execution | Headless (claude --print) |
Visible in Claude Code |
| Intervention | Kill the process | Deny tool calls, chat mid-loop |
| Permissions | --dangerously-skip-permissions |
User-controlled |
| Context | Fresh process per agent | Fresh Agent subagent per agent |
| State updates | Shell functions | Claude Code reads/writes files directly |