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.
- package/README.md +2 -0
- package/dist/{token-goat-chunk-OZRSREKR.mjs → token-goat-chunk-2AWQ2R5X.mjs} +2 -2
- package/dist/{token-goat-chunk-5NNYIUGV.mjs → token-goat-chunk-2NNUA2LR.mjs} +4 -4
- package/dist/{token-goat-chunk-4RN64ZND.mjs → token-goat-chunk-2WOUYWLM.mjs} +2 -1
- package/dist/{token-goat-chunk-HUDC5GS5.mjs → token-goat-chunk-435UQTKD.mjs} +5 -3
- package/dist/{token-goat-chunk-6DQNNFJ6.mjs → token-goat-chunk-44BM7DDQ.mjs} +3 -3
- package/dist/{token-goat-chunk-4JMWPWCS.mjs → token-goat-chunk-52NSDWYY.mjs} +2 -2
- package/dist/{token-goat-chunk-IHKZ3QNA.mjs → token-goat-chunk-67BNIKKO.mjs} +19 -16
- package/dist/{token-goat-chunk-XBESNWEX.mjs → token-goat-chunk-6AK46ZT7.mjs} +2 -3
- package/dist/{token-goat-chunk-M56BWPBN.mjs → token-goat-chunk-7CPMDFGB.mjs} +166 -40
- package/dist/token-goat-chunk-ASLWOQ3I.mjs +14 -0
- package/dist/{token-goat-chunk-QM76S6YS.mjs → token-goat-chunk-BGYOZ6DO.mjs} +6 -4
- package/dist/{token-goat-chunk-JXK2HQXS.mjs → token-goat-chunk-C5YPNZKQ.mjs} +3 -3
- package/dist/{token-goat-chunk-MVSWBNMD.mjs → token-goat-chunk-CIQ2FTY3.mjs} +19 -14
- package/dist/{token-goat-chunk-BJBRGPBX.mjs → token-goat-chunk-D4ETHJD6.mjs} +6 -4
- package/dist/{token-goat-chunk-VE27HPIF.mjs → token-goat-chunk-DNRPXHYH.mjs} +21 -17
- package/dist/{token-goat-chunk-YWSP6IU7.mjs → token-goat-chunk-DNSPXQXQ.mjs} +2 -2
- package/dist/token-goat-chunk-DPNLUJWB.mjs +220 -0
- package/dist/{token-goat-chunk-I7CB3X4K.mjs → token-goat-chunk-E4ZOJIZK.mjs} +10 -7
- package/dist/{token-goat-chunk-IZXKVT4A.mjs → token-goat-chunk-E5TK5DNO.mjs} +11 -4
- package/dist/{token-goat-chunk-MMLMALWK.mjs → token-goat-chunk-EUSDXRXU.mjs} +60 -12
- package/dist/{token-goat-chunk-7R2XYKC5.mjs → token-goat-chunk-FTP4U4QA.mjs} +12 -9
- package/dist/{token-goat-chunk-LEG3JNJ6.mjs → token-goat-chunk-G23DWHV4.mjs} +17 -14
- package/dist/{token-goat-chunk-L7SDVGBT.mjs → token-goat-chunk-G7IWXCFF.mjs} +49 -23
- package/dist/{token-goat-chunk-NILVK7XM.mjs → token-goat-chunk-GLXRTTLE.mjs} +7 -5
- package/dist/{token-goat-chunk-6CCQDAYY.mjs → token-goat-chunk-H5J3C56Q.mjs} +35 -16
- package/dist/{token-goat-chunk-Q4S3UQGO.mjs → token-goat-chunk-HNFZZHFW.mjs} +2 -2
- package/dist/{token-goat-chunk-CBMY2FGI.mjs → token-goat-chunk-HUYUHODZ.mjs} +572 -230
- package/dist/token-goat-chunk-IVE6U7KV.mjs +53 -0
- package/dist/{token-goat-chunk-F7QZRIWM.mjs → token-goat-chunk-IVWI2OCK.mjs} +8 -30
- package/dist/{token-goat-chunk-GMOUBOX4.mjs → token-goat-chunk-JTKCQMQA.mjs} +37 -5
- package/dist/{token-goat-chunk-6SGLIPQB.mjs → token-goat-chunk-KOPIR3KZ.mjs} +12 -9
- package/dist/token-goat-chunk-L7H3U27L.mjs +35 -0
- package/dist/{token-goat-chunk-FSTWAOW6.mjs → token-goat-chunk-LZNBQTDK.mjs} +6 -4
- package/dist/token-goat-chunk-MELOKFDJ.mjs +199 -0
- package/dist/{token-goat-chunk-VWZKZPSR.mjs → token-goat-chunk-NMBWLRHW.mjs} +76 -39
- package/dist/{token-goat-chunk-HXNAC4ZF.mjs → token-goat-chunk-O6I2XU4P.mjs} +12 -10
- package/dist/{token-goat-chunk-MAMQPC43.mjs → token-goat-chunk-ONXH6NZ5.mjs} +1 -1
- package/dist/token-goat-chunk-ORNFMIER.mjs +295 -0
- package/dist/{token-goat-chunk-66LODAUT.mjs → token-goat-chunk-PGTH2U4C.mjs} +1 -1
- package/dist/{token-goat-chunk-SJEKA7Y2.mjs → token-goat-chunk-PKRWMHVP.mjs} +76 -64
- package/dist/{token-goat-chunk-DA43OE7L.mjs → token-goat-chunk-PQ53BSCF.mjs} +1 -1
- package/dist/{token-goat-chunk-RSS3TLXU.mjs → token-goat-chunk-PYSUADX4.mjs} +2 -2
- package/dist/{token-goat-chunk-EL7M26WP.mjs → token-goat-chunk-QO3LXVVR.mjs} +185 -104
- package/dist/{token-goat-chunk-XI2VFAV6.mjs → token-goat-chunk-RLP6J7WR.mjs} +6 -6
- package/dist/token-goat-chunk-RQGGMPCR.mjs +205 -0
- package/dist/{token-goat-chunk-6Z5ULNE5.mjs → token-goat-chunk-RTMVLHWX.mjs} +165 -60
- package/dist/{token-goat-chunk-E3K3BTEQ.mjs → token-goat-chunk-S4VSXURL.mjs} +8 -6
- package/dist/{token-goat-chunk-LKSXAMJB.mjs → token-goat-chunk-SE6E4BKJ.mjs} +1 -1
- package/dist/token-goat-chunk-TCQANXYC.mjs +351 -0
- package/dist/{token-goat-chunk-GGLEE35R.mjs → token-goat-chunk-TDUT2CL6.mjs} +7 -7
- package/dist/{token-goat-chunk-CC2PYJM7.mjs → token-goat-chunk-TGOXNAHW.mjs} +54 -112
- package/dist/{token-goat-chunk-XKY4VKJ4.mjs → token-goat-chunk-UA5BKWWQ.mjs} +1 -1
- package/dist/{token-goat-chunk-UBUKHVYW.mjs → token-goat-chunk-UXSXQQIY.mjs} +1 -1
- package/dist/{token-goat-chunk-D5ICEPSB.mjs → token-goat-chunk-VMFWNHGR.mjs} +79 -68
- package/dist/token-goat-chunk-VQ6F6T7X.mjs +36 -0
- package/dist/{token-goat-chunk-4STDIGYC.mjs → token-goat-chunk-VZQEWRVH.mjs} +6 -4
- package/dist/{token-goat-chunk-OSUFN2FV.mjs → token-goat-chunk-XB5KKOCG.mjs} +5 -25
- package/dist/{token-goat-chunk-L45ZQRT7.mjs → token-goat-chunk-XYWPOSCN.mjs} +57 -615
- package/dist/{token-goat-chunk-4JJBFT7V.mjs → token-goat-chunk-YAGLESS3.mjs} +8 -5
- package/dist/token-goat-chunk-YKSRAWUU.mjs +33 -0
- package/dist/{token-goat-chunk-F2ARFHLJ.mjs → token-goat-chunk-YOOVFPTP.mjs} +2 -2
- package/dist/{token-goat-chunk-EEIDFMEM.mjs → token-goat-chunk-YZAAZU2S.mjs} +12 -3
- package/dist/token-goat-chunk-Z6KBMOBI.mjs +53 -0
- package/dist/{token-goat-chunk-RJH64KQH.mjs → token-goat-chunk-ZER6EAXZ.mjs} +3 -3
- package/dist/token-goat-hook-client.cjs +475 -0
- package/dist/token-goat-hook-client.mjs +26 -0
- package/dist/token-goat-hook.mjs +31 -27
- package/dist/token-goat.core.mjs +9 -44
- package/docs/C4_RUNTIME_ARCHITECTURE.md +2 -2
- package/docs/cli.md +3 -2
- package/docs/install.md +16 -14
- package/package.json +1 -1
- package/dist/token-goat-chunk-7MAFDRVR.mjs +0 -47
- package/dist/token-goat-chunk-BCN2YQC6.mjs +0 -32
- package/dist/token-goat-chunk-D7GHQKQD.mjs +0 -30
- package/dist/token-goat-chunk-IFORDBGC.mjs +0 -192
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
compressText,
|
|
10
10
|
computeFileFingerprint,
|
|
11
11
|
createHandoff,
|
|
12
|
-
|
|
12
|
+
didYouMeanLines,
|
|
13
13
|
emit,
|
|
14
14
|
emitErr,
|
|
15
15
|
enclosingSymbol,
|
|
@@ -93,13 +93,16 @@ import {
|
|
|
93
93
|
runYamlQuery,
|
|
94
94
|
runZipList,
|
|
95
95
|
runZipRead,
|
|
96
|
+
statThroughHandle,
|
|
96
97
|
symbolNamesInFile,
|
|
97
98
|
upsertNote,
|
|
98
99
|
warnIfFilesStale
|
|
99
|
-
} from "./token-goat-chunk-
|
|
100
|
+
} from "./token-goat-chunk-NMBWLRHW.mjs";
|
|
101
|
+
import "./token-goat-chunk-VZQEWRVH.mjs";
|
|
100
102
|
import {
|
|
101
103
|
compareSemver
|
|
102
|
-
} from "./token-goat-chunk-
|
|
104
|
+
} from "./token-goat-chunk-2NNUA2LR.mjs";
|
|
105
|
+
import "./token-goat-chunk-PQ53BSCF.mjs";
|
|
103
106
|
import {
|
|
104
107
|
MCP_DISABLE_NOTE,
|
|
105
108
|
buildCopilotWasteReport,
|
|
@@ -107,10 +110,10 @@ import {
|
|
|
107
110
|
findProjectSession,
|
|
108
111
|
isCopilotTranscript,
|
|
109
112
|
unusedMcpServers
|
|
110
|
-
} from "./token-goat-chunk-
|
|
113
|
+
} from "./token-goat-chunk-C5YPNZKQ.mjs";
|
|
111
114
|
import {
|
|
112
115
|
buildResumePacket
|
|
113
|
-
} from "./token-goat-chunk-
|
|
116
|
+
} from "./token-goat-chunk-RLP6J7WR.mjs";
|
|
114
117
|
import {
|
|
115
118
|
DEFAULT_RECONCILE_BUDGET_MS,
|
|
116
119
|
HOOK_EVENTS,
|
|
@@ -129,7 +132,7 @@ import {
|
|
|
129
132
|
runRecallCommand,
|
|
130
133
|
runReconcile,
|
|
131
134
|
storeWebOutput
|
|
132
|
-
} from "./token-goat-chunk-
|
|
135
|
+
} from "./token-goat-chunk-DNRPXHYH.mjs";
|
|
133
136
|
import {
|
|
134
137
|
HINT_CATEGORIES,
|
|
135
138
|
MAX_FILES_SCANNED,
|
|
@@ -146,6 +149,7 @@ import {
|
|
|
146
149
|
compactDoc,
|
|
147
150
|
compactPathFor,
|
|
148
151
|
confirmAndApply,
|
|
152
|
+
dataDirWriteRefusal,
|
|
149
153
|
detectWalkMode,
|
|
150
154
|
dirtyQueuePathFor,
|
|
151
155
|
drainHeartbeatPathFor,
|
|
@@ -163,6 +167,7 @@ import {
|
|
|
163
167
|
formatSymbolLocation,
|
|
164
168
|
getDirtyPathsFor,
|
|
165
169
|
getEmbeddingCoverage,
|
|
170
|
+
getHintSpendTotals,
|
|
166
171
|
getHintStatsSummary,
|
|
167
172
|
getHintStatsTotals,
|
|
168
173
|
getParserFreshness,
|
|
@@ -201,28 +206,32 @@ import {
|
|
|
201
206
|
visionTokensSavedByText,
|
|
202
207
|
walkProject,
|
|
203
208
|
writeCompact
|
|
204
|
-
} from "./token-goat-chunk-
|
|
209
|
+
} from "./token-goat-chunk-RTMVLHWX.mjs";
|
|
210
|
+
import "./token-goat-chunk-L7H3U27L.mjs";
|
|
211
|
+
import "./token-goat-chunk-RRNZMM3A.mjs";
|
|
205
212
|
import {
|
|
206
213
|
GEMINI_TOOL_NAME_MAP
|
|
207
|
-
} from "./token-goat-chunk-
|
|
214
|
+
} from "./token-goat-chunk-E5TK5DNO.mjs";
|
|
208
215
|
import {
|
|
209
216
|
CompressedOutput,
|
|
210
217
|
TOOL_FILTERS,
|
|
211
218
|
ToolFilter,
|
|
212
219
|
deliverCompressed,
|
|
213
220
|
detectFromCommand
|
|
214
|
-
} from "./token-goat-chunk-
|
|
221
|
+
} from "./token-goat-chunk-ZER6EAXZ.mjs";
|
|
215
222
|
import {
|
|
216
223
|
buildWasteReport,
|
|
217
224
|
extractResultText,
|
|
218
225
|
findLatestTranscript,
|
|
219
226
|
projectTranscriptsDir,
|
|
220
227
|
safeStringify
|
|
221
|
-
} from "./token-goat-chunk-
|
|
228
|
+
} from "./token-goat-chunk-44BM7DDQ.mjs";
|
|
222
229
|
import {
|
|
223
230
|
COPILOT_CLI_HOOK_SCRIPT,
|
|
224
231
|
HOOKS_SCRIPT_FILE,
|
|
232
|
+
LEGACY_HOOKS_SCRIPT_FILE,
|
|
225
233
|
MATERIALIZE_SHRUNK_IMAGE_JS,
|
|
234
|
+
SHIM_TRY_SERVER,
|
|
226
235
|
buildGuidanceBlock,
|
|
227
236
|
buildGuidanceBody,
|
|
228
237
|
bundledCliPath,
|
|
@@ -257,14 +266,14 @@ import {
|
|
|
257
266
|
visualStudioProjectMcpPath,
|
|
258
267
|
visualStudioSolutionVscodeMcpPath,
|
|
259
268
|
visualStudioUserMcpPath
|
|
260
|
-
} from "./token-goat-chunk-
|
|
269
|
+
} from "./token-goat-chunk-EUSDXRXU.mjs";
|
|
261
270
|
import {
|
|
262
271
|
buildManifest,
|
|
263
272
|
clearAll,
|
|
264
273
|
loadEntries,
|
|
265
274
|
setEntry,
|
|
266
275
|
unsetEntry
|
|
267
|
-
} from "./token-goat-chunk-
|
|
276
|
+
} from "./token-goat-chunk-G7IWXCFF.mjs";
|
|
268
277
|
import {
|
|
269
278
|
AGENT_SALT_MARKER,
|
|
270
279
|
CONTEXT_AUTOCOMPACT_TOKENS,
|
|
@@ -288,37 +297,37 @@ import {
|
|
|
288
297
|
skillOutputsDir,
|
|
289
298
|
storeCompact,
|
|
290
299
|
storeOutput
|
|
291
|
-
} from "./token-goat-chunk-
|
|
300
|
+
} from "./token-goat-chunk-H5J3C56Q.mjs";
|
|
292
301
|
import {
|
|
293
302
|
getSessionFiles,
|
|
294
303
|
getSessionId
|
|
295
|
-
} from "./token-goat-chunk-
|
|
304
|
+
} from "./token-goat-chunk-TDUT2CL6.mjs";
|
|
296
305
|
import {
|
|
297
306
|
claudeConfigDir,
|
|
298
307
|
formatBytes,
|
|
299
308
|
formatTokenEstimate
|
|
300
|
-
} from "./token-goat-chunk-
|
|
309
|
+
} from "./token-goat-chunk-ONXH6NZ5.mjs";
|
|
301
310
|
import {
|
|
302
311
|
BASH_OUTPUT_SUBDIR,
|
|
303
312
|
getBashOutput,
|
|
304
313
|
isRecallCacheType
|
|
305
|
-
} from "./token-goat-chunk-
|
|
314
|
+
} from "./token-goat-chunk-O6I2XU4P.mjs";
|
|
306
315
|
import {
|
|
307
316
|
DEFAULT_MAX_AGE_MS,
|
|
308
317
|
DEFAULT_MAX_COUNT,
|
|
309
318
|
listBlobs,
|
|
310
319
|
pruneBlobs
|
|
311
|
-
} from "./token-goat-chunk-
|
|
320
|
+
} from "./token-goat-chunk-D4ETHJD6.mjs";
|
|
312
321
|
import {
|
|
313
322
|
capJsonRows,
|
|
314
323
|
estimateTokens,
|
|
315
324
|
estimateTokensFromLength,
|
|
316
325
|
trimToBudget
|
|
317
|
-
} from "./token-goat-chunk-
|
|
326
|
+
} from "./token-goat-chunk-52NSDWYY.mjs";
|
|
318
327
|
import {
|
|
319
328
|
clipLongMatchLine,
|
|
320
329
|
combineStreams
|
|
321
|
-
} from "./token-goat-chunk-
|
|
330
|
+
} from "./token-goat-chunk-2WOUYWLM.mjs";
|
|
322
331
|
import {
|
|
323
332
|
C,
|
|
324
333
|
HOOK_STATS_RETENTION_DAYS,
|
|
@@ -340,19 +349,28 @@ import {
|
|
|
340
349
|
statsHasHarnessColumn,
|
|
341
350
|
stripAnsiEscapes,
|
|
342
351
|
summarize
|
|
343
|
-
} from "./token-goat-chunk-
|
|
352
|
+
} from "./token-goat-chunk-CIQ2FTY3.mjs";
|
|
353
|
+
import {
|
|
354
|
+
queryServers,
|
|
355
|
+
serverStatuses
|
|
356
|
+
} from "./token-goat-chunk-RQGGMPCR.mjs";
|
|
357
|
+
import {
|
|
358
|
+
readMarker,
|
|
359
|
+
touchMarker
|
|
360
|
+
} from "./token-goat-chunk-DPNLUJWB.mjs";
|
|
361
|
+
import "./token-goat-chunk-SE6E4BKJ.mjs";
|
|
344
362
|
import {
|
|
345
363
|
docxOutline,
|
|
346
364
|
docxTables,
|
|
347
365
|
docxText,
|
|
348
366
|
formatDocxTables
|
|
349
|
-
} from "./token-goat-chunk-
|
|
367
|
+
} from "./token-goat-chunk-UA5BKWWQ.mjs";
|
|
350
368
|
import {
|
|
351
369
|
pptxNotesText,
|
|
352
370
|
pptxOutline,
|
|
353
371
|
pptxSlideText,
|
|
354
372
|
pptxTextGrep
|
|
355
|
-
} from "./token-goat-chunk-
|
|
373
|
+
} from "./token-goat-chunk-HNFZZHFW.mjs";
|
|
356
374
|
import {
|
|
357
375
|
formatXlsxColumns,
|
|
358
376
|
formatXlsxRange,
|
|
@@ -361,11 +379,16 @@ import {
|
|
|
361
379
|
querySheet,
|
|
362
380
|
rangeSheet,
|
|
363
381
|
xlsxColumns
|
|
364
|
-
} from "./token-goat-chunk-
|
|
382
|
+
} from "./token-goat-chunk-PYSUADX4.mjs";
|
|
365
383
|
import {
|
|
366
384
|
formatCsvTable,
|
|
367
385
|
parseWhereSpecs
|
|
368
|
-
} from "./token-goat-chunk-
|
|
386
|
+
} from "./token-goat-chunk-DNSPXQXQ.mjs";
|
|
387
|
+
import "./token-goat-chunk-3BTK54F3.mjs";
|
|
388
|
+
import "./token-goat-chunk-UXSXQQIY.mjs";
|
|
389
|
+
import "./token-goat-chunk-XTQAOTSO.mjs";
|
|
390
|
+
import "./token-goat-chunk-AH6QILZM.mjs";
|
|
391
|
+
import "./token-goat-chunk-PGTH2U4C.mjs";
|
|
369
392
|
import {
|
|
370
393
|
assetEmbedSha,
|
|
371
394
|
deleteFileEmbeddings,
|
|
@@ -387,18 +410,21 @@ import {
|
|
|
387
410
|
maxChunksEmbedSha,
|
|
388
411
|
missingTreeSitterGrammarPackages,
|
|
389
412
|
modelFilesPresent,
|
|
413
|
+
oversizeEmbedSha,
|
|
390
414
|
parserFingerprintForLanguage,
|
|
391
415
|
readSection,
|
|
392
416
|
treeSitterCoreAvailable,
|
|
393
417
|
treeSitterCoreLoadError
|
|
394
|
-
} from "./token-goat-chunk-
|
|
418
|
+
} from "./token-goat-chunk-VMFWNHGR.mjs";
|
|
395
419
|
import {
|
|
396
420
|
getFileEntry,
|
|
397
421
|
getProjectFileEntries,
|
|
422
|
+
projectScopeClause,
|
|
398
423
|
querySymbols
|
|
399
|
-
} from "./token-goat-chunk-
|
|
424
|
+
} from "./token-goat-chunk-435UQTKD.mjs";
|
|
400
425
|
import {
|
|
401
426
|
TREE_SITTER_LANGUAGES,
|
|
427
|
+
allowReadOnlyIndex,
|
|
402
428
|
detectLanguage,
|
|
403
429
|
detectLanguageOfFile,
|
|
404
430
|
fenceFor,
|
|
@@ -407,14 +433,13 @@ import {
|
|
|
407
433
|
matchGroovySlashy,
|
|
408
434
|
nonTreeSitterLanguageCount,
|
|
409
435
|
redactIfDotenv
|
|
410
|
-
} from "./token-goat-chunk-
|
|
436
|
+
} from "./token-goat-chunk-7CPMDFGB.mjs";
|
|
411
437
|
import {
|
|
412
438
|
CONFIG_KEY_ENV_OVERRIDES,
|
|
413
439
|
PROJECT_LOCKED_KEYS,
|
|
414
440
|
PROJECT_LOCKED_SECTIONS,
|
|
415
441
|
SUPPORTED_OCR_LANG_CODES,
|
|
416
442
|
defaultConfig,
|
|
417
|
-
envBool,
|
|
418
443
|
fileIsAbsent,
|
|
419
444
|
findProject,
|
|
420
445
|
fingerprintContent,
|
|
@@ -423,8 +448,10 @@ import {
|
|
|
423
448
|
getLastConfigParseError,
|
|
424
449
|
getLastProjectConfigParseError,
|
|
425
450
|
getProjectConfigInfo,
|
|
451
|
+
hookServerEnabled,
|
|
426
452
|
invalidateConfigCache,
|
|
427
453
|
isSupportedOcrLang,
|
|
454
|
+
isUnderSystemTemp,
|
|
428
455
|
lastProjectConfigLockedKeys,
|
|
429
456
|
loadConfig,
|
|
430
457
|
loadPersistedConfig,
|
|
@@ -436,22 +463,21 @@ import {
|
|
|
436
463
|
stringify,
|
|
437
464
|
validateEnumField,
|
|
438
465
|
validateNumericField
|
|
439
|
-
} from "./token-goat-chunk-
|
|
466
|
+
} from "./token-goat-chunk-TGOXNAHW.mjs";
|
|
467
|
+
import "./token-goat-chunk-XB5KKOCG.mjs";
|
|
468
|
+
import "./token-goat-chunk-YZAAZU2S.mjs";
|
|
469
|
+
import {
|
|
470
|
+
envBool
|
|
471
|
+
} from "./token-goat-chunk-IVE6U7KV.mjs";
|
|
440
472
|
import {
|
|
441
|
-
ENV_KEYS,
|
|
442
473
|
LOCK_WAIT_MS_HARDENED,
|
|
443
|
-
PACKAGE_NAME,
|
|
444
|
-
VERSION,
|
|
445
474
|
assertProjectScopeTarget,
|
|
446
475
|
assertWriteInScope,
|
|
447
476
|
atomicWriteBytes,
|
|
448
477
|
atomicWriteText,
|
|
449
478
|
backupFile,
|
|
450
|
-
canonicalize,
|
|
451
479
|
cappedSourceBytesSaved,
|
|
452
|
-
configPath,
|
|
453
480
|
countNoun,
|
|
454
|
-
dataDir,
|
|
455
481
|
decodeSource,
|
|
456
482
|
detectSourceEncoding,
|
|
457
483
|
encodeSource,
|
|
@@ -459,19 +485,16 @@ import {
|
|
|
459
485
|
ensureNewline,
|
|
460
486
|
escapeRegExp,
|
|
461
487
|
extractErrorMessage,
|
|
462
|
-
|
|
463
|
-
globalDbPath,
|
|
488
|
+
hasCreatedConfig,
|
|
464
489
|
hookCommandFor,
|
|
465
490
|
hookExecPartsFor,
|
|
466
491
|
installSingleFilePlugin,
|
|
467
492
|
isTestFile,
|
|
468
493
|
isUnderBlockedRoot,
|
|
469
|
-
isWindows,
|
|
470
494
|
pad,
|
|
471
495
|
projectPathIsConsultable,
|
|
472
496
|
projectScopeRoot,
|
|
473
497
|
pushAll,
|
|
474
|
-
quoteShellPath,
|
|
475
498
|
recordCreatedConfig,
|
|
476
499
|
redactUrlQuery,
|
|
477
500
|
removeCreatedBackups,
|
|
@@ -479,16 +502,13 @@ import {
|
|
|
479
502
|
removeFileInScope,
|
|
480
503
|
requireNonNegativeStrictInt,
|
|
481
504
|
requirePositiveStrictInt,
|
|
482
|
-
resolveOnPath,
|
|
483
505
|
runGit,
|
|
484
|
-
sleepSync,
|
|
485
506
|
stripDelimitedBlock,
|
|
486
507
|
stripLower,
|
|
487
508
|
stripOwnHooksFromMap,
|
|
488
509
|
stripStaleGroupHooks,
|
|
489
510
|
takeCreatedConfig,
|
|
490
511
|
toKB,
|
|
491
|
-
tokenGoatHome,
|
|
492
512
|
uninstallSingleFilePlugin,
|
|
493
513
|
upsertDelimitedBlock,
|
|
494
514
|
withExtension,
|
|
@@ -497,7 +517,15 @@ import {
|
|
|
497
517
|
withRetryOnLock,
|
|
498
518
|
writeIfDifferent,
|
|
499
519
|
writeJsonSettings
|
|
500
|
-
} from "./token-goat-chunk-
|
|
520
|
+
} from "./token-goat-chunk-XYWPOSCN.mjs";
|
|
521
|
+
import {
|
|
522
|
+
canonicalize,
|
|
523
|
+
foldPath,
|
|
524
|
+
isWindows,
|
|
525
|
+
quoteShellPath,
|
|
526
|
+
resolveOnPath,
|
|
527
|
+
sleepSync
|
|
528
|
+
} from "./token-goat-chunk-TCQANXYC.mjs";
|
|
501
529
|
import {
|
|
502
530
|
UNTRUSTED_FILE_TAG,
|
|
503
531
|
UNTRUSTED_TOOL_TAG,
|
|
@@ -512,9 +540,19 @@ import {
|
|
|
512
540
|
resolveIndexPath,
|
|
513
541
|
toDisplayPath
|
|
514
542
|
} from "./token-goat-chunk-NMTKNYGF.mjs";
|
|
543
|
+
import {
|
|
544
|
+
ENV_KEYS,
|
|
545
|
+
PACKAGE_NAME,
|
|
546
|
+
VERSION,
|
|
547
|
+
configPath,
|
|
548
|
+
dataDir,
|
|
549
|
+
globalDbPath,
|
|
550
|
+
tokenGoatHome
|
|
551
|
+
} from "./token-goat-chunk-MELOKFDJ.mjs";
|
|
552
|
+
import "./token-goat-chunk-Y4AFKTHK.mjs";
|
|
515
553
|
import {
|
|
516
554
|
compileGuardedRegex
|
|
517
|
-
} from "./token-goat-chunk-
|
|
555
|
+
} from "./token-goat-chunk-JTKCQMQA.mjs";
|
|
518
556
|
import {
|
|
519
557
|
__export,
|
|
520
558
|
init_define_import_meta_env
|
|
@@ -4010,6 +4048,18 @@ init_define_import_meta_env();
|
|
|
4010
4048
|
|
|
4011
4049
|
// src/bridges/shim_common.ts
|
|
4012
4050
|
init_define_import_meta_env();
|
|
4051
|
+
var SHIM_FILE = "token-goat-shim.cjs";
|
|
4052
|
+
var LEGACY_SHIM_FILE = "token-goat-shim.js";
|
|
4053
|
+
function legacyShimForwarder(noOp) {
|
|
4054
|
+
const answer = noOp === "" ? "" : `
|
|
4055
|
+
try { process.stdout.write('${noOp}') } catch {}`;
|
|
4056
|
+
return `#!/usr/bin/env node
|
|
4057
|
+
// Forwards to token-goat-shim.cjs for hook commands wired before the shim was renamed.
|
|
4058
|
+
import('./token-goat-shim.cjs').catch(() => {${answer}
|
|
4059
|
+
process.exitCode = 0
|
|
4060
|
+
});
|
|
4061
|
+
`;
|
|
4062
|
+
}
|
|
4013
4063
|
var SHIM_REQUIRES = `const { spawnSync } = require('node:child_process')
|
|
4014
4064
|
const path = require('node:path')
|
|
4015
4065
|
const { pathToFileURL } = require('node:url')`;
|
|
@@ -4041,10 +4091,12 @@ var SHIM_TRY_IN_PROCESS = `// Attempts the in-process hook call: import()s dist/
|
|
|
4041
4091
|
async function tryInProcess(entryPath, eventName, input, harnessWaitMs) {
|
|
4042
4092
|
if (!entryPath) return undefined
|
|
4043
4093
|
try {
|
|
4094
|
+
const payload = JSON.parse(input)
|
|
4095
|
+
const served = await tryServer(entryPath, eventName, input, harnessWaitMs)
|
|
4096
|
+
if (served !== undefined) return served
|
|
4044
4097
|
const hookLibPath = path.join(path.dirname(entryPath), 'token-goat-hook.mjs')
|
|
4045
4098
|
if (!require('node:fs').existsSync(hookLibPath)) return undefined
|
|
4046
4099
|
const mod = await import(pathToFileURL(hookLibPath).href)
|
|
4047
|
-
const payload = JSON.parse(input)
|
|
4048
4100
|
return await mod.relayInProcess(eventName, payload, harnessWaitMs)
|
|
4049
4101
|
} catch {
|
|
4050
4102
|
return undefined
|
|
@@ -4130,6 +4182,8 @@ ${SHIM_REQUIRES}
|
|
|
4130
4182
|
|
|
4131
4183
|
${SHIM_VALID_HOOK_EVENTS}
|
|
4132
4184
|
|
|
4185
|
+
${SHIM_TRY_SERVER}
|
|
4186
|
+
|
|
4133
4187
|
${SHIM_TRY_IN_PROCESS}
|
|
4134
4188
|
|
|
4135
4189
|
${SHIM_MAX_BUFFER_CONST}
|
|
@@ -4280,21 +4334,46 @@ function execFormSupportedForVersionOutput(stdout) {
|
|
|
4280
4334
|
function expectedHookEntryFor(scriptPath, event) {
|
|
4281
4335
|
return claudeExecFormHooksSupported() ? hookExecPartsFor(scriptPath, event) : { command: hookCommandFor(scriptPath, event) };
|
|
4282
4336
|
}
|
|
4337
|
+
function realPathOrNull(p) {
|
|
4338
|
+
if (!path3.isAbsolute(p)) return null;
|
|
4339
|
+
try {
|
|
4340
|
+
return fs3.realpathSync.native(p);
|
|
4341
|
+
} catch {
|
|
4342
|
+
return null;
|
|
4343
|
+
}
|
|
4344
|
+
}
|
|
4345
|
+
function sameHookWord(a, b) {
|
|
4346
|
+
if (a === b) return true;
|
|
4347
|
+
const realA = realPathOrNull(a);
|
|
4348
|
+
return realA !== null && realA === realPathOrNull(b);
|
|
4349
|
+
}
|
|
4350
|
+
function stringFormHookWords(command) {
|
|
4351
|
+
const words = [];
|
|
4352
|
+
for (const m of command.matchAll(/"((?:\\.|[^"\\])*)"|(\S+)/g)) {
|
|
4353
|
+
const quoted = m[1];
|
|
4354
|
+
words.push(quoted === void 0 ? m[2] : process.platform === "win32" ? quoted : quoted.replace(/\\(.)/g, "$1"));
|
|
4355
|
+
}
|
|
4356
|
+
return words;
|
|
4357
|
+
}
|
|
4283
4358
|
function hookEntryMatches(command, args, expected) {
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
const
|
|
4287
|
-
|
|
4359
|
+
const execForm = expected.args !== void 0;
|
|
4360
|
+
if (!execForm && args !== void 0 && args.length > 0) return false;
|
|
4361
|
+
const a = execForm ? [command, ...args ?? []] : stringFormHookWords(command);
|
|
4362
|
+
const b = execForm ? [expected.command, ...expected.args] : stringFormHookWords(expected.command);
|
|
4363
|
+
return a.length === b.length && a.every((v, i) => sameHookWord(v, b[i]));
|
|
4288
4364
|
}
|
|
4289
4365
|
function claudeHookScriptPath() {
|
|
4290
|
-
return path3.join(claudeConfigDir(), "hooks",
|
|
4366
|
+
return path3.join(claudeConfigDir(), "hooks", SHIM_FILE);
|
|
4367
|
+
}
|
|
4368
|
+
function claudeLegacyHookScriptPath() {
|
|
4369
|
+
return path3.join(claudeConfigDir(), "hooks", LEGACY_SHIM_FILE);
|
|
4291
4370
|
}
|
|
4292
|
-
function anyScopeReferencesShim(
|
|
4371
|
+
function anyScopeReferencesShim(scriptPaths, currentScope, alreadyStripped) {
|
|
4293
4372
|
const referencesIn = (map) => {
|
|
4294
4373
|
for (const groups of Object.values(map ?? {})) {
|
|
4295
4374
|
for (const group of groups) {
|
|
4296
4375
|
for (const h of group.hooks ?? []) {
|
|
4297
|
-
if (h.command.includes(
|
|
4376
|
+
if (scriptPaths.some((p) => h.command.includes(p) || (h.args ?? []).some((a) => a.includes(p)))) return true;
|
|
4298
4377
|
}
|
|
4299
4378
|
}
|
|
4300
4379
|
}
|
|
@@ -4363,7 +4442,9 @@ function installHooksScoped(scope) {
|
|
|
4363
4442
|
const scriptPath = claudeHookScriptPath();
|
|
4364
4443
|
const scriptChanged = withInstallScope(void 0, () => {
|
|
4365
4444
|
ensureDirSync(path3.dirname(scriptPath));
|
|
4366
|
-
|
|
4445
|
+
const forwarderChanged = writeIfDifferent(claudeLegacyHookScriptPath(), legacyShimForwarder("{}"));
|
|
4446
|
+
const scriptChanged2 = writeIfDifferent(scriptPath, CLAUDECODE_HOOK_SCRIPT);
|
|
4447
|
+
return scriptChanged2 || forwarderChanged;
|
|
4367
4448
|
});
|
|
4368
4449
|
let settingsChanged = false;
|
|
4369
4450
|
for (const [eventKey, eventArg] of HOOK_EVENT_MAP) {
|
|
@@ -4430,8 +4511,8 @@ function uninstallHooksScoped(scope) {
|
|
|
4430
4511
|
const removed = stripOwnHooksFromMap(hooks, isTokenGoatHookCommand);
|
|
4431
4512
|
const scriptPath = claudeHookScriptPath();
|
|
4432
4513
|
let removedScript = false;
|
|
4433
|
-
if (!anyScopeReferencesShim(scriptPath, scope, hooks)) {
|
|
4434
|
-
removedScript = withInstallScope(void 0, () => removeFileInScope(
|
|
4514
|
+
if (!anyScopeReferencesShim([scriptPath, claudeLegacyHookScriptPath()], scope, hooks)) {
|
|
4515
|
+
removedScript = withInstallScope(void 0, () => [scriptPath, claudeLegacyHookScriptPath()].map((p2) => removeFileInScope(p2)).some(Boolean));
|
|
4435
4516
|
}
|
|
4436
4517
|
if (!removed) return removedScript;
|
|
4437
4518
|
if (Object.keys(hooks).length === 0) {
|
|
@@ -4610,6 +4691,8 @@ function stripTg(value) {
|
|
|
4610
4691
|
return value
|
|
4611
4692
|
}
|
|
4612
4693
|
|
|
4694
|
+
${SHIM_TRY_SERVER}
|
|
4695
|
+
|
|
4613
4696
|
${SHIM_TRY_IN_PROCESS}
|
|
4614
4697
|
|
|
4615
4698
|
${SHIM_MAX_BUFFER_CONST}
|
|
@@ -4729,7 +4812,10 @@ function codexAgentsPath() {
|
|
|
4729
4812
|
return path4.join(os2.homedir(), ".codex", "AGENTS.md");
|
|
4730
4813
|
}
|
|
4731
4814
|
function codexHookScriptPath() {
|
|
4732
|
-
return path4.join(os2.homedir(), ".codex", "hooks",
|
|
4815
|
+
return path4.join(os2.homedir(), ".codex", "hooks", SHIM_FILE);
|
|
4816
|
+
}
|
|
4817
|
+
function codexLegacyHookScriptPath() {
|
|
4818
|
+
return path4.join(os2.homedir(), ".codex", "hooks", LEGACY_SHIM_FILE);
|
|
4733
4819
|
}
|
|
4734
4820
|
function readCodexConfig(p, opts = {}) {
|
|
4735
4821
|
let raw;
|
|
@@ -4786,6 +4872,7 @@ function installCodex() {
|
|
|
4786
4872
|
const scriptPath = codexHookScriptPath();
|
|
4787
4873
|
ensureDirSync(path4.dirname(scriptPath));
|
|
4788
4874
|
atomicWriteText(scriptPath, CODEX_HOOK_SCRIPT);
|
|
4875
|
+
atomicWriteText(codexLegacyHookScriptPath(), legacyShimForwarder("{}"));
|
|
4789
4876
|
const config = readCodexConfig(configPath2, { strict: true });
|
|
4790
4877
|
const hooks = config.hooks ?? {};
|
|
4791
4878
|
let hooksChanged = false;
|
|
@@ -4939,10 +5026,12 @@ function uninstallCodex() {
|
|
|
4939
5026
|
if (stripAgentsBlock(agentsPath)) {
|
|
4940
5027
|
removedAny = true;
|
|
4941
5028
|
}
|
|
4942
|
-
|
|
4943
|
-
|
|
4944
|
-
|
|
4945
|
-
|
|
5029
|
+
for (const p of [scriptPath, codexLegacyHookScriptPath()]) {
|
|
5030
|
+
try {
|
|
5031
|
+
fs4.unlinkSync(p);
|
|
5032
|
+
removedAny = true;
|
|
5033
|
+
} catch {
|
|
5034
|
+
}
|
|
4946
5035
|
}
|
|
4947
5036
|
removeCreatedBackups(configPath2);
|
|
4948
5037
|
return removedAny;
|
|
@@ -5320,6 +5409,8 @@ function toKimi(parsed) {
|
|
|
5320
5409
|
return ''
|
|
5321
5410
|
}
|
|
5322
5411
|
|
|
5412
|
+
${SHIM_TRY_SERVER}
|
|
5413
|
+
|
|
5323
5414
|
${SHIM_TRY_IN_PROCESS}
|
|
5324
5415
|
|
|
5325
5416
|
${SHIM_MAX_BUFFER_CONST}
|
|
@@ -5393,7 +5484,10 @@ function kimiAgentsPath() {
|
|
|
5393
5484
|
return path7.join(kimiHome(), "AGENTS.md");
|
|
5394
5485
|
}
|
|
5395
5486
|
function kimiHookScriptPath() {
|
|
5396
|
-
return path7.join(kimiHome(), "hooks",
|
|
5487
|
+
return path7.join(kimiHome(), "hooks", SHIM_FILE);
|
|
5488
|
+
}
|
|
5489
|
+
function kimiLegacyHookScriptPath() {
|
|
5490
|
+
return path7.join(kimiHome(), "hooks", LEGACY_SHIM_FILE);
|
|
5397
5491
|
}
|
|
5398
5492
|
function kimiSkillDir() {
|
|
5399
5493
|
return path7.join(kimiHome(), "skills", "token-goat");
|
|
@@ -5463,6 +5557,7 @@ function installKimi() {
|
|
|
5463
5557
|
const scriptPath = kimiHookScriptPath();
|
|
5464
5558
|
ensureDirSync(path7.dirname(scriptPath));
|
|
5465
5559
|
atomicWriteText(scriptPath, KIMI_HOOK_SCRIPT);
|
|
5560
|
+
atomicWriteText(kimiLegacyHookScriptPath(), legacyShimForwarder(""));
|
|
5466
5561
|
const config = readKimiConfig(configPath2, { strict: true });
|
|
5467
5562
|
const existing = Array.isArray(config.hooks) ? config.hooks : [];
|
|
5468
5563
|
const desired = KIMI_HOOK_EVENTS.map((event) => ({
|
|
@@ -5514,12 +5609,14 @@ function uninstallKimi() {
|
|
|
5514
5609
|
}
|
|
5515
5610
|
} catch {
|
|
5516
5611
|
}
|
|
5517
|
-
|
|
5518
|
-
|
|
5519
|
-
fs7.
|
|
5520
|
-
|
|
5612
|
+
for (const p of [kimiHookScriptPath(), kimiLegacyHookScriptPath()]) {
|
|
5613
|
+
try {
|
|
5614
|
+
if (fs7.existsSync(p)) {
|
|
5615
|
+
fs7.rmSync(p, { force: true });
|
|
5616
|
+
removed = true;
|
|
5617
|
+
}
|
|
5618
|
+
} catch {
|
|
5521
5619
|
}
|
|
5522
|
-
} catch {
|
|
5523
5620
|
}
|
|
5524
5621
|
removeCreatedBackups(configPath2);
|
|
5525
5622
|
return removed;
|
|
@@ -5613,7 +5710,7 @@ function resolveEntryPath(): string | undefined {
|
|
|
5613
5710
|
// undefined (triggering the spawnSync fallback below) when entryPath is absent, the
|
|
5614
5711
|
// sibling file doesn't exist (an install predating this file), or anything else goes
|
|
5615
5712
|
// wrong -- this must never throw.
|
|
5616
|
-
type RelayInProcessFn = (event: string, payload: unknown) => Promise<string>;
|
|
5713
|
+
type RelayInProcessFn = (event: string, payload: unknown, harnessWaitMs?: number, opts?: { elapsedMs?: () => number }) => Promise<string>;
|
|
5617
5714
|
let cachedRelayInProcess: RelayInProcessFn | undefined;
|
|
5618
5715
|
async function resolveRelayInProcess(): Promise<RelayInProcessFn | undefined> {
|
|
5619
5716
|
if (cachedRelayInProcess) return cachedRelayInProcess;
|
|
@@ -5681,11 +5778,13 @@ function callHookViaSpawn(event: string, payload: Record<string, unknown>): Reco
|
|
|
5681
5778
|
// its own fail-open null rather than being force-killed by pi's own hook timeout
|
|
5682
5779
|
// budget, ~5000ms) when the in-process path is unavailable or throws.
|
|
5683
5780
|
async function callHook(event: string, payload: Record<string, unknown>): Promise<Record<string, unknown> | null> {
|
|
5781
|
+
// Timed from here, not from process start: this host lives far longer than one call, so the hook library's default clock (process age) would record the host's uptime as this call's duration.
|
|
5782
|
+
const start = performance.now();
|
|
5684
5783
|
const relay = await resolveRelayInProcess();
|
|
5685
5784
|
if (relay) {
|
|
5686
5785
|
try {
|
|
5687
5786
|
process.env.TOKEN_GOAT_HARNESS_OVERRIDE = "pi";
|
|
5688
|
-
const out = await relay(event, payload);
|
|
5787
|
+
const out = await relay(event, payload, undefined, { elapsedMs: () => performance.now() - start });
|
|
5689
5788
|
const trimmed = out?.trim();
|
|
5690
5789
|
if (!trimmed) return null;
|
|
5691
5790
|
return JSON.parse(trimmed) as Record<string, unknown>;
|
|
@@ -6047,10 +6146,12 @@ function callHookViaSpawn(event, payload) {
|
|
|
6047
6146
|
// its own fail-open null rather than being force-killed by the host's own hook timeout
|
|
6048
6147
|
// budget, ~5000ms) when the in-process path is unavailable or throws.
|
|
6049
6148
|
async function callHook(event, payload) {
|
|
6149
|
+
// Timed from here, not from process start: this host lives far longer than one call, so the hook library's default clock (process age) would record the host's uptime as this call's duration.
|
|
6150
|
+
const start = performance.now();
|
|
6050
6151
|
const relay = await resolveRelayInProcess();
|
|
6051
6152
|
if (relay) {
|
|
6052
6153
|
try {
|
|
6053
|
-
const out = await relay(event, payload);
|
|
6154
|
+
const out = await relay(event, payload, undefined, { elapsedMs: () => performance.now() - start });
|
|
6054
6155
|
const trimmed = out ? out.trim() : "";
|
|
6055
6156
|
if (!trimmed) return null;
|
|
6056
6157
|
return JSON.parse(trimmed);
|
|
@@ -6580,6 +6681,8 @@ function allowResponse(eventName) {
|
|
|
6580
6681
|
return eventName === 'pre_tool_use' ? '{"decision":"allow"}' : '{}'
|
|
6581
6682
|
}
|
|
6582
6683
|
|
|
6684
|
+
${SHIM_TRY_SERVER}
|
|
6685
|
+
|
|
6583
6686
|
${SHIM_TRY_IN_PROCESS}
|
|
6584
6687
|
|
|
6585
6688
|
${SHIM_MAX_BUFFER_CONST}
|
|
@@ -6673,7 +6776,10 @@ function grokConfigPath() {
|
|
|
6673
6776
|
return path11.join(grokHooksDir(), "token-goat.json");
|
|
6674
6777
|
}
|
|
6675
6778
|
function grokHookScriptPath() {
|
|
6676
|
-
return path11.join(grokHooksDir(),
|
|
6779
|
+
return path11.join(grokHooksDir(), SHIM_FILE);
|
|
6780
|
+
}
|
|
6781
|
+
function grokLegacyHookScriptPath() {
|
|
6782
|
+
return path11.join(grokHooksDir(), LEGACY_SHIM_FILE);
|
|
6677
6783
|
}
|
|
6678
6784
|
function buildConfig(scriptPath) {
|
|
6679
6785
|
const hooks = {};
|
|
@@ -6687,11 +6793,12 @@ function buildConfig(scriptPath) {
|
|
|
6687
6793
|
function installGrok() {
|
|
6688
6794
|
const configPath2 = grokConfigPath();
|
|
6689
6795
|
const scriptPath = grokHookScriptPath();
|
|
6796
|
+
const forwarderChanged = writeIfDifferent(grokLegacyHookScriptPath(), legacyShimForwarder("{}"));
|
|
6690
6797
|
const scriptChanged = writeIfDifferent(scriptPath, GROK_HOOK_SCRIPT);
|
|
6691
6798
|
const desiredText = `${JSON.stringify(buildConfig(scriptPath), null, 2)}
|
|
6692
6799
|
`;
|
|
6693
6800
|
const configChanged = writeIfDifferent(configPath2, desiredText, true);
|
|
6694
|
-
return { configPath: configPath2, hookScriptPath: scriptPath, alreadyInstalled: !scriptChanged && !configChanged };
|
|
6801
|
+
return { configPath: configPath2, hookScriptPath: scriptPath, alreadyInstalled: !scriptChanged && !forwarderChanged && !configChanged };
|
|
6695
6802
|
}
|
|
6696
6803
|
function uninstallGrok() {
|
|
6697
6804
|
const configPath2 = grokConfigPath();
|
|
@@ -6702,10 +6809,12 @@ function uninstallGrok() {
|
|
|
6702
6809
|
removedAny = true;
|
|
6703
6810
|
} catch {
|
|
6704
6811
|
}
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6812
|
+
for (const p of [scriptPath, grokLegacyHookScriptPath()]) {
|
|
6813
|
+
try {
|
|
6814
|
+
fs11.unlinkSync(p);
|
|
6815
|
+
removedAny = true;
|
|
6816
|
+
} catch {
|
|
6817
|
+
}
|
|
6709
6818
|
}
|
|
6710
6819
|
removeCreatedBackups(configPath2);
|
|
6711
6820
|
return removedAny;
|
|
@@ -7193,6 +7302,9 @@ init_define_import_meta_env();
|
|
|
7193
7302
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
7194
7303
|
import * as fs15 from "node:fs";
|
|
7195
7304
|
import * as path15 from "node:path";
|
|
7305
|
+
var ProcessListTimeout = class extends Error {
|
|
7306
|
+
};
|
|
7307
|
+
var PROCESS_LIST_TIMEOUT_MS = 2e4;
|
|
7196
7308
|
var INTERPRETER_BASENAMES = /* @__PURE__ */ new Set(["node.exe", "python.exe", "python3.exe", "pwsh.exe", "powershell.exe", "cmd.exe"]);
|
|
7197
7309
|
function describeProcess(commandLine) {
|
|
7198
7310
|
for (const m of commandLine.matchAll(/[^\s"]+\.(?:js|mjs|cjs|ts|py|exe)\b/gi)) {
|
|
@@ -7203,11 +7315,14 @@ function describeProcess(commandLine) {
|
|
|
7203
7315
|
return trimmed.length > 0 ? trimmed.length > 60 ? trimmed.slice(0, 60) + "\u2026" : trimmed : "(no command line)";
|
|
7204
7316
|
}
|
|
7205
7317
|
function checkMcpProcessHealth(processes) {
|
|
7206
|
-
if (processes
|
|
7318
|
+
if (!Array.isArray(processes)) {
|
|
7319
|
+
const failure = processes;
|
|
7320
|
+
const query = `Get-CimInstance Win32_Process -Filter "Name='node.exe'" | Select-Object ProcessId,ParentProcessId,CommandLine`;
|
|
7321
|
+
const advice = failure.transient === true ? `Run doctor again once the machine is less busy, or list them yourself with: ${query}` : `List them yourself with: ${query}`;
|
|
7207
7322
|
return {
|
|
7208
7323
|
name: "MCP process health",
|
|
7209
7324
|
status: "warn",
|
|
7210
|
-
message:
|
|
7325
|
+
message: `could not read the process list (${displaySafeText(failure.reason)}), so duplicate MCP launchers and orphaned Node processes were not checked. ${advice}`
|
|
7211
7326
|
};
|
|
7212
7327
|
}
|
|
7213
7328
|
const byPid = new Set(processes.map((process3) => process3.processId));
|
|
@@ -7240,19 +7355,37 @@ function runProcessListCommand() {
|
|
|
7240
7355
|
const shell = path15.join(systemRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe");
|
|
7241
7356
|
const result = spawnSync2(fs15.existsSync(shell) ? shell : "powershell.exe", ["-NoProfile", "-NonInteractive", "-Command", command], {
|
|
7242
7357
|
encoding: "utf8",
|
|
7243
|
-
timeout:
|
|
7358
|
+
timeout: PROCESS_LIST_TIMEOUT_MS,
|
|
7244
7359
|
maxBuffer: 10 * 1024 * 1024,
|
|
7245
7360
|
windowsHide: true
|
|
7246
7361
|
});
|
|
7247
|
-
|
|
7248
|
-
|
|
7362
|
+
return processListOutput(result);
|
|
7363
|
+
}
|
|
7364
|
+
function processListOutput(result) {
|
|
7365
|
+
if (result.error !== void 0) {
|
|
7366
|
+
const code = result.error.code;
|
|
7367
|
+
if (code === "ETIMEDOUT") throw new ProcessListTimeout(`PowerShell did not finish within ${PROCESS_LIST_TIMEOUT_MS / 1e3}s`);
|
|
7368
|
+
if (code === "ENOENT") throw new Error("powershell.exe was not found");
|
|
7369
|
+
throw result.error;
|
|
7370
|
+
}
|
|
7371
|
+
const stdout = result.stdout ?? "";
|
|
7372
|
+
if (result.status !== 0 && stdout.trim() === "") {
|
|
7373
|
+
const firstLine2 = (result.stderr ?? "").split(/\r?\n/).map((line) => line.trim()).find((line) => line !== "");
|
|
7374
|
+
throw new Error(`PowerShell exited with code ${String(result.status)}${firstLine2 !== void 0 ? `: ${firstLine2}` : ""}`);
|
|
7375
|
+
}
|
|
7376
|
+
return stdout;
|
|
7249
7377
|
}
|
|
7250
7378
|
function readWindowsProcesses(runCommand = runProcessListCommand) {
|
|
7251
7379
|
if (process.platform !== "win32") return [];
|
|
7252
7380
|
try {
|
|
7253
7381
|
const output = runCommand().trim();
|
|
7254
7382
|
if (output === "") return [];
|
|
7255
|
-
|
|
7383
|
+
let parsed;
|
|
7384
|
+
try {
|
|
7385
|
+
parsed = JSON.parse(output);
|
|
7386
|
+
} catch {
|
|
7387
|
+
return { reason: "PowerShell printed something other than the JSON process list" };
|
|
7388
|
+
}
|
|
7256
7389
|
const rows = Array.isArray(parsed) ? parsed : [parsed];
|
|
7257
7390
|
return rows.flatMap((row) => {
|
|
7258
7391
|
if (typeof row !== "object" || row === null) return [];
|
|
@@ -7265,8 +7398,9 @@ function readWindowsProcesses(runCommand = runProcessListCommand) {
|
|
|
7265
7398
|
commandLine: typeof value["CommandLine"] === "string" ? value["CommandLine"] : ""
|
|
7266
7399
|
}];
|
|
7267
7400
|
});
|
|
7268
|
-
} catch {
|
|
7269
|
-
|
|
7401
|
+
} catch (e) {
|
|
7402
|
+
const reason = e instanceof Error ? e.message : String(e);
|
|
7403
|
+
return e instanceof ProcessListTimeout ? { reason, transient: true } : { reason };
|
|
7270
7404
|
}
|
|
7271
7405
|
}
|
|
7272
7406
|
function checkWorkerRunning(dataDir2) {
|
|
@@ -7598,35 +7732,31 @@ function freelistBytes(header) {
|
|
|
7598
7732
|
const rawPageSize = header.readUInt16BE(16);
|
|
7599
7733
|
return (rawPageSize === 1 ? 65536 : rawPageSize) * header.readUInt32BE(36);
|
|
7600
7734
|
}
|
|
7601
|
-
var
|
|
7602
|
-
{ name: "
|
|
7603
|
-
{ name: "
|
|
7604
|
-
{
|
|
7605
|
-
|
|
7735
|
+
var STORAGE_GROUPS = [
|
|
7736
|
+
{ name: "refs", owns: /^refs$/, command: "grows with the files indexed, so it shrinks only when files leave the index" },
|
|
7737
|
+
{ name: "symbols and their search index", owns: /^symbols(_fts\w*)?$/, command: "grows with the files indexed, so it shrinks only when files leave the index" },
|
|
7738
|
+
{
|
|
7739
|
+
name: "embeddings",
|
|
7740
|
+
owns: /^(chunks|chunk_vectors\w*)$/,
|
|
7741
|
+
command: "these back 'semantic'; to drop them, set indexing.embeddings_enabled = false and indexing.auto_reclaim_embeddings = true, then run 'token-goat doctor --repair'"
|
|
7742
|
+
},
|
|
7743
|
+
{ name: "usage stats", owns: /^(stats\w*|hint_\w+|unmapped_tools)$/, command: "ages out on its own (180-day retention)" },
|
|
7744
|
+
{ name: "recall cache", owns: /^cache_recall\w*$/, command: "ages out on its own" }
|
|
7606
7745
|
];
|
|
7607
|
-
var
|
|
7746
|
+
var OWNER_BYTES_SQL = `SELECT COALESCE(m.tbl_name, s.name) AS owner, SUM(s.pgsize) AS bytes FROM dbstat AS s LEFT JOIN sqlite_master AS m ON m.name = s.name WHERE s.aggregate = 1 GROUP BY owner`;
|
|
7608
7747
|
function dbCategoryBreakdown(dbPath) {
|
|
7609
|
-
|
|
7610
|
-
const shares = [];
|
|
7611
|
-
for (const cat of CATEGORY_COLUMNS) {
|
|
7612
|
-
try {
|
|
7613
|
-
const row = db.prepare(`SELECT COALESCE(SUM(LENGTH(${cat.column})), 0) as bytes FROM ${cat.table}`).get();
|
|
7614
|
-
if (row.bytes > 0) shares.push({ name: cat.name, bytes: row.bytes, command: cat.command });
|
|
7615
|
-
} catch {
|
|
7616
|
-
}
|
|
7617
|
-
}
|
|
7748
|
+
let rows;
|
|
7618
7749
|
try {
|
|
7619
|
-
|
|
7620
|
-
if (row.n > 0) {
|
|
7621
|
-
shares.push({
|
|
7622
|
-
name: "embedding vectors",
|
|
7623
|
-
bytes: row.n * VECTOR_BYTES_PER_ROW,
|
|
7624
|
-
command: "'token-goat reclaim-index --rebuild' drops them (set indexing.embeddings_enabled = false first so they don't regrow)"
|
|
7625
|
-
});
|
|
7626
|
-
}
|
|
7750
|
+
rows = getDb(dbPath).prepare(OWNER_BYTES_SQL).all();
|
|
7627
7751
|
} catch {
|
|
7752
|
+
return [];
|
|
7628
7753
|
}
|
|
7629
|
-
|
|
7754
|
+
const shares = STORAGE_GROUPS.map((group) => ({
|
|
7755
|
+
name: group.name,
|
|
7756
|
+
bytes: rows.filter((r) => group.owns.test(r.owner)).reduce((sum, r) => sum + r.bytes, 0),
|
|
7757
|
+
command: group.command
|
|
7758
|
+
}));
|
|
7759
|
+
return shares.filter((share) => share.bytes > 0).sort((a, b) => b.bytes - a.bytes);
|
|
7630
7760
|
}
|
|
7631
7761
|
function oversizeDbMessage(dbPath, sizeBytes, freeBytes, tempRows, categories = [], topConsumers = [], thresholdMb = 1500, autoReclaimEmbeddings = false) {
|
|
7632
7762
|
const mb = (bytes) => Math.round(bytes / (1024 * 1024));
|
|
@@ -7637,15 +7767,18 @@ function oversizeDbMessage(dbPath, sizeBytes, freeBytes, tempRows, categories =
|
|
|
7637
7767
|
advice.push(`'token-goat doctor --repair' will automatically reclaim embedding vectors and compact global.db`);
|
|
7638
7768
|
}
|
|
7639
7769
|
const head = `global.db is ${mb(sizeBytes)} MB at ${displaySafeText(dbPath)} (larger than threshold of ${thresholdMb} MB). `;
|
|
7640
|
-
const
|
|
7770
|
+
const listed = categories.slice(0, 3);
|
|
7771
|
+
const totalCategoryBytes = listed.reduce((sum, c) => sum + c.bytes, 0);
|
|
7641
7772
|
const unmeasuredBytes = sizeBytes - totalCategoryBytes;
|
|
7642
|
-
const breakdown = totalCategoryBytes > 0 && sizeBytes > 0 ? ` Where it went: ${
|
|
7773
|
+
const breakdown = totalCategoryBytes > 0 && sizeBytes > 0 ? ` Where it went: ${listed.map((c) => `${c.name} ${mb(c.bytes)} MB (${Math.round(c.bytes / sizeBytes * 100)}%) -- ${c.command}`).join("; ")}.${unmeasuredBytes >= sizeBytes / 20 ? ` The other ${mb(unmeasuredBytes)} MB is smaller tables and free pages.` : ""}` : "";
|
|
7643
7774
|
let base = advice.length > 0 ? `${head}${advice.join("; ")}.${breakdown}` : `${head}Only ${mb(freeBytes)} MB of it is free pages and none of it is temp-dir scratch, so it is live index data that neither 'reclaim-index' nor 'project prune' will shrink.${breakdown}`;
|
|
7644
|
-
|
|
7775
|
+
const [top] = topConsumers;
|
|
7776
|
+
if (top !== void 0) {
|
|
7645
7777
|
const list = topConsumers.map((c) => `${path17.basename(c.root) || c.root} (${countNoun(c.fileCount, "file")})`).join(", ");
|
|
7646
7778
|
base += ` Top index consumers: ${list}.`;
|
|
7779
|
+
base += ` To shrink it, take out a project you do not need surgical reads in: 'token-goat project exclude "${displaySafeText(top.root)}"' removes its rows, then 'token-goat reclaim-index' returns the space.`;
|
|
7647
7780
|
}
|
|
7648
|
-
return base
|
|
7781
|
+
return `${base} If this size is expected, raise indexing.max_db_size_mb above ${Math.ceil(sizeBytes / (1024 * 1024))}.`;
|
|
7649
7782
|
}
|
|
7650
7783
|
function checkDbExists(dataDir2, maxDbSizeMb) {
|
|
7651
7784
|
const dbPath = path17.join(dataDir2, "global.db");
|
|
@@ -7749,6 +7882,29 @@ function checkSymbolCount(dbPath, rootDir) {
|
|
|
7749
7882
|
}
|
|
7750
7883
|
}
|
|
7751
7884
|
var EMBED_COVERAGE_WARN_FRACTION = 0.25;
|
|
7885
|
+
function unembeddedReasons(dbPath, rootDir, symbolOnlyKb, maxChunks) {
|
|
7886
|
+
const db = getDb(dbPath);
|
|
7887
|
+
const scope = rootDir === void 0 ? null : projectScopeClause("path");
|
|
7888
|
+
const rows = db.prepare(`SELECT path, sha, embed_sha FROM files${scope === null ? "" : ` WHERE ${scope.clause}`}`).all(...scope === null || rootDir === void 0 ? [] : scope.params(rootDir));
|
|
7889
|
+
let owed = 0;
|
|
7890
|
+
let overSizeCap = 0;
|
|
7891
|
+
for (const row of rows) {
|
|
7892
|
+
if (isUnderSystemTemp(row.path)) continue;
|
|
7893
|
+
if (row.embed_sha === oversizeEmbedSha(row.sha, symbolOnlyKb)) overSizeCap += 1;
|
|
7894
|
+
else if (!isEmbedFresh(row.embed_sha ?? void 0, row.sha, true, true, symbolOnlyKb, maxChunks)) owed += 1;
|
|
7895
|
+
}
|
|
7896
|
+
return { owed, overSizeCap };
|
|
7897
|
+
}
|
|
7898
|
+
function unembeddedReasonText(reasons, sizeKb) {
|
|
7899
|
+
let text = "";
|
|
7900
|
+
if (reasons.owed > 0) {
|
|
7901
|
+
text += ` ${countNoun(reasons.owed, "file")} ${reasons.owed === 1 ? "is" : "are"} still owed an embed: the worker embeds them while it is idle, or run 'token-goat index' in the project to embed them now.`;
|
|
7902
|
+
}
|
|
7903
|
+
if (reasons.overSizeCap > 0) {
|
|
7904
|
+
text += ` ${countNoun(reasons.overSizeCap, "file")} ${reasons.overSizeCap === 1 ? "is" : "are"} over indexing.large_file_symbol_only_kb (currently ${sizeKb} KB) and indexed for symbols only; raise it with 'token-goat config set indexing.large_file_symbol_only_kb <KB>' and the next 'token-goat index' embeds them.`;
|
|
7905
|
+
}
|
|
7906
|
+
return text;
|
|
7907
|
+
}
|
|
7752
7908
|
function checkEmbeddingCoverage(dbPath, rootDir) {
|
|
7753
7909
|
if (!fs18.existsSync(dbPath)) {
|
|
7754
7910
|
return { name: "Embedding coverage", status: "ok", message: "no database yet" };
|
|
@@ -7768,7 +7924,7 @@ function checkEmbeddingCoverage(dbPath, rootDir) {
|
|
|
7768
7924
|
return {
|
|
7769
7925
|
name: "Embedding coverage",
|
|
7770
7926
|
status: "warn",
|
|
7771
|
-
message: `only ${embeddedFiles} of ${indexedFiles} indexed file(s) (${pct3}%) have embeddings
|
|
7927
|
+
message: `only ${embeddedFiles} of ${indexedFiles} indexed file(s) (${pct3}%) have embeddings, so 'semantic' searches those files only, and reports finding nothing in the same words it uses after searching everything.` + unembeddedReasonText(unembeddedReasons(dbPath, rootDir, sizeKb, cfg.indexing.max_chunks_per_file), sizeKb) + ` Exact symbol lookups are unaffected`
|
|
7772
7928
|
};
|
|
7773
7929
|
}
|
|
7774
7930
|
return {
|
|
@@ -8022,16 +8178,33 @@ function checkDiskSpace(dataDir2) {
|
|
|
8022
8178
|
}
|
|
8023
8179
|
return { name: "Disk Space", status: "warn", message: "disk space check unavailable on this platform" };
|
|
8024
8180
|
}
|
|
8025
|
-
function checkCopilotCli(configPath2, scriptPath) {
|
|
8026
|
-
if (!fs18.existsSync(configPath2)
|
|
8181
|
+
function checkCopilotCli(configPath2, scriptPath, scope = "user") {
|
|
8182
|
+
if (!fs18.existsSync(configPath2)) {
|
|
8027
8183
|
return null;
|
|
8028
8184
|
}
|
|
8185
|
+
const name = scope === "project" ? "Copilot CLI (project)" : "Copilot CLI";
|
|
8186
|
+
const { install, harness } = copilotHooksRecovery(path17.dirname(configPath2), scope);
|
|
8187
|
+
if (scope === "project" && !hasCreatedConfig(configPath2)) {
|
|
8188
|
+
return {
|
|
8189
|
+
name,
|
|
8190
|
+
status: "warn",
|
|
8191
|
+
message: `hook config at ${configPath2} was not written by token-goat on this machine, so doctor does not run the command it names. If these hooks are yours, run "${install}" to rewrite them here.`
|
|
8192
|
+
};
|
|
8193
|
+
}
|
|
8194
|
+
if (!fs18.existsSync(scriptPath)) {
|
|
8195
|
+
if (!fs18.existsSync(path17.join(path17.dirname(scriptPath), LEGACY_HOOKS_SCRIPT_FILE))) return null;
|
|
8196
|
+
return {
|
|
8197
|
+
name,
|
|
8198
|
+
status: "warn",
|
|
8199
|
+
message: `hooks at ${path17.dirname(scriptPath)} still run ${LEGACY_HOOKS_SCRIPT_FILE} from an older token-goat build, which Node loads as an ES module under any package.json that says "type": "module" and then fails every tool call. Recovery: run "${install}", then fully restart ${harness}.`
|
|
8200
|
+
};
|
|
8201
|
+
}
|
|
8029
8202
|
let config;
|
|
8030
8203
|
try {
|
|
8031
8204
|
config = JSON.parse(fs18.readFileSync(configPath2, "utf-8"));
|
|
8032
8205
|
} catch (err2) {
|
|
8033
8206
|
return {
|
|
8034
|
-
name
|
|
8207
|
+
name,
|
|
8035
8208
|
status: "fail",
|
|
8036
8209
|
message: `hook config at ${configPath2} is not valid JSON: ${extractErrorMessage(err2, "unknown error")}`
|
|
8037
8210
|
};
|
|
@@ -8039,17 +8212,17 @@ function checkCopilotCli(configPath2, scriptPath) {
|
|
|
8039
8212
|
const preToolUseCommand = config.hooks?.["preToolUse"]?.[0]?.command;
|
|
8040
8213
|
if (typeof preToolUseCommand !== "string" || preToolUseCommand === "") {
|
|
8041
8214
|
return {
|
|
8042
|
-
name
|
|
8215
|
+
name,
|
|
8043
8216
|
status: "fail",
|
|
8044
|
-
message: `hook config at ${configPath2} has no preToolUse entry; run:
|
|
8217
|
+
message: `hook config at ${configPath2} has no preToolUse entry; run: ${install}`
|
|
8045
8218
|
};
|
|
8046
8219
|
}
|
|
8047
8220
|
const bakedExecPath = /^"([^"]+)"/.exec(preToolUseCommand)?.[1];
|
|
8048
8221
|
if (bakedExecPath !== void 0 && !fs18.existsSync(bakedExecPath)) {
|
|
8049
8222
|
return {
|
|
8050
|
-
name
|
|
8223
|
+
name,
|
|
8051
8224
|
status: "fail",
|
|
8052
|
-
message: `hook points at a node binary that no longer exists (${bakedExecPath}) -- likely stale after an nvm/fnm/volta node upgrade. Recovery: run "
|
|
8225
|
+
message: `hook points at a node binary that no longer exists (${bakedExecPath}) -- likely stale after an nvm/fnm/volta node upgrade. Recovery: run "${install}", then fully restart ${harness} (renaming/reinstalling the hook has no effect on an already-running session -- hook configs are cached at startup).`
|
|
8053
8226
|
};
|
|
8054
8227
|
}
|
|
8055
8228
|
const synthetic = JSON.stringify({
|
|
@@ -8067,31 +8240,38 @@ function checkCopilotCli(configPath2, scriptPath) {
|
|
|
8067
8240
|
});
|
|
8068
8241
|
if (res.error) {
|
|
8069
8242
|
return {
|
|
8070
|
-
name
|
|
8243
|
+
name,
|
|
8071
8244
|
status: "fail",
|
|
8072
|
-
message: `hook failed to launch: ${extractErrorMessage(res.error, "unknown error")}. Recovery: run "
|
|
8245
|
+
message: `hook failed to launch: ${extractErrorMessage(res.error, "unknown error")}. Recovery: run "${install}", then fully restart ${harness}.`
|
|
8073
8246
|
};
|
|
8074
8247
|
}
|
|
8075
8248
|
if (res.status !== 0) {
|
|
8076
8249
|
return {
|
|
8077
|
-
name
|
|
8250
|
+
name,
|
|
8078
8251
|
status: "fail",
|
|
8079
|
-
message: `hook exited with status ${res.status} -- Copilot's preToolUse fails closed on a non-zero exit and denies every tool call for the rest of the session. Recovery: run "
|
|
8252
|
+
message: `hook exited with status ${res.status} -- Copilot's preToolUse fails closed on a non-zero exit and denies every tool call for the rest of the session. Recovery: run "${install}", then fully restart ${harness} (a live session won't pick up the fix).`
|
|
8080
8253
|
};
|
|
8081
8254
|
}
|
|
8082
8255
|
try {
|
|
8083
8256
|
JSON.parse(res.stdout ?? "");
|
|
8084
8257
|
} catch {
|
|
8085
8258
|
return {
|
|
8086
|
-
name
|
|
8259
|
+
name,
|
|
8087
8260
|
status: "fail",
|
|
8088
|
-
message:
|
|
8261
|
+
message: `hook did not return valid JSON -- Copilot treats this as a hook error and denies every tool call. Recovery: run "${install}", then fully restart ${harness}.`
|
|
8089
8262
|
};
|
|
8090
8263
|
}
|
|
8091
8264
|
if (!shimIsCurrent(scriptPath, COPILOT_CLI_HOOK_SCRIPT)) {
|
|
8092
|
-
return { name
|
|
8265
|
+
return { name, status: "warn", message: staleShimMessage(scriptPath, "Copilot", install) + `, then fully restart ${harness}.` };
|
|
8266
|
+
}
|
|
8267
|
+
return { name, status: "ok", message: "preToolUse hook invokes cleanly and returns valid JSON" };
|
|
8268
|
+
}
|
|
8269
|
+
function copilotHooksRecovery(hooksDir, scope) {
|
|
8270
|
+
const owners = readCopilotHooksOwners(hooksDir);
|
|
8271
|
+
if (!owners.has("copilot") && owners.has("vscode")) {
|
|
8272
|
+
return { install: scope === "project" ? "token-goat install --vscode" : "token-goat install --vscode --user", harness: "VS Code" };
|
|
8093
8273
|
}
|
|
8094
|
-
return {
|
|
8274
|
+
return { install: scope === "project" ? "token-goat install --copilot --local" : "token-goat install --copilot", harness: "Copilot CLI" };
|
|
8095
8275
|
}
|
|
8096
8276
|
function shimIsCurrent(scriptPath, expected) {
|
|
8097
8277
|
return fs18.readFileSync(scriptPath, "utf-8").replace(/\r\n/g, "\n") === expected.replace(/\r\n/g, "\n");
|
|
@@ -8100,7 +8280,14 @@ function staleShimMessage(scriptPath, harness, reinstall) {
|
|
|
8100
8280
|
return `hook shim at ${scriptPath} was written by an older token-goat build, so fixes to it since then are not reaching ${harness}. Recovery: run "${reinstall}"`;
|
|
8101
8281
|
}
|
|
8102
8282
|
function checkHookShim(name, scriptPath, expected, reinstall) {
|
|
8103
|
-
if (!fs18.existsSync(scriptPath))
|
|
8283
|
+
if (!fs18.existsSync(scriptPath)) {
|
|
8284
|
+
if (!fs18.existsSync(path17.join(path17.dirname(scriptPath), LEGACY_SHIM_FILE))) return null;
|
|
8285
|
+
return {
|
|
8286
|
+
name,
|
|
8287
|
+
status: "warn",
|
|
8288
|
+
message: `hooks at ${path17.dirname(scriptPath)} still run ${LEGACY_SHIM_FILE} from an older token-goat build, which Node loads as an ES module under any package.json that says "type": "module" and then fails every tool call. Recovery: run "${reinstall}", then restart any running session.`
|
|
8289
|
+
};
|
|
8290
|
+
}
|
|
8104
8291
|
if (shimIsCurrent(scriptPath, expected)) return { name, status: "ok", message: `hook shim at ${scriptPath} matches this build` };
|
|
8105
8292
|
return { name, status: "warn", message: staleShimMessage(scriptPath, name, reinstall) + ", then restart any running session." };
|
|
8106
8293
|
}
|
|
@@ -8239,6 +8426,28 @@ function checkUnmappedTools(dbPath, options) {
|
|
|
8239
8426
|
return { name, status: "warn", message: `could not read the tool-name histogram: ${extractErrorMessage(e)}` };
|
|
8240
8427
|
}
|
|
8241
8428
|
}
|
|
8429
|
+
function checkWorker(dir) {
|
|
8430
|
+
if (checkWorkerRunning(dir)) return { name: "Worker", status: "ok", message: "running" };
|
|
8431
|
+
const refusal2 = fs18.existsSync(dir) ? dataDirWriteRefusal(dir) : void 0;
|
|
8432
|
+
if (refusal2 !== void 0) {
|
|
8433
|
+
return { name: "Worker", status: "fail", message: `not running, and cannot start: ${displaySafeText(dir)} cannot be written (${displaySafeText(extractErrorMessage(refusal2))}); make it writable, then run 'token-goat worker start'` };
|
|
8434
|
+
}
|
|
8435
|
+
return { name: "Worker", status: "warn", message: "not running" };
|
|
8436
|
+
}
|
|
8437
|
+
function checkHookServer(state) {
|
|
8438
|
+
const name = "Hook server";
|
|
8439
|
+
if (!state.enabled) return { name, status: "ok", message: "off (hooks.server or TOKEN_GOAT_HOOK_SERVER); every hook call starts its own process" };
|
|
8440
|
+
if (state.statuses.length > 0) return { name, status: "ok", message: `${state.statuses.length} running (${state.statuses.map((s) => `slot ${s.slot}, pid ${s.pid}, ${s.served} served`).join("; ")})` };
|
|
8441
|
+
if (state.failure !== void 0) return { name, status: "warn", message: `not running, and the last start failed: ${state.failure}. Run 'token-goat hook-server run' to see it in the foreground` };
|
|
8442
|
+
return { name, status: "ok", message: "not running; the next hook call starts one" };
|
|
8443
|
+
}
|
|
8444
|
+
async function runDoctorChecks(dataDir2, configPath2, rootDir, processes) {
|
|
8445
|
+
const results = runDoctor(dataDir2, configPath2, rootDir, processes);
|
|
8446
|
+
const enabled = hookServerEnabled();
|
|
8447
|
+
const dir = dataDir2 || dataDir();
|
|
8448
|
+
results.push(checkHookServer({ enabled, statuses: enabled ? await serverStatuses(dir) : [], failure: readMarker("failed", dir) }));
|
|
8449
|
+
return results;
|
|
8450
|
+
}
|
|
8242
8451
|
function runDoctor(dataDir2, configPath2, rootDir, processes) {
|
|
8243
8452
|
const results = [];
|
|
8244
8453
|
const actualDataDir = dataDir2 || dataDir();
|
|
@@ -8246,7 +8455,7 @@ function runDoctor(dataDir2, configPath2, rootDir, processes) {
|
|
|
8246
8455
|
results.push(checkTsCompiler());
|
|
8247
8456
|
results.push(checkTreeSitter());
|
|
8248
8457
|
results.push(checkStrayClaudeMdBlocks());
|
|
8249
|
-
results.push(
|
|
8458
|
+
results.push(checkWorker(actualDataDir));
|
|
8250
8459
|
const cfg = loadConfig(rootDir);
|
|
8251
8460
|
results.push(checkDbExists(actualDataDir, cfg.indexing.max_db_size_mb));
|
|
8252
8461
|
results.push(checkSymbolBodySize(path17.join(actualDataDir, "global.db")));
|
|
@@ -8265,6 +8474,8 @@ function runDoctor(dataDir2, configPath2, rootDir, processes) {
|
|
|
8265
8474
|
results.push(checkDiskSpace(actualDataDir));
|
|
8266
8475
|
const copilotResult = checkCopilotCli(copilotCliConfigPath(), copilotCliScriptPath());
|
|
8267
8476
|
if (copilotResult) results.push(copilotResult);
|
|
8477
|
+
const copilotProjectResult = checkCopilotCli(copilotCliConfigPath({ local: true }), copilotCliScriptPath({ local: true }), "project");
|
|
8478
|
+
if (copilotProjectResult) results.push(copilotProjectResult);
|
|
8268
8479
|
const claudeShimResult = checkHookShim("Claude Code", claudeHookScriptPath(), CLAUDECODE_HOOK_SCRIPT, isInstalled("user") || !isInstalled("project") ? "token-goat install" : "token-goat install --project");
|
|
8269
8480
|
if (claudeShimResult) results.push(claudeShimResult);
|
|
8270
8481
|
const claudeEventsResult = checkClaudeHookEvents({ user: missingHookEvents("user"), project: missingHookEvents("project") });
|
|
@@ -8485,7 +8696,7 @@ async function runDoctorAndExit(opts) {
|
|
|
8485
8696
|
console.log();
|
|
8486
8697
|
}
|
|
8487
8698
|
}
|
|
8488
|
-
const results =
|
|
8699
|
+
const results = await runDoctorChecks(options.dataDir, options.configPath, options.rootDir, options.processes);
|
|
8489
8700
|
printDoctorResults(results);
|
|
8490
8701
|
if (options.context === true) {
|
|
8491
8702
|
console.log("\n## Context footprint\n");
|
|
@@ -8523,7 +8734,7 @@ async function runDoctorAndExit(opts) {
|
|
|
8523
8734
|
}
|
|
8524
8735
|
}
|
|
8525
8736
|
try {
|
|
8526
|
-
const { checkUpdateStatus } = await import("./token-goat-chunk-
|
|
8737
|
+
const { checkUpdateStatus } = await import("./token-goat-chunk-YAGLESS3.mjs");
|
|
8527
8738
|
const update = await checkUpdateStatus(1500);
|
|
8528
8739
|
if (update.updateAvailable && update.latest) {
|
|
8529
8740
|
console.log(`
|
|
@@ -8646,7 +8857,7 @@ function generateCompactHelp() {
|
|
|
8646
8857
|
" compress, recall, bash-output, web-output, mcp-output, bench",
|
|
8647
8858
|
"",
|
|
8648
8859
|
"Config & Integration: install, uninstall, upgrade, mcp-serve, mcp-status, hook,",
|
|
8649
|
-
" bridges-status, worker, statusline, version, config, config-get,",
|
|
8860
|
+
" bridges-status, worker, hook-server, statusline, version, config, config-get,",
|
|
8650
8861
|
" capabilities, help",
|
|
8651
8862
|
"",
|
|
8652
8863
|
"Data: note, note-add, note-get, note-list, describe, sqlite-query,",
|
|
@@ -11569,11 +11780,12 @@ function openWithinRoot(rootReal, p) {
|
|
|
11569
11780
|
if (!isPathWithinRoot(rootReal, realPath)) return "outside-root";
|
|
11570
11781
|
let realStat;
|
|
11571
11782
|
try {
|
|
11572
|
-
realStat =
|
|
11783
|
+
realStat = statThroughHandle(realPath);
|
|
11573
11784
|
} catch {
|
|
11574
11785
|
return "outside-root";
|
|
11575
11786
|
}
|
|
11576
|
-
|
|
11787
|
+
const fdStat = fs21.fstatSync(fd, { bigint: true });
|
|
11788
|
+
if (realStat.dev !== fdStat.dev || realStat.ino !== fdStat.ino) return "outside-root";
|
|
11577
11789
|
ownershipTransferred = true;
|
|
11578
11790
|
return { fd, stat };
|
|
11579
11791
|
} finally {
|
|
@@ -13580,9 +13792,9 @@ function cmdNoteAdd(file, opts) {
|
|
|
13580
13792
|
const messages = [`No symbol named '${opts.symbol}' is indexed in '${file}'`];
|
|
13581
13793
|
const allNames = symbolNamesInFile(resolvedPath);
|
|
13582
13794
|
const available = rankSimilarNames(allNames, opts.symbol);
|
|
13583
|
-
if (available.length > 0) messages.push(
|
|
13795
|
+
if (available.length > 0) messages.push(...didYouMeanLines(available));
|
|
13584
13796
|
else if (allNames.length > 0) messages.push(`Try: token-goat outline ${file}`);
|
|
13585
|
-
throw new CliError(messages
|
|
13797
|
+
throw new CliError(messages);
|
|
13586
13798
|
}
|
|
13587
13799
|
symbol = opts.symbol;
|
|
13588
13800
|
fingerprint = fingerprintContent(match2.body);
|
|
@@ -13911,9 +14123,9 @@ function cmdInsertSection(file, opts) {
|
|
|
13911
14123
|
const allHeadings = listSections(file);
|
|
13912
14124
|
const messages = [`Section '${opts.after}' not found in '${file}'`];
|
|
13913
14125
|
const available = filterSimilarHeadings(allHeadings, opts.after);
|
|
13914
|
-
if (available.length > 0) messages.push(
|
|
14126
|
+
if (available.length > 0) messages.push(...didYouMeanLines(available));
|
|
13915
14127
|
else if (allHeadings.length > 0) messages.push(`Try: token-goat outline ${file}`);
|
|
13916
|
-
throw new CliError(messages
|
|
14128
|
+
throw new CliError(messages);
|
|
13917
14129
|
}
|
|
13918
14130
|
if (result.occurrences !== void 0) {
|
|
13919
14131
|
const lines = [
|
|
@@ -13925,7 +14137,7 @@ function cmdInsertSection(file, opts) {
|
|
|
13925
14137
|
if (result.occurrences.length > AMBIGUOUS_HEADING_LIMIT) {
|
|
13926
14138
|
lines.push(` (${result.occurrences.length - AMBIGUOUS_HEADING_LIMIT} more not shown)`);
|
|
13927
14139
|
}
|
|
13928
|
-
throw new CliError(lines
|
|
14140
|
+
throw new CliError(lines);
|
|
13929
14141
|
}
|
|
13930
14142
|
let rawBytes;
|
|
13931
14143
|
try {
|
|
@@ -16233,8 +16445,7 @@ function collectCapabilities(config = loadConfig()) {
|
|
|
16233
16445
|
id: "at_rest.symbol_index",
|
|
16234
16446
|
kind: "at-rest",
|
|
16235
16447
|
what: "Stores the text of indexed source files in a local database, so a symbol can be returned without re-reading the file.",
|
|
16236
|
-
// Always on: it is the product. Reported anyway, because a reviewer deciding about data at
|
|
16237
|
-
// rest needs the always-on items more than the optional ones.
|
|
16448
|
+
// Always on: it is the product. Reported anyway, because a reviewer deciding about data at rest needs the always-on items more than the optional ones.
|
|
16238
16449
|
enabled: true,
|
|
16239
16450
|
controlledBy: "always on (this is what the tool does)",
|
|
16240
16451
|
enforcedAt: "src/db.ts"
|
|
@@ -16246,15 +16457,24 @@ function collectCapabilities(config = loadConfig()) {
|
|
|
16246
16457
|
enabled: true,
|
|
16247
16458
|
controlledBy: "always on, 24-hour expiry",
|
|
16248
16459
|
enforcedAt: "src/disk_cache.ts"
|
|
16460
|
+
},
|
|
16461
|
+
{
|
|
16462
|
+
id: "ipc.hook_server",
|
|
16463
|
+
kind: "local-ipc",
|
|
16464
|
+
what: "Keeps up to three hook servers running between hook calls, each on a named pipe (Windows) or Unix socket (elsewhere) that answers only a caller holding the key file in the data directory.",
|
|
16465
|
+
// Read the way the server reads it, which a project's config cannot change.
|
|
16466
|
+
enabled: hookServerEnabled(),
|
|
16467
|
+
controlledBy: "hooks.server (global config only), TOKEN_GOAT_HOOK_SERVER",
|
|
16468
|
+
enforcedAt: "src/hook_server.ts::runHookServer"
|
|
16249
16469
|
}
|
|
16250
16470
|
];
|
|
16251
16471
|
}
|
|
16252
16472
|
function renderCapabilities(caps) {
|
|
16253
16473
|
const lines = [];
|
|
16254
|
-
for (const kind of ["egress", "at-rest"]) {
|
|
16474
|
+
for (const [kind, heading] of [["egress", "Can send data off this machine:"], ["at-rest", "Leaves data on this machine:"], ["local-ipc", "Listens for other processes on this machine:"]]) {
|
|
16255
16475
|
const group = caps.filter((c) => c.kind === kind);
|
|
16256
16476
|
if (group.length === 0) continue;
|
|
16257
|
-
lines.push(
|
|
16477
|
+
lines.push(heading);
|
|
16258
16478
|
for (const c of group) {
|
|
16259
16479
|
lines.push(` [${c.enabled ? "ON " : "OFF"}] ${displaySafeText(c.id)}`);
|
|
16260
16480
|
lines.push(` ${c.what}`);
|
|
@@ -17044,7 +17264,7 @@ async function auditSessionCorpus(opts = {}) {
|
|
|
17044
17264
|
windowDays,
|
|
17045
17265
|
toolErrors: { byTool: [], byModel: [], unknownPrefixes: [] }
|
|
17046
17266
|
};
|
|
17047
|
-
const toolErrorAcc = (await import("./token-goat-chunk-
|
|
17267
|
+
const toolErrorAcc = (await import("./token-goat-chunk-G23DWHV4.mjs")).newToolErrorAccumulator();
|
|
17048
17268
|
const toolMap = /* @__PURE__ */ new Map();
|
|
17049
17269
|
const attachmentMap = /* @__PURE__ */ new Map();
|
|
17050
17270
|
const hookMap = /* @__PURE__ */ new Map();
|
|
@@ -18270,6 +18490,11 @@ async function runStatuslineCommand(opts = {}) {
|
|
|
18270
18490
|
|
|
18271
18491
|
// src/cli_hint_stats.ts
|
|
18272
18492
|
init_define_import_meta_env();
|
|
18493
|
+
var SESSION_JSON_SCOPE = {
|
|
18494
|
+
session: ["emitted", "actedOn", "efficacyPct", "unobservable", "detected", "bytesEmitted", "legacyEmissions", "totals.spentBytes", "totals.legacyEmissions"],
|
|
18495
|
+
allTime: ["suppressed", "suppressionPermanent", "manualEffective", "manualIneffective"],
|
|
18496
|
+
unavailable: ["totals.savedBytes"]
|
|
18497
|
+
};
|
|
18273
18498
|
function formatSpentCell(row) {
|
|
18274
18499
|
if (row.emitted === 0) return "n/a";
|
|
18275
18500
|
if (row.bytesEmitted === null) return "n/a (legacy)";
|
|
@@ -18309,6 +18534,16 @@ TOTAL saved-bytes=${totals.savedBytes} (all-time, every hint kind) spent-byt
|
|
|
18309
18534
|
`
|
|
18310
18535
|
);
|
|
18311
18536
|
}
|
|
18537
|
+
function printSessionTotals(totals) {
|
|
18538
|
+
const spent = totals.spentBytes === null ? "n/a" : String(totals.spentBytes);
|
|
18539
|
+
const legacyNote = totals.legacyEmissions > 0 ? ` (excludes ${totals.legacyEmissions} legacy emission(s) recorded before spend tracking)` : "";
|
|
18540
|
+
process.stdout.write(
|
|
18541
|
+
`
|
|
18542
|
+
TOTAL (this session) spent-bytes=${spent} (hint_emissions ledger only)${legacyNote}
|
|
18543
|
+
saved-bytes: not available per session, because the stats ledger it comes from records no session id. Run \`token-goat hint-stats\` without --session-id for the all-time figure.
|
|
18544
|
+
`
|
|
18545
|
+
);
|
|
18546
|
+
}
|
|
18312
18547
|
function runHintStatsCommand(opts = {}) {
|
|
18313
18548
|
if (opts.reset === true) {
|
|
18314
18549
|
resetHintStats();
|
|
@@ -18327,13 +18562,24 @@ function runHintStatsCommand(opts = {}) {
|
|
|
18327
18562
|
`);
|
|
18328
18563
|
return;
|
|
18329
18564
|
}
|
|
18330
|
-
const
|
|
18565
|
+
const session = opts.sessionId;
|
|
18566
|
+
const rows = getHintStatsSummary(session);
|
|
18331
18567
|
if (opts.json === true) {
|
|
18332
|
-
|
|
18568
|
+
const payload = session === void 0 ? rows : { session, scope: SESSION_JSON_SCOPE, rows, totals: { savedBytes: null, ...getHintSpendTotals(session) } };
|
|
18569
|
+
process.stdout.write(`${displaySafeJson(payload, 0)}
|
|
18333
18570
|
`);
|
|
18334
18571
|
return;
|
|
18335
18572
|
}
|
|
18336
|
-
|
|
18573
|
+
const noEmissions = rows.every((r) => r.emitted === 0 && r.actedOn === 0 && r.unobservable === 0 && r.detected === 0);
|
|
18574
|
+
if (session !== void 0) {
|
|
18575
|
+
process.stdout.write(
|
|
18576
|
+
`Session: ${displaySafeText(session)}
|
|
18577
|
+
emitted, undisplayed, acted-on, efficacy and spent-bytes count this session only. suppressed, manual+ and manual- are all-time, across every session: suppression is decided on the whole history, and manual marks carry no session.
|
|
18578
|
+
`
|
|
18579
|
+
);
|
|
18580
|
+
if (noEmissions) process.stdout.write("No hint emissions were recorded for this session, so every per-session figure below is 0.\n");
|
|
18581
|
+
}
|
|
18582
|
+
if (session === void 0 && noEmissions) {
|
|
18337
18583
|
process.stdout.write("No hint emissions recorded yet \u2014 the zeros below are absence of data, not measured ineffectiveness.\n");
|
|
18338
18584
|
}
|
|
18339
18585
|
printSummary(rows);
|
|
@@ -18359,7 +18605,8 @@ function runHintStatsCommand(opts = {}) {
|
|
|
18359
18605
|
hints.backoff_thresholds is empty, so suppression here is permanent rather than a self-healing throttle: ${names} will not emit again on any occasion. Set backoff_thresholds to re-enable probe emissions, or run \`token-goat hint-stats --reset\` to clear the ledger.
|
|
18360
18606
|
`);
|
|
18361
18607
|
}
|
|
18362
|
-
printTotals(getHintStatsTotals());
|
|
18608
|
+
if (session === void 0) printTotals(getHintStatsTotals());
|
|
18609
|
+
else printSessionTotals(getHintSpendTotals(session));
|
|
18363
18610
|
}
|
|
18364
18611
|
|
|
18365
18612
|
// src/cli_session.ts
|
|
@@ -18392,7 +18639,7 @@ function cmdWaste(opts = {}) {
|
|
|
18392
18639
|
});
|
|
18393
18640
|
}
|
|
18394
18641
|
async function cmdAudit(opts = {}) {
|
|
18395
|
-
const { runAuditCommand } = await import("./token-goat-chunk-
|
|
18642
|
+
const { runAuditCommand } = await import("./token-goat-chunk-67BNIKKO.mjs");
|
|
18396
18643
|
return runAuditCommand({
|
|
18397
18644
|
...opts.project !== void 0 ? { project: opts.project } : {},
|
|
18398
18645
|
...opts.transcript !== void 0 ? { transcript: opts.transcript } : {},
|
|
@@ -18407,7 +18654,7 @@ async function cmdSessionAudit(opts = {}) {
|
|
|
18407
18654
|
throw new CliError(err2 instanceof Error ? err2.message : String(err2));
|
|
18408
18655
|
}
|
|
18409
18656
|
if (opts.toolErrors === true) {
|
|
18410
|
-
const { formatToolErrorCensus } = await import("./token-goat-chunk-
|
|
18657
|
+
const { formatToolErrorCensus } = await import("./token-goat-chunk-G23DWHV4.mjs");
|
|
18411
18658
|
out(opts.json === true ? displaySafeJson({ filesScanned: summary.filesScanned, windowDays: summary.windowDays, ...summary.toolErrors }, 0) : formatToolErrorCensus(summary.toolErrors, summary));
|
|
18412
18659
|
return;
|
|
18413
18660
|
}
|
|
@@ -18474,6 +18721,13 @@ function cmdStatusline(opts = {}) {
|
|
|
18474
18721
|
return runStatuslineCommand({ ...opts.json === true ? { json: true } : {} });
|
|
18475
18722
|
}
|
|
18476
18723
|
function cmdHintStats(opts = {}) {
|
|
18724
|
+
if (opts.sessionId !== void 0) {
|
|
18725
|
+
const mutating = [opts.reset === true ? "--reset" : null, opts.markEffective !== void 0 ? "--mark-effective" : null, opts.markIneffective !== void 0 ? "--mark-ineffective" : null].filter((f) => f !== null);
|
|
18726
|
+
if (mutating.length > 0) {
|
|
18727
|
+
throw new CliError(`--session-id cannot be combined with ${mutating.join(", ")}: those change cross-session state (every session's emissions and marks), not one session's view`);
|
|
18728
|
+
}
|
|
18729
|
+
}
|
|
18730
|
+
const session = opts.sessionId === void 0 ? void 0 : resolveHintStatsSession(opts.sessionId);
|
|
18477
18731
|
if (opts.markEffective !== void 0 && !isHintCategory(opts.markEffective)) {
|
|
18478
18732
|
throw new CliError(`--mark-effective must be one of: ${HINT_CATEGORIES.join(", ")} (got: ${opts.markEffective})`);
|
|
18479
18733
|
}
|
|
@@ -18484,9 +18738,18 @@ function cmdHintStats(opts = {}) {
|
|
|
18484
18738
|
...opts.json === true ? { json: true } : {},
|
|
18485
18739
|
...opts.reset === true ? { reset: true } : {},
|
|
18486
18740
|
...opts.markEffective !== void 0 && isHintCategory(opts.markEffective) ? { markEffective: opts.markEffective } : {},
|
|
18487
|
-
...opts.markIneffective !== void 0 && isHintCategory(opts.markIneffective) ? { markIneffective: opts.markIneffective } : {}
|
|
18741
|
+
...opts.markIneffective !== void 0 && isHintCategory(opts.markIneffective) ? { markIneffective: opts.markIneffective } : {},
|
|
18742
|
+
...session !== void 0 ? { sessionId: session } : {}
|
|
18488
18743
|
});
|
|
18489
18744
|
}
|
|
18745
|
+
function resolveHintStatsSession(arg) {
|
|
18746
|
+
const trimmed = arg.trim();
|
|
18747
|
+
if (trimmed === "") throw new CliError("--session-id needs a session id, or `latest` for the most recent session");
|
|
18748
|
+
if (trimmed !== "latest") return trimmed;
|
|
18749
|
+
const latest = findLatestSessionId();
|
|
18750
|
+
if (latest === null) throw new CliError("--session-id latest: no session state found on disk; pass a session id explicitly");
|
|
18751
|
+
return latest;
|
|
18752
|
+
}
|
|
18490
18753
|
|
|
18491
18754
|
// src/cli_skills.ts
|
|
18492
18755
|
init_define_import_meta_env();
|
|
@@ -18751,10 +19014,10 @@ async function cmdSkillSection(nameHeading, headingArg) {
|
|
|
18751
19014
|
}
|
|
18752
19015
|
const messages = [`Section '${heading}' not found in skill '${skillName}'`];
|
|
18753
19016
|
const available = filterSimilarHeadings(allHeadings, heading);
|
|
18754
|
-
if (available.length > 0) messages.push(
|
|
19017
|
+
if (available.length > 0) messages.push(...didYouMeanLines(available));
|
|
18755
19018
|
else if (allHeadings.length === 0) messages.push(`skill '${skillName}' has no headings`);
|
|
18756
19019
|
else messages.push(`Try: token-goat outline ${filePath}`);
|
|
18757
|
-
throw new CliError(messages
|
|
19020
|
+
throw new CliError(messages);
|
|
18758
19021
|
}
|
|
18759
19022
|
out(extracted);
|
|
18760
19023
|
}
|
|
@@ -18821,6 +19084,7 @@ var METHODOLOGY = {
|
|
|
18821
19084
|
billing: "They are not GitHub Copilot usage, provider-reported token consumption, or billing data.",
|
|
18822
19085
|
byte_derived_formula: "Most read, hook, and command entries go through savedTokensFromBytes in src/stats.ts, which is Math.round(bytes_saved / 4). Image entries are the exception: they are priced in visual tokens, not bytes.",
|
|
18823
19086
|
filter_estimates: "Output compressors record their filter-calculated delta, measured against what the harness would actually have delivered rather than the full command output. Image entries are priced in visual tokens (28x28-pixel patches, capped at the configured vision tier), because an image is not billed by its byte size; where the pixel dimensions are unavailable the tier ceiling is used.",
|
|
19087
|
+
read_command_baselines: "A read command is credited the bytes of what it replaced, less what it printed. Naming a file (read, section, outline and the rest) replaces reading that file whole, capped at 100,000 bytes per file, about what one Read returns before it truncates. A search over files the caller did not name (symbol NAME, semantic) replaces a search plus a read of the one file wanted, so it is credited the largest matched file under the same cap, not every match. refs is credited the one line per reference a plain text search prints, and changed the diff it stands in for; both are shell output, so both are first cut to what the harness would have delivered of it.",
|
|
18824
19088
|
advisory_events: "Zero-byte, zero-token advisory events show that guidance fired, not that an agent followed it.",
|
|
18825
19089
|
audit: "Use stats --full or stats --json for source and command breakdowns; reconcile billing with provider-exported usage data."
|
|
18826
19090
|
};
|
|
@@ -18836,6 +19100,7 @@ function renderMethodology(json = false) {
|
|
|
18836
19100
|
`\`tokens saved\` is a ${METHODOLOGY.estimate_scope.toLowerCase()} ${METHODOLOGY.billing}`,
|
|
18837
19101
|
"",
|
|
18838
19102
|
`- ${METHODOLOGY.byte_derived_formula}`,
|
|
19103
|
+
`- ${METHODOLOGY.read_command_baselines}`,
|
|
18839
19104
|
`- ${METHODOLOGY.filter_estimates}`,
|
|
18840
19105
|
`- ${METHODOLOGY.advisory_events}`,
|
|
18841
19106
|
`- ${METHODOLOGY.audit}`,
|
|
@@ -19251,7 +19516,7 @@ function registerSessionCommands(program2, guard) {
|
|
|
19251
19516
|
})
|
|
19252
19517
|
)
|
|
19253
19518
|
);
|
|
19254
|
-
program2.command("capabilities").description("report every capability that can send data off this machine, and its current state").option("-j, --json", "emit as JSON, for asserting on in a pipeline").action(
|
|
19519
|
+
program2.command("capabilities").description("report every capability that can send data off this machine, leave data on it, or listen for other processes on it, and its current state").option("-j, --json", "emit as JSON, for asserting on in a pipeline").action(
|
|
19255
19520
|
guard((opts) => {
|
|
19256
19521
|
const caps = collectCapabilities();
|
|
19257
19522
|
console.log(opts.json ? displaySafeJson({ version: VERSION, capabilities: caps }) : renderCapabilities(caps));
|
|
@@ -19274,7 +19539,7 @@ function registerSessionCommands(program2, guard) {
|
|
|
19274
19539
|
));
|
|
19275
19540
|
program2.command("mcp-audit").description("MCP server schema cost-vs-usage report: estimate per-server token cost from cached tool calls").option("--project <path>", "project root to analyze").option("--json", "output JSON").action(guard(cmdMcpAudit));
|
|
19276
19541
|
program2.command("recall [query]").description("search across every cached bash-output, web-output, and mcp-output entry (full-text); with no query, list them newest-first").option("--type <type>", "filter to one cache type: bash, web, or mcp").option("--limit <n>", "max results to return (default: 10)").option("--json", "output JSON").action(guard(cmdRecall));
|
|
19277
|
-
program2.command("hint-stats").description("per-category efficacy report for token-goat's discretionary hint hooks (emitted/acted-on/suppression)").option("--json", "output JSON").option("--reset", "clear all tracked emissions and manual marks").option("--mark-effective <category>", 'record a manual "effective" vote for a hint category').option("--mark-ineffective <category>", 'record a manual "ineffective" vote for a hint category').action(guard(cmdHintStats));
|
|
19542
|
+
program2.command("hint-stats").description("per-category efficacy report for token-goat's discretionary hint hooks (emitted/acted-on/suppression); all-time unless --session-id narrows it").option("--json", "output JSON").option("--session-id <id>", "scope emission counts, efficacy and spend to one session id (or `latest`); suppression and manual marks stay all-time, and saved-bytes has no per-session figure").option("--reset", "clear all tracked emissions and manual marks").option("--mark-effective <category>", 'record a manual "effective" vote for a hint category').option("--mark-ineffective <category>", 'record a manual "ineffective" vote for a hint category').action(guard(cmdHintStats));
|
|
19278
19543
|
program2.command("statusline").description("render one line of terminal status text from a harness statusline payload on stdin (Claude Code statusLine.command)").option("--json", "emit the underlying data as JSON instead of a rendered line (debug)").action(guard(cmdStatusline));
|
|
19279
19544
|
program2.command("skill-body <name>").description("retrieve a skill's cached body").option("-c, --compact", "print compact slice instead of full body").action(guard(cmdSkillBody));
|
|
19280
19545
|
program2.command("skill-compact [name]").description("regenerate and cache compact slice for a skill").option("--path <file>", "read the skill body from this file instead of resolving by name").option("--all", "regenerate compacts for all skills, skipping fresh ones").action(guard(cmdSkillCompact));
|
|
@@ -19350,6 +19615,39 @@ function registerSessionCommands(program2, guard) {
|
|
|
19350
19615
|
program2.command("describe [target] [table]").description("describe columns and structure of a session store table or SQLite database file instead of querying SELECT *").option("-j, --json", "output as JSON").action(guard(cmdDescribe));
|
|
19351
19616
|
}
|
|
19352
19617
|
|
|
19618
|
+
// src/cli_hook_server.ts
|
|
19619
|
+
init_define_import_meta_env();
|
|
19620
|
+
async function cmdHookServerRun(opts) {
|
|
19621
|
+
const slot = Number(opts.slot ?? "0");
|
|
19622
|
+
const { runHookServer } = await import("./token-goat-chunk-ORNFMIER.mjs");
|
|
19623
|
+
try {
|
|
19624
|
+
await runHookServer(slot, (argv) => run(argv));
|
|
19625
|
+
} catch (e) {
|
|
19626
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
19627
|
+
touchMarker("failed", `slot ${slot}: ${message}`);
|
|
19628
|
+
throw new CliError(message);
|
|
19629
|
+
}
|
|
19630
|
+
}
|
|
19631
|
+
function formatHookServerStatus(s, now = Date.now()) {
|
|
19632
|
+
return `slot ${s.slot}: pid ${s.pid}, v${s.version}, up ${formatAge(now - s.startedAt)}, served ${s.served}, errors ${s.errors}, idle ${formatAge(now - s.lastUsedAt)}`;
|
|
19633
|
+
}
|
|
19634
|
+
async function cmdHookServerStatus(opts) {
|
|
19635
|
+
const statuses = await serverStatuses();
|
|
19636
|
+
if (opts.json === true) {
|
|
19637
|
+
out(displaySafeJson(statuses));
|
|
19638
|
+
return;
|
|
19639
|
+
}
|
|
19640
|
+
if (statuses.length === 0) {
|
|
19641
|
+
out("No hook server is running. The next hook call starts one.");
|
|
19642
|
+
return;
|
|
19643
|
+
}
|
|
19644
|
+
for (const s of statuses) out(formatHookServerStatus(s));
|
|
19645
|
+
}
|
|
19646
|
+
async function cmdHookServerStop() {
|
|
19647
|
+
const stopped = await queryServers("stop");
|
|
19648
|
+
out(stopped.length === 0 ? "No hook server is running." : `Stopped ${stopped.length} hook server${stopped.length === 1 ? "" : "s"}.`);
|
|
19649
|
+
}
|
|
19650
|
+
|
|
19353
19651
|
// src/bridges_status.ts
|
|
19354
19652
|
init_define_import_meta_env();
|
|
19355
19653
|
var NO_SERVER_HANDLER_REASON = "token-goat has no registered server-side handler for this event (zero registerHook('notification'|'stop', ...) call sites in src/) -- wiring it client-side would currently be a no-op";
|
|
@@ -20043,7 +20341,16 @@ function runBenchCommand(opts) {
|
|
|
20043
20341
|
|
|
20044
20342
|
// src/cli.ts
|
|
20045
20343
|
var CliError = class extends Error {
|
|
20344
|
+
lines;
|
|
20345
|
+
constructor(message) {
|
|
20346
|
+
super(typeof message === "string" ? message : message.join("\n"));
|
|
20347
|
+
this.lines = typeof message === "string" ? void 0 : message;
|
|
20348
|
+
}
|
|
20046
20349
|
};
|
|
20350
|
+
function formatCommandError(e) {
|
|
20351
|
+
if (e instanceof CliError && e.lines !== void 0) return "token-goat: " + e.lines.map(displaySafeText).join("\n");
|
|
20352
|
+
return "token-goat: " + displaySafeText(extractErrorMessage(e));
|
|
20353
|
+
}
|
|
20047
20354
|
function out(text) {
|
|
20048
20355
|
const payload = colorStdout() ? text : stripAnsiEscapes(text);
|
|
20049
20356
|
process.stdout.write(ensureNewline(payload));
|
|
@@ -20284,7 +20591,7 @@ async function cmdMcpServe() {
|
|
|
20284
20591
|
let StdioServerTransport;
|
|
20285
20592
|
try {
|
|
20286
20593
|
;
|
|
20287
|
-
({ createMcpServer } = await import("./token-goat-chunk-
|
|
20594
|
+
({ createMcpServer } = await import("./token-goat-chunk-PKRWMHVP.mjs"));
|
|
20288
20595
|
({ StdioServerTransport } = await import("./token-goat-chunk-EVC4TOLE.mjs"));
|
|
20289
20596
|
} catch (err2) {
|
|
20290
20597
|
process.stderr.write(
|
|
@@ -20309,7 +20616,7 @@ async function cmdHook(event, opts) {
|
|
|
20309
20616
|
if (typeof opts.harness === "string" && opts.harness.length > 0) {
|
|
20310
20617
|
process.env[ENV_KEYS.HARNESS_OVERRIDE] = opts.harness;
|
|
20311
20618
|
}
|
|
20312
|
-
const { relay } = await import("./token-goat-chunk-
|
|
20619
|
+
const { relay } = await import("./token-goat-chunk-Z6KBMOBI.mjs");
|
|
20313
20620
|
await relay(event);
|
|
20314
20621
|
}
|
|
20315
20622
|
function projectHooksCommitNote(pathFiles, hooksConfigPath) {
|
|
@@ -20346,7 +20653,7 @@ async function cmdInstall(opts) {
|
|
|
20346
20653
|
if (opts.project === true && opts.user === true) {
|
|
20347
20654
|
throw new Error("install takes either -p/--project or --user, not both.");
|
|
20348
20655
|
}
|
|
20349
|
-
await import("./token-goat-chunk-
|
|
20656
|
+
await import("./token-goat-chunk-Z6KBMOBI.mjs");
|
|
20350
20657
|
const scope = opts.project === true ? "project" : "user";
|
|
20351
20658
|
if (wantsClaudeCodeBase(opts)) {
|
|
20352
20659
|
const result = installHooks(scope);
|
|
@@ -20528,7 +20835,7 @@ function cmdMcpStatus(opts) {
|
|
|
20528
20835
|
const scope = opts.project === true ? { projectRoot: process.cwd() } : {};
|
|
20529
20836
|
out(displaySafeJson(opts.vscode === true ? vscodeDecoderConfigured(scope) : visualStudioMcpStatus(scope), 0));
|
|
20530
20837
|
}
|
|
20531
|
-
function cmdUninstall(opts) {
|
|
20838
|
+
async function cmdUninstall(opts) {
|
|
20532
20839
|
if (opts.project === true && opts.user === true) {
|
|
20533
20840
|
throw new Error("uninstall takes either -p/--project or --user, not both.");
|
|
20534
20841
|
}
|
|
@@ -20578,7 +20885,7 @@ function cmdUninstall(opts) {
|
|
|
20578
20885
|
if (opts.hermes === true) {
|
|
20579
20886
|
out("No separate Hermes integration to remove (it shares the Claude Code hook entries).");
|
|
20580
20887
|
}
|
|
20581
|
-
if (opts.purge === true) runPurge();
|
|
20888
|
+
if (opts.purge === true) await runPurge();
|
|
20582
20889
|
}
|
|
20583
20890
|
function leftoverIntegrations(opts) {
|
|
20584
20891
|
const candidates = [
|
|
@@ -20620,7 +20927,8 @@ function leftoverIntegrations(opts) {
|
|
|
20620
20927
|
}
|
|
20621
20928
|
return found;
|
|
20622
20929
|
}
|
|
20623
|
-
function runPurge() {
|
|
20930
|
+
async function runPurge() {
|
|
20931
|
+
await queryServers("stop");
|
|
20624
20932
|
if (isWorkerRunning()) {
|
|
20625
20933
|
err('token-goat: the background worker is running, so --purge would delete files it is about to rewrite. Run "token-goat worker stop" first.');
|
|
20626
20934
|
return;
|
|
@@ -20681,7 +20989,7 @@ async function cmdDoctor(opts) {
|
|
|
20681
20989
|
doctorOpts.rootDir = project.root;
|
|
20682
20990
|
}
|
|
20683
20991
|
if (opts.json === true) {
|
|
20684
|
-
const results =
|
|
20992
|
+
const results = await runDoctorChecks(doctorOpts.dataDir, doctorOpts.configPath, doctorOpts.rootDir);
|
|
20685
20993
|
out(displaySafeJson(results, 0));
|
|
20686
20994
|
if (results.some((r) => r.status === "fail")) {
|
|
20687
20995
|
throw new CliError("doctor checks failed");
|
|
@@ -20937,7 +21245,7 @@ async function cmdCompress(commandArgs, opts = {}) {
|
|
|
20937
21245
|
process.exitCode = 1;
|
|
20938
21246
|
return;
|
|
20939
21247
|
}
|
|
20940
|
-
const bashRunner = await import("./token-goat-chunk-
|
|
21248
|
+
const bashRunner = await import("./token-goat-chunk-VQ6F6T7X.mjs");
|
|
20941
21249
|
if (opts.compress === false) {
|
|
20942
21250
|
process.exitCode = bashRunner.runRaw(
|
|
20943
21251
|
command,
|
|
@@ -20959,7 +21267,7 @@ async function cmdCompress(commandArgs, opts = {}) {
|
|
|
20959
21267
|
...opts.shell !== void 0 ? { shellType: opts.shell } : {}
|
|
20960
21268
|
});
|
|
20961
21269
|
} catch (e) {
|
|
20962
|
-
err(
|
|
21270
|
+
err(formatCommandError(e));
|
|
20963
21271
|
process.exitCode = 1;
|
|
20964
21272
|
}
|
|
20965
21273
|
}
|
|
@@ -20991,11 +21299,41 @@ ${content}`;
|
|
|
20991
21299
|
const bytesSaved = cappedSourceBytesSaved(fullSourceBytes, Buffer.byteLength(toEmit, "utf8"));
|
|
20992
21300
|
recordStat("gdrive_sections", bytesSaved, savedTokensFromBytes(bytesSaved));
|
|
20993
21301
|
}
|
|
21302
|
+
var READ_ONLY_INDEX_COMMANDS = /* @__PURE__ */ new Set([
|
|
21303
|
+
"symbol",
|
|
21304
|
+
"read",
|
|
21305
|
+
"brief",
|
|
21306
|
+
"section",
|
|
21307
|
+
"semantic",
|
|
21308
|
+
"skeleton",
|
|
21309
|
+
"outline",
|
|
21310
|
+
"refs",
|
|
21311
|
+
"answer",
|
|
21312
|
+
"ask",
|
|
21313
|
+
"map",
|
|
21314
|
+
"exports",
|
|
21315
|
+
"imports",
|
|
21316
|
+
"find",
|
|
21317
|
+
"locate",
|
|
21318
|
+
"callers",
|
|
21319
|
+
"call-chain",
|
|
21320
|
+
"impact",
|
|
21321
|
+
"dead",
|
|
21322
|
+
"deps",
|
|
21323
|
+
"types",
|
|
21324
|
+
"scope",
|
|
21325
|
+
"similar",
|
|
21326
|
+
"context-for",
|
|
21327
|
+
"test-for"
|
|
21328
|
+
]);
|
|
20994
21329
|
var originalHelpInformation = null;
|
|
20995
21330
|
function buildProgram() {
|
|
20996
21331
|
const program2 = new Command();
|
|
20997
21332
|
program2.name("token-goat").description("Surgical token-reduction companion for AI coding agents").version(VERSION, "-v, --version", "print the token-goat version").option("--cwd <path>", "run as if invoked from this directory (overrides the real working directory)").option("--notice <text>", "print this line to stdout before the command's own output");
|
|
20998
|
-
program2.hook("preAction", (thisCommand) => {
|
|
21333
|
+
program2.hook("preAction", (thisCommand, actionCommand) => {
|
|
21334
|
+
if (actionCommand.parent === program2 && READ_ONLY_INDEX_COMMANDS.has(actionCommand.name())) {
|
|
21335
|
+
allowReadOnlyIndex(() => err("token-goat: the index database cannot be written here, so this run reads it without writing: no stats are recorded and changed files are not reindexed."));
|
|
21336
|
+
}
|
|
20999
21337
|
const opts = thisCommand.opts();
|
|
21000
21338
|
const cwdOverride = opts.cwd;
|
|
21001
21339
|
if (cwdOverride !== void 0) {
|
|
@@ -21030,8 +21368,7 @@ function buildProgram() {
|
|
|
21030
21368
|
process.exitCode = 0;
|
|
21031
21369
|
}
|
|
21032
21370
|
} catch (e) {
|
|
21033
|
-
|
|
21034
|
-
err(`token-goat: ${displaySafeText(msg)}`);
|
|
21371
|
+
err(formatCommandError(e));
|
|
21035
21372
|
process.exitCode = 1;
|
|
21036
21373
|
}
|
|
21037
21374
|
};
|
|
@@ -21188,13 +21525,17 @@ function buildProgram() {
|
|
|
21188
21525
|
program2.command("handoff-create <name> [text]").description("create a project-local named compressed handoff").option("--file <path>", "read handoff text from a local file instead of the argument").action(guard(cmdHandoffCreate));
|
|
21189
21526
|
program2.command("handoff-resolve <name>").description("resolve a project-local handoff compactly, or return it in full").option("--full", "return the full handoff text").action(guard(cmdHandoffResolve));
|
|
21190
21527
|
program2.command("hook <event>").description("hook relay entrypoint (reads JSON on stdin)").option("--harness <name>", "override harness detection for this invocation (sets TOKEN_GOAT_HARNESS_OVERRIDE)").action(guard(cmdHook));
|
|
21191
|
-
program2.command("install").description("install hooks into Claude Code settings").option("-p, --project", "install into project scope instead of user scope").option("--user", "with --vscode, install into user scope instead of this project (every project at once, but nothing past the first folder of a multi-root workspace)").option("--codex", "
|
|
21192
|
-
program2.command("uninstall").description("remove token-goat hooks from Claude Code settings").option("-p, --project", "uninstall from project scope instead of user scope").option("--user", "with --vscode, remove the user-scope install instead of this project one").option("--codex", "
|
|
21528
|
+
program2.command("install").description("install hooks into Claude Code settings, or with harness flags into those harnesses instead").option("-p, --project", "install into project scope instead of user scope").option("--user", "with --vscode, install into user scope instead of this project (every project at once, but nothing past the first folder of a multi-root workspace)").option("--codex", "patch Codex CLI (~/.codex/config.toml, ~/.codex/AGENTS.md)").option("--gemini", "patch Gemini CLI (~/.gemini/settings.json)").option("--qwen", "patch Qwen Code (~/.qwen/settings.json)").option("--kimi", "register a Kimi Code hook config, shim, instructions block and skill ($KIMI_CODE_HOME or ~/.kimi-code: config.toml, hooks/token-goat-shim.cjs, AGENTS.md, skills/token-goat/SKILL.md)").option("--pi", "drop a pi (pi-coding-agent) extension (~/.pi/agent/extensions/token-goat.ts)").option("--opencode", "drop an opencode plugin (~/.config/opencode/plugins/token-goat.ts, %APPDATA%\\opencode\\plugins\\token-goat.ts on Windows)").option("--hermes", "verify token-goat hooks are present for Hermes Agent (writes nothing new)").option("--openclaw", "register an OpenClaw plugin (~/.openclaw/openclaw.json, ~/.openclaw/plugins/token-goat.ts)").option("--copilot", "register a Copilot CLI hook config and routing block (~/.copilot/hooks/token-goat.json, ~/.copilot/hooks/token-goat-shim.cjs, ~/.copilot/copilot-instructions.md; with --local, <project>/.github/hooks/token-goat.json, <project>/.github/hooks/token-goat-shim.cjs, <project>/.github/copilot-instructions.md)").option("--grok", "register a Grok CLI (xAI Grok Build) hook config (~/.grok/hooks/token-goat.json, ~/.grok/hooks/token-goat-shim.cjs)").option("--vscode", "configure a VS Code MCP server (the workspace .vscode/mcp.json by default; --user for the user-profile mcp.json) and Copilot routing guidance").option("--visualstudio", "configure a Visual Studio (2022 17.14+ / 2026) Copilot MCP server and routing guidance, no hooks (%USERPROFILE%\\.mcp.json and %USERPROFILE%\\copilot-instructions.md; -p/--project for <project>/.mcp.json and <project>/.github/copilot-instructions.md)").option("--zed", "register token-goat as a Zed MCP context server (%APPDATA%\\Zed\\settings.json on Windows, ~/.config/zed/settings.json elsewhere, plus a generated shim script); Zed has no hooks API, so this is user scope only, no -p/--project support").option("--cursor", 'register a Cursor MCP server (~/.cursor/mcp.json by default; -p/--project for <project>/.cursor/mcp.json); writes no Cursor hooks config -- Cursor already imports the Claude Code hooks "token-goat install" writes to ~/.claude/settings.json').option("--local", "with --pi, install the project-local extension (<project>/.pi/extensions/token-goat.ts) instead of the global one").action(guard(cmdInstall));
|
|
21529
|
+
program2.command("uninstall").description("remove token-goat hooks from Claude Code settings, or with harness flags from those harnesses instead").option("-p, --project", "uninstall from project scope instead of user scope").option("--user", "with --vscode, remove the user-scope install instead of this project one").option("--codex", "strip the Codex CLI integration (~/.codex/config.toml, ~/.codex/AGENTS.md)").option("--gemini", "strip the Gemini CLI integration (~/.gemini/settings.json)").option("--qwen", "strip the Qwen Code integration (~/.qwen/settings.json)").option("--kimi", "strip the Kimi Code integration (config.toml hooks, hooks/token-goat-shim.cjs, the AGENTS.md block and skills/token-goat under $KIMI_CODE_HOME or ~/.kimi-code)").option("--pi", "remove the pi (pi-coding-agent) extension").option("--opencode", "remove the opencode plugin").option("--hermes", "no-op verification flag for symmetry with install (removes no files)").option("--openclaw", "remove the OpenClaw plugin and config entry").option("--copilot", "remove the Copilot CLI hook config and shim script, and strip the token-goat block from ~/.copilot/copilot-instructions.md (or <project>/.github/copilot-instructions.md with --local)").option("--grok", "remove the Grok CLI hook config and shim script").option("--vscode", "remove the VS Code MCP server (project scope by default; --user for the user-profile one) and routing guidance").option("--visualstudio", "remove the Visual Studio MCP server entry and routing guidance (user scope by default; -p/--project for the project one)").option("--zed", "remove the Zed MCP context server entry and its generated shim script").option("--cursor", "remove the Cursor MCP server entry (user scope by default; -p/--project for the project one)").option("--local", "with --pi, remove the project-local extension instead of the global one").option("--purge", "also delete the data directories (index, caches, session state, logs); refuses while the worker is running").action(guard(cmdUninstall));
|
|
21193
21530
|
program2.command("mcp-status").description("check whether an MCP integration is already configured (used by the VS Code extension)").option("--vscode", "check VS Code mcp.json (user scope, plus workspace scope with --project)").option("--visualstudio", "check the Visual Studio %USERPROFILE%\\.mcp.json (plus the project .mcp.json with --project)").option("-p, --project", "also check the project file: .vscode/mcp.json for --vscode, .mcp.json for --visualstudio (relative to --cwd or the real cwd)").action(guard(cmdMcpStatus));
|
|
21194
21531
|
const worker = program2.command("worker").description("background indexer lifecycle");
|
|
21195
21532
|
worker.command("start").description("start the background indexer").action(guard(cmdWorkerStart));
|
|
21196
21533
|
worker.command("stop").description("stop the background indexer").action(guard(cmdWorkerStop));
|
|
21197
21534
|
worker.command("status").description("check if the indexer is running").action(guard(cmdWorkerStatus));
|
|
21535
|
+
const hookServer = program2.command("hook-server").description("resident processes that answer hook calls and read-only commands without starting Node for each one");
|
|
21536
|
+
hookServer.command("run", { hidden: true }).description("serve one slot (started automatically by the first hook call)").option("--slot <n>", "which slot to serve", "0").action(guard(cmdHookServerRun));
|
|
21537
|
+
hookServer.command("status").description("list the running hook servers").option("-j, --json", "output as JSON").action(guard(cmdHookServerStatus));
|
|
21538
|
+
hookServer.command("stop").description("stop every running hook server (the next hook call starts a fresh one)").action(guard(cmdHookServerStop));
|
|
21198
21539
|
program2.command("stats").description("show session statistics (bare = totals only; --full for the breakdown)").option("-j, --json", "output as JSON").option("--full", "show the full breakdown (by source, by command, by day)").option("--short", "force the rich short KPI view even when stdout is not a TTY (e.g. piped)").option("--methodology", "explain local savings estimates and their billing limits").option("--hooks", "show the per-event/per-harness hook latency breakdown (median/p95/slowest/last-seen)").option("--window-days <days>", "days to include (0 = all time)", "30").option("--home-dir <path>", "home directory (for testing)").action(guard(cmdStats));
|
|
21199
21540
|
program2.command("doctor").description("diagnose token-goat health").option("--context", "include context footprint analysis").option("--json", "emit check results as JSON instead of text").option("--repair", "automatically repair fixable issues (permissive settings, missing semantics models)").option("--fix", "alias for --repair").action(guard(cmdDoctor));
|
|
21200
21541
|
program2.command("bash-output [id]").description("retrieve cached bash output by ID or file").option("--head <n>", "show first N lines").option("--tail <n>", "show last N lines").option("--grep <pattern>", "filter lines matching regex").option("--max-matches <n>", "cap --grep output to the first N matching lines").option("--section <heading>", "extract a specific section from the output").option("--full", "print the entire cached entry with no head/tail elision").option("--file <path>", "read from raw output file instead of cache").option("--transcript", "parse the --file as a JSONL agent transcript: keep assistant text blocks in order before filtering").option("--verify-last-write [seconds]", "verify the file or cache entry was written within [seconds] (default: 60s) to catch stale/no-op terminal output").option("--strict", "exit non-zero when --verify-last-write detects stale output").action(guard(cmdBashOutput));
|
|
@@ -21210,7 +21551,7 @@ function buildProgram() {
|
|
|
21210
21551
|
program2.command("compress [command...]").alias("bash").alias("run").description("run a shell command (under a POSIX shell / bash) and emit a compressed view of its output").allowUnknownOption(true).option("-c, --cmd <command>", "the shell command to run, as one string (use / for paths across platforms)").option("--cmd-b64 <payload>", "the shell command as a base64-encoded string (preserves quotes, backslashes, and symbols across platforms)").option("--shell <type>", "shell interpreter to run under: bash | pwsh | powershell | native").option("-f, --filter <name>", "filter name (auto-detected from the command when omitted)").option("--timeout <seconds>", "wall-clock timeout in seconds (0 = built-in default)").option("--no-compress", "stream output raw without compression (debug the wrapper)").option("--profile <name>", "compression profile: aggressive | balanced | minimal").option("--max-tokens <n>", "post-compress token cap (0 = no cap)").option("--cap-hint-b64 <payload>", "base64 text printed after the output when --max-tokens cut it (the Bash hook sets it to the narrower read command)").option("-q, --quiet-success", "on exit code 0, emit only [tg: ok] summary and store full output for recall via bash-output").option("--native", "use native platform shell (e.g. cmd.exe on Windows) instead of bash, preserving Windows path backslashes").action(cmdCompress);
|
|
21211
21552
|
program2.command("upgrade").alias("update").description("check for updates and upgrade token-goat to the latest version").option("--check", "check whether an update is available without installing").option("-j, --json", "emit version check status as JSON").action(
|
|
21212
21553
|
(opts) => guard(async () => {
|
|
21213
|
-
const { cmdUpgrade } = await import("./token-goat-chunk-
|
|
21554
|
+
const { cmdUpgrade } = await import("./token-goat-chunk-YAGLESS3.mjs");
|
|
21214
21555
|
await cmdUpgrade(opts, () => cmdInstall({}));
|
|
21215
21556
|
})()
|
|
21216
21557
|
);
|
|
@@ -21260,7 +21601,7 @@ async function run(argv = process.argv) {
|
|
|
21260
21601
|
return;
|
|
21261
21602
|
}
|
|
21262
21603
|
if (argv[2] === "--batch-serve" && typeof argv[3] === "string") {
|
|
21263
|
-
const { serveBatch } = await import("./token-goat-chunk-
|
|
21604
|
+
const { serveBatch } = await import("./token-goat-chunk-ASLWOQ3I.mjs");
|
|
21264
21605
|
serveBatch(argv[3], (a) => run(a));
|
|
21265
21606
|
return;
|
|
21266
21607
|
}
|
|
@@ -21284,80 +21625,81 @@ async function run(argv = process.argv) {
|
|
|
21284
21625
|
process.exitCode = 1;
|
|
21285
21626
|
return;
|
|
21286
21627
|
}
|
|
21287
|
-
|
|
21288
|
-
err(`token-goat: ${displaySafeText(msg)}`);
|
|
21628
|
+
err(formatCommandError(e));
|
|
21289
21629
|
process.exitCode = 1;
|
|
21290
21630
|
}
|
|
21291
21631
|
}
|
|
21292
|
-
|
|
21293
21632
|
export {
|
|
21294
|
-
|
|
21295
|
-
|
|
21296
|
-
|
|
21297
|
-
|
|
21298
|
-
|
|
21299
|
-
|
|
21300
|
-
|
|
21301
|
-
cmdPdfExtract,
|
|
21302
|
-
cmdPdfLocate,
|
|
21303
|
-
cmdPdfOutline,
|
|
21304
|
-
cmdPdfMeta,
|
|
21305
|
-
cmdVideoChapters,
|
|
21306
|
-
cmdSharepointResolve,
|
|
21307
|
-
cmdXlsxSheets,
|
|
21308
|
-
cmdXlsxHead,
|
|
21309
|
-
cmdXlsxColumns,
|
|
21310
|
-
cmdXlsxRange,
|
|
21311
|
-
cmdXlsxQuery,
|
|
21312
|
-
cmdPptxOutline,
|
|
21313
|
-
cmdPptxSlide,
|
|
21314
|
-
cmdPptxNotes,
|
|
21315
|
-
cmdPptxText,
|
|
21633
|
+
CliError,
|
|
21634
|
+
_applyFiltersAndPrint,
|
|
21635
|
+
applyExitOverride,
|
|
21636
|
+
buildProgram,
|
|
21637
|
+
cmdCsvProfile,
|
|
21638
|
+
cmdCsvQuery,
|
|
21639
|
+
cmdDescribe,
|
|
21316
21640
|
cmdDocxOutline,
|
|
21317
21641
|
cmdDocxTables,
|
|
21318
21642
|
cmdDocxText,
|
|
21319
|
-
|
|
21320
|
-
cmdTranscript,
|
|
21321
|
-
cmdCsvQuery,
|
|
21322
|
-
cmdCsvProfile,
|
|
21323
|
-
cmdJsonOutline,
|
|
21324
|
-
cmdJsonQuery,
|
|
21325
|
-
cmdYamlOutline,
|
|
21326
|
-
cmdYamlQuery,
|
|
21327
|
-
cmdXmlOutline,
|
|
21328
|
-
cmdXmlQuery,
|
|
21643
|
+
cmdHtmlLint,
|
|
21329
21644
|
cmdHtmlOutline,
|
|
21330
21645
|
cmdHtmlQuery,
|
|
21331
|
-
cmdHtmlLint,
|
|
21332
|
-
cmdOpenApiOutline,
|
|
21333
|
-
cmdOpenApiOp,
|
|
21334
|
-
cmdZipList,
|
|
21335
|
-
cmdZipRead,
|
|
21336
|
-
cmdNoteAdd,
|
|
21337
|
-
cmdWriteFile,
|
|
21338
|
-
cmdReplace,
|
|
21339
|
-
cmdInsertSection,
|
|
21340
|
-
fenceOcrText,
|
|
21341
21646
|
cmdImageMeta,
|
|
21342
21647
|
cmdImageText,
|
|
21343
|
-
|
|
21344
|
-
|
|
21345
|
-
|
|
21648
|
+
cmdIndex,
|
|
21649
|
+
cmdInsertSection,
|
|
21650
|
+
cmdJsonOutline,
|
|
21651
|
+
cmdJsonQuery,
|
|
21652
|
+
cmdNoteAdd,
|
|
21653
|
+
cmdOpenApiOp,
|
|
21654
|
+
cmdOpenApiOutline,
|
|
21655
|
+
cmdPdfExtract,
|
|
21656
|
+
cmdPdfLocate,
|
|
21657
|
+
cmdPdfMeta,
|
|
21658
|
+
cmdPdfOutline,
|
|
21659
|
+
cmdPptxNotes,
|
|
21660
|
+
cmdPptxOutline,
|
|
21661
|
+
cmdPptxSlide,
|
|
21662
|
+
cmdPptxText,
|
|
21663
|
+
cmdReplace,
|
|
21664
|
+
cmdSessionSchema,
|
|
21665
|
+
cmdSharepointResolve,
|
|
21346
21666
|
cmdSkillBody,
|
|
21347
21667
|
cmdSkillCompact,
|
|
21348
|
-
cmdSkillList,
|
|
21349
|
-
cmdSkillSize,
|
|
21350
|
-
cmdSkillHistory,
|
|
21351
21668
|
cmdSkillDiff,
|
|
21669
|
+
cmdSkillHistory,
|
|
21670
|
+
cmdSkillList,
|
|
21352
21671
|
cmdSkillSection,
|
|
21353
|
-
|
|
21354
|
-
|
|
21672
|
+
cmdSkillSize,
|
|
21673
|
+
cmdSqliteQuery,
|
|
21674
|
+
cmdSqliteSchema,
|
|
21675
|
+
cmdSqliteTables,
|
|
21676
|
+
cmdTranscript,
|
|
21677
|
+
cmdTranscriptOutline,
|
|
21678
|
+
cmdVideoChapters,
|
|
21679
|
+
cmdWriteFile,
|
|
21680
|
+
cmdXlsxColumns,
|
|
21681
|
+
cmdXlsxHead,
|
|
21682
|
+
cmdXlsxQuery,
|
|
21683
|
+
cmdXlsxRange,
|
|
21684
|
+
cmdXlsxSheets,
|
|
21685
|
+
cmdXmlOutline,
|
|
21686
|
+
cmdXmlQuery,
|
|
21687
|
+
cmdYamlOutline,
|
|
21688
|
+
cmdYamlQuery,
|
|
21689
|
+
cmdZipList,
|
|
21690
|
+
cmdZipRead,
|
|
21355
21691
|
err,
|
|
21356
|
-
|
|
21357
|
-
|
|
21692
|
+
expandGlobs,
|
|
21693
|
+
fenceFileFieldIfMatched,
|
|
21694
|
+
fenceFileText,
|
|
21695
|
+
fenceOcrText,
|
|
21696
|
+
fileSizeOrZero,
|
|
21697
|
+
formatCommandError,
|
|
21358
21698
|
leftoverIntegrations,
|
|
21359
|
-
|
|
21360
|
-
|
|
21361
|
-
|
|
21362
|
-
|
|
21699
|
+
out,
|
|
21700
|
+
requireInt,
|
|
21701
|
+
requireNonNegativeInt,
|
|
21702
|
+
requirePositiveInt,
|
|
21703
|
+
run,
|
|
21704
|
+
visualStudioManualSteps
|
|
21363
21705
|
};
|