token-pilot 0.24.2 → 0.26.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/.claude-plugin/marketplace.json +29 -12
  2. package/.claude-plugin/plugin.json +23 -5
  3. package/CHANGELOG.md +179 -0
  4. package/README.md +54 -3
  5. package/dist/agents/tp-api-surface-tracker.md +4 -3
  6. package/dist/agents/tp-audit-scanner.md +1 -1
  7. package/dist/agents/tp-commit-writer.md +1 -1
  8. package/dist/agents/tp-dead-code-finder.md +22 -7
  9. package/dist/agents/tp-debugger.md +1 -1
  10. package/dist/agents/tp-dep-health.md +3 -2
  11. package/dist/agents/tp-history-explorer.md +1 -1
  12. package/dist/agents/tp-impact-analyzer.md +1 -1
  13. package/dist/agents/tp-incident-timeline.md +1 -1
  14. package/dist/agents/tp-migration-scout.md +1 -1
  15. package/dist/agents/tp-onboard.md +1 -1
  16. package/dist/agents/tp-pr-reviewer.md +1 -1
  17. package/dist/agents/tp-refactor-planner.md +1 -1
  18. package/dist/agents/tp-review-impact.md +1 -1
  19. package/dist/agents/tp-run.md +1 -1
  20. package/dist/agents/tp-session-restorer.md +1 -1
  21. package/dist/agents/tp-test-coverage-gapper.md +1 -1
  22. package/dist/agents/tp-test-triage.md +1 -1
  23. package/dist/agents/tp-test-writer.md +1 -1
  24. package/dist/cli/detect-client.d.ts +39 -0
  25. package/dist/cli/detect-client.js +106 -0
  26. package/dist/cli/install-agents.d.ts +1 -0
  27. package/dist/cli/install-agents.js +31 -1
  28. package/dist/cli/tool-audit.d.ts +58 -0
  29. package/dist/cli/tool-audit.js +123 -0
  30. package/dist/cli/typo-guard.d.ts +1 -1
  31. package/dist/cli/typo-guard.js +1 -0
  32. package/dist/core/tool-call-log.d.ts +63 -0
  33. package/dist/core/tool-call-log.js +171 -0
  34. package/dist/handlers/read-symbols.js +23 -1
  35. package/dist/hooks/installer.js +27 -12
  36. package/dist/index.js +71 -0
  37. package/dist/server/profile-recommender.d.ts +48 -0
  38. package/dist/server/profile-recommender.js +102 -0
  39. package/dist/server/token-estimates.d.ts +17 -3
  40. package/dist/server/token-estimates.js +77 -45
  41. package/dist/server/tool-definitions.js +1 -1
  42. package/dist/server/tool-profiles.d.ts +46 -0
  43. package/dist/server/tool-profiles.js +81 -0
  44. package/dist/server.js +38 -1
  45. package/package.json +1 -1
  46. package/start.sh +0 -0
  47. package/.mcp.json +0 -8
@@ -1,15 +1,32 @@
1
1
  {
2
2
  "name": "token-pilot",
3
- "displayName": "Token Pilot",
4
- "description": "Reduces token consumption by 60-80% via AST-aware lazy file reading. 18 MCP tools for structural code reading, symbol navigation, and cross-file search.",
5
- "version": "0.13.0",
6
- "author": "Digital-Threads",
7
- "repository": "https://github.com/Digital-Threads/token-pilot",
8
- "license": "MIT",
9
- "keywords": ["mcp", "token", "ast", "code-reading", "optimization"],
10
- "categories": ["developer-tools", "code-analysis"],
11
- "installMethod": "plugin",
12
- "requirements": {
13
- "node": ">=18.0.0"
14
- }
3
+ "owner": {
4
+ "name": "Digital-Threads",
5
+ "email": "shahinyanm@gmail.com"
6
+ },
7
+ "metadata": {
8
+ "description": "Token Pilot — save 60-90% tokens when AI reads code",
9
+ "version": "0.26.6"
10
+ },
11
+ "plugins": [
12
+ {
13
+ "name": "token-pilot",
14
+ "source": "./",
15
+ "description": "Reduces token consumption by 60-90% via AST-aware lazy file reading, structural symbol navigation, and cross-session tool-usage analytics. 22 MCP tools + 19 subagents + budget watchdog hooks.",
16
+ "version": "0.26.6",
17
+ "author": {
18
+ "name": "Digital-Threads"
19
+ },
20
+ "category": "development",
21
+ "keywords": [
22
+ "mcp",
23
+ "token",
24
+ "ast",
25
+ "code-reading",
26
+ "optimization",
27
+ "context-window",
28
+ "subagents"
29
+ ]
30
+ }
31
+ ]
15
32
  }
@@ -1,9 +1,27 @@
1
1
  {
2
2
  "name": "token-pilot",
3
- "version": "0.24.2",
4
- "description": "Enforcement layer for token-efficient AI coding: MCP-first hook with structural denial summaries, SessionStart reminder, bless-agents CLI, and six tp-* subagents works for every agent including those without MCP access.",
5
- "author": "token-pilot",
3
+ "version": "0.26.6",
4
+ "description": "Saves 60-90% tokens when AI reads code. AST-aware lazy reading, symbol navigation, cross-session tool-usage analytics, 19 subagents with budget watchdog.",
5
+ "author": {
6
+ "name": "Digital-Threads",
7
+ "url": "https://github.com/Digital-Threads"
8
+ },
9
+ "homepage": "https://github.com/Digital-Threads/token-pilot#readme",
10
+ "repository": "https://github.com/Digital-Threads/token-pilot",
6
11
  "license": "MIT",
7
- "skills": "../skills",
8
- "hooks": "./hooks"
12
+ "keywords": [
13
+ "mcp",
14
+ "token",
15
+ "ast",
16
+ "code-reading",
17
+ "context-window",
18
+ "subagents",
19
+ "optimization"
20
+ ],
21
+ "mcpServers": {
22
+ "token-pilot": {
23
+ "command": "sh",
24
+ "args": ["${CLAUDE_PLUGIN_ROOT}/start.sh"]
25
+ }
26
+ }
9
27
  }
package/CHANGELOG.md CHANGED
@@ -5,6 +5,185 @@ All notable changes to Token Pilot will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.26.6] - 2026-04-18
9
+
10
+ ### Fixed — EPIPE stacktrace when piping CLI to `head`/`less`/`grep`
11
+
12
+ First field report after the plugin install worked: user ran
13
+ `npx token-pilot doctor | head -5` and got a red "Unhandled 'error' event"
14
+ stacktrace from node:events. Classic Node.js CLI wart — `console.log`
15
+ tries to write after `head` closed stdin, EPIPE propagates, no handler,
16
+ crash.
17
+
18
+ Fixed by swallowing `EPIPE` on stdout and stderr at process start
19
+ (`process.stdout.on('error', ...)`). Any CLI piped to `head | less | grep`
20
+ should behave this way; ours now does.
21
+
22
+ Confirmed: `node dist/index.js doctor | head -5` returns exit 0 with a
23
+ clean truncated output, no stacktrace.
24
+
25
+ ## [0.26.5] - 2026-04-18
26
+
27
+ ### Fixed — plugin installation path was broken since 2026-03-01
28
+
29
+ Surface: a user asked "can token-pilot be installed as a Claude Code plugin?". The `.claude-plugin/` manifest said yes, but attempting `claude plugin install token-pilot@token-pilot` against our repo failed on schema errors. Root cause: `marketplace.json` and `plugin.json` were written 2026-03-01 for the Claude Code schema as-of-then. The schema has since moved to a `owner`/`plugins`-array shape in `marketplace.json` and `author`-as-object in `plugin.json`, with `mcpServers` declared inside `plugin.json` itself. Our files never caught up. Every user who tried the plugin path for 48 days saw a validation error.
30
+
31
+ Fixed: both manifests rewritten to current shape. Verified end-to-end — `claude plugin marketplace add <path> && claude plugin install token-pilot@token-pilot` now reports ✔ Successfully installed and the MCP server connects green.
32
+
33
+ ### Added — README documents both install paths
34
+
35
+ Until now the README only described npm/npx. With plugin install fixed, the Claude Code section now lays out three paths side-by-side:
36
+ - **A.** `claude plugin install` — hooks + MCP + (optional) tp-* agents in one step.
37
+ - **B.** `claude mcp add -- npx -y token-pilot` — for npm-based setups.
38
+ - **C.** `npx -y token-pilot init` — the one-liner that writes path B for you.
39
+
40
+ ### Changed — plugin-aware CLI behaviour
41
+
42
+ - **`install-hook`** now early-returns with an explanation when `CLAUDE_PLUGIN_ROOT` is set. Plugin installation already wires hooks via `.claude-plugin/hooks/hooks.json`; calling `install-hook` on top would double-register every PreToolUse/PostToolUse matcher. This prevents the silent duplication.
43
+ - **`install-agents`** keeps working under plugin mode (tp-* subagents are independent of plugin hooks — they live in `~/.claude/agents/` regardless) but now prints a one-line note so the user doesn't wonder why a plugin install needs a manual step. New regression test covers the plugin-mode path.
44
+ - **`doctor`** prints a new `Install mode:` line — one of `plugin (<root>)` / `dev / worktree (contributor)` / `npm / npx`. Helps diagnose support issues: "why do I have two hook entries?" → doctor says `plugin` → answer is "remove the manual install-hook run".
45
+
46
+ ### Removed — repo-level `.mcp.json`
47
+
48
+ The file at the repo root was a 2026-03 plugin-compat artifact using `${CLAUDE_PLUGIN_ROOT}/start.sh`. It only resolved correctly when token-pilot ran as a registered plugin — for anyone developing the repo locally (or running the MCP server from a worktree) it just produced `✗ Failed to connect` in `claude mcp list`. With plugin install fixed and the `mcpServers` block moved inside `plugin.json`, the file is no longer needed from either path. Removed.
49
+
50
+ **Note for users migrating npm → plugin:** if you ran `npx token-pilot install-hook` on your old npm setup and then install as a plugin, both will register hooks — every PreToolUse matcher fires twice. Clean the manual entry out of `~/.claude/settings.json` (the one whose `command` starts with `token-pilot hook-read`). The v0.26.5 early-return only prevents *new* duplicates; it doesn't clean old ones.
51
+
52
+ 975 tests still passing (+1 new: plugin-mode regression).
53
+
54
+ ## [0.26.4] - 2026-04-18
55
+
56
+ ### Added — automatic profile recommendation in `doctor`
57
+
58
+ v0.26.3 shipped profiles, but the default stayed `full` — a breaking default change would silently hide tools from anyone who actually uses `code_audit` / `test_summary` / `find_unused`. The correct path: **data-driven advisory, not default flip**.
59
+
60
+ `npx token-pilot doctor` now reads the cumulative `.token-pilot/tool-calls.jsonl` (introduced v0.26.2) and prints a profile recommendation:
61
+
62
+ ```
63
+ ── profile recommendation ──
64
+ data: 30 calls, 1 distinct tools
65
+ recommend: TOKEN_PILOT_PROFILE=nav
66
+ why: Every tool you've used (1 distinct) is part of the nav subset. You're a read-only explorer.
67
+ savings: ~2200 tokens (−54%) on every tools/list response
68
+ apply: add "env": { "TOKEN_PILOT_PROFILE": "nav" } to your token-pilot entry in .mcp.json
69
+ ```
70
+
71
+ Decision matrix (pure, unit-tested):
72
+ - Every call ∈ nav-set → recommend `nav`.
73
+ - Uses edit-prep tools (read_for_edit, batch reads) but never full-only → recommend `edit`.
74
+ - Touches any full-only tool (test_summary, code_audit, find_unused, session_*) → stay on `full`.
75
+ - <20 calls total → insufficient data, say so honestly, tell user to re-run doctor after a few sessions.
76
+
77
+ **Never auto-applies.** Recommendation is printed, not written. Users who haven't read the CHANGELOG learn the lever exists next time they run `doctor`. Gives the narrowest profile that *doesn't silently break their workflow*, because the recommendation is based on their actual usage — not ours.
78
+
79
+ 11 unit tests on the decision matrix + formatter (min-samples boundary, all branches of the matrix, empty-input safety, env-snippet rendering).
80
+
81
+ ## [0.26.3] - 2026-04-18
82
+
83
+ ### Added — tool profiles (lifted honestly from Token Savior's idea)
84
+
85
+ When an MCP server advertises 22 tools, every `tools/list` response costs the agent ~4 k tokens *before it does anything*. Most sessions don't need every tool — a code-review subagent uses `smart_read` + `find_usages` + `outline` and nothing else. A profile lets the operator ship a narrower `tools/list` while keeping every handler live (so a subagent that explicitly names a filtered-out tool still gets served — we just don't brag about every tool upfront).
86
+
87
+ **Three profiles:**
88
+
89
+ | Profile | Tools | ~Tokens in `tools/list` | When to use |
90
+ |---------|------:|------------------------:|-------------|
91
+ | `full` *(default)* | 22 | ~4 150 | All capabilities, same as pre-v0.26.3 |
92
+ | `edit` | 16 | ~3 120 | Code-change workflows (nav + batch reads + read_for_edit) |
93
+ | `nav` | 10 | ~1 910 | Read-only exploration (smart_read, outline, find_usages, project_overview, module_info, related_files, explore_area, smart_log, smart_diff, read_symbol) |
94
+
95
+ **Savings:** `nav` saves ~2.2 k tokens (54 %) at session start; `edit` saves ~1 k (25 %). Every session pays this tax, so it compounds fast across a working day.
96
+
97
+ **Selection:** set `TOKEN_PILOT_PROFILE=nav|edit|full` in the MCP server env block. Unknown values fall back to `full` with a stderr warning.
98
+
99
+ **Containment invariant** (guarded by a unit test): `nav ⊂ edit ⊂ full`. A future tool added to `tool-definitions.ts` without updating a profile set ends up in `full` only — conservative by default, so we never accidentally hide a tool from everyone.
100
+
101
+ 11 unit tests (filter math, containment, unknown-value fallback, case-insensitivity, whitespace).
102
+
103
+ ### Noted for later — context-mode stewardship
104
+
105
+ We currently integrate with [context-mode](https://github.com/mksglu/context-mode) only as a detector + advisor (suggest its `execute` tool when Bash stdout is large). If in a future release we don't deepen that integration, the dependency should be dropped — carrying a soft integration we don't leverage is exactly the kind of "not saving tokens, therefore a problem" the user mandate calls out. Tracked, not actioned this release.
106
+
107
+ ## [0.26.2] - 2026-04-18
108
+
109
+ ### Added — persistent per-tool savings data
110
+
111
+ The user's mandate for Token Pilot is one thing: **"save the maximum number of tokens, all possible ways, no hacks, clean architecture"** — and the corollary, "if a tool doesn't save tokens, or saves poorly, drop it". Executing that mandate responsibly needs **data across many sessions**, not one Opus field report on a Go monorepo.
112
+
113
+ Until v0.26.1 the MCP tool-call analytics lived entirely in memory (`SessionAnalytics`). The moment the MCP server restarted — every session end, every `/clear`, every laptop reboot — the per-tool distribution reset. Decisions about which tools pay off had no real baseline.
114
+
115
+ **1. `src/core/tool-call-log.ts` — append-only JSONL log of every MCP tool call.** Schema matches the in-memory `ToolCall` minus runtime-only fields (intent, decisionTrace). Written from `recordWithTrace` fire-and-forget. Same rotation + retention contract as the existing `hook-events.jsonl` (10 MB rotation, 30-day age cap, 100 MB total size cap). Silent on disk errors — telemetry never blocks the tool-response path. 9 regression tests (roundtrip, JSONL tolerance, cross-session persistence, retention by age, retention by size).
116
+
117
+ **2. `npx token-pilot tool-audit` — CLI that reads every log file + archive and emits a per-tool savings table.** Default human-readable output, `--json` for scripts. Flags a tool as "low-value" when reduction <20% *across ≥5 calls* — the min-samples gate exists so one bad session doesn't get a tool removed. Output is sorted by total tokens saved so your biggest contributor sits on top. 10 unit tests covering aggregation math, sorting, flagging threshold, JSON shape, empty-dataset message.
118
+
119
+ What this unlocks (not in this release, but the foundation is now in place):
120
+ - Real prune decisions: "after 50 sessions, `X` saves <5% on average → remove or restrict".
121
+ - CI savings-regression gate: `tool-audit --fail-below=20` on a baseline.
122
+ - Tool description tuning: compare `smart_read`'s cumulative reduction to `read_symbol` — whichever consistently wins, describe more aggressively.
123
+
124
+ No behavioural change to existing tools — this is strictly observation infrastructure.
125
+
126
+ ## [0.26.1] - 2026-04-18
127
+
128
+ ### Fixed — savings accounting regressions from Opus 4.7 field report
129
+
130
+ The single mandate from the user: **"if a tool doesn't save tokens, or saves poorly, it's a real problem"**. Two tools on Opus 4.7's 19/19 verification reported poor savings that turned out to be accounting/dedupe bugs, not tool failures. Fixing them instead of removing them.
131
+
132
+ **1. `read_symbols` overlap dedupe (15% → 40-60% savings).** The ast-index parser resolves two distinct requested symbols to the same line range on arrow-function exports, Vue SFCs, and type-vs-function ambiguity. Before this fix the handler emitted the body N× — a 4× token blow-up on the field-report file (`nuxt/composables/useCart.ts`). Now the handler keys sections by `startLine:endLine` and emits a short dedupe note instead of repeating the source. Caller still sees which names they asked for; the header advertises the savings (`DEDUPED: N (parser overlap — saved ~N× body tokens)`). Two regression tests.
133
+
134
+ **2. `smart_read` small-file pass-through no longer reports -2% "negative savings".** When `smart_read` returns a file ≤`smallFileThreshold` (200 lines) verbatim with a tiny header, it's not compressing anything — but the recorder was still setting `wouldBe = fullFile`, making the header's 1-2% overhead show up as *negative* savings on `session_analytics`'s Needs-improvement line. New `detectSavingsCategoryPure('none')` branch classifies these calls honestly; server zeroes `wouldBe = returned` → 0% savings claimed, no ghost overhead. Six unit tests on the classifier.
135
+
136
+ ### Not shipped (on purpose)
137
+
138
+ Per advisor guidance, we held off on three things that looked tempting but lack data:
139
+ - **Server-side `find_usages` short-symbol fallback.** We just shipped a description hint in v0.26.0. Measure whether agents follow the hint before writing speculative server code.
140
+ - **Removing any tool based on one session of data.** Opus on a Go monorepo ≠ average usage. Needs persistent per-tool stats across sessions first.
141
+ - **CI savings-regression gate.** Premature without a cumulative baseline.
142
+
143
+ The next iteration will build the persistent `.token-pilot/tool-calls.jsonl` + `npx token-pilot tool-audit` CLI so future prune/fix decisions are data-backed, not anecdotal.
144
+
145
+ ## [0.26.0] - 2026-04-18
146
+
147
+ ### Added — cross-client honesty
148
+
149
+ **1. `install-agents` detects non-Claude clients and skips silently.** Until this release, running `npx token-pilot install-agents` in Cursor / Codex CLI / Gemini CLI / Cline silently created a `~/.claude/agents/` directory that nothing in those clients would ever read. `tp-*` subagents are a Claude Code concept — other clients still benefit from MCP tools + Read hook, but the 19 delegates sit idle. New detector (`src/cli/detect-client.ts`) checks env vars (`CURSOR_TRACE_ID`, `GEMINI_CLI`, `OPENAI_CODEX`, `CLAUDE_PLUGIN_ROOT`) and on-disk markers (`~/.claude/`, `~/.cursor/`, `~/.codex/`, `~/.gemini/`). When a non-Claude client is detected and `--scope` is not passed, install-agents prints a clear warning and exits 0 without touching disk. Explicit `--scope=user|project` overrides (multi-client setups). 10 detector unit tests + 3 integration tests.
150
+
151
+ **2. README: client support matrix.** Honest table showing what works where — MCP tools ✅ everywhere, subagents + `model:` frontmatter + budget watchdog Claude Code only. Non-Claude users get ~60% of the package. Fixes the implicit "works with all clients" promise that was hiding a real gap.
152
+
153
+ ### Improved
154
+
155
+ **3. `tp-dead-code-finder` project-type detection.** Field report showed this agent running 128 `find_usages` iterations over 145s on a Go project — because it defaulted to MCP-based scanning even when native tools (`go vet + deadcode`, `phpstan --level=max`, `vulture`, `ts-prune`) would do the same job in one Bash call. Agent body now instructs the first pass through the right native analyzer based on project markers (`go.mod`, `composer.json`, `pyproject.toml`, `package.json`). `find_unused` is the fallback, not the default. Budget discipline: ≥40 candidates → report top-20 with confidence, not iterate.
156
+
157
+ **4. `find_usages` tool description: Grep hint for short symbols.** Semantic find is great for specific symbol names, but wastes tokens when the symbol is ≤4 chars and generic (`id`, `err`, `Cmd`, `db`) — resolves ambiguously across thousands of files, Grep is cheaper. Description now says so explicitly.
158
+
159
+ ### Deferred to a later epic
160
+
161
+ - **Auto session-snapshot writer on `PreCompact` / `Stop` hook events.** Claude Code does not expose these events to external hooks today — needs either an upstream feature request or a polling alternative. Tracked as research, not shipped.
162
+ - **Cross-client equivalents of `tp-*` subagents.** Cursor Custom Rules (`.cursor/rules/*.mdc`), Gemini `GEMINI.md`, Codex system prompts — can we generate equivalent guidance from our templates? Separate design doc, not v0.26.
163
+
164
+ ## [0.25.0] - 2026-04-18
165
+
166
+ ### Fixed — findings from Opus 4.7 19/19 verification
167
+
168
+ A live verification of all 19 agents on a real Go monorepo surfaced three issues. Fixed together.
169
+
170
+ **1. `install-agents` / installer: PostToolUse idempotence was broken for upgrades.** The check treated the whole PostToolUse section as one unit — *"any token-pilot hook present → skip"*. Users who installed when only the Bash matcher existed (v0.21.x) kept that, never received the Task matcher added in v0.23.0, and their budget watchdog was **silently disabled forever**. 6 out of 19 agents in the field test went over-budget without a single entry in `.token-pilot/over-budget.log` — because the hook wasn't registered at all. Now installer checks each PostToolUse matcher individually (same contract as PreToolUse). Regression test reproduces the v0.21-style settings file and asserts that re-install picks up the Task matcher.
171
+
172
+ **2. `tp-api-surface-tracker` false REMOVED classification.** Field test: `smart_diff` labelled a symbol as REMOVED; `read_symbol` confirmed it was still there (context around it had changed). Agent body now **requires `read_symbol` verification before reporting REMOVED**. Symbols that still exist are reclassified PATCH (body-only change). Prevents false breaking-change alarms in the MAJOR/MINOR/PATCH verdict.
173
+
174
+ **3. `tp-dep-health` over-scans monorepo orchestration roots.** When the root `package.json` has only dev-deps and real services live in gitignored sub-repos or under `services/`/`packages/`/`apps/`, the agent used to scan the whole repo for nothing. Agent now detects this shape and returns a one-line instruction to re-run against a specific sub-repo, instead of iterating find_usages on zero-dep input.
175
+
176
+ ### Deferred to v0.26
177
+
178
+ From the same report, larger changes that need design:
179
+
180
+ - **`tp-dead-code-finder` project-type detection.** 128 `find_usages` iterations in 145 s when `find_unused` is permission-denied in sandbox. Needs Go → `go vet` + `deadcode`, PHP → phpstan, etc. integration.
181
+ - **Auto-invoke `session_snapshot` on Stop / Pre-Compact hook.** `tp-session-restorer` is dead without a paired writer — right now the snapshot file is only created on explicit user call. Needs a hook-type evaluation (Stop hook doesn't exist in Claude Code's current hook set; may need a Pre-Compact substitute).
182
+ - **`find_usages` → Grep fallback for single-word symbols.** 0 % savings observed when symbols are short (structural overview is already longer than the hit list).
183
+
184
+ ### Numbers
185
+ - 912 tests green (+1 regression for installer's per-matcher idempotence), `tsc --noEmit` clean.
186
+
8
187
  ## [0.24.2] - 2026-04-18
9
188
 
10
189
  ### Changed — README manual-install section restored and expanded
package/README.md CHANGED
@@ -44,7 +44,31 @@ This does two things:
44
44
  1. Creates (or merges into) `.mcp.json` with `token-pilot` + [`context-mode`](https://github.com/mksglu/claude-context-mode).
45
45
  2. If you're on a TTY, asks whether to install the `tp-*` subagents now — pick `user` (available in every project) or `project` scope.
46
46
 
47
- Restart your AI assistant to activate. The Read hook auto-installs the first time `token-pilot` starts inside Claude Code. Works with **Claude Code, Cursor, Codex, Antigravity, Cline**, and any MCP-compatible client.
47
+ Restart your AI assistant to activate. The Read hook auto-installs the first time `token-pilot` starts inside Claude Code. Works with **Claude Code, Cursor, Codex, Antigravity, Cline**, and any MCP-compatible client — though support varies (see matrix below).
48
+
49
+ ## Client support matrix
50
+
51
+ Not every capability works in every client. Subagents are a Claude Code concept; other clients still get the MCP tools + Read hook but won't auto-invoke `tp-*` agents.
52
+
53
+ | Client | MCP tools | Read hook (context-mode) | `tp-*` subagents (19) | `model:` frontmatter (haiku) | Budget watchdog |
54
+ |-----------------|:---------:|:------------------------:|:---------------------:|:----------------------------:|:---------------:|
55
+ | Claude Code | ✅ | ✅ | ✅ | ✅ | ✅ |
56
+ | Cursor | ✅ | ✅ | ❌ | ❌ (ignored) | ❌ |
57
+ | Codex CLI | ✅ | ✅ | ❌ | ❌ | ❌ |
58
+ | Gemini CLI | ✅ | ✅ | ❌ | ❌ | ❌ |
59
+ | Cline (VS Code) | ✅ | ✅ | ❌ | ❌ | ❌ |
60
+ | Antigravity | ✅ | ✅ | ❌ | ❌ | ❌ |
61
+
62
+ **What non-Claude users get (~60% of the package):**
63
+ - All 22 MCP tools: `smart_read`, `read_symbol`, `find_usages`, `smart_diff`, `code_audit`, `session_analytics`, etc.
64
+ - The Read hook that blocks oversized reads and suggests token-saving alternatives.
65
+
66
+ **What needs Claude Code to work:**
67
+ - 19 `tp-*` subagents invoked via the `Task` tool.
68
+ - `model: claude-haiku-4-5` frontmatter on format-bound agents (commit-writer, session-restorer, onboard) — cheaper runs.
69
+ - `PostToolUse:Task` budget watchdog — logs agent runs exceeding their declared budget to `.token-pilot/over-budget.log`.
70
+
71
+ `install-agents` detects non-Claude clients via env vars + filesystem markers (`CURSOR_TRACE_ID`, `~/.codex/`, `~/.gemini/`, etc.) and **skips installing** unless you pass `--scope=user|project` explicitly.
48
72
 
49
73
  ## Manual MCP install (per-client examples)
50
74
 
@@ -52,10 +76,20 @@ If `init` isn't right for your setup — CI, non-TTY environments, editing a sha
52
76
 
53
77
  ### Claude Code
54
78
 
55
- Two equivalent paths:
79
+ Three paths — pick one, they're mutually exclusive.
80
+
81
+ **A. As a Claude Code plugin (one-step install — hooks + MCP registered together):**
82
+
83
+ ```bash
84
+ claude plugin marketplace add https://github.com/Digital-Threads/token-pilot
85
+ claude plugin install token-pilot@token-pilot
86
+ ```
87
+
88
+ Claude Code clones the repo into `~/.claude/plugins/cache/token-pilot/`, sets `CLAUDE_PLUGIN_ROOT`, and registers the MCP server + all hooks declared in `.claude-plugin/hooks/hooks.json`. No `install-hook` call needed. `install-agents` still applies for the tp-* subagents (they're separate from plugin hooks).
89
+
90
+ **B. Via MCP config (npm-based, no plugin system):**
56
91
 
57
92
  ```bash
58
- # Via CLI (recommended — handles scope + scoping)
59
93
  claude mcp add token-pilot -- npx -y token-pilot
60
94
  claude mcp add --scope user token-pilot -- npx -y token-pilot
61
95
  claude mcp add --scope project token-pilot -- npx -y token-pilot
@@ -72,6 +106,10 @@ claude mcp add --scope project token-pilot -- npx -y token-pilot
72
106
  }
73
107
  ```
74
108
 
109
+ Then `npx token-pilot install-hook` to register the PreToolUse Read/Edit hooks and `npx token-pilot install-agents --scope=user` to install the 19 tp-* subagents.
110
+
111
+ **C. One-liner `init`:** `npx -y token-pilot init` — writes path B config for you, then prompts about subagents.
112
+
75
113
  ### Cursor
76
114
 
77
115
  Cursor reads `.cursor/mcp.json` (project) or `~/.cursor/mcp.json` (global):
@@ -119,11 +157,22 @@ No env vars required. Optional overrides:
119
157
 
120
158
  | Env var | Default | Purpose |
121
159
  |---|---|---|
160
+ | `TOKEN_PILOT_PROFILE` | `full` | `nav`/`edit`/`full` — trims the advertised `tools/list` payload to save ~2 k tokens per session (see "Tool profiles" below) |
122
161
  | `TOKEN_PILOT_DENY_THRESHOLD` | `300` | Line count above which the Read hook intervenes |
123
162
  | `TOKEN_PILOT_ADAPTIVE_THRESHOLD` | `false` | Enable the adaptive curve as the session burns |
124
163
  | `TOKEN_PILOT_BYPASS` | unset | Set to `1` to disable the Read hook for one session |
125
164
  | `TOKEN_PILOT_SKIP_POSTINSTALL` | unset | Skip the `ast-index` safety-net install at `npm install` time |
126
165
 
166
+ ### Tool profiles
167
+
168
+ | Profile | Tools | ~Tokens | Use when |
169
+ |---------|------:|--------:|----------|
170
+ | `full` *(default)* | 22 | ~4 150 | All capabilities |
171
+ | `edit` | 16 | ~3 120 | Code-change workflows (nav + batch reads + `read_for_edit`) |
172
+ | `nav` | 10 | ~1 910 | Read-only exploration / subagents that only navigate |
173
+
174
+ Set via `TOKEN_PILOT_PROFILE` in your MCP server env block. Handlers stay live regardless — a subagent that explicitly names a filtered-out tool still gets served. The profile only trims what we advertise in `tools/list` at session start.
175
+
127
176
  ### Subagents (Claude Code only)
128
177
 
129
178
  `tp-*` subagents are a Claude Code feature. Other clients use only the MCP tools + Read hook. To install on a target scope explicitly:
@@ -255,6 +304,8 @@ token-pilot install-hook # Install PreToolUse hook
255
304
  token-pilot uninstall-hook
256
305
  token-pilot stats # Totals + top files from hook-events.jsonl
257
306
  token-pilot stats --session[=<id>] | --by-agent
307
+ token-pilot tool-audit # Per-tool savings distribution (cumulative across sessions)
308
+ token-pilot tool-audit --json # Same, machine-readable
258
309
  token-pilot doctor # Diagnostics (ast-index, config, upstream drift)
259
310
  token-pilot install-ast-index # Download ast-index binary (auto on first run)
260
311
  ```
@@ -8,8 +8,8 @@ tools:
8
8
  - mcp__token-pilot__smart_diff
9
9
  - mcp__token-pilot__read_symbol
10
10
  - Bash
11
- token_pilot_version: "0.24.2"
12
- token_pilot_body_hash: 1ab0a379cfa6cf59c908be61c573ba208c0a8c47d7712bc5341c3600dd49ac3c
11
+ token_pilot_version: "0.26.6"
12
+ token_pilot_body_hash: f30fb3378463d6518041650487f1074b5411c6c3d6d7df315d21267f25f812d6
13
13
  ---
14
14
 
15
15
  You are a token-pilot agent (`tp-<name>`). Your defining contract:
@@ -29,7 +29,8 @@ When asked to audit API surface change:
29
29
  1. Find public surface HEAD: `outline` each file named by the project's exports entry (main/module/exports in package.json, or `index.*` / `mod.*`). Collect { name, signature, visibility=public } for every symbol.
30
30
  2. Walk git back to the comparison point (argued by user, else last release tag found via `git describe --tags --abbrev=0`). Use `smart_log --since=<tag>` to scope; `git worktree` or `git show <tag>:<file>` via Bash to reconstruct past outline.
31
31
  3. For each symbol present in only one side:
32
- - Removed **MAJOR** (breaking)
32
+ - **Always verify REMOVED with `read_symbol` on HEAD before reporting.** `smart_diff` can mis-label a symbol as REMOVED when only its surrounding context changed — a short confirmation read prevents false breaking-change alarms. If the symbol is still there, reclassify as PATCH (body-only change).
33
+ - Removed (verified) → **MAJOR** (breaking)
33
34
  - Added → **MINOR** (backward-compatible)
34
35
  4. For symbols present on both sides, `read_symbol` current + `git show <tag>:<file>` past. Compare signatures:
35
36
  - Parameter added without default → **MAJOR**
@@ -10,7 +10,7 @@ tools:
10
10
  - mcp__token-pilot__read_section
11
11
  - Grep
12
12
  - Read
13
- token_pilot_version: "0.24.2"
13
+ token_pilot_version: "0.26.6"
14
14
  token_pilot_body_hash: a740dc6c928d11d7c2c5fbaa953c50b0e35f2abc2dd6e5ef5117bf469a2d0207
15
15
  ---
16
16
 
@@ -8,7 +8,7 @@ tools:
8
8
  - mcp__token-pilot__test_summary
9
9
  - mcp__token-pilot__outline
10
10
  - Bash
11
- token_pilot_version: "0.24.2"
11
+ token_pilot_version: "0.26.6"
12
12
  token_pilot_body_hash: 559a0b61d20974bf33e35bc4c80dcf1b41d10d4df46cf9d05d3d5620713cd46f
13
13
  ---
14
14
 
@@ -1,16 +1,17 @@
1
1
  ---
2
2
  name: tp-dead-code-finder
3
- description: Use this when the user asks to find or remove dead / unused code ("clean up this file", "find unused exports", "pre-release cleanup"). Cross-checks find_unused with Grep, git history, and dynamic-lookup patterns before classifying. Output-only — NEVER deletes code itself.
3
+ description: Use this when the user asks to find or remove dead / unused code ("clean up this file", "find unused exports", "pre-release cleanup"). Picks the fastest per-language analyzer first (go vet/deadcode, phpstan, vulture, ts-prune), falls back to find_unused + find_usages cross-check. Output-only — NEVER deletes code itself.
4
4
  tools:
5
5
  - mcp__token-pilot__find_unused
6
6
  - mcp__token-pilot__find_usages
7
7
  - mcp__token-pilot__smart_log
8
8
  - mcp__token-pilot__outline
9
9
  - mcp__token-pilot__related_files
10
+ - Bash
10
11
  - Grep
11
12
  - Read
12
- token_pilot_version: "0.24.2"
13
- token_pilot_body_hash: 482e33ba566dc75d87753d980267fb2e01763e5924612efd54ec89993b5e12fd
13
+ token_pilot_version: "0.26.6"
14
+ token_pilot_body_hash: 33798b70002a206c4547d08ff46caefe6dbe5a9300f94ab5dad4a57ab5fb4478
14
15
  ---
15
16
 
16
17
  You are a token-pilot agent (`tp-<name>`). Your defining contract:
@@ -25,15 +26,29 @@ Role: safe dead-code detection.
25
26
 
26
27
  Response budget: ~600 tokens.
27
28
 
28
- When asked to find unused code:
29
+ ## Project-type detection (DO THIS FIRST)
29
30
 
30
- 1. Start with `find_unused` treat its output as a candidate list, not a verdict.
31
- 2. For each candidate, re-verify with `find_usages` across the whole repo (including tests/fixtures/docs). Reflection, dynamic imports, string-based routing, DI containers — `find_unused` misses these; Grep the symbol name as a string as a backstop.
31
+ Before touching `find_unused` (which does per-symbol scans and can balloon to 100+ tool calls on large repos), pick the cheapest **native** analyzer for the project. Run ONE detection Bash call:
32
+
33
+ - `go.mod` present → Go. Use `go vet ./...` + `deadcode ./...` (install: `go install golang.org/x/tools/cmd/deadcode@latest`). 1 Bash call instead of N.
34
+ - `composer.json` with `phpstan` dep → PHP. Use `vendor/bin/phpstan analyse --level=max` with `unusedElements: true`.
35
+ - `pyproject.toml` / `requirements.txt` → Python. Try `vulture .` (install: `pip install vulture --user`). Reports unused code with confidence %.
36
+ - `package.json` with TypeScript → TS. Try `npx -y ts-prune` (exports-only) or `knip` if configured (broader).
37
+ - None of the above, or analyzer unavailable → fall back to `find_unused`.
38
+
39
+ If the native analyzer works, use its output as the **candidate list** and still cross-check with `find_usages` / Grep (see below) before promoting to "safe to remove". Native tools have false-positives too (reflection, DI, string-based routing).
40
+
41
+ ## Verification pipeline (always runs)
42
+
43
+ 1. Build candidate list (native analyzer or `find_unused`).
44
+ 2. For each candidate, re-verify with `find_usages` across the whole repo (including tests/fixtures/docs). Reflection, dynamic imports, string-based routing, DI containers — analyzers miss these; Grep the symbol name as a string as a backstop.
32
45
  3. `smart_log` each candidate's file — symbols added within the last 2 weeks are often mid-feature, not dead. Flag, don't delete.
33
46
  4. Group by confidence: **safe to remove** (zero refs, old, no dynamic-lookup risk), **probably safe** (needs human glance), **unsafe** (dynamic-lookup / recent / test-only survivor).
34
47
  5. Deliver: checklist grouped by confidence, each entry as `path:line — symbol — reason for classification`. Do NOT delete anything.
35
48
 
36
- Do NOT delete code in this agent — output the list, let the user act. Do NOT rely on `find_unused` alone for the safe bucket. Confidence threshold: "safe to remove" bucket requires BOTH empty `find_usages` AND empty Grep of the name as a string.
49
+ Do NOT delete code in this agent — output the list, let the user act. Do NOT rely on analyzer output alone for the "safe" bucket. Confidence threshold: "safe to remove" requires ALL of: empty `find_usages`, empty Grep-as-string, file older than 2 weeks.
50
+
51
+ Budget discipline: if the candidate list exceeds 40 items, report the top-20 with highest confidence + one-line summary of the rest. Do not iterate `find_usages` 100+ times.
37
52
 
38
53
  RESPONSE CONTRACT:
39
54
  - Lead with a one-line verdict.
@@ -11,7 +11,7 @@ tools:
11
11
  - mcp__token-pilot__read_for_edit
12
12
  - Read
13
13
  - Bash
14
- token_pilot_version: "0.24.2"
14
+ token_pilot_version: "0.26.6"
15
15
  token_pilot_body_hash: 04864ae0bf0689863d7de9f4c0b44b293087b34098ad2771837e491d37dab953
16
16
  ---
17
17
 
@@ -8,8 +8,8 @@ tools:
8
8
  - mcp__token-pilot__find_unused
9
9
  - Bash
10
10
  - Read
11
- token_pilot_version: "0.24.2"
12
- token_pilot_body_hash: abf5f78b2d55e4611eb1cdde75d604993071f14ac7b5cd6b51ecd5cc1beddc38
11
+ token_pilot_version: "0.26.6"
12
+ token_pilot_body_hash: 6224d989835ea284985b474005b8b46052b7007c4610e661b10658286b5c6624
13
13
  ---
14
14
 
15
15
  You are a token-pilot agent (`tp-<name>`). Your defining contract:
@@ -27,6 +27,7 @@ Response budget: ~600 tokens.
27
27
  When asked to audit dependencies:
28
28
 
29
29
  1. Enumerate deps: `Read package.json` / `pnpm-lock.yaml` / `requirements.txt` / `Gemfile` / `Cargo.toml` — whichever the project uses. One-line summary of counts (prod / dev).
30
+ - **Monorepo orchestration root detection:** if the root manifest has only dev dependencies (or only workspace pointers) AND the real source lives in sub-repos (gitignored or under `services/`, `packages/`, `apps/`), STOP. Return: "This is a monorepo root with no production deps of its own — re-run this agent pointing at `<sub-repo>` via Task(subagent_type=tp-dep-health) per service". Do not scan further.
30
31
  2. Run the native outdated check: `npm outdated --json` (or pip list --outdated, etc.) via Bash. Parse into `{pkg, current, latest, major|minor|patch}`.
31
32
  3. For each outdated package, count actual IMPORTS across source: `find_usages` on the package name (or Grep `from "pkg"` / `require("pkg")` for non-JS). Zero = candidate for removal; many = priority upgrade.
32
33
  4. For high-usage stale deps, `smart_log -- <sample source file>` touching the import to see when the usage last moved — stale dep + stale integration = low risk; stale dep + active integration = urgent.
@@ -9,7 +9,7 @@ tools:
9
9
  - mcp__token-pilot__outline
10
10
  - Bash
11
11
  - Read
12
- token_pilot_version: "0.24.2"
12
+ token_pilot_version: "0.26.6"
13
13
  token_pilot_body_hash: b2daca007e959eaf26bf9a4d92ba36c3aa277a51de4ca4db674833d36acbe11b
14
14
  ---
15
15
 
@@ -11,7 +11,7 @@ tools:
11
11
  - mcp__token-pilot__smart_read_many
12
12
  - mcp__token-pilot__read_symbols
13
13
  - Read
14
- token_pilot_version: "0.24.2"
14
+ token_pilot_version: "0.26.6"
15
15
  token_pilot_body_hash: 0be2620ce0303f912f6b3334f261d169f064970c0d16602fa1e76db4cb2ea441
16
16
  ---
17
17
 
@@ -7,7 +7,7 @@ tools:
7
7
  - mcp__token-pilot__find_usages
8
8
  - mcp__token-pilot__read_symbol
9
9
  - Bash
10
- token_pilot_version: "0.24.2"
10
+ token_pilot_version: "0.26.6"
11
11
  token_pilot_body_hash: 420ffc423c7479a8d4e1b226cf73eb98d6d41388317c74a950d7f3b6240b6786
12
12
  ---
13
13
 
@@ -10,7 +10,7 @@ tools:
10
10
  - mcp__token-pilot__smart_read_many
11
11
  - Grep
12
12
  - Glob
13
- token_pilot_version: "0.24.2"
13
+ token_pilot_version: "0.26.6"
14
14
  token_pilot_body_hash: cf32cdee777430ecc6732db32b3f883a685c8a02b6dc93379d71b15555e79b3e
15
15
  ---
16
16
 
@@ -10,7 +10,7 @@ tools:
10
10
  - mcp__token-pilot__smart_read
11
11
  - mcp__token-pilot__smart_read_many
12
12
  - mcp__token-pilot__read_section
13
- token_pilot_version: "0.24.2"
13
+ token_pilot_version: "0.26.6"
14
14
  token_pilot_body_hash: ae0b86eaffaf34bf283b94b5572481fa8c2d6a2a25193f1173b70bef0fbe1919
15
15
  ---
16
16
 
@@ -10,7 +10,7 @@ tools:
10
10
  - mcp__token-pilot__smart_read_many
11
11
  - mcp__token-pilot__read_for_edit
12
12
  - Read
13
- token_pilot_version: "0.24.2"
13
+ token_pilot_version: "0.26.6"
14
14
  token_pilot_body_hash: eb9fb7f87d9ab61c5b18248a40b283008b5d73414ddb2e3094ff0826e7e463d0
15
15
  ---
16
16
 
@@ -7,7 +7,7 @@ tools:
7
7
  - mcp__token-pilot__read_diff
8
8
  - mcp__token-pilot__outline
9
9
  - mcp__token-pilot__read_symbol
10
- token_pilot_version: "0.24.2"
10
+ token_pilot_version: "0.26.6"
11
11
  token_pilot_body_hash: a058518619fd6e2def0c9226f6c70438a5e0a80efe680c935414ecd7e1b14a4f
12
12
  ---
13
13
 
@@ -8,7 +8,7 @@ tools:
8
8
  - mcp__token-pilot__outline
9
9
  - mcp__token-pilot__module_info
10
10
  - Bash
11
- token_pilot_version: "0.24.2"
11
+ token_pilot_version: "0.26.6"
12
12
  token_pilot_body_hash: 72b635f511492188587d6cb6fd70f936ae34cf5df1f9cd9eff7849cf1231e185
13
13
  ---
14
14
 
@@ -15,7 +15,7 @@ tools:
15
15
  - Grep
16
16
  - Glob
17
17
  - Bash
18
- token_pilot_version: "0.24.2"
18
+ token_pilot_version: "0.26.6"
19
19
  token_pilot_body_hash: d665d57085db38077d0eeab74bda8bdb84c9ad59688495486059af5d3fac67cf
20
20
  ---
21
21
 
@@ -9,7 +9,7 @@ tools:
9
9
  - mcp__token-pilot__session_budget
10
10
  - Bash
11
11
  - Read
12
- token_pilot_version: "0.24.2"
12
+ token_pilot_version: "0.26.6"
13
13
  token_pilot_body_hash: 35b7f333a28c94e7dc89fcc3171703c4b466225f55cd5c701b7592f4f6486440
14
14
  ---
15
15
 
@@ -10,7 +10,7 @@ tools:
10
10
  - mcp__token-pilot__test_summary
11
11
  - Glob
12
12
  - Grep
13
- token_pilot_version: "0.24.2"
13
+ token_pilot_version: "0.26.6"
14
14
  token_pilot_body_hash: cc3d1f46fdb95ac3caf9344f69f1ddcd5ce5a175ee70aa150b7f9fda93edb152
15
15
  ---
16
16
 
@@ -7,7 +7,7 @@ tools:
7
7
  - mcp__token-pilot__read_range
8
8
  - mcp__token-pilot__find_usages
9
9
  - mcp__token-pilot__read_symbol
10
- token_pilot_version: "0.24.2"
10
+ token_pilot_version: "0.26.6"
11
11
  token_pilot_body_hash: 255912c47661d203c8f9a735237bc419f97e937f788a01811bbe126ee3dd5878
12
12
  ---
13
13