{"id":50665581,"url":"https://github.com/samuel0101010/wisp-agentdiff","last_synced_at":"2026-06-08T06:04:22.527Z","repository":{"id":358746572,"uuid":"1242702477","full_name":"Samuel0101010/wisp-agentdiff","owner":"Samuel0101010","description":"Per-agent diff review for Claude Code parallel subagent workflows. Each subagent worktree captured automatically, tabbed TUI to approve, revert, or merge each one independently.","archived":false,"fork":false,"pushed_at":"2026-05-18T22:18:53.000Z","size":20006,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-18T23:59:26.871Z","etag":null,"topics":["anthropic","claude-code","claude-code-plugin","cli","code-review","diff-tool","git-worktree","ink","multi-agent","subagents","tui","typescript"],"latest_commit_sha":null,"homepage":"https://github.com/Samuel0101010/wisp-agentdiff#readme","language":"TypeScript","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/Samuel0101010.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"docs/roadmap.md","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-05-18T17:11:06.000Z","updated_at":"2026-05-18T22:18:57.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Samuel0101010/wisp-agentdiff","commit_stats":null,"previous_names":["samuel0101010/wisp-agentdiff"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/Samuel0101010/wisp-agentdiff","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Samuel0101010%2Fwisp-agentdiff","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Samuel0101010%2Fwisp-agentdiff/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Samuel0101010%2Fwisp-agentdiff/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Samuel0101010%2Fwisp-agentdiff/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Samuel0101010","download_url":"https://codeload.github.com/Samuel0101010/wisp-agentdiff/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Samuel0101010%2Fwisp-agentdiff/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34050238,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-08T02:00:07.615Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["anthropic","claude-code","claude-code-plugin","cli","code-review","diff-tool","git-worktree","ink","multi-agent","subagents","tui","typescript"],"created_at":"2026-06-08T06:04:06.683Z","updated_at":"2026-06-08T06:04:22.511Z","avatar_url":"https://github.com/Samuel0101010.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/assets/wisp-logo.png\" alt=\"WISP\" width=\"440\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/assets/wisp-figure.png\" alt=\"WISP mascot\" width=\"240\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/Samuel0101010/wisp-agentdiff/releases\"\u003e\u003cimg src=\"https://img.shields.io/badge/Release-v1.4.1-C2A148?style=for-the-badge\" alt=\"Release v1.4.1\"\u003e\u003c/a\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-MIT-blue?style=for-the-badge\" alt=\"License: MIT\"\u003e\u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/badge/TypeScript-3178C6?style=for-the-badge\u0026logo=typescript\u0026logoColor=white\" alt=\"TypeScript\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Node-%3E%3D20-339933?style=for-the-badge\u0026logo=nodedotjs\u0026logoColor=white\" alt=\"Node \u003e=20\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Ink-TUI-00B4FF?style=for-the-badge\" alt=\"Ink TUI\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Claude_Code-Subagent_Worktrees-D97757?style=for-the-badge\" alt=\"Claude Code subagent worktrees\"\u003e\n\u003c/p\u003e\n\n# wisp-agentdiff\n\nPer-agent diffs for Claude Code parallel subagent workflows.\n\nClaude Code can fan out five subagents in parallel, each in its own git\nworktree. When one of them goes rogue, the current workflow gives you one\nbutton: keep everything, or throw everything away. `wisp-agentdiff` adds\nthe missing step in between — a tabbed TUI where each subagent's diff,\ntoken usage, and tool-call list lives on its own pane, and one keystroke\napproves, reverts, or merges it.\n\nFive subagents refactor the auth module. Four edit cleanly; agent 3 also\nrewrites `src/db/pool.ts` for no good reason. Open the review, press `n`\nto step to agent 3, `r` to revert it, `m` to merge the other four. The\npool file never enters the working tree. If two approved agents touched\nthe same file, the merge refuses and points at the conflict — no silent\nmerge markers, no theirs/ours guessing.\n\n## What it looks like\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/assets/screenshot-1-opening.png\" alt=\"wisp-agentdiff review — opening with 5 agents pending\" width=\"720\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\u003cem\u003eOpening — five subagents recorded, viewing \u003ccode\u003eauth\u003c/code\u003e's diff.\u003c/em\u003e\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/assets/screenshot-2-decisions.png\" alt=\"wisp-agentdiff after approving four and reverting the rogue db agent\" width=\"720\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\u003cem\u003eAfter \u003ccode\u003ea a r a a\u003c/code\u003e — \u003ccode\u003edb\u003c/code\u003e is reverted because it rewrote \u003ccode\u003esrc/db/pool.ts\u003c/code\u003e for no good reason.\u003c/em\u003e\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/assets/screenshot-3-conflict.png\" alt=\"wisp-agentdiff conflict view — db and api both touched src/db/pool.ts\" width=\"720\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\u003cem\u003eConflict view — \u003ccode\u003edb\u003c/code\u003e and \u003ccode\u003eapi\u003c/code\u003e both touched \u003ccode\u003esrc/db/pool.ts\u003c/code\u003e. The merge step refuses until one side is reverted.\u003c/em\u003e\u003c/p\u003e\n\n## Install\n\nTwo equivalent paths — pick one.\n\n### Option A — Claude Code plugin (one-step, recommended)\n\nInside any Claude Code session:\n\n```text\n/plugin marketplace add Samuel0101010/wisp-agentdiff\n/plugin install wisp-agentdiff@wisp-agentdiff\n```\n\nClaude Code clones the repo, registers the `wisp-agentdiff` skill and\n`/review-agents` slash command, and wires the native `WorktreeCreate` /\n`WorktreeRemove` hooks automatically. No `settings.json` edit required.\n\nThe hooks invoke `npx -y wisp-agentdiff@latest` on first use — first\nworktree capture incurs a one-time ~1 s download, every subsequent\ncall is local-cached.\n\n### Option B — npm + manual hook snippet\n\n```bash\nnpx wisp-agentdiff install\n```\n\nThat deploys the SKILL and `/review-agents` slash command into\n`~/.claude/` and prints the hook snippet. Paste the snippet into\n`~/.claude/settings.json` once:\n\n```jsonc\n{\n  \"hooks\": {\n    \"WorktreeCreate\": [\n      { \"matcher\": \"*\", \"hooks\": [{ \"type\": \"command\", \"command\": \"wisp-agentdiff hook worktree-create\" }] }\n    ],\n    \"WorktreeRemove\": [\n      { \"matcher\": \"*\", \"hooks\": [{ \"type\": \"command\", \"command\": \"wisp-agentdiff hook worktree-remove\" }] }\n    ]\n  }\n}\n```\n\nFrom then on, every subagent Claude Code spawns with\n`isolation: worktree` in its frontmatter is captured automatically.\n\n## Verify the install\n\nRight after `/plugin install` (or `npx wisp-agentdiff install`), the state\nfile doesn't exist yet — nothing has run. Two ways to confirm the plugin is\nwired correctly before you trust it on real work:\n\n```\nnode \"${CLAUDE_PLUGIN_ROOT}/dist/index.js\" doctor --repo .\n```\n\nPrints `OK` / `WARN` / `FAIL` for: git repo present, binary reachable,\nplugin manifest reachable, state file present (and last modified when),\nskill copy in `~/.claude/`. If everything is `OK` or only `WARN`s, the\nplugin is healthy and just hasn't captured anything yet.\n\nTo actually exercise the hook path end-to-end, dispatch the canary\nsubagent the plugin ships:\n\n```\nTask(subagent_type: \"wisp-self-test\",\n     description: \"verify wisp-agentdiff hooks fire\",\n     prompt: \"go\")\n```\n\nIt creates a single-line file inside an isolated worktree. The\n`WorktreeCreate` hook should register it in\n`.claude/wisp-agentdiff-state.json`; `WorktreeRemove` should capture the\ndiff. After it finishes, `/review-agents` will show one agent labelled\n`wisp-self-test` (its real subagent_type, derived from the session\ntranscript) with the single-line file above as its diff. If you see\n\"no subagents recorded\" after the canary runs, the hooks aren't firing —\nopen an issue with the output of `wisp-agentdiff doctor`.\n\n## Use\n\nAfter a Claude Code session has run 2+ subagents:\n\n```bash\nwisp-agentdiff review\n```\n\n— or say *\"review the agents\"* / *\"show me what each agent did\"* in chat\nand the skill triggers it for you, or type `/review-agents`.\n\n### Hotkeys\n\n| Key | Action |\n|-----|--------|\n| `a` | approve active agent (auto-advances) |\n| `r` | revert active agent (auto-advances) |\n| `n` / `p` | next / previous agent |\n| `c` | toggle cross-agent conflict view |\n| `m` | merge all approved agents into HEAD |\n| `j` / `k` | scroll diff |\n| `q` | quit |\n\n### Conflict gating\n\nIf two approved agents touched the same file, the merge step refuses and\nshows you the overlap. You revert one side, then re-press `m`. The tool\nwill not write conflict markers, will not pick a winner, and will not\nhalf-merge then abort — either all approved agents land or none do.\n\n## Pruning\n\nOver many sessions, subagent worktrees and their `wisp-agentdiff/agent-*`\nbranches accumulate because Claude Code persists worktrees until\nsession-end and `WorktreeRemove` rarely fires. Run `wisp-agentdiff prune`\nto garbage-collect orphaned worktrees and branches; pass\n`wisp-agentdiff prune --dry-run` first to preview what would be removed.\nBy default only entries older than `--older-than-hours 168` (one week)\nare considered; pass `--all` to prune every captured wisp-agentdiff\nworktree and branch regardless of age.\n\n## How it works\n\n```\nClaude Code subagent ─► WorktreeCreate hook ─► wisp-agentdiff registers agent\n                                   │\n                                   ▼\n                       isolated git worktree\n                                   │\n                Subagent edits + JSONL transcript captured\n                                   │\n                                   ▼\n            WorktreeRemove hook ─► capture diff, remove worktree\n                                   │\n                                   ▼\n              wisp-agentdiff review ─► tabbed TUI → [m] merges approved\n```\n\nWe hook into Claude Code's native worktree lifecycle rather than wrapping\n`git worktree add` ourselves, so the integration survives upstream Claude\nCode changes and respects `.worktreeinclude`. Full architecture:\n[`docs/architecture.md`](docs/architecture.md).\n\n## Why not tazuna / plural / cwt\n\n`tazuna`, `plural`, and `cwt` are worktree *orchestrators* — they spawn\nisolated sessions but stop at isolation and leave the diff to `git diff`\nby hand. Native Claude Code worktrees give you the isolation primitive\nbut no review surface — cleanup is all-or-nothing.\n`wisp-agentdiff` fills the review step: aggregated TUI, per-agent token\n+ tool-call telemetry, cross-agent conflict detection, single-key\napprove / revert / merge.\n\n## Related — `wisp-orchestrator`\n\nIf you need the *before* of the agent-crew lifecycle — visual team\nbuilder, plan-as-DAG, live execution graph in the browser, hours-long\nautonomous runs — see [**wisp-orchestrator**](https://github.com/Samuel0101010/wisp-orchestrator). Same author, complementary\nworkflow:\n\n| Stage | Tool |\n|------|------|\n| Plan + spawn + watch multi-agent runs | **wisp-orchestrator** |\n| Review + approve + merge the resulting per-agent worktrees | **wisp-agentdiff** *(this repo)* |\n\n## Status \u0026 roadmap\n\nv1.0 ships the core loop. Backlog and open questions live in\n[`docs/roadmap.md`](docs/roadmap.md). Issues and PRs welcome.\n\n## Develop\n\n```bash\nnpm install\nnpm run check          # lint + typecheck + test + build\nnpm run test:watch     # iterating on a single module\nnpm run dev            # tsup watch build\n```\n\nCI matrix: Linux / macOS / Windows × Node 20 + 22.\n\n## License\n\nMIT — see [`LICENSE`](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamuel0101010%2Fwisp-agentdiff","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsamuel0101010%2Fwisp-agentdiff","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamuel0101010%2Fwisp-agentdiff/lists"}