--- name: run description: 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.json` exists (run `/agent-loop:init` first) - `.loop/prd.json` exists with stories (run `/agent-loop:plan` first) ## 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 `maxIterations` from `.loop/config.json`. - If `--skip-eval` is provided, skip the evaluator pass. - If `--story ` is provided, only work on that specific story. ### Step 1: Load State 1. Read `.loop/config.json` — get `mode`, `maxIterations`, `evalRetries`, `scopeBudgets` 2. Read `.loop/prd.json` — get the story list and their statuses 3. Check `.loop/progress.md` exists; 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: 1. `.loop/prompts/generator/_base.md` 2. `.loop/prompts/generator/{mode}.md` Then substitute these template variables in the assembled text: - `{{MAX_FILES_TO_READ}}` → from `config.scopeBudgets.{mode}.maxFilesToRead` - `{{MAX_LINES_TO_WRITE}}` → from `config.scopeBudgets.{mode}.maxLinesToWrite` - `{{MAX_FILES_TO_MODIFY}}` → from `config.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: , 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 `COMPLETE`, 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: 1. `.loop/prompts/evaluator/_base.md` 2. `.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: , description: "Evaluator: {story.id}", subagent_type: "general-purpose", mode: "auto" ) ``` Wait for completion. Parse the verdict from the output: - Look for `PASS` → story passes - Look for `REJECT` → story rejected; extract reason from `...` - No verdict tag found → treat as REJECT (fail-safe) #### 2j. Update State Based on Verdict **On PASS (or skip-eval):** 1. Update `.loop/prd.json` — set `passes: true` for the story 2. Report to user: ✓ **{story.id} PASSED** **On REJECT:** 1. Update `.loop/prd.json`: - Keep `passes: false` - Increment `rejections` count - Append `[REJECTED] {reason}` to `notes` 2. Report to user: ✗ **{story.id} REJECTED** — {reason} 3. Check if `rejections` >= `evalRetries` from config: - If yes: set `blocked: true` in prd.json, append `[BLOCKED]` to notes - Report: ⚠ **{story.id} BLOCKED** — rejected {N} times, needs human review #### 2k. Append Progress Entry Append to `.loop/progress.md`: ```markdown ### {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:triage` if 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.json` cannot 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 |