Skip to content

bjspdn/tap-tool

Repository files navigation

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 back

Agents

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 | false

Tickets 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 artifacts

Directory 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.jsonl

Quality gates

Gates are shell commands in .tap/fingerprint.jsonbun 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

Getting started

Install:

npm install -g @bjspdn/tap

Note

Also available on GitHub.

Initialize in your project:

tap init

Scaffolds .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 run spawns 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-permissions does 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.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages