token-goat 2.9.28 → 2.9.29

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 (77) hide show
  1. package/README.md +2 -0
  2. package/dist/{token-goat-chunk-OZRSREKR.mjs → token-goat-chunk-2AWQ2R5X.mjs} +2 -2
  3. package/dist/{token-goat-chunk-5NNYIUGV.mjs → token-goat-chunk-2NNUA2LR.mjs} +4 -4
  4. package/dist/{token-goat-chunk-4RN64ZND.mjs → token-goat-chunk-2WOUYWLM.mjs} +2 -1
  5. package/dist/{token-goat-chunk-HUDC5GS5.mjs → token-goat-chunk-435UQTKD.mjs} +5 -3
  6. package/dist/{token-goat-chunk-6DQNNFJ6.mjs → token-goat-chunk-44BM7DDQ.mjs} +3 -3
  7. package/dist/{token-goat-chunk-4JMWPWCS.mjs → token-goat-chunk-52NSDWYY.mjs} +2 -2
  8. package/dist/{token-goat-chunk-IHKZ3QNA.mjs → token-goat-chunk-67BNIKKO.mjs} +19 -16
  9. package/dist/{token-goat-chunk-XBESNWEX.mjs → token-goat-chunk-6AK46ZT7.mjs} +2 -3
  10. package/dist/{token-goat-chunk-M56BWPBN.mjs → token-goat-chunk-7CPMDFGB.mjs} +166 -40
  11. package/dist/token-goat-chunk-ASLWOQ3I.mjs +14 -0
  12. package/dist/{token-goat-chunk-QM76S6YS.mjs → token-goat-chunk-BGYOZ6DO.mjs} +6 -4
  13. package/dist/{token-goat-chunk-JXK2HQXS.mjs → token-goat-chunk-C5YPNZKQ.mjs} +3 -3
  14. package/dist/{token-goat-chunk-MVSWBNMD.mjs → token-goat-chunk-CIQ2FTY3.mjs} +19 -14
  15. package/dist/{token-goat-chunk-BJBRGPBX.mjs → token-goat-chunk-D4ETHJD6.mjs} +6 -4
  16. package/dist/{token-goat-chunk-VE27HPIF.mjs → token-goat-chunk-DNRPXHYH.mjs} +21 -17
  17. package/dist/{token-goat-chunk-YWSP6IU7.mjs → token-goat-chunk-DNSPXQXQ.mjs} +2 -2
  18. package/dist/token-goat-chunk-DPNLUJWB.mjs +220 -0
  19. package/dist/{token-goat-chunk-I7CB3X4K.mjs → token-goat-chunk-E4ZOJIZK.mjs} +10 -7
  20. package/dist/{token-goat-chunk-IZXKVT4A.mjs → token-goat-chunk-E5TK5DNO.mjs} +11 -4
  21. package/dist/{token-goat-chunk-MMLMALWK.mjs → token-goat-chunk-EUSDXRXU.mjs} +60 -12
  22. package/dist/{token-goat-chunk-7R2XYKC5.mjs → token-goat-chunk-FTP4U4QA.mjs} +12 -9
  23. package/dist/{token-goat-chunk-LEG3JNJ6.mjs → token-goat-chunk-G23DWHV4.mjs} +17 -14
  24. package/dist/{token-goat-chunk-L7SDVGBT.mjs → token-goat-chunk-G7IWXCFF.mjs} +49 -23
  25. package/dist/{token-goat-chunk-NILVK7XM.mjs → token-goat-chunk-GLXRTTLE.mjs} +7 -5
  26. package/dist/{token-goat-chunk-6CCQDAYY.mjs → token-goat-chunk-H5J3C56Q.mjs} +35 -16
  27. package/dist/{token-goat-chunk-Q4S3UQGO.mjs → token-goat-chunk-HNFZZHFW.mjs} +2 -2
  28. package/dist/{token-goat-chunk-CBMY2FGI.mjs → token-goat-chunk-HUYUHODZ.mjs} +572 -230
  29. package/dist/token-goat-chunk-IVE6U7KV.mjs +53 -0
  30. package/dist/{token-goat-chunk-F7QZRIWM.mjs → token-goat-chunk-IVWI2OCK.mjs} +8 -30
  31. package/dist/{token-goat-chunk-GMOUBOX4.mjs → token-goat-chunk-JTKCQMQA.mjs} +37 -5
  32. package/dist/{token-goat-chunk-6SGLIPQB.mjs → token-goat-chunk-KOPIR3KZ.mjs} +12 -9
  33. package/dist/token-goat-chunk-L7H3U27L.mjs +35 -0
  34. package/dist/{token-goat-chunk-FSTWAOW6.mjs → token-goat-chunk-LZNBQTDK.mjs} +6 -4
  35. package/dist/token-goat-chunk-MELOKFDJ.mjs +199 -0
  36. package/dist/{token-goat-chunk-VWZKZPSR.mjs → token-goat-chunk-NMBWLRHW.mjs} +76 -39
  37. package/dist/{token-goat-chunk-HXNAC4ZF.mjs → token-goat-chunk-O6I2XU4P.mjs} +12 -10
  38. package/dist/{token-goat-chunk-MAMQPC43.mjs → token-goat-chunk-ONXH6NZ5.mjs} +1 -1
  39. package/dist/token-goat-chunk-ORNFMIER.mjs +295 -0
  40. package/dist/{token-goat-chunk-66LODAUT.mjs → token-goat-chunk-PGTH2U4C.mjs} +1 -1
  41. package/dist/{token-goat-chunk-SJEKA7Y2.mjs → token-goat-chunk-PKRWMHVP.mjs} +76 -64
  42. package/dist/{token-goat-chunk-DA43OE7L.mjs → token-goat-chunk-PQ53BSCF.mjs} +1 -1
  43. package/dist/{token-goat-chunk-RSS3TLXU.mjs → token-goat-chunk-PYSUADX4.mjs} +2 -2
  44. package/dist/{token-goat-chunk-EL7M26WP.mjs → token-goat-chunk-QO3LXVVR.mjs} +185 -104
  45. package/dist/{token-goat-chunk-XI2VFAV6.mjs → token-goat-chunk-RLP6J7WR.mjs} +6 -6
  46. package/dist/token-goat-chunk-RQGGMPCR.mjs +205 -0
  47. package/dist/{token-goat-chunk-6Z5ULNE5.mjs → token-goat-chunk-RTMVLHWX.mjs} +165 -60
  48. package/dist/{token-goat-chunk-E3K3BTEQ.mjs → token-goat-chunk-S4VSXURL.mjs} +8 -6
  49. package/dist/{token-goat-chunk-LKSXAMJB.mjs → token-goat-chunk-SE6E4BKJ.mjs} +1 -1
  50. package/dist/token-goat-chunk-TCQANXYC.mjs +351 -0
  51. package/dist/{token-goat-chunk-GGLEE35R.mjs → token-goat-chunk-TDUT2CL6.mjs} +7 -7
  52. package/dist/{token-goat-chunk-CC2PYJM7.mjs → token-goat-chunk-TGOXNAHW.mjs} +54 -112
  53. package/dist/{token-goat-chunk-XKY4VKJ4.mjs → token-goat-chunk-UA5BKWWQ.mjs} +1 -1
  54. package/dist/{token-goat-chunk-UBUKHVYW.mjs → token-goat-chunk-UXSXQQIY.mjs} +1 -1
  55. package/dist/{token-goat-chunk-D5ICEPSB.mjs → token-goat-chunk-VMFWNHGR.mjs} +79 -68
  56. package/dist/token-goat-chunk-VQ6F6T7X.mjs +36 -0
  57. package/dist/{token-goat-chunk-4STDIGYC.mjs → token-goat-chunk-VZQEWRVH.mjs} +6 -4
  58. package/dist/{token-goat-chunk-OSUFN2FV.mjs → token-goat-chunk-XB5KKOCG.mjs} +5 -25
  59. package/dist/{token-goat-chunk-L45ZQRT7.mjs → token-goat-chunk-XYWPOSCN.mjs} +57 -615
  60. package/dist/{token-goat-chunk-4JJBFT7V.mjs → token-goat-chunk-YAGLESS3.mjs} +8 -5
  61. package/dist/token-goat-chunk-YKSRAWUU.mjs +33 -0
  62. package/dist/{token-goat-chunk-F2ARFHLJ.mjs → token-goat-chunk-YOOVFPTP.mjs} +2 -2
  63. package/dist/{token-goat-chunk-EEIDFMEM.mjs → token-goat-chunk-YZAAZU2S.mjs} +12 -3
  64. package/dist/token-goat-chunk-Z6KBMOBI.mjs +53 -0
  65. package/dist/{token-goat-chunk-RJH64KQH.mjs → token-goat-chunk-ZER6EAXZ.mjs} +3 -3
  66. package/dist/token-goat-hook-client.cjs +475 -0
  67. package/dist/token-goat-hook-client.mjs +26 -0
  68. package/dist/token-goat-hook.mjs +31 -27
  69. package/dist/token-goat.core.mjs +9 -44
  70. package/docs/C4_RUNTIME_ARCHITECTURE.md +2 -2
  71. package/docs/cli.md +3 -2
  72. package/docs/install.md +16 -14
  73. package/package.json +1 -1
  74. package/dist/token-goat-chunk-7MAFDRVR.mjs +0 -47
  75. package/dist/token-goat-chunk-BCN2YQC6.mjs +0 -32
  76. package/dist/token-goat-chunk-D7GHQKQD.mjs +0 -30
  77. package/dist/token-goat-chunk-IFORDBGC.mjs +0 -192
@@ -2,36 +2,40 @@ import { createRequire as __cjsRequire } from 'node:module';
2
2
  const require = __cjsRequire(import.meta.url);
3
3
  import {
4
4
  relayInProcess
5
- } from "./token-goat-chunk-EL7M26WP.mjs";
6
- import "./token-goat-chunk-F7QZRIWM.mjs";
7
- import "./token-goat-chunk-I7CB3X4K.mjs";
8
- import "./token-goat-chunk-VE27HPIF.mjs";
9
- import "./token-goat-chunk-6Z5ULNE5.mjs";
10
- import "./token-goat-chunk-IZXKVT4A.mjs";
11
- import "./token-goat-chunk-RJH64KQH.mjs";
12
- import "./token-goat-chunk-6DQNNFJ6.mjs";
13
- import "./token-goat-chunk-MMLMALWK.mjs";
14
- import "./token-goat-chunk-L7SDVGBT.mjs";
15
- import "./token-goat-chunk-6CCQDAYY.mjs";
16
- import "./token-goat-chunk-GGLEE35R.mjs";
17
- import "./token-goat-chunk-MAMQPC43.mjs";
18
- import "./token-goat-chunk-HXNAC4ZF.mjs";
19
- import "./token-goat-chunk-BJBRGPBX.mjs";
20
- import "./token-goat-chunk-4JMWPWCS.mjs";
21
- import "./token-goat-chunk-4RN64ZND.mjs";
22
- import "./token-goat-chunk-MVSWBNMD.mjs";
5
+ } from "./token-goat-chunk-QO3LXVVR.mjs";
6
+ import "./token-goat-chunk-IVWI2OCK.mjs";
7
+ import "./token-goat-chunk-DNRPXHYH.mjs";
8
+ import "./token-goat-chunk-RTMVLHWX.mjs";
9
+ import "./token-goat-chunk-L7H3U27L.mjs";
10
+ import "./token-goat-chunk-RRNZMM3A.mjs";
11
+ import "./token-goat-chunk-E4ZOJIZK.mjs";
12
+ import "./token-goat-chunk-E5TK5DNO.mjs";
13
+ import "./token-goat-chunk-ZER6EAXZ.mjs";
14
+ import "./token-goat-chunk-44BM7DDQ.mjs";
15
+ import "./token-goat-chunk-EUSDXRXU.mjs";
16
+ import "./token-goat-chunk-G7IWXCFF.mjs";
17
+ import "./token-goat-chunk-H5J3C56Q.mjs";
18
+ import "./token-goat-chunk-TDUT2CL6.mjs";
19
+ import "./token-goat-chunk-ONXH6NZ5.mjs";
20
+ import "./token-goat-chunk-O6I2XU4P.mjs";
21
+ import "./token-goat-chunk-D4ETHJD6.mjs";
22
+ import "./token-goat-chunk-52NSDWYY.mjs";
23
+ import "./token-goat-chunk-2WOUYWLM.mjs";
24
+ import "./token-goat-chunk-CIQ2FTY3.mjs";
23
25
  import "./token-goat-chunk-3BTK54F3.mjs";
24
- import "./token-goat-chunk-D5ICEPSB.mjs";
25
- import "./token-goat-chunk-HUDC5GS5.mjs";
26
- import "./token-goat-chunk-M56BWPBN.mjs";
27
- import "./token-goat-chunk-CC2PYJM7.mjs";
28
- import "./token-goat-chunk-EEIDFMEM.mjs";
29
- import "./token-goat-chunk-OSUFN2FV.mjs";
30
- import "./token-goat-chunk-L45ZQRT7.mjs";
26
+ import "./token-goat-chunk-VMFWNHGR.mjs";
27
+ import "./token-goat-chunk-435UQTKD.mjs";
28
+ import "./token-goat-chunk-7CPMDFGB.mjs";
29
+ import "./token-goat-chunk-TGOXNAHW.mjs";
30
+ import "./token-goat-chunk-XB5KKOCG.mjs";
31
+ import "./token-goat-chunk-YZAAZU2S.mjs";
32
+ import "./token-goat-chunk-IVE6U7KV.mjs";
33
+ import "./token-goat-chunk-XYWPOSCN.mjs";
34
+ import "./token-goat-chunk-TCQANXYC.mjs";
31
35
  import "./token-goat-chunk-NMTKNYGF.mjs";
36
+ import "./token-goat-chunk-MELOKFDJ.mjs";
32
37
  import "./token-goat-chunk-Y4AFKTHK.mjs";
33
- import "./token-goat-chunk-GMOUBOX4.mjs";
34
- import "./token-goat-chunk-RRNZMM3A.mjs";
38
+ import "./token-goat-chunk-JTKCQMQA.mjs";
35
39
  import {
36
40
  init_define_import_meta_env
37
41
  } from "./token-goat-chunk-A37V4PBF.mjs";
@@ -1,52 +1,15 @@
1
1
  import { createRequire as __cjsRequire } from 'node:module';
2
2
  const require = __cjsRequire(import.meta.url);
3
3
  import {
4
- run
5
- } from "./token-goat-chunk-CBMY2FGI.mjs";
6
- import "./token-goat-chunk-VWZKZPSR.mjs";
7
- import "./token-goat-chunk-4STDIGYC.mjs";
8
- import "./token-goat-chunk-5NNYIUGV.mjs";
9
- import "./token-goat-chunk-DA43OE7L.mjs";
10
- import "./token-goat-chunk-JXK2HQXS.mjs";
11
- import "./token-goat-chunk-XI2VFAV6.mjs";
12
- import "./token-goat-chunk-VE27HPIF.mjs";
13
- import "./token-goat-chunk-6Z5ULNE5.mjs";
14
- import "./token-goat-chunk-IZXKVT4A.mjs";
15
- import "./token-goat-chunk-RJH64KQH.mjs";
16
- import "./token-goat-chunk-6DQNNFJ6.mjs";
17
- import "./token-goat-chunk-MMLMALWK.mjs";
18
- import "./token-goat-chunk-L7SDVGBT.mjs";
19
- import "./token-goat-chunk-6CCQDAYY.mjs";
20
- import "./token-goat-chunk-GGLEE35R.mjs";
21
- import "./token-goat-chunk-MAMQPC43.mjs";
22
- import "./token-goat-chunk-HXNAC4ZF.mjs";
23
- import "./token-goat-chunk-BJBRGPBX.mjs";
24
- import "./token-goat-chunk-4JMWPWCS.mjs";
25
- import "./token-goat-chunk-4RN64ZND.mjs";
26
- import "./token-goat-chunk-MVSWBNMD.mjs";
27
- import "./token-goat-chunk-LKSXAMJB.mjs";
28
- import "./token-goat-chunk-XKY4VKJ4.mjs";
29
- import "./token-goat-chunk-Q4S3UQGO.mjs";
30
- import "./token-goat-chunk-RSS3TLXU.mjs";
31
- import "./token-goat-chunk-YWSP6IU7.mjs";
32
- import "./token-goat-chunk-3BTK54F3.mjs";
33
- import "./token-goat-chunk-UBUKHVYW.mjs";
34
- import "./token-goat-chunk-XTQAOTSO.mjs";
35
- import "./token-goat-chunk-AH6QILZM.mjs";
36
- import "./token-goat-chunk-66LODAUT.mjs";
37
- import "./token-goat-chunk-D5ICEPSB.mjs";
38
- import "./token-goat-chunk-HUDC5GS5.mjs";
39
- import "./token-goat-chunk-M56BWPBN.mjs";
40
- import "./token-goat-chunk-CC2PYJM7.mjs";
41
- import "./token-goat-chunk-EEIDFMEM.mjs";
42
- import "./token-goat-chunk-OSUFN2FV.mjs";
4
+ runCliViaServer
5
+ } from "./token-goat-chunk-RQGGMPCR.mjs";
6
+ import "./token-goat-chunk-DPNLUJWB.mjs";
7
+ import "./token-goat-chunk-IVE6U7KV.mjs";
43
8
  import {
44
9
  installEpipeGuard
45
- } from "./token-goat-chunk-L45ZQRT7.mjs";
10
+ } from "./token-goat-chunk-TCQANXYC.mjs";
46
11
  import "./token-goat-chunk-NMTKNYGF.mjs";
47
- import "./token-goat-chunk-Y4AFKTHK.mjs";
48
- import "./token-goat-chunk-GMOUBOX4.mjs";
49
- import "./token-goat-chunk-RRNZMM3A.mjs";
12
+ import "./token-goat-chunk-MELOKFDJ.mjs";
50
13
  import {
51
14
  init_define_import_meta_env
52
15
  } from "./token-goat-chunk-A37V4PBF.mjs";
@@ -54,4 +17,6 @@ import {
54
17
  // src/main.ts
55
18
  init_define_import_meta_env();
56
19
  installEpipeGuard();
57
- void run();
20
+ void runCliViaServer(process.argv).then(async (served) => {
21
+ if (!served) await (await import("./token-goat-chunk-HUYUHODZ.mjs")).run();
22
+ });
@@ -80,7 +80,7 @@ flowchart TB
80
80
  end
81
81
 
82
82
  subgraph TGProcesses ["Token-Goat Runtime Containers"]
83
- HookShim["🪝 Hook Shim<br/><small>[~/.claude/hooks/token-goat-shim.js]</small><br/>In-process fast path / Subprocess launcher"]:::shim
83
+ HookShim["🪝 Hook Shim<br/><small>[~/.claude/hooks/token-goat-shim.cjs]</small><br/>In-process fast path / Subprocess launcher"]:::shim
84
84
  HookRelay["⚡ Hook Relay & Normalizer<br/><small>[dist/token-goat-hook.mjs]</small><br/>Normalizes Codex/Gemini/Claude schemas"]:::process
85
85
  CLIBinary["💻 CLI Tool & Command Suite<br/><small>[dist/token-goat.mjs]</small><br/>100+ surgical read, outline, pack commands"]:::process
86
86
  MCPServer["🔌 MCP stdio Server<br/><small>[token-goat mcp-serve]</small><br/>18 tools: symbol, read, retrieve, section"]:::process
@@ -218,7 +218,7 @@ flowchart TB
218
218
  sequenceDiagram
219
219
  autonumber
220
220
  participant Agent as AI Agent (Claude Code)
221
- participant Shim as token-goat-shim.js
221
+ participant Shim as token-goat-shim.cjs
222
222
  participant Relay as relay.ts / hook_registry.ts
223
223
  participant Filter as ToolFilter (tool_filters/)
224
224
  participant Store as session_store.ts & disk_cache.ts
package/docs/cli.md CHANGED
@@ -99,7 +99,7 @@ token-goat pdf-extract manual.pdf --pages 12-15 --layout --head 120
99
99
  | `token-goat waste [--project <path>] [--transcript <path>] [--top <n>] [--json] [--copilot]` | Session spend-ledger: parses the current project's Claude Code session transcript and reports token cost by tool, by file, the top N most expensive individual tool calls, files read once and never referenced again, Bash commands run repeatedly without hitting token-goat's own bash-output cache, and the assistant's own text-output cost (generated tokens plus a cache-unaware re-send upper bound). See [Session waste ledger](#session-waste-ledger) below. |
100
100
  | `token-goat mcp-audit [--project <path>] [--json]` | MCP server schema cost report: scans .mcp.json for installed MCP servers, estimates per-server token costs from cached tool calls, correlates schema complexity against real call frequency. Outputs as markdown table or JSON. |
101
101
  | `token-goat recall ["<query>"] [--type bash\|web\|mcp] [--limit <n>] [--json]` | Full-text search across every cached bash-output, web-output, and mcp-output entry at once — one command instead of remembering which cache type holds a prior result. Ranked by relevance (BM25 via SQLite FTS5). With **no query**, lists every cached entry newest-first instead of searching, so you can browse when the ids have scrolled out of context and you have no term to search for. `--type` narrows to one cache type; `--limit` caps results (default 10). Each hit shows its cache type, id, the exact recall command (`bash-output <id>` / `web-output <id>` / `mcp-output <id>`), and a content snippet. See [Cross-cache recall](#cross-cache-recall) below. |
102
- | `token-goat hint-stats [--json] [--reset] [--mark-effective <cat>] [--mark-ineffective <cat>]` | Per-category efficacy report for token-goat's discretionary hint hooks: how often each hint category was emitted, how often the agent actually followed its specific suggestion within the next few tool calls, whether the category is currently auto-suppressed, and the bytes each category spent (injected into context) plus an all-time saved-bytes/spent-bytes summary line (the two cover disjoint populations and are deliberately never netted against each other). `--reset` clears all tracked data; `--mark-effective`/`--mark-ineffective <category>` record a manual vote as a supplement to the automatic signal. See [Hint efficacy tracking](#hint-efficacy-tracking) below. |
102
+ | `token-goat hint-stats [--json] [--session-id <id>] [--reset] [--mark-effective <cat>] [--mark-ineffective <cat>]` | Per-category efficacy report for token-goat's discretionary hint hooks: how often each hint category was emitted, how often the agent actually followed its specific suggestion within the next few tool calls, whether the category is currently auto-suppressed, and the bytes each category spent (injected into context) plus an all-time saved-bytes/spent-bytes summary line (the two cover disjoint populations and are deliberately never netted against each other). `--session-id <id>` (or `latest`) narrows the emission counts, efficacy and spend to one session; suppression and manual marks stay all-time, saved-bytes is left out because the stats ledger records no session, and `--session-id` is rejected alongside the three mutating flags. `--reset` clears all tracked data; `--mark-effective`/`--mark-ineffective <category>` record a manual vote as a supplement to the automatic signal. See [Hint efficacy tracking](#hint-efficacy-tracking) below. |
103
103
  | `token-goat history` | Show current session access history: bash commands and URLs fetched. |
104
104
  | `token-goat session-outline` | Turn-by-turn structure (role, preview, tool calls, approx size) of a Claude Code session JSONL transcript, instead of a raw Read; defaults to the current project's most recent session. |
105
105
  | `token-goat session-slice <turns>` | Full content of one turn range from a Claude Code session JSONL transcript (see `session-outline` for turn numbers), instead of a raw Read. |
@@ -170,6 +170,7 @@ token-goat pdf-extract manual.pdf --pages 12-15 --layout --head 120
170
170
  | `token-goat mcp-serve` | Run token-goat as an MCP stdio server exposing all 18 tools: read/symbol/section/outline/skeleton/semantic/index_status/refs/brief/map/changed/grep/imports/exports/compress_text/retrieve_text/handoff_create/handoff_resolve. |
171
171
  | `token-goat version` | Print the token-goat version. |
172
172
  | `token-goat statusline` | Claude Code statusline command surfacing session stats (bytes saved, hint efficacy, cache hit rate) inline in the terminal. |
173
+ | `token-goat hook-server status` / `stop` | Inspect or stop the resident hook servers: up to three per data directory, started in the background by the first hook call, and each answering hook calls and read-only commands from an already-loaded process instead of a fresh Node start. `status` prints each running server's slot, pid, version, uptime, calls served, errors and idle time (`--json` for the same as JSON). `stop` asks each one to exit over its authenticated channel; one in the middle of a call finishes it first. A server also exits on its own after 30 minutes idle (3 minutes for the two overflow slots), when the installed build changes, when `hooks.server` in the global config or `TOKEN_GOAT_HOOK_SERVER` turns it off, and within two seconds of its key file being deleted. `token-goat hook-server run --slot N` is what the background start runs; you do not need to call it. |
173
174
  | `token-goat lockdeps [path]` | Summarize lock file dependencies as a compact table. Reads poetry.lock, uv.lock, requirements.txt, Pipfile.lock, package-lock.json, Cargo.lock, and yarn.lock. Direct dependencies only — optional and transitive entries excluded. `--json` for structured output. |
174
175
  | `token-goat logfold [src]` | Collapse consecutive duplicate log lines. Runs of identical or structurally equivalent lines fold to `[Nx] line`. Normalizes timestamps, UUIDs, IPs, hex IDs, and bare integers (counters, PIDs, ports, byte counts) before comparing so the same event with different values folds correctly. `--tail N` keeps last N lines; `--no-normalize` disables normalization; `--fold-repeats` also folds non-consecutive duplicates anywhere in the input, attributing the total count to the first occurrence (capped at 20,000 distinct keys, past which it falls back to consecutive-only); `--json` for structured output. |
175
176
  | `token-goat hot [--limit N]` | Cross-session file frequency table: read and edit counts tallied from all stored sessions, ranked by total activity. Shows which files dominate your token spend across your entire history. `--project <dir>` filters to one project; `--json` for structured output. |
@@ -180,7 +181,7 @@ token-goat pdf-extract manual.pdf --pages 12-15 --layout --head 120
180
181
  | `token-goat install` | Wire up hooks (and, with the harness flags below, other AI tool integrations). No `--dry-run` or `--verify` flag — run `token-goat doctor` after install to audit the result. |
181
182
  | `token-goat upgrade` | Check for updates or upgrade token-goat to the latest version via npm. Pass `--check` to report status without installing. `--json` emits machine-readable version status. |
182
183
  | `token-goat doctor` | Confirm everything is wired correctly. Surfaces install state, cold-import timing, cache hit rates, compaction-budget telemetry, opt-in flag status, and canonical-root sanity. A **Parser freshness** check reports how much of the index for this project was written by a different build of the extractor. The stamp only refreshes when something touches a file, so after an upgrade a project goes on answering `symbol`, `read`, `outline` and `skeleton` from the previous extractor with nothing saying so. It warns past a quarter and names the fix: a plain `token-goat index` in that project, which is enough on its own, since a parser mismatch reparses without `--force`. A **Tool names** check reports any tool name a harness sent that reached no handler wanting it, and calls out the ones that differ from a handled name only by capitalisation or punctuation — the signature of a bridge that forgot to rename something, which is otherwise invisible. When `global.db` passes 1 GB, the warning now also breaks the total down by category (symbol bodies, refs, chunk text, embedding vectors, stats detail) with each one's measured byte share and the exact command that shrinks it -- `reclaim-index --rebuild` for the derived-row categories, disabling `indexing.embeddings_enabled` first for vectors so they don't regrow, and nothing manual for stats detail, which ages out on its own. A **Security** section reports the posture in one place: whether offline mode is on, whether injection scanning is on, whether the Google Drive integration is enabled, whether fetching runs against an allow list or a deny list, whether MCP reads are confined to the project root, and whether the data directory is readable by other local users. It only warns when a protection that ships on has been switched off, so a default install stays quiet. It read-only audits `~/.copilot/mcp-config.json` for globally configured Chrome DevTools or Playwright `npx` launchers, recommending project scope or removal when inactive; it never prints server configuration or secrets. On Windows, it also reports duplicate Chrome DevTools/Playwright MCP launchers and orphaned Node processes without terminating anything. Pass `--context` to show the **Context footprint** section: a fill bar with severity (ok / warn / high / URGENT), per-component breakdown (skills catalog, loaded skill bodies, CLAUDE.md+MEMORY.md, conversation estimate), session-to-session growth trend with sessions-to-URGENT projection, and tiered compaction recommendations (Tier 0–4) naming the exact commands to run. Auto-shown when fill > 40 % or any loaded skill > 2 K tokens lacks a compact. `--json` emits the check results (one entry per check, with `ok`/`warn`/`fail` status) as JSON instead of text. |
183
- | `token-goat capabilities` | List every capability that can send data off this machine or leave data on it, with whether it is currently on, the config key that decides that, and the exact `file::symbol` where the decision is made — so a reviewer can open the code rather than take the list's word for it. `--json` emits the same thing for a pipeline to assert on, which is the point: the answer comes from the binary installed on your machine, not from documentation that may describe a different build. A test in the suite fails the build when a module that can open a network connection is missing from this list, and equally when the list names one that no longer connects anywhere. |
184
+ | `token-goat capabilities` | List every capability that can send data off this machine, leave data on it, or listen for other processes on it, with whether it is currently on, the config key that decides that, and the exact `file::symbol` where the decision is made, so a reviewer can open the code rather than take the list's word for it. `--json` emits the same thing for a pipeline to assert on, which is the point: the answer comes from the binary installed on your machine, not from documentation that may describe a different build. A test in the suite fails the build when a module that can open a network connection is missing from this list, and equally when the list names one that no longer connects anywhere. |
184
185
  | `token-goat baseline` | Emit a project map: file count, per-language file counts, the top indexed symbols (by name/kind/location), and the most recently modified files. `--subagent` emits a terser variant (fewer symbols, fewer recent files) for context handed to a freshly spawned subagent; `--json` for the machine-readable form. |
185
186
  | `token-goat compact-doc <path>` | Build an extractive compact sidecar for a large reference doc (`.md`/`.markdown`). The compact is stored in the token-goat data dir as a SHA-keyed sidecar; `pre_read` serves it in place of the full file when it exists and is fresh, typically saving 60–95% of the tokens the full read would cost (measured across this repo's own 44 docs: median 67%, range 5–99%, depending on how much of the doc is prose under headings). Use `--force` to rebuild, `--sentences N` to control lines per section (default 2), `--show` to print the result. The sidecar is automatically marked stale when you edit the source file. Config: `[hints] stable_doc_compacts = true` (default on). |
186
187
 
package/docs/install.md CHANGED
@@ -128,7 +128,7 @@ This writes hook entries into `~/.qwen/settings.json`. Unlike Gemini CLI (its ow
128
128
  token-goat install --kimi
129
129
  ```
130
130
 
131
- This writes `[[hooks]]` entries into `~/.kimi-code/config.toml` (or `$KIMI_CODE_HOME/config.toml`), covering Kimi Code's `PreToolUse`, `PostToolUse`, `PreCompact`, `UserPromptSubmit`, `SubagentStop`, and `SessionStart` events. Kimi Code sends a Claude-Code-shaped snake_case payload on stdin, but it reads a different response: only a top-level `message` and `hookSpecificOutput.permissionDecision` / `permissionDecisionReason`. So the install also writes a small shim at `~/.kimi-code/hooks/token-goat-shim.js` that translates token-goat's answer into that contract, turns a hint into `message`, and writes nothing at all for a no-op. Image shrinking, session hints, post-edit indexing, compact assist, and bash output compression all work. `Notification` and `Stop` are not wired, because token-goat has no handler for them. Input and output rewriting are not wired either: Kimi Code offers no channel to replace a tool's input or its result. This bridge was built from MoonshotAI/kimi-code's own source and docs, not tested against a live Kimi Code install, so if hooks are not firing, `token-goat doctor` and the `config.toml` contents are the first things to check. To remove: `token-goat uninstall --kimi`.
131
+ This writes `[[hooks]]` entries into `~/.kimi-code/config.toml` (or `$KIMI_CODE_HOME/config.toml`), covering Kimi Code's `PreToolUse`, `PostToolUse`, `PreCompact`, `UserPromptSubmit`, `SubagentStop`, and `SessionStart` events. Kimi Code sends a Claude-Code-shaped snake_case payload on stdin, but it reads a different response: only a top-level `message` and `hookSpecificOutput.permissionDecision` / `permissionDecisionReason`. So the install also writes a small shim at `~/.kimi-code/hooks/token-goat-shim.cjs` that translates token-goat's answer into that contract, turns a hint into `message`, and writes nothing at all for a no-op. Image shrinking, session hints, post-edit indexing, compact assist, and bash output compression all work. `Notification` and `Stop` are not wired, because token-goat has no handler for them. Input and output rewriting are not wired either: Kimi Code offers no channel to replace a tool's input or its result. This bridge was built from MoonshotAI/kimi-code's own source and docs, not tested against a live Kimi Code install, so if hooks are not firing, `token-goat doctor` and the `config.toml` contents are the first things to check. To remove: `token-goat uninstall --kimi`.
132
132
 
133
133
  ### opencode users
134
134
 
@@ -136,7 +136,7 @@ This writes `[[hooks]]` entries into `~/.kimi-code/config.toml` (or `$KIMI_CODE_
136
136
  token-goat install --opencode
137
137
  ```
138
138
 
139
- The `--opencode` flag patches Claude Code and drops a TypeScript bridge plugin into opencode's plugins directory — one command, no separate base install. Image shrinking, post-edit indexing, compact assist, and rewritten tool results (prompt-injection fencing, secret redaction, and output compression replace the raw result, the same protection Claude Code sessions get) work. So do repeat-search denial for `websearch`, repeat-load denial for `skill`, and the subagent prompt briefing for `task` — all three tool ids and their argument keys were verified against opencode's own source at the installed release's tag. Session hints don't — opencode's plugin API has no way to inject context before a tool read.
139
+ The `--opencode` flag drops a TypeScript bridge plugin into opencode's plugins directory. Image shrinking, post-edit indexing, compact assist, and rewritten tool results (prompt-injection fencing, secret redaction, and output compression replace the raw result, the same protection Claude Code sessions get) work. So do repeat-search denial for `websearch`, repeat-load denial for `skill`, and the subagent prompt briefing for `task` — all three tool ids and their argument keys were verified against opencode's own source at the installed release's tag. Session hints don't — opencode's plugin API has no way to inject context before a tool read.
140
140
 
141
141
  ### openclaw users
142
142
 
@@ -174,13 +174,13 @@ This writes `.pi/extensions/token-goat.ts` in the current project only. Remove i
174
174
  token-goat install --copilot
175
175
  ```
176
176
 
177
- The `--copilot` flag patches Claude Code and registers a Copilot CLI hook config: `~/.copilot/hooks/token-goat.json` (a `{ version, hooks }` file registering `sessionStart`, `preToolUse`, `postToolUse`, `preCompact`, `agentStop`, `subagentStop`, and `userPromptSubmitted`, per Copilot's own [hooks reference](https://docs.github.com/en/copilot/reference/hooks-reference)) plus the shim script it points at, `~/.copilot/hooks/token-goat-shim.js`. Unlike Codex, Copilot's event names and response schema (`permissionDecision`/`modifiedArgs` for `preToolUse`, `modifiedResult`/`additionalContext` for `postToolUse`, `decision`/`reason` for `agentStop`/`subagentStop`) genuinely differ from Claude Code's, so the shim translates rather than passes through.
177
+ The `--copilot` flag patches Claude Code and registers a Copilot CLI hook config: `~/.copilot/hooks/token-goat.json` (a `{ version, hooks }` file registering `sessionStart`, `preToolUse`, `postToolUse`, `preCompact`, `agentStop`, `subagentStop`, and `userPromptSubmitted`, per Copilot's own [hooks reference](https://docs.github.com/en/copilot/reference/hooks-reference)) plus the shim script it points at, `~/.copilot/hooks/token-goat-shim.cjs`. Unlike Codex, Copilot's event names and response schema (`permissionDecision`/`modifiedArgs` for `preToolUse`, `modifiedResult`/`additionalContext` for `postToolUse`, `decision`/`reason` for `agentStop`/`subagentStop`) genuinely differ from Claude Code's, so the shim translates rather than passes through.
178
178
 
179
179
  What works: **the command-routing reminder** (`sessionStart` returns `additionalContext`, so Copilot is told token-goat exists before it picks its first read tool — this is the one channel that lands ahead of that decision), **bash output compression and re-read denial** (`preToolUse` returns `modifiedArgs` or `permissionDecision: "deny"`), **background-shell output compression** (`postToolUse` returns `modifiedResult`), **image shrinking** (`preToolUse` on a `view` call returns `modifiedArgs` carrying the full original arguments with `path` swapped to a materialized shrunk copy — Copilot replaces the tool call's arguments wholesale with `modifiedArgs`, so the rewrite must carry them all), **post-edit indexing** (a `postToolUse` side effect; it needs no response channel), and **stop-hallucination logging** (`agentStop`/`subagentStop` map a token-goat `deny` onto `decision: "block"`, everything else onto `decision: "allow"`). `preCompact` and `userPromptSubmitted` are notification-only on real Copilot CLI, per its docs: Copilot never reads a response body for either, so token-goat's compaction manifest and prompt-context hints have no surfacing channel there. The shim still calls through for both so token-goat's internal side effects keep running, but nothing gets injected back into the agent. Copilot's built-in tool names are remapped onto token-goat's internal names where a clear match exists (`view`→Read, `edit`→Edit, `create`→Write, `bash`/`powershell`→Bash, `read_bash`/`read_powershell`→BashOutput, `web_fetch`→WebFetch, `grep`→Grep, `glob`→Glob). MCP-server tool calls, which Copilot names `<server>-<tool>` rather than `mcp__<server>__<tool>`, are translated too, but only when the name matches Copilot's own cached tool list exactly — never guessed from the name's shape, because a server name can itself contain a hyphen and a wrong guess would make the read-only MCP dedup path deny an ordinary built-in call. With no cache to match against, nothing is translated. `memory`, `ask_user`, `write_bash`/`write_powershell` (which send keystrokes to a running shell, not commands), and `stop_bash`/`list_bash` pass through unmapped and simply no-op. `task`, Copilot's subagent tool, is not remapped either, but it is handled under its own name: a `task` spawn gets the same prompt briefing, duplicate-spawn advisory, and recall pointer on a long report that a Claude Code `Agent` spawn gets. The once-per-session unrestricted-spawn advisory is the one exception: it is suppressed under Copilot, because it rides the `postToolUse` `additionalContext` channel Copilot discards, and its `subagent_type` advice describes Claude Code's Task schema, which Copilot's `task` tool does not use.
180
180
 
181
181
  **Why the background-shell compression matters most on Copilot.** Copilot runs shell commands in the background: a build or a test suite is started once, and the model then checks on it repeatedly while it runs. Each check hands back everything the command has printed since it started, from the first line. So the second check re-sends the whole first check, the third re-sends the first two, and a check ten minutes into a slow build re-sends the same output for the tenth time. The model has already read all of it and pays again for every word, every time. Token-goat sends the first check through untouched, then returns only the new part on each later check, with one line saying that is what it is; a check that found nothing new comes back as a single short line instead of the whole output again. Measured through the installed hook: a second check of 5,200 characters came back as about 1,250, and a third check that added nothing came back as 60 — roughly a quarter of the cost for the second look and about one percent for the third, improving the longer the command runs. Nothing is lost, because what is cut is what was already sent. It only shortens a check when the new output genuinely continues the last one seen; anything else passes straight through, so the worst case is a saving that does not happen rather than a wrong answer.
182
182
 
183
- No ambient environment variable documents "this process is running under Copilot CLI" the way Codex/opencode set one, so the shim sets `TOKEN_GOAT_HARNESS_OVERRIDE=copilot_cli` itself before calling `token-goat hook` (same workaround `--pi` uses). Install also writes a token-goat routing block into `~/.copilot/copilot-instructions.md` (the same delimited-block gate written to `~/.claude/CLAUDE.md` and `~/.codex/AGENTS.md`), merged idempotently so any hand-written content outside the markers is preserved byte-for-byte. If you set `COPILOT_HOME`, install follows it — hooks go to `$COPILOT_HOME/hooks/` and the routing block to `$COPILOT_HOME/copilot-instructions.md`, matching where Copilot CLI actually reads them. To install for one project instead of user scope: `token-goat install --copilot --local` (writes `.github/hooks/token-goat.json` and `.github/copilot-instructions.md` in the current project). `.github/hooks/token-goat.json` holds absolute paths to node and token-goat on your machine, so do not commit it or the `token-goat-shim.js` next to it: list them in `.git/info/exclude` (just for you) or `.gitignore`. Install prints this reminder. To remove: `token-goat uninstall --copilot`.
183
+ No ambient environment variable documents "this process is running under Copilot CLI" the way Codex/opencode set one, so the shim sets `TOKEN_GOAT_HARNESS_OVERRIDE=copilot_cli` itself before calling `token-goat hook` (same workaround `--pi` uses). Install also writes a token-goat routing block into `~/.copilot/copilot-instructions.md` (the same delimited-block gate written to `~/.claude/CLAUDE.md` and `~/.codex/AGENTS.md`), merged idempotently so any hand-written content outside the markers is preserved byte-for-byte. If you set `COPILOT_HOME`, install follows it — hooks go to `$COPILOT_HOME/hooks/` and the routing block to `$COPILOT_HOME/copilot-instructions.md`, matching where Copilot CLI actually reads them. To install for one project instead of user scope: `token-goat install --copilot --local` (writes `.github/hooks/token-goat.json` and `.github/copilot-instructions.md` in the current project). `.github/hooks/token-goat.json` holds absolute paths to node and token-goat on your machine, so do not commit it or the `token-goat-shim.cjs` and `token-goat-shim.js` next to it: list them in `.git/info/exclude` (just for you) or `.gitignore`. Install prints this reminder. To remove: `token-goat uninstall --copilot`.
184
184
 
185
185
  **If Copilot CLI starts denying every tool call with `Denied by preToolUse hook ... (hook errored)`:** this is Copilot's own fail-closed behavior for a `preToolUse` hook that crashes, exits non-zero, or returns unparseable output -- it isn't limited to token-goat's own tool calls, since a fail-closed `preToolUse` hook blocks the whole session. Copilot caches hook configs at session start, so **renaming or reinstalling the hook mid-session has no effect** -- the only recovery is: run `token-goat install --copilot` (or `token-goat doctor`, which now checks the installed hook end-to-end and calls out a stale node-binary path from an nvm/fnm/volta upgrade specifically), then **fully restart Copilot CLI**.
186
186
 
@@ -190,7 +190,7 @@ No ambient environment variable documents "this process is running under Copilot
190
190
  token-goat install --vscode
191
191
  ```
192
192
 
193
- This installs into the **current project**: the MCP entry goes to `.vscode/mcp.json` (a timestamped `.bak` is written before any change to an existing file), the agent hooks to `.github/hooks/` (`token-goat.json` plus the `token-goat-shim.js` it runs), and the routing guidance to `.github/copilot-instructions.md`. Run it once in each project you want token-goat in. VS Code's Copilot agent reads hooks from that folder, so token-goat sees the agent's built-in tool calls: `read_file`, `view_image`, `list_dir`, `grep_search`, `file_search`, `create_file`, `replace_string_in_file`, `insert_edit_into_file`, `edit_notebook_file`, and `run_in_terminal`. Both `.vscode/mcp.json` and `.github/hooks/token-goat.json` hold absolute paths to node and token-goat on your machine, so do not commit them or the `token-goat-shim.js` next to them: list them in `.git/info/exclude` (just for you) or `.gitignore`. Install prints this reminder.
193
+ This installs into the **current project**: the MCP entry goes to `.vscode/mcp.json` (a timestamped `.bak` is written before any change to an existing file), the agent hooks to `.github/hooks/` (`token-goat.json` plus the `token-goat-shim.cjs` it runs), and the routing guidance to `.github/copilot-instructions.md`. Run it once in each project you want token-goat in. VS Code's Copilot agent reads hooks from that folder, so token-goat sees the agent's built-in tool calls: `read_file`, `view_image`, `list_dir`, `grep_search`, `file_search`, `create_file`, `replace_string_in_file`, `insert_edit_into_file`, `edit_notebook_file`, and `run_in_terminal`. Both `.vscode/mcp.json` and `.github/hooks/token-goat.json` hold absolute paths to node and token-goat on your machine, so do not commit them or the `token-goat-shim.js` next to them: list them in `.git/info/exclude` (just for you) or `.gitignore`. Install prints this reminder.
194
194
 
195
195
  `--vscode` is the one integration that installs into the project rather than user scope by default, and the reason is a limitation of VS Code itself. VS Code resolves an agent hook's working directory from the hook **file's** own location: the folder of the workspace that contains it, or the workspace's first folder when no workspace contains it. A user-scope hooks file lives in `~/.copilot/hooks/`, which is inside no workspace folder, so it always runs with the **first** folder of a multi-root workspace as its working directory — and since token-goat confines every pre-approval hook to that directory, read hints, image shrinking and edit interception silently do nothing for every other folder. A project-scope hooks file is inside its own folder, so each folder gets its own.
196
196
 
@@ -255,7 +255,7 @@ Grok Build already reads Claude Code's `~/.claude/settings.json` as a "Harness C
255
255
  token-goat install --grok
256
256
  ```
257
257
 
258
- The `--grok` flag patches Claude Code and additionally writes a standalone hook config at `~/.grok/hooks/token-goat.json` (global scope only — Grok's own project-scoped `<project>/.grok/hooks/*.json` requires a separate manual `/hooks-trust` grant this bridge can't perform for you) plus the shim it points at, `~/.grok/hooks/token-goat-shim.js`. The shim's only job is translating that one response shape: a token-goat `{"decision":"block",...}` deny becomes Grok's documented `{"decision":"deny",...}` (with exit code 2, matching Grok's own "explicit deny" convention), and every other event's response is forwarded through unmodified — Grok already sends the raw camelCase wire payload (`toolName`/`toolInput`/`sessionId`) token-goat's built-in `grok` harness detection (`GROK_SESSION_ID`, set on every hook subprocess Grok spawns) already normalizes correctly. That normalization maps every tool id registered in the grok 0.2.93 binary itself — both shell-tool spellings (`run_terminal_command` and `run_terminal_cmd`), `web_fetch`, `web_search`, `glob`, and the `hashline_*`/`*_concise` read/edit/grep variants — onto token-goat's internal tool names, so hooks fire regardless of which id a given Grok build sends.
258
+ The `--grok` flag patches Claude Code and additionally writes a standalone hook config at `~/.grok/hooks/token-goat.json` (global scope only — Grok's own project-scoped `<project>/.grok/hooks/*.json` requires a separate manual `/hooks-trust` grant this bridge can't perform for you) plus the shim it points at, `~/.grok/hooks/token-goat-shim.cjs`. The shim's only job is translating that one response shape: a token-goat `{"decision":"block",...}` deny becomes Grok's documented `{"decision":"deny",...}` (with exit code 2, matching Grok's own "explicit deny" convention), and every other event's response is forwarded through unmodified — Grok already sends the raw camelCase wire payload (`toolName`/`toolInput`/`sessionId`) token-goat's built-in `grok` harness detection (`GROK_SESSION_ID`, set on every hook subprocess Grok spawns) already normalizes correctly. That normalization maps every tool id registered in the grok 0.2.93 binary itself — both shell-tool spellings (`run_terminal_command` and `run_terminal_cmd`), `web_fetch`, `web_search`, `glob`, and the `hashline_*`/`*_concise` read/edit/grep variants — onto token-goat's internal tool names, so hooks fire regardless of which id a given Grok build sends.
259
259
 
260
260
  To remove: `token-goat uninstall --grok`.
261
261
 
@@ -284,7 +284,7 @@ There is no auto-update mechanism — token-goat never schedules or runs anythin
284
284
 
285
285
  ### Upgrading from the Python version
286
286
 
287
- The old Python package (`pip install token-goat`) wrote hook entries into `settings.json` with commands containing `token_goat` (underscore), invoking Python directly: something like `pythonw.exe -m token_goat.cli hook pre_tool_use`. The npm package invokes a generated shim instead (`"<node>" "~/.claude/hooks/token-goat-shim.js" pre_tool_use "<entry>"`).
287
+ The old Python package (`pip install token-goat`) wrote hook entries into `settings.json` with commands containing `token_goat` (underscore), invoking Python directly: something like `pythonw.exe -m token_goat.cli hook pre_tool_use`. The npm package invokes a generated shim instead (`"<node>" "~/.claude/hooks/token-goat-shim.cjs" pre_tool_use "<entry>"`).
288
288
 
289
289
  Both `install` and `uninstall` recognize the older command spellings — `token_goat`, `tokenwise`, `tg-hook`, `token-goat-hook`, and the pre-shim `token-goat hook` — so you do not need to hand-edit `settings.json`. Installing replaces a stale entry in place rather than leaving a dead one beside the new one, and uninstalling removes it.
290
290
 
@@ -386,19 +386,21 @@ MATLAB, OpenEdge ABL and Salesforce metadata share their file extensions with ot
386
386
 
387
387
  `token-goat install` writes the following on your machine — nothing else, anywhere. Every entry is reversed by `token-goat uninstall`. Integrations for other harnesses are additive on the way out as well as in, so a plain uninstall does not touch one you installed with `--codex`, `--copilot`, or a sibling flag: rather than undo something you did not ask about, it names each one still present and the flag that removes it. Run `token-goat doctor` at any time to see which of these are currently present.
388
388
 
389
- A bare `token-goat install` (no other flag) installs the Claude Code integration below. Passing a harness flag — `--vscode`, `--codex`, `--gemini`, and so on — installs only that harness's own files, listed in its own section further down: it never also touches `~/.claude/` on the side. If you want both, run `install` again with the other flag, or pass both flags in the same command. The one exception is `--hermes`, which delegates to `claude -p` and so genuinely needs the Claude Code hooks below; it installs them the same way a bare `install` does.
389
+ A bare `token-goat install` (no other flag) installs the Claude Code integration below. Passing a harness flag (`--vscode`, `--codex`, `--gemini`, and so on) installs only that harness's own files, listed in its own section further down: it never also touches `~/.claude/` on the side. To have the Claude Code integration as well, run a bare `token-goat install` too. Several harness flags in one command install each of those harnesses. The one exception is `--hermes`, which delegates to `claude -p` and so genuinely needs the Claude Code hooks below; it installs them the same way a bare `install` does.
390
390
 
391
391
  **Claude Code integration** (`~/.claude/`; written by a bare `install`, or by `--hermes`)
392
392
 
393
393
  | Path | What |
394
394
  |------|------|
395
395
  | `~/.claude/settings.json` | Hook entries for `SessionStart`, `PreToolUse` (Read/Grep/Bash, Drive/WebFetch), `PostToolUse` (Edit/Write/MultiEdit, Read/Grep/Glob, Bash, WebFetch, Skill), and `PreCompact`. Hook entries only: install writes nothing under `permissions`, so it never grants the agent unprompted execution of anything. Existing hooks are preserved; a timestamped `.bak` is written before any change.<br><br>The `PreToolUse` and `PostToolUse` matchers are narrowed to exactly the tools token-goat handles (plus `^mcp__`), generated from the live hook registry rather than a fixed list, so they can't fall out of date as handlers change. Claude Code starts a new process per matcher hit and most of that cost is process startup, so a catch-all matcher would make every unrelated tool call — `TodoWrite`, `TaskUpdate`, and friends — pay for a hook that has nothing to do. |
396
- | `~/.claude/hooks/token-goat-shim.js` | The hook script those `settings.json` commands invoke (`"<node>" "<shim>" <event> "<entry>"`). It imports the hook library in-process instead of spawning a second process, and naming the node binary directly skips the npm bin wrapper — on Windows a `cmd.exe` layer every hook would otherwise pay for. Measured 480 ms → 324 ms per hook call. Regenerated on every `install` run. Always written here even for a `--project` install, since the command bakes in machine-specific absolute paths; a project-scope `settings.json` just points at this one. |
396
+ | `~/.claude/hooks/token-goat-shim.cjs` | The hook script those `settings.json` commands invoke (`"<node>" "<shim>" <event> "<entry>"`). It imports the hook library in-process instead of spawning a second process, and naming the node binary directly skips the npm bin wrapper — on Windows a `cmd.exe` layer every hook would otherwise pay for. Measured 480 ms → 324 ms per hook call. Regenerated on every `install` run. Always written here even for a `--project` install, since the command bakes in machine-specific absolute paths; a project-scope `settings.json` just points at this one. The `.cjs` extension keeps Node from loading it as an ES module when a package.json above it says `"type": "module"`. A small `token-goat-shim.js` beside it hands off to the `.cjs` file, for sessions started before the rename that still run the old path. |
397
397
  | `~/.claude/CLAUDE.md` | A delimited block (`<!-- token-goat-begin -->` … `<!-- token-goat-end -->`) telling the agent to prefer `token-goat read` / `symbol` / `section` over `Read` / `Grep`. Any existing content is preserved; a timestamped `.bak` is written before any change. |
398
398
  | `~/.claude/skills/token-goat/SKILL.md` | The token-goat skill — the same routing guidance in skill form. A timestamped `.bak` is written before any change. |
399
399
 
400
400
  **Background worker.** token-goat does not register any persistent OS-level autostart entry — no Windows registry `Run` key, no systemd user unit, no XDG `.desktop` entry, and no macOS launchd `.plist`. The worker that drains the reindex queue is started manually as a detached child process: `token-goat worker start` launches `node <npm-prefix>/lib/node_modules/token-goat/dist/token-goat.mjs --worker-daemon` and returns immediately, and the child keeps running independent of the parent shell. `token-goat worker status` reports whether it's running; `token-goat worker stop` kills it. If it crashes or is killed while the machine stays up, the next edit hook detects it's gone and respawns it automatically (checked on every edit, rate-limited to roughly once every 5 minutes). It does not survive a reboot or logout, though — re-run `token-goat worker start` after either.
401
401
 
402
+ **Hook server.** The first hook call also starts up to three hook servers in the background: plain detached `node` processes, not OS services, that answer later hook calls and read-only commands so each call skips starting Node. Each listens on a named pipe (Windows) or a Unix socket with mode 0600 (elsewhere), never on a network port, and answers only a caller that proves it holds the random key in `hook-server.key` in the data directory, a file readable only by you. `hook-server.spawn-<slot>`, `hook-server.disabled` and `hook-server.failed` beside it are small marker files: a start rate limit, a record that the config turned the server off, and the reason the last start failed. A server exits after 30 minutes idle, after an upgrade replaces the build it loaded, when `server = false` under `[hooks]` in the global config or `TOKEN_GOAT_HOOK_SERVER=0` turns it off, and within two seconds of its key file being deleted. `uninstall` and `uninstall --purge` stop every running server before touching anything else. `token-goat capabilities` lists it under "Listens for other processes on this machine".
403
+
402
404
  There is no auto-update mechanism. Updating token-goat is always a manual `npm install -g token-goat@latest`.
403
405
 
404
406
  **Data directory** (created on first run)
@@ -421,7 +423,7 @@ Three things follow, and they are worth knowing before you decide. It never leav
421
423
  |------|------|
422
424
  | `~/.codex/config.toml` | Hooks block with Codex-specific matchers (`view_image|Bash`, `apply_patch`, `web_search`) plus `PreCompact`/`UserPromptSubmit`/`SubagentStop` global hooks. Existing hooks preserved. |
423
425
  | `~/.codex/AGENTS.md` | A delimited block (`<!-- token-goat-codex-begin -->` … `<!-- token-goat-codex-end -->`) with the same routing guidance, adapted for Codex tool names. |
424
- | `~/.codex/hooks/token-goat-shim.js` | The hook script `config.toml`'s hook commands invoke (`node "<path>" <event>`). Strips internal `_tg_*` keys and injects `hookSpecificOutput.hookEventName` to satisfy Codex's strict schemas. Regenerated on every `install --codex` run. |
426
+ | `~/.codex/hooks/token-goat-shim.cjs` | The hook script `config.toml`'s hook commands invoke (`node "<path>" <event>`). Strips internal `_tg_*` keys and injects `hookSpecificOutput.hookEventName` to satisfy Codex's strict schemas. Regenerated on every `install --codex` run. The `.cjs` extension keeps Node from loading it as an ES module when a package.json above it says `"type": "module"`. A small `token-goat-shim.js` beside it hands off to the `.cjs` file, for sessions started before the rename that still run the old path. |
425
427
 
426
428
  **With `--gemini`** (Gemini CLI integration)
427
429
 
@@ -440,7 +442,7 @@ Three things follow, and they are worth knowing before you decide. It never leav
440
442
  | Path | What |
441
443
  |------|------|
442
444
  | `~/.kimi-code/config.toml` | `[[hooks]]` entries for Kimi Code's `PreToolUse`, `PostToolUse`, `PreCompact`, `UserPromptSubmit`, `SubagentStop`, and `SessionStart` events. Each entry carries only `event` and `command`, the keys Kimi Code's strict schema accepts. Existing hooks and other config keys preserved; a timestamped `.bak` is written before any change. |
443
- | `~/.kimi-code/hooks/token-goat-shim.js` | The hook script those commands invoke. Rewrites a token-goat block into `hookSpecificOutput.permissionDecision` and a hint into a top-level `message`, and writes empty stdout for a no-op. Regenerated on every `install --kimi` run. |
445
+ | `~/.kimi-code/hooks/token-goat-shim.cjs` | The hook script those commands invoke. Rewrites a token-goat block into `hookSpecificOutput.permissionDecision` and a hint into a top-level `message`, and writes empty stdout for a no-op. Regenerated on every `install --kimi` run. The `.cjs` extension keeps Node from loading it as an ES module when a package.json above it says `"type": "module"`. A small `token-goat-shim.js` beside it hands off to the `.cjs` file, for sessions started before the rename that still run the old path. |
444
446
  | `~/.kimi-code/AGENTS.md` | A delimited block (`<!-- token-goat-kimi-begin -->` ... `<!-- token-goat-kimi-end -->`) with the routing guidance, adapted for Kimi Code tool names. |
445
447
  | `~/.kimi-code/skills/token-goat/SKILL.md` | The same guidance as a Kimi Code skill. |
446
448
 
@@ -461,7 +463,7 @@ Three things follow, and they are worth knowing before you decide. It never leav
461
463
  | Path | What |
462
464
  |------|------|
463
465
  | `~/.copilot/hooks/token-goat.json` | Hook config (`{ version, hooks }`) registering `preToolUse`, `postToolUse`, `preCompact`, `agentStop`, and `subagentStop`, each pointing at the shim script below. Existing files elsewhere in the hooks directory are untouched. |
464
- | `~/.copilot/hooks/token-goat-shim.js` | The shim `token-goat.json`'s hook commands invoke (`node "<path>"`). Translates Copilot's event names and response schema (`permissionDecision`/`modifiedArgs`, `additionalContext`) to/from token-goat's internal hook protocol. Regenerated on every `install --copilot` run. A project-local install (`--copilot --local`) writes `<project>/.github/hooks/token-goat.json` and `<project>/.github/hooks/token-goat-shim.js` instead. |
466
+ | `~/.copilot/hooks/token-goat-shim.cjs` | The shim `token-goat.json`'s hook commands invoke (`node "<path>"`). Translates Copilot's event names and response schema (`permissionDecision`/`modifiedArgs`, `additionalContext`) to/from token-goat's internal hook protocol. Regenerated on every `install --copilot` run. A project-local install (`--copilot --local`) writes `<project>/.github/hooks/token-goat.json` and `<project>/.github/hooks/token-goat-shim.cjs` instead. The `.cjs` extension keeps Node from loading it as an ES module in a repository whose package.json says `"type": "module"`. A two-line `token-goat-shim.js` beside it hands off to the `.cjs` file, for Copilot sessions started before the rename that still run the old path. |
465
467
  | `~/.copilot/copilot-instructions.md` | A delimited block (`<!-- token-goat-begin -->` … `<!-- token-goat-end -->`) with the same routing gate written to `~/.claude/CLAUDE.md` and `~/.codex/AGENTS.md`, naming Copilot CLI's own `view`/`grep`/`glob` tools in the conflict-resolution clause. Merged idempotently — everything outside the markers is preserved byte-for-byte. A project-local install (`--copilot --local`) writes `<project>/.github/copilot-instructions.md` instead. |
466
468
 
467
469
  **With `--grok`** (Grok CLI / xAI Grok Build hook bridge)
@@ -469,7 +471,7 @@ Three things follow, and they are worth knowing before you decide. It never leav
469
471
  | Path | What |
470
472
  |------|------|
471
473
  | `~/.grok/hooks/token-goat.json` | Hook config (`{ hooks }`) registering `PreToolUse`, `PostToolUse`, `PreCompact`, `UserPromptSubmit`, and `SubagentStop` with an empty (match-everything) matcher, each pointing at the shim script below. Existing files elsewhere in the hooks directory are untouched; global scope only (Grok's project-scoped `.grok/hooks/` requires a separate manual `/hooks-trust` grant). |
472
- | `~/.grok/hooks/token-goat-shim.js` | The shim `token-goat.json`'s hook commands invoke. Translates `PreToolUse`'s deny shape only (`{"decision":"block",...}` → Grok's documented `{"decision":"deny",...}`, plus exit code 2); every other event's response is forwarded unmodified. Regenerated on every `install --grok` run. |
474
+ | `~/.grok/hooks/token-goat-shim.cjs` | The shim `token-goat.json`'s hook commands invoke. Translates `PreToolUse`'s deny shape only (`{"decision":"block",...}` → Grok's documented `{"decision":"deny",...}`, plus exit code 2); every other event's response is forwarded unmodified. Regenerated on every `install --grok` run. The `.cjs` extension keeps Node from loading it as an ES module when a package.json above it says `"type": "module"`. A small `token-goat-shim.js` beside it hands off to the `.cjs` file, for sessions started before the rename that still run the old path. |
473
475
 
474
476
  **With `--vscode`** (VS Code MCP configuration; **project scope by default** — the only integration that inverts the usual default, because VS Code pins a user-scope hook to the first folder of a multi-root workspace — with `--user` for the old every-project install)
475
477
 
@@ -477,7 +479,7 @@ Three things follow, and they are worth knowing before you decide. It never leav
477
479
  |------|------|
478
480
  | `<project>/.vscode/mcp.json` — or `%APPDATA%\Code\User\mcp.json` (Windows) / `~/Library/Application Support/Code/User/mcp.json` (macOS) / `~/.config/Code/User/mcp.json` (Linux) with `--user` | Merges the `token-goat` stdio entry under VS Code's `servers` root key, preserving unrelated servers and settings. `--user` refuses to write when the project scope already has a token-goat-managed entry, to avoid a duplicate registration; the reverse direction is a migration instead, and removes the user-scope install. |
479
481
  | `<project>/.github/copilot-instructions.md` (`~/.copilot/instructions/token-goat.instructions.md` with `--user`) | A delimited VS Code routing block that documents supported MCP selection and what the agent hooks can and cannot do with built-in file reads. The user-scope file is a personal instructions file with `applyTo: '**'`, so VS Code applies it in every workspace; install creates it with that frontmatter if it is missing and otherwise merges the block in, and uninstall deletes it again when nothing else is left in it. A user-scope install never writes into the folder you run it from. |
480
- | `<project>/.github/hooks/token-goat.json`, `token-goat-shim.js`, `token-goat.owners` (`~/.copilot/hooks/` with `--user`) | VS Code agent hooks, shared with `--copilot`; the owners file records which of the two installs still uses them. |
482
+ | `<project>/.github/hooks/token-goat.json`, `token-goat-shim.cjs`, `token-goat-shim.js`, `token-goat.owners` (`~/.copilot/hooks/` with `--user`) | VS Code agent hooks, shared with `--copilot`; the owners file records which of the two installs still uses them. |
481
483
 
482
484
  **With `--visualstudio`** (Visual Studio MCP configuration; user scope by default, `-p`/`--project` for the solution folder)
483
485
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "token-goat",
3
- "version": "2.9.28",
3
+ "version": "2.9.29",
4
4
  "description": "Surgical token-reduction companion for Claude Code and other AI coding agents",
5
5
  "type": "module",
6
6
  "main": "./dist/token-goat.mjs",
@@ -1,47 +0,0 @@
1
- import { createRequire as __cjsRequire } from 'node:module';
2
- const require = __cjsRequire(import.meta.url);
3
- import {
4
- buildEvent,
5
- relay,
6
- relayInProcess
7
- } from "./token-goat-chunk-EL7M26WP.mjs";
8
- import "./token-goat-chunk-F7QZRIWM.mjs";
9
- import "./token-goat-chunk-I7CB3X4K.mjs";
10
- import {
11
- MAX_STDIN_BYTES,
12
- readStdinJson
13
- } from "./token-goat-chunk-VE27HPIF.mjs";
14
- import "./token-goat-chunk-6Z5ULNE5.mjs";
15
- import "./token-goat-chunk-IZXKVT4A.mjs";
16
- import "./token-goat-chunk-RJH64KQH.mjs";
17
- import "./token-goat-chunk-6DQNNFJ6.mjs";
18
- import "./token-goat-chunk-MMLMALWK.mjs";
19
- import "./token-goat-chunk-L7SDVGBT.mjs";
20
- import "./token-goat-chunk-6CCQDAYY.mjs";
21
- import "./token-goat-chunk-GGLEE35R.mjs";
22
- import "./token-goat-chunk-MAMQPC43.mjs";
23
- import "./token-goat-chunk-HXNAC4ZF.mjs";
24
- import "./token-goat-chunk-BJBRGPBX.mjs";
25
- import "./token-goat-chunk-4JMWPWCS.mjs";
26
- import "./token-goat-chunk-4RN64ZND.mjs";
27
- import "./token-goat-chunk-MVSWBNMD.mjs";
28
- import "./token-goat-chunk-3BTK54F3.mjs";
29
- import "./token-goat-chunk-D5ICEPSB.mjs";
30
- import "./token-goat-chunk-HUDC5GS5.mjs";
31
- import "./token-goat-chunk-M56BWPBN.mjs";
32
- import "./token-goat-chunk-CC2PYJM7.mjs";
33
- import "./token-goat-chunk-EEIDFMEM.mjs";
34
- import "./token-goat-chunk-OSUFN2FV.mjs";
35
- import "./token-goat-chunk-L45ZQRT7.mjs";
36
- import "./token-goat-chunk-NMTKNYGF.mjs";
37
- import "./token-goat-chunk-Y4AFKTHK.mjs";
38
- import "./token-goat-chunk-GMOUBOX4.mjs";
39
- import "./token-goat-chunk-RRNZMM3A.mjs";
40
- import "./token-goat-chunk-A37V4PBF.mjs";
41
- export {
42
- MAX_STDIN_BYTES,
43
- buildEvent,
44
- readStdinJson,
45
- relay,
46
- relayInProcess
47
- };
@@ -1,32 +0,0 @@
1
- import { createRequire as __cjsRequire } from 'node:module';
2
- const require = __cjsRequire(import.meta.url);
3
- import {
4
- DEFAULT_HEARTBEAT_INTERVAL_MS,
5
- DEFAULT_TIMEOUT_SECONDS,
6
- MAX_CAPTURE_BYTES,
7
- resolveFilter,
8
- run,
9
- runRaw
10
- } from "./token-goat-chunk-F7QZRIWM.mjs";
11
- import "./token-goat-chunk-RJH64KQH.mjs";
12
- import "./token-goat-chunk-HXNAC4ZF.mjs";
13
- import "./token-goat-chunk-BJBRGPBX.mjs";
14
- import "./token-goat-chunk-4RN64ZND.mjs";
15
- import "./token-goat-chunk-MVSWBNMD.mjs";
16
- import "./token-goat-chunk-HUDC5GS5.mjs";
17
- import "./token-goat-chunk-M56BWPBN.mjs";
18
- import "./token-goat-chunk-CC2PYJM7.mjs";
19
- import "./token-goat-chunk-EEIDFMEM.mjs";
20
- import "./token-goat-chunk-OSUFN2FV.mjs";
21
- import "./token-goat-chunk-L45ZQRT7.mjs";
22
- import "./token-goat-chunk-NMTKNYGF.mjs";
23
- import "./token-goat-chunk-GMOUBOX4.mjs";
24
- import "./token-goat-chunk-A37V4PBF.mjs";
25
- export {
26
- DEFAULT_HEARTBEAT_INTERVAL_MS,
27
- DEFAULT_TIMEOUT_SECONDS,
28
- MAX_CAPTURE_BYTES,
29
- resolveFilter,
30
- run,
31
- runRaw
32
- };
@@ -1,30 +0,0 @@
1
- import { createRequire as __cjsRequire } from 'node:module';
2
- const require = __cjsRequire(import.meta.url);
3
- import {
4
- MAX_RESUME_CHARS,
5
- MAX_RESUME_TOKENS,
6
- buildResumePacket
7
- } from "./token-goat-chunk-XI2VFAV6.mjs";
8
- import "./token-goat-chunk-L7SDVGBT.mjs";
9
- import "./token-goat-chunk-6CCQDAYY.mjs";
10
- import "./token-goat-chunk-GGLEE35R.mjs";
11
- import "./token-goat-chunk-MAMQPC43.mjs";
12
- import "./token-goat-chunk-HXNAC4ZF.mjs";
13
- import "./token-goat-chunk-BJBRGPBX.mjs";
14
- import "./token-goat-chunk-4JMWPWCS.mjs";
15
- import "./token-goat-chunk-4RN64ZND.mjs";
16
- import "./token-goat-chunk-MVSWBNMD.mjs";
17
- import "./token-goat-chunk-HUDC5GS5.mjs";
18
- import "./token-goat-chunk-M56BWPBN.mjs";
19
- import "./token-goat-chunk-CC2PYJM7.mjs";
20
- import "./token-goat-chunk-EEIDFMEM.mjs";
21
- import "./token-goat-chunk-OSUFN2FV.mjs";
22
- import "./token-goat-chunk-L45ZQRT7.mjs";
23
- import "./token-goat-chunk-NMTKNYGF.mjs";
24
- import "./token-goat-chunk-GMOUBOX4.mjs";
25
- import "./token-goat-chunk-A37V4PBF.mjs";
26
- export {
27
- MAX_RESUME_CHARS,
28
- MAX_RESUME_TOKENS,
29
- buildResumePacket
30
- };