{"id":49924720,"url":"https://github.com/hinanohart/tab-conductor","last_synced_at":"2026-05-16T22:38:52.662Z","repository":{"id":354145322,"uuid":"1222358623","full_name":"hinanohart/tab-conductor","owner":"hinanohart","description":"Stable, observable multi-tab orchestrator skill for Claude Code: supervisor + worker subprocesses with JSON state, cost cap, secret deny, stuck detection, and post-mortem persistence.","archived":false,"fork":false,"pushed_at":"2026-05-16T11:51:27.000Z","size":202,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-16T13:40:18.134Z","etag":null,"topics":["agent","claude-code","json-state","multi-tab","orchestration","parallel","skill","subprocess","supervisor","worker"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hinanohart.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-27T09:36:01.000Z","updated_at":"2026-05-16T11:51:30.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/hinanohart/tab-conductor","commit_stats":null,"previous_names":["hinanohart/tab-conductor"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/hinanohart/tab-conductor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hinanohart%2Ftab-conductor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hinanohart%2Ftab-conductor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hinanohart%2Ftab-conductor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hinanohart%2Ftab-conductor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hinanohart","download_url":"https://codeload.github.com/hinanohart/tab-conductor/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hinanohart%2Ftab-conductor/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33121452,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-16T18:38:32.183Z","status":"ssl_error","status_checked_at":"2026-05-16T18:38:29.903Z","response_time":115,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent","claude-code","json-state","multi-tab","orchestration","parallel","skill","subprocess","supervisor","worker"],"created_at":"2026-05-16T22:38:51.914Z","updated_at":"2026-05-16T22:38:52.655Z","avatar_url":"https://github.com/hinanohart.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tab-conductor\n\n[![CI](https://github.com/hinanohart/tab-conductor/actions/workflows/ci.yml/badge.svg)](https://github.com/hinanohart/tab-conductor/actions/workflows/ci.yml)\n[![Coverage](https://img.shields.io/badge/coverage-83%25-green)](https://github.com/hinanohart/tab-conductor)\n[![PyPI](https://img.shields.io/badge/pypi-coming_soon-lightgrey)](https://pypi.org/project/tab-conductor/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n[![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue)](https://www.python.org/downloads/)\n\nStable, observable multi-tab orchestrator skill for Claude Code.\n\ntab-conductor spawns N parallel `claude -p` worker subprocesses, coordinates them through a shared JSON state file, and enforces cost caps, secret denial, and stuck-process detection — all without experimental flags, tmux workarounds, or process-level hacks.\n\n\u003e **Disclaimer**: This project is not affiliated with or endorsed by Anthropic. It uses the Claude CLI (`claude -p`) as a subprocess backend. Anthropic's official multi-agent solution is [Agent Teams](https://docs.anthropic.com/en/docs/build-with-claude/agents) (currently experimental).\n\n---\n\n## Why tab-conductor?\n\n| Differentiator | Detail |\n|---|---|\n| **Persistent JSON state** | Every run leaves `state.json` + structured logs — readable after crash, resumable, post-mortem ready |\n| **Cost + secret guardrails** | Per-worker `$1` and global `$5` cap with SIGINT→SIGTERM→SIGKILL escalation; secret deny-list scrubs API keys from all output |\n| **No experimental flags** | Works with any `claude` CLI build that supports `claude -p --output-format stream-json`; no `--dangerously-*` required |\n| **Failure museum** | Failed runs preserved under `.orchestrator/` (never deleted); `bugreport` command packages everything as redacted tar.gz |\n| **Skill bundle** | Ships as a Claude Code skill (`~/.claude/skills/tab-conductor/`) with progressive disclosure — SKILL.md ≤ 100 lines, full references behind links |\n\n---\n\n## Comparison\n\n| Feature | **tab-conductor** | Anthropic Agent Teams | claude_code_agent_farm | claude-squad |\n|---|---|---|---|---|\n| Stable (no experimental flag) | Yes | No (experimental) | Yes | Yes |\n| Persistent JSON state | Yes | No | Partial | No |\n| Cost cap enforcement | Yes (per-worker + global) | API-level only | No | No |\n| Secret deny-list | Yes (regex scrub) | No | No | No |\n| Stuck detection | Yes (3-layer) | Unknown | No | No |\n| Failure museum / bugreport | Yes | No | No | No |\n| Claude Code Skill bundle | Yes | N/A | No | No |\n| DAG task plans (YAML) | Yes | No | No | Partial |\n| HMAC state signing | Optional | No | No | No |\n| OS support | Linux + macOS + WSL2 | Linux | Linux | Linux |\n\nSee [docs/COMPARISON.md](docs/COMPARISON.md) for detailed feature-by-feature analysis.\n\n---\n\n## Install\n\n```bash\n# 1. Clone and create venv\ngit clone https://github.com/hinanohart/tab-conductor.git\ncd tab-conductor\nuv venv \u0026\u0026 source .venv/bin/activate\nuv pip install -e \".[dev]\"\n\n# 2. Install as Claude Code skill\nbash scripts/install_skill.sh\n```\n\n---\n\n## 5-Minute Quickstart\n\n```bash\n# Step 1: Validate a plan (no API key needed)\ntab-conductor validate examples/scenario_a_refactor/plan.yaml\n\n# Step 2: Run with mock workers (no API key needed, no subprocesses)\ntab-conductor run examples/scenario_a_refactor/plan.yaml \\\n    --mock --max-parallel 3 --state-dir .orchestrator/demo\n\n# Step 3: Watch progress in another terminal\ntab-conductor watch \u003cRUN_ID\u003e\n\n# Step 4: Inspect final state\ntab-conductor show \u003cRUN_ID\u003e\n```\n\n**Example plan.yaml:**\n\n```yaml\nname: \"refactor-utils\"\ndescription: \"Lint + type + verify pipeline\"\nmax_parallel: 3\n\ntasks:\n  - id: lint\n    kind: refactor\n    prompt: \"Run ruff on src/ and fix all auto-fixable issues.\"\n    priority: 5\n    max_retries: 2\n\n  - id: types\n    kind: refactor\n    prompt: \"Run mypy --strict on src/ and fix all type errors.\"\n    priority: 5\n    max_retries: 2\n\n  - id: verify\n    kind: verify\n    prompt: \"Run pytest -x and confirm all tests pass.\"\n    priority: 9\n    depends_on: [lint, types]\n    max_retries: 1\n```\n\n\u003e Cost caps and HMAC signing are configured at run time via CLI flags\n\u003e (`--cap-usd-per-worker`, `--cap-usd-global`, `--require-hmac`), not\n\u003e inside the plan file. See `tab-conductor run --help`.\n\n---\n\n## Architecture\n\n```mermaid\nflowchart TB\n    User([User])\n    subgraph Supervisor[\"Supervisor (current Claude Code session)\"]\n        SC[CLI: tab-conductor run plan.yaml]\n        OP[Orchestrator loop]\n        ST[(state.json + state.lock\\nflock + os.replace)]\n        EV[(events/*.jsonl)]\n    end\n    subgraph Workers[\"Worker subprocesses\"]\n        W1[claude -p stream-json\\n--max-budget-usd]\n        W2[claude -p ...]\n        WN[claude -p ...]\n    end\n    subgraph Logs[\"state_dir/logs + transcripts\"]\n        L1[worker_*.jsonl]\n        SUP[supervisor.jsonl]\n    end\n    User --\u003e SC --\u003e OP \u003c--\u003e ST\n    OP --\u003e W1 \u0026 W2 \u0026 WN\n    Workers --\u003e Logs\n    OP -- \"summary only\" --\u003e SC\n```\n\nSee [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for full implementation notes, sequence diagrams, and state.json schema examples.\n\n---\n\n## Core Commands\n\n| Command | Description |\n|---|---|\n| `run \u003cplan.yaml\u003e` | Parse plan, spawn workers, supervise to completion |\n| `ls` | List all runs under the state root directory |\n| `show \u003cRUN_ID\u003e` | Pretty-print current state.json for a run |\n| `watch \u003cRUN_ID\u003e` | Live-refresh progress every 1 second |\n| `kill \u003cRUN_ID\u003e` | Send SIGTERM to all workers of a run |\n| `bugreport \u003cRUN_ID\u003e` | Package state + logs as tar.gz with secrets redacted |\n| `validate \u003cplan.yaml\u003e` | Validate plan YAML without running (safe dry-run) |\n| `version` | Print version and exit |\n\n---\n\n## Plan Format\n\n```yaml\n# top-level metadata (all optional except \"tasks\")\nname: \"my-run\"                      # display name\ndescription: \"...\"                  # free-form description\nmax_parallel: 3                     # concurrent worker limit (overridden by --max-parallel)\n\ntasks:\n  - id: task1                       # unique identifier, required\n    kind: general                   # arbitrary string label, default \"general\"\n    prompt: \"...\"                   # instruction passed to the worker, required\n    priority: 5                     # 0..9, higher = runs first within ready set, default 5\n    depends_on: []                  # list of task IDs that must complete first, default []\n    max_retries: 2                  # 0..10, default 2\n```\n\nRun-time guarantees (cost cap, HMAC, max parallel) are configured via CLI\nflags on `tab-conductor run`, not via fields inside `plan.yaml`. See\n`tab-conductor run --help` for the authoritative list.\n\n---\n\n## Safety Guarantees\n\n| Guarantee | Implementation |\n|---|---|\n| **Cost cap** | Per-worker `--max-budget-usd`; global SIGTERM when `cost_usd_total \u003e= cap` |\n| **Secret deny** | Regex scrub of Anthropic (`sk-ant-…`), OpenAI/generic (`sk-…`), GitHub (`ghp_/gho_/ghu_/ghs_/ghr_…`), AWS (`AKIA…`, `ASIA…`), `key=value` pairs, and base64-like 40+ char strings before any bundled write; deny-list path read for `.env*`, `*.pem`, `~/.ssh/` private keys, `~/.aws/`, `~/.kaggle/`, etc. |\n| **Stuck detection** | 3-layer: heartbeat timeout → capture hash stall → pgrep liveness |\n| **Atomic state** | `flock(state.lock)` + `os.replace(state.json.tmp, state.json)` — no partial writes |\n| **Failure museum** | `.orchestrator/` never auto-deleted; `bugreport` packages with `--redact` |\n\nSee [docs/SECURITY_THREAT_MODEL.md](docs/SECURITY_THREAT_MODEL.md) for full 4-layer threat model.\n\n---\n\n## Examples\n\n| Scenario | Description |\n|---|---|\n| [scenario_a_refactor](examples/scenario_a_refactor/) | Parallel lint + type-check + test verification |\n| [scenario_b_translate](examples/scenario_b_translate/) | Concurrent docstring translation across modules |\n| [scenario_c_multi_provider](examples/scenario_c_multi_provider/) | Multi-strategy approach to a single problem |\n| [scenario_d_pipeline](examples/scenario_d_pipeline/) | DAG pipeline with sequential dependencies |\n| [scenario_e_repro](examples/scenario_e_repro/) | Parallel bug reproduction with 3 hypotheses |\n\n---\n\n## Status: alpha (v0.1.0)\n\nThis project is in **alpha**. The plan schema, state schema, and CLI flags are stabilizing but may change before v1.0.\n\n- Performance benchmarks: see [docs/PERFORMANCE.md](docs/PERFORMANCE.md) (placeholders; measure-then-update)\n- Changelog: see [CHANGELOG.md](CHANGELOG.md)\n\n---\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md).\n\n---\n\n## License\n\nMIT © 2026 hinanohart\n\nSPDX-License-Identifier: MIT\n\n---\n\n## Acknowledgements\n\n- [Anthropic Agent Teams](https://docs.anthropic.com/en/docs/build-with-claude/agents) — the official multi-agent solution this project complements\n- [Dicklesworthstone/claude_code_agent_farm](https://github.com/Dicklesworthstone/claude_code_agent_farm) — inspiration for multi-agent coordination patterns\n- [smtg-ai/claude-squad](https://github.com/smtg-ai/claude-squad) — inspiration for supervisor/worker architecture\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhinanohart%2Ftab-conductor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhinanohart%2Ftab-conductor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhinanohart%2Ftab-conductor/lists"}