token-goat 2.9.19 → 2.9.20
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 +3 -1
- package/dist/token-goat-chunk-2CLWWRFR.mjs +26 -0
- package/dist/{token-goat-chunk-WKO5TVNA.mjs → token-goat-chunk-2Q3N5KUQ.mjs} +531 -571
- package/dist/{token-goat-chunk-DA6TIDLI.mjs → token-goat-chunk-3OGZOFLS.mjs} +18 -13
- package/dist/{token-goat-chunk-PIAESKVU.mjs → token-goat-chunk-3VTJC7KU.mjs} +568 -429
- package/dist/{token-goat-chunk-ZGQXRYKE.mjs → token-goat-chunk-6LJNM4ZZ.mjs} +1 -1
- package/dist/{token-goat-chunk-SOKAPOOC.mjs → token-goat-chunk-74ADIZZX.mjs} +46 -47
- package/dist/{token-goat-chunk-LACH3WKS.mjs → token-goat-chunk-ASTBLE2R.mjs} +3 -3
- package/dist/{token-goat-chunk-VJQBYSXG.mjs → token-goat-chunk-AU2K2QHR.mjs} +3 -3
- package/dist/token-goat-chunk-BQIC3AVL.mjs +292 -0
- package/dist/{token-goat-chunk-P46RTOAQ.mjs → token-goat-chunk-CBXLE54Q.mjs} +10 -7
- package/dist/{token-goat-chunk-3W5P673V.mjs → token-goat-chunk-DNAF26L4.mjs} +1 -1
- package/dist/{token-goat-chunk-FQYMZASI.mjs → token-goat-chunk-DPHJU3P7.mjs} +789 -4456
- package/dist/{token-goat-chunk-FX5DHKGF.mjs → token-goat-chunk-DW4VKU7D.mjs} +4 -4
- package/dist/token-goat-chunk-DYUBZZNP.mjs +198 -0
- package/dist/{token-goat-chunk-EP7TCWHM.mjs → token-goat-chunk-ERGHDBC6.mjs} +70 -65
- package/dist/token-goat-chunk-EUZKG7ZO.mjs +304 -0
- package/dist/{token-goat-chunk-AVRD7SBO.mjs → token-goat-chunk-FWYZVS3E.mjs} +270 -29
- package/dist/token-goat-chunk-G6SYQQO7.mjs +41 -0
- package/dist/{token-goat-chunk-62VJ47WN.mjs → token-goat-chunk-GIPMOGOI.mjs} +5 -5
- package/dist/{token-goat-chunk-L2UOJBV4.mjs → token-goat-chunk-H4VC5TR6.mjs} +27 -19
- package/dist/{token-goat-chunk-2GTB5RBZ.mjs → token-goat-chunk-I5PQRHFE.mjs} +11 -271
- package/dist/{token-goat-chunk-MU6I4IDI.mjs → token-goat-chunk-ITWYDOKP.mjs} +11 -7
- package/dist/{token-goat-chunk-IBTFGZBX.mjs → token-goat-chunk-K3ZNBN4U.mjs} +2 -2
- package/dist/{token-goat-chunk-S7RFIX4Y.mjs → token-goat-chunk-K5XPIUVB.mjs} +45 -14
- package/dist/token-goat-chunk-KT75DZK4.mjs +1989 -0
- package/dist/{token-goat-chunk-F24NE3FO.mjs → token-goat-chunk-MNJWG2ZO.mjs} +2 -2
- package/dist/{token-goat-chunk-NJKNAC37.mjs → token-goat-chunk-MUJV7BR3.mjs} +1 -1
- package/dist/{token-goat-chunk-FJZ5MZK7.mjs → token-goat-chunk-ODF7H7WS.mjs} +2 -2
- package/dist/{token-goat-chunk-GYC34EGE.mjs → token-goat-chunk-ONMU7BON.mjs} +2 -2
- package/dist/{token-goat-chunk-KWM6KBPA.mjs → token-goat-chunk-P4XBHZXU.mjs} +1 -1
- package/dist/{token-goat-chunk-7DGTVBWP.mjs → token-goat-chunk-PAVWB4L4.mjs} +159 -1863
- package/dist/{token-goat-chunk-DHIXE6GV.mjs → token-goat-chunk-PTW22MRC.mjs} +1 -1
- package/dist/token-goat-chunk-SL454EN5.mjs +1816 -0
- package/dist/token-goat-chunk-SP5QR2HN.mjs +1379 -0
- package/dist/{token-goat-chunk-BTKDZW7F.mjs → token-goat-chunk-T46UKRFM.mjs} +1 -1
- package/dist/{token-goat-chunk-JNIFSVWM.mjs → token-goat-chunk-T63VHOL3.mjs} +5 -1
- package/dist/token-goat-chunk-VSJGPEBB.mjs +248 -0
- package/dist/{token-goat-chunk-EXLLLIC3.mjs → token-goat-chunk-VYXGHGUY.mjs} +3 -3
- package/dist/token-goat-chunk-W6QYCWAT.mjs +128 -0
- package/dist/{token-goat-chunk-HPMMLV37.mjs → token-goat-chunk-Z4ALQADF.mjs} +256 -341
- package/dist/token-goat-chunk-ZHFM4DHJ.mjs +324 -0
- package/dist/token-goat-hook.mjs +17 -11
- package/dist/token-goat.core.mjs +27 -19
- package/docs/C4_RUNTIME_ARCHITECTURE.md +1 -1
- package/docs/cli.md +13 -12
- package/docs/install.md +1 -1
- package/docs/security.md +2 -2
- package/package.json +3 -2
- package/dist/token-goat-chunk-NYFYIRG3.mjs +0 -35
|
@@ -2,7 +2,16 @@ import { createRequire as __cjsRequire } from 'node:module';
|
|
|
2
2
|
const require = __cjsRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
4
|
compareSemver
|
|
5
|
-
} from "./token-goat-chunk-
|
|
5
|
+
} from "./token-goat-chunk-ONMU7BON.mjs";
|
|
6
|
+
import {
|
|
7
|
+
buildCopilotWasteReport,
|
|
8
|
+
findLatestCopilotSession,
|
|
9
|
+
findProjectSession,
|
|
10
|
+
isCopilotTranscript
|
|
11
|
+
} from "./token-goat-chunk-EUZKG7ZO.mjs";
|
|
12
|
+
import {
|
|
13
|
+
buildResumePacket
|
|
14
|
+
} from "./token-goat-chunk-W6QYCWAT.mjs";
|
|
6
15
|
import {
|
|
7
16
|
ALL_SYMBOLS_IN_FILE_LIMIT,
|
|
8
17
|
AMBIGUOUS_HEADING_LIMIT,
|
|
@@ -13,6 +22,8 @@ import {
|
|
|
13
22
|
computeFileFingerprint,
|
|
14
23
|
createHandoff,
|
|
15
24
|
didYouMean,
|
|
25
|
+
emit,
|
|
26
|
+
emitErr,
|
|
16
27
|
enclosingSymbol,
|
|
17
28
|
extraFileArgsNote,
|
|
18
29
|
extractTranscriptText,
|
|
@@ -96,183 +107,197 @@ import {
|
|
|
96
107
|
symbolNamesInFile,
|
|
97
108
|
upsertNote,
|
|
98
109
|
warnIfFilesStale
|
|
99
|
-
} from "./token-goat-chunk-
|
|
110
|
+
} from "./token-goat-chunk-3VTJC7KU.mjs";
|
|
100
111
|
import {
|
|
101
112
|
DEFAULT_RECONCILE_BUDGET_MS,
|
|
102
113
|
HOOK_EVENTS,
|
|
103
114
|
MCP_TOOL_PATTERN,
|
|
104
115
|
WEB_OUTPUT_SUBDIR,
|
|
105
116
|
buildCommandManifest,
|
|
106
|
-
buildWasteReport,
|
|
107
117
|
checkSymbolBodySize,
|
|
108
118
|
cmdDescribe,
|
|
109
119
|
cmdSessionSchema,
|
|
110
|
-
extractResultText,
|
|
111
120
|
filterCommandManifest,
|
|
112
|
-
findLatestTranscript,
|
|
113
121
|
formatCommandManifest,
|
|
114
122
|
getWebOutput,
|
|
115
123
|
getWebOutputByUrlFromDisk,
|
|
116
124
|
getWebOutputRaw,
|
|
117
|
-
projectTranscriptsDir,
|
|
118
125
|
readStdinJson,
|
|
119
126
|
runRecallCommand,
|
|
120
127
|
runReconcile,
|
|
121
|
-
safeStringify,
|
|
122
128
|
storeWebOutput
|
|
123
|
-
} from "./token-goat-chunk-
|
|
129
|
+
} from "./token-goat-chunk-I5PQRHFE.mjs";
|
|
130
|
+
import {
|
|
131
|
+
buildWasteReport,
|
|
132
|
+
extractResultText,
|
|
133
|
+
findLatestTranscript,
|
|
134
|
+
projectTranscriptsDir,
|
|
135
|
+
safeStringify
|
|
136
|
+
} from "./token-goat-chunk-BQIC3AVL.mjs";
|
|
137
|
+
import {
|
|
138
|
+
buildManifest
|
|
139
|
+
} from "./token-goat-chunk-VSJGPEBB.mjs";
|
|
124
140
|
import {
|
|
125
|
-
AGENT_SALT_MARKER,
|
|
126
|
-
CONTEXT_AUTOCOMPACT_TOKENS,
|
|
127
141
|
GEMINI_TOOL_NAME_MAP,
|
|
128
|
-
HOOKS_SCRIPT_FILE,
|
|
129
|
-
MATERIALIZE_SHRUNK_IMAGE_JS,
|
|
130
142
|
MAX_FILES_SCANNED,
|
|
131
|
-
SESSIONS_SUBDIR,
|
|
132
|
-
SKILLS_OUTPUT_SUBDIR,
|
|
133
143
|
SKIP_DIRS,
|
|
134
144
|
WORKER_HEARTBEAT_STALE_MS,
|
|
135
145
|
WorkerAlreadyRunningError,
|
|
136
146
|
applyIndexingPriority,
|
|
137
147
|
auditClaudeMd,
|
|
138
148
|
buildExtractiveCompact,
|
|
139
|
-
buildGuidanceBlock,
|
|
140
|
-
buildGuidanceBody,
|
|
141
149
|
buildLineDiff,
|
|
142
|
-
buildManifestWithCount,
|
|
143
150
|
buildProjectMap,
|
|
144
151
|
buildStats,
|
|
145
|
-
bundledCliPath,
|
|
146
|
-
capJsonRows,
|
|
147
|
-
claudeConfigDir,
|
|
148
152
|
cmdReclaimIndex,
|
|
149
153
|
compactDoc,
|
|
150
154
|
compactPathFor,
|
|
151
155
|
confirmAndApply,
|
|
152
|
-
contentHash,
|
|
153
|
-
copilotCliConfigPath,
|
|
154
|
-
copilotCliMcpToolsDir,
|
|
155
|
-
copilotCliScriptPath,
|
|
156
|
-
copilotCliUserRoot,
|
|
157
|
-
copilotHooksFilePaths,
|
|
158
156
|
detectWalkMode,
|
|
159
157
|
dirtyQueuePathFor,
|
|
160
158
|
drainHeartbeatPathFor,
|
|
161
|
-
dropEmptyServers,
|
|
162
159
|
emptyIndexMessage,
|
|
163
160
|
enqueueDirtyPathSafe,
|
|
164
|
-
estimateTokens,
|
|
165
|
-
estimateTokensFromLength,
|
|
166
|
-
extractChecklistSection,
|
|
167
|
-
extractCompactFromMarker,
|
|
168
|
-
extractNamedSection,
|
|
169
161
|
fenceUntrusted,
|
|
170
162
|
findClaudeMdFiles,
|
|
171
163
|
findContentDuplicates,
|
|
172
|
-
findLatestSessionId,
|
|
173
164
|
findMemSuggestionCandidates,
|
|
174
165
|
findMemoryMd,
|
|
175
166
|
findOrphanedChunkPaths,
|
|
176
167
|
findSystemTempFiles,
|
|
177
168
|
findTopIndexedProjects,
|
|
178
|
-
formatAge,
|
|
179
|
-
formatBytes,
|
|
180
169
|
formatMemSuggestions,
|
|
181
170
|
formatProjectMap,
|
|
182
171
|
formatSymbolLocation,
|
|
183
|
-
formatTokenEstimate,
|
|
184
|
-
getContextPressure,
|
|
185
172
|
getDirtyPathsFor,
|
|
186
173
|
getEmbeddingCoverage,
|
|
187
174
|
getHintStatsSummary,
|
|
188
175
|
getHintStatsTotals,
|
|
189
176
|
getParserFreshness,
|
|
190
177
|
getProjectIndexCounts,
|
|
191
|
-
getSessionFiles,
|
|
192
|
-
getSessionId,
|
|
193
|
-
getSkillFilePath,
|
|
194
178
|
getTrackedFiles,
|
|
195
|
-
|
|
196
|
-
incrementSkillHit,
|
|
179
|
+
indexSizeBytes,
|
|
197
180
|
injectionFencingEnabled,
|
|
198
|
-
installCopilotCli,
|
|
199
|
-
installCopilotHooksFile,
|
|
200
|
-
installVisualStudio,
|
|
201
181
|
isCompactFresh,
|
|
202
|
-
isCopilotCliInstalled,
|
|
203
182
|
isHintCategory,
|
|
204
183
|
isIgnoredIndexPath,
|
|
205
|
-
isManagedServer,
|
|
206
184
|
isPrivateIpv4Octets,
|
|
207
185
|
isPrivateIpv6Groups,
|
|
208
|
-
isResidueServersJson,
|
|
209
186
|
isSuppressionCategory,
|
|
210
|
-
isVisualStudioInstalled,
|
|
211
187
|
isWorkerRunning,
|
|
212
|
-
jsonc,
|
|
213
|
-
listOutputs,
|
|
214
|
-
listSkills,
|
|
215
|
-
loadSessionCache,
|
|
216
|
-
managedServer,
|
|
217
188
|
mapLookupBytesSaved,
|
|
218
189
|
markCategoryEffective,
|
|
219
190
|
markCategoryIneffective,
|
|
220
191
|
pruneBlockedRoot,
|
|
221
192
|
pruneDeletedFiles,
|
|
222
193
|
pruneOrphanedChunks,
|
|
223
|
-
|
|
194
|
+
pruneOrphanedVectors,
|
|
224
195
|
pruneSystemTempFiles,
|
|
225
196
|
pruneUnembeddableChunks,
|
|
226
197
|
readCompactBody,
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
readServersJson,
|
|
230
|
-
releaseCopilotHooksFile,
|
|
198
|
+
reclaimIndex,
|
|
199
|
+
recordKnownRootThrottled,
|
|
231
200
|
removeFileFromIndex,
|
|
232
201
|
resetHintStats,
|
|
233
202
|
runContextStats,
|
|
234
203
|
runDetachedWorkerDaemon,
|
|
235
204
|
scanAndRecord,
|
|
236
|
-
serversOf,
|
|
237
|
-
sessionsDir,
|
|
238
|
-
setTokenGoatServer,
|
|
239
205
|
shrinkImage,
|
|
240
|
-
skillDescriptionLine,
|
|
241
|
-
skillOutputsDir,
|
|
242
206
|
startDetachedWorker,
|
|
243
207
|
stopWorker,
|
|
244
|
-
storeCompact,
|
|
245
|
-
storeOutput,
|
|
246
|
-
syncVisualStudioProjectGuidance,
|
|
247
208
|
toolMatcherFor,
|
|
248
|
-
trimToBudget,
|
|
249
|
-
uninstallCopilotCli,
|
|
250
|
-
uninstallVisualStudio,
|
|
251
209
|
urlPolicyDenialReason,
|
|
252
210
|
visionTokensSavedByText,
|
|
211
|
+
walkProject,
|
|
212
|
+
writeCompact
|
|
213
|
+
} from "./token-goat-chunk-DPHJU3P7.mjs";
|
|
214
|
+
import {
|
|
215
|
+
CompressedOutput,
|
|
216
|
+
TOOL_FILTERS,
|
|
217
|
+
ToolFilter,
|
|
218
|
+
deliverCompressed,
|
|
219
|
+
detectFromCommand
|
|
220
|
+
} from "./token-goat-chunk-PAVWB4L4.mjs";
|
|
221
|
+
import {
|
|
222
|
+
HOOKS_SCRIPT_FILE,
|
|
223
|
+
MATERIALIZE_SHRUNK_IMAGE_JS,
|
|
224
|
+
buildGuidanceBlock,
|
|
225
|
+
buildGuidanceBody,
|
|
226
|
+
bundledCliPath,
|
|
227
|
+
copilotCliConfigPath,
|
|
228
|
+
copilotCliMcpToolsDir,
|
|
229
|
+
copilotCliScriptPath,
|
|
230
|
+
copilotHooksFilePaths,
|
|
231
|
+
dropEmptyServers,
|
|
232
|
+
hasManagedServer,
|
|
233
|
+
installCopilotCli,
|
|
234
|
+
installCopilotHooksFile,
|
|
235
|
+
installVisualStudio,
|
|
236
|
+
isCopilotCliInstalled,
|
|
237
|
+
isManagedServer,
|
|
238
|
+
isResidueServersJson,
|
|
239
|
+
isVisualStudioInstalled,
|
|
240
|
+
jsonc,
|
|
241
|
+
managedServer,
|
|
242
|
+
readCopilotHooksOwners,
|
|
243
|
+
readServersJson,
|
|
244
|
+
releaseCopilotHooksFile,
|
|
245
|
+
serversOf,
|
|
246
|
+
setTokenGoatServer,
|
|
247
|
+
skillDescriptionLine,
|
|
248
|
+
syncVisualStudioProjectGuidance,
|
|
249
|
+
uninstallCopilotCli,
|
|
250
|
+
uninstallVisualStudio,
|
|
253
251
|
visualStudioDuplicateNote,
|
|
254
252
|
visualStudioManagedEntry,
|
|
255
253
|
visualStudioMcpStatus,
|
|
256
254
|
visualStudioOtherScopeHasManagedServer,
|
|
257
255
|
visualStudioProjectMcpPath,
|
|
258
256
|
visualStudioSolutionVscodeMcpPath,
|
|
259
|
-
visualStudioUserMcpPath
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
257
|
+
visualStudioUserMcpPath
|
|
258
|
+
} from "./token-goat-chunk-SP5QR2HN.mjs";
|
|
259
|
+
import {
|
|
260
|
+
AGENT_SALT_MARKER,
|
|
261
|
+
CONTEXT_AUTOCOMPACT_TOKENS,
|
|
262
|
+
SESSIONS_SUBDIR,
|
|
263
|
+
SKILLS_OUTPUT_SUBDIR,
|
|
264
|
+
contentHash,
|
|
265
|
+
eventCount,
|
|
266
|
+
extractCompactFromMarker,
|
|
267
|
+
extractNamedSection,
|
|
268
|
+
findLatestSessionId,
|
|
269
|
+
formatAge,
|
|
270
|
+
getContextPressure,
|
|
271
|
+
getSessionFiles,
|
|
272
|
+
getSessionId,
|
|
273
|
+
getSkillFilePath,
|
|
274
|
+
incrementSkillHit,
|
|
275
|
+
listOutputs,
|
|
276
|
+
listSkills,
|
|
277
|
+
loadSessionCache,
|
|
278
|
+
loadSessionState,
|
|
279
|
+
pruneSkillOutputs,
|
|
280
|
+
sessionsDir,
|
|
281
|
+
skillOutputsDir,
|
|
282
|
+
storeCompact,
|
|
283
|
+
storeOutput
|
|
284
|
+
} from "./token-goat-chunk-KT75DZK4.mjs";
|
|
285
|
+
import {
|
|
286
|
+
capJsonRows,
|
|
287
|
+
claudeConfigDir,
|
|
288
|
+
estimateTokens,
|
|
289
|
+
estimateTokensFromLength,
|
|
290
|
+
formatBytes,
|
|
291
|
+
formatTokenEstimate,
|
|
292
|
+
trimToBudget
|
|
293
|
+
} from "./token-goat-chunk-ZHFM4DHJ.mjs";
|
|
263
294
|
import {
|
|
264
295
|
BASH_OUTPUT_SUBDIR,
|
|
265
|
-
CompressedOutput,
|
|
266
|
-
FILTERS,
|
|
267
|
-
TOOL_FILTERS,
|
|
268
|
-
ToolFilter,
|
|
269
296
|
clipLongMatchLine,
|
|
270
297
|
combineStreams,
|
|
271
|
-
deliverCompressed,
|
|
272
|
-
detectFromCommand,
|
|
273
298
|
getBashOutput,
|
|
274
299
|
isRecallCacheType
|
|
275
|
-
} from "./token-goat-chunk-
|
|
300
|
+
} from "./token-goat-chunk-SL454EN5.mjs";
|
|
276
301
|
import {
|
|
277
302
|
C,
|
|
278
303
|
DEFAULT_MAX_AGE_MS,
|
|
@@ -286,7 +311,6 @@ import {
|
|
|
286
311
|
formatLocalTimestamp,
|
|
287
312
|
getGlobalDb,
|
|
288
313
|
listBlobs,
|
|
289
|
-
loadBlob,
|
|
290
314
|
pruneBlobs,
|
|
291
315
|
pruneStalePatternCoveredUnmappedTools,
|
|
292
316
|
readUnmappedTools,
|
|
@@ -297,21 +321,21 @@ import {
|
|
|
297
321
|
savedTokensFromBytes,
|
|
298
322
|
statsHasDurationColumn,
|
|
299
323
|
statsHasHarnessColumn,
|
|
300
|
-
|
|
324
|
+
stripAnsiEscapes,
|
|
301
325
|
summarize
|
|
302
|
-
} from "./token-goat-chunk-
|
|
326
|
+
} from "./token-goat-chunk-K5XPIUVB.mjs";
|
|
303
327
|
import {
|
|
304
328
|
docxOutline,
|
|
305
329
|
docxTables,
|
|
306
330
|
docxText,
|
|
307
331
|
formatDocxTables
|
|
308
|
-
} from "./token-goat-chunk-
|
|
332
|
+
} from "./token-goat-chunk-PTW22MRC.mjs";
|
|
309
333
|
import {
|
|
310
334
|
pptxNotesText,
|
|
311
335
|
pptxOutline,
|
|
312
336
|
pptxSlideText,
|
|
313
337
|
pptxTextGrep
|
|
314
|
-
} from "./token-goat-chunk-
|
|
338
|
+
} from "./token-goat-chunk-DNAF26L4.mjs";
|
|
315
339
|
import {
|
|
316
340
|
formatXlsxColumns,
|
|
317
341
|
formatXlsxRange,
|
|
@@ -320,12 +344,13 @@ import {
|
|
|
320
344
|
querySheet,
|
|
321
345
|
rangeSheet,
|
|
322
346
|
xlsxColumns
|
|
323
|
-
} from "./token-goat-chunk-
|
|
347
|
+
} from "./token-goat-chunk-ODF7H7WS.mjs";
|
|
324
348
|
import {
|
|
325
349
|
formatCsvTable,
|
|
326
350
|
parseWhereSpecs
|
|
327
|
-
} from "./token-goat-chunk-
|
|
351
|
+
} from "./token-goat-chunk-P4XBHZXU.mjs";
|
|
328
352
|
import {
|
|
353
|
+
assetEmbedSha,
|
|
329
354
|
deleteFileEmbeddings,
|
|
330
355
|
embeddingBackendLoadError,
|
|
331
356
|
embeddingsDepsAvailable,
|
|
@@ -342,18 +367,19 @@ import {
|
|
|
342
367
|
isTreeSitterAvailable,
|
|
343
368
|
listSections,
|
|
344
369
|
loadRegexExtractors,
|
|
370
|
+
maxChunksEmbedSha,
|
|
345
371
|
missingTreeSitterGrammarPackages,
|
|
346
372
|
modelFilesPresent,
|
|
347
373
|
parserFingerprintForLanguage,
|
|
348
374
|
readSection,
|
|
349
375
|
treeSitterCoreAvailable,
|
|
350
376
|
treeSitterCoreLoadError
|
|
351
|
-
} from "./token-goat-chunk-
|
|
377
|
+
} from "./token-goat-chunk-ERGHDBC6.mjs";
|
|
352
378
|
import {
|
|
353
379
|
getFileEntry,
|
|
354
380
|
getProjectFileEntries,
|
|
355
381
|
querySymbols
|
|
356
|
-
} from "./token-goat-chunk-
|
|
382
|
+
} from "./token-goat-chunk-K3ZNBN4U.mjs";
|
|
357
383
|
import {
|
|
358
384
|
TREE_SITTER_LANGUAGES,
|
|
359
385
|
detectLanguage,
|
|
@@ -364,7 +390,7 @@ import {
|
|
|
364
390
|
matchGroovySlashy,
|
|
365
391
|
nonTreeSitterLanguageCount,
|
|
366
392
|
redactIfDotenv
|
|
367
|
-
} from "./token-goat-chunk-
|
|
393
|
+
} from "./token-goat-chunk-T63VHOL3.mjs";
|
|
368
394
|
import {
|
|
369
395
|
CONFIG_KEY_ENV_OVERRIDES,
|
|
370
396
|
PROJECT_LOCKED_KEYS,
|
|
@@ -393,7 +419,7 @@ import {
|
|
|
393
419
|
stringify,
|
|
394
420
|
validateEnumField,
|
|
395
421
|
validateNumericField
|
|
396
|
-
} from "./token-goat-chunk-
|
|
422
|
+
} from "./token-goat-chunk-74ADIZZX.mjs";
|
|
397
423
|
import {
|
|
398
424
|
ENV_KEYS,
|
|
399
425
|
LOCK_WAIT_MS_HARDENED,
|
|
@@ -438,7 +464,6 @@ import {
|
|
|
438
464
|
requirePositiveStrictInt,
|
|
439
465
|
resolveOnPath,
|
|
440
466
|
runGit,
|
|
441
|
-
safeSlice,
|
|
442
467
|
sleepSync,
|
|
443
468
|
stripDelimitedBlock,
|
|
444
469
|
stripLower,
|
|
@@ -455,7 +480,7 @@ import {
|
|
|
455
480
|
withRetryOnLock,
|
|
456
481
|
writeIfDifferent,
|
|
457
482
|
writeJsonSettings
|
|
458
|
-
} from "./token-goat-chunk-
|
|
483
|
+
} from "./token-goat-chunk-6LJNM4ZZ.mjs";
|
|
459
484
|
import {
|
|
460
485
|
UNTRUSTED_FILE_TAG,
|
|
461
486
|
UNTRUSTED_TOOL_TAG,
|
|
@@ -3603,9 +3628,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3603
3628
|
* @param {string} [path]
|
|
3604
3629
|
* @return {(string|null|Command)}
|
|
3605
3630
|
*/
|
|
3606
|
-
executableDir(
|
|
3607
|
-
if (
|
|
3608
|
-
this._executableDir =
|
|
3631
|
+
executableDir(path42) {
|
|
3632
|
+
if (path42 === void 0) return this._executableDir;
|
|
3633
|
+
this._executableDir = path42;
|
|
3609
3634
|
return this;
|
|
3610
3635
|
}
|
|
3611
3636
|
/**
|
|
@@ -3905,8 +3930,8 @@ function attemptedCommandName(argv) {
|
|
|
3905
3930
|
}
|
|
3906
3931
|
|
|
3907
3932
|
// src/cli.ts
|
|
3908
|
-
import * as
|
|
3909
|
-
import * as
|
|
3933
|
+
import * as fs45 from "fs";
|
|
3934
|
+
import * as path41 from "path";
|
|
3910
3935
|
|
|
3911
3936
|
// src/walk_index.ts
|
|
3912
3937
|
init_define_import_meta_env();
|
|
@@ -4177,6 +4202,12 @@ main().catch(() => {
|
|
|
4177
4202
|
})
|
|
4178
4203
|
`;
|
|
4179
4204
|
|
|
4205
|
+
// src/canonical_skill.ts
|
|
4206
|
+
init_define_import_meta_env();
|
|
4207
|
+
import { gunzipSync } from "node:zlib";
|
|
4208
|
+
var CANONICAL_SKILL_GZIP_BASE64 = "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";
|
|
4209
|
+
var CANONICAL_SKILL_MD = gunzipSync(Buffer.from(CANONICAL_SKILL_GZIP_BASE64, "base64")).toString("utf8");
|
|
4210
|
+
|
|
4180
4211
|
// src/install.ts
|
|
4181
4212
|
var HOOK_EVENT_MAP = [
|
|
4182
4213
|
["PreToolUse", "pre_tool_use"],
|
|
@@ -4476,23 +4507,8 @@ function findStrayClaudeMdBlocks(searchRoot) {
|
|
|
4476
4507
|
walk(root, 0);
|
|
4477
4508
|
return found.sort();
|
|
4478
4509
|
}
|
|
4479
|
-
function skillMdFrontmatter(gdrive) {
|
|
4480
|
-
return `---
|
|
4481
|
-
name: token-goat
|
|
4482
|
-
${skillDescriptionLine(gdrive)}
|
|
4483
|
-
allowed-tools:
|
|
4484
|
-
- Bash
|
|
4485
|
-
- Read
|
|
4486
|
-
- Grep
|
|
4487
|
-
- Glob
|
|
4488
|
-
---`;
|
|
4489
|
-
}
|
|
4490
4510
|
function skillMdContent() {
|
|
4491
|
-
|
|
4492
|
-
return `${skillMdFrontmatter(gdrive)}
|
|
4493
|
-
|
|
4494
|
-
${buildGuidanceBody("Claude Code's own Read, Grep, and Glob preference rules", { gdrive })}
|
|
4495
|
-
`;
|
|
4511
|
+
return CANONICAL_SKILL_MD;
|
|
4496
4512
|
}
|
|
4497
4513
|
function skillDir() {
|
|
4498
4514
|
return path3.join(claudeConfigDir(), "skills", "token-goat");
|
|
@@ -4539,6 +4555,9 @@ ${SHIM_REQUIRES}
|
|
|
4539
4555
|
|
|
4540
4556
|
${SHIM_VALID_HOOK_EVENTS}
|
|
4541
4557
|
|
|
4558
|
+
// Codex sets no env var of its own identifying a hook subprocess; see this module's docblock.
|
|
4559
|
+
process.env.TOKEN_GOAT_HARNESS_OVERRIDE = 'codex'
|
|
4560
|
+
|
|
4542
4561
|
// Keep in sync with CLAUDE_CODE_EVENT_NAMES in src/hook_registry.ts -- the
|
|
4543
4562
|
// live/wired 'token-goat hook <event>' path (src/relay.ts) always emits this
|
|
4544
4563
|
// PascalCase spelling for hookSpecificOutput.hookEventName, never the raw
|
|
@@ -4667,7 +4686,7 @@ function groupHasTokenGoat2(groups, matcher, predicate) {
|
|
|
4667
4686
|
|
|
4668
4687
|
// src/bridges/codex_install.ts
|
|
4669
4688
|
var CODEX_COMMAND_MARKER = "token-goat-shim";
|
|
4670
|
-
var CODEX_MATCHERS = ["view_image|shell|bash", "apply_patch", "web_search"];
|
|
4689
|
+
var CODEX_MATCHERS = ["view_image|Bash|exec|shell|bash", "apply_patch", "web_search"];
|
|
4671
4690
|
var CODEX_HOOK_EVENTS = ["PreToolUse", "PostToolUse"];
|
|
4672
4691
|
var CODEX_EVENT_ARG = {
|
|
4673
4692
|
PreToolUse: "pre_tool_use",
|
|
@@ -4950,7 +4969,7 @@ function buildAgentsBlock() {
|
|
|
4950
4969
|
return buildGuidanceBlock({
|
|
4951
4970
|
beginMarker: AGENTS_BEGIN,
|
|
4952
4971
|
endMarker: AGENTS_END,
|
|
4953
|
-
fallbackToolClause: "Codex's native `
|
|
4972
|
+
fallbackToolClause: "Codex's native `exec`, `apply_patch`, and `view_image` tools (shell commands like `cat`/`type` run inside `exec`)",
|
|
4954
4973
|
gdrive: loadConfig().gdrive.enabled
|
|
4955
4974
|
});
|
|
4956
4975
|
}
|
|
@@ -5142,10 +5161,10 @@ function readQwenSettings(p, opts = {}) {
|
|
|
5142
5161
|
let parsed;
|
|
5143
5162
|
try {
|
|
5144
5163
|
parsed = JSON.parse(raw);
|
|
5145
|
-
} catch {
|
|
5164
|
+
} catch (e) {
|
|
5146
5165
|
if (opts.strict === true) {
|
|
5147
5166
|
throw new QwenSettingsParseError(
|
|
5148
|
-
`Qwen Code settings file '${p}' exists but contains invalid JSON. Fix or back up the file before running install
|
|
5167
|
+
`Qwen Code settings file '${p}' exists but contains invalid JSON. Fix or back up the file before running install. (${extractErrorMessage(e)})`
|
|
5149
5168
|
);
|
|
5150
5169
|
}
|
|
5151
5170
|
return {};
|
|
@@ -7155,8 +7174,8 @@ import * as path15 from "node:path";
|
|
|
7155
7174
|
var INTERPRETER_BASENAMES = /* @__PURE__ */ new Set(["node.exe", "python.exe", "python3.exe", "pwsh.exe", "powershell.exe", "cmd.exe"]);
|
|
7156
7175
|
function describeProcess(commandLine) {
|
|
7157
7176
|
for (const m of commandLine.matchAll(/[^\s"]+\.(?:js|mjs|cjs|ts|py|exe)\b/gi)) {
|
|
7158
|
-
const
|
|
7159
|
-
if (!INTERPRETER_BASENAMES.has(
|
|
7177
|
+
const basename10 = m[0].replace(/\\/g, "/").split("/").pop() ?? m[0];
|
|
7178
|
+
if (!INTERPRETER_BASENAMES.has(basename10.toLowerCase())) return basename10;
|
|
7160
7179
|
}
|
|
7161
7180
|
const trimmed = commandLine.trim();
|
|
7162
7181
|
return trimmed.length > 0 ? trimmed.length > 60 ? trimmed.slice(0, 60) + "\u2026" : trimmed : "(no command line)";
|
|
@@ -7542,7 +7561,7 @@ function checkSecurityPosture(cfg, dataDirPath) {
|
|
|
7542
7561
|
}
|
|
7543
7562
|
|
|
7544
7563
|
// src/cli_doctor.ts
|
|
7545
|
-
var DB_SIZE_WARN_BYTES =
|
|
7564
|
+
var DB_SIZE_WARN_BYTES = 1500 * 1024 * 1024;
|
|
7546
7565
|
function freelistBytes(header) {
|
|
7547
7566
|
if (header.length < 40) return 0;
|
|
7548
7567
|
const rawPageSize = header.readUInt16BE(16);
|
|
@@ -7578,12 +7597,15 @@ function dbCategoryBreakdown(dbPath) {
|
|
|
7578
7597
|
}
|
|
7579
7598
|
return shares.sort((a, b) => b.bytes - a.bytes);
|
|
7580
7599
|
}
|
|
7581
|
-
function oversizeDbMessage(dbPath, sizeBytes, freeBytes, tempRows, categories = [], topConsumers = []) {
|
|
7600
|
+
function oversizeDbMessage(dbPath, sizeBytes, freeBytes, tempRows, categories = [], topConsumers = [], thresholdMb = 1500, autoReclaimEmbeddings = false) {
|
|
7582
7601
|
const mb = (bytes) => Math.round(bytes / (1024 * 1024));
|
|
7583
7602
|
const advice = [];
|
|
7584
7603
|
if (freeBytes >= sizeBytes / 10) advice.push(`'token-goat reclaim-index' returns the ${mb(freeBytes)} MB of it that is free pages`);
|
|
7585
7604
|
if (tempRows > 0) advice.push(`'token-goat project prune' removes ${countNoun(tempRows, "scratch file")} indexed under the OS temp dir`);
|
|
7586
|
-
|
|
7605
|
+
if (autoReclaimEmbeddings) {
|
|
7606
|
+
advice.push(`'token-goat doctor --repair' will automatically reclaim embedding vectors and compact global.db`);
|
|
7607
|
+
}
|
|
7608
|
+
const head = `global.db is ${mb(sizeBytes)} MB at ${displaySafeText(dbPath)} (larger than threshold of ${thresholdMb} MB). `;
|
|
7587
7609
|
const totalCategoryBytes = categories.reduce((sum, c) => sum + c.bytes, 0);
|
|
7588
7610
|
const breakdown = totalCategoryBytes > 0 ? ` Where it went: ${categories.slice(0, 3).map((c) => `${c.name} ${mb(c.bytes)} MB (${Math.round(c.bytes / totalCategoryBytes * 100)}%) -- ${c.command}`).join("; ")}.` : "";
|
|
7589
7611
|
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}`;
|
|
@@ -7593,7 +7615,7 @@ function oversizeDbMessage(dbPath, sizeBytes, freeBytes, tempRows, categories =
|
|
|
7593
7615
|
}
|
|
7594
7616
|
return base;
|
|
7595
7617
|
}
|
|
7596
|
-
function checkDbExists(dataDir2) {
|
|
7618
|
+
function checkDbExists(dataDir2, maxDbSizeMb) {
|
|
7597
7619
|
const dbPath = path17.join(dataDir2, "global.db");
|
|
7598
7620
|
if (!fs18.existsSync(dbPath)) {
|
|
7599
7621
|
return {
|
|
@@ -7602,7 +7624,7 @@ function checkDbExists(dataDir2) {
|
|
|
7602
7624
|
message: `global.db not found at ${dbPath}`
|
|
7603
7625
|
};
|
|
7604
7626
|
}
|
|
7605
|
-
const sizeBytes =
|
|
7627
|
+
const sizeBytes = indexSizeBytes(dbPath);
|
|
7606
7628
|
const SQLITE_HEADER = "SQLite format 3\0";
|
|
7607
7629
|
let header = "";
|
|
7608
7630
|
let headerBytes = Buffer.alloc(0);
|
|
@@ -7625,7 +7647,10 @@ function checkDbExists(dataDir2) {
|
|
|
7625
7647
|
message: `global.db at ${dbPath} is not a valid SQLite file (${sizeBytes} bytes) \u2014 likely truncated or corrupt`
|
|
7626
7648
|
};
|
|
7627
7649
|
}
|
|
7628
|
-
|
|
7650
|
+
const cfg = loadConfig();
|
|
7651
|
+
const thresholdMb = maxDbSizeMb ?? cfg.indexing.max_db_size_mb ?? 1500;
|
|
7652
|
+
const warnBytes = thresholdMb * 1024 * 1024;
|
|
7653
|
+
if (sizeBytes > warnBytes) {
|
|
7629
7654
|
let tempRows = 0;
|
|
7630
7655
|
try {
|
|
7631
7656
|
tempRows = findSystemTempFiles(dbPath).length;
|
|
@@ -7637,7 +7662,20 @@ function checkDbExists(dataDir2) {
|
|
|
7637
7662
|
} catch {
|
|
7638
7663
|
}
|
|
7639
7664
|
const topConsumers = findTopIndexedProjects(dbPath, 3);
|
|
7640
|
-
return {
|
|
7665
|
+
return {
|
|
7666
|
+
name: "Database",
|
|
7667
|
+
status: "warn",
|
|
7668
|
+
message: oversizeDbMessage(
|
|
7669
|
+
dbPath,
|
|
7670
|
+
sizeBytes,
|
|
7671
|
+
freelistBytes(headerBytes),
|
|
7672
|
+
tempRows,
|
|
7673
|
+
categories,
|
|
7674
|
+
topConsumers,
|
|
7675
|
+
thresholdMb,
|
|
7676
|
+
cfg.indexing.auto_reclaim_embeddings
|
|
7677
|
+
)
|
|
7678
|
+
};
|
|
7641
7679
|
}
|
|
7642
7680
|
return {
|
|
7643
7681
|
name: "Database",
|
|
@@ -8163,7 +8201,8 @@ function runDoctor(dataDir2, configPath2, rootDir, processes) {
|
|
|
8163
8201
|
results.push(checkTreeSitter());
|
|
8164
8202
|
results.push(checkStrayClaudeMdBlocks());
|
|
8165
8203
|
results.push(checkWorkerRunning(actualDataDir) ? { name: "Worker", status: "ok", message: "running" } : { name: "Worker", status: "warn", message: "not running" });
|
|
8166
|
-
|
|
8204
|
+
const cfg = loadConfig(rootDir);
|
|
8205
|
+
results.push(checkDbExists(actualDataDir, cfg.indexing.max_db_size_mb));
|
|
8167
8206
|
results.push(checkSymbolBodySize(path17.join(actualDataDir, "global.db")));
|
|
8168
8207
|
results.push(checkSymbolCount(path17.join(actualDataDir, "global.db"), rootDir));
|
|
8169
8208
|
results.push(checkDirtyQueueHealth(actualDataDir));
|
|
@@ -8255,6 +8294,22 @@ async function runDoctorRepair(opts) {
|
|
|
8255
8294
|
} catch (e) {
|
|
8256
8295
|
errors.push(`Failed to clean up ${displaySafeText(projectMcp)}: ${extractErrorMessage(e)}`);
|
|
8257
8296
|
}
|
|
8297
|
+
const actualDataDir = opts?.dataDir ?? dataDir();
|
|
8298
|
+
const dbPath = path17.join(actualDataDir, "global.db");
|
|
8299
|
+
if (cfg.indexing.auto_reclaim_embeddings && fs18.existsSync(dbPath)) {
|
|
8300
|
+
try {
|
|
8301
|
+
const sizeBytes = indexSizeBytes(dbPath);
|
|
8302
|
+
const thresholdMb = cfg.indexing.max_db_size_mb ?? 1500;
|
|
8303
|
+
const maxBytes = thresholdMb * 1024 * 1024;
|
|
8304
|
+
if (sizeBytes > maxBytes) {
|
|
8305
|
+
const res = reclaimIndex(dbPath, { embeddingsOnly: true });
|
|
8306
|
+
const savedMb = Math.round((res.beforeBytes - res.afterBytes) / (1024 * 1024));
|
|
8307
|
+
repairs.push(`Auto-reclaimed embeddings and compacted global.db (${savedMb > 0 ? `reclaimed ${savedMb} MB` : "compacted"})`);
|
|
8308
|
+
}
|
|
8309
|
+
} catch (e) {
|
|
8310
|
+
errors.push(`Failed to auto-reclaim embeddings from global.db: ${extractErrorMessage(e)}`);
|
|
8311
|
+
}
|
|
8312
|
+
}
|
|
8258
8313
|
return { repairs, errors };
|
|
8259
8314
|
}
|
|
8260
8315
|
function printDoctorResults(results) {
|
|
@@ -8416,7 +8471,7 @@ async function runDoctorAndExit(opts) {
|
|
|
8416
8471
|
}
|
|
8417
8472
|
}
|
|
8418
8473
|
try {
|
|
8419
|
-
const { checkUpdateStatus } = await import("./token-goat-chunk-
|
|
8474
|
+
const { checkUpdateStatus } = await import("./token-goat-chunk-AU2K2QHR.mjs");
|
|
8420
8475
|
const update = await checkUpdateStatus(1500);
|
|
8421
8476
|
if (update.updateAvailable && update.latest) {
|
|
8422
8477
|
console.log(`
|
|
@@ -8851,13 +8906,6 @@ function performHttpFetch(targetUrl, opts) {
|
|
|
8851
8906
|
}
|
|
8852
8907
|
|
|
8853
8908
|
// src/config_commands.ts
|
|
8854
|
-
function emit(text) {
|
|
8855
|
-
const payload = colorStdout() ? text : stripAnsi(text);
|
|
8856
|
-
process.stdout.write(ensureNewline(payload));
|
|
8857
|
-
}
|
|
8858
|
-
function emitErr(text) {
|
|
8859
|
-
process.stderr.write(ensureNewline(text));
|
|
8860
|
-
}
|
|
8861
8909
|
function saveConfigSafe(cfg) {
|
|
8862
8910
|
ensureDirSync(path18.dirname(configPath()));
|
|
8863
8911
|
saveConfig(cfg);
|
|
@@ -9307,13 +9355,15 @@ function cmdProject(opts) {
|
|
|
9307
9355
|
invalidateConfigCache();
|
|
9308
9356
|
const prunedTempFiles = pruneSystemTempFiles();
|
|
9309
9357
|
const prunedOrphanChunks = pruneOrphanedChunks();
|
|
9358
|
+
const prunedOrphanVectors = pruneOrphanedVectors();
|
|
9310
9359
|
if (opts.json === true) {
|
|
9311
|
-
emit(displaySafeJson({ pruned: removed, blocked_roots: after, prunedTempFiles: prunedTempFiles.length, prunedOrphanChunkFiles: prunedOrphanChunks.length }));
|
|
9360
|
+
emit(displaySafeJson({ pruned: removed, blocked_roots: after, prunedTempFiles: prunedTempFiles.length, prunedOrphanChunkFiles: prunedOrphanChunks.length, prunedOrphanVectors }));
|
|
9312
9361
|
return;
|
|
9313
9362
|
}
|
|
9314
9363
|
emit(`Pruned ${removed} stale root(s). Remaining: ${after.length}`);
|
|
9315
9364
|
emit(`Pruned ${prunedTempFiles.length} stale indexed temp-dir file(s).`);
|
|
9316
9365
|
emit(`Pruned orphaned embedding chunks for ${prunedOrphanChunks.length} file(s).`);
|
|
9366
|
+
emit(`Pruned ${prunedOrphanVectors} orphaned embedding vector(s).`);
|
|
9317
9367
|
return;
|
|
9318
9368
|
}
|
|
9319
9369
|
emitErr(`project: unknown action '${action}'. Use list, exclude, or prune.`);
|
|
@@ -12211,7 +12261,7 @@ function extractGeneric(lines) {
|
|
|
12211
12261
|
return result;
|
|
12212
12262
|
}
|
|
12213
12263
|
function extractFailures(text, options) {
|
|
12214
|
-
const cleaned =
|
|
12264
|
+
const cleaned = stripAnsiEscapes(text);
|
|
12215
12265
|
const lines = cleaned.split("\n");
|
|
12216
12266
|
const detected = options?.runner ?? detectRunner(cleaned);
|
|
12217
12267
|
if (detected === "pytest") {
|
|
@@ -12386,7 +12436,8 @@ function cmdConflicts(targetPath, opts) {
|
|
|
12386
12436
|
process.exitCode = runConflicts({
|
|
12387
12437
|
...targetPath !== void 0 ? { path: targetPath } : {},
|
|
12388
12438
|
...opts.json === true ? { json: true } : {},
|
|
12389
|
-
...opts.summary === true ? { summary: true } : {}
|
|
12439
|
+
...opts.summary === true ? { summary: true } : {},
|
|
12440
|
+
...opts.context !== void 0 ? { context: parseInt(opts.context, 10) } : {}
|
|
12390
12441
|
});
|
|
12391
12442
|
}
|
|
12392
12443
|
async function cmdScreenshot(url, destPath, opts) {
|
|
@@ -12434,7 +12485,7 @@ function cmdPack(patterns, opts) {
|
|
|
12434
12485
|
}
|
|
12435
12486
|
const result = expandedList.length > 0 ? collectFiles(root, expandedList, collectOpts) : collectFromStdin(root, collectOpts);
|
|
12436
12487
|
if (opts.budget !== void 0) {
|
|
12437
|
-
const budgetN =
|
|
12488
|
+
const budgetN = requireInt("--budget", opts.budget);
|
|
12438
12489
|
if (result.total_tokens > budgetN) {
|
|
12439
12490
|
err(`token-goat: pack: token count ${result.total_tokens} exceeds budget ${budgetN}`);
|
|
12440
12491
|
process.exitCode = 3;
|
|
@@ -12471,7 +12522,7 @@ function cmdTokens(patterns, opts) {
|
|
|
12471
12522
|
let entries = [...result.entries];
|
|
12472
12523
|
if (opts.asc === true) entries.reverse();
|
|
12473
12524
|
const eligibleCount = entries.length;
|
|
12474
|
-
if (opts.top !== void 0) entries = entries.slice(0,
|
|
12525
|
+
if (opts.top !== void 0) entries = entries.slice(0, requireNonNegativeInt("--top", opts.top));
|
|
12475
12526
|
const truncated = entries.length < eligibleCount;
|
|
12476
12527
|
if (opts.json === true) {
|
|
12477
12528
|
out(displaySafeJson({ entries, truncated, totalCount: eligibleCount, total_tokens: result.total_tokens, total_lines: result.total_lines }));
|
|
@@ -12519,7 +12570,7 @@ function cmdBudget(patterns, opts) {
|
|
|
12519
12570
|
if (opts.json === true) {
|
|
12520
12571
|
out(displaySafeJson(result));
|
|
12521
12572
|
} else {
|
|
12522
|
-
const contextK = opts.context !== void 0 ?
|
|
12573
|
+
const contextK = opts.context !== void 0 ? requirePositiveInt("--context", opts.context) : Math.round(loadConfig().context.model_window_tokens / 1e3);
|
|
12523
12574
|
out(formatBudgetText(result, contextK));
|
|
12524
12575
|
}
|
|
12525
12576
|
}
|
|
@@ -12866,8 +12917,8 @@ async function cmdPdfLocate(file, pattern, opts) {
|
|
|
12866
12917
|
const locateOpts = {
|
|
12867
12918
|
ignoreCase: opts.ignoreCase === true
|
|
12868
12919
|
};
|
|
12869
|
-
if (opts.maxMatches !== void 0) locateOpts.maxMatches =
|
|
12870
|
-
if (opts.context !== void 0) locateOpts.context =
|
|
12920
|
+
if (opts.maxMatches !== void 0) locateOpts.maxMatches = requirePositiveInt("--max-matches", opts.maxMatches);
|
|
12921
|
+
if (opts.context !== void 0) locateOpts.context = requirePositiveInt("--context", opts.context);
|
|
12871
12922
|
if (opts.pages !== void 0) locateOpts.pages = opts.pages;
|
|
12872
12923
|
const { matches: matches2, truncated } = await runPdfLocate(file, pattern, locateOpts);
|
|
12873
12924
|
const pages = matches2.map((m) => m.page);
|
|
@@ -12977,14 +13028,14 @@ async function cmdXlsxSheets(file, opts = {}) {
|
|
|
12977
13028
|
recordXlsxStat("xlsx_sheets", file, text);
|
|
12978
13029
|
}
|
|
12979
13030
|
async function cmdXlsxHead(file, opts) {
|
|
12980
|
-
const rows = opts.rows !== void 0 ?
|
|
13031
|
+
const rows = opts.rows !== void 0 ? requireNonNegativeInt("--rows", opts.rows) : 20;
|
|
12981
13032
|
const columns = opts.columns ? opts.columns.split(",").map((c) => c.trim()).filter(Boolean) : void 0;
|
|
12982
13033
|
const text = fenceFileText(await headSheet(file, opts.sheet, rows, columns));
|
|
12983
13034
|
out(text);
|
|
12984
13035
|
recordXlsxStat("xlsx_head", file, text);
|
|
12985
13036
|
}
|
|
12986
13037
|
async function cmdXlsxColumns(file, opts = {}) {
|
|
12987
|
-
const maxRows = opts.head !== void 0 ?
|
|
13038
|
+
const maxRows = opts.head !== void 0 ? requireNonNegativeInt("--head", opts.head) : 100;
|
|
12988
13039
|
const result = await xlsxColumns(file, opts.sheet, maxRows);
|
|
12989
13040
|
if (opts.json === true) {
|
|
12990
13041
|
const text = displaySafeJson({
|
|
@@ -13012,7 +13063,7 @@ async function cmdXlsxQuery(file, opts) {
|
|
|
13012
13063
|
const result = await querySheet(file, opts.sheet, {
|
|
13013
13064
|
...columns !== void 0 ? { columns } : {},
|
|
13014
13065
|
...wheres !== void 0 ? { wheres } : {},
|
|
13015
|
-
...opts.head !== void 0 ? { head:
|
|
13066
|
+
...opts.head !== void 0 ? { head: requireNonNegativeInt("--head", opts.head) } : {}
|
|
13016
13067
|
});
|
|
13017
13068
|
if (opts.json === true) {
|
|
13018
13069
|
const rowsJson = result.rows.map((r) => Object.fromEntries(result.header.map((h, i) => [h, fenceFileFieldIfMatched(r[i] ?? "")])));
|
|
@@ -13044,13 +13095,13 @@ async function cmdPptxOutline(file, opts) {
|
|
|
13044
13095
|
recordDocStat("pptx_outline", file, text);
|
|
13045
13096
|
}
|
|
13046
13097
|
async function cmdPptxSlide(file, opts) {
|
|
13047
|
-
const n =
|
|
13098
|
+
const n = requireNonNegativeInt("--slide", opts.slide);
|
|
13048
13099
|
const text = fenceFileText(await pptxSlideText(file, n, opts.notes === true));
|
|
13049
13100
|
out(text);
|
|
13050
13101
|
recordDocStat("pptx_slide", file, text);
|
|
13051
13102
|
}
|
|
13052
13103
|
async function cmdPptxNotes(file, opts) {
|
|
13053
|
-
const n = opts.slide !== void 0 ?
|
|
13104
|
+
const n = opts.slide !== void 0 ? requireNonNegativeInt("--slide", opts.slide) : void 0;
|
|
13054
13105
|
const text = await pptxNotesText(file, n);
|
|
13055
13106
|
const printed = text.length > 0 ? fenceFileText(text) : "no speaker notes found";
|
|
13056
13107
|
out(printed);
|
|
@@ -13179,7 +13230,7 @@ function cmdXmlOutline(file, opts) {
|
|
|
13179
13230
|
process.exitCode = runXmlOutline({
|
|
13180
13231
|
file,
|
|
13181
13232
|
...opts.json === true ? { json: true } : {},
|
|
13182
|
-
...depthStr !== void 0 ? { maxDepth:
|
|
13233
|
+
...depthStr !== void 0 ? { maxDepth: requireNonNegativeInt("--max-depth", depthStr) } : {}
|
|
13183
13234
|
});
|
|
13184
13235
|
}
|
|
13185
13236
|
function cmdXmlQuery(file, pathOrOpts, optsMaybe) {
|
|
@@ -13990,13 +14041,6 @@ init_define_import_meta_env();
|
|
|
13990
14041
|
|
|
13991
14042
|
// src/answer_router.ts
|
|
13992
14043
|
init_define_import_meta_env();
|
|
13993
|
-
function emit2(text) {
|
|
13994
|
-
const payload = colorStdout() ? text : stripAnsi(text);
|
|
13995
|
-
process.stdout.write(ensureNewline(payload));
|
|
13996
|
-
}
|
|
13997
|
-
function emitErr2(text) {
|
|
13998
|
-
process.stderr.write(ensureNewline(text));
|
|
13999
|
-
}
|
|
14000
14044
|
function refusal(why, suggestion) {
|
|
14001
14045
|
return `cannot answer deterministically: ${why}; try: ${suggestion}`;
|
|
14002
14046
|
}
|
|
@@ -14128,11 +14172,11 @@ function subjectModeFor(intent) {
|
|
|
14128
14172
|
function runAnswer(opts) {
|
|
14129
14173
|
const question = opts.question.trim();
|
|
14130
14174
|
if (question.length === 0) {
|
|
14131
|
-
|
|
14175
|
+
emitErr(refusal("the question is empty", 'token-goat answer "who calls <symbol>"'));
|
|
14132
14176
|
return 1;
|
|
14133
14177
|
}
|
|
14134
14178
|
if (isJudgementQuestion(question)) {
|
|
14135
|
-
|
|
14179
|
+
emitErr(
|
|
14136
14180
|
refusal(
|
|
14137
14181
|
"that asks for judgement, intent, or runtime behaviour, which the index cannot answer -- it would need the code read and reasoned over",
|
|
14138
14182
|
`token-goat semantic "${question}"`
|
|
@@ -14142,7 +14186,7 @@ function runAnswer(opts) {
|
|
|
14142
14186
|
}
|
|
14143
14187
|
const cls = classify(question);
|
|
14144
14188
|
if (cls === null) {
|
|
14145
|
-
|
|
14189
|
+
emitErr(
|
|
14146
14190
|
refusal(
|
|
14147
14191
|
"no intent matched -- this router only answers where/who-calls/what-tests-cover/what-exports/what-imports/what-breaks questions about a named symbol or file",
|
|
14148
14192
|
`token-goat semantic "${question}"`
|
|
@@ -14152,7 +14196,7 @@ function runAnswer(opts) {
|
|
|
14152
14196
|
}
|
|
14153
14197
|
const resolved = resolveSubject(cls.subject, subjectModeFor(cls.intent));
|
|
14154
14198
|
if (resolved === null) {
|
|
14155
|
-
|
|
14199
|
+
emitErr(
|
|
14156
14200
|
refusal(
|
|
14157
14201
|
`'${cls.subject}' is not an indexed symbol or file`,
|
|
14158
14202
|
`token-goat semantic "${question}"`
|
|
@@ -14166,7 +14210,7 @@ function runAnswer(opts) {
|
|
|
14166
14210
|
const more = resolved.candidates.length - shown.length;
|
|
14167
14211
|
const first = shown[0] ?? "";
|
|
14168
14212
|
const next = FILE_INTENTS.has(cls.intent) ? `token-goat answer "${cls.intent === "tests" ? "tests for" : cls.intent === "imports" ? "imports of" : "exports of"} ${first}"` : `token-goat outline ${first}`;
|
|
14169
|
-
|
|
14213
|
+
emitErr(
|
|
14170
14214
|
refusal(
|
|
14171
14215
|
`'${cls.subject}' names ${resolved.candidates.length} files in this project (${shown.join(", ")}${more > 0 ? `, +${more} more` : ""})`,
|
|
14172
14216
|
next
|
|
@@ -14175,7 +14219,7 @@ function runAnswer(opts) {
|
|
|
14175
14219
|
return 1;
|
|
14176
14220
|
}
|
|
14177
14221
|
if (resolved.kind === "symbol-only") {
|
|
14178
|
-
|
|
14222
|
+
emitErr(
|
|
14179
14223
|
refusal(
|
|
14180
14224
|
`'${cls.subject}' is a symbol; exports/imports are file-level`,
|
|
14181
14225
|
`token-goat ${cls.intent} ${toDisplayPath(rootDir, resolved.file)}`
|
|
@@ -14187,19 +14231,19 @@ function runAnswer(opts) {
|
|
|
14187
14231
|
const file = resolved.kind === "symbol" ? resolved.file : resolved.path;
|
|
14188
14232
|
const display = toDisplayPath(rootDir, file);
|
|
14189
14233
|
if (cls.intent === "tests") {
|
|
14190
|
-
|
|
14234
|
+
emit(`via: token-goat test-for ${display}`);
|
|
14191
14235
|
return runTestFor({ file });
|
|
14192
14236
|
}
|
|
14193
14237
|
if (cls.intent === "exports") {
|
|
14194
|
-
|
|
14238
|
+
emit(`via: token-goat exports ${display}`);
|
|
14195
14239
|
return runExports({ file });
|
|
14196
14240
|
}
|
|
14197
|
-
|
|
14241
|
+
emit(`via: token-goat imports ${display}`);
|
|
14198
14242
|
return runImports({ file });
|
|
14199
14243
|
}
|
|
14200
14244
|
if (resolved.kind === "file") {
|
|
14201
14245
|
const display = toDisplayPath(rootDir, resolved.path);
|
|
14202
|
-
|
|
14246
|
+
emitErr(
|
|
14203
14247
|
refusal(
|
|
14204
14248
|
`'${cls.subject}' is a file, and ${cls.intent === "where" ? "where" : cls.intent} needs a symbol`,
|
|
14205
14249
|
`token-goat outline ${display}`
|
|
@@ -14208,16 +14252,16 @@ function runAnswer(opts) {
|
|
|
14208
14252
|
return 1;
|
|
14209
14253
|
}
|
|
14210
14254
|
if (cls.intent === "callers") {
|
|
14211
|
-
|
|
14255
|
+
emit(`via: token-goat callers ${displaySafeText(resolved.name)} --limit ${ANSWER_DELEGATE_LIMIT}`);
|
|
14212
14256
|
return runCallers({ symbol: resolved.name, limit: ANSWER_DELEGATE_LIMIT });
|
|
14213
14257
|
}
|
|
14214
14258
|
if (cls.intent === "impact") {
|
|
14215
|
-
|
|
14259
|
+
emit(`via: token-goat impact ${displaySafeText(resolved.name)} --top ${ANSWER_DELEGATE_LIMIT}`);
|
|
14216
14260
|
return runImpact({ symbol: resolved.name, top: ANSWER_DELEGATE_LIMIT });
|
|
14217
14261
|
}
|
|
14218
|
-
|
|
14262
|
+
emit(`via: token-goat symbol ${displaySafeText(resolved.name)} -p --exclude-vendored`);
|
|
14219
14263
|
const r = runSymbol({ name: resolved.name, projectRoot: rootDir, limit: ANSWER_DELEGATE_LIMIT, excludeVendored: true });
|
|
14220
|
-
if (r.text.length > 0)
|
|
14264
|
+
if (r.text.length > 0) emit(r.text);
|
|
14221
14265
|
return r.code;
|
|
14222
14266
|
}
|
|
14223
14267
|
|
|
@@ -14225,13 +14269,6 @@ function runAnswer(opts) {
|
|
|
14225
14269
|
init_define_import_meta_env();
|
|
14226
14270
|
import * as path25 from "node:path";
|
|
14227
14271
|
var DEFAULT_AFFECTED_DEPTH = 5;
|
|
14228
|
-
function emit3(text) {
|
|
14229
|
-
const payload = colorStdout() ? text : stripAnsi(text);
|
|
14230
|
-
process.stdout.write(ensureNewline(payload));
|
|
14231
|
-
}
|
|
14232
|
-
function emitErr3(text) {
|
|
14233
|
-
process.stderr.write(ensureNewline(text));
|
|
14234
|
-
}
|
|
14235
14272
|
function guardedFilter(filter2) {
|
|
14236
14273
|
const guarded = compileGuardedRegex(filter2);
|
|
14237
14274
|
if (!guarded.ok) throw new Error(`--filter is not usable as a regular expression: ${guarded.reason}`);
|
|
@@ -14286,43 +14323,43 @@ function computeAffected(opts) {
|
|
|
14286
14323
|
}
|
|
14287
14324
|
function runAffected(opts) {
|
|
14288
14325
|
if (opts.depth !== void 0 && opts.depth <= 0) {
|
|
14289
|
-
|
|
14326
|
+
emitErr(`--depth must be a positive number, got: ${opts.depth}`);
|
|
14290
14327
|
return 1;
|
|
14291
14328
|
}
|
|
14292
14329
|
if (opts.files.length === 0) {
|
|
14293
|
-
|
|
14330
|
+
emitErr("No changed files given. Pass paths as arguments, or pipe them in with --stdin.");
|
|
14294
14331
|
return 1;
|
|
14295
14332
|
}
|
|
14296
14333
|
if (opts.filter !== void 0) {
|
|
14297
14334
|
const guarded = compileGuardedRegex(opts.filter);
|
|
14298
14335
|
if (!guarded.ok) {
|
|
14299
|
-
|
|
14336
|
+
emitErr(`--filter is not usable as a regular expression: ${guarded.reason}`);
|
|
14300
14337
|
return 1;
|
|
14301
14338
|
}
|
|
14302
14339
|
}
|
|
14303
14340
|
const result = computeAffected(opts);
|
|
14304
14341
|
if (opts.json === true) {
|
|
14305
|
-
|
|
14342
|
+
emit(displaySafeJson(result));
|
|
14306
14343
|
return 0;
|
|
14307
14344
|
}
|
|
14308
14345
|
if (opts.quiet === true) {
|
|
14309
|
-
for (const f of result.testFiles)
|
|
14346
|
+
for (const f of result.testFiles) emit(f);
|
|
14310
14347
|
} else if (result.testFiles.length === 0) {
|
|
14311
14348
|
const traced = opts.files.length - result.unknownSeeds.length;
|
|
14312
14349
|
if (traced === 0) {
|
|
14313
|
-
|
|
14350
|
+
emit(`Nothing could be traced: ${result.unknownSeeds.length === 1 ? "the file given is not tracked" : "none of the files given are tracked"} in this project.`);
|
|
14314
14351
|
} else {
|
|
14315
|
-
|
|
14352
|
+
emit(`No test files import ${countNoun(traced, "changed file")} (within ${countNoun(result.depth, "hop")}).`);
|
|
14316
14353
|
}
|
|
14317
14354
|
} else {
|
|
14318
|
-
|
|
14319
|
-
for (const f of result.testFiles)
|
|
14355
|
+
emit(`${countNoun(result.testFiles.length, "affected test file")} (${countNoun(result.reachedCount, "file")} reached within ${countNoun(result.depth, "hop")}):`);
|
|
14356
|
+
for (const f of result.testFiles) emit(` ${f}`);
|
|
14320
14357
|
}
|
|
14321
14358
|
if (result.unknownSeeds.length > 0) {
|
|
14322
|
-
|
|
14359
|
+
emitErr(`Not tracked in this project, so nothing was traced from ${result.unknownSeeds.length === 1 ? "it" : "them"}: ${result.unknownSeeds.join(", ")}`);
|
|
14323
14360
|
}
|
|
14324
14361
|
if (result.depthLimited) {
|
|
14325
|
-
|
|
14362
|
+
emitErr(`Stopped at --depth ${result.depth} with ${countNoun(result.unexploredAtFrontier, "file")} still unexplored; more tests may be affected (raise --depth).`);
|
|
14326
14363
|
}
|
|
14327
14364
|
return 0;
|
|
14328
14365
|
}
|
|
@@ -14924,6 +14961,69 @@ function cmdTrace(src, opts) {
|
|
|
14924
14961
|
// src/text_logfold.ts
|
|
14925
14962
|
init_define_import_meta_env();
|
|
14926
14963
|
import * as fs31 from "fs";
|
|
14964
|
+
|
|
14965
|
+
// src/filters.ts
|
|
14966
|
+
init_define_import_meta_env();
|
|
14967
|
+
var DROP = () => null;
|
|
14968
|
+
var FILTERS = [
|
|
14969
|
+
{
|
|
14970
|
+
// git fetch/clone progress: "remote: Counting objects: 73% (8/11)", "Receiving objects: 100% (11/11), done.", "Resolving deltas: ...".
|
|
14971
|
+
name: "git-progress",
|
|
14972
|
+
pattern: /^(remote:\s+)?(Counting objects|Compressing objects|Receiving objects|Resolving deltas|Unpacking objects|Enumerating objects|Writing objects):/i,
|
|
14973
|
+
replacer: DROP
|
|
14974
|
+
},
|
|
14975
|
+
{
|
|
14976
|
+
// npm install summary chatter: "added 142 packages in 3s", "changed 5 packages", "audited 200 packages in 1s".
|
|
14977
|
+
name: "npm-summary",
|
|
14978
|
+
pattern: /^\s*(added|removed|changed|audited)\s+\d+\s+packages?\b/i,
|
|
14979
|
+
replacer: DROP
|
|
14980
|
+
},
|
|
14981
|
+
{
|
|
14982
|
+
// npm/yarn deprecation + funding noise that adds nothing actionable.
|
|
14983
|
+
name: "npm-funding",
|
|
14984
|
+
pattern: /^\s*\d+\s+packages? are looking for funding\b/i,
|
|
14985
|
+
replacer: DROP
|
|
14986
|
+
},
|
|
14987
|
+
{
|
|
14988
|
+
// pip download progress: "Downloading foo-1.2.3-py3-none-any.whl (1.2 MB)" and the " |████████| 1.2 MB 5.0 MB/s" meter lines.
|
|
14989
|
+
name: "pip-download",
|
|
14990
|
+
pattern: /^\s*(Downloading|Collecting|Using cached|Requirement already satisfied)\b/i,
|
|
14991
|
+
replacer: DROP
|
|
14992
|
+
},
|
|
14993
|
+
{
|
|
14994
|
+
// A progress meter line built from Unicode box-drawing/block glyphs, e.g. "████████░░░░ 60%". Restricted to those glyphs (not ASCII #/=/-) so an ASCII final state like "Building [####] 100%" is preserved as real output.
|
|
14995
|
+
name: "progress-bar",
|
|
14996
|
+
pattern: /[█▉▊▋▌▍▎▏▓▒░]{3,}/,
|
|
14997
|
+
replacer: DROP
|
|
14998
|
+
},
|
|
14999
|
+
{
|
|
15000
|
+
// Docker layer pull progress: "abc123: Pulling fs layer", "abc123: Download complete", "abc123: Pull complete".
|
|
15001
|
+
name: "docker-pull",
|
|
15002
|
+
pattern: /^[0-9a-f]{6,}:\s+(Pulling|Waiting|Downloading|Verifying|Extracting|Download complete|Pull complete|Already exists)\b/i,
|
|
15003
|
+
replacer: DROP
|
|
15004
|
+
},
|
|
15005
|
+
{
|
|
15006
|
+
// cargo build chatter: " Compiling foo v0.1.0", " Downloading crates ...".
|
|
15007
|
+
name: "cargo-progress",
|
|
15008
|
+
pattern: /^\s*(Compiling|Downloading|Downloaded|Updating|Fetching)\s+\S/,
|
|
15009
|
+
replacer: DROP
|
|
15010
|
+
},
|
|
15011
|
+
{
|
|
15012
|
+
// Webpack/bundler asset rows are voluminous; keep the build result lines (errors, warnings, "compiled") by only dropping plain asset size rows.
|
|
15013
|
+
name: "webpack-asset",
|
|
15014
|
+
pattern: /^\s*(asset|chunk)\s+\S+\s+[\d.]+\s*(KiB|MiB|bytes)\b/i,
|
|
15015
|
+
replacer: DROP
|
|
15016
|
+
},
|
|
15017
|
+
{
|
|
15018
|
+
// A binary-content marker line: any line carrying a NUL byte is treated as non-text and collapsed to a single readable marker.
|
|
15019
|
+
name: "binary-content",
|
|
15020
|
+
// eslint-disable-next-line no-control-regex -- intentionally matches the NUL control byte that signals binary content
|
|
15021
|
+
pattern: /\x00/,
|
|
15022
|
+
replacer: () => "[binary content elided by token-goat]"
|
|
15023
|
+
}
|
|
15024
|
+
];
|
|
15025
|
+
|
|
15026
|
+
// src/text_logfold.ts
|
|
14927
15027
|
var VOLATILE_SUBS = [
|
|
14928
15028
|
{ re: /\b\d{1,2}:\d{2}:\d{2}(?:\.\d+)?\b/g, placeholder: "[HH:MM:SS]" },
|
|
14929
15029
|
{ re: /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, placeholder: "[UUID]" },
|
|
@@ -16103,7 +16203,7 @@ function registerAnalysisCommands(program2, guard) {
|
|
|
16103
16203
|
).option("--file <path>", "narrow to one source file's gaps (matched exact or as a path suffix against the report's own file keys)").option("--json", "emit the gap report as JSON instead of text").action(guard(cmdCoverageReportGaps));
|
|
16104
16204
|
program2.command("conflicts [path]").description(
|
|
16105
16205
|
"unresolved git merge-conflict markers (<<<<<<< / ||||||| / ======= / >>>>>>>, two-way or diff3 three-way) instead of a raw Read or grep\n\npath may be a single file, a directory (scanned recursively), or omitted entirely (scans the whole project from the current directory); only files with at least one conflict region or malformed-marker warning are reported"
|
|
16106
|
-
).option("--summary", "line ranges and ours/base/theirs labels only, omitting the conflict content").option("--json", "emit the results as JSON instead of text").action(guard(cmdConflicts));
|
|
16206
|
+
).option("-C, --context <n>", "lines of surrounding context to include before and after each conflict region (default: 3)").option("--summary", "line ranges and ours/base/theirs labels only, omitting the conflict content").option("--json", "emit the results as JSON instead of text").action(guard(cmdConflicts));
|
|
16107
16207
|
program2.command("history").description("show recent session history: bash commands and web fetches (current-session or recent cache)").option("--limit <n>", "max entries to show (default: 30)").option("-j, --json", "output as JSON").action((opts) => guard(() => cmdHistory(opts))());
|
|
16108
16208
|
program2.command("changed [ref]").description("list files or symbols changed since a git ref").option("--since <ref>", "git ref to compare against (default: HEAD~5)").option("--symbol", "list symbols instead of files").option("-j, --json", "output as JSON").option("--grep <pattern>", "filter to changed files whose path matches this regex (falls back to a literal substring match when the pattern does not compile); applies to file paths even in --symbol mode").option("--exclude-tests", "hide changed files that live in a test file (opt-in; default output is unchanged); applies to file paths even in --symbol mode").action(
|
|
16109
16209
|
(ref, opts) => runExit(
|
|
@@ -16235,7 +16335,7 @@ function renderCapabilities(caps) {
|
|
|
16235
16335
|
|
|
16236
16336
|
// src/cli_session.ts
|
|
16237
16337
|
init_define_import_meta_env();
|
|
16238
|
-
import * as
|
|
16338
|
+
import * as fs40 from "node:fs";
|
|
16239
16339
|
|
|
16240
16340
|
// src/session_audit.ts
|
|
16241
16341
|
init_define_import_meta_env();
|
|
@@ -16243,6 +16343,23 @@ import * as fs34 from "node:fs";
|
|
|
16243
16343
|
import * as os16 from "node:os";
|
|
16244
16344
|
import * as path31 from "node:path";
|
|
16245
16345
|
import * as readline from "node:readline";
|
|
16346
|
+
var MODEL_VISIBLE_CATEGORIES = ["toolResults", "assistantText", "assistantThinking", "toolUseInputs", "attachments", "userTurns", "harnessMeta", "system"];
|
|
16347
|
+
function computeCalibration(estimated, measured) {
|
|
16348
|
+
let modelVisibleBytes = 0;
|
|
16349
|
+
let estimatedTokens = 0;
|
|
16350
|
+
for (const key of MODEL_VISIBLE_CATEGORIES) {
|
|
16351
|
+
modelVisibleBytes += estimated[key].bytes;
|
|
16352
|
+
estimatedTokens += estimated[key].estTokens;
|
|
16353
|
+
}
|
|
16354
|
+
const measuredFirstWriteTokens = measured.inputTokens + measured.cacheCreationTokens;
|
|
16355
|
+
return {
|
|
16356
|
+
modelVisibleBytes,
|
|
16357
|
+
estimatedTokens,
|
|
16358
|
+
measuredFirstWriteTokens,
|
|
16359
|
+
relativeError: measuredFirstWriteTokens === 0 ? 0 : (estimatedTokens - measuredFirstWriteTokens) / measuredFirstWriteTokens,
|
|
16360
|
+
bytesPerMeasuredToken: measuredFirstWriteTokens === 0 ? 0 : modelVisibleBytes / measuredFirstWriteTokens
|
|
16361
|
+
};
|
|
16362
|
+
}
|
|
16246
16363
|
function emptyMeasured() {
|
|
16247
16364
|
return { apiCalls: 0, inputTokens: 0, cacheCreationTokens: 0, cacheReadTokens: 0, outputTokens: 0 };
|
|
16248
16365
|
}
|
|
@@ -16317,8 +16434,12 @@ var DENY_TEMPLATES = [
|
|
|
16317
16434
|
{ kind: "doc_unchanged_deny", re: /is unchanged since last read\. Use `token-goat (?:section|read)/, tool: "Read" },
|
|
16318
16435
|
{ kind: "doc_diff_deny", re: /Content changed since last read of [\s\S]*?Use `token-goat (?:section|read)/, tool: "Read" },
|
|
16319
16436
|
{ kind: "read_served_deny", re: /was already served in this session, byte for byte/, tool: "Read" },
|
|
16437
|
+
// Its own kind rather than folded into read_served_deny above, whose stat name this branch shares: the wording is disjoint (a span, not a byte-for-byte whole serve) and so is the follow-up it invites, since the model still needs part of that span and has to choose a narrower call rather than recall the whole result.
|
|
16438
|
+
{ kind: "range_reread_deny", re: /Lines \d+\.\.\d+ of [\s\S]*?was already read this session/, tool: "Read" },
|
|
16320
16439
|
{ kind: "markdown_already_read_deny", re: /Markdown file already read this session\. Use `token-goat section/, tool: "Read" },
|
|
16321
16440
|
{ kind: "read_count_deny", re: /(?:Read|Tried to read) this file \d+ times already/, tool: "Read" },
|
|
16441
|
+
// Shares read_count_deny's stat name and matches none of its wording: this branch fires on the SHAPE of the reads (consecutive line windows walking one file) rather than on their count, and says so.
|
|
16442
|
+
{ kind: "sequential_paging_deny", re: /Sequential line-range paging detected on /, tool: "Read" },
|
|
16322
16443
|
{ kind: "generic_reread_deny", re: /was already read this session \(\d+ read/, tool: "Read" },
|
|
16323
16444
|
{ kind: "large_file_deny", re: /is very large \(\d+(?:\.\d+)?KB\)\./, tool: "Read" },
|
|
16324
16445
|
{ kind: "file_type_handler_deny", re: /too large to preview \(exceeds the in-hook scan cap\)|cannot be read as text\.|Read cannot return spreadsheet content|Read cannot return slide content|Read cannot return document content|Use Read with offset and limit parameters to read specific line ranges/, tool: "Read" },
|
|
@@ -16347,10 +16468,10 @@ var SHELL_READER_TOKEN_RE = /\b(?:sed|grep|cat|head|tail|awk|rg|less|nl|python3?
|
|
|
16347
16468
|
function escapeRegExp2(s) {
|
|
16348
16469
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
16349
16470
|
}
|
|
16350
|
-
function shellReadMatch(command,
|
|
16351
|
-
if (
|
|
16352
|
-
if (!command.includes(
|
|
16353
|
-
const escaped = escapeRegExp2(
|
|
16471
|
+
function shellReadMatch(command, basename10) {
|
|
16472
|
+
if (basename10 === "" || !SHELL_READER_TOKEN_RE.test(command)) return "none";
|
|
16473
|
+
if (!command.includes(basename10)) return "none";
|
|
16474
|
+
const escaped = escapeRegExp2(basename10);
|
|
16354
16475
|
const strict = new RegExp(`(?:^|["'\`/\\\\\\s])${escaped}(?:$|["'\`/\\\\\\s,;:)])`);
|
|
16355
16476
|
return strict.test(command) ? "match" : "ambiguous";
|
|
16356
16477
|
}
|
|
@@ -16390,7 +16511,7 @@ function deepStringBytes(value) {
|
|
|
16390
16511
|
}
|
|
16391
16512
|
return 0;
|
|
16392
16513
|
}
|
|
16393
|
-
var OMISSION_MARKER_RE = /(?:--- (\d+) lines omitted ---|\[token-goat: \+?(\d+) more [a-z ]*lines omitted\]|--- patch: (\d+) lines omitted by token-goat ---|\.\.\. (\d+) lines omitted by token-goat \.\.\.)/g;
|
|
16514
|
+
var OMISSION_MARKER_RE = /(?:--- (\d+) lines omitted ---|\[token-goat: \+?(\d+) (?:more )?[a-z ]*lines omitted\]|--- patch: (\d+) lines omitted by token-goat ---|\.\.\. (\d+) lines omitted by token-goat \.\.\.)/g;
|
|
16394
16515
|
function toolResultText(content) {
|
|
16395
16516
|
if (typeof content === "string") return content;
|
|
16396
16517
|
if (Array.isArray(content)) {
|
|
@@ -16588,7 +16709,7 @@ async function auditOneFile(filePath, s, toolMap, attachmentMap, hookMap, laneOb
|
|
|
16588
16709
|
s.editErrorBaseline.totalEdits += 1;
|
|
16589
16710
|
}
|
|
16590
16711
|
if (openDenies.length > 0) {
|
|
16591
|
-
const bashCommand = name === "Bash" && typeof input["command"] === "string" ? input["command"] : void 0;
|
|
16712
|
+
const bashCommand = name === "Bash" && typeof input["command"] === "string" ? input["command"].toLowerCase() : void 0;
|
|
16592
16713
|
for (const o of openDenies) {
|
|
16593
16714
|
if (o.toolCalls.length >= 10) continue;
|
|
16594
16715
|
const isReadSamePath = readNorm !== void 0 && o.path !== "" && readNorm === o.path;
|
|
@@ -16639,13 +16760,13 @@ async function auditOneFile(filePath, s, toolMap, attachmentMap, hookMap, laneOb
|
|
|
16639
16760
|
if (name === "Read" || name === "Skill") {
|
|
16640
16761
|
const denyTemplate = DENY_TEMPLATES.find((t) => t.tool === name && t.re.test(text));
|
|
16641
16762
|
if (denyTemplate !== void 0) {
|
|
16642
|
-
const
|
|
16643
|
-
const lastSlash =
|
|
16763
|
+
const path42 = readPathById.get(id) ?? "";
|
|
16764
|
+
const lastSlash = path42.lastIndexOf("/");
|
|
16644
16765
|
openDenies.push({
|
|
16645
16766
|
kind: denyTemplate.kind,
|
|
16646
16767
|
withheldBytes: parseWithheldBytes(denyTemplate.kind, text),
|
|
16647
|
-
path:
|
|
16648
|
-
basename: lastSlash === -1 ?
|
|
16768
|
+
path: path42,
|
|
16769
|
+
basename: lastSlash === -1 ? path42 : path42.slice(lastSlash + 1),
|
|
16649
16770
|
callIndexAtDeny: perCall.length,
|
|
16650
16771
|
compactEpochAtOpen: compactEpoch,
|
|
16651
16772
|
compactEpochAtWindow: null,
|
|
@@ -16946,6 +17067,7 @@ async function auditSessionCorpus(opts = {}) {
|
|
|
16946
17067
|
system: emptyCategory(),
|
|
16947
17068
|
otherLocal: emptyCategory()
|
|
16948
17069
|
},
|
|
17070
|
+
calibration: { modelVisibleBytes: 0, estimatedTokens: 0, measuredFirstWriteTokens: 0, relativeError: 0, bytesPerMeasuredToken: 0 },
|
|
16949
17071
|
tools: [],
|
|
16950
17072
|
attachmentKinds: [],
|
|
16951
17073
|
hookOutputs: [],
|
|
@@ -17006,6 +17128,7 @@ async function auditSessionCorpus(opts = {}) {
|
|
|
17006
17128
|
summary.hookOutputs = [...hookMap.values()].sort((a, b) => b.contextBytes - a.contextBytes || b.fires - a.fires || a.origin.localeCompare(b.origin) || a.event.localeCompare(b.event));
|
|
17007
17129
|
summary.denyOutcomes = aggregateDenyOutcomes(denyRows);
|
|
17008
17130
|
summary.editErrorBaseline.rate = summary.editErrorBaseline.totalEdits === 0 ? 0 : summary.editErrorBaseline.totalErrors / summary.editErrorBaseline.totalEdits;
|
|
17131
|
+
summary.calibration = computeCalibration(summary.estimated, summary.measured);
|
|
17009
17132
|
summary.runtimeMs = Date.now() - started;
|
|
17010
17133
|
return summary;
|
|
17011
17134
|
}
|
|
@@ -17046,11 +17169,20 @@ function formatSessionAudit(s) {
|
|
|
17046
17169
|
["system lines", e.system],
|
|
17047
17170
|
["local bookkeeping (never sent)", e.otherLocal]
|
|
17048
17171
|
];
|
|
17049
|
-
const
|
|
17172
|
+
const cal = s.calibration;
|
|
17173
|
+
const modelVisibleBytes = cal.modelVisibleBytes;
|
|
17050
17174
|
for (const [label, cat] of rows.sort((a, b) => b[1].bytes - a[1].bytes)) {
|
|
17051
17175
|
lines.push(`${label.padEnd(31)} count ${fmt(cat.count).padStart(11)} bytes ${fmt(cat.bytes).padStart(15)} est-tokens ${fmt(cat.estTokens).padStart(13)} ${label === "local bookkeeping (never sent)" ? "(excluded from share)" : pct(cat.bytes, modelVisibleBytes)}`);
|
|
17052
17176
|
}
|
|
17053
17177
|
lines.push("");
|
|
17178
|
+
lines.push("## Estimator calibration (the estimate above against the billed ledger above it)");
|
|
17179
|
+
lines.push(`Model-visible bytes: ${fmt(cal.modelVisibleBytes).padStart(18)}`);
|
|
17180
|
+
lines.push(`Estimated tokens (chars/3): ${fmt(cal.estimatedTokens).padStart(18)}`);
|
|
17181
|
+
lines.push(`Measured first-write tokens: ${fmt(cal.measuredFirstWriteTokens).padStart(18)} (input + cache-write; NEVER input alone -- a cached session bills nearly every first write as a cache write)`);
|
|
17182
|
+
lines.push(`Estimator error: ${(cal.relativeError >= 0 ? "+" : "") + (cal.relativeError * 100).toFixed(1) + "%"} ${cal.relativeError >= 0 ? "over" : "under"} measured`);
|
|
17183
|
+
lines.push(`Implied bytes per token: ${cal.bytesPerMeasuredToken.toFixed(2)} (against the 3.0 the estimate divides by)`);
|
|
17184
|
+
lines.push("Read the error as a bound, not a correction factor. Two effects inflate the measured side and neither is separable here: a prefix whose cache entry expires is written again and billed twice while the estimate counts it once, and the system prompt and tool schemas are sent on every call but appear in the transcript only in part. Both push the measured figure up, so an estimate below it is expected and only the magnitude carries information.");
|
|
17185
|
+
lines.push("");
|
|
17054
17186
|
lines.push("## Tool results by tool (estimated content size; calls = tool_use invocations)");
|
|
17055
17187
|
for (const t of s.tools.slice(0, 25)) {
|
|
17056
17188
|
lines.push(`${displaySafeText(t.name).padEnd(42)} calls ${fmt(t.calls).padStart(9)} bytes ${fmt(t.resultBytes).padStart(15)} est-tokens ${fmt(t.resultEstTokens).padStart(12)}`);
|
|
@@ -17621,142 +17753,8 @@ async function runMemoryCommand(opts = {}) {
|
|
|
17621
17753
|
|
|
17622
17754
|
// src/cli_waste.ts
|
|
17623
17755
|
init_define_import_meta_env();
|
|
17624
|
-
import * as fs39 from "node:fs";
|
|
17625
|
-
import * as path36 from "node:path";
|
|
17626
|
-
|
|
17627
|
-
// src/copilot_waste.ts
|
|
17628
|
-
init_define_import_meta_env();
|
|
17629
17756
|
import * as fs38 from "node:fs";
|
|
17630
17757
|
import * as path35 from "node:path";
|
|
17631
|
-
var HOOK_RECORD_TYPES = /* @__PURE__ */ new Set(["hook.start", "hook.end"]);
|
|
17632
|
-
function splitInjectedBlocks(transformed) {
|
|
17633
|
-
const out2 = [];
|
|
17634
|
-
const blockRe = /<([a-z_][a-z0-9_]*)>([\s\S]*?)<\/\1>/gi;
|
|
17635
|
-
let m;
|
|
17636
|
-
while ((m = blockRe.exec(transformed)) !== null) {
|
|
17637
|
-
const tag = (m[1] ?? "").toLowerCase();
|
|
17638
|
-
const body = m[2] ?? "";
|
|
17639
|
-
let kind = tag;
|
|
17640
|
-
if (tag === "system_reminder") {
|
|
17641
|
-
const inner = /^\s*<([a-z_][a-z0-9_]*)>/i.exec(body);
|
|
17642
|
-
kind = inner !== null ? `reminder:${(inner[1] ?? "").toLowerCase()}` : "reminder:text";
|
|
17643
|
-
}
|
|
17644
|
-
out2.push({ kind, body: m[0] });
|
|
17645
|
-
}
|
|
17646
|
-
return out2;
|
|
17647
|
-
}
|
|
17648
|
-
function findLatestCopilotSession() {
|
|
17649
|
-
const root = path35.join(copilotCliUserRoot(), "session-state");
|
|
17650
|
-
let entries;
|
|
17651
|
-
try {
|
|
17652
|
-
entries = fs38.readdirSync(root);
|
|
17653
|
-
} catch {
|
|
17654
|
-
return null;
|
|
17655
|
-
}
|
|
17656
|
-
let best = null;
|
|
17657
|
-
let bestMtime = -Infinity;
|
|
17658
|
-
for (const entry of entries) {
|
|
17659
|
-
const candidate = path35.join(root, entry, "events.jsonl");
|
|
17660
|
-
try {
|
|
17661
|
-
const st = fs38.statSync(candidate);
|
|
17662
|
-
if (!st.isFile()) continue;
|
|
17663
|
-
if (st.mtimeMs > bestMtime) {
|
|
17664
|
-
bestMtime = st.mtimeMs;
|
|
17665
|
-
best = candidate;
|
|
17666
|
-
}
|
|
17667
|
-
} catch {
|
|
17668
|
-
}
|
|
17669
|
-
}
|
|
17670
|
-
return best;
|
|
17671
|
-
}
|
|
17672
|
-
function readNumber(source, key) {
|
|
17673
|
-
const value = source[key];
|
|
17674
|
-
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
17675
|
-
}
|
|
17676
|
-
function buildCopilotWasteReport(eventsPath) {
|
|
17677
|
-
const raw = fs38.readFileSync(eventsPath, "utf-8");
|
|
17678
|
-
const report = {
|
|
17679
|
-
sessionPath: eventsPath,
|
|
17680
|
-
sessionId: path35.basename(path35.dirname(eventsPath)),
|
|
17681
|
-
turns: 0,
|
|
17682
|
-
tokens: null,
|
|
17683
|
-
blocks: [],
|
|
17684
|
-
compactions: [],
|
|
17685
|
-
hookRecordBytes: 0,
|
|
17686
|
-
totalEventBytes: Buffer.byteLength(raw, "utf-8"),
|
|
17687
|
-
// Read through the real resolution chain rather than passed in. Copilot's
|
|
17688
|
-
// own COPILOT_CACHE_HOME override is what tests point at a fixture, so the
|
|
17689
|
-
// shipping path is the tested path and there is no seam here that only a
|
|
17690
|
-
// test ever supplies.
|
|
17691
|
-
mcpTools: readCopilotMcpTools()
|
|
17692
|
-
};
|
|
17693
|
-
const classes = /* @__PURE__ */ new Map();
|
|
17694
|
-
const seen = /* @__PURE__ */ new Map();
|
|
17695
|
-
for (const line of raw.split("\n")) {
|
|
17696
|
-
const trimmed = line.trim();
|
|
17697
|
-
if (trimmed === "") continue;
|
|
17698
|
-
let event;
|
|
17699
|
-
try {
|
|
17700
|
-
event = JSON.parse(trimmed);
|
|
17701
|
-
} catch {
|
|
17702
|
-
continue;
|
|
17703
|
-
}
|
|
17704
|
-
const type = typeof event["type"] === "string" ? event["type"] : "";
|
|
17705
|
-
const data = event["data"] ?? {};
|
|
17706
|
-
if (HOOK_RECORD_TYPES.has(type)) {
|
|
17707
|
-
report.hookRecordBytes += Buffer.byteLength(trimmed, "utf-8");
|
|
17708
|
-
continue;
|
|
17709
|
-
}
|
|
17710
|
-
if (type === "session.shutdown") {
|
|
17711
|
-
report.tokens = {
|
|
17712
|
-
systemTokens: readNumber(data, "systemTokens"),
|
|
17713
|
-
toolDefinitionsTokens: readNumber(data, "toolDefinitionsTokens"),
|
|
17714
|
-
conversationTokens: readNumber(data, "conversationTokens"),
|
|
17715
|
-
currentTokens: readNumber(data, "currentTokens")
|
|
17716
|
-
};
|
|
17717
|
-
continue;
|
|
17718
|
-
}
|
|
17719
|
-
if (type === "session.compaction_complete") {
|
|
17720
|
-
const summary = typeof data["summaryContent"] === "string" ? data["summaryContent"] : "";
|
|
17721
|
-
report.compactions.push({
|
|
17722
|
-
trigger: typeof data["trigger"] === "string" ? data["trigger"] : "unknown",
|
|
17723
|
-
summaryBytes: Buffer.byteLength(summary, "utf-8"),
|
|
17724
|
-
preTokens: readNumber(data, "preCompactionTokens"),
|
|
17725
|
-
postTokens: readNumber(data, "postCompactionTokens")
|
|
17726
|
-
});
|
|
17727
|
-
continue;
|
|
17728
|
-
}
|
|
17729
|
-
if (type !== "user.message") continue;
|
|
17730
|
-
const transformed = typeof data["transformedContent"] === "string" ? data["transformedContent"] : "";
|
|
17731
|
-
if (transformed === "") continue;
|
|
17732
|
-
report.turns += 1;
|
|
17733
|
-
for (const block of splitInjectedBlocks(transformed)) {
|
|
17734
|
-
const bytes = Buffer.byteLength(block.body, "utf-8");
|
|
17735
|
-
let cls = classes.get(block.kind);
|
|
17736
|
-
if (cls === void 0) {
|
|
17737
|
-
cls = { kind: block.kind, count: 0, bytes: 0, repeatBytes: 0, repeatCount: 0 };
|
|
17738
|
-
classes.set(block.kind, cls);
|
|
17739
|
-
}
|
|
17740
|
-
cls.count += 1;
|
|
17741
|
-
cls.bytes += bytes;
|
|
17742
|
-
let bucket = seen.get(block.kind);
|
|
17743
|
-
if (bucket === void 0) {
|
|
17744
|
-
bucket = /* @__PURE__ */ new Set();
|
|
17745
|
-
seen.set(block.kind, bucket);
|
|
17746
|
-
}
|
|
17747
|
-
if (bucket.has(block.body)) {
|
|
17748
|
-
cls.repeatBytes += bytes;
|
|
17749
|
-
cls.repeatCount += 1;
|
|
17750
|
-
} else {
|
|
17751
|
-
bucket.add(block.body);
|
|
17752
|
-
}
|
|
17753
|
-
}
|
|
17754
|
-
}
|
|
17755
|
-
report.blocks = [...classes.values()].sort((a, b) => b.bytes - a.bytes);
|
|
17756
|
-
return report;
|
|
17757
|
-
}
|
|
17758
|
-
|
|
17759
|
-
// src/cli_waste.ts
|
|
17760
17758
|
function printCopilotReport(report) {
|
|
17761
17759
|
const w = (text) => {
|
|
17762
17760
|
process.stdout.write(text);
|
|
@@ -17955,9 +17953,50 @@ function printResidentContext(resident, w) {
|
|
|
17955
17953
|
w(resident.compactionCount === 0 ? "\n" : ", each re-injecting the fixed preamble (CLAUDE.md, memory, skill and agent listings)\n");
|
|
17956
17954
|
}
|
|
17957
17955
|
async function runWasteCommand(opts = {}) {
|
|
17956
|
+
const projectRoot = resolveProjectRoot(opts.project !== void 0 ? { project: opts.project } : {});
|
|
17957
|
+
if (opts.transcript !== void 0) {
|
|
17958
|
+
const resolvedPath = path35.resolve(opts.transcript);
|
|
17959
|
+
if (!fs38.existsSync(resolvedPath)) {
|
|
17960
|
+
if (opts.copilot === true) {
|
|
17961
|
+
const detail = `Copilot session event log not found: ${resolvedPath}`;
|
|
17962
|
+
if (opts.json === true) {
|
|
17963
|
+
process.stdout.write(`${displaySafeJson({ error: detail }, 0)}
|
|
17964
|
+
`);
|
|
17965
|
+
} else {
|
|
17966
|
+
process.stdout.write("\n# token-goat waste (Copilot CLI)\n");
|
|
17967
|
+
process.stdout.write(`${detail}
|
|
17968
|
+
`);
|
|
17969
|
+
}
|
|
17970
|
+
process.exitCode = 1;
|
|
17971
|
+
return;
|
|
17972
|
+
}
|
|
17973
|
+
process.stderr.write(`token-goat: transcript not found: ${resolvedPath}
|
|
17974
|
+
`);
|
|
17975
|
+
process.exitCode = 1;
|
|
17976
|
+
return;
|
|
17977
|
+
}
|
|
17978
|
+
if (opts.copilot === true || isCopilotTranscript(resolvedPath)) {
|
|
17979
|
+
const copilotReport = buildCopilotWasteReport(resolvedPath);
|
|
17980
|
+
if (opts.json === true) {
|
|
17981
|
+
process.stdout.write(`${displaySafeJson(copilotReport, 0)}
|
|
17982
|
+
`);
|
|
17983
|
+
return;
|
|
17984
|
+
}
|
|
17985
|
+
printCopilotReport(copilotReport);
|
|
17986
|
+
return;
|
|
17987
|
+
}
|
|
17988
|
+
const report2 = await buildWasteReport(resolvedPath, opts.top !== void 0 ? { topN: opts.top } : {});
|
|
17989
|
+
if (opts.json === true) {
|
|
17990
|
+
process.stdout.write(`${displaySafeJson(report2, 0)}
|
|
17991
|
+
`);
|
|
17992
|
+
return;
|
|
17993
|
+
}
|
|
17994
|
+
printReport2(report2);
|
|
17995
|
+
return;
|
|
17996
|
+
}
|
|
17958
17997
|
if (opts.copilot === true) {
|
|
17959
|
-
const eventsPath = opts.
|
|
17960
|
-
if (eventsPath === null || !
|
|
17998
|
+
const eventsPath = opts.project !== void 0 ? findLatestCopilotSession({ projectRoot }) : findLatestCopilotSession({ projectRoot }) ?? findLatestCopilotSession();
|
|
17999
|
+
if (eventsPath === null || !fs38.existsSync(eventsPath)) {
|
|
17961
18000
|
const detail = eventsPath === null ? "no Copilot CLI session found under <copilot-home>/session-state" : `Copilot session event log not found: ${eventsPath}`;
|
|
17962
18001
|
if (opts.json === true) {
|
|
17963
18002
|
process.stdout.write(`${displaySafeJson({ error: detail }, 0)}
|
|
@@ -17979,9 +18018,8 @@ async function runWasteCommand(opts = {}) {
|
|
|
17979
18018
|
printCopilotReport(copilotReport);
|
|
17980
18019
|
return;
|
|
17981
18020
|
}
|
|
17982
|
-
const
|
|
17983
|
-
|
|
17984
|
-
if (transcriptPath === null) {
|
|
18021
|
+
const detected = findProjectSession(projectRoot);
|
|
18022
|
+
if (detected === null) {
|
|
17985
18023
|
if (opts.json === true) {
|
|
17986
18024
|
process.stdout.write(`${displaySafeJson({ error: "no session transcript found", project: projectRoot }, 0)}
|
|
17987
18025
|
`);
|
|
@@ -17994,13 +18032,17 @@ async function runWasteCommand(opts = {}) {
|
|
|
17994
18032
|
process.exitCode = 1;
|
|
17995
18033
|
return;
|
|
17996
18034
|
}
|
|
17997
|
-
if (
|
|
17998
|
-
|
|
18035
|
+
if (detected.kind === "copilot") {
|
|
18036
|
+
const copilotReport = buildCopilotWasteReport(detected.path);
|
|
18037
|
+
if (opts.json === true) {
|
|
18038
|
+
process.stdout.write(`${displaySafeJson(copilotReport, 0)}
|
|
17999
18039
|
`);
|
|
18000
|
-
|
|
18040
|
+
return;
|
|
18041
|
+
}
|
|
18042
|
+
printCopilotReport(copilotReport);
|
|
18001
18043
|
return;
|
|
18002
18044
|
}
|
|
18003
|
-
const report = await buildWasteReport(
|
|
18045
|
+
const report = await buildWasteReport(detected.path, opts.top !== void 0 ? { topN: opts.top } : {});
|
|
18004
18046
|
if (opts.json === true) {
|
|
18005
18047
|
process.stdout.write(`${displaySafeJson(report, 0)}
|
|
18006
18048
|
`);
|
|
@@ -18011,13 +18053,13 @@ async function runWasteCommand(opts = {}) {
|
|
|
18011
18053
|
|
|
18012
18054
|
// src/cli_mcp_audit.ts
|
|
18013
18055
|
init_define_import_meta_env();
|
|
18014
|
-
import * as
|
|
18056
|
+
import * as fs39 from "node:fs";
|
|
18015
18057
|
import * as os18 from "node:os";
|
|
18016
|
-
import * as
|
|
18058
|
+
import * as path36 from "node:path";
|
|
18017
18059
|
function readMcpJsonFile(configPath2) {
|
|
18018
18060
|
try {
|
|
18019
|
-
if (!
|
|
18020
|
-
const content =
|
|
18061
|
+
if (!fs39.existsSync(configPath2)) return null;
|
|
18062
|
+
const content = fs39.readFileSync(configPath2, "utf-8");
|
|
18021
18063
|
const parsed = JSON.parse(content);
|
|
18022
18064
|
const servers = parsed && typeof parsed === "object" ? parsed.mcpServers ?? ("servers" in parsed ? null : parsed) : null;
|
|
18023
18065
|
return servers && typeof servers === "object" ? servers : null;
|
|
@@ -18033,8 +18075,8 @@ function driveLetterCaseVariants(p) {
|
|
|
18033
18075
|
}
|
|
18034
18076
|
function readClaudeJsonConfig(claudeJsonPath, projectRoot) {
|
|
18035
18077
|
try {
|
|
18036
|
-
if (!
|
|
18037
|
-
const parsed = JSON.parse(
|
|
18078
|
+
if (!fs39.existsSync(claudeJsonPath)) return null;
|
|
18079
|
+
const parsed = JSON.parse(fs39.readFileSync(claudeJsonPath, "utf-8"));
|
|
18038
18080
|
const projects = parsed && typeof parsed === "object" ? parsed.projects : null;
|
|
18039
18081
|
if (!projects || typeof projects !== "object") return null;
|
|
18040
18082
|
const slashForms = [projectRoot, projectRoot.replace(/\\/g, "/"), projectRoot.replace(/\//g, "\\")];
|
|
@@ -18052,9 +18094,9 @@ function readClaudeJsonConfig(claudeJsonPath, projectRoot) {
|
|
|
18052
18094
|
}
|
|
18053
18095
|
}
|
|
18054
18096
|
function discoverMcpConfig(projectRoot, home) {
|
|
18055
|
-
const mcpJsonPath =
|
|
18056
|
-
const claudeJsonPath =
|
|
18057
|
-
const copilotJsonPath =
|
|
18097
|
+
const mcpJsonPath = path36.join(projectRoot, ".mcp.json");
|
|
18098
|
+
const claudeJsonPath = path36.join(home, ".claude.json");
|
|
18099
|
+
const copilotJsonPath = path36.join(home, ".copilot", "mcp-config.json");
|
|
18058
18100
|
const sourcesChecked = [mcpJsonPath, claudeJsonPath, copilotJsonPath];
|
|
18059
18101
|
const fromMcpJson = readMcpJsonFile(mcpJsonPath);
|
|
18060
18102
|
if (fromMcpJson !== null) return { servers: fromMcpJson, sourcePath: mcpJsonPath, sourcesChecked };
|
|
@@ -18247,7 +18289,7 @@ async function runStatuslineCommand(opts = {}) {
|
|
|
18247
18289
|
return;
|
|
18248
18290
|
}
|
|
18249
18291
|
const line = renderStatusline(data);
|
|
18250
|
-
process.stdout.write(`${colorStdout() ? line :
|
|
18292
|
+
process.stdout.write(`${colorStdout() ? line : stripAnsiEscapes(line)}
|
|
18251
18293
|
`);
|
|
18252
18294
|
}
|
|
18253
18295
|
|
|
@@ -18276,7 +18318,7 @@ function printSummary(rows) {
|
|
|
18276
18318
|
const w = (text) => {
|
|
18277
18319
|
process.stdout.write(text);
|
|
18278
18320
|
};
|
|
18279
|
-
w(pad("category", 22) + pad("emitted", 9) + pad("undisplayed", 13) + pad("acted-on", 10) + pad("efficacy", 12) + pad("suppressed", 17) + pad("manual+", 9) + pad("manual-", 9) + "spent\n");
|
|
18321
|
+
w(pad("category", 22) + pad("emitted", 9) + pad("undisplayed", 13) + pad("acted-on", 10) + pad("efficacy", 12) + pad("suppressed", 17) + pad("manual+", 9) + pad("manual-", 9) + "spent-bytes\n");
|
|
18280
18322
|
for (const row of rows) {
|
|
18281
18323
|
w(
|
|
18282
18324
|
pad(row.category, 22) + pad(emittedCell(row), 9) + pad(detectedCell(row), 13) + pad(String(row.actedOn), 10) + pad(efficacyCell(row), 12) + pad(suppressedCell(row), 17) + pad(String(row.manualEffective), 9) + pad(String(row.manualIneffective), 9) + formatSpentCell(row) + "\n"
|
|
@@ -18288,7 +18330,7 @@ function printTotals(totals) {
|
|
|
18288
18330
|
const legacyNote = totals.legacyEmissions > 0 ? ` (excludes ${totals.legacyEmissions} legacy emission(s) recorded before spend tracking)` : "";
|
|
18289
18331
|
process.stdout.write(
|
|
18290
18332
|
`
|
|
18291
|
-
TOTAL saved=${totals.savedBytes} (all-time, every hint kind) spent=${spent} (hint_emissions ledger only)${legacyNote}
|
|
18333
|
+
TOTAL saved-bytes=${totals.savedBytes} (all-time, every hint kind) spent-bytes=${spent} (hint_emissions ledger only)${legacyNote}
|
|
18292
18334
|
`
|
|
18293
18335
|
);
|
|
18294
18336
|
}
|
|
@@ -18370,10 +18412,18 @@ function cmdWaste(opts = {}) {
|
|
|
18370
18412
|
...opts.project !== void 0 ? { project: opts.project } : {},
|
|
18371
18413
|
...opts.transcript !== void 0 ? { transcript: opts.transcript } : {},
|
|
18372
18414
|
...opts.json === true ? { json: true } : {},
|
|
18373
|
-
...opts.top !== void 0 ? { top:
|
|
18415
|
+
...opts.top !== void 0 ? { top: requireNonNegativeInt("--top", opts.top) } : {},
|
|
18374
18416
|
...opts.copilot === true ? { copilot: true } : {}
|
|
18375
18417
|
});
|
|
18376
18418
|
}
|
|
18419
|
+
async function cmdAudit(opts = {}) {
|
|
18420
|
+
const { runAuditCommand } = await import("./token-goat-chunk-DYUBZZNP.mjs");
|
|
18421
|
+
return runAuditCommand({
|
|
18422
|
+
...opts.project !== void 0 ? { project: opts.project } : {},
|
|
18423
|
+
...opts.transcript !== void 0 ? { transcript: opts.transcript } : {},
|
|
18424
|
+
...opts.json === true ? { json: true } : {}
|
|
18425
|
+
});
|
|
18426
|
+
}
|
|
18377
18427
|
async function cmdSessionAudit(opts = {}) {
|
|
18378
18428
|
let summary;
|
|
18379
18429
|
try {
|
|
@@ -18400,7 +18450,7 @@ ${formatSessionOutline(turns)}`;
|
|
|
18400
18450
|
}
|
|
18401
18451
|
function sessionTranscriptSize(transcriptPath) {
|
|
18402
18452
|
try {
|
|
18403
|
-
return
|
|
18453
|
+
return fs40.statSync(transcriptPath).size;
|
|
18404
18454
|
} catch {
|
|
18405
18455
|
return 0;
|
|
18406
18456
|
}
|
|
@@ -18436,7 +18486,7 @@ function cmdRecall(query, opts = {}) {
|
|
|
18436
18486
|
}
|
|
18437
18487
|
runRecallCommand(query, {
|
|
18438
18488
|
...type !== void 0 ? { type } : {},
|
|
18439
|
-
...opts.limit !== void 0 ? { limit:
|
|
18489
|
+
...opts.limit !== void 0 ? { limit: requireNonNegativeInt("--limit", opts.limit) } : {},
|
|
18440
18490
|
...opts.json === true ? { json: true } : {}
|
|
18441
18491
|
});
|
|
18442
18492
|
}
|
|
@@ -18460,14 +18510,14 @@ function cmdHintStats(opts = {}) {
|
|
|
18460
18510
|
|
|
18461
18511
|
// src/cli_skills.ts
|
|
18462
18512
|
init_define_import_meta_env();
|
|
18463
|
-
import * as
|
|
18464
|
-
import * as
|
|
18513
|
+
import * as fs41 from "node:fs";
|
|
18514
|
+
import * as path37 from "node:path";
|
|
18465
18515
|
async function cmdSkillBody(name, opts) {
|
|
18466
18516
|
const filePath = await getSkillFilePath(name);
|
|
18467
18517
|
if (filePath === null) {
|
|
18468
18518
|
throw new CliError(`skill '${name}' not found`);
|
|
18469
18519
|
}
|
|
18470
|
-
const body = decodeSource(
|
|
18520
|
+
const body = decodeSource(fs41.readFileSync(filePath));
|
|
18471
18521
|
if (opts.compact === true) {
|
|
18472
18522
|
const emitted = extractCompactFromMarker(body) ?? body;
|
|
18473
18523
|
out(emitted);
|
|
@@ -18494,7 +18544,7 @@ async function cmdSkillCompact(name, opts) {
|
|
|
18494
18544
|
}
|
|
18495
18545
|
let body2;
|
|
18496
18546
|
try {
|
|
18497
|
-
body2 = decodeSource(
|
|
18547
|
+
body2 = decodeSource(fs41.readFileSync(filePath));
|
|
18498
18548
|
} catch {
|
|
18499
18549
|
unresolvable++;
|
|
18500
18550
|
continue;
|
|
@@ -18528,19 +18578,19 @@ async function cmdSkillCompact(name, opts) {
|
|
|
18528
18578
|
if (!opts.path.trim()) {
|
|
18529
18579
|
throw new CliError("--path cannot be empty");
|
|
18530
18580
|
}
|
|
18531
|
-
if (!
|
|
18581
|
+
if (!fs41.existsSync(opts.path)) {
|
|
18532
18582
|
throw new CliError(`skill file not found: ${opts.path}`);
|
|
18533
18583
|
}
|
|
18534
18584
|
try {
|
|
18535
|
-
body =
|
|
18585
|
+
body = fs41.readFileSync(opts.path, "utf-8");
|
|
18536
18586
|
} catch (e) {
|
|
18537
18587
|
if (e.code === "ENOENT") {
|
|
18538
18588
|
throw new CliError(`skill file not found: ${opts.path}`);
|
|
18539
18589
|
}
|
|
18540
18590
|
throw new CliError(`failed to read skill file '${opts.path}': ${extractErrorMessage(e)}`);
|
|
18541
18591
|
}
|
|
18542
|
-
cacheName = name ??
|
|
18543
|
-
sourcePath =
|
|
18592
|
+
cacheName = name ?? path37.basename(path37.dirname(path37.resolve(opts.path)));
|
|
18593
|
+
sourcePath = path37.resolve(opts.path);
|
|
18544
18594
|
} else {
|
|
18545
18595
|
if (name === void 0 || !name.trim()) {
|
|
18546
18596
|
throw new CliError("skill-compact requires a <name> or --path <file>");
|
|
@@ -18549,7 +18599,7 @@ async function cmdSkillCompact(name, opts) {
|
|
|
18549
18599
|
if (filePath === null) {
|
|
18550
18600
|
throw new CliError(`skill '${name}' not found`);
|
|
18551
18601
|
}
|
|
18552
|
-
body =
|
|
18602
|
+
body = fs41.readFileSync(filePath, "utf-8");
|
|
18553
18603
|
cacheName = name;
|
|
18554
18604
|
sourcePath = filePath;
|
|
18555
18605
|
}
|
|
@@ -18681,8 +18731,8 @@ async function cmdSkillDiff(name) {
|
|
|
18681
18731
|
}
|
|
18682
18732
|
const newer = versions[0];
|
|
18683
18733
|
const older = versions[1];
|
|
18684
|
-
const newerBody = await
|
|
18685
|
-
const olderBody = await
|
|
18734
|
+
const newerBody = await fs41.promises.readFile(path37.resolve(dir, `${newer.outputId}.txt`), "utf-8").catch(() => null);
|
|
18735
|
+
const olderBody = await fs41.promises.readFile(path37.resolve(dir, `${older.outputId}.txt`), "utf-8").catch(() => null);
|
|
18686
18736
|
if (newerBody === null || olderBody === null) {
|
|
18687
18737
|
out(`a cached version of '${name}' was evicted while diffing -- try again`);
|
|
18688
18738
|
return;
|
|
@@ -18711,7 +18761,7 @@ async function cmdSkillSection(nameHeading, headingArg) {
|
|
|
18711
18761
|
if (!filePath) {
|
|
18712
18762
|
throw new CliError(`skill '${skillName}' not found`);
|
|
18713
18763
|
}
|
|
18714
|
-
const body = decodeSource(
|
|
18764
|
+
const body = decodeSource(fs41.readFileSync(filePath));
|
|
18715
18765
|
const extracted = extractNamedSection(body, heading);
|
|
18716
18766
|
if (!extracted) {
|
|
18717
18767
|
const allHeadings = listSections(filePath);
|
|
@@ -18732,94 +18782,12 @@ async function cmdSkillSection(nameHeading, headingArg) {
|
|
|
18732
18782
|
// src/cache_session_commands.ts
|
|
18733
18783
|
init_define_import_meta_env();
|
|
18734
18784
|
|
|
18735
|
-
// src/resume.ts
|
|
18736
|
-
init_define_import_meta_env();
|
|
18737
|
-
import { readFile } from "node:fs/promises";
|
|
18738
|
-
var MAX_RESUME_TOKENS = 2e3;
|
|
18739
|
-
var MAX_RESUME_CHARS = MAX_RESUME_TOKENS * 4;
|
|
18740
|
-
var SKILL_MAX_COUNT = 3;
|
|
18741
|
-
var SKILL_MAX_CHARS_EACH = 400;
|
|
18742
|
-
async function buildSkillsSection(sessionId) {
|
|
18743
|
-
const skills = await listSkills(sessionId);
|
|
18744
|
-
if (skills.length === 0) return [];
|
|
18745
|
-
const skillLines = ["## Skills"];
|
|
18746
|
-
for (const skill of skills.slice(0, SKILL_MAX_COUNT)) {
|
|
18747
|
-
let checklist = null;
|
|
18748
|
-
try {
|
|
18749
|
-
const filePath = await getSkillFilePath(skill.name);
|
|
18750
|
-
if (filePath !== null) {
|
|
18751
|
-
const body = await readFile(filePath, "utf-8");
|
|
18752
|
-
checklist = extractChecklistSection(body);
|
|
18753
|
-
}
|
|
18754
|
-
} catch {
|
|
18755
|
-
checklist = null;
|
|
18756
|
-
}
|
|
18757
|
-
if (checklist !== null) {
|
|
18758
|
-
const trimmed = checklist.length > SKILL_MAX_CHARS_EACH ? checklist.slice(0, SKILL_MAX_CHARS_EACH).trimEnd() + "\u2026" : checklist;
|
|
18759
|
-
skillLines.push(`**${skill.name}**:`);
|
|
18760
|
-
skillLines.push(trimmed);
|
|
18761
|
-
} else {
|
|
18762
|
-
skillLines.push(`**${skill.name}** \u2014 \`token-goat skill-body ${skill.name} --section DoD\``);
|
|
18763
|
-
}
|
|
18764
|
-
}
|
|
18765
|
-
skillLines.push("");
|
|
18766
|
-
return skillLines;
|
|
18767
|
-
}
|
|
18768
|
-
async function buildResumePacket(sessionId) {
|
|
18769
|
-
const blob = loadBlob(SESSIONS_SUBDIR, sessionId);
|
|
18770
|
-
if (blob === null || typeof blob !== "object") return null;
|
|
18771
|
-
const raw = blob;
|
|
18772
|
-
const filesArr = Array.isArray(raw["files"]) ? raw["files"] : [];
|
|
18773
|
-
const lines = [`# Resume packet \u2014 session ${sessionId}`, ""];
|
|
18774
|
-
try {
|
|
18775
|
-
lines.push(...await buildSkillsSection(sessionId));
|
|
18776
|
-
} catch {
|
|
18777
|
-
}
|
|
18778
|
-
const editedPaths = filesArr.filter((f) => f["wasEdited"] === true).map((f) => typeof f["path"] === "string" ? f["path"] : "").filter(Boolean).slice(0, 10);
|
|
18779
|
-
if (editedPaths.length > 0) {
|
|
18780
|
-
lines.push("## Edited files");
|
|
18781
|
-
for (const p of editedPaths) lines.push(`- ${p}`);
|
|
18782
|
-
lines.push("");
|
|
18783
|
-
}
|
|
18784
|
-
const topRead = [...filesArr].filter((f) => f["wasEdited"] !== true).sort((a, b) => (typeof b["readCount"] === "number" ? b["readCount"] : 0) - (typeof a["readCount"] === "number" ? a["readCount"] : 0)).slice(0, 8).map((f) => typeof f["path"] === "string" ? f["path"] : "").filter(Boolean);
|
|
18785
|
-
if (topRead.length > 0) {
|
|
18786
|
-
lines.push("## Top files read");
|
|
18787
|
-
for (const p of topRead) lines.push(`- ${p}`);
|
|
18788
|
-
lines.push("");
|
|
18789
|
-
}
|
|
18790
|
-
const bashOutputs = Array.isArray(raw["bashOutputs"]) ? raw["bashOutputs"] : [];
|
|
18791
|
-
const recentBash = bashOutputs.slice(-2);
|
|
18792
|
-
if (recentBash.length > 0) {
|
|
18793
|
-
lines.push("## Recent bash commands");
|
|
18794
|
-
for (const entry of recentBash) {
|
|
18795
|
-
if (Array.isArray(entry) && typeof entry[1] === "string") {
|
|
18796
|
-
const bashEntry = getBashOutput(entry[1]);
|
|
18797
|
-
if (bashEntry !== null) lines.push(`- ${displaySafeText(bashEntry.command)}`);
|
|
18798
|
-
}
|
|
18799
|
-
}
|
|
18800
|
-
lines.push("");
|
|
18801
|
-
}
|
|
18802
|
-
try {
|
|
18803
|
-
const projectRoot = resolveProjectRoot();
|
|
18804
|
-
const result = runGit(["diff", "--stat"], { cwd: projectRoot });
|
|
18805
|
-
if (result.exitCode === 0 && result.stdout.trim().length > 0) {
|
|
18806
|
-
lines.push("## Uncommitted changes (git diff --stat)");
|
|
18807
|
-
lines.push(result.stdout.trim());
|
|
18808
|
-
lines.push("");
|
|
18809
|
-
}
|
|
18810
|
-
} catch {
|
|
18811
|
-
}
|
|
18812
|
-
const text = lines.join("\n");
|
|
18813
|
-
if (text.length <= MAX_RESUME_CHARS) return text;
|
|
18814
|
-
return safeSlice(text, MAX_RESUME_CHARS) + "\n... (truncated to cap)\n";
|
|
18815
|
-
}
|
|
18816
|
-
|
|
18817
18785
|
// src/cli_stats.ts
|
|
18818
18786
|
init_define_import_meta_env();
|
|
18819
|
-
import * as
|
|
18820
|
-
import * as
|
|
18787
|
+
import * as fs42 from "node:fs";
|
|
18788
|
+
import * as path38 from "node:path";
|
|
18821
18789
|
function writeRaw(text) {
|
|
18822
|
-
const payload = colorStdout() ? text :
|
|
18790
|
+
const payload = colorStdout() ? text : stripAnsiEscapes(text);
|
|
18823
18791
|
process.stdout.write(ensureNewline(payload));
|
|
18824
18792
|
}
|
|
18825
18793
|
function rankByReadCount(entries, topN) {
|
|
@@ -18829,8 +18797,8 @@ function formatTopFiles(ranked) {
|
|
|
18829
18797
|
if (ranked.length === 0) return "";
|
|
18830
18798
|
const lines = ["Top files this session:"];
|
|
18831
18799
|
for (const { path: filePath, count } of ranked) {
|
|
18832
|
-
const
|
|
18833
|
-
lines.push(` ${count.toString().padStart(3)}x ${
|
|
18800
|
+
const basename10 = path38.basename(filePath);
|
|
18801
|
+
lines.push(` ${count.toString().padStart(3)}x ${basename10} (${filePath})`);
|
|
18834
18802
|
}
|
|
18835
18803
|
return lines.join("\n");
|
|
18836
18804
|
}
|
|
@@ -18847,11 +18815,11 @@ function renderTopSessionFiles(topN = 5) {
|
|
|
18847
18815
|
function renderTopSessionFilesFromDisk(topN = 5, overrideSessionsDir) {
|
|
18848
18816
|
try {
|
|
18849
18817
|
const dir = overrideSessionsDir ?? sessionsDir();
|
|
18850
|
-
if (!
|
|
18851
|
-
const files =
|
|
18818
|
+
if (!fs42.existsSync(dir)) return "";
|
|
18819
|
+
const files = fs42.readdirSync(dir).filter((f) => f.endsWith(".json")).map((f) => ({ name: f, mtime: fs42.statSync(path38.join(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).slice(0, 3);
|
|
18852
18820
|
for (const { name } of files) {
|
|
18853
18821
|
try {
|
|
18854
|
-
const raw =
|
|
18822
|
+
const raw = fs42.readFileSync(path38.join(dir, name), "utf-8");
|
|
18855
18823
|
const data = JSON.parse(raw);
|
|
18856
18824
|
const filesList = data["files"];
|
|
18857
18825
|
if (!Array.isArray(filesList)) continue;
|
|
@@ -18943,13 +18911,10 @@ function runStats(opts = {}) {
|
|
|
18943
18911
|
}
|
|
18944
18912
|
|
|
18945
18913
|
// src/cache_session_commands.ts
|
|
18946
|
-
function emitErr4(text) {
|
|
18947
|
-
process.stderr.write(ensureNewline(text));
|
|
18948
|
-
}
|
|
18949
18914
|
function capAndNote(rows, limit) {
|
|
18950
18915
|
const shown = rows.slice(0, limit);
|
|
18951
18916
|
if (shown.length < rows.length) {
|
|
18952
|
-
|
|
18917
|
+
emitErr(`Showing ${shown.length} of ${rows.length} entries (raise --limit to see the rest).`);
|
|
18953
18918
|
}
|
|
18954
18919
|
return shown;
|
|
18955
18920
|
}
|
|
@@ -18959,11 +18924,11 @@ function parseLimitOpt(cmdName, limitStr, dflt = 30) {
|
|
|
18959
18924
|
try {
|
|
18960
18925
|
n = requireNonNegativeStrictInt("--limit", limitStr);
|
|
18961
18926
|
} catch (e) {
|
|
18962
|
-
|
|
18927
|
+
emitErr(`${cmdName}: --limit must be a positive number, got: "${limitStr}"`);
|
|
18963
18928
|
throw new Error(`invalid --limit: ${limitStr}`, { cause: e });
|
|
18964
18929
|
}
|
|
18965
18930
|
if (n === 0) {
|
|
18966
|
-
|
|
18931
|
+
emitErr(`${cmdName}: --limit must be a positive number, got: "${limitStr}"`);
|
|
18967
18932
|
throw new Error(`invalid --limit: ${limitStr}`);
|
|
18968
18933
|
}
|
|
18969
18934
|
return n;
|
|
@@ -19201,11 +19166,17 @@ function cmdCompactHint(opts) {
|
|
|
19201
19166
|
const cache = sessionId !== null ? loadSessionCache(sessionId) : null;
|
|
19202
19167
|
const transcriptPath = sessionId !== null ? resolveSessionTranscript(sessionId) : null;
|
|
19203
19168
|
const pressure = getContextPressure(cache ?? void 0, transcriptPath ?? void 0);
|
|
19204
|
-
|
|
19169
|
+
let manifest = "";
|
|
19170
|
+
let events = 0;
|
|
19171
|
+
if (sessionId !== null && cache !== null) {
|
|
19172
|
+
loadSessionState(sessionId);
|
|
19173
|
+
manifest = buildManifest(sessionId, process.cwd(), transcriptPath ?? void 0);
|
|
19174
|
+
events = eventCount(cache);
|
|
19175
|
+
}
|
|
19205
19176
|
const manifestTokens = estimateTokens(manifest);
|
|
19206
19177
|
const pct3 = (pressure.fillFraction * 100).toFixed(1);
|
|
19207
19178
|
if (opts.json === true) {
|
|
19208
|
-
const out2 = { tier: pressure.tier, fillFraction: pressure.fillFraction, pct: Number(pct3), manifestTokens, eventCount };
|
|
19179
|
+
const out2 = { tier: pressure.tier, fillFraction: pressure.fillFraction, pct: Number(pct3), manifestTokens, eventCount: events };
|
|
19209
19180
|
if (sessionId !== null) out2["sessionId"] = sessionId;
|
|
19210
19181
|
if (opts.trigger !== void 0) out2["trigger"] = opts.trigger;
|
|
19211
19182
|
process.stdout.write(displaySafeJson(out2) + "\n");
|
|
@@ -19215,7 +19186,7 @@ function cmdCompactHint(opts) {
|
|
|
19215
19186
|
`);
|
|
19216
19187
|
if (sessionId !== null) process.stdout.write(`Session: ${sessionId}
|
|
19217
19188
|
`);
|
|
19218
|
-
process.stdout.write(`Manifest: ${manifestTokens} tokens, ${countNoun(
|
|
19189
|
+
process.stdout.write(`Manifest: ${manifestTokens} tokens, ${countNoun(events, "event")}
|
|
19219
19190
|
`);
|
|
19220
19191
|
if (opts.trigger === "auto") {
|
|
19221
19192
|
const remaining = Math.max(0, Math.round((1 - pressure.fillFraction) * CONTEXT_AUTOCOMPACT_TOKENS));
|
|
@@ -19318,6 +19289,7 @@ function registerSessionCommands(program2, guard) {
|
|
|
19318
19289
|
program2.command("bootstrap-audit").description("audit Claude Code startup-context contributors without reading prompt bodies").option("--project <path>", "project root to analyze").option("--home <path>", "home directory override (for CI/testing)").option("--follow-links", "follow external symlink/junction roots and direct children").option("-j, --json", "output as JSON").option("--top <n>", "largest metadata entries to show (default 10)", "10").option("--warn-tokens <n>", "warn when total estimated startup tokens exceed n").option("--fail-tokens <n>", "fail when total estimated startup tokens exceed n").option("--warn-bytes <n>", "warn when agent/skill metadata bytes exceed n").option("--fail-bytes <n>", "fail when agent/skill metadata bytes exceed n").action(guard(cmdBootstrapAudit));
|
|
19319
19290
|
program2.command("memory").description("analyze CLAUDE.md files for duplicate/overlapping content (--fix to apply safe mechanical fixes)").option("--project <path>", "project root to analyze").option("--analyze", "report-only analysis (default)").option("--fix", "remove exact-duplicate lines (confirm-gated; shows a diff before writing)").option("--yes", "apply --fix changes without prompting (non-interactive)").action(guard(cmdMemory));
|
|
19320
19291
|
program2.command("waste").description("session spend-ledger: token cost per tool/file from the current Claude Code session transcript, plus waste signals").option("--project <path>", "project root to analyze").option("--transcript <path>", "explicit transcript JSONL path (default: most-recently-modified transcript for this project)").option("--top <n>", "number of top expensive tool calls to show (default: 10)").option("--copilot", "analyze a Copilot CLI session event log instead, reporting Copilot's own token split").option("--json", "output JSON").action(guard(cmdWaste));
|
|
19292
|
+
program2.command("audit").description("session retrospective: analyze the current session transcript (Copilot CLI or Claude Code) and emit a Maintainer Feedback Card").option("--project <path>", "project root to analyze").option("--transcript <path>", "explicit transcript path (default: active or newest session for this project)").option("-j, --json", "output as JSON").action(guard(cmdAudit));
|
|
19321
19293
|
program2.command("session-outline [session-id-or-path]").description("turn-by-turn structure (role, preview, tool calls, approx size) of a Claude Code session JSONL transcript, instead of a raw Read; defaults to the current project's most recent session").option("--project <path>", "project root to resolve the session transcript against").option("--json", "output JSON").action(guard(cmdSessionOutline));
|
|
19322
19294
|
program2.command("session-slice [session-id-or-path]").description("full content of one turn range from a Claude Code session JSONL transcript (see session-outline for turn numbers), instead of a raw Read").requiredOption("--range <spec>", "turn range, e.g. 5-9 or 12 (see session-outline for turn numbers)").option("--project <path>", "project root to resolve the session transcript against").option("--json", "output JSON").action(guard(cmdSessionSlice));
|
|
19323
19295
|
program2.command("session-audit").alias("audit-session").description("corpus-wide token attribution across every local Claude Code session transcript: measured billed usage, estimated content size by source and by tool, and billed cost by session position (aggregate counts only, never transcript content)").option("--dir <path>", "transcript corpus root to scan (default: ~/.claude/projects)").option("--json", "output JSON").action(guard(cmdSessionAudit));
|
|
@@ -19432,16 +19404,15 @@ var BRIDGE_CAPABILITY_MATRIX = [
|
|
|
19432
19404
|
harness: "codex",
|
|
19433
19405
|
label: "Codex CLI",
|
|
19434
19406
|
sourceFile: "src/bridges/codex_install.ts (CODEX_HOOK_EVENTS, CODEX_GLOBAL_HOOK_EVENTS)",
|
|
19435
|
-
verification: "
|
|
19436
|
-
verificationNote:
|
|
19407
|
+
verification: "dogfooded",
|
|
19408
|
+
verificationNote: `codex-cli 0.155.0, 2026-09-22: observed running the installed config.toml hooks and delivering real payloads to the shim -- PreToolUse/PostToolUse with tool_name "Bash" and tool_input.command, and PreCompact with trigger "auto" from a forced auto-compaction. A pre-tool deny was honored (the model dropped Get-Content and ran token-goat outline instead) and post-tool additionalContext reached the model; the pre-compact response did not, which is why codex is in PRE_COMPACT_CONTEXT_DROPPED. Two conditions gate the tool events and both fail silently. config.toml must carry the matching [hooks.state] trusted_hash the installer writes, and the matcher must name the tool as it appears on the hook wire -- "Bash" for shell execution, since Codex normalizes its own exec tool into Claude Code's vocabulary before matching, while apply_patch stays native. A matcher naming the internal spelling produced a run with eight pre_compact rows and no pre_tool_use or post_tool_use row at all, and that also stranded every queued compaction manifest. Verified end to end after the fix: a forced auto-compaction run recorded eight compactions and twelve manifest deliveries in its own rollout transcript.`,
|
|
19437
19409
|
implemented: /* @__PURE__ */ new Set(["pre_tool_use", "post_tool_use", "pre_compact", "user_prompt_submit", "subagent_stop"]),
|
|
19438
19410
|
reasons: [
|
|
19439
19411
|
{ events: ["post_tool_use_failure"], reason: NO_SEPARATE_FAILURE_EVENT_REASON },
|
|
19440
|
-
{ events: ["post_compact"], reason: NO_POST_COMPACT_EVENT_REASON },
|
|
19441
19412
|
{ events: ["notification", "stop"], reason: NO_SERVER_HANDLER_REASON },
|
|
19442
19413
|
{
|
|
19443
|
-
events: ["session_start"],
|
|
19444
|
-
reason: "Codex CLI
|
|
19414
|
+
events: ["post_compact", "session_start"],
|
|
19415
|
+
reason: "Codex CLI 0.155.0 does declare PostCompact and SessionStart -- both appear in the hook-event enum next to PreToolUse and PreCompact, so the earlier claim that it had no session-start equivalent and no post-compact event was wrong. They stay unwired for the reason the rest of this table applies: neither channel has been measured. The post-compact input has no summary field anywhere in the binary's payload key list (session_id, turn_id, agent_id, agent_type, transcript_path, hook_event_name, model, permission_mode, trigger, tool_name, tool_input, tool_use_id), so postCompactHandler would have nothing to count, and whether SessionStart forwards additionalContext has not been run"
|
|
19445
19416
|
}
|
|
19446
19417
|
]
|
|
19447
19418
|
},
|
|
@@ -19582,7 +19553,7 @@ var BRIDGE_CAPABILITY_MATRIX = [
|
|
|
19582
19553
|
reasons: [
|
|
19583
19554
|
{
|
|
19584
19555
|
events: ["pre_compact", "post_tool_use_failure"],
|
|
19585
|
-
reason: "VS Code reads the shared Copilot hooks file but maps only sessionStart, sessionEnd, userPromptSubmitted, preToolUse, postToolUse, agentStop, subagentStop and errorOccurred out of it, so the file's preCompact and postToolUseFailure entries never fire there"
|
|
19556
|
+
reason: "VS Code reads the shared Copilot hooks file but maps only sessionStart, sessionEnd, userPromptSubmitted, preToolUse, postToolUse, agentStop, subagentStop and errorOccurred out of it, so the file's preCompact and postToolUseFailure entries never fire there. Re-read in the 1.138.0 bundle, where the github-copilot branch of that table still lists exactly those eight: the compaction manifest is unavailable on this harness rather than merely unwired, and unlike Copilot CLI and Codex there is no queueing fallback, because the trigger itself never arrives"
|
|
19586
19557
|
},
|
|
19587
19558
|
{ events: ["post_compact"], reason: NO_POST_COMPACT_EVENT_REASON },
|
|
19588
19559
|
{ events: ["notification", "stop"], reason: NO_SERVER_HANDLER_REASON }
|
|
@@ -19735,25 +19706,25 @@ function installVerificationNotice(harness) {
|
|
|
19735
19706
|
|
|
19736
19707
|
// src/purge.ts
|
|
19737
19708
|
init_define_import_meta_env();
|
|
19738
|
-
import * as
|
|
19739
|
-
import * as
|
|
19709
|
+
import * as fs43 from "node:fs";
|
|
19710
|
+
import * as path39 from "node:path";
|
|
19740
19711
|
function directorySize(root) {
|
|
19741
19712
|
let total = 0;
|
|
19742
19713
|
let entries;
|
|
19743
19714
|
try {
|
|
19744
|
-
entries =
|
|
19715
|
+
entries = fs43.readdirSync(root, { withFileTypes: true });
|
|
19745
19716
|
} catch {
|
|
19746
19717
|
return 0;
|
|
19747
19718
|
}
|
|
19748
19719
|
for (const entry of entries) {
|
|
19749
|
-
const full =
|
|
19720
|
+
const full = path39.join(root, entry.name);
|
|
19750
19721
|
if (entry.isDirectory()) {
|
|
19751
19722
|
total += directorySize(full);
|
|
19752
19723
|
continue;
|
|
19753
19724
|
}
|
|
19754
19725
|
if (!entry.isFile()) continue;
|
|
19755
19726
|
try {
|
|
19756
|
-
total +=
|
|
19727
|
+
total += fs43.statSync(full).size;
|
|
19757
19728
|
} catch {
|
|
19758
19729
|
}
|
|
19759
19730
|
}
|
|
@@ -19772,7 +19743,7 @@ function purgeDataDirectories() {
|
|
|
19772
19743
|
}
|
|
19773
19744
|
const bytes = directorySize(root);
|
|
19774
19745
|
try {
|
|
19775
|
-
|
|
19746
|
+
fs43.rmSync(root, { recursive: true, force: true });
|
|
19776
19747
|
result.removed.push({ path: root, bytes });
|
|
19777
19748
|
} catch (e) {
|
|
19778
19749
|
result.failed.push({ path: root, reason: e instanceof Error ? e.message : String(e) });
|
|
@@ -19919,8 +19890,8 @@ async function getSectionContent(fileId, heading, opts = {}) {
|
|
|
19919
19890
|
|
|
19920
19891
|
// src/cli_bench.ts
|
|
19921
19892
|
init_define_import_meta_env();
|
|
19922
|
-
import * as
|
|
19923
|
-
import * as
|
|
19893
|
+
import * as fs44 from "node:fs";
|
|
19894
|
+
import * as path40 from "node:path";
|
|
19924
19895
|
var ControlFilter = class extends ToolFilter {
|
|
19925
19896
|
constructor(name, transform) {
|
|
19926
19897
|
super();
|
|
@@ -19941,13 +19912,13 @@ var CONTROL_FILTERS = {
|
|
|
19941
19912
|
};
|
|
19942
19913
|
var MAX_BENCH_FILE_BYTES = 5 * 1024 * 1024;
|
|
19943
19914
|
function readCaseFile(id, filePath, what) {
|
|
19944
|
-
const bytes =
|
|
19915
|
+
const bytes = fs44.statSync(filePath).size;
|
|
19945
19916
|
if (bytes > MAX_BENCH_FILE_BYTES) {
|
|
19946
19917
|
throw new Error(
|
|
19947
19918
|
`bench case ${id}: ${what} is ${bytes} bytes, over the ${MAX_BENCH_FILE_BYTES}-byte limit for a corpus file (${filePath})`
|
|
19948
19919
|
);
|
|
19949
19920
|
}
|
|
19950
|
-
return
|
|
19921
|
+
return fs44.readFileSync(filePath, "utf8");
|
|
19951
19922
|
}
|
|
19952
19923
|
function parseCase(id, metaPath, outputPath) {
|
|
19953
19924
|
const metaText = readCaseFile(id, metaPath, "metadata");
|
|
@@ -19982,7 +19953,7 @@ function parseCase(id, metaPath, outputPath) {
|
|
|
19982
19953
|
function loadCorpus(dir) {
|
|
19983
19954
|
let entries;
|
|
19984
19955
|
try {
|
|
19985
|
-
entries =
|
|
19956
|
+
entries = fs44.readdirSync(dir);
|
|
19986
19957
|
} catch {
|
|
19987
19958
|
throw new Error(`bench corpus not found: ${dir}`);
|
|
19988
19959
|
}
|
|
@@ -19990,9 +19961,9 @@ function loadCorpus(dir) {
|
|
|
19990
19961
|
for (const entry of entries.sort()) {
|
|
19991
19962
|
if (!entry.endsWith(".json")) continue;
|
|
19992
19963
|
const id = entry.slice(0, -".json".length);
|
|
19993
|
-
const outputPath =
|
|
19994
|
-
if (!
|
|
19995
|
-
cases.push(parseCase(id,
|
|
19964
|
+
const outputPath = path40.join(dir, `${id}.txt`);
|
|
19965
|
+
if (!fs44.existsSync(outputPath)) throw new Error(`bench case ${id}: missing output file ${outputPath}`);
|
|
19966
|
+
cases.push(parseCase(id, path40.join(dir, entry), outputPath));
|
|
19996
19967
|
}
|
|
19997
19968
|
if (cases.length === 0) throw new Error(`bench corpus is empty: ${dir}`);
|
|
19998
19969
|
return cases;
|
|
@@ -20112,10 +20083,10 @@ function appendTsv(file, report, commit) {
|
|
|
20112
20083
|
report.mustKeepTotal,
|
|
20113
20084
|
report.coveredFilters
|
|
20114
20085
|
].join(" ");
|
|
20115
|
-
const dir =
|
|
20116
|
-
|
|
20117
|
-
const header =
|
|
20118
|
-
|
|
20086
|
+
const dir = path40.dirname(path40.resolve(file));
|
|
20087
|
+
fs44.mkdirSync(dir, { recursive: true });
|
|
20088
|
+
const header = fs44.existsSync(file) ? "" : TSV_HEADER;
|
|
20089
|
+
fs44.appendFileSync(file, header + row + "\n", "utf8");
|
|
20119
20090
|
}
|
|
20120
20091
|
function currentCommit(cwd) {
|
|
20121
20092
|
const opts = cwd === void 0 ? {} : { cwd };
|
|
@@ -20144,7 +20115,7 @@ function runBenchCommand(opts) {
|
|
|
20144
20115
|
var CliError = class extends Error {
|
|
20145
20116
|
};
|
|
20146
20117
|
function out(text) {
|
|
20147
|
-
const payload = colorStdout() ? text :
|
|
20118
|
+
const payload = colorStdout() ? text : stripAnsiEscapes(text);
|
|
20148
20119
|
process.stdout.write(ensureNewline(payload));
|
|
20149
20120
|
}
|
|
20150
20121
|
function err(text) {
|
|
@@ -20155,10 +20126,10 @@ function readBoundedText(text, file) {
|
|
|
20155
20126
|
if (text === void 0 && file === void 0) throw new CliError("provide text or --file");
|
|
20156
20127
|
let value;
|
|
20157
20128
|
if (file !== void 0) {
|
|
20158
|
-
if (
|
|
20129
|
+
if (fs45.statSync(file).size > CONTENT_MAX_INPUT_CHARS) {
|
|
20159
20130
|
throw new CliError(`file exceeds the ${CONTENT_MAX_INPUT_CHARS}-byte safety limit`);
|
|
20160
20131
|
}
|
|
20161
|
-
value =
|
|
20132
|
+
value = fs45.readFileSync(file, "utf8");
|
|
20162
20133
|
} else {
|
|
20163
20134
|
if (text === void 0) throw new CliError("provide text or --file");
|
|
20164
20135
|
value = text;
|
|
@@ -20203,35 +20174,11 @@ function cmdHandoffResolve(name, opts) {
|
|
|
20203
20174
|
if (result === null) throw new CliError(`no local handoff named "${name}" in this project`);
|
|
20204
20175
|
out(typeof result === "string" ? result : formatCompression(result, false, "payload withheld: inlining it would cost more tokens than the original text; pass --full to get the original text back outright"));
|
|
20205
20176
|
}
|
|
20206
|
-
function requireInt2(flag, raw) {
|
|
20207
|
-
if (!/^-?\d+$/.test(raw)) {
|
|
20208
|
-
throw new CliError(`${flag} must be a number, got: "${raw}"`);
|
|
20209
|
-
}
|
|
20210
|
-
const n = Number.parseInt(raw, 10);
|
|
20211
|
-
if (!Number.isFinite(n)) {
|
|
20212
|
-
throw new CliError(`${flag} must be a number, got: "${raw}"`);
|
|
20213
|
-
}
|
|
20214
|
-
return n;
|
|
20215
|
-
}
|
|
20216
|
-
function requireNonNegativeInt2(flag, raw) {
|
|
20217
|
-
const n = requireInt2(flag, raw);
|
|
20218
|
-
if (n < 0) {
|
|
20219
|
-
throw new CliError(`${flag} must be a non-negative number, got: "${raw}"`);
|
|
20220
|
-
}
|
|
20221
|
-
return n;
|
|
20222
|
-
}
|
|
20223
|
-
function requirePositiveInt2(flag, raw) {
|
|
20224
|
-
const n = requireInt2(flag, raw);
|
|
20225
|
-
if (n <= 0) {
|
|
20226
|
-
throw new CliError(`${flag} must be a positive number, got: "${raw}"`);
|
|
20227
|
-
}
|
|
20228
|
-
return n;
|
|
20229
|
-
}
|
|
20230
20177
|
async function cmdSemantic(query, opts) {
|
|
20231
20178
|
if (!query && !opts.preflight && !opts.warm) {
|
|
20232
20179
|
throw new CliError("missing required argument: query");
|
|
20233
20180
|
}
|
|
20234
|
-
const limit = opts.limit !== void 0 ?
|
|
20181
|
+
const limit = opts.limit !== void 0 ? requireNonNegativeInt("--limit", opts.limit) : 20;
|
|
20235
20182
|
const { text, code } = await runSemantic(query ?? "", {
|
|
20236
20183
|
limit,
|
|
20237
20184
|
...opts.json === true ? { json: true } : {},
|
|
@@ -20268,7 +20215,7 @@ async function cmdIndex(pathArg, opts = {}) {
|
|
|
20268
20215
|
const ixCfg = loadConfig().indexing;
|
|
20269
20216
|
if ((loadConfig().indexing?.embeddings_enabled ?? true) && embeddingsDepsAvailable(getDb(dbPath))) {
|
|
20270
20217
|
ensureEmbeddingProvenance(getDb(dbPath));
|
|
20271
|
-
pruneUnembeddableChunks(getDb(dbPath), ixCfg.max_chunks_per_file, deleteFileEmbeddings);
|
|
20218
|
+
pruneUnembeddableChunks(getDb(dbPath), ixCfg.max_chunks_per_file, deleteFileEmbeddings, { asset: assetEmbedSha, maxChunks: maxChunksEmbedSha });
|
|
20272
20219
|
}
|
|
20273
20220
|
let indexed = 0;
|
|
20274
20221
|
let failed = 0;
|
|
@@ -20305,7 +20252,8 @@ async function cmdIndex(pathArg, opts = {}) {
|
|
|
20305
20252
|
continue;
|
|
20306
20253
|
}
|
|
20307
20254
|
const sha = fingerprintFile(key);
|
|
20308
|
-
if (sha === null && !
|
|
20255
|
+
if (sha === null && !fs45.existsSync(key)) continue;
|
|
20256
|
+
recordKnownRootThrottled(key, dataDir(), dbPath);
|
|
20309
20257
|
const entry = sha !== null ? getFileEntry(key, dbPath) : null;
|
|
20310
20258
|
const spellingStale = entry !== null && indexedPathSpellingIsStale(entry.filePath, key);
|
|
20311
20259
|
const parseUnchanged = !force && !spellingStale && sha !== null && entry?.sha === sha && entry.parserSha === parserFingerprintForLanguage(entry.language);
|
|
@@ -20341,7 +20289,7 @@ async function cmdIndex(pathArg, opts = {}) {
|
|
|
20341
20289
|
}
|
|
20342
20290
|
continue;
|
|
20343
20291
|
}
|
|
20344
|
-
if (!
|
|
20292
|
+
if (!fs45.existsSync(key)) continue;
|
|
20345
20293
|
}
|
|
20346
20294
|
const embedFresh = parseUnchanged ? embedUnchanged : embedFreshFor(getFileEntry(key, dbPath)?.embedSha);
|
|
20347
20295
|
if (!embedFresh) {
|
|
@@ -20402,7 +20350,7 @@ async function cmdMcpServe() {
|
|
|
20402
20350
|
let StdioServerTransport;
|
|
20403
20351
|
try {
|
|
20404
20352
|
;
|
|
20405
|
-
({ createMcpServer } = await import("./token-goat-chunk-
|
|
20353
|
+
({ createMcpServer } = await import("./token-goat-chunk-3OGZOFLS.mjs"));
|
|
20406
20354
|
({ StdioServerTransport } = await import("./token-goat-chunk-EVC4TOLE.mjs"));
|
|
20407
20355
|
} catch (err2) {
|
|
20408
20356
|
process.stderr.write(
|
|
@@ -20427,11 +20375,11 @@ async function cmdHook(event, opts) {
|
|
|
20427
20375
|
if (typeof opts.harness === "string" && opts.harness.length > 0) {
|
|
20428
20376
|
process.env[ENV_KEYS.HARNESS_OVERRIDE] = opts.harness;
|
|
20429
20377
|
}
|
|
20430
|
-
const { relay } = await import("./token-goat-chunk-
|
|
20378
|
+
const { relay } = await import("./token-goat-chunk-G6SYQQO7.mjs");
|
|
20431
20379
|
await relay(event);
|
|
20432
20380
|
}
|
|
20433
20381
|
function projectHooksCommitNote(pathFiles, hooksConfigPath) {
|
|
20434
|
-
const shim = hooksConfigPath === void 0 ? "" : ` (${displaySafePath(
|
|
20382
|
+
const shim = hooksConfigPath === void 0 ? "" : ` (${displaySafePath(path41.join(path41.dirname(hooksConfigPath), HOOKS_SCRIPT_FILE))} is generated with them)`;
|
|
20435
20383
|
return `Note: ${pathFiles.map((p) => displaySafePath(p)).join(", ")} ${pathFiles.length === 1 ? "holds" : "hold"} absolute paths to node and token-goat on this machine${shim}, so do not commit them: list them in .git/info/exclude or .gitignore.`;
|
|
20436
20384
|
}
|
|
20437
20385
|
function visualStudioManualSteps(scope) {
|
|
@@ -20464,7 +20412,7 @@ async function cmdInstall(opts) {
|
|
|
20464
20412
|
if (opts.project === true && opts.user === true) {
|
|
20465
20413
|
throw new Error("install takes either -p/--project or --user, not both.");
|
|
20466
20414
|
}
|
|
20467
|
-
await import("./token-goat-chunk-
|
|
20415
|
+
await import("./token-goat-chunk-G6SYQQO7.mjs");
|
|
20468
20416
|
const scope = opts.project === true ? "project" : "user";
|
|
20469
20417
|
if (wantsClaudeCodeBase(opts)) {
|
|
20470
20418
|
const result = installHooks(scope);
|
|
@@ -20610,16 +20558,16 @@ async function cmdInstall(opts) {
|
|
|
20610
20558
|
);
|
|
20611
20559
|
}
|
|
20612
20560
|
try {
|
|
20613
|
-
const skillDir2 =
|
|
20614
|
-
if (
|
|
20615
|
-
const entries =
|
|
20561
|
+
const skillDir2 = path41.join(claudeConfigDir(), "skills");
|
|
20562
|
+
if (fs45.existsSync(skillDir2)) {
|
|
20563
|
+
const entries = fs45.readdirSync(skillDir2, { withFileTypes: true });
|
|
20616
20564
|
const skillNames = [];
|
|
20617
20565
|
const sessionId = getSessionId();
|
|
20618
20566
|
for (const entry of entries) {
|
|
20619
20567
|
if (!entry.isDirectory()) continue;
|
|
20620
|
-
const skillFile =
|
|
20621
|
-
if (
|
|
20622
|
-
const body =
|
|
20568
|
+
const skillFile = path41.join(skillDir2, entry.name, "SKILL.md");
|
|
20569
|
+
if (fs45.existsSync(skillFile)) {
|
|
20570
|
+
const body = fs45.readFileSync(skillFile, "utf-8");
|
|
20623
20571
|
const compact = extractCompactFromMarker(body);
|
|
20624
20572
|
if (compact === null) continue;
|
|
20625
20573
|
const sourceSha = contentHash(body);
|
|
@@ -20630,9 +20578,9 @@ async function cmdInstall(opts) {
|
|
|
20630
20578
|
if (skillNames.length > 0) {
|
|
20631
20579
|
const dir = skillOutputsDir();
|
|
20632
20580
|
ensureDirSync(dir);
|
|
20633
|
-
const pregenPath =
|
|
20581
|
+
const pregenPath = path41.join(dir, "pregen.json");
|
|
20634
20582
|
const pregenData = { ts: Date.now(), names: skillNames };
|
|
20635
|
-
await
|
|
20583
|
+
await fs45.promises.writeFile(pregenPath, JSON.stringify(pregenData, null, 2));
|
|
20636
20584
|
out(`Pre-generated ${skillNames.length} skill compacts.`);
|
|
20637
20585
|
}
|
|
20638
20586
|
}
|
|
@@ -20772,7 +20720,7 @@ function cmdWorkerStatus() {
|
|
|
20772
20720
|
out(isWorkerRunning() ? "Worker is running." : "Worker is not running.");
|
|
20773
20721
|
}
|
|
20774
20722
|
function cmdStats(opts = {}) {
|
|
20775
|
-
const windowDays = opts.windowDays !== void 0 ?
|
|
20723
|
+
const windowDays = opts.windowDays !== void 0 ? requireNonNegativeInt("--window-days", opts.windowDays) : 30;
|
|
20776
20724
|
const statsOpts = {
|
|
20777
20725
|
json: opts.json === true,
|
|
20778
20726
|
windowDays,
|
|
@@ -20812,7 +20760,7 @@ async function cmdDoctor(opts) {
|
|
|
20812
20760
|
}
|
|
20813
20761
|
}
|
|
20814
20762
|
function _applyFiltersAndPrint(content, opts, fenceByProvenance = false, fenceTag = UNTRUSTED_WEB_TAG) {
|
|
20815
|
-
const
|
|
20763
|
+
const emit2 = (text) => {
|
|
20816
20764
|
if (!fenceByProvenance || text === "") {
|
|
20817
20765
|
out(text);
|
|
20818
20766
|
return text;
|
|
@@ -20843,7 +20791,7 @@ function _applyFiltersAndPrint(content, opts, fenceByProvenance = false, fenceTa
|
|
|
20843
20791
|
}
|
|
20844
20792
|
}
|
|
20845
20793
|
if (opts.grep !== void 0 && opts.maxMatches !== void 0) {
|
|
20846
|
-
const cap =
|
|
20794
|
+
const cap = requireNonNegativeInt("--max-matches", opts.maxMatches);
|
|
20847
20795
|
const matched = content === "" ? [] : content.split(/\r?\n/);
|
|
20848
20796
|
if (matched.length > cap) {
|
|
20849
20797
|
content = [...matched.slice(0, cap), "[token-goat: showing first " + cap + " of " + matched.length + " matching lines; raise --max-matches for more]"].join("\n");
|
|
@@ -20851,11 +20799,11 @@ function _applyFiltersAndPrint(content, opts, fenceByProvenance = false, fenceTa
|
|
|
20851
20799
|
}
|
|
20852
20800
|
const rawLines = content.split(/\r?\n/);
|
|
20853
20801
|
if (opts.full === true) {
|
|
20854
|
-
return
|
|
20802
|
+
return emit2(rawLines.join("\n"));
|
|
20855
20803
|
}
|
|
20856
20804
|
const lines = rawLines.length > 1 && rawLines[rawLines.length - 1] === "" ? rawLines.slice(0, -1) : rawLines;
|
|
20857
|
-
const headN = opts.head !== void 0 ?
|
|
20858
|
-
const tailN = opts.tail !== void 0 ?
|
|
20805
|
+
const headN = opts.head !== void 0 ? requireNonNegativeInt("--head", opts.head) : 30;
|
|
20806
|
+
const tailN = opts.tail !== void 0 ? requireNonNegativeInt("--tail", opts.tail) : 80;
|
|
20859
20807
|
const applyElision = (lines2, headN2, tailN2) => lines2.length > headN2 + tailN2 + 1 ? [...lines2.slice(0, headN2), "...(elided)...", ...lines2.slice(lines2.length - tailN2)] : lines2;
|
|
20860
20808
|
const noteLineCap = (which, flag, shown, total) => {
|
|
20861
20809
|
if (shown >= total) return;
|
|
@@ -20874,7 +20822,7 @@ function _applyFiltersAndPrint(content, opts, fenceByProvenance = false, fenceTa
|
|
|
20874
20822
|
result = lines.slice(Math.max(0, lines.length - tailN));
|
|
20875
20823
|
noteLineCap("last", "tail", result.length, lines.length);
|
|
20876
20824
|
}
|
|
20877
|
-
return
|
|
20825
|
+
return emit2(result.join("\n"));
|
|
20878
20826
|
}
|
|
20879
20827
|
function cmdBashOutput(id, opts) {
|
|
20880
20828
|
const parseVerifyThreshold = (optVal) => {
|
|
@@ -20895,7 +20843,7 @@ function cmdBashOutput(id, opts) {
|
|
|
20895
20843
|
}
|
|
20896
20844
|
let content;
|
|
20897
20845
|
try {
|
|
20898
|
-
const st =
|
|
20846
|
+
const st = fs45.statSync(opts.file);
|
|
20899
20847
|
if (st.isFIFO() || st.isSocket()) {
|
|
20900
20848
|
throw new CliError(`--file '${opts.file}' is a special file (FIFO or socket) \u2014 only regular files are supported`);
|
|
20901
20849
|
}
|
|
@@ -20910,7 +20858,7 @@ function cmdBashOutput(id, opts) {
|
|
|
20910
20858
|
`);
|
|
20911
20859
|
}
|
|
20912
20860
|
}
|
|
20913
|
-
content = redactIfDotenv(opts.file, decodeSource(
|
|
20861
|
+
content = redactIfDotenv(opts.file, decodeSource(fs45.readFileSync(opts.file)));
|
|
20914
20862
|
} catch (e) {
|
|
20915
20863
|
if (e instanceof CliError) throw e;
|
|
20916
20864
|
throw new CliError(`cannot read file: ${opts.file}`);
|
|
@@ -20974,15 +20922,15 @@ function cmdMcpOutput(id, opts) {
|
|
|
20974
20922
|
if (opts.file.includes("\0")) {
|
|
20975
20923
|
throw new CliError("--file path contains a null byte");
|
|
20976
20924
|
}
|
|
20977
|
-
if (!
|
|
20925
|
+
if (!fs45.existsSync(opts.file)) {
|
|
20978
20926
|
throw new CliError(`file not found: ${opts.file}`);
|
|
20979
20927
|
}
|
|
20980
20928
|
try {
|
|
20981
|
-
const st =
|
|
20929
|
+
const st = fs45.statSync(opts.file);
|
|
20982
20930
|
if (st.isFIFO() || st.isSocket()) {
|
|
20983
20931
|
throw new CliError(`--file '${opts.file}' is a special file (FIFO or socket) \u2014 only regular files are supported`);
|
|
20984
20932
|
}
|
|
20985
|
-
content = decodeSource(
|
|
20933
|
+
content = decodeSource(fs45.readFileSync(opts.file));
|
|
20986
20934
|
} catch (e) {
|
|
20987
20935
|
if (e instanceof CliError) throw e;
|
|
20988
20936
|
throw new CliError(`cannot read file: ${opts.file}`);
|
|
@@ -21003,7 +20951,7 @@ function cmdMcpOutput(id, opts) {
|
|
|
21003
20951
|
const data = extractJsonFromMcpOutput(content);
|
|
21004
20952
|
let head;
|
|
21005
20953
|
if (opts.head !== void 0) {
|
|
21006
|
-
head =
|
|
20954
|
+
head = requireNonNegativeInt("--head", opts.head);
|
|
21007
20955
|
}
|
|
21008
20956
|
const queryResult = queryJson(data, opts.jsonQuery);
|
|
21009
20957
|
const { head: _omittedHead, ...restOpts } = opts;
|
|
@@ -21055,12 +21003,12 @@ async function cmdCompress(commandArgs, opts = {}) {
|
|
|
21055
21003
|
process.exitCode = 1;
|
|
21056
21004
|
return;
|
|
21057
21005
|
}
|
|
21058
|
-
const bashRunner = await import("./token-goat-chunk-
|
|
21006
|
+
const bashRunner = await import("./token-goat-chunk-CBXLE54Q.mjs");
|
|
21059
21007
|
if (opts.compress === false) {
|
|
21060
21008
|
process.exitCode = bashRunner.runRaw(command, parseTimeout(opts.timeout, bashRunner.DEFAULT_TIMEOUT_SECONDS));
|
|
21061
21009
|
return;
|
|
21062
21010
|
}
|
|
21063
|
-
const maxTokens = opts.maxTokens !== void 0 ?
|
|
21011
|
+
const maxTokens = opts.maxTokens !== void 0 ? requireNonNegativeInt("--max-tokens", opts.maxTokens) : 0;
|
|
21064
21012
|
process.exitCode = await bashRunner.run(command, {
|
|
21065
21013
|
filterName: opts.filter,
|
|
21066
21014
|
timeout: parseTimeout(opts.timeout, bashRunner.DEFAULT_TIMEOUT_SECONDS),
|
|
@@ -21160,7 +21108,7 @@ function buildProgram() {
|
|
|
21160
21108
|
more,
|
|
21161
21109
|
() => runSymbol({
|
|
21162
21110
|
...name !== void 0 ? { name } : {},
|
|
21163
|
-
limit: opts.limit !== void 0 ?
|
|
21111
|
+
limit: opts.limit !== void 0 ? requireNonNegativeInt("--limit", opts.limit) : 20,
|
|
21164
21112
|
...opts.file !== void 0 ? { file: opts.file } : {},
|
|
21165
21113
|
...opts.kind !== void 0 ? { kind: opts.kind } : {},
|
|
21166
21114
|
...projectRoot !== void 0 ? { projectRoot } : {},
|
|
@@ -21202,8 +21150,8 @@ function buildProgram() {
|
|
|
21202
21150
|
return runBrief({
|
|
21203
21151
|
spec,
|
|
21204
21152
|
...opts.json === true ? { json: true } : {},
|
|
21205
|
-
...opts.limit !== void 0 ? { limit:
|
|
21206
|
-
...opts.context !== void 0 ? { context:
|
|
21153
|
+
...opts.limit !== void 0 ? { limit: requireNonNegativeInt("--limit", opts.limit) } : {},
|
|
21154
|
+
...opts.context !== void 0 ? { context: requireNonNegativeInt("--context", opts.context) } : {},
|
|
21207
21155
|
...opts.excludeTests === true ? { excludeTests: true } : {},
|
|
21208
21156
|
...opts.grep !== void 0 ? { grep: opts.grep } : {}
|
|
21209
21157
|
});
|
|
@@ -21211,14 +21159,26 @@ function buildProgram() {
|
|
|
21211
21159
|
);
|
|
21212
21160
|
program2.command("section <spec> [more...]").description(
|
|
21213
21161
|
'read one section from a file (spec: file::heading, or file::<unambiguous heading prefix> \u2014 e.g. "Lesson 16" resolves a longer unique heading; comma-separated file::A,B for a merged multi-heading view), or list all sections with --list'
|
|
21214
|
-
).option("-j, --json", "output as JSON").option("--list", "list all section headings in the file instead of reading one").option("--grep <pattern>", "with --list, filter headings to this regex (literal substring if it is not valid regex)").action(
|
|
21215
|
-
|
|
21162
|
+
).option("-j, --json", "output as JSON").option("--list", "list all section headings in the file instead of reading one").option("--grep <pattern>", "with --list, filter headings to this regex (literal substring if it is not valid regex)").option("--max-lines <n>", "limit returned section content to at most N lines from the top").option("--head <n>", "alias for --max-lines").action((spec, more, opts) => {
|
|
21163
|
+
const maxLinesRaw = opts.maxLines ?? opts.head;
|
|
21164
|
+
const maxLines = maxLinesRaw !== void 0 ? requireNonNegativeInt("--max-lines", maxLinesRaw) : void 0;
|
|
21165
|
+
return opts.list === true ? runExit(() => {
|
|
21216
21166
|
emitExtraFileArgsNote("section --list", spec, more, { mergeable: false });
|
|
21217
21167
|
return runListSections({ file: spec, ...opts.json === true ? { json: true } : {}, ...opts.grep !== void 0 ? { grep: opts.grep } : {} });
|
|
21218
21168
|
}) : runExitText(
|
|
21219
|
-
() => noteExtraFileArgs(
|
|
21220
|
-
|
|
21221
|
-
|
|
21169
|
+
() => noteExtraFileArgs(
|
|
21170
|
+
"section",
|
|
21171
|
+
spec,
|
|
21172
|
+
more,
|
|
21173
|
+
() => runSection({
|
|
21174
|
+
spec,
|
|
21175
|
+
...opts.json === true ? { json: true } : {},
|
|
21176
|
+
...maxLines !== void 0 ? { maxLines } : {}
|
|
21177
|
+
}),
|
|
21178
|
+
{ noun: "spec", mergeable: namedSpecsMergeable([spec, ...more]) }
|
|
21179
|
+
)
|
|
21180
|
+
);
|
|
21181
|
+
});
|
|
21222
21182
|
program2.command("semantic [query]").description("semantic search (falls back to full-text search)").option("-l, --limit <n>", "max results").option("-j, --json", "output as JSON").option("--grep <pattern>", "filter to hits whose file path matches this regex (literal substring if it is not valid regex); matched against the path as rendered").option("--exclude-tests", "hide hits whose file is a test file (opt-in; default output is unchanged)").option("--preflight", "run semantic embedding preflight check and exit").option("--warm", "warm up the embedding model session in memory").action(guard(cmdSemantic));
|
|
21223
21183
|
const registerSymbolListing = (name, description, run2) => {
|
|
21224
21184
|
program2.command(`${name} <file> [more...]`).description(description).option("-j, --json", "output as JSON").option("--min-lines <n>", "only show symbols at least N lines long").option("--grep <pattern>", "only show symbols whose name matches this regex (literal substring if it is not valid regex)").option("--force-refresh", "reparse file from disk before querying (ignore stale index)").option("--stats", "add per-symbol reference count and doc-coverage flag").action(
|
|
@@ -21230,7 +21190,7 @@ function buildProgram() {
|
|
|
21230
21190
|
() => run2({
|
|
21231
21191
|
file,
|
|
21232
21192
|
...opts.json === true ? { json: true } : {},
|
|
21233
|
-
...opts.minLines !== void 0 ? { minLines:
|
|
21193
|
+
...opts.minLines !== void 0 ? { minLines: requireNonNegativeInt("--min-lines", opts.minLines) } : {},
|
|
21234
21194
|
...opts.grep !== void 0 ? { grep: opts.grep } : {},
|
|
21235
21195
|
...opts.forceRefresh === true ? { forceRefresh: true } : {},
|
|
21236
21196
|
...opts.stats === true ? { stats: true } : {}
|
|
@@ -21259,9 +21219,9 @@ function buildProgram() {
|
|
|
21259
21219
|
spec,
|
|
21260
21220
|
...opts.callers === true ? { callers: true } : {},
|
|
21261
21221
|
...opts.json === true ? { json: true } : {},
|
|
21262
|
-
...opts.limit !== void 0 ? { limit:
|
|
21263
|
-
...opts.top !== void 0 ? { top:
|
|
21264
|
-
...opts.context !== void 0 ? { context:
|
|
21222
|
+
...opts.limit !== void 0 ? { limit: requireNonNegativeInt("--limit", opts.limit) } : {},
|
|
21223
|
+
...opts.top !== void 0 ? { top: requireNonNegativeInt("--top", opts.top) } : {},
|
|
21224
|
+
...opts.context !== void 0 ? { context: requireNonNegativeInt("--context", opts.context) } : {},
|
|
21265
21225
|
...opts.excludeTests === true ? { excludeTests: true } : {},
|
|
21266
21226
|
...opts.grep !== void 0 ? { grep: opts.grep } : {}
|
|
21267
21227
|
});
|
|
@@ -21275,7 +21235,7 @@ function buildProgram() {
|
|
|
21275
21235
|
program2.command("bench").description("replay a corpus of captured command output through the compressors; prints the byte savings ratio and a fidelity check, and exits 1 when a must-keep line was dropped").option("--corpus <dir>", "corpus directory (default: tests/fixtures/bench, relative to the working directory)").option("--tsv <path>", "append one result row, keyed by the current commit, creating the file and its header if absent").option("--validate", "score the corpus with control filters instead: proves the ratio has a floor and the fidelity guard can actually fail").option("-j, --json", "output as JSON").action(
|
|
21276
21236
|
(opts) => runExitText(
|
|
21277
21237
|
() => runBenchCommand({
|
|
21278
|
-
corpus: opts.corpus ??
|
|
21238
|
+
corpus: opts.corpus ?? path41.join("tests", "fixtures", "bench"),
|
|
21279
21239
|
...opts.tsv !== void 0 ? { tsv: opts.tsv } : {},
|
|
21280
21240
|
...opts.validate === true ? { validate: true } : {},
|
|
21281
21241
|
...opts.json === true ? { json: true } : {}
|
|
@@ -21309,7 +21269,7 @@ function buildProgram() {
|
|
|
21309
21269
|
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("-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("-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);
|
|
21310
21270
|
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(
|
|
21311
21271
|
(opts) => guard(async () => {
|
|
21312
|
-
const { cmdUpgrade } = await import("./token-goat-chunk-
|
|
21272
|
+
const { cmdUpgrade } = await import("./token-goat-chunk-AU2K2QHR.mjs");
|
|
21313
21273
|
await cmdUpgrade(opts, () => cmdInstall({}));
|
|
21314
21274
|
})()
|
|
21315
21275
|
);
|
|
@@ -21379,6 +21339,9 @@ async function run(argv = process.argv) {
|
|
|
21379
21339
|
}
|
|
21380
21340
|
|
|
21381
21341
|
export {
|
|
21342
|
+
requireInt,
|
|
21343
|
+
requireNonNegativeInt,
|
|
21344
|
+
requirePositiveInt,
|
|
21382
21345
|
expandGlobs,
|
|
21383
21346
|
fenceFileText,
|
|
21384
21347
|
fenceFileFieldIfMatched,
|
|
@@ -21438,9 +21401,6 @@ export {
|
|
|
21438
21401
|
CliError,
|
|
21439
21402
|
out,
|
|
21440
21403
|
err,
|
|
21441
|
-
requireInt2 as requireInt,
|
|
21442
|
-
requireNonNegativeInt2 as requireNonNegativeInt,
|
|
21443
|
-
requirePositiveInt2 as requirePositiveInt,
|
|
21444
21404
|
cmdIndex,
|
|
21445
21405
|
visualStudioManualSteps,
|
|
21446
21406
|
leftoverIntegrations,
|