feat: launch execution in tmux, orchestrator monitors progress

This commit is contained in:
2026-03-27 11:48:15 -04:00
parent f867630639
commit a2b4369035
3 changed files with 56 additions and 133 deletions

View File

@@ -10,7 +10,7 @@
"name": "agent-loop", "name": "agent-loop",
"source": "./", "source": "./",
"description": "Autonomous generator-evaluator agent loop for long-running coding tasks. Plan interactively, then execute with full visibility.", "description": "Autonomous generator-evaluator agent loop for long-running coding tasks. Plan interactively, then execute with full visibility.",
"version": "0.7.0", "version": "0.8.0",
"author": { "author": {
"name": "Sheldon" "name": "Sheldon"
}, },

View File

@@ -1,6 +1,6 @@
{ {
"name": "agent-loop", "name": "agent-loop",
"version": "0.7.0", "version": "0.8.0",
"description": "Autonomous generator-evaluator agent loop for long-running coding tasks. Plan with /agent-loop:init, then execute with /agent-loop:run.", "description": "Autonomous generator-evaluator agent loop for long-running coding tasks. Plan with /agent-loop:init, then execute with /agent-loop:run.",
"author": { "author": {
"name": "Sheldon" "name": "Sheldon"

View File

@@ -1,19 +1,17 @@
--- ---
name: run 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." description: "Agent Loop — single entry point. Scaffolds .loop/ if missing, generates stories if no prd.json, then launches autonomous execution in tmux."
--- ---
# /run — Agent Loop # /run — Agent Loop
Single entry point for the agent loop. Handles setup, planning, and execution automatically based on what's already done. Single entry point for the agent loop. Handles setup and planning interactively, then launches autonomous execution in a tmux session.
## Usage ## Usage
``` ```
/agent-loop:run # Full flow: setup → stories → loop /agent-loop:run # Full flow: setup → stories → launch
/agent-loop:run 3 # Limit to 3 loop iterations
/agent-loop:run --skip-eval # Skip evaluator pass /agent-loop:run --skip-eval # Skip evaluator pass
/agent-loop:run --story US-003 # Run only a specific story
``` ```
## Instructions ## Instructions
@@ -88,151 +86,76 @@ Agent(
--- ---
## Phase 3: Validate ## Phase 3: Validate and Launch
1. Read `.loop/prd.json` and verify: 1. Read `.loop/prd.json` and verify:
- Has a `userStories` array (NOT `sprints`, `stories`, or `tasks`) - Has a `userStories` array (NOT `sprints`, `stories`, or `tasks`)
- Each story has: `id`, `title`, `passes`, `priority` - Each story has: `id`, `title`, `passes`, `priority`
- If invalid, show the error and stop. - If invalid, show the error and stop.
2. Read `.loop/config.json` for `mode`, `maxIterations`, `evalRetries`, `scopeBudgets`. 2. Read `.loop/config.json` for `mode`, `maxIterations`.
3. Find prompts. Check these paths (first match wins): 3. Verify `.loop/loop.sh` exists and is executable.
- `.loop/prompts/` (local)
- `~/.claude/plugins/cache/agent-loop/agent-loop/*/prompts/` (plugin cache)
If no prompts found, stop with error. 4. Parse arguments for any flags to pass through (e.g., `--skip-eval`).
4. Parse arguments: number → max iterations, `--skip-eval`, `--story <ID>` 5. Build the loop.sh command with any flags:
--- ```bash
LOOP_CMD=".loop/loop.sh"
# Add --skip-eval if requested
# Add --max N if specified
```
## Phase 4: Execute Loop 6. Launch in tmux:
Report: ```bash
tmux new-session -d -s agent-loop -c <project_root> "$LOOP_CMD"
```
> **Loop Ready** 7. Report to the user:
> **Loop launched in tmux session `agent-loop`**
> - Stories: {total} to complete
> - Mode: {mode} > - Mode: {mode}
> - Stories: {passed}/{total} complete
> - Max iterations: {N}
> - Eval: {on/off}
> >
> Starting. Interrupt me at any time. > **Monitor:**
> - Watch live: `tmux attach -t agent-loop`
For each iteration (1 to max iterations): > - Check progress: read `.loop/progress.md`
> - Check status: read `.loop/prd.json`
### 4a. Find Next Story > - Stop the loop: `tmux kill-session -t agent-loop`
>
Find the story with the lowest `priority` where `passes` is `false` and `blocked` is not `true`. If `--story` was specified, use that story. > I can also check on progress for you — just ask "how's it going?"
**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 ## Monitoring
> **Loop Complete** If the user asks about progress (e.g., "status", "how's it going", "check progress"):
> - Iterations: {N}
1. Read `.loop/prd.json` — count passed/failed/blocked stories
2. Read `.loop/progress.md` — show the latest session log entries
3. Capture recent tmux output:
```bash
tmux capture-pane -t agent-loop -p | tail -30
```
4. Report:
> **Loop Status**
> - Stories: {passed}/{total} complete, {blocked} blocked > - Stories: {passed}/{total} complete, {blocked} blocked
> - Current: {last story from progress.md}
> - tmux session: {running/stopped}
## Error Handling ---
- Agent fails or empty output → warn and continue ## When Loop Completes
- prd.json unparseable → stop
- User says "stop" → end loop, report status The tmux session exits when `loop.sh` finishes. If the user asks for a summary:
1. Read `.loop/prd.json` for final story statuses
2. Read `.loop/progress.md` for the full session log
3. Check git log for commits made during the run
Report the final status and suggest `/agent-loop:triage` if any stories are blocked.