@bjspdn/tap
v1.11.1
Published
A CLI that orchestrates Claude Code agents to execute software engineering work items autonomously. You describe what to build; tap creates tickets, then drives agents through a Planner→Composer→Reviewer pipeline until each item passes.
Readme
tap
A CLI that orchestrates Claude Code agents to execute software engineering work items autonomously. You describe what to build; tap creates tickets, then drives agents through a Planner→Composer→Reviewer pipeline until each item passes.
Workflow
tap add "description"
→ Claude explores codebase, writes simplified ticket YAML
tap run <slug>
→ Planner reads ticket + explores codebase
→ Emits ordered tasks (name, files, action, done criteria)
→ For each task:
Worktree created for isolation
Composer writes code via TDD
Reviewer verifies intent alignment + runs quality gates
PASS → next task / FAIL → Planner re-plans with failure context
→ Merger agent merges all passing branches back
→ Ticket marked done
tap run slug1 slug2 --parallel
→ Worktree per ticket, concurrent execution (4 max)
→ Merger agent merges passing branches backAgents
| Agent | Default Model | Job | | ------------ | ------------- | -------------------------------------------------------------------------------- | | Planner | Opus | Reads ticket, explores codebase, decomposes into ordered tasks. Re-plans on FAIL (max 3). | | Composer | Sonnet | Writes code and tests via TDD. 100-line file / 15-line function ceiling. | | Reviewer | Opus | Verifies intent, behavior, and discipline. Emits PASS/FAIL. Commits on PASS. | | Merger | Opus | Merges worktree branches, resolves conflicts, runs quality gates. |
Each agent invocation gets a fresh context window (subprocess model). Agents are spawned as claude -p subprocesses with config-driven model, effort, and discipline blocks. No agent files on disk — prompts are assembled at runtime from typed blocks and piped via stdin.
Config-driven agents
Model, effort, and discipline blocks are configured per agent in .tap/config.json:
{
"agents": {
"Composer": { "model": "sonnet", "effort": "high" },
"Reviewer": { "model": "opus", "effort": "high" },
"Planner": { "model": "opus", "effort": "high" },
"Merger": { "model": "opus", "effort": "high" }
}
}Each agent receives a set of discipline blocks (e.g. discovery, tdd-discipline, verification, verdict). Blocks can be overridden per agent via blocks (explicit list) or disableBlocks (subtract from defaults). See docs/config.md for full reference.
Tickets
title: string
description: string
constraints:
- string
type: ticket | bug
created: YYYY-MM-DD
done: true | falseTickets live in .tap/tracker/tickets/. Five fields. done: boolean replaces a 6-state status machine.
CLI
tap add "description" # create ticket
tap run <slug> # run single ticket
tap run <s1> <s2> --parallel # run multiple in parallel
tap init # scaffold .tap/ into project
tap update # update managed files
tap remove # remove tap artifactsDirectory layout
.tap/
├── config.json # agent model/effort/block configuration
├── fingerprint.json # quality gates
├── domain/
│ ├── contexts/ # domain context files
│ └── glossary.yaml # domain vocabulary
├── tracker/
│ └── tickets/ # ticket YAML files
└── logs/ # execution logs per ticket
└── <slug>/
├── planner-0.stdin.md
├── planner-0.jsonl
├── composer-1.stdin.md
├── composer-1.jsonl
├── reviewer-1.stdin.md
└── reviewer-1.jsonlQuality gates
Gates are shell commands in .tap/fingerprint.json — bun test, tsc --noEmit, cargo test, or whatever the project uses. Both Composer and Reviewer receive the gate list in their prompt. Reviewer runs each gate independently. Pre-existing failures are filed as bugs, not counted against the Composer.
Documentation
- Execution flow — full call chain from CLI to agent spawning
- Config reference — model, effort, and block configuration
Getting started
Install:
npm install -g @bjspdn/tap[!NOTE] Also available on GitHub.
Initialize in your project:
tap initScaffolds .tap/ with config.json, fingerprint.json, domain/, and tracker/. You will be prompted to configure your quality gates.
Create a ticket:
tap add "add rate limiting to the API endpoints"Run it:
tap run <slug>[!CAUTION]
tap runspawns Claude processes with--dangerously-skip-permissions. Agents execute any bash command, file write, or tool call without confirmation. This is required for unattended loop execution, but a prompt injection in your codebase or dependencies could cause arbitrary command execution. Run inside a devcontainer with network isolation if untrusted code is in scope. Even inside a devcontainer,--dangerously-skip-permissionsdoes not prevent exfiltration to whitelisted domains (e.g., pushing secrets to a public GitHub repo). The firewall limits the attack surface but does not eliminate it. Only mount what the project needs.
