Skip to content

Latest commit

 

History

12 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tanagram-harness

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.

Install

/plugin install ./tanagram-harness --scope user

Or from the marketplace:

/plugin marketplace add tanagram/harness
/plugin install tanagram-harness

Quick Start

  1. Generate a harness.json for your project:

    npx @tanagram/harness init
    

    This detects your project structure and walks you through setup interactively. (Optional — works without one for simple single-service projects.)

  2. Run /harness start my-feature

  3. Develop your feature in the isolated worktree

  4. Run /harness test to verify against real running services

  5. Run /harness pr to create a pull request

  6. Run /harness cleanup to remove the worktree and free ports

harness.json Reference

{
  "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" }
}

Top-Level Fields

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

Service Fields

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

Without harness.json

For simple single-service projects, the plugin auto-detects:

  • Node.js (package.json): npm installnpm run dev on port 3000
  • Python (pyproject.toml): poetry installpoetry run uvicorn on port 8000

No config needed.

Commands

/harness start [feature-name]

Creates an isolated git worktree, copies env files, installs dependencies, starts all services with auto-allocated ports, and enters plan mode to begin development.

/harness test [feature-name]

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.

/harness pr [feature-name]

Stages changes, commits, pushes, and creates a GitHub PR with summary and test plan.

/harness cleanup [feature-name]

Stops all services, frees ports, removes the worktree, and optionally deletes the remote branch.

/harness status

Lists active worktrees, running stacks, and port allocations across all features.

Port Allocation

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.

Example Configs

Next.js App

{
  "services": [
    {
      "name": "web",
      "directory": ".",
      "install": "npm install",
      "start": "PORT=${PORT} npm run dev",
      "port": 3000,
      "health": "/",
      "test": "npm test"
    }
  ]
}

Django + React

{
  "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" }
}

Rails + Sidekiq

{
  "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"]
    }
  ]
}

How It Works

  1. Worktree isolation — Each feature gets its own git worktree branched from your base branch. The main repo stays clean.
  2. Port allocation — A registry at ~/.claude/stack-registry.json tracks which ports are in use across all active features. Each worktree gets a unique slot so services never collide.
  3. Config-driven servicesharness.json declares your services, their start commands, health checks, and test commands. The plugin handles dependency ordering, parallel installs, and health check polling.
  4. Real testing — The skill explicitly instructs Claude to test against real running services, never mocks. Browser verification uses Chrome DevTools MCP.
  5. State tracking — Each worktree gets a .feature-meta.json and .stack/ directory for PIDs, logs, and port assignments.

License

MIT

About

A Claude Code plugin that gives you the full feature lifecycle in one command — isolated worktrees, dev stack orchestration, real testing, and PR creation.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages