token-pilot 0.35.0 → 0.39.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/README.md +79 -0
- 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/cli/stats.d.ts +2 -0
- package/dist/cli/stats.js +32 -0
- package/dist/cli/typo-guard.d.ts +1 -1
- package/dist/cli/typo-guard.js +2 -0
- package/dist/core/event-log.d.ts +7 -0
- package/dist/core/event-log.js +10 -1
- package/dist/core/workflow.d.ts +117 -0
- package/dist/core/workflow.js +269 -0
- package/dist/hooks/post-task.d.ts +18 -3
- package/dist/hooks/post-task.js +44 -11
- package/dist/hooks/pre-task.d.ts +9 -4
- package/dist/hooks/pre-task.js +23 -8
- package/dist/hooks/session-start.js +61 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +129 -1
- package/package.json +1 -1
- package/skills/guide/SKILL.md +11 -0
- package/skills/install/SKILL.md +10 -0
- package/skills/stats/SKILL.md +8 -0
package/dist/index.js
CHANGED
|
@@ -27,6 +27,7 @@ import { installHook, uninstallHook, cleanStaleHookEntries, isTokenPilotPluginEn
|
|
|
27
27
|
import { runHookEntryPoint } from "./hooks/safe-runner.js";
|
|
28
28
|
import { loadErrors, formatErrorList } from "./core/error-log.js";
|
|
29
29
|
import { appendDiagnostic } from "./core/event-log.js";
|
|
30
|
+
import { startWorkflow, endWorkflow, listWorkflows, workflowStatus, formatWorkflowStatus, formatWorkflowList, } from "./core/workflow.js";
|
|
30
31
|
import { findBinary, installBinary, checkBinaryUpdate, isNewerVersion, } from "./ast-index/binary-manager.js";
|
|
31
32
|
import { loadConfig } from "./config/loader.js";
|
|
32
33
|
import { isDangerousRoot } from "./core/validation.js";
|
|
@@ -229,7 +230,30 @@ export async function main(cliArgs = process.argv.slice(2)) {
|
|
|
229
230
|
/* never block dispatch on telemetry */
|
|
230
231
|
});
|
|
231
232
|
}
|
|
232
|
-
|
|
233
|
+
// v0.38.0 — fleet budget guard. When a workflow is active and
|
|
234
|
+
// its token ceiling is within reach, append a wind-down note
|
|
235
|
+
// to whatever the routing decision produced. The dispatch is
|
|
236
|
+
// never hard-blocked on budget (a half-finished fan-out is
|
|
237
|
+
// worse than a small overrun) — we advise, and surface an
|
|
238
|
+
// over-budget diagnostic so `workflow status` reflects it.
|
|
239
|
+
const { activeWorkflowId, workflowStatus, isWorkflowNearBudget } = await import("./core/workflow.js");
|
|
240
|
+
const wfId = activeWorkflowId();
|
|
241
|
+
let budgetNote = "";
|
|
242
|
+
if (wfId) {
|
|
243
|
+
const st = await workflowStatus(process.cwd(), wfId);
|
|
244
|
+
if (st && isWorkflowNearBudget(st)) {
|
|
245
|
+
budgetNote =
|
|
246
|
+
`\n\n[token-pilot] workflow ${wfId} is at ${st.pct ?? "~"}% of its ` +
|
|
247
|
+
`${st.budget_tokens} token ceiling — finish in-flight work and ` +
|
|
248
|
+
`report rather than starting new branches.`;
|
|
249
|
+
appendDiagnostic(process.cwd(), {
|
|
250
|
+
code: "workflow_near_budget",
|
|
251
|
+
level: "warn",
|
|
252
|
+
detail: { workflow_id: wfId, pct: st.pct, used: st.used_tokens },
|
|
253
|
+
}).catch(() => { });
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
const rendered = renderPreTaskOutput(decision, budgetNote);
|
|
233
257
|
if (rendered)
|
|
234
258
|
process.stdout.write(rendered);
|
|
235
259
|
});
|
|
@@ -348,6 +372,15 @@ export async function main(cliArgs = process.argv.slice(2)) {
|
|
|
348
372
|
process.stdout.write(formatErrorList(records) + "\n");
|
|
349
373
|
return;
|
|
350
374
|
}
|
|
375
|
+
case "workflow": {
|
|
376
|
+
// v0.38.0 — fleet workflow lifecycle. token-pilot owns the
|
|
377
|
+
// workflow boundary (we set TOKEN_PILOT_WORKFLOW_ID ourselves),
|
|
378
|
+
// so this works regardless of whether Claude Code's /workflow
|
|
379
|
+
// propagates an env var. Subcommands: start / end / status / list.
|
|
380
|
+
const code = await handleWorkflowCli(cliArgs.slice(1));
|
|
381
|
+
process.exit(code);
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
351
384
|
case "migrate-hooks": {
|
|
352
385
|
// v0.33.0 — clean stale npx-cache / pinned-version token-pilot
|
|
353
386
|
// hook entries from user-level + project-level settings.json so
|
|
@@ -903,6 +936,101 @@ export function handleHookEdit() {
|
|
|
903
936
|
process.stdout.write(rendered);
|
|
904
937
|
process.exit(0);
|
|
905
938
|
}
|
|
939
|
+
/**
|
|
940
|
+
* v0.38.0 — `token-pilot workflow <subcommand>` CLI.
|
|
941
|
+
*
|
|
942
|
+
* start <goal> [--budget=N] [--max-parallel=N]
|
|
943
|
+
* Create a workflow envelope and print an `export
|
|
944
|
+
* TOKEN_PILOT_WORKFLOW_ID=<id>` line. Wrap a fan-out batch with
|
|
945
|
+
* this so every hook event gets tagged with the id.
|
|
946
|
+
* end [<id>] Stamp the workflow ended (defaults to active env id).
|
|
947
|
+
* status [<id>] Show live budget + task counts (defaults to env id).
|
|
948
|
+
* list All recorded workflows, newest first.
|
|
949
|
+
*
|
|
950
|
+
* Returns a process exit code.
|
|
951
|
+
*/
|
|
952
|
+
export async function handleWorkflowCli(argv) {
|
|
953
|
+
const projectRoot = process.cwd();
|
|
954
|
+
const sub = argv[0];
|
|
955
|
+
const flag = (k) => {
|
|
956
|
+
for (const a of argv) {
|
|
957
|
+
if (a.startsWith(`--${k}=`))
|
|
958
|
+
return a.slice(k.length + 3);
|
|
959
|
+
}
|
|
960
|
+
return undefined;
|
|
961
|
+
};
|
|
962
|
+
const envId = process.env.TOKEN_PILOT_WORKFLOW_ID ||
|
|
963
|
+
process.env.CLAUDE_CODE_WORKFLOW_ID ||
|
|
964
|
+
undefined;
|
|
965
|
+
switch (sub) {
|
|
966
|
+
case "start": {
|
|
967
|
+
const goal = argv.slice(1).filter((a) => !a.startsWith("--")).join(" ");
|
|
968
|
+
if (!goal) {
|
|
969
|
+
process.stderr.write('workflow start: a goal is required — `token-pilot workflow start "review last sprint"`\n');
|
|
970
|
+
return 1;
|
|
971
|
+
}
|
|
972
|
+
const budgetRaw = flag("budget");
|
|
973
|
+
const parallelRaw = flag("max-parallel");
|
|
974
|
+
const env = await startWorkflow({
|
|
975
|
+
projectRoot,
|
|
976
|
+
goal,
|
|
977
|
+
budgetTokens: budgetRaw ? Number(budgetRaw) : null,
|
|
978
|
+
maxParallel: parallelRaw ? Number(parallelRaw) : null,
|
|
979
|
+
});
|
|
980
|
+
// The id goes to stdout as an `export` line so a user can do
|
|
981
|
+
// eval "$(token-pilot workflow start '...')"
|
|
982
|
+
// and have the env var set for the fan-out that follows.
|
|
983
|
+
process.stdout.write(`export TOKEN_PILOT_WORKFLOW_ID=${env.workflow_id}\n`);
|
|
984
|
+
process.stderr.write(`[token-pilot] workflow ${env.workflow_id} started` +
|
|
985
|
+
(env.budget_tokens ? ` · ${env.budget_tokens} token ceiling` : "") +
|
|
986
|
+
`\n`);
|
|
987
|
+
return 0;
|
|
988
|
+
}
|
|
989
|
+
case "end": {
|
|
990
|
+
const id = argv[1] && !argv[1].startsWith("--") ? argv[1] : envId;
|
|
991
|
+
if (!id) {
|
|
992
|
+
process.stderr.write("workflow end: no id given and TOKEN_PILOT_WORKFLOW_ID not set.\n");
|
|
993
|
+
return 1;
|
|
994
|
+
}
|
|
995
|
+
const env = await endWorkflow(projectRoot, id);
|
|
996
|
+
if (!env) {
|
|
997
|
+
process.stderr.write(`workflow end: unknown workflow "${id}".\n`);
|
|
998
|
+
return 1;
|
|
999
|
+
}
|
|
1000
|
+
const status = await workflowStatus(projectRoot, id);
|
|
1001
|
+
if (status)
|
|
1002
|
+
process.stdout.write(formatWorkflowStatus(status) + "\n");
|
|
1003
|
+
process.stderr.write(`[token-pilot] workflow ${id} ended.\n`);
|
|
1004
|
+
return 0;
|
|
1005
|
+
}
|
|
1006
|
+
case "status": {
|
|
1007
|
+
const id = argv[1] && !argv[1].startsWith("--") ? argv[1] : envId;
|
|
1008
|
+
if (!id) {
|
|
1009
|
+
process.stderr.write("workflow status: no id given and TOKEN_PILOT_WORKFLOW_ID not set.\n");
|
|
1010
|
+
return 1;
|
|
1011
|
+
}
|
|
1012
|
+
const status = await workflowStatus(projectRoot, id);
|
|
1013
|
+
if (!status) {
|
|
1014
|
+
process.stderr.write(`workflow status: unknown workflow "${id}".\n`);
|
|
1015
|
+
return 1;
|
|
1016
|
+
}
|
|
1017
|
+
process.stdout.write(formatWorkflowStatus(status) + "\n");
|
|
1018
|
+
return 0;
|
|
1019
|
+
}
|
|
1020
|
+
case "list": {
|
|
1021
|
+
const workflows = await listWorkflows(projectRoot);
|
|
1022
|
+
process.stdout.write(formatWorkflowList(workflows) + "\n");
|
|
1023
|
+
return 0;
|
|
1024
|
+
}
|
|
1025
|
+
default:
|
|
1026
|
+
process.stderr.write("Usage: token-pilot workflow <start|end|status|list>\n" +
|
|
1027
|
+
' start "<goal>" [--budget=N] [--max-parallel=N]\n' +
|
|
1028
|
+
" end [<id>]\n" +
|
|
1029
|
+
" status [<id>]\n" +
|
|
1030
|
+
" list\n");
|
|
1031
|
+
return sub ? 1 : 0;
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
906
1034
|
export async function handleInstallHook(projectRoot) {
|
|
907
1035
|
// v0.26.5 — plugin-aware early-return. If we're running as a Claude
|
|
908
1036
|
// Code plugin (CLAUDE_PLUGIN_ROOT set) the hooks are already declared
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "token-pilot",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.39.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",
|
package/skills/guide/SKILL.md
CHANGED
|
@@ -3,6 +3,17 @@ name: guide
|
|
|
3
3
|
description: Show a quick-reference guide for all Token Pilot tools — when to use each one
|
|
4
4
|
command: guide
|
|
5
5
|
user_invocable: true
|
|
6
|
+
# v0.36.0 — disallowed-tools is a Claude Code 2.1.152+ field that
|
|
7
|
+
# strips the listed tools from the model's surface while this skill
|
|
8
|
+
# is active. The guide just renders Markdown; it never needs Edit /
|
|
9
|
+
# Write / Bash / Task. Defense-in-depth so a runaway model can't
|
|
10
|
+
# mutate the workspace while a help screen is on display.
|
|
11
|
+
disallowed-tools:
|
|
12
|
+
- Bash
|
|
13
|
+
- Edit
|
|
14
|
+
- MultiEdit
|
|
15
|
+
- Write
|
|
16
|
+
- Task
|
|
6
17
|
---
|
|
7
18
|
|
|
8
19
|
Display the following Token Pilot tool reference to the user. Show it exactly as formatted below.
|
package/skills/install/SKILL.md
CHANGED
|
@@ -3,6 +3,16 @@ name: install
|
|
|
3
3
|
description: Install or check ast-index binary (auto-downloads if missing)
|
|
4
4
|
command: install
|
|
5
5
|
user_invocable: true
|
|
6
|
+
# v0.36.0 — disallowed-tools (Claude Code 2.1.152+). The install
|
|
7
|
+
# skill drives one `npx token-pilot install-ast-index` Bash command;
|
|
8
|
+
# nothing else. Keep Bash, block all write/edit/delegation tools so
|
|
9
|
+
# a rogue interpretation can't extend the install into arbitrary
|
|
10
|
+
# workspace mutation.
|
|
11
|
+
disallowed-tools:
|
|
12
|
+
- Edit
|
|
13
|
+
- MultiEdit
|
|
14
|
+
- Write
|
|
15
|
+
- Task
|
|
6
16
|
---
|
|
7
17
|
|
|
8
18
|
Run the following command to install or verify the ast-index binary:
|
package/skills/stats/SKILL.md
CHANGED
|
@@ -3,6 +3,14 @@ name: stats
|
|
|
3
3
|
description: Show Token Pilot session analytics — token savings, per-tool breakdown, top files, per-agent grouping
|
|
4
4
|
command: stats
|
|
5
5
|
user_invocable: true
|
|
6
|
+
# v0.36.0 — disallowed-tools (Claude Code 2.1.152+). stats only reads
|
|
7
|
+
# the events log and runs `token-pilot stats` variants. No
|
|
8
|
+
# Edit/Write/Task ever — block them defensively.
|
|
9
|
+
disallowed-tools:
|
|
10
|
+
- Edit
|
|
11
|
+
- MultiEdit
|
|
12
|
+
- Write
|
|
13
|
+
- Task
|
|
6
14
|
---
|
|
7
15
|
|
|
8
16
|
Two entry points:
|