Files
loop-loop/skills/run/SKILL.md

239 lines
6.0 KiB
Markdown

---
name: run
description: "Agent Loop — single entry point. Scaffolds .loop/ if missing, generates stories if no prd.json, then runs the generator-evaluator loop with full visibility."
---
# /run — Agent Loop
Single entry point for the agent loop. Handles setup, planning, and execution automatically based on what's already done.
## Usage
```
/agent-loop:run # Full flow: setup → stories → loop
/agent-loop:run 3 # Limit to 3 loop iterations
/agent-loop:run --skip-eval # Skip evaluator pass
/agent-loop:run --story US-003 # Run only a specific story
```
## Instructions
Follow this sequence. Each phase checks what exists and skips if already done.
---
## Phase 1: Scaffold (if needed)
Check if `.loop/config.json` exists.
**If it does NOT exist**, run the setup script:
Ask the user: **Mode?** (a) Implement (b) Explore (c) Fix — default is Implement.
Then run:
```bash
bash "$(ls -d ~/.claude/plugins/cache/agent-loop/agent-loop/*/setup.sh 2>/dev/null | head -1)" <mode>
```
Show the output. If setup fails, stop.
**If it already exists**, skip to Phase 2.
---
## Phase 2: Generate Stories (if needed)
Check if `.loop/prd.json` exists.
**If it does NOT exist**, generate it:
1. Search for existing specs:
- `docs/superpowers/specs/*.md`
- `docs/specs/*.md`
- `SPEC.md`, `PRD.md`, `DESIGN.md` at project root
If found: "I found a spec at `{path}`. Using it to generate stories."
If not found: ask "What do you want to build? 1-3 sentences."
2. Read the project root and tech stack info.
3. Dispatch the **agent-loop:planner** agent:
```
Agent(
subagent_type: "agent-loop:planner",
prompt: "Generate prd.json and sprint contracts.\n\nMode: {mode}\nProject root: {path}\n\nSpec:\n{spec content}\n\nTech stack: {detected stack}",
description: "Planning: generate stories"
)
```
4. After the planner finishes, read `.loop/prd.json` and present:
> **Stories generated — Review before running**
>
> 1. US-001: {title}
> 2. US-002: {title}
> ...
>
> **Review:**
> - `.loop/prd.json` — stories and acceptance criteria
> - `.loop/contracts/` — done conditions per story
>
> Let me know if you want changes, or say **go** to start the loop.
5. **STOP and wait for the user.** Do NOT start the loop automatically. The user must say "go", "start", "run", "looks good", or similar before proceeding to Phase 3.
**If `prd.json` already exists**, skip to Phase 3.
---
## Phase 3: Validate
1. Read `.loop/prd.json` and verify:
- Has a `userStories` array (NOT `sprints`, `stories`, or `tasks`)
- Each story has: `id`, `title`, `passes`, `priority`
- If invalid, show the error and stop.
2. Read `.loop/config.json` for `mode`, `maxIterations`, `evalRetries`, `scopeBudgets`.
3. Find prompts. Check these paths (first match wins):
- `.loop/prompts/` (local)
- `~/.claude/plugins/cache/agent-loop/agent-loop/*/prompts/` (plugin cache)
If no prompts found, stop with error.
4. Parse arguments: number → max iterations, `--skip-eval`, `--story <ID>`
---
## Phase 4: Execute Loop
Report:
> **Loop Ready**
> - Mode: {mode}
> - Stories: {passed}/{total} complete
> - Max iterations: {N}
> - Eval: {on/off}
>
> Starting. Interrupt me at any time.
For each iteration (1 to max iterations):
### 4a. Find Next Story
Find the story with the lowest `priority` where `passes` is `false` and `blocked` is not `true`. If `--story` was specified, use that story.
**If no actionable story remains:**
- All `passes: true` → report success and stop
- Some `blocked: true` → report which ones
- Stop
### 4b. Report Iteration Start
> **Iteration {N}/{max} — {story.id}: {story.title}**
If the story has `[REJECTED]` in `notes`, summarize the feedback.
### 4c. Assemble Generator Prompt
Read and concatenate with `---` separator:
1. `{prompt_path}/generator/_base.md`
2. `{prompt_path}/generator/{mode}.md`
Substitute variables:
- `{{MAX_FILES_TO_READ}}` → from config scopeBudgets
- `{{MAX_LINES_TO_WRITE}}` → from config scopeBudgets
- `{{MAX_FILES_TO_MODIFY}}` → from config scopeBudgets
- `{{MODE}}` → mode
- `{{ITERATION}}` → current iteration
- `{{MAX_ITERATIONS}}` → max iterations
- `{{LOOP_DIR}}` → absolute path to `.loop/`
- `{{PROJECT_ROOT}}` → project root
- `{{CURRENT_STORY_ID}}` → story ID
### 4d. Capture Pre-Generator Git State
Run `git rev-parse HEAD` and save the SHA.
### 4e. Dispatch Generator Agent
```
Agent(
prompt: <assembled generator prompt>,
description: "Generator: {story.id}",
subagent_type: "general-purpose",
mode: "bypassPermissions"
)
```
### 4f. Check Completion Signal
If output contains `<promise>COMPLETE</promise>`, report done and stop.
### 4g. Evaluator (unless skipped)
If `--skip-eval` or `config.skipEval` is true, skip to 4h and treat as PASS.
Otherwise, read and concatenate:
1. `{prompt_path}/evaluator/_base.md`
2. `{prompt_path}/evaluator/{mode}.md`
Substitute same variables plus `{{PRE_GENERATOR_SHA}}` and `{{CURRENT_STORY_ID}}`.
```
Agent(
prompt: <assembled evaluator prompt>,
description: "Evaluator: {story.id}",
subagent_type: "general-purpose",
mode: "bypassPermissions"
)
```
Parse verdict:
- `<verdict>PASS</verdict>` → PASS
- `<verdict>REJECT</verdict>` → REJECT, extract reason
- No verdict → REJECT (fail-safe)
### 4h. Update State
**PASS:** Set `passes: true` in prd.json. Report: **{story.id} PASSED**
**REJECT:** Increment `rejections`, append `[REJECTED] {reason}` to `notes`. Report: **{story.id} REJECTED** — {reason}
If `rejections >= evalRetries`: set `blocked: true`. Report: **{story.id} BLOCKED**
### 4i. Append Progress
Append to `.loop/progress.md`:
```markdown
### {story.id} — {story.title}
Date: {date}
Iteration: {N}
Verdict: {verdict}
---
```
### 4j. Continue
Show: `{passed}/{total} stories complete`
Continue to next iteration.
---
## Loop Exit
> **Loop Complete**
> - Iterations: {N}
> - Stories: {passed}/{total} complete, {blocked} blocked
## Error Handling
- Agent fails or empty output → warn and continue
- prd.json unparseable → stop
- User says "stop" → end loop, report status