token-pilot 0.46.0 → 0.46.1
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.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +26 -0
- package/README.md +1 -1
- package/agents/tp-api-surface-tracker.md +1 -1
- package/agents/tp-audit-scanner.md +1 -1
- package/agents/tp-commit-writer.md +1 -1
- package/agents/tp-context-engineer.md +1 -1
- package/agents/tp-dead-code-finder.md +1 -1
- package/agents/tp-debugger.md +1 -1
- package/agents/tp-dep-health.md +1 -1
- package/agents/tp-doc-writer.md +1 -1
- package/agents/tp-history-explorer.md +1 -1
- package/agents/tp-impact-analyzer.md +1 -1
- package/agents/tp-incident-timeline.md +1 -1
- package/agents/tp-incremental-builder.md +1 -1
- package/agents/tp-migration-scout.md +1 -1
- package/agents/tp-onboard.md +1 -1
- package/agents/tp-performance-profiler.md +1 -1
- package/agents/tp-pr-reviewer.md +1 -1
- package/agents/tp-refactor-planner.md +1 -1
- package/agents/tp-review-impact.md +1 -1
- package/agents/tp-run.md +1 -1
- package/agents/tp-session-restorer.md +1 -1
- package/agents/tp-ship-coordinator.md +1 -1
- package/agents/tp-spec-writer.md +1 -1
- package/agents/tp-test-coverage-gapper.md +1 -1
- package/agents/tp-test-triage.md +1 -1
- package/agents/tp-test-writer.md +1 -1
- package/dist/core/event-log.d.ts +7 -0
- package/dist/core/event-log.js +9 -1
- package/dist/handlers/test-summary.js +42 -0
- package/package.json +4 -4
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Token Pilot — save 60-90% tokens when AI reads code",
|
|
9
|
-
"version": "0.46.
|
|
9
|
+
"version": "0.46.1"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
13
13
|
"name": "token-pilot",
|
|
14
14
|
"source": "./",
|
|
15
15
|
"description": "Reduces token consumption by 60-90% via AST-aware lazy file reading, structural symbol navigation, and cross-session tool-usage analytics. 23 MCP tools + 25 subagents + budget watchdog hooks.",
|
|
16
|
-
"version": "0.46.
|
|
16
|
+
"version": "0.46.1",
|
|
17
17
|
"author": {
|
|
18
18
|
"name": "Digital-Threads"
|
|
19
19
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "token-pilot",
|
|
3
|
-
"version": "0.46.
|
|
3
|
+
"version": "0.46.1",
|
|
4
4
|
"description": "Saves 60-90% tokens on AI code reading. AST-aware lazy reads, symbol navigation, find_usages, structural git diff/log, edit-safety guard, Task-routing matcher, cross-session telemetry (errors + diagnostics), 25 tp-* subagents tiered to haiku/sonnet/opus with budget watchdog.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Digital-Threads",
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,32 @@ 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.46.1] - 2026-06-18
|
|
9
|
+
|
|
10
|
+
### Fixed — node:test (`node --test`) TAP output parsing
|
|
11
|
+
|
|
12
|
+
`test_summary` did not recognise `node --test`: `detectRunner` had no `node`
|
|
13
|
+
case, so node:test output fell through to the generic parser. node:test emits a
|
|
14
|
+
TAP footer (`# pass N` / `# fail N`, number after the word) and `ok N - name`
|
|
15
|
+
points (`ok` before the number), which the generic `<N> passed` regex never
|
|
16
|
+
matches — a green 2/2 run was reported as 0 passed. Added a `node` runner:
|
|
17
|
+
detected by command (`node --test` / `node:test`) or by the TAP footer, parsing
|
|
18
|
+
pass/fail/skipped/tests from the footer with a fallback to counting `ok` /
|
|
19
|
+
`not ok` lines; failure names come from `not ok N - name`. Purely additive — no
|
|
20
|
+
existing parser touched.
|
|
21
|
+
|
|
22
|
+
### Changed — dev-dependency security + decoupled registry publish (no shipped change)
|
|
23
|
+
|
|
24
|
+
- Bump `vitest` / `@vitest/coverage-v8` to 4.x — clears the 6 remaining
|
|
25
|
+
dev-only high advisories in the vitest/vite/esbuild chain. `npm audit` now
|
|
26
|
+
reports **0 vulnerabilities** (dev + prod). No runtime/package change: dev
|
|
27
|
+
deps are not shipped to npm consumers; the full 1402-test suite is green on
|
|
28
|
+
vitest 4.
|
|
29
|
+
- `publish-mcp.yml`: the MCP Registry job no longer hard-depends on npm-job
|
|
30
|
+
**success** (`if: !cancelled()`). A failed npm publish (e.g. EOTP on a
|
|
31
|
+
manual-token release) no longer blocks the registry update; re-run the job
|
|
32
|
+
via `workflow_dispatch` after a manual `npm publish`.
|
|
33
|
+
|
|
8
34
|
## [0.46.0] - 2026-06-13
|
|
9
35
|
|
|
10
36
|
### Added — UserPromptSubmit per-turn reinforcement (caveman-style awareness)
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**Token-efficient AI coding, enforced.** Cuts context consumption in AI coding assistants by up to **90%** without changing the way you work.
|
|
4
4
|
|
|
5
|
-
> **Why it matters more now:** as frontier models move up in price
|
|
5
|
+
> **Why it matters more now:** as frontier models move up in price, the tokens you *don't* spend reading code are worth more, not less. The savings are in tokens; the value is in tokens × price. Token Pilot keeps the expensive main thread lean so the premium model spends its budget on reasoning, not on re-reading files.
|
|
6
6
|
|
|
7
7
|
Three layers, each useful on its own, stronger together:
|
|
8
8
|
|
|
@@ -9,7 +9,7 @@ tools:
|
|
|
9
9
|
- mcp__token-pilot__read_symbol
|
|
10
10
|
- Bash
|
|
11
11
|
model: haiku
|
|
12
|
-
token_pilot_version: "0.46.
|
|
12
|
+
token_pilot_version: "0.46.1"
|
|
13
13
|
token_pilot_body_hash: dd184501203fa7f3c73f419c4ffbe33c4be75400cb64a7a51733a3fe23f6e085
|
|
14
14
|
requiredMcpServers:
|
|
15
15
|
- "token-pilot"
|
|
@@ -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.46.
|
|
11
|
+
token_pilot_version: "0.46.1"
|
|
12
12
|
token_pilot_body_hash: de64a406b5176de19f7422619c7de7949b1f28865f225402c9cea9255f377428
|
|
13
13
|
requiredMcpServers:
|
|
14
14
|
- "token-pilot"
|
package/agents/tp-debugger.md
CHANGED
package/agents/tp-dep-health.md
CHANGED
package/agents/tp-doc-writer.md
CHANGED
|
@@ -12,7 +12,7 @@ tools:
|
|
|
12
12
|
- mcp__token-pilot__read_symbols
|
|
13
13
|
- Read
|
|
14
14
|
model: sonnet
|
|
15
|
-
token_pilot_version: "0.46.
|
|
15
|
+
token_pilot_version: "0.46.1"
|
|
16
16
|
token_pilot_body_hash: 351a987e11eba63852f5431a16d8eb53104f4f689f82fdcc5a2bf4db948ba92f
|
|
17
17
|
requiredMcpServers:
|
|
18
18
|
- "token-pilot"
|
|
@@ -8,7 +8,7 @@ tools:
|
|
|
8
8
|
- mcp__token-pilot__read_symbol
|
|
9
9
|
- Bash
|
|
10
10
|
model: inherit
|
|
11
|
-
token_pilot_version: "0.46.
|
|
11
|
+
token_pilot_version: "0.46.1"
|
|
12
12
|
token_pilot_body_hash: de5722bfea374eaab096c1ae635c37879e7a91370ee3cd0532f4240be03c91eb
|
|
13
13
|
requiredMcpServers:
|
|
14
14
|
- "token-pilot"
|
package/agents/tp-onboard.md
CHANGED
|
@@ -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.46.
|
|
13
|
+
token_pilot_version: "0.46.1"
|
|
14
14
|
token_pilot_body_hash: 832e95633fbc8e9b0c10f3e540a327d4be062fb4b3f17a6cce6be13f414e2927
|
|
15
15
|
requiredMcpServers:
|
|
16
16
|
- "token-pilot"
|
package/agents/tp-pr-reviewer.md
CHANGED
|
@@ -11,7 +11,7 @@ tools:
|
|
|
11
11
|
- mcp__token-pilot__read_for_edit
|
|
12
12
|
- Read
|
|
13
13
|
model: sonnet
|
|
14
|
-
token_pilot_version: "0.46.
|
|
14
|
+
token_pilot_version: "0.46.1"
|
|
15
15
|
token_pilot_body_hash: f83f50d05b4f70285ae7afed2b1a406fc436df56e61a0aedbfb31edc7f2b6e66
|
|
16
16
|
requiredMcpServers:
|
|
17
17
|
- "token-pilot"
|
|
@@ -8,7 +8,7 @@ tools:
|
|
|
8
8
|
- mcp__token-pilot__outline
|
|
9
9
|
- mcp__token-pilot__read_symbol
|
|
10
10
|
model: sonnet
|
|
11
|
-
token_pilot_version: "0.46.
|
|
11
|
+
token_pilot_version: "0.46.1"
|
|
12
12
|
token_pilot_body_hash: c5f6fc122c89e16e5cf774045f92169ee3468555320b898171ba13eca5323550
|
|
13
13
|
requiredMcpServers:
|
|
14
14
|
- "token-pilot"
|
|
@@ -9,7 +9,7 @@ tools:
|
|
|
9
9
|
- mcp__token-pilot__module_info
|
|
10
10
|
- Bash
|
|
11
11
|
model: sonnet
|
|
12
|
-
token_pilot_version: "0.46.
|
|
12
|
+
token_pilot_version: "0.46.1"
|
|
13
13
|
token_pilot_body_hash: 8ef3c3341cbfed4eb8dd130126a9683edc57e378c92ff0ca764d584fd941c55c
|
|
14
14
|
requiredMcpServers:
|
|
15
15
|
- "token-pilot"
|
package/agents/tp-run.md
CHANGED
package/agents/tp-spec-writer.md
CHANGED
|
@@ -10,7 +10,7 @@ tools:
|
|
|
10
10
|
- mcp__token-pilot__test_summary
|
|
11
11
|
- Glob
|
|
12
12
|
- Grep
|
|
13
|
-
token_pilot_version: "0.46.
|
|
13
|
+
token_pilot_version: "0.46.1"
|
|
14
14
|
token_pilot_body_hash: be81eed53a3720d146cf89e4a14a7a56577633f7c84c234c412ab70d64c05b11
|
|
15
15
|
requiredMcpServers:
|
|
16
16
|
- "token-pilot"
|
package/agents/tp-test-triage.md
CHANGED
|
@@ -8,7 +8,7 @@ tools:
|
|
|
8
8
|
- mcp__token-pilot__find_usages
|
|
9
9
|
- mcp__token-pilot__read_symbol
|
|
10
10
|
model: sonnet
|
|
11
|
-
token_pilot_version: "0.46.
|
|
11
|
+
token_pilot_version: "0.46.1"
|
|
12
12
|
token_pilot_body_hash: 362ecf4cb03b059421ea26933473700900073dc38b3a7fe271208dfb1ae14f90
|
|
13
13
|
requiredMcpServers:
|
|
14
14
|
- "token-pilot"
|
package/agents/tp-test-writer.md
CHANGED
package/dist/core/event-log.d.ts
CHANGED
|
@@ -56,6 +56,13 @@ export interface HookEvent {
|
|
|
56
56
|
* Optional — absent when no workflow is active.
|
|
57
57
|
*/
|
|
58
58
|
workflow_id?: string;
|
|
59
|
+
/**
|
|
60
|
+
* Loom spine link — id of the Loom task this event belongs to, when the
|
|
61
|
+
* session was launched by Loom (LOOM_TASK_ID set). Lets Loom attribute token
|
|
62
|
+
* savings to a task exactly. Optional — absent outside Loom, so standalone
|
|
63
|
+
* token-pilot events stay byte-identical to before.
|
|
64
|
+
*/
|
|
65
|
+
task_id?: string;
|
|
59
66
|
event: "denied" | "allowed" | "bypass" | "pass-through" | "task" | "diagnostic" | string;
|
|
60
67
|
file: string;
|
|
61
68
|
lines: number;
|
package/dist/core/event-log.js
CHANGED
|
@@ -115,8 +115,16 @@ export async function appendEvent(projectRoot, event) {
|
|
|
115
115
|
const wf = event.workflow_id ??
|
|
116
116
|
process.env.TOKEN_PILOT_WORKFLOW_ID ??
|
|
117
117
|
process.env.CLAUDE_CODE_WORKFLOW_ID ??
|
|
118
|
+
process.env.LOOM_WORKFLOW_ID ??
|
|
118
119
|
undefined;
|
|
119
|
-
|
|
120
|
+
// Loom spine: tag the task id when the session was launched by Loom.
|
|
121
|
+
// Env-driven so call sites stay unchanged; absent outside Loom → no field.
|
|
122
|
+
const taskId = event.task_id ?? process.env.LOOM_TASK_ID ?? undefined;
|
|
123
|
+
let tagged = event;
|
|
124
|
+
if (wf)
|
|
125
|
+
tagged = { ...tagged, workflow_id: wf };
|
|
126
|
+
if (taskId)
|
|
127
|
+
tagged = { ...tagged, task_id: taskId };
|
|
120
128
|
await ensureLogDir(projectRoot);
|
|
121
129
|
await rotateIfNeeded(projectRoot);
|
|
122
130
|
const line = JSON.stringify(tagged) + "\n";
|
|
@@ -73,6 +73,8 @@ export function detectRunner(command, output) {
|
|
|
73
73
|
return 'rspec';
|
|
74
74
|
if (cmd.includes('mocha'))
|
|
75
75
|
return 'mocha';
|
|
76
|
+
if (cmd.includes('node --test') || cmd.includes('node:test'))
|
|
77
|
+
return 'node';
|
|
76
78
|
// Detect from output
|
|
77
79
|
const lower = output.toLowerCase();
|
|
78
80
|
if (lower.includes('vitest') || lower.includes('vite'))
|
|
@@ -85,6 +87,9 @@ export function detectRunner(command, output) {
|
|
|
85
87
|
return 'phpunit';
|
|
86
88
|
if (lower.includes('--- fail:') || lower.includes('--- pass:') || lower.includes('ok \t'))
|
|
87
89
|
return 'go';
|
|
90
|
+
// node:test prints a TAP summary footer: "# tests N" + "# pass N" + "# fail N".
|
|
91
|
+
if (/^#\s*tests\s+\d+/m.test(output) && /^#\s*pass\s+\d+/m.test(output))
|
|
92
|
+
return 'node';
|
|
88
93
|
return 'generic';
|
|
89
94
|
}
|
|
90
95
|
// ──────────────────────────────────────────────
|
|
@@ -103,6 +108,8 @@ export function parseTestOutput(output, runner) {
|
|
|
103
108
|
return parseGoTest(output);
|
|
104
109
|
case 'cargo':
|
|
105
110
|
return parseCargoTest(output);
|
|
111
|
+
case 'node':
|
|
112
|
+
return parseNodeTest(output);
|
|
106
113
|
default:
|
|
107
114
|
return parseGeneric(output);
|
|
108
115
|
}
|
|
@@ -243,6 +250,41 @@ function parseGoTest(output) {
|
|
|
243
250
|
}
|
|
244
251
|
return result;
|
|
245
252
|
}
|
|
253
|
+
function parseNodeTest(output) {
|
|
254
|
+
const result = { total: 0, passed: 0, failed: 0, skipped: 0, failures: [] };
|
|
255
|
+
// node:test (`node --test`) prints a TAP summary footer:
|
|
256
|
+
// # tests 2
|
|
257
|
+
// # pass 2
|
|
258
|
+
// # fail 0
|
|
259
|
+
// # skipped 0
|
|
260
|
+
const num = (re) => {
|
|
261
|
+
const m = output.match(re);
|
|
262
|
+
return m ? parseInt(m[1], 10) : null;
|
|
263
|
+
};
|
|
264
|
+
const pass = num(/^#\s*pass\s+(\d+)/m);
|
|
265
|
+
const fail = num(/^#\s*fail\s+(\d+)/m);
|
|
266
|
+
const skip = num(/^#\s*skipped\s+(\d+)/m);
|
|
267
|
+
const tests = num(/^#\s*tests\s+(\d+)/m);
|
|
268
|
+
if (pass !== null || fail !== null) {
|
|
269
|
+
result.passed = pass ?? 0;
|
|
270
|
+
result.failed = fail ?? 0;
|
|
271
|
+
result.skipped = skip ?? 0;
|
|
272
|
+
result.total = tests ?? result.passed + result.failed + result.skipped;
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
// No footer (truncated output) — count the TAP point lines instead.
|
|
276
|
+
result.passed = (output.match(/^ok\s+\d+/gm) ?? []).length;
|
|
277
|
+
result.failed = (output.match(/^not ok\s+\d+/gm) ?? []).length;
|
|
278
|
+
result.total = result.passed + result.failed + result.skipped;
|
|
279
|
+
}
|
|
280
|
+
// Failure names come from the TAP point: "not ok 3 - the test name".
|
|
281
|
+
const failPattern = /^not ok\s+\d+\s*-\s*(.+)$/gm;
|
|
282
|
+
let match;
|
|
283
|
+
while ((match = failPattern.exec(output)) !== null) {
|
|
284
|
+
result.failures.push({ name: match[1].trim(), error: '' });
|
|
285
|
+
}
|
|
286
|
+
return result;
|
|
287
|
+
}
|
|
246
288
|
function parseCargoTest(output) {
|
|
247
289
|
const result = { total: 0, passed: 0, failed: 0, skipped: 0, failures: [] };
|
|
248
290
|
// test result: ok. 5 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "token-pilot",
|
|
3
|
-
"version": "0.46.
|
|
3
|
+
"version": "0.46.1",
|
|
4
4
|
"description": "Save up to 80% tokens when AI reads code — MCP server for token-efficient code navigation, AST-aware structural reading instead of dumping full files into context window",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -67,15 +67,15 @@
|
|
|
67
67
|
"mcpName": "io.github.Digital-Threads/token-pilot",
|
|
68
68
|
"license": "MIT",
|
|
69
69
|
"dependencies": {
|
|
70
|
-
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
71
70
|
"@ast-index/cli": "^3.44.0",
|
|
71
|
+
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
72
72
|
"chokidar": "^4.0.3"
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
|
-
"@vitest/coverage-v8": "^3.2.4",
|
|
76
75
|
"@types/node": "^22.0.0",
|
|
76
|
+
"@vitest/coverage-v8": "^4.1.8",
|
|
77
77
|
"typescript": "^5.7.0",
|
|
78
|
-
"vitest": "^
|
|
78
|
+
"vitest": "^4.1.8"
|
|
79
79
|
},
|
|
80
80
|
"engines": {
|
|
81
81
|
"node": ">=18.0.0"
|