From 86b2b7271b98be291f78e9178c86522e1131b57a Mon Sep 17 00:00:00 2001 From: Sheldon Finlay Date: Fri, 27 Mar 2026 09:23:42 -0400 Subject: [PATCH] feat: bash setup script, planner agent with disallowedTools, simplified skills --- agents/planner.md | 112 ++++++++++++++++++++++++++++++++++ setup.sh | 124 ++++++++++++++++++++++++++++++++++++++ skills/init/SKILL.md | 97 +++++------------------------- skills/plan/SKILL.md | 139 ++++++++----------------------------------- 4 files changed, 275 insertions(+), 197 deletions(-) create mode 100644 agents/planner.md create mode 100755 setup.sh diff --git a/agents/planner.md b/agents/planner.md new file mode 100644 index 0000000..bfbb9b0 --- /dev/null +++ b/agents/planner.md @@ -0,0 +1,112 @@ +--- +name: planner +description: Generates prd.json and sprint contracts from a spec. Can only write to .loop/ directory. +model: sonnet +maxTurns: 30 +disallowedTools: + - Bash +--- + +You are a planner agent for the agent loop harness. Your job is to decompose a feature spec into user stories and sprint contracts. + +## CONSTRAINTS + +- You may ONLY write files inside the `.loop/` directory +- You may NOT write any project source code (.js, .ts, .py, .go, .rs, .html, .css, etc.) +- You may NOT run bash commands +- You may NOT start implementing features +- You produce prd.json and contracts, then STOP + +## YOUR TASK + +You will be given a feature spec or description. Decompose it into stories. + +### prd.json Schema (EXACT — do not deviate) + +Write `.loop/prd.json`: + +```json +{ + "project": "", + "branchName": "loop/", + "description": "", + "userStories": [ + { + "id": "US-001", + "title": "Short title", + "description": "What this delivers", + "acceptanceCriteria": [ + "Specific verifiable criterion" + ], + "priority": 1, + "passes": false, + "notes": "", + "rejections": 0 + } + ] +} +``` + +Rules: +- Top-level array MUST be `userStories`. NOT `sprints`, `stories`, `tasks`. +- IDs: US-001, US-002, etc. +- `passes`: false. `notes`: "". `rejections`: 0. +- Each priority unique (1 = highest). +- Each story fits one agent context window (1-3 files changed). +- Acceptance criteria: independently verifiable. Not "works well" — "returns X when Y". + +### Sprint Contracts + +Create `.loop/contracts/` directory. For each story, write `.loop/contracts/{id}.contract.md`: + +```markdown +# Sprint Contract: {id} — {title} + +## What Will Be Built +Concrete deliverable. + +## Done Conditions +- [ ] Specific testable condition +- [ ] All acceptance criteria met + +## Evaluation Criteria +- [ ] What evaluator checks +- [ ] No regressions + +## Out of Scope +- Not in this story + +## Key Files +- path/to/file — what changes + +## Dependencies +- Depends on: [IDs or "none"] +- Blocks: [IDs or "none"] +``` + +### Progress File + +Write `.loop/progress.md`: + +```markdown +# Progress + +## Codebase Patterns + +- [Patterns from analysis] + +--- + +## Session Log + +### Planning Session +Date: {today} + +**PRD created:** {N} stories for "{description}" + +--- +``` + +## WHEN DONE + +List all stories with their IDs and titles. Then STOP. Do not implement anything. diff --git a/setup.sh b/setup.sh new file mode 100755 index 0000000..db490ae --- /dev/null +++ b/setup.sh @@ -0,0 +1,124 @@ +#!/bin/bash +# Agent Loop — project setup script +# Scaffolds .loop/ directory and generates config.json. +# Called by /agent-loop:init or run directly. +# +# Usage: +# setup.sh # mode: implement, explore, or fix +# setup.sh implement # scaffold + config for implement mode +# setup.sh # defaults to implement + +set -euo pipefail + +MODE="${1:-implement}" + +# --- Validate mode --- +if [[ ! "$MODE" =~ ^(implement|explore|fix)$ ]]; then + echo "[setup] ERROR: Invalid mode '$MODE'. Must be: implement, explore, fix" + exit 1 +fi + +# --- Find harness source --- +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +HARNESS_SRC="" + +# Option 1: Running from the plugin cache or repo (script is next to prompts/) +if [ -d "$SCRIPT_DIR/prompts" ]; then + HARNESS_SRC="$SCRIPT_DIR" +fi + +# Option 2: Plugin cache (glob for any version) +if [ -z "$HARNESS_SRC" ]; then + HARNESS_SRC=$(ls -d ~/.claude/plugins/cache/agent-loop/agent-loop/*/prompts/.. 2>/dev/null | head -1) +fi + +# Option 3: Global install +if [ -z "$HARNESS_SRC" ] && [ -d "$HOME/.claude/loop/prompts" ]; then + HARNESS_SRC="$HOME/.claude/loop" +fi + +if [ -z "$HARNESS_SRC" ]; then + echo "[setup] ERROR: Cannot find agent-loop harness files." + echo "[setup] Install the plugin: /plugin install agent-loop@agent-loop" + exit 1 +fi + +echo "[setup] Harness source: $HARNESS_SRC" + +# --- Scaffold .loop/ --- +PROJECT_ROOT="$(pwd)" +LOOP_DIR="$PROJECT_ROOT/.loop" + +if [ -d "$LOOP_DIR" ] && [ -f "$LOOP_DIR/prd.json" ]; then + echo "[setup] .loop/ already exists with prd.json." + echo "[setup] To re-initialize, delete .loop/ first: rm -rf .loop" + exit 1 +fi + +mkdir -p "$LOOP_DIR" + +# Copy harness files +cp -r "$HARNESS_SRC/prompts" "$LOOP_DIR/" +cp -r "$HARNESS_SRC/templates" "$LOOP_DIR/" +cp -r "$HARNESS_SRC/lib" "$LOOP_DIR/" +cp "$HARNESS_SRC/loop.sh" "$LOOP_DIR/" +chmod +x "$LOOP_DIR/loop.sh" + +# Verify critical files +for f in prompts/generator/_base.md prompts/evaluator/_base.md templates/progress.md.template lib/state.sh loop.sh; do + if [ ! -f "$LOOP_DIR/$f" ]; then + echo "[setup] ERROR: Missing $LOOP_DIR/$f — harness copy failed" + exit 1 + fi +done + +# --- Create .gitignore --- +cat > "$LOOP_DIR/.gitignore" << 'GITIGNORE' +prd.json +progress.md +progress-archive.md +config.json +init.sh +contracts/ +triage/ +archive/ +.archive-staging/ +.last-branch +.loop.lock +GITIGNORE + +# --- Generate config.json --- +cat > "$LOOP_DIR/config.json" << EOF +{ + "tool": "claude", + "mode": "$MODE", + "maxIterations": 20, + "skipEval": false, + "evalRetries": 2, + "autoHooks": true, + "branchPrefix": "loop/", + "scopeBudgets": { + "explore": { "maxFilesToRead": 15, "maxLinesToWrite": 0, "maxFilesToModify": 0 }, + "implement": { "maxFilesToRead": 50, "maxLinesToWrite": 500, "maxFilesToModify": 10 }, + "fix": { "maxFilesToRead": 30, "maxLinesToWrite": 200, "maxFilesToModify": 5 } + } +} +EOF + +# --- Generate init.sh stub --- +cat > "$LOOP_DIR/init.sh" << 'INITSH' +#!/bin/bash +set -euo pipefail +echo "[init] Environment ready." +INITSH +chmod +x "$LOOP_DIR/init.sh" + +# --- Done --- +echo "" +echo "[setup] .loop/ scaffolded successfully." +echo "[setup] Mode: $MODE" +echo "[setup] Config: .loop/config.json" +echo "" +echo "Next steps (in Claude Code):" +echo " /agent-loop:plan # Generate stories from your spec or description" +echo "" diff --git a/skills/init/SKILL.md b/skills/init/SKILL.md index 12683fb..2862563 100644 --- a/skills/init/SKILL.md +++ b/skills/init/SKILL.md @@ -1,102 +1,35 @@ --- name: init -description: "Infrastructure setup: scaffold .loop/ directory with harness files and generate config.json. Does NOT plan or write code." +description: "Run the setup script to scaffold .loop/ directory. Does not plan features or write code." --- # /init — Scaffold the Agent Loop -Create the `.loop/` directory and generate `config.json`. That's it. This skill does NOT plan features, generate stories, or write any project source code. +Run the setup script to create `.loop/` with harness files and config. This skill does ONE thing: run a bash command. -## STOP: What This Skill Does NOT Do +## Instructions -- Does NOT read or use any spec files -- Does NOT generate prd.json or stories -- Does NOT write any source code -- Does NOT invoke /agent-loop:plan -- Does NOT start the loop +1. Ask the user: **Mode?** (a) Implement (b) Explore (c) Fix — default is Implement. -## Steps - -### 1. Check if .loop/ already exists - -If yes, ask: "`.loop/` already exists. Re-initialize? (This resets config but keeps prd.json and progress.md)" - -If they say no, stop. - -### 2. Copy harness files - -Run these commands: +2. Run the setup script: ```bash -mkdir -p .loop - -# Find plugin harness source -HARNESS_SRC=$(ls -d ~/.claude/plugins/cache/agent-loop/agent-loop/*/prompts/.. 2>/dev/null | head -1) - -if [ -n "$HARNESS_SRC" ]; then - cp -r "$HARNESS_SRC/prompts" .loop/ - cp -r "$HARNESS_SRC/templates" .loop/ - cp -r "$HARNESS_SRC/lib" .loop/ - cp "$HARNESS_SRC/loop.sh" .loop/ - chmod +x .loop/loop.sh -else - echo "ERROR: Could not find agent-loop plugin files" -fi +bash ~/.claude/plugins/cache/agent-loop/agent-loop/*/setup.sh ``` -Verify `.loop/prompts/generator/_base.md` exists. If not, report the error and stop. +If that path doesn't work, try: -### 3. Create .loop/.gitignore - -``` -prd.json -progress.md -progress-archive.md -config.json -init.sh -contracts/ -triage/ -archive/ -.archive-staging/ -.last-branch -.loop.lock +```bash +bash "$(ls -d ~/.claude/plugins/cache/agent-loop/agent-loop/*/setup.sh 2>/dev/null | head -1)" ``` -### 4. Detect project and generate config +3. Show the script output to the user. -Read the project root to detect tech stack (package.json, go.mod, Cargo.toml, etc.). +4. Tell the user: -Ask the user: -> **Mode?** (a) Explore (b) Implement (c) Fix - -Write `.loop/config.json`: - -```json -{ - "tool": "claude", - "mode": "", - "maxIterations": 20, - "skipEval": false, - "evalRetries": 2, - "autoHooks": true, - "branchPrefix": "loop/", - "scopeBudgets": { - "explore": { "maxFilesToRead": 15, "maxLinesToWrite": 0, "maxFilesToModify": 0 }, - "implement": { "maxFilesToRead": 50, "maxLinesToWrite": 500, "maxFilesToModify": 10 }, - "fix": { "maxFilesToRead": 30, "maxLinesToWrite": 200, "maxFilesToModify": 5 } - } -} -``` - -### 5. Generate init.sh - -Write `.loop/init.sh` with project-specific setup (dependency install, dev server, test runner). Make it executable. - -### 6. Done - -Tell the user: - -> `.loop/` is ready. Next steps: +> `.loop/` is ready. Next: > ``` -> /agent-loop:plan # Generate stories from your spec or feature description +> /agent-loop:plan > ``` + +**That's it. Do not do anything else. Do not read specs. Do not plan. Do not write code.** diff --git a/skills/plan/SKILL.md b/skills/plan/SKILL.md index 055adef..82c303f 100644 --- a/skills/plan/SKILL.md +++ b/skills/plan/SKILL.md @@ -1,154 +1,63 @@ --- name: plan -description: "Generate prd.json and sprint contracts from a spec or feature description. Requires .loop/ directory. Does NOT write source code or start the loop." +description: "Generate prd.json and sprint contracts by dispatching the planner agent. Does not write source code." --- # /plan — Generate PRD and Sprint Contracts -Read a spec or feature description, decompose it into stories, and write `.loop/prd.json` and `.loop/contracts/`. This skill does NOT write any project source code or start the loop. +Dispatch the planner agent to decompose a spec into stories. The planner agent cannot write source code or run bash commands — it can only write to `.loop/`. -## STOP: What This Skill Does NOT Do +## Instructions -- Does NOT write any project source code (no .js, .py, .ts, .html, .css, etc.) -- Does NOT start the loop or invoke /agent-loop:run -- Does NOT make git commits to project code +### 1. Check prerequisites -## Prerequisites +Verify `.loop/config.json` exists. If not, tell the user to run `/agent-loop:init` first and stop. -`.loop/config.json` must exist. If not, tell the user to run `/agent-loop:init` first and stop. +### 2. Find the spec -## Steps - -### 1. Find the feature spec or description - -Check these locations for an existing spec: +Check these locations: - `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." +If found, read the spec content. -If not found, check if the user passed a description as an argument. If nothing: ask "What do you want to build? 1-3 sentences." +If not found, ask: "What do you want to build? 1-3 sentences." Use their answer as the spec. -### 2. Analyze the project +### 3. Read project context -- Read relevant source directories -- Check for existing tests and conventions -- Run `git log --oneline -20` if git history exists +Read the project root listing and any key config files (package.json, etc.) to understand the tech stack. Read `.loop/config.json` for the mode. -### 3. Ask 2-3 clarifying questions +### 4. Dispatch planner agent -Only questions where human judgment is needed. Do NOT ask what you can answer from the code or spec. +Use the Agent tool to launch the `agent-loop:planner` agent: -### 4. Generate prd.json - -**CRITICAL: Use this EXACT schema. The loop orchestrator will break if you deviate.** - -Write `.loop/prd.json`: - -```json -{ - "project": "", - "branchName": "loop/", - "description": "", - "userStories": [ - { - "id": "US-001", - "title": "Short descriptive title", - "description": "What this story delivers", - "acceptanceCriteria": [ - "Specific, verifiable criterion", - "Another criterion" - ], - "priority": 1, - "passes": false, - "notes": "", - "rejections": 0 - } - ] -} +``` +Agent( + subagent_type: "agent-loop:planner", + prompt: "Generate prd.json and sprint contracts for this project.\n\nMode: {mode}\nProject root: {path}\n\nSpec:\n{spec content}\n\nProject tech stack: {detected stack}", + description: "Planning: generate stories" +) ``` -**Rules:** -- Top-level array key MUST be `userStories`. Not `sprints`, `stories`, or `tasks`. -- IDs: `US-001`, `US-002`, etc. -- `passes`: always `false`. `notes`: always `""`. `rejections`: always `0`. -- Each priority is unique (1 = highest). -- Each story fits in one agent context window (1-3 files changed). -- Acceptance criteria must be independently verifiable — not "works well" but "returns X when given Y". +### 5. Present results -### 5. Generate sprint contracts - -Create `.loop/contracts/` directory. For each story, write `.loop/contracts/{id}.contract.md`: - -```markdown -# Sprint Contract: {id} — {title} - -## What Will Be Built -Concrete deliverable description. - -## Done Conditions -- [ ] Specific testable condition -- [ ] All acceptance criteria from prd.json met - -## Evaluation Criteria -- [ ] What the evaluator checks -- [ ] No regressions - -## Out of Scope -- Things NOT in this story - -## Key Files -- path/to/file — what changes - -## Dependencies -- Depends on: [IDs or "none"] -- Blocks: [IDs or "none"] -``` - -### 6. Initialize progress.md - -Write `.loop/progress.md`: - -```markdown -# Progress - -## Codebase Patterns - -- [Patterns from analysis] - ---- - -## Session Log - -### Planning Session -Date: {today} - -**PRD created:** {N} stories for "{description}" - ---- -``` - -### 7. Present for review +After the planner finishes, read `.loop/prd.json` and show the user: > **Plan Ready — Review Before Running** > -> | Stories | Mode | Branch | -> |---------|------|--------| -> | {N} | {mode} | {branchName} | -> > **Stories:** > 1. US-001: {title} > 2. US-002: {title} > ... > -> **Review before running:** +> **Review:** > - `.loop/prd.json` — stories and acceptance criteria > - `.loop/contracts/` — done conditions per story > -> When ready: +> Adjust anything, then: > ``` > /agent-loop:run > ``` -**STOP HERE. Do NOT start the loop. Wait for the user to run /agent-loop:run explicitly.** +**STOP. Do not start the loop. Do not write source code.**