A Claude Code plugin that gives you the full feature lifecycle in one command — isolated worktrees, dev stack orchestration, real testing, and PR creation.
/harness start fix-auth-flow
/harness test
/harness pr
/harness cleanup
Inspired by OpenAI's Harness Engineering — the idea that every feature should be developed in an isolated, bootable environment with mechanical enforcement and real validation.
/plugin install ./tanagram-harness --scope user
Or from the marketplace:
/plugin marketplace add tanagram/harness
/plugin install tanagram-harness
-
Generate a
harness.jsonfor your project:npx @tanagram/harness initThis detects your project structure and walks you through setup interactively. (Optional — works without one for simple single-service projects.)
-
Run
/harness start my-feature -
Develop your feature in the isolated worktree
-
Run
/harness testto verify against real running services -
Run
/harness prto create a pull request -
Run
/harness cleanupto remove the worktree and free ports
{
"baseBranch": "origin/main",
"envFiles": ["**/.env"],
"services": [
{
"name": "api",
"directory": "backend",
"install": "poetry install --with dev",
"start": "poetry run uvicorn main:app --port ${PORT}",
"port": 8000,
"health": "/health",
"test": "poetry run pytest -x",
"dependsOn": []
},
{
"name": "web",
"directory": "frontend",
"install": "pnpm install",
"start": "PORT=${PORT} pnpm dev",
"port": 3000,
"health": "/",
"test": "pnpm test && pnpm typecheck",
"dependsOn": ["api"],
"env": {
"VITE_API_BASE_URL": "http://localhost:${ports.api}"
}
}
],
"portOffset": 10,
"browser": { "entry": "web" }
}| Field | Type | Default | Description |
|---|---|---|---|
baseBranch |
string | "origin/main" |
Branch to create worktrees from |
envFiles |
string[] | ["**/.env", "**/.env.local"] |
Glob patterns for env files to copy into worktrees |
services |
Service[] | auto-detected | Services to start |
portOffset |
number | 10 |
Port offset multiplier per worktree slot |
browser.entry |
string | first service | Which service to open in browser for verification |
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | yes | Service identifier |
directory |
string | yes | Subdirectory relative to project root |
install |
string | no | Dependency install command |
start |
string | yes | Start command (${PORT} is substituted with the allocated port) |
port |
number | yes | Base port number |
health |
string | no | Health check endpoint path (e.g. "/health") |
test |
string | no | Test command |
dependsOn |
string[] | no | Services that must start before this one |
env |
object | no | Env vars to set when starting. Values support ${ports.SERVICE} to reference another service's allocated port |
For simple single-service projects, the plugin auto-detects:
- Node.js (
package.json):npm install→npm run devon port 3000 - Python (
pyproject.toml):poetry install→poetry run uvicornon port 8000
No config needed.
Creates an isolated git worktree, copies env files, installs dependencies, starts all services with auto-allocated ports, and enters plan mode to begin development.
Runs service tests per harness.json, verifies in-browser via Chrome DevTools MCP, and checks stack logs for errors. All tests run against real services — no mocks.
Stages changes, commits, pushes, and creates a GitHub PR with summary and test plan.
Stops all services, frees ports, removes the worktree, and optionally deletes the remote branch.
Lists active worktrees, running stacks, and port allocations across all features.
Each concurrent worktree gets a slot. Ports are offset by slot * portOffset:
| Service | Base | Slot 1 | Slot 2 | Slot 3 |
|---|---|---|---|---|
| api | 8000 | 8010 | 8020 | 8030 |
| web | 3000 | 3010 | 3020 | 3030 |
Port assignments are tracked in ~/.claude/stack-registry.json.
{
"services": [
{
"name": "web",
"directory": ".",
"install": "npm install",
"start": "PORT=${PORT} npm run dev",
"port": 3000,
"health": "/",
"test": "npm test"
}
]
}{
"baseBranch": "origin/main",
"services": [
{
"name": "api",
"directory": "api",
"install": "pip install -r requirements.txt",
"start": "python manage.py runserver 0.0.0.0:${PORT}",
"port": 8000,
"health": "/api/health/",
"test": "python manage.py test"
},
{
"name": "web",
"directory": "web",
"install": "npm install",
"start": "REACT_APP_API_URL=http://localhost:8010 PORT=${PORT} npm start",
"port": 3000,
"health": "/",
"test": "npm test",
"dependsOn": ["api"]
}
],
"browser": { "entry": "web" }
}{
"services": [
{
"name": "web",
"directory": ".",
"install": "bundle install",
"start": "PORT=${PORT} bin/rails server",
"port": 3000,
"health": "/up",
"test": "bin/rails test"
},
{
"name": "worker",
"directory": ".",
"start": "bundle exec sidekiq",
"port": 7433,
"dependsOn": ["web"]
}
]
}- Worktree isolation — Each feature gets its own git worktree branched from your base branch. The main repo stays clean.
- Port allocation — A registry at
~/.claude/stack-registry.jsontracks which ports are in use across all active features. Each worktree gets a unique slot so services never collide. - Config-driven services —
harness.jsondeclares your services, their start commands, health checks, and test commands. The plugin handles dependency ordering, parallel installs, and health check polling. - Real testing — The skill explicitly instructs Claude to test against real running services, never mocks. Browser verification uses Chrome DevTools MCP.
- State tracking — Each worktree gets a
.feature-meta.jsonand.stack/directory for PIDs, logs, and port assignments.
MIT