Files
loop-loop/skills/run/SKILL.md
Sheldon Finlay 344b179b4d feat: support parallel loops with per-project tmux session names
The tmux session name is now derived from the project directory name
(e.g., agent-loop-server, agent-loop-webapp). This allows running
multiple loops in parallel on different projects without collisions.

Previously hardcoded to "agent-loop", which meant launching a second
loop would kill the first project's tmux session.
2026-04-02 10:54:22 -04:00

238 lines
7.4 KiB
Markdown

---
name: run
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
Single entry point for the agent loop. Handles setup and planning interactively, then launches autonomous execution in a tmux session.
## Usage
```
/agent-loop:run # Full flow: setup → stories → launch
/agent-loop:run --skip-eval # Skip evaluator pass
```
## Instructions
Follow this sequence. Each phase checks what exists and skips if already done.
---
## Phase 1: Scaffold or Update Harness
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**, check if the harness files need updating. Compare the installed harness version against the plugin version:
```bash
INSTALLED=$(cat .loop/.harness-version 2>/dev/null || echo "unknown")
PLUGIN=$(jq -r '.version // empty' "$(ls -d ~/.claude/plugins/cache/agent-loop/agent-loop/*/.claude-plugin/plugin.json 2>/dev/null | tail -1)" 2>/dev/null || echo "unknown")
echo "installed=$INSTALLED plugin=$PLUGIN"
```
If the versions differ (or installed is "unknown"), update the harness files:
```bash
bash "$(ls -d ~/.claude/plugins/cache/agent-loop/agent-loop/*/setup.sh 2>/dev/null | tail -1)" --update
```
Tell the user: *"Updated harness files to v{version}."* Then continue to Phase 2.
If versions match, skip to Phase 2.
---
## Phase 2: Generate Stories (if needed)
Check if `.loop/prd.json` exists.
**If it exists**, check whether the previous run is complete. Run:
```bash
source .loop/lib/state.sh 2>/dev/null; LOOP_DIR=.loop all_stories_pass 2>/dev/null && echo "ALL_PASSED" || echo "IN_PROGRESS"
```
Also check if the feature branch from prd.json still exists:
```bash
jq -r '.branchName // empty' .loop/prd.json
```
If the result is `ALL_PASSED` **or** the branch no longer exists (deleted after merge), the previous run is done. Archive it and reset:
```bash
LOOP_DIR=.loop source .loop/lib/state.sh && source .loop/lib/archive.sh && archive_and_reset .loop
```
Tell the user: *"Archived previous run ({branch}). Starting fresh."*
Then proceed to generate new stories below.
If the result is `IN_PROGRESS` and the branch still exists, the previous run is still active. Tell the user:
> **Existing run found** — {passed}/{total} stories complete on `{branch}`.
>
> - Say **go** to resume the existing run
> - Say **archive** to archive this run and start fresh
Wait for the user to decide before proceeding.
**If `prd.json` does NOT exist**, generate it:
1. Search for existing specs or plans:
- `docs/superpowers/specs/*.md`
- `docs/superpowers/plans/*.md`
- `docs/specs/*.md`
- `docs/plans/*.md`
- `SPEC.md`, `PRD.md`, `DESIGN.md`, `PLAN.md` at project root
- Any markdown file that looks like a feature spec or implementation plan
If found: "I found a spec at `{path}`. Using it to generate stories."
If NOT found, stop and tell the user:
> **No spec or plan found.** Agent Loop decomposes existing plans into stories — it doesn't create plans from scratch.
>
> Create a plan first, then re-run `/agent-loop:run`:
> - Describe your idea to Claude and ask it to write a spec
> - Use `/plan` if available
> - Or create a markdown file at `docs/specs/` or `SPEC.md`
>
> The plan should describe what to build, the tech stack, and key requirements.
**STOP here. Do NOT ask the user to describe the project in a few sentences. Do NOT proceed without a spec file.**
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 and Launch
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`.
3. Verify `.loop/loop.sh` exists and is executable.
4. Parse arguments for any flags to pass through (e.g., `--skip-eval`).
5. Build the loop.sh command and derive a unique tmux session name:
```bash
LOOP_CMD=".loop/loop.sh"
# Add --skip-eval if requested
# Add --max N if specified
# Derive tmux session name from project directory name.
# This allows multiple loops to run in parallel on different projects.
SESSION_NAME="agent-loop-$(basename "$(pwd)")"
```
6. Kill any existing tmux session for THIS project, then launch detached:
```bash
tmux kill-session -t "$SESSION_NAME" 2>/dev/null; tmux new-session -d -s "$SESSION_NAME" -c <project_root> "$LOOP_CMD"
```
7. Start a **background watcher** that waits for the loop to finish. Use the Bash tool with `run_in_background: true`:
```bash
while tmux has-session -t "$SESSION_NAME" 2>/dev/null; do sleep 10; done; echo "LOOP_COMPLETE"
```
This runs silently. When the tmux session exits, Claude Code gets notified automatically.
8. Tell the user:
> **Loop launched** as tmux session `{SESSION_NAME}`. Watch it live:
> ```
> ! tmux attach -t {SESSION_NAME}
> ```
> (Type the above — it opens the session right here in your terminal.)
>
> - **Detach** (return to Claude Code): `Ctrl+B` then `D`
> - **Stop the loop**: `Ctrl+C`
> - Ask me "status" anytime and I'll check progress.
>
> I'll notify you when the loop finishes.
---
## When Background Watcher Completes
When you receive the background task notification (the watcher prints "LOOP_COMPLETE"), the loop has finished. Automatically:
1. Read `.loop/prd.json` — count passed/failed/blocked stories
2. Read `.loop/progress.md` — show the latest session log entries
3. Check `git log --oneline` for commits made during the run
4. Present a summary:
> **Loop Complete**
> - Stories: {passed}/{total} complete, {blocked} blocked
> - Iterations: {from progress.md}
> - Commits: {list from git log}
>
> {If any stories blocked: "Some stories need human review. Run /agent-loop:triage for details."}
> {If all passed: "All stories complete. Review the code and test it."}
---
## Monitoring (if user asks mid-run)
If the user asks about progress (e.g., "status", "how's it going"):
1. Read `.loop/prd.json` — count passed/failed/blocked
2. Derive the session name and capture recent tmux output:
```bash
SESSION_NAME="agent-loop-$(basename "$(pwd)")"
tmux capture-pane -t "$SESSION_NAME" -p | tail -20
```
3. Report current status.