A reusable project template for orchestrating Claude Code agent teams. Fork this repo, customize the agents and tasks for your project, and let the agents build overnight.
You (human) Orchestrator (bash) Agents (claude --print)
│ │ │
│ Write TRD + task files │ │
│ Define agent personas │ │
│ Run: snapp-build-all.sh │ │
│──────────────────────────────>│ │
│ │ Read sprint-1.json │
│ │ Resolve dependencies │
│ │ Dispatch task to agent ──────>│
│ │ │ Read persona
│ │ │ Read project CLAUDE.md
│ │ │ Implement task
│ │ │ Run tests
│ (sleeping) │ Log output │ Commit
│ │ │<─────────
│ │ Check: passed/failed │
│ │ Next task ──────────────────>│
│ │ ... │
│ │ Sprint done → git push │
│ │ Next sprint │
│ │ ... │
│ │ Generate master report │
│ (wake up) │<───────── │
│ Read report │ │
│<─────────────────────────────│ │
gh repo create my-project --template thomwinans/agentic-template
cd my-project# Edit the project-wide instructions
vim .claude/CLAUDE.md
# Edit agent personas for your stack/domain
vim .claude/agents/*.md
# Create your task files
vim .claude/tasks/sprint-1.json
# Configure auto-approve permissions
vim .claude/settings.local.json./scripts/build.sh .claude/tasks/sprint-1.jsonnohup ./scripts/build-all.sh > build.log 2>&1 &cat .claude/reports/master-report_*.md
# or individual sprint reports:
ls .claude/reports/report_*.md.claude/
├── CLAUDE.md # Project-wide rules (edit this)
├── settings.local.json # Auto-approve tool permissions
├── agents/ # Agent persona files
│ ├── archie.md # Architect — contracts, interfaces, integration
│ ├── bex.md # Backend — services, repositories, APIs
│ ├── frankie.md # Frontend — UI components, state
│ ├── sage.md # UX Designer — specs, flows, copy
│ ├── quinn.md # QA — tests at every level
│ ├── delta.md # DevOps — infra, Docker, CI/CD
│ ├── piper.md # Data Engineer — Steampipe/DuckDB/PostgreSQL pipelines
│ └── vera.md # Trust-But-Verify — runs after every sprint automatically
├── tasks/ # Sprint task definitions
│ ├── sprint-1.json # First sprint
│ ├── sprint-2.json # Second sprint
│ └── progress.json # Auto-maintained state tracker
├── reports/ # Generated build reports
└── logs/ # Per-task execution logs
scripts/
├── build.sh # Run one sprint
└── build-all.sh # Chain all sprints
Never let two agents implement against an interface that hasn't been locked.
The workflow is:
- Architect defines contracts (interfaces, DTOs, API specs)
- Human reviews and commits contracts to main
- Implementation agents work in parallel against locked contracts
- QA validates against contracts
- Architect integrates and resolves conflicts
Each sprint is a JSON file containing ordered tasks with explicit dependencies:
{
"sprint": "S1",
"description": "Foundation — what this sprint delivers",
"tasks": [
{
"id": "S1-001",
"title": "Human-readable task title",
"agent": "delta",
"depends_on": [],
"prompt": "Detailed instructions for the agent...",
"done_when": "Acceptance criteria — what must be true."
},
{
"id": "S1-002",
"title": "Second task",
"agent": "bex",
"depends_on": ["S1-001"],
"prompt": "This task depends on S1-001...",
"done_when": "Criteria..."
}
]
}Fields:
id: Unique task identifier. Convention:S{sprint}-{sequence}title: Short description (used in commits and reports)agent: Which persona file to load (filename without .md)depends_on: List of task IDs that must be completed firstprompt: Full instructions for the agent. Be specific — the agent has no context beyond this prompt + its persona + CLAUDE.mddone_when: Acceptance criteria. Should be verifiable (tests pass, file exists, endpoint responds)
Each .claude/agents/{name}.md file defines:
- Role: What this agent is responsible for
- Domain: What files/systems it owns
- Patterns: Code conventions it must follow
- Boundaries: What it must NOT do (e.g., "do not modify Snapp.Shared")
- Quality bar: What "done" looks like
The orchestrator injects the persona into the prompt before dispatching to Claude Code.
progress.json tracks task status:
{
"S1-001": "completed",
"S1-002": "in_progress",
"S1-003": "pending"
}States: pending → in_progress → completed | failed | blocked
The orchestrator manages this automatically. To retry a failed task, set it back to pending in progress.json and re-run the sprint.
After each sprint, a report is generated at .claude/reports/report_{timestamp}.md:
## Summary
| Status | Count |
|-----------|-------|
| Completed | 6 |
| Failed | 1 |
| Blocked | 1 |
| Total | 8 |
## Task Details
- [+] S1-001 (delta): Initialize repo — completed
- [x] S1-002 (bex): Auth service — failed
- [?] S1-003 (quinn): Auth tests — blockedThe master build script generates an additional master-report_{timestamp}.md with per-sprint results.
The default agents are tuned for a .NET/Blazor/AWS stack. To adapt:
- Keep the roles, change the skills. The architect/backend/frontend/UX/QA/DevOps split works for most software projects.
- Update technology references. Replace ".NET" with your stack, "MudBlazor" with your component library, "DynamoDB" with your database, etc.
- Update patterns sections. Each persona has a "Patterns" section — replace with your project's conventions.
- Add or remove agents. The template includes
piper.mdfor data engineering (Steampipe/DuckDB/PostgreSQL pipelines). Don't need UX? Removesage.md.
A task prompt should contain everything the agent needs to work autonomously:
- What to build (specific files, endpoints, components)
- How to build it (patterns to follow, libraries to use)
- What to reference (which TRD section, which interface, which config)
- How to test it (specific test cases, commands to run)
- What to commit (commit message convention)
Bad prompt: "Build the auth service." Good prompt: "Create Snapp.Service.Auth with endpoints POST /api/auth/magic-link, POST /api/auth/validate... [2 paragraphs of specific implementation details] ... Integration tests: magic link flow through Papercut, token refresh, rate limiting..."
Tasks within a sprint can have dependencies. The orchestrator resolves them:
- Tasks with no dependencies (or all deps met) run first
- Tasks whose deps are met run next
- Tasks whose deps failed are marked
blocked - Multiple passes ensure all resolvable tasks execute
Cross-sprint dependencies are implicit: sprint N runs only after sprint N-1 completes.
./scripts/build.sh <sprint-file> [--dry-run] [--resume TASK_ID]
# Examples:
./scripts/build.sh .claude/tasks/sprint-1.json
./scripts/build.sh .claude/tasks/sprint-1.json --dry-run
./scripts/build.sh .claude/tasks/sprint-1.json --resume S1-004./scripts/build-all.sh [--continue-on-failure] [--start-from SPRINT]
# Examples:
./scripts/build-all.sh # stop on first failure
./scripts/build-all.sh --continue-on-failure # push through failures
./scripts/build-all.sh --start-from S3 # resume from Sprint 3nohup ./scripts/build-all.sh > build.log 2>&1 &
echo "Build running as PID $!. Check .claude/reports/ tomorrow."- Claude Code CLI installed and authenticated
jq(JSON processing):brew install jqgitinitialized in project root--dangerously-skip-permissionsenabled (verify:claude --print --dangerously-skip-permissions "echo ok")
Q: A task failed. How do I retry it?
Edit .claude/tasks/progress.json, set the task status back to "pending", and re-run the sprint.
Q: Can I run agents in parallel? The orchestrator runs tasks sequentially within a sprint (to avoid git conflicts). For true parallelism, use git worktrees — each agent works in its own worktree. This requires a more sophisticated orchestrator (future enhancement).
Q: How much does this cost?
Each task is capped at --max-budget-usd 5.00. A sprint of 5 tasks costs at most $25. A full 17-sprint project (~55 tasks) costs at most ~$275, though actual usage is typically lower.
Q: The agent modified a file it shouldn't have. Update the agent's persona to explicitly state boundaries. Add "You must NOT modify {file/directory}" to the persona. The contract-first approach prevents most of these issues.
Q: How do I add a new sprint?
- Create
.claude/tasks/sprint-N.jsonfollowing the format - Add
"sprint-N.json"to the SPRINTS array inbuild-all.sh - Run
./scripts/build.sh .claude/tasks/sprint-N.json