token-goat 2.9.19 → 2.9.21
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-JNIFSVWM.mjs → token-goat-chunk-2ZHD3XCD.mjs} +5 -1
- package/dist/{token-goat-chunk-P46RTOAQ.mjs → token-goat-chunk-4IIU3GNS.mjs} +10 -7
- package/dist/{token-goat-chunk-2GTB5RBZ.mjs → token-goat-chunk-4V4OZHHV.mjs} +11 -271
- package/dist/token-goat-chunk-64OEF3UN.mjs +128 -0
- package/dist/{token-goat-chunk-AVRD7SBO.mjs → token-goat-chunk-6AQLZMCO.mjs} +270 -29
- package/dist/{token-goat-chunk-LACH3WKS.mjs → token-goat-chunk-BIEDTF6V.mjs} +3 -3
- package/dist/{token-goat-chunk-PIAESKVU.mjs → token-goat-chunk-BKHJRFDE.mjs} +568 -429
- package/dist/token-goat-chunk-CAHN4QU7.mjs +26 -0
- package/dist/{token-goat-chunk-MU6I4IDI.mjs → token-goat-chunk-CMAJGP3E.mjs} +11 -7
- package/dist/token-goat-chunk-CMHBTXMY.mjs +41 -0
- package/dist/{token-goat-chunk-HPMMLV37.mjs → token-goat-chunk-CZ5ZFJSN.mjs} +256 -341
- package/dist/{token-goat-chunk-7DGTVBWP.mjs → token-goat-chunk-DDP64XR7.mjs} +159 -1863
- package/dist/{token-goat-chunk-FX5DHKGF.mjs → token-goat-chunk-DISVHOW6.mjs} +4 -4
- package/dist/{token-goat-chunk-L2UOJBV4.mjs → token-goat-chunk-FZN77SZD.mjs} +27 -19
- package/dist/{token-goat-chunk-DA6TIDLI.mjs → token-goat-chunk-GO7OWONJ.mjs} +18 -13
- package/dist/{token-goat-chunk-EP7TCWHM.mjs → token-goat-chunk-IAMIQLCV.mjs} +83 -66
- package/dist/{token-goat-chunk-NJKNAC37.mjs → token-goat-chunk-IJUHQX2M.mjs} +1 -1
- package/dist/token-goat-chunk-KQI24O4B.mjs +292 -0
- package/dist/{token-goat-chunk-GYC34EGE.mjs → token-goat-chunk-KRPJIXCT.mjs} +2 -2
- package/dist/token-goat-chunk-KVAXTA2W.mjs +198 -0
- package/dist/{token-goat-chunk-FJZ5MZK7.mjs → token-goat-chunk-LK3YOKDF.mjs} +2 -2
- package/dist/token-goat-chunk-M43UJVYQ.mjs +1816 -0
- package/dist/{token-goat-chunk-SOKAPOOC.mjs → token-goat-chunk-M6CDVASA.mjs} +46 -47
- package/dist/token-goat-chunk-MECDAPXB.mjs +1989 -0
- package/dist/token-goat-chunk-MEKVJZUN.mjs +324 -0
- package/dist/token-goat-chunk-MQACN7VG.mjs +1379 -0
- package/dist/{token-goat-chunk-3W5P673V.mjs → token-goat-chunk-MZQORUX5.mjs} +1 -1
- package/dist/{token-goat-chunk-DHIXE6GV.mjs → token-goat-chunk-ORRDWKLA.mjs} +1 -1
- package/dist/{token-goat-chunk-F24NE3FO.mjs → token-goat-chunk-PCR43MCM.mjs} +2 -2
- package/dist/token-goat-chunk-PDYQA3AP.mjs +248 -0
- package/dist/{token-goat-chunk-S7RFIX4Y.mjs → token-goat-chunk-PHDNWISV.mjs} +45 -14
- package/dist/token-goat-chunk-PPYZS7TI.mjs +304 -0
- package/dist/{token-goat-chunk-BTKDZW7F.mjs → token-goat-chunk-QTIRVK3M.mjs} +1 -1
- package/dist/{token-goat-chunk-62VJ47WN.mjs → token-goat-chunk-QUM3UNWS.mjs} +5 -5
- package/dist/{token-goat-chunk-KWM6KBPA.mjs → token-goat-chunk-SHV6QQAS.mjs} +1 -1
- package/dist/{token-goat-chunk-FQYMZASI.mjs → token-goat-chunk-SMUYPBF5.mjs} +796 -4464
- package/dist/{token-goat-chunk-ZGQXRYKE.mjs → token-goat-chunk-TGBSMHPM.mjs} +1 -1
- package/dist/{token-goat-chunk-EXLLLIC3.mjs → token-goat-chunk-VXKT3W4C.mjs} +3 -3
- package/dist/{token-goat-chunk-WKO5TVNA.mjs → token-goat-chunk-XJUPKJF5.mjs} +544 -576
- package/dist/{token-goat-chunk-IBTFGZBX.mjs → token-goat-chunk-XQSSPX3X.mjs} +2 -2
- package/dist/{token-goat-chunk-VJQBYSXG.mjs → token-goat-chunk-ZJWPJL7O.mjs} +3 -3
- 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-KRPJIXCT.mjs";
|
|
6
|
+
import {
|
|
7
|
+
buildCopilotWasteReport,
|
|
8
|
+
findLatestCopilotSession,
|
|
9
|
+
findProjectSession,
|
|
10
|
+
isCopilotTranscript
|
|
11
|
+
} from "./token-goat-chunk-PPYZS7TI.mjs";
|
|
12
|
+
import {
|
|
13
|
+
buildResumePacket
|
|
14
|
+
} from "./token-goat-chunk-64OEF3UN.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,195 @@ import {
|
|
|
96
107
|
symbolNamesInFile,
|
|
97
108
|
upsertNote,
|
|
98
109
|
warnIfFilesStale
|
|
99
|
-
} from "./token-goat-chunk-
|
|
110
|
+
} from "./token-goat-chunk-BKHJRFDE.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-4V4OZHHV.mjs";
|
|
130
|
+
import {
|
|
131
|
+
buildWasteReport,
|
|
132
|
+
extractResultText,
|
|
133
|
+
findLatestTranscript,
|
|
134
|
+
projectTranscriptsDir,
|
|
135
|
+
safeStringify
|
|
136
|
+
} from "./token-goat-chunk-KQI24O4B.mjs";
|
|
137
|
+
import {
|
|
138
|
+
buildManifest
|
|
139
|
+
} from "./token-goat-chunk-PDYQA3AP.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
|
-
findOrphanedChunkPaths,
|
|
176
166
|
findSystemTempFiles,
|
|
177
167
|
findTopIndexedProjects,
|
|
178
|
-
formatAge,
|
|
179
|
-
formatBytes,
|
|
180
168
|
formatMemSuggestions,
|
|
181
169
|
formatProjectMap,
|
|
182
170
|
formatSymbolLocation,
|
|
183
|
-
formatTokenEstimate,
|
|
184
|
-
getContextPressure,
|
|
185
171
|
getDirtyPathsFor,
|
|
186
172
|
getEmbeddingCoverage,
|
|
187
173
|
getHintStatsSummary,
|
|
188
174
|
getHintStatsTotals,
|
|
189
175
|
getParserFreshness,
|
|
190
176
|
getProjectIndexCounts,
|
|
191
|
-
getSessionFiles,
|
|
192
|
-
getSessionId,
|
|
193
|
-
getSkillFilePath,
|
|
194
177
|
getTrackedFiles,
|
|
195
|
-
|
|
196
|
-
incrementSkillHit,
|
|
178
|
+
indexSizeBytes,
|
|
197
179
|
injectionFencingEnabled,
|
|
198
|
-
installCopilotCli,
|
|
199
|
-
installCopilotHooksFile,
|
|
200
|
-
installVisualStudio,
|
|
201
180
|
isCompactFresh,
|
|
202
|
-
isCopilotCliInstalled,
|
|
203
181
|
isHintCategory,
|
|
204
182
|
isIgnoredIndexPath,
|
|
205
|
-
isManagedServer,
|
|
206
183
|
isPrivateIpv4Octets,
|
|
207
184
|
isPrivateIpv6Groups,
|
|
208
|
-
isResidueServersJson,
|
|
209
185
|
isSuppressionCategory,
|
|
210
|
-
isVisualStudioInstalled,
|
|
211
186
|
isWorkerRunning,
|
|
212
|
-
jsonc,
|
|
213
|
-
listOutputs,
|
|
214
|
-
listSkills,
|
|
215
|
-
loadSessionCache,
|
|
216
|
-
managedServer,
|
|
217
187
|
mapLookupBytesSaved,
|
|
218
188
|
markCategoryEffective,
|
|
219
189
|
markCategoryIneffective,
|
|
220
190
|
pruneBlockedRoot,
|
|
221
191
|
pruneDeletedFiles,
|
|
222
|
-
pruneOrphanedChunks,
|
|
223
|
-
pruneSkillOutputs,
|
|
224
192
|
pruneSystemTempFiles,
|
|
225
193
|
pruneUnembeddableChunks,
|
|
226
194
|
readCompactBody,
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
readServersJson,
|
|
230
|
-
releaseCopilotHooksFile,
|
|
195
|
+
reclaimIndex,
|
|
196
|
+
recordKnownRootThrottled,
|
|
231
197
|
removeFileFromIndex,
|
|
232
198
|
resetHintStats,
|
|
233
199
|
runContextStats,
|
|
234
200
|
runDetachedWorkerDaemon,
|
|
235
201
|
scanAndRecord,
|
|
236
|
-
serversOf,
|
|
237
|
-
sessionsDir,
|
|
238
|
-
setTokenGoatServer,
|
|
239
202
|
shrinkImage,
|
|
240
|
-
skillDescriptionLine,
|
|
241
|
-
skillOutputsDir,
|
|
242
203
|
startDetachedWorker,
|
|
243
204
|
stopWorker,
|
|
244
|
-
|
|
245
|
-
storeOutput,
|
|
246
|
-
syncVisualStudioProjectGuidance,
|
|
205
|
+
sweepKnownRoots,
|
|
247
206
|
toolMatcherFor,
|
|
248
|
-
trimToBudget,
|
|
249
|
-
uninstallCopilotCli,
|
|
250
|
-
uninstallVisualStudio,
|
|
251
207
|
urlPolicyDenialReason,
|
|
252
208
|
visionTokensSavedByText,
|
|
209
|
+
walkProject,
|
|
210
|
+
writeCompact
|
|
211
|
+
} from "./token-goat-chunk-SMUYPBF5.mjs";
|
|
212
|
+
import {
|
|
213
|
+
CompressedOutput,
|
|
214
|
+
TOOL_FILTERS,
|
|
215
|
+
ToolFilter,
|
|
216
|
+
deliverCompressed,
|
|
217
|
+
detectFromCommand
|
|
218
|
+
} from "./token-goat-chunk-DDP64XR7.mjs";
|
|
219
|
+
import {
|
|
220
|
+
HOOKS_SCRIPT_FILE,
|
|
221
|
+
MATERIALIZE_SHRUNK_IMAGE_JS,
|
|
222
|
+
buildGuidanceBlock,
|
|
223
|
+
buildGuidanceBody,
|
|
224
|
+
bundledCliPath,
|
|
225
|
+
copilotCliConfigPath,
|
|
226
|
+
copilotCliMcpToolsDir,
|
|
227
|
+
copilotCliScriptPath,
|
|
228
|
+
copilotHooksFilePaths,
|
|
229
|
+
dropEmptyServers,
|
|
230
|
+
hasManagedServer,
|
|
231
|
+
installCopilotCli,
|
|
232
|
+
installCopilotHooksFile,
|
|
233
|
+
installVisualStudio,
|
|
234
|
+
isCopilotCliInstalled,
|
|
235
|
+
isManagedServer,
|
|
236
|
+
isResidueServersJson,
|
|
237
|
+
isVisualStudioInstalled,
|
|
238
|
+
jsonc,
|
|
239
|
+
managedServer,
|
|
240
|
+
readCopilotHooksOwners,
|
|
241
|
+
readServersJson,
|
|
242
|
+
releaseCopilotHooksFile,
|
|
243
|
+
serversOf,
|
|
244
|
+
setTokenGoatServer,
|
|
245
|
+
skillDescriptionLine,
|
|
246
|
+
syncVisualStudioProjectGuidance,
|
|
247
|
+
uninstallCopilotCli,
|
|
248
|
+
uninstallVisualStudio,
|
|
253
249
|
visualStudioDuplicateNote,
|
|
254
250
|
visualStudioManagedEntry,
|
|
255
251
|
visualStudioMcpStatus,
|
|
256
252
|
visualStudioOtherScopeHasManagedServer,
|
|
257
253
|
visualStudioProjectMcpPath,
|
|
258
254
|
visualStudioSolutionVscodeMcpPath,
|
|
259
|
-
visualStudioUserMcpPath
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
255
|
+
visualStudioUserMcpPath
|
|
256
|
+
} from "./token-goat-chunk-MQACN7VG.mjs";
|
|
257
|
+
import {
|
|
258
|
+
AGENT_SALT_MARKER,
|
|
259
|
+
CONTEXT_AUTOCOMPACT_TOKENS,
|
|
260
|
+
SESSIONS_SUBDIR,
|
|
261
|
+
SKILLS_OUTPUT_SUBDIR,
|
|
262
|
+
contentHash,
|
|
263
|
+
eventCount,
|
|
264
|
+
extractCompactFromMarker,
|
|
265
|
+
extractNamedSection,
|
|
266
|
+
findLatestSessionId,
|
|
267
|
+
formatAge,
|
|
268
|
+
getContextPressure,
|
|
269
|
+
getSessionFiles,
|
|
270
|
+
getSessionId,
|
|
271
|
+
getSkillFilePath,
|
|
272
|
+
incrementSkillHit,
|
|
273
|
+
listOutputs,
|
|
274
|
+
listSkills,
|
|
275
|
+
loadSessionCache,
|
|
276
|
+
loadSessionState,
|
|
277
|
+
pruneSkillOutputs,
|
|
278
|
+
sessionsDir,
|
|
279
|
+
skillOutputsDir,
|
|
280
|
+
storeCompact,
|
|
281
|
+
storeOutput
|
|
282
|
+
} from "./token-goat-chunk-MECDAPXB.mjs";
|
|
283
|
+
import {
|
|
284
|
+
capJsonRows,
|
|
285
|
+
claudeConfigDir,
|
|
286
|
+
estimateTokens,
|
|
287
|
+
estimateTokensFromLength,
|
|
288
|
+
formatBytes,
|
|
289
|
+
formatTokenEstimate,
|
|
290
|
+
trimToBudget
|
|
291
|
+
} from "./token-goat-chunk-MEKVJZUN.mjs";
|
|
263
292
|
import {
|
|
264
293
|
BASH_OUTPUT_SUBDIR,
|
|
265
|
-
CompressedOutput,
|
|
266
|
-
FILTERS,
|
|
267
|
-
TOOL_FILTERS,
|
|
268
|
-
ToolFilter,
|
|
269
294
|
clipLongMatchLine,
|
|
270
295
|
combineStreams,
|
|
271
|
-
deliverCompressed,
|
|
272
|
-
detectFromCommand,
|
|
273
296
|
getBashOutput,
|
|
274
297
|
isRecallCacheType
|
|
275
|
-
} from "./token-goat-chunk-
|
|
298
|
+
} from "./token-goat-chunk-M43UJVYQ.mjs";
|
|
276
299
|
import {
|
|
277
300
|
C,
|
|
278
301
|
DEFAULT_MAX_AGE_MS,
|
|
@@ -286,7 +309,6 @@ import {
|
|
|
286
309
|
formatLocalTimestamp,
|
|
287
310
|
getGlobalDb,
|
|
288
311
|
listBlobs,
|
|
289
|
-
loadBlob,
|
|
290
312
|
pruneBlobs,
|
|
291
313
|
pruneStalePatternCoveredUnmappedTools,
|
|
292
314
|
readUnmappedTools,
|
|
@@ -297,21 +319,21 @@ import {
|
|
|
297
319
|
savedTokensFromBytes,
|
|
298
320
|
statsHasDurationColumn,
|
|
299
321
|
statsHasHarnessColumn,
|
|
300
|
-
|
|
322
|
+
stripAnsiEscapes,
|
|
301
323
|
summarize
|
|
302
|
-
} from "./token-goat-chunk-
|
|
324
|
+
} from "./token-goat-chunk-PHDNWISV.mjs";
|
|
303
325
|
import {
|
|
304
326
|
docxOutline,
|
|
305
327
|
docxTables,
|
|
306
328
|
docxText,
|
|
307
329
|
formatDocxTables
|
|
308
|
-
} from "./token-goat-chunk-
|
|
330
|
+
} from "./token-goat-chunk-ORRDWKLA.mjs";
|
|
309
331
|
import {
|
|
310
332
|
pptxNotesText,
|
|
311
333
|
pptxOutline,
|
|
312
334
|
pptxSlideText,
|
|
313
335
|
pptxTextGrep
|
|
314
|
-
} from "./token-goat-chunk-
|
|
336
|
+
} from "./token-goat-chunk-MZQORUX5.mjs";
|
|
315
337
|
import {
|
|
316
338
|
formatXlsxColumns,
|
|
317
339
|
formatXlsxRange,
|
|
@@ -320,12 +342,13 @@ import {
|
|
|
320
342
|
querySheet,
|
|
321
343
|
rangeSheet,
|
|
322
344
|
xlsxColumns
|
|
323
|
-
} from "./token-goat-chunk-
|
|
345
|
+
} from "./token-goat-chunk-LK3YOKDF.mjs";
|
|
324
346
|
import {
|
|
325
347
|
formatCsvTable,
|
|
326
348
|
parseWhereSpecs
|
|
327
|
-
} from "./token-goat-chunk-
|
|
349
|
+
} from "./token-goat-chunk-SHV6QQAS.mjs";
|
|
328
350
|
import {
|
|
351
|
+
assetEmbedSha,
|
|
329
352
|
deleteFileEmbeddings,
|
|
330
353
|
embeddingBackendLoadError,
|
|
331
354
|
embeddingsDepsAvailable,
|
|
@@ -342,18 +365,19 @@ import {
|
|
|
342
365
|
isTreeSitterAvailable,
|
|
343
366
|
listSections,
|
|
344
367
|
loadRegexExtractors,
|
|
368
|
+
maxChunksEmbedSha,
|
|
345
369
|
missingTreeSitterGrammarPackages,
|
|
346
370
|
modelFilesPresent,
|
|
347
371
|
parserFingerprintForLanguage,
|
|
348
372
|
readSection,
|
|
349
373
|
treeSitterCoreAvailable,
|
|
350
374
|
treeSitterCoreLoadError
|
|
351
|
-
} from "./token-goat-chunk-
|
|
375
|
+
} from "./token-goat-chunk-IAMIQLCV.mjs";
|
|
352
376
|
import {
|
|
353
377
|
getFileEntry,
|
|
354
378
|
getProjectFileEntries,
|
|
355
379
|
querySymbols
|
|
356
|
-
} from "./token-goat-chunk-
|
|
380
|
+
} from "./token-goat-chunk-XQSSPX3X.mjs";
|
|
357
381
|
import {
|
|
358
382
|
TREE_SITTER_LANGUAGES,
|
|
359
383
|
detectLanguage,
|
|
@@ -364,7 +388,7 @@ import {
|
|
|
364
388
|
matchGroovySlashy,
|
|
365
389
|
nonTreeSitterLanguageCount,
|
|
366
390
|
redactIfDotenv
|
|
367
|
-
} from "./token-goat-chunk-
|
|
391
|
+
} from "./token-goat-chunk-2ZHD3XCD.mjs";
|
|
368
392
|
import {
|
|
369
393
|
CONFIG_KEY_ENV_OVERRIDES,
|
|
370
394
|
PROJECT_LOCKED_KEYS,
|
|
@@ -393,7 +417,7 @@ import {
|
|
|
393
417
|
stringify,
|
|
394
418
|
validateEnumField,
|
|
395
419
|
validateNumericField
|
|
396
|
-
} from "./token-goat-chunk-
|
|
420
|
+
} from "./token-goat-chunk-M6CDVASA.mjs";
|
|
397
421
|
import {
|
|
398
422
|
ENV_KEYS,
|
|
399
423
|
LOCK_WAIT_MS_HARDENED,
|
|
@@ -438,7 +462,6 @@ import {
|
|
|
438
462
|
requirePositiveStrictInt,
|
|
439
463
|
resolveOnPath,
|
|
440
464
|
runGit,
|
|
441
|
-
safeSlice,
|
|
442
465
|
sleepSync,
|
|
443
466
|
stripDelimitedBlock,
|
|
444
467
|
stripLower,
|
|
@@ -455,7 +478,7 @@ import {
|
|
|
455
478
|
withRetryOnLock,
|
|
456
479
|
writeIfDifferent,
|
|
457
480
|
writeJsonSettings
|
|
458
|
-
} from "./token-goat-chunk-
|
|
481
|
+
} from "./token-goat-chunk-TGBSMHPM.mjs";
|
|
459
482
|
import {
|
|
460
483
|
UNTRUSTED_FILE_TAG,
|
|
461
484
|
UNTRUSTED_TOOL_TAG,
|
|
@@ -3603,9 +3626,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3603
3626
|
* @param {string} [path]
|
|
3604
3627
|
* @return {(string|null|Command)}
|
|
3605
3628
|
*/
|
|
3606
|
-
executableDir(
|
|
3607
|
-
if (
|
|
3608
|
-
this._executableDir =
|
|
3629
|
+
executableDir(path42) {
|
|
3630
|
+
if (path42 === void 0) return this._executableDir;
|
|
3631
|
+
this._executableDir = path42;
|
|
3609
3632
|
return this;
|
|
3610
3633
|
}
|
|
3611
3634
|
/**
|
|
@@ -3905,8 +3928,8 @@ function attemptedCommandName(argv) {
|
|
|
3905
3928
|
}
|
|
3906
3929
|
|
|
3907
3930
|
// src/cli.ts
|
|
3908
|
-
import * as
|
|
3909
|
-
import * as
|
|
3931
|
+
import * as fs45 from "fs";
|
|
3932
|
+
import * as path41 from "path";
|
|
3910
3933
|
|
|
3911
3934
|
// src/walk_index.ts
|
|
3912
3935
|
init_define_import_meta_env();
|
|
@@ -4177,6 +4200,12 @@ main().catch(() => {
|
|
|
4177
4200
|
})
|
|
4178
4201
|
`;
|
|
4179
4202
|
|
|
4203
|
+
// src/canonical_skill.ts
|
|
4204
|
+
init_define_import_meta_env();
|
|
4205
|
+
import { gunzipSync } from "node:zlib";
|
|
4206
|
+
var CANONICAL_SKILL_GZIP_BASE64 = "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";
|
|
4207
|
+
var CANONICAL_SKILL_MD = gunzipSync(Buffer.from(CANONICAL_SKILL_GZIP_BASE64, "base64")).toString("utf8");
|
|
4208
|
+
|
|
4180
4209
|
// src/install.ts
|
|
4181
4210
|
var HOOK_EVENT_MAP = [
|
|
4182
4211
|
["PreToolUse", "pre_tool_use"],
|
|
@@ -4476,23 +4505,8 @@ function findStrayClaudeMdBlocks(searchRoot) {
|
|
|
4476
4505
|
walk(root, 0);
|
|
4477
4506
|
return found.sort();
|
|
4478
4507
|
}
|
|
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
4508
|
function skillMdContent() {
|
|
4491
|
-
|
|
4492
|
-
return `${skillMdFrontmatter(gdrive)}
|
|
4493
|
-
|
|
4494
|
-
${buildGuidanceBody("Claude Code's own Read, Grep, and Glob preference rules", { gdrive })}
|
|
4495
|
-
`;
|
|
4509
|
+
return CANONICAL_SKILL_MD;
|
|
4496
4510
|
}
|
|
4497
4511
|
function skillDir() {
|
|
4498
4512
|
return path3.join(claudeConfigDir(), "skills", "token-goat");
|
|
@@ -4539,6 +4553,9 @@ ${SHIM_REQUIRES}
|
|
|
4539
4553
|
|
|
4540
4554
|
${SHIM_VALID_HOOK_EVENTS}
|
|
4541
4555
|
|
|
4556
|
+
// Codex sets no env var of its own identifying a hook subprocess; see this module's docblock.
|
|
4557
|
+
process.env.TOKEN_GOAT_HARNESS_OVERRIDE = 'codex'
|
|
4558
|
+
|
|
4542
4559
|
// Keep in sync with CLAUDE_CODE_EVENT_NAMES in src/hook_registry.ts -- the
|
|
4543
4560
|
// live/wired 'token-goat hook <event>' path (src/relay.ts) always emits this
|
|
4544
4561
|
// PascalCase spelling for hookSpecificOutput.hookEventName, never the raw
|
|
@@ -4667,7 +4684,7 @@ function groupHasTokenGoat2(groups, matcher, predicate) {
|
|
|
4667
4684
|
|
|
4668
4685
|
// src/bridges/codex_install.ts
|
|
4669
4686
|
var CODEX_COMMAND_MARKER = "token-goat-shim";
|
|
4670
|
-
var CODEX_MATCHERS = ["view_image|shell|bash", "apply_patch", "web_search"];
|
|
4687
|
+
var CODEX_MATCHERS = ["view_image|Bash|exec|shell|bash", "apply_patch", "web_search"];
|
|
4671
4688
|
var CODEX_HOOK_EVENTS = ["PreToolUse", "PostToolUse"];
|
|
4672
4689
|
var CODEX_EVENT_ARG = {
|
|
4673
4690
|
PreToolUse: "pre_tool_use",
|
|
@@ -4950,7 +4967,7 @@ function buildAgentsBlock() {
|
|
|
4950
4967
|
return buildGuidanceBlock({
|
|
4951
4968
|
beginMarker: AGENTS_BEGIN,
|
|
4952
4969
|
endMarker: AGENTS_END,
|
|
4953
|
-
fallbackToolClause: "Codex's native `
|
|
4970
|
+
fallbackToolClause: "Codex's native `exec`, `apply_patch`, and `view_image` tools (shell commands like `cat`/`type` run inside `exec`)",
|
|
4954
4971
|
gdrive: loadConfig().gdrive.enabled
|
|
4955
4972
|
});
|
|
4956
4973
|
}
|
|
@@ -5142,10 +5159,10 @@ function readQwenSettings(p, opts = {}) {
|
|
|
5142
5159
|
let parsed;
|
|
5143
5160
|
try {
|
|
5144
5161
|
parsed = JSON.parse(raw);
|
|
5145
|
-
} catch {
|
|
5162
|
+
} catch (e) {
|
|
5146
5163
|
if (opts.strict === true) {
|
|
5147
5164
|
throw new QwenSettingsParseError(
|
|
5148
|
-
`Qwen Code settings file '${p}' exists but contains invalid JSON. Fix or back up the file before running install
|
|
5165
|
+
`Qwen Code settings file '${p}' exists but contains invalid JSON. Fix or back up the file before running install. (${extractErrorMessage(e)})`
|
|
5149
5166
|
);
|
|
5150
5167
|
}
|
|
5151
5168
|
return {};
|
|
@@ -7155,8 +7172,8 @@ import * as path15 from "node:path";
|
|
|
7155
7172
|
var INTERPRETER_BASENAMES = /* @__PURE__ */ new Set(["node.exe", "python.exe", "python3.exe", "pwsh.exe", "powershell.exe", "cmd.exe"]);
|
|
7156
7173
|
function describeProcess(commandLine) {
|
|
7157
7174
|
for (const m of commandLine.matchAll(/[^\s"]+\.(?:js|mjs|cjs|ts|py|exe)\b/gi)) {
|
|
7158
|
-
const
|
|
7159
|
-
if (!INTERPRETER_BASENAMES.has(
|
|
7175
|
+
const basename10 = m[0].replace(/\\/g, "/").split("/").pop() ?? m[0];
|
|
7176
|
+
if (!INTERPRETER_BASENAMES.has(basename10.toLowerCase())) return basename10;
|
|
7160
7177
|
}
|
|
7161
7178
|
const trimmed = commandLine.trim();
|
|
7162
7179
|
return trimmed.length > 0 ? trimmed.length > 60 ? trimmed.slice(0, 60) + "\u2026" : trimmed : "(no command line)";
|
|
@@ -7542,7 +7559,7 @@ function checkSecurityPosture(cfg, dataDirPath) {
|
|
|
7542
7559
|
}
|
|
7543
7560
|
|
|
7544
7561
|
// src/cli_doctor.ts
|
|
7545
|
-
var DB_SIZE_WARN_BYTES =
|
|
7562
|
+
var DB_SIZE_WARN_BYTES = 1500 * 1024 * 1024;
|
|
7546
7563
|
function freelistBytes(header) {
|
|
7547
7564
|
if (header.length < 40) return 0;
|
|
7548
7565
|
const rawPageSize = header.readUInt16BE(16);
|
|
@@ -7578,12 +7595,15 @@ function dbCategoryBreakdown(dbPath) {
|
|
|
7578
7595
|
}
|
|
7579
7596
|
return shares.sort((a, b) => b.bytes - a.bytes);
|
|
7580
7597
|
}
|
|
7581
|
-
function oversizeDbMessage(dbPath, sizeBytes, freeBytes, tempRows, categories = [], topConsumers = []) {
|
|
7598
|
+
function oversizeDbMessage(dbPath, sizeBytes, freeBytes, tempRows, categories = [], topConsumers = [], thresholdMb = 1500, autoReclaimEmbeddings = false) {
|
|
7582
7599
|
const mb = (bytes) => Math.round(bytes / (1024 * 1024));
|
|
7583
7600
|
const advice = [];
|
|
7584
7601
|
if (freeBytes >= sizeBytes / 10) advice.push(`'token-goat reclaim-index' returns the ${mb(freeBytes)} MB of it that is free pages`);
|
|
7585
7602
|
if (tempRows > 0) advice.push(`'token-goat project prune' removes ${countNoun(tempRows, "scratch file")} indexed under the OS temp dir`);
|
|
7586
|
-
|
|
7603
|
+
if (autoReclaimEmbeddings) {
|
|
7604
|
+
advice.push(`'token-goat doctor --repair' will automatically reclaim embedding vectors and compact global.db`);
|
|
7605
|
+
}
|
|
7606
|
+
const head = `global.db is ${mb(sizeBytes)} MB at ${displaySafeText(dbPath)} (larger than threshold of ${thresholdMb} MB). `;
|
|
7587
7607
|
const totalCategoryBytes = categories.reduce((sum, c) => sum + c.bytes, 0);
|
|
7588
7608
|
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
7609
|
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 +7613,7 @@ function oversizeDbMessage(dbPath, sizeBytes, freeBytes, tempRows, categories =
|
|
|
7593
7613
|
}
|
|
7594
7614
|
return base;
|
|
7595
7615
|
}
|
|
7596
|
-
function checkDbExists(dataDir2) {
|
|
7616
|
+
function checkDbExists(dataDir2, maxDbSizeMb) {
|
|
7597
7617
|
const dbPath = path17.join(dataDir2, "global.db");
|
|
7598
7618
|
if (!fs18.existsSync(dbPath)) {
|
|
7599
7619
|
return {
|
|
@@ -7602,7 +7622,7 @@ function checkDbExists(dataDir2) {
|
|
|
7602
7622
|
message: `global.db not found at ${dbPath}`
|
|
7603
7623
|
};
|
|
7604
7624
|
}
|
|
7605
|
-
const sizeBytes =
|
|
7625
|
+
const sizeBytes = indexSizeBytes(dbPath);
|
|
7606
7626
|
const SQLITE_HEADER = "SQLite format 3\0";
|
|
7607
7627
|
let header = "";
|
|
7608
7628
|
let headerBytes = Buffer.alloc(0);
|
|
@@ -7625,7 +7645,10 @@ function checkDbExists(dataDir2) {
|
|
|
7625
7645
|
message: `global.db at ${dbPath} is not a valid SQLite file (${sizeBytes} bytes) \u2014 likely truncated or corrupt`
|
|
7626
7646
|
};
|
|
7627
7647
|
}
|
|
7628
|
-
|
|
7648
|
+
const cfg = loadConfig();
|
|
7649
|
+
const thresholdMb = maxDbSizeMb ?? cfg.indexing.max_db_size_mb ?? 1500;
|
|
7650
|
+
const warnBytes = thresholdMb * 1024 * 1024;
|
|
7651
|
+
if (sizeBytes > warnBytes) {
|
|
7629
7652
|
let tempRows = 0;
|
|
7630
7653
|
try {
|
|
7631
7654
|
tempRows = findSystemTempFiles(dbPath).length;
|
|
@@ -7637,7 +7660,20 @@ function checkDbExists(dataDir2) {
|
|
|
7637
7660
|
} catch {
|
|
7638
7661
|
}
|
|
7639
7662
|
const topConsumers = findTopIndexedProjects(dbPath, 3);
|
|
7640
|
-
return {
|
|
7663
|
+
return {
|
|
7664
|
+
name: "Database",
|
|
7665
|
+
status: "warn",
|
|
7666
|
+
message: oversizeDbMessage(
|
|
7667
|
+
dbPath,
|
|
7668
|
+
sizeBytes,
|
|
7669
|
+
freelistBytes(headerBytes),
|
|
7670
|
+
tempRows,
|
|
7671
|
+
categories,
|
|
7672
|
+
topConsumers,
|
|
7673
|
+
thresholdMb,
|
|
7674
|
+
cfg.indexing.auto_reclaim_embeddings
|
|
7675
|
+
)
|
|
7676
|
+
};
|
|
7641
7677
|
}
|
|
7642
7678
|
return {
|
|
7643
7679
|
name: "Database",
|
|
@@ -8163,7 +8199,8 @@ function runDoctor(dataDir2, configPath2, rootDir, processes) {
|
|
|
8163
8199
|
results.push(checkTreeSitter());
|
|
8164
8200
|
results.push(checkStrayClaudeMdBlocks());
|
|
8165
8201
|
results.push(checkWorkerRunning(actualDataDir) ? { name: "Worker", status: "ok", message: "running" } : { name: "Worker", status: "warn", message: "not running" });
|
|
8166
|
-
|
|
8202
|
+
const cfg = loadConfig(rootDir);
|
|
8203
|
+
results.push(checkDbExists(actualDataDir, cfg.indexing.max_db_size_mb));
|
|
8167
8204
|
results.push(checkSymbolBodySize(path17.join(actualDataDir, "global.db")));
|
|
8168
8205
|
results.push(checkSymbolCount(path17.join(actualDataDir, "global.db"), rootDir));
|
|
8169
8206
|
results.push(checkDirtyQueueHealth(actualDataDir));
|
|
@@ -8255,6 +8292,22 @@ async function runDoctorRepair(opts) {
|
|
|
8255
8292
|
} catch (e) {
|
|
8256
8293
|
errors.push(`Failed to clean up ${displaySafeText(projectMcp)}: ${extractErrorMessage(e)}`);
|
|
8257
8294
|
}
|
|
8295
|
+
const actualDataDir = opts?.dataDir ?? dataDir();
|
|
8296
|
+
const dbPath = path17.join(actualDataDir, "global.db");
|
|
8297
|
+
if (cfg.indexing.auto_reclaim_embeddings && fs18.existsSync(dbPath)) {
|
|
8298
|
+
try {
|
|
8299
|
+
const sizeBytes = indexSizeBytes(dbPath);
|
|
8300
|
+
const thresholdMb = cfg.indexing.max_db_size_mb ?? 1500;
|
|
8301
|
+
const maxBytes = thresholdMb * 1024 * 1024;
|
|
8302
|
+
if (sizeBytes > maxBytes) {
|
|
8303
|
+
const res = reclaimIndex(dbPath, { embeddingsOnly: true });
|
|
8304
|
+
const savedMb = Math.round((res.beforeBytes - res.afterBytes) / (1024 * 1024));
|
|
8305
|
+
repairs.push(`Auto-reclaimed embeddings and compacted global.db (${savedMb > 0 ? `reclaimed ${savedMb} MB` : "compacted"})`);
|
|
8306
|
+
}
|
|
8307
|
+
} catch (e) {
|
|
8308
|
+
errors.push(`Failed to auto-reclaim embeddings from global.db: ${extractErrorMessage(e)}`);
|
|
8309
|
+
}
|
|
8310
|
+
}
|
|
8258
8311
|
return { repairs, errors };
|
|
8259
8312
|
}
|
|
8260
8313
|
function printDoctorResults(results) {
|
|
@@ -8416,7 +8469,7 @@ async function runDoctorAndExit(opts) {
|
|
|
8416
8469
|
}
|
|
8417
8470
|
}
|
|
8418
8471
|
try {
|
|
8419
|
-
const { checkUpdateStatus } = await import("./token-goat-chunk-
|
|
8472
|
+
const { checkUpdateStatus } = await import("./token-goat-chunk-ZJWPJL7O.mjs");
|
|
8420
8473
|
const update = await checkUpdateStatus(1500);
|
|
8421
8474
|
if (update.updateAvailable && update.latest) {
|
|
8422
8475
|
console.log(`
|
|
@@ -8851,13 +8904,6 @@ function performHttpFetch(targetUrl, opts) {
|
|
|
8851
8904
|
}
|
|
8852
8905
|
|
|
8853
8906
|
// 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
8907
|
function saveConfigSafe(cfg) {
|
|
8862
8908
|
ensureDirSync(path18.dirname(configPath()));
|
|
8863
8909
|
saveConfig(cfg);
|
|
@@ -9276,10 +9322,11 @@ function cmdProject(opts) {
|
|
|
9276
9322
|
const removed = before.length - after.length;
|
|
9277
9323
|
const stale = before.filter((r) => !after.includes(r));
|
|
9278
9324
|
const staleTempFiles = findSystemTempFiles();
|
|
9279
|
-
const
|
|
9325
|
+
const sweep = sweepKnownRoots(void 0, { dryRun: opts.dryRun === true });
|
|
9326
|
+
const orphanChunkPaths = sweep.prunedOrphanChunkPaths;
|
|
9280
9327
|
if (opts.dryRun === true) {
|
|
9281
9328
|
if (opts.json === true) {
|
|
9282
|
-
emit(displaySafeJson({ dryRun: true, wouldPrune: removed, stale, wouldPruneTempFiles: staleTempFiles.length, staleTempFiles, wouldPruneOrphanChunkFiles: orphanChunkPaths.length, orphanChunkPaths, blocked_roots: before }));
|
|
9329
|
+
emit(displaySafeJson({ dryRun: true, wouldPrune: removed, stale, wouldPruneTempFiles: staleTempFiles.length, staleTempFiles, wouldPruneOrphanChunkFiles: orphanChunkPaths.length, orphanChunkPaths, wouldPruneDeadFileRows: sweep.prunedRows, deadRowRoots: sweep.prunedRoots, flaggedRoots: sweep.flaggedRoots, blocked_roots: before }));
|
|
9283
9330
|
return;
|
|
9284
9331
|
}
|
|
9285
9332
|
if (removed === 0) {
|
|
@@ -9300,20 +9347,31 @@ function cmdProject(opts) {
|
|
|
9300
9347
|
emit(`Would prune orphaned embedding chunks for ${orphanChunkPaths.length} file(s):`);
|
|
9301
9348
|
for (const p of orphanChunkPaths) emit(` ${p}`);
|
|
9302
9349
|
}
|
|
9350
|
+
if (sweep.prunedRows === 0) {
|
|
9351
|
+
emit("Would prune 0 dead file row(s) under known roots. Nothing to do.");
|
|
9352
|
+
} else {
|
|
9353
|
+
emit(`Would prune ${sweep.prunedRows} dead file row(s) under ${sweep.prunedRoots.length} known root(s):`);
|
|
9354
|
+
for (const r of sweep.prunedRoots) emit(` ${r}`);
|
|
9355
|
+
}
|
|
9356
|
+
for (const r of sweep.flaggedRoots) emit(` skipped (too many rows would go at once, root may be partly offline): ${r}`);
|
|
9303
9357
|
return;
|
|
9304
9358
|
}
|
|
9305
9359
|
cfg.worker.blocked_roots = after;
|
|
9306
9360
|
saveConfigSafe(cfg);
|
|
9307
9361
|
invalidateConfigCache();
|
|
9308
9362
|
const prunedTempFiles = pruneSystemTempFiles();
|
|
9309
|
-
const prunedOrphanChunks =
|
|
9363
|
+
const prunedOrphanChunks = sweep.prunedOrphanChunkPaths;
|
|
9364
|
+
const prunedOrphanVectors = sweep.prunedOrphanVectors;
|
|
9310
9365
|
if (opts.json === true) {
|
|
9311
|
-
emit(displaySafeJson({ pruned: removed, blocked_roots: after, prunedTempFiles: prunedTempFiles.length, prunedOrphanChunkFiles: prunedOrphanChunks.length }));
|
|
9366
|
+
emit(displaySafeJson({ pruned: removed, blocked_roots: after, prunedTempFiles: prunedTempFiles.length, prunedOrphanChunkFiles: prunedOrphanChunks.length, prunedOrphanVectors, prunedDeadFileRows: sweep.prunedRows, deadRowRoots: sweep.prunedRoots, flaggedRoots: sweep.flaggedRoots }));
|
|
9312
9367
|
return;
|
|
9313
9368
|
}
|
|
9314
9369
|
emit(`Pruned ${removed} stale root(s). Remaining: ${after.length}`);
|
|
9315
9370
|
emit(`Pruned ${prunedTempFiles.length} stale indexed temp-dir file(s).`);
|
|
9316
9371
|
emit(`Pruned orphaned embedding chunks for ${prunedOrphanChunks.length} file(s).`);
|
|
9372
|
+
emit(`Pruned ${prunedOrphanVectors} orphaned embedding vector(s).`);
|
|
9373
|
+
emit(`Pruned ${sweep.prunedRows} dead file row(s) under ${sweep.prunedRoots.length} known root(s).`);
|
|
9374
|
+
for (const r of sweep.flaggedRoots) emit(` skipped (too many rows would go at once, root may be partly offline): ${r}`);
|
|
9317
9375
|
return;
|
|
9318
9376
|
}
|
|
9319
9377
|
emitErr(`project: unknown action '${action}'. Use list, exclude, or prune.`);
|
|
@@ -12211,7 +12269,7 @@ function extractGeneric(lines) {
|
|
|
12211
12269
|
return result;
|
|
12212
12270
|
}
|
|
12213
12271
|
function extractFailures(text, options) {
|
|
12214
|
-
const cleaned =
|
|
12272
|
+
const cleaned = stripAnsiEscapes(text);
|
|
12215
12273
|
const lines = cleaned.split("\n");
|
|
12216
12274
|
const detected = options?.runner ?? detectRunner(cleaned);
|
|
12217
12275
|
if (detected === "pytest") {
|
|
@@ -12386,7 +12444,8 @@ function cmdConflicts(targetPath, opts) {
|
|
|
12386
12444
|
process.exitCode = runConflicts({
|
|
12387
12445
|
...targetPath !== void 0 ? { path: targetPath } : {},
|
|
12388
12446
|
...opts.json === true ? { json: true } : {},
|
|
12389
|
-
...opts.summary === true ? { summary: true } : {}
|
|
12447
|
+
...opts.summary === true ? { summary: true } : {},
|
|
12448
|
+
...opts.context !== void 0 ? { context: parseInt(opts.context, 10) } : {}
|
|
12390
12449
|
});
|
|
12391
12450
|
}
|
|
12392
12451
|
async function cmdScreenshot(url, destPath, opts) {
|
|
@@ -12434,7 +12493,7 @@ function cmdPack(patterns, opts) {
|
|
|
12434
12493
|
}
|
|
12435
12494
|
const result = expandedList.length > 0 ? collectFiles(root, expandedList, collectOpts) : collectFromStdin(root, collectOpts);
|
|
12436
12495
|
if (opts.budget !== void 0) {
|
|
12437
|
-
const budgetN =
|
|
12496
|
+
const budgetN = requireInt("--budget", opts.budget);
|
|
12438
12497
|
if (result.total_tokens > budgetN) {
|
|
12439
12498
|
err(`token-goat: pack: token count ${result.total_tokens} exceeds budget ${budgetN}`);
|
|
12440
12499
|
process.exitCode = 3;
|
|
@@ -12471,7 +12530,7 @@ function cmdTokens(patterns, opts) {
|
|
|
12471
12530
|
let entries = [...result.entries];
|
|
12472
12531
|
if (opts.asc === true) entries.reverse();
|
|
12473
12532
|
const eligibleCount = entries.length;
|
|
12474
|
-
if (opts.top !== void 0) entries = entries.slice(0,
|
|
12533
|
+
if (opts.top !== void 0) entries = entries.slice(0, requireNonNegativeInt("--top", opts.top));
|
|
12475
12534
|
const truncated = entries.length < eligibleCount;
|
|
12476
12535
|
if (opts.json === true) {
|
|
12477
12536
|
out(displaySafeJson({ entries, truncated, totalCount: eligibleCount, total_tokens: result.total_tokens, total_lines: result.total_lines }));
|
|
@@ -12519,7 +12578,7 @@ function cmdBudget(patterns, opts) {
|
|
|
12519
12578
|
if (opts.json === true) {
|
|
12520
12579
|
out(displaySafeJson(result));
|
|
12521
12580
|
} else {
|
|
12522
|
-
const contextK = opts.context !== void 0 ?
|
|
12581
|
+
const contextK = opts.context !== void 0 ? requirePositiveInt("--context", opts.context) : Math.round(loadConfig().context.model_window_tokens / 1e3);
|
|
12523
12582
|
out(formatBudgetText(result, contextK));
|
|
12524
12583
|
}
|
|
12525
12584
|
}
|
|
@@ -12866,8 +12925,8 @@ async function cmdPdfLocate(file, pattern, opts) {
|
|
|
12866
12925
|
const locateOpts = {
|
|
12867
12926
|
ignoreCase: opts.ignoreCase === true
|
|
12868
12927
|
};
|
|
12869
|
-
if (opts.maxMatches !== void 0) locateOpts.maxMatches =
|
|
12870
|
-
if (opts.context !== void 0) locateOpts.context =
|
|
12928
|
+
if (opts.maxMatches !== void 0) locateOpts.maxMatches = requirePositiveInt("--max-matches", opts.maxMatches);
|
|
12929
|
+
if (opts.context !== void 0) locateOpts.context = requirePositiveInt("--context", opts.context);
|
|
12871
12930
|
if (opts.pages !== void 0) locateOpts.pages = opts.pages;
|
|
12872
12931
|
const { matches: matches2, truncated } = await runPdfLocate(file, pattern, locateOpts);
|
|
12873
12932
|
const pages = matches2.map((m) => m.page);
|
|
@@ -12977,14 +13036,14 @@ async function cmdXlsxSheets(file, opts = {}) {
|
|
|
12977
13036
|
recordXlsxStat("xlsx_sheets", file, text);
|
|
12978
13037
|
}
|
|
12979
13038
|
async function cmdXlsxHead(file, opts) {
|
|
12980
|
-
const rows = opts.rows !== void 0 ?
|
|
13039
|
+
const rows = opts.rows !== void 0 ? requireNonNegativeInt("--rows", opts.rows) : 20;
|
|
12981
13040
|
const columns = opts.columns ? opts.columns.split(",").map((c) => c.trim()).filter(Boolean) : void 0;
|
|
12982
13041
|
const text = fenceFileText(await headSheet(file, opts.sheet, rows, columns));
|
|
12983
13042
|
out(text);
|
|
12984
13043
|
recordXlsxStat("xlsx_head", file, text);
|
|
12985
13044
|
}
|
|
12986
13045
|
async function cmdXlsxColumns(file, opts = {}) {
|
|
12987
|
-
const maxRows = opts.head !== void 0 ?
|
|
13046
|
+
const maxRows = opts.head !== void 0 ? requireNonNegativeInt("--head", opts.head) : 100;
|
|
12988
13047
|
const result = await xlsxColumns(file, opts.sheet, maxRows);
|
|
12989
13048
|
if (opts.json === true) {
|
|
12990
13049
|
const text = displaySafeJson({
|
|
@@ -13012,7 +13071,7 @@ async function cmdXlsxQuery(file, opts) {
|
|
|
13012
13071
|
const result = await querySheet(file, opts.sheet, {
|
|
13013
13072
|
...columns !== void 0 ? { columns } : {},
|
|
13014
13073
|
...wheres !== void 0 ? { wheres } : {},
|
|
13015
|
-
...opts.head !== void 0 ? { head:
|
|
13074
|
+
...opts.head !== void 0 ? { head: requireNonNegativeInt("--head", opts.head) } : {}
|
|
13016
13075
|
});
|
|
13017
13076
|
if (opts.json === true) {
|
|
13018
13077
|
const rowsJson = result.rows.map((r) => Object.fromEntries(result.header.map((h, i) => [h, fenceFileFieldIfMatched(r[i] ?? "")])));
|
|
@@ -13044,13 +13103,13 @@ async function cmdPptxOutline(file, opts) {
|
|
|
13044
13103
|
recordDocStat("pptx_outline", file, text);
|
|
13045
13104
|
}
|
|
13046
13105
|
async function cmdPptxSlide(file, opts) {
|
|
13047
|
-
const n =
|
|
13106
|
+
const n = requireNonNegativeInt("--slide", opts.slide);
|
|
13048
13107
|
const text = fenceFileText(await pptxSlideText(file, n, opts.notes === true));
|
|
13049
13108
|
out(text);
|
|
13050
13109
|
recordDocStat("pptx_slide", file, text);
|
|
13051
13110
|
}
|
|
13052
13111
|
async function cmdPptxNotes(file, opts) {
|
|
13053
|
-
const n = opts.slide !== void 0 ?
|
|
13112
|
+
const n = opts.slide !== void 0 ? requireNonNegativeInt("--slide", opts.slide) : void 0;
|
|
13054
13113
|
const text = await pptxNotesText(file, n);
|
|
13055
13114
|
const printed = text.length > 0 ? fenceFileText(text) : "no speaker notes found";
|
|
13056
13115
|
out(printed);
|
|
@@ -13179,7 +13238,7 @@ function cmdXmlOutline(file, opts) {
|
|
|
13179
13238
|
process.exitCode = runXmlOutline({
|
|
13180
13239
|
file,
|
|
13181
13240
|
...opts.json === true ? { json: true } : {},
|
|
13182
|
-
...depthStr !== void 0 ? { maxDepth:
|
|
13241
|
+
...depthStr !== void 0 ? { maxDepth: requireNonNegativeInt("--max-depth", depthStr) } : {}
|
|
13183
13242
|
});
|
|
13184
13243
|
}
|
|
13185
13244
|
function cmdXmlQuery(file, pathOrOpts, optsMaybe) {
|
|
@@ -13990,13 +14049,6 @@ init_define_import_meta_env();
|
|
|
13990
14049
|
|
|
13991
14050
|
// src/answer_router.ts
|
|
13992
14051
|
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
14052
|
function refusal(why, suggestion) {
|
|
14001
14053
|
return `cannot answer deterministically: ${why}; try: ${suggestion}`;
|
|
14002
14054
|
}
|
|
@@ -14128,11 +14180,11 @@ function subjectModeFor(intent) {
|
|
|
14128
14180
|
function runAnswer(opts) {
|
|
14129
14181
|
const question = opts.question.trim();
|
|
14130
14182
|
if (question.length === 0) {
|
|
14131
|
-
|
|
14183
|
+
emitErr(refusal("the question is empty", 'token-goat answer "who calls <symbol>"'));
|
|
14132
14184
|
return 1;
|
|
14133
14185
|
}
|
|
14134
14186
|
if (isJudgementQuestion(question)) {
|
|
14135
|
-
|
|
14187
|
+
emitErr(
|
|
14136
14188
|
refusal(
|
|
14137
14189
|
"that asks for judgement, intent, or runtime behaviour, which the index cannot answer -- it would need the code read and reasoned over",
|
|
14138
14190
|
`token-goat semantic "${question}"`
|
|
@@ -14142,7 +14194,7 @@ function runAnswer(opts) {
|
|
|
14142
14194
|
}
|
|
14143
14195
|
const cls = classify(question);
|
|
14144
14196
|
if (cls === null) {
|
|
14145
|
-
|
|
14197
|
+
emitErr(
|
|
14146
14198
|
refusal(
|
|
14147
14199
|
"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
14200
|
`token-goat semantic "${question}"`
|
|
@@ -14152,7 +14204,7 @@ function runAnswer(opts) {
|
|
|
14152
14204
|
}
|
|
14153
14205
|
const resolved = resolveSubject(cls.subject, subjectModeFor(cls.intent));
|
|
14154
14206
|
if (resolved === null) {
|
|
14155
|
-
|
|
14207
|
+
emitErr(
|
|
14156
14208
|
refusal(
|
|
14157
14209
|
`'${cls.subject}' is not an indexed symbol or file`,
|
|
14158
14210
|
`token-goat semantic "${question}"`
|
|
@@ -14166,7 +14218,7 @@ function runAnswer(opts) {
|
|
|
14166
14218
|
const more = resolved.candidates.length - shown.length;
|
|
14167
14219
|
const first = shown[0] ?? "";
|
|
14168
14220
|
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
|
-
|
|
14221
|
+
emitErr(
|
|
14170
14222
|
refusal(
|
|
14171
14223
|
`'${cls.subject}' names ${resolved.candidates.length} files in this project (${shown.join(", ")}${more > 0 ? `, +${more} more` : ""})`,
|
|
14172
14224
|
next
|
|
@@ -14175,7 +14227,7 @@ function runAnswer(opts) {
|
|
|
14175
14227
|
return 1;
|
|
14176
14228
|
}
|
|
14177
14229
|
if (resolved.kind === "symbol-only") {
|
|
14178
|
-
|
|
14230
|
+
emitErr(
|
|
14179
14231
|
refusal(
|
|
14180
14232
|
`'${cls.subject}' is a symbol; exports/imports are file-level`,
|
|
14181
14233
|
`token-goat ${cls.intent} ${toDisplayPath(rootDir, resolved.file)}`
|
|
@@ -14187,19 +14239,19 @@ function runAnswer(opts) {
|
|
|
14187
14239
|
const file = resolved.kind === "symbol" ? resolved.file : resolved.path;
|
|
14188
14240
|
const display = toDisplayPath(rootDir, file);
|
|
14189
14241
|
if (cls.intent === "tests") {
|
|
14190
|
-
|
|
14242
|
+
emit(`via: token-goat test-for ${display}`);
|
|
14191
14243
|
return runTestFor({ file });
|
|
14192
14244
|
}
|
|
14193
14245
|
if (cls.intent === "exports") {
|
|
14194
|
-
|
|
14246
|
+
emit(`via: token-goat exports ${display}`);
|
|
14195
14247
|
return runExports({ file });
|
|
14196
14248
|
}
|
|
14197
|
-
|
|
14249
|
+
emit(`via: token-goat imports ${display}`);
|
|
14198
14250
|
return runImports({ file });
|
|
14199
14251
|
}
|
|
14200
14252
|
if (resolved.kind === "file") {
|
|
14201
14253
|
const display = toDisplayPath(rootDir, resolved.path);
|
|
14202
|
-
|
|
14254
|
+
emitErr(
|
|
14203
14255
|
refusal(
|
|
14204
14256
|
`'${cls.subject}' is a file, and ${cls.intent === "where" ? "where" : cls.intent} needs a symbol`,
|
|
14205
14257
|
`token-goat outline ${display}`
|
|
@@ -14208,16 +14260,16 @@ function runAnswer(opts) {
|
|
|
14208
14260
|
return 1;
|
|
14209
14261
|
}
|
|
14210
14262
|
if (cls.intent === "callers") {
|
|
14211
|
-
|
|
14263
|
+
emit(`via: token-goat callers ${displaySafeText(resolved.name)} --limit ${ANSWER_DELEGATE_LIMIT}`);
|
|
14212
14264
|
return runCallers({ symbol: resolved.name, limit: ANSWER_DELEGATE_LIMIT });
|
|
14213
14265
|
}
|
|
14214
14266
|
if (cls.intent === "impact") {
|
|
14215
|
-
|
|
14267
|
+
emit(`via: token-goat impact ${displaySafeText(resolved.name)} --top ${ANSWER_DELEGATE_LIMIT}`);
|
|
14216
14268
|
return runImpact({ symbol: resolved.name, top: ANSWER_DELEGATE_LIMIT });
|
|
14217
14269
|
}
|
|
14218
|
-
|
|
14270
|
+
emit(`via: token-goat symbol ${displaySafeText(resolved.name)} -p --exclude-vendored`);
|
|
14219
14271
|
const r = runSymbol({ name: resolved.name, projectRoot: rootDir, limit: ANSWER_DELEGATE_LIMIT, excludeVendored: true });
|
|
14220
|
-
if (r.text.length > 0)
|
|
14272
|
+
if (r.text.length > 0) emit(r.text);
|
|
14221
14273
|
return r.code;
|
|
14222
14274
|
}
|
|
14223
14275
|
|
|
@@ -14225,13 +14277,6 @@ function runAnswer(opts) {
|
|
|
14225
14277
|
init_define_import_meta_env();
|
|
14226
14278
|
import * as path25 from "node:path";
|
|
14227
14279
|
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
14280
|
function guardedFilter(filter2) {
|
|
14236
14281
|
const guarded = compileGuardedRegex(filter2);
|
|
14237
14282
|
if (!guarded.ok) throw new Error(`--filter is not usable as a regular expression: ${guarded.reason}`);
|
|
@@ -14286,43 +14331,43 @@ function computeAffected(opts) {
|
|
|
14286
14331
|
}
|
|
14287
14332
|
function runAffected(opts) {
|
|
14288
14333
|
if (opts.depth !== void 0 && opts.depth <= 0) {
|
|
14289
|
-
|
|
14334
|
+
emitErr(`--depth must be a positive number, got: ${opts.depth}`);
|
|
14290
14335
|
return 1;
|
|
14291
14336
|
}
|
|
14292
14337
|
if (opts.files.length === 0) {
|
|
14293
|
-
|
|
14338
|
+
emitErr("No changed files given. Pass paths as arguments, or pipe them in with --stdin.");
|
|
14294
14339
|
return 1;
|
|
14295
14340
|
}
|
|
14296
14341
|
if (opts.filter !== void 0) {
|
|
14297
14342
|
const guarded = compileGuardedRegex(opts.filter);
|
|
14298
14343
|
if (!guarded.ok) {
|
|
14299
|
-
|
|
14344
|
+
emitErr(`--filter is not usable as a regular expression: ${guarded.reason}`);
|
|
14300
14345
|
return 1;
|
|
14301
14346
|
}
|
|
14302
14347
|
}
|
|
14303
14348
|
const result = computeAffected(opts);
|
|
14304
14349
|
if (opts.json === true) {
|
|
14305
|
-
|
|
14350
|
+
emit(displaySafeJson(result));
|
|
14306
14351
|
return 0;
|
|
14307
14352
|
}
|
|
14308
14353
|
if (opts.quiet === true) {
|
|
14309
|
-
for (const f of result.testFiles)
|
|
14354
|
+
for (const f of result.testFiles) emit(f);
|
|
14310
14355
|
} else if (result.testFiles.length === 0) {
|
|
14311
14356
|
const traced = opts.files.length - result.unknownSeeds.length;
|
|
14312
14357
|
if (traced === 0) {
|
|
14313
|
-
|
|
14358
|
+
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
14359
|
} else {
|
|
14315
|
-
|
|
14360
|
+
emit(`No test files import ${countNoun(traced, "changed file")} (within ${countNoun(result.depth, "hop")}).`);
|
|
14316
14361
|
}
|
|
14317
14362
|
} else {
|
|
14318
|
-
|
|
14319
|
-
for (const f of result.testFiles)
|
|
14363
|
+
emit(`${countNoun(result.testFiles.length, "affected test file")} (${countNoun(result.reachedCount, "file")} reached within ${countNoun(result.depth, "hop")}):`);
|
|
14364
|
+
for (const f of result.testFiles) emit(` ${f}`);
|
|
14320
14365
|
}
|
|
14321
14366
|
if (result.unknownSeeds.length > 0) {
|
|
14322
|
-
|
|
14367
|
+
emitErr(`Not tracked in this project, so nothing was traced from ${result.unknownSeeds.length === 1 ? "it" : "them"}: ${result.unknownSeeds.join(", ")}`);
|
|
14323
14368
|
}
|
|
14324
14369
|
if (result.depthLimited) {
|
|
14325
|
-
|
|
14370
|
+
emitErr(`Stopped at --depth ${result.depth} with ${countNoun(result.unexploredAtFrontier, "file")} still unexplored; more tests may be affected (raise --depth).`);
|
|
14326
14371
|
}
|
|
14327
14372
|
return 0;
|
|
14328
14373
|
}
|
|
@@ -14924,6 +14969,69 @@ function cmdTrace(src, opts) {
|
|
|
14924
14969
|
// src/text_logfold.ts
|
|
14925
14970
|
init_define_import_meta_env();
|
|
14926
14971
|
import * as fs31 from "fs";
|
|
14972
|
+
|
|
14973
|
+
// src/filters.ts
|
|
14974
|
+
init_define_import_meta_env();
|
|
14975
|
+
var DROP = () => null;
|
|
14976
|
+
var FILTERS = [
|
|
14977
|
+
{
|
|
14978
|
+
// git fetch/clone progress: "remote: Counting objects: 73% (8/11)", "Receiving objects: 100% (11/11), done.", "Resolving deltas: ...".
|
|
14979
|
+
name: "git-progress",
|
|
14980
|
+
pattern: /^(remote:\s+)?(Counting objects|Compressing objects|Receiving objects|Resolving deltas|Unpacking objects|Enumerating objects|Writing objects):/i,
|
|
14981
|
+
replacer: DROP
|
|
14982
|
+
},
|
|
14983
|
+
{
|
|
14984
|
+
// npm install summary chatter: "added 142 packages in 3s", "changed 5 packages", "audited 200 packages in 1s".
|
|
14985
|
+
name: "npm-summary",
|
|
14986
|
+
pattern: /^\s*(added|removed|changed|audited)\s+\d+\s+packages?\b/i,
|
|
14987
|
+
replacer: DROP
|
|
14988
|
+
},
|
|
14989
|
+
{
|
|
14990
|
+
// npm/yarn deprecation + funding noise that adds nothing actionable.
|
|
14991
|
+
name: "npm-funding",
|
|
14992
|
+
pattern: /^\s*\d+\s+packages? are looking for funding\b/i,
|
|
14993
|
+
replacer: DROP
|
|
14994
|
+
},
|
|
14995
|
+
{
|
|
14996
|
+
// 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.
|
|
14997
|
+
name: "pip-download",
|
|
14998
|
+
pattern: /^\s*(Downloading|Collecting|Using cached|Requirement already satisfied)\b/i,
|
|
14999
|
+
replacer: DROP
|
|
15000
|
+
},
|
|
15001
|
+
{
|
|
15002
|
+
// 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.
|
|
15003
|
+
name: "progress-bar",
|
|
15004
|
+
pattern: /[█▉▊▋▌▍▎▏▓▒░]{3,}/,
|
|
15005
|
+
replacer: DROP
|
|
15006
|
+
},
|
|
15007
|
+
{
|
|
15008
|
+
// Docker layer pull progress: "abc123: Pulling fs layer", "abc123: Download complete", "abc123: Pull complete".
|
|
15009
|
+
name: "docker-pull",
|
|
15010
|
+
pattern: /^[0-9a-f]{6,}:\s+(Pulling|Waiting|Downloading|Verifying|Extracting|Download complete|Pull complete|Already exists)\b/i,
|
|
15011
|
+
replacer: DROP
|
|
15012
|
+
},
|
|
15013
|
+
{
|
|
15014
|
+
// cargo build chatter: " Compiling foo v0.1.0", " Downloading crates ...".
|
|
15015
|
+
name: "cargo-progress",
|
|
15016
|
+
pattern: /^\s*(Compiling|Downloading|Downloaded|Updating|Fetching)\s+\S/,
|
|
15017
|
+
replacer: DROP
|
|
15018
|
+
},
|
|
15019
|
+
{
|
|
15020
|
+
// Webpack/bundler asset rows are voluminous; keep the build result lines (errors, warnings, "compiled") by only dropping plain asset size rows.
|
|
15021
|
+
name: "webpack-asset",
|
|
15022
|
+
pattern: /^\s*(asset|chunk)\s+\S+\s+[\d.]+\s*(KiB|MiB|bytes)\b/i,
|
|
15023
|
+
replacer: DROP
|
|
15024
|
+
},
|
|
15025
|
+
{
|
|
15026
|
+
// A binary-content marker line: any line carrying a NUL byte is treated as non-text and collapsed to a single readable marker.
|
|
15027
|
+
name: "binary-content",
|
|
15028
|
+
// eslint-disable-next-line no-control-regex -- intentionally matches the NUL control byte that signals binary content
|
|
15029
|
+
pattern: /\x00/,
|
|
15030
|
+
replacer: () => "[binary content elided by token-goat]"
|
|
15031
|
+
}
|
|
15032
|
+
];
|
|
15033
|
+
|
|
15034
|
+
// src/text_logfold.ts
|
|
14927
15035
|
var VOLATILE_SUBS = [
|
|
14928
15036
|
{ re: /\b\d{1,2}:\d{2}:\d{2}(?:\.\d+)?\b/g, placeholder: "[HH:MM:SS]" },
|
|
14929
15037
|
{ 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 +16211,7 @@ function registerAnalysisCommands(program2, guard) {
|
|
|
16103
16211
|
).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
16212
|
program2.command("conflicts [path]").description(
|
|
16105
16213
|
"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));
|
|
16214
|
+
).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
16215
|
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
16216
|
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
16217
|
(ref, opts) => runExit(
|
|
@@ -16235,7 +16343,7 @@ function renderCapabilities(caps) {
|
|
|
16235
16343
|
|
|
16236
16344
|
// src/cli_session.ts
|
|
16237
16345
|
init_define_import_meta_env();
|
|
16238
|
-
import * as
|
|
16346
|
+
import * as fs40 from "node:fs";
|
|
16239
16347
|
|
|
16240
16348
|
// src/session_audit.ts
|
|
16241
16349
|
init_define_import_meta_env();
|
|
@@ -16243,6 +16351,23 @@ import * as fs34 from "node:fs";
|
|
|
16243
16351
|
import * as os16 from "node:os";
|
|
16244
16352
|
import * as path31 from "node:path";
|
|
16245
16353
|
import * as readline from "node:readline";
|
|
16354
|
+
var MODEL_VISIBLE_CATEGORIES = ["toolResults", "assistantText", "assistantThinking", "toolUseInputs", "attachments", "userTurns", "harnessMeta", "system"];
|
|
16355
|
+
function computeCalibration(estimated, measured) {
|
|
16356
|
+
let modelVisibleBytes = 0;
|
|
16357
|
+
let estimatedTokens = 0;
|
|
16358
|
+
for (const key of MODEL_VISIBLE_CATEGORIES) {
|
|
16359
|
+
modelVisibleBytes += estimated[key].bytes;
|
|
16360
|
+
estimatedTokens += estimated[key].estTokens;
|
|
16361
|
+
}
|
|
16362
|
+
const measuredFirstWriteTokens = measured.inputTokens + measured.cacheCreationTokens;
|
|
16363
|
+
return {
|
|
16364
|
+
modelVisibleBytes,
|
|
16365
|
+
estimatedTokens,
|
|
16366
|
+
measuredFirstWriteTokens,
|
|
16367
|
+
relativeError: measuredFirstWriteTokens === 0 ? 0 : (estimatedTokens - measuredFirstWriteTokens) / measuredFirstWriteTokens,
|
|
16368
|
+
bytesPerMeasuredToken: measuredFirstWriteTokens === 0 ? 0 : modelVisibleBytes / measuredFirstWriteTokens
|
|
16369
|
+
};
|
|
16370
|
+
}
|
|
16246
16371
|
function emptyMeasured() {
|
|
16247
16372
|
return { apiCalls: 0, inputTokens: 0, cacheCreationTokens: 0, cacheReadTokens: 0, outputTokens: 0 };
|
|
16248
16373
|
}
|
|
@@ -16317,8 +16442,12 @@ var DENY_TEMPLATES = [
|
|
|
16317
16442
|
{ kind: "doc_unchanged_deny", re: /is unchanged since last read\. Use `token-goat (?:section|read)/, tool: "Read" },
|
|
16318
16443
|
{ kind: "doc_diff_deny", re: /Content changed since last read of [\s\S]*?Use `token-goat (?:section|read)/, tool: "Read" },
|
|
16319
16444
|
{ kind: "read_served_deny", re: /was already served in this session, byte for byte/, tool: "Read" },
|
|
16445
|
+
// 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.
|
|
16446
|
+
{ kind: "range_reread_deny", re: /Lines \d+\.\.\d+ of [\s\S]*?was already read this session/, tool: "Read" },
|
|
16320
16447
|
{ kind: "markdown_already_read_deny", re: /Markdown file already read this session\. Use `token-goat section/, tool: "Read" },
|
|
16321
16448
|
{ kind: "read_count_deny", re: /(?:Read|Tried to read) this file \d+ times already/, tool: "Read" },
|
|
16449
|
+
// 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.
|
|
16450
|
+
{ kind: "sequential_paging_deny", re: /Sequential line-range paging detected on /, tool: "Read" },
|
|
16322
16451
|
{ kind: "generic_reread_deny", re: /was already read this session \(\d+ read/, tool: "Read" },
|
|
16323
16452
|
{ kind: "large_file_deny", re: /is very large \(\d+(?:\.\d+)?KB\)\./, tool: "Read" },
|
|
16324
16453
|
{ 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 +16476,10 @@ var SHELL_READER_TOKEN_RE = /\b(?:sed|grep|cat|head|tail|awk|rg|less|nl|python3?
|
|
|
16347
16476
|
function escapeRegExp2(s) {
|
|
16348
16477
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
16349
16478
|
}
|
|
16350
|
-
function shellReadMatch(command,
|
|
16351
|
-
if (
|
|
16352
|
-
if (!command.includes(
|
|
16353
|
-
const escaped = escapeRegExp2(
|
|
16479
|
+
function shellReadMatch(command, basename10) {
|
|
16480
|
+
if (basename10 === "" || !SHELL_READER_TOKEN_RE.test(command)) return "none";
|
|
16481
|
+
if (!command.includes(basename10)) return "none";
|
|
16482
|
+
const escaped = escapeRegExp2(basename10);
|
|
16354
16483
|
const strict = new RegExp(`(?:^|["'\`/\\\\\\s])${escaped}(?:$|["'\`/\\\\\\s,;:)])`);
|
|
16355
16484
|
return strict.test(command) ? "match" : "ambiguous";
|
|
16356
16485
|
}
|
|
@@ -16390,7 +16519,7 @@ function deepStringBytes(value) {
|
|
|
16390
16519
|
}
|
|
16391
16520
|
return 0;
|
|
16392
16521
|
}
|
|
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;
|
|
16522
|
+
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
16523
|
function toolResultText(content) {
|
|
16395
16524
|
if (typeof content === "string") return content;
|
|
16396
16525
|
if (Array.isArray(content)) {
|
|
@@ -16588,7 +16717,7 @@ async function auditOneFile(filePath, s, toolMap, attachmentMap, hookMap, laneOb
|
|
|
16588
16717
|
s.editErrorBaseline.totalEdits += 1;
|
|
16589
16718
|
}
|
|
16590
16719
|
if (openDenies.length > 0) {
|
|
16591
|
-
const bashCommand = name === "Bash" && typeof input["command"] === "string" ? input["command"] : void 0;
|
|
16720
|
+
const bashCommand = name === "Bash" && typeof input["command"] === "string" ? input["command"].toLowerCase() : void 0;
|
|
16592
16721
|
for (const o of openDenies) {
|
|
16593
16722
|
if (o.toolCalls.length >= 10) continue;
|
|
16594
16723
|
const isReadSamePath = readNorm !== void 0 && o.path !== "" && readNorm === o.path;
|
|
@@ -16639,13 +16768,13 @@ async function auditOneFile(filePath, s, toolMap, attachmentMap, hookMap, laneOb
|
|
|
16639
16768
|
if (name === "Read" || name === "Skill") {
|
|
16640
16769
|
const denyTemplate = DENY_TEMPLATES.find((t) => t.tool === name && t.re.test(text));
|
|
16641
16770
|
if (denyTemplate !== void 0) {
|
|
16642
|
-
const
|
|
16643
|
-
const lastSlash =
|
|
16771
|
+
const path42 = readPathById.get(id) ?? "";
|
|
16772
|
+
const lastSlash = path42.lastIndexOf("/");
|
|
16644
16773
|
openDenies.push({
|
|
16645
16774
|
kind: denyTemplate.kind,
|
|
16646
16775
|
withheldBytes: parseWithheldBytes(denyTemplate.kind, text),
|
|
16647
|
-
path:
|
|
16648
|
-
basename: lastSlash === -1 ?
|
|
16776
|
+
path: path42,
|
|
16777
|
+
basename: lastSlash === -1 ? path42 : path42.slice(lastSlash + 1),
|
|
16649
16778
|
callIndexAtDeny: perCall.length,
|
|
16650
16779
|
compactEpochAtOpen: compactEpoch,
|
|
16651
16780
|
compactEpochAtWindow: null,
|
|
@@ -16946,6 +17075,7 @@ async function auditSessionCorpus(opts = {}) {
|
|
|
16946
17075
|
system: emptyCategory(),
|
|
16947
17076
|
otherLocal: emptyCategory()
|
|
16948
17077
|
},
|
|
17078
|
+
calibration: { modelVisibleBytes: 0, estimatedTokens: 0, measuredFirstWriteTokens: 0, relativeError: 0, bytesPerMeasuredToken: 0 },
|
|
16949
17079
|
tools: [],
|
|
16950
17080
|
attachmentKinds: [],
|
|
16951
17081
|
hookOutputs: [],
|
|
@@ -17006,6 +17136,7 @@ async function auditSessionCorpus(opts = {}) {
|
|
|
17006
17136
|
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
17137
|
summary.denyOutcomes = aggregateDenyOutcomes(denyRows);
|
|
17008
17138
|
summary.editErrorBaseline.rate = summary.editErrorBaseline.totalEdits === 0 ? 0 : summary.editErrorBaseline.totalErrors / summary.editErrorBaseline.totalEdits;
|
|
17139
|
+
summary.calibration = computeCalibration(summary.estimated, summary.measured);
|
|
17009
17140
|
summary.runtimeMs = Date.now() - started;
|
|
17010
17141
|
return summary;
|
|
17011
17142
|
}
|
|
@@ -17046,11 +17177,20 @@ function formatSessionAudit(s) {
|
|
|
17046
17177
|
["system lines", e.system],
|
|
17047
17178
|
["local bookkeeping (never sent)", e.otherLocal]
|
|
17048
17179
|
];
|
|
17049
|
-
const
|
|
17180
|
+
const cal = s.calibration;
|
|
17181
|
+
const modelVisibleBytes = cal.modelVisibleBytes;
|
|
17050
17182
|
for (const [label, cat] of rows.sort((a, b) => b[1].bytes - a[1].bytes)) {
|
|
17051
17183
|
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
17184
|
}
|
|
17053
17185
|
lines.push("");
|
|
17186
|
+
lines.push("## Estimator calibration (the estimate above against the billed ledger above it)");
|
|
17187
|
+
lines.push(`Model-visible bytes: ${fmt(cal.modelVisibleBytes).padStart(18)}`);
|
|
17188
|
+
lines.push(`Estimated tokens (chars/3): ${fmt(cal.estimatedTokens).padStart(18)}`);
|
|
17189
|
+
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)`);
|
|
17190
|
+
lines.push(`Estimator error: ${(cal.relativeError >= 0 ? "+" : "") + (cal.relativeError * 100).toFixed(1) + "%"} ${cal.relativeError >= 0 ? "over" : "under"} measured`);
|
|
17191
|
+
lines.push(`Implied bytes per token: ${cal.bytesPerMeasuredToken.toFixed(2)} (against the 3.0 the estimate divides by)`);
|
|
17192
|
+
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.");
|
|
17193
|
+
lines.push("");
|
|
17054
17194
|
lines.push("## Tool results by tool (estimated content size; calls = tool_use invocations)");
|
|
17055
17195
|
for (const t of s.tools.slice(0, 25)) {
|
|
17056
17196
|
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 +17761,8 @@ async function runMemoryCommand(opts = {}) {
|
|
|
17621
17761
|
|
|
17622
17762
|
// src/cli_waste.ts
|
|
17623
17763
|
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
17764
|
import * as fs38 from "node:fs";
|
|
17630
17765
|
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
17766
|
function printCopilotReport(report) {
|
|
17761
17767
|
const w = (text) => {
|
|
17762
17768
|
process.stdout.write(text);
|
|
@@ -17955,9 +17961,50 @@ function printResidentContext(resident, w) {
|
|
|
17955
17961
|
w(resident.compactionCount === 0 ? "\n" : ", each re-injecting the fixed preamble (CLAUDE.md, memory, skill and agent listings)\n");
|
|
17956
17962
|
}
|
|
17957
17963
|
async function runWasteCommand(opts = {}) {
|
|
17964
|
+
const projectRoot = resolveProjectRoot(opts.project !== void 0 ? { project: opts.project } : {});
|
|
17965
|
+
if (opts.transcript !== void 0) {
|
|
17966
|
+
const resolvedPath = path35.resolve(opts.transcript);
|
|
17967
|
+
if (!fs38.existsSync(resolvedPath)) {
|
|
17968
|
+
if (opts.copilot === true) {
|
|
17969
|
+
const detail = `Copilot session event log not found: ${resolvedPath}`;
|
|
17970
|
+
if (opts.json === true) {
|
|
17971
|
+
process.stdout.write(`${displaySafeJson({ error: detail }, 0)}
|
|
17972
|
+
`);
|
|
17973
|
+
} else {
|
|
17974
|
+
process.stdout.write("\n# token-goat waste (Copilot CLI)\n");
|
|
17975
|
+
process.stdout.write(`${detail}
|
|
17976
|
+
`);
|
|
17977
|
+
}
|
|
17978
|
+
process.exitCode = 1;
|
|
17979
|
+
return;
|
|
17980
|
+
}
|
|
17981
|
+
process.stderr.write(`token-goat: transcript not found: ${resolvedPath}
|
|
17982
|
+
`);
|
|
17983
|
+
process.exitCode = 1;
|
|
17984
|
+
return;
|
|
17985
|
+
}
|
|
17986
|
+
if (opts.copilot === true || isCopilotTranscript(resolvedPath)) {
|
|
17987
|
+
const copilotReport = buildCopilotWasteReport(resolvedPath);
|
|
17988
|
+
if (opts.json === true) {
|
|
17989
|
+
process.stdout.write(`${displaySafeJson(copilotReport, 0)}
|
|
17990
|
+
`);
|
|
17991
|
+
return;
|
|
17992
|
+
}
|
|
17993
|
+
printCopilotReport(copilotReport);
|
|
17994
|
+
return;
|
|
17995
|
+
}
|
|
17996
|
+
const report2 = await buildWasteReport(resolvedPath, opts.top !== void 0 ? { topN: opts.top } : {});
|
|
17997
|
+
if (opts.json === true) {
|
|
17998
|
+
process.stdout.write(`${displaySafeJson(report2, 0)}
|
|
17999
|
+
`);
|
|
18000
|
+
return;
|
|
18001
|
+
}
|
|
18002
|
+
printReport2(report2);
|
|
18003
|
+
return;
|
|
18004
|
+
}
|
|
17958
18005
|
if (opts.copilot === true) {
|
|
17959
|
-
const eventsPath = opts.
|
|
17960
|
-
if (eventsPath === null || !
|
|
18006
|
+
const eventsPath = opts.project !== void 0 ? findLatestCopilotSession({ projectRoot }) : findLatestCopilotSession({ projectRoot }) ?? findLatestCopilotSession();
|
|
18007
|
+
if (eventsPath === null || !fs38.existsSync(eventsPath)) {
|
|
17961
18008
|
const detail = eventsPath === null ? "no Copilot CLI session found under <copilot-home>/session-state" : `Copilot session event log not found: ${eventsPath}`;
|
|
17962
18009
|
if (opts.json === true) {
|
|
17963
18010
|
process.stdout.write(`${displaySafeJson({ error: detail }, 0)}
|
|
@@ -17979,9 +18026,8 @@ async function runWasteCommand(opts = {}) {
|
|
|
17979
18026
|
printCopilotReport(copilotReport);
|
|
17980
18027
|
return;
|
|
17981
18028
|
}
|
|
17982
|
-
const
|
|
17983
|
-
|
|
17984
|
-
if (transcriptPath === null) {
|
|
18029
|
+
const detected = findProjectSession(projectRoot);
|
|
18030
|
+
if (detected === null) {
|
|
17985
18031
|
if (opts.json === true) {
|
|
17986
18032
|
process.stdout.write(`${displaySafeJson({ error: "no session transcript found", project: projectRoot }, 0)}
|
|
17987
18033
|
`);
|
|
@@ -17994,13 +18040,17 @@ async function runWasteCommand(opts = {}) {
|
|
|
17994
18040
|
process.exitCode = 1;
|
|
17995
18041
|
return;
|
|
17996
18042
|
}
|
|
17997
|
-
if (
|
|
17998
|
-
|
|
18043
|
+
if (detected.kind === "copilot") {
|
|
18044
|
+
const copilotReport = buildCopilotWasteReport(detected.path);
|
|
18045
|
+
if (opts.json === true) {
|
|
18046
|
+
process.stdout.write(`${displaySafeJson(copilotReport, 0)}
|
|
17999
18047
|
`);
|
|
18000
|
-
|
|
18048
|
+
return;
|
|
18049
|
+
}
|
|
18050
|
+
printCopilotReport(copilotReport);
|
|
18001
18051
|
return;
|
|
18002
18052
|
}
|
|
18003
|
-
const report = await buildWasteReport(
|
|
18053
|
+
const report = await buildWasteReport(detected.path, opts.top !== void 0 ? { topN: opts.top } : {});
|
|
18004
18054
|
if (opts.json === true) {
|
|
18005
18055
|
process.stdout.write(`${displaySafeJson(report, 0)}
|
|
18006
18056
|
`);
|
|
@@ -18011,13 +18061,13 @@ async function runWasteCommand(opts = {}) {
|
|
|
18011
18061
|
|
|
18012
18062
|
// src/cli_mcp_audit.ts
|
|
18013
18063
|
init_define_import_meta_env();
|
|
18014
|
-
import * as
|
|
18064
|
+
import * as fs39 from "node:fs";
|
|
18015
18065
|
import * as os18 from "node:os";
|
|
18016
|
-
import * as
|
|
18066
|
+
import * as path36 from "node:path";
|
|
18017
18067
|
function readMcpJsonFile(configPath2) {
|
|
18018
18068
|
try {
|
|
18019
|
-
if (!
|
|
18020
|
-
const content =
|
|
18069
|
+
if (!fs39.existsSync(configPath2)) return null;
|
|
18070
|
+
const content = fs39.readFileSync(configPath2, "utf-8");
|
|
18021
18071
|
const parsed = JSON.parse(content);
|
|
18022
18072
|
const servers = parsed && typeof parsed === "object" ? parsed.mcpServers ?? ("servers" in parsed ? null : parsed) : null;
|
|
18023
18073
|
return servers && typeof servers === "object" ? servers : null;
|
|
@@ -18033,8 +18083,8 @@ function driveLetterCaseVariants(p) {
|
|
|
18033
18083
|
}
|
|
18034
18084
|
function readClaudeJsonConfig(claudeJsonPath, projectRoot) {
|
|
18035
18085
|
try {
|
|
18036
|
-
if (!
|
|
18037
|
-
const parsed = JSON.parse(
|
|
18086
|
+
if (!fs39.existsSync(claudeJsonPath)) return null;
|
|
18087
|
+
const parsed = JSON.parse(fs39.readFileSync(claudeJsonPath, "utf-8"));
|
|
18038
18088
|
const projects = parsed && typeof parsed === "object" ? parsed.projects : null;
|
|
18039
18089
|
if (!projects || typeof projects !== "object") return null;
|
|
18040
18090
|
const slashForms = [projectRoot, projectRoot.replace(/\\/g, "/"), projectRoot.replace(/\//g, "\\")];
|
|
@@ -18052,9 +18102,9 @@ function readClaudeJsonConfig(claudeJsonPath, projectRoot) {
|
|
|
18052
18102
|
}
|
|
18053
18103
|
}
|
|
18054
18104
|
function discoverMcpConfig(projectRoot, home) {
|
|
18055
|
-
const mcpJsonPath =
|
|
18056
|
-
const claudeJsonPath =
|
|
18057
|
-
const copilotJsonPath =
|
|
18105
|
+
const mcpJsonPath = path36.join(projectRoot, ".mcp.json");
|
|
18106
|
+
const claudeJsonPath = path36.join(home, ".claude.json");
|
|
18107
|
+
const copilotJsonPath = path36.join(home, ".copilot", "mcp-config.json");
|
|
18058
18108
|
const sourcesChecked = [mcpJsonPath, claudeJsonPath, copilotJsonPath];
|
|
18059
18109
|
const fromMcpJson = readMcpJsonFile(mcpJsonPath);
|
|
18060
18110
|
if (fromMcpJson !== null) return { servers: fromMcpJson, sourcePath: mcpJsonPath, sourcesChecked };
|
|
@@ -18247,7 +18297,7 @@ async function runStatuslineCommand(opts = {}) {
|
|
|
18247
18297
|
return;
|
|
18248
18298
|
}
|
|
18249
18299
|
const line = renderStatusline(data);
|
|
18250
|
-
process.stdout.write(`${colorStdout() ? line :
|
|
18300
|
+
process.stdout.write(`${colorStdout() ? line : stripAnsiEscapes(line)}
|
|
18251
18301
|
`);
|
|
18252
18302
|
}
|
|
18253
18303
|
|
|
@@ -18276,7 +18326,7 @@ function printSummary(rows) {
|
|
|
18276
18326
|
const w = (text) => {
|
|
18277
18327
|
process.stdout.write(text);
|
|
18278
18328
|
};
|
|
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");
|
|
18329
|
+
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
18330
|
for (const row of rows) {
|
|
18281
18331
|
w(
|
|
18282
18332
|
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 +18338,7 @@ function printTotals(totals) {
|
|
|
18288
18338
|
const legacyNote = totals.legacyEmissions > 0 ? ` (excludes ${totals.legacyEmissions} legacy emission(s) recorded before spend tracking)` : "";
|
|
18289
18339
|
process.stdout.write(
|
|
18290
18340
|
`
|
|
18291
|
-
TOTAL saved=${totals.savedBytes} (all-time, every hint kind) spent=${spent} (hint_emissions ledger only)${legacyNote}
|
|
18341
|
+
TOTAL saved-bytes=${totals.savedBytes} (all-time, every hint kind) spent-bytes=${spent} (hint_emissions ledger only)${legacyNote}
|
|
18292
18342
|
`
|
|
18293
18343
|
);
|
|
18294
18344
|
}
|
|
@@ -18370,10 +18420,18 @@ function cmdWaste(opts = {}) {
|
|
|
18370
18420
|
...opts.project !== void 0 ? { project: opts.project } : {},
|
|
18371
18421
|
...opts.transcript !== void 0 ? { transcript: opts.transcript } : {},
|
|
18372
18422
|
...opts.json === true ? { json: true } : {},
|
|
18373
|
-
...opts.top !== void 0 ? { top:
|
|
18423
|
+
...opts.top !== void 0 ? { top: requireNonNegativeInt("--top", opts.top) } : {},
|
|
18374
18424
|
...opts.copilot === true ? { copilot: true } : {}
|
|
18375
18425
|
});
|
|
18376
18426
|
}
|
|
18427
|
+
async function cmdAudit(opts = {}) {
|
|
18428
|
+
const { runAuditCommand } = await import("./token-goat-chunk-KVAXTA2W.mjs");
|
|
18429
|
+
return runAuditCommand({
|
|
18430
|
+
...opts.project !== void 0 ? { project: opts.project } : {},
|
|
18431
|
+
...opts.transcript !== void 0 ? { transcript: opts.transcript } : {},
|
|
18432
|
+
...opts.json === true ? { json: true } : {}
|
|
18433
|
+
});
|
|
18434
|
+
}
|
|
18377
18435
|
async function cmdSessionAudit(opts = {}) {
|
|
18378
18436
|
let summary;
|
|
18379
18437
|
try {
|
|
@@ -18400,7 +18458,7 @@ ${formatSessionOutline(turns)}`;
|
|
|
18400
18458
|
}
|
|
18401
18459
|
function sessionTranscriptSize(transcriptPath) {
|
|
18402
18460
|
try {
|
|
18403
|
-
return
|
|
18461
|
+
return fs40.statSync(transcriptPath).size;
|
|
18404
18462
|
} catch {
|
|
18405
18463
|
return 0;
|
|
18406
18464
|
}
|
|
@@ -18436,7 +18494,7 @@ function cmdRecall(query, opts = {}) {
|
|
|
18436
18494
|
}
|
|
18437
18495
|
runRecallCommand(query, {
|
|
18438
18496
|
...type !== void 0 ? { type } : {},
|
|
18439
|
-
...opts.limit !== void 0 ? { limit:
|
|
18497
|
+
...opts.limit !== void 0 ? { limit: requireNonNegativeInt("--limit", opts.limit) } : {},
|
|
18440
18498
|
...opts.json === true ? { json: true } : {}
|
|
18441
18499
|
});
|
|
18442
18500
|
}
|
|
@@ -18460,14 +18518,14 @@ function cmdHintStats(opts = {}) {
|
|
|
18460
18518
|
|
|
18461
18519
|
// src/cli_skills.ts
|
|
18462
18520
|
init_define_import_meta_env();
|
|
18463
|
-
import * as
|
|
18464
|
-
import * as
|
|
18521
|
+
import * as fs41 from "node:fs";
|
|
18522
|
+
import * as path37 from "node:path";
|
|
18465
18523
|
async function cmdSkillBody(name, opts) {
|
|
18466
18524
|
const filePath = await getSkillFilePath(name);
|
|
18467
18525
|
if (filePath === null) {
|
|
18468
18526
|
throw new CliError(`skill '${name}' not found`);
|
|
18469
18527
|
}
|
|
18470
|
-
const body = decodeSource(
|
|
18528
|
+
const body = decodeSource(fs41.readFileSync(filePath));
|
|
18471
18529
|
if (opts.compact === true) {
|
|
18472
18530
|
const emitted = extractCompactFromMarker(body) ?? body;
|
|
18473
18531
|
out(emitted);
|
|
@@ -18494,7 +18552,7 @@ async function cmdSkillCompact(name, opts) {
|
|
|
18494
18552
|
}
|
|
18495
18553
|
let body2;
|
|
18496
18554
|
try {
|
|
18497
|
-
body2 = decodeSource(
|
|
18555
|
+
body2 = decodeSource(fs41.readFileSync(filePath));
|
|
18498
18556
|
} catch {
|
|
18499
18557
|
unresolvable++;
|
|
18500
18558
|
continue;
|
|
@@ -18528,19 +18586,19 @@ async function cmdSkillCompact(name, opts) {
|
|
|
18528
18586
|
if (!opts.path.trim()) {
|
|
18529
18587
|
throw new CliError("--path cannot be empty");
|
|
18530
18588
|
}
|
|
18531
|
-
if (!
|
|
18589
|
+
if (!fs41.existsSync(opts.path)) {
|
|
18532
18590
|
throw new CliError(`skill file not found: ${opts.path}`);
|
|
18533
18591
|
}
|
|
18534
18592
|
try {
|
|
18535
|
-
body =
|
|
18593
|
+
body = fs41.readFileSync(opts.path, "utf-8");
|
|
18536
18594
|
} catch (e) {
|
|
18537
18595
|
if (e.code === "ENOENT") {
|
|
18538
18596
|
throw new CliError(`skill file not found: ${opts.path}`);
|
|
18539
18597
|
}
|
|
18540
18598
|
throw new CliError(`failed to read skill file '${opts.path}': ${extractErrorMessage(e)}`);
|
|
18541
18599
|
}
|
|
18542
|
-
cacheName = name ??
|
|
18543
|
-
sourcePath =
|
|
18600
|
+
cacheName = name ?? path37.basename(path37.dirname(path37.resolve(opts.path)));
|
|
18601
|
+
sourcePath = path37.resolve(opts.path);
|
|
18544
18602
|
} else {
|
|
18545
18603
|
if (name === void 0 || !name.trim()) {
|
|
18546
18604
|
throw new CliError("skill-compact requires a <name> or --path <file>");
|
|
@@ -18549,7 +18607,7 @@ async function cmdSkillCompact(name, opts) {
|
|
|
18549
18607
|
if (filePath === null) {
|
|
18550
18608
|
throw new CliError(`skill '${name}' not found`);
|
|
18551
18609
|
}
|
|
18552
|
-
body =
|
|
18610
|
+
body = fs41.readFileSync(filePath, "utf-8");
|
|
18553
18611
|
cacheName = name;
|
|
18554
18612
|
sourcePath = filePath;
|
|
18555
18613
|
}
|
|
@@ -18681,8 +18739,8 @@ async function cmdSkillDiff(name) {
|
|
|
18681
18739
|
}
|
|
18682
18740
|
const newer = versions[0];
|
|
18683
18741
|
const older = versions[1];
|
|
18684
|
-
const newerBody = await
|
|
18685
|
-
const olderBody = await
|
|
18742
|
+
const newerBody = await fs41.promises.readFile(path37.resolve(dir, `${newer.outputId}.txt`), "utf-8").catch(() => null);
|
|
18743
|
+
const olderBody = await fs41.promises.readFile(path37.resolve(dir, `${older.outputId}.txt`), "utf-8").catch(() => null);
|
|
18686
18744
|
if (newerBody === null || olderBody === null) {
|
|
18687
18745
|
out(`a cached version of '${name}' was evicted while diffing -- try again`);
|
|
18688
18746
|
return;
|
|
@@ -18711,7 +18769,7 @@ async function cmdSkillSection(nameHeading, headingArg) {
|
|
|
18711
18769
|
if (!filePath) {
|
|
18712
18770
|
throw new CliError(`skill '${skillName}' not found`);
|
|
18713
18771
|
}
|
|
18714
|
-
const body = decodeSource(
|
|
18772
|
+
const body = decodeSource(fs41.readFileSync(filePath));
|
|
18715
18773
|
const extracted = extractNamedSection(body, heading);
|
|
18716
18774
|
if (!extracted) {
|
|
18717
18775
|
const allHeadings = listSections(filePath);
|
|
@@ -18732,94 +18790,12 @@ async function cmdSkillSection(nameHeading, headingArg) {
|
|
|
18732
18790
|
// src/cache_session_commands.ts
|
|
18733
18791
|
init_define_import_meta_env();
|
|
18734
18792
|
|
|
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
18793
|
// src/cli_stats.ts
|
|
18818
18794
|
init_define_import_meta_env();
|
|
18819
|
-
import * as
|
|
18820
|
-
import * as
|
|
18795
|
+
import * as fs42 from "node:fs";
|
|
18796
|
+
import * as path38 from "node:path";
|
|
18821
18797
|
function writeRaw(text) {
|
|
18822
|
-
const payload = colorStdout() ? text :
|
|
18798
|
+
const payload = colorStdout() ? text : stripAnsiEscapes(text);
|
|
18823
18799
|
process.stdout.write(ensureNewline(payload));
|
|
18824
18800
|
}
|
|
18825
18801
|
function rankByReadCount(entries, topN) {
|
|
@@ -18829,8 +18805,8 @@ function formatTopFiles(ranked) {
|
|
|
18829
18805
|
if (ranked.length === 0) return "";
|
|
18830
18806
|
const lines = ["Top files this session:"];
|
|
18831
18807
|
for (const { path: filePath, count } of ranked) {
|
|
18832
|
-
const
|
|
18833
|
-
lines.push(` ${count.toString().padStart(3)}x ${
|
|
18808
|
+
const basename10 = path38.basename(filePath);
|
|
18809
|
+
lines.push(` ${count.toString().padStart(3)}x ${basename10} (${filePath})`);
|
|
18834
18810
|
}
|
|
18835
18811
|
return lines.join("\n");
|
|
18836
18812
|
}
|
|
@@ -18847,11 +18823,11 @@ function renderTopSessionFiles(topN = 5) {
|
|
|
18847
18823
|
function renderTopSessionFilesFromDisk(topN = 5, overrideSessionsDir) {
|
|
18848
18824
|
try {
|
|
18849
18825
|
const dir = overrideSessionsDir ?? sessionsDir();
|
|
18850
|
-
if (!
|
|
18851
|
-
const files =
|
|
18826
|
+
if (!fs42.existsSync(dir)) return "";
|
|
18827
|
+
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
18828
|
for (const { name } of files) {
|
|
18853
18829
|
try {
|
|
18854
|
-
const raw =
|
|
18830
|
+
const raw = fs42.readFileSync(path38.join(dir, name), "utf-8");
|
|
18855
18831
|
const data = JSON.parse(raw);
|
|
18856
18832
|
const filesList = data["files"];
|
|
18857
18833
|
if (!Array.isArray(filesList)) continue;
|
|
@@ -18943,13 +18919,10 @@ function runStats(opts = {}) {
|
|
|
18943
18919
|
}
|
|
18944
18920
|
|
|
18945
18921
|
// src/cache_session_commands.ts
|
|
18946
|
-
function emitErr4(text) {
|
|
18947
|
-
process.stderr.write(ensureNewline(text));
|
|
18948
|
-
}
|
|
18949
18922
|
function capAndNote(rows, limit) {
|
|
18950
18923
|
const shown = rows.slice(0, limit);
|
|
18951
18924
|
if (shown.length < rows.length) {
|
|
18952
|
-
|
|
18925
|
+
emitErr(`Showing ${shown.length} of ${rows.length} entries (raise --limit to see the rest).`);
|
|
18953
18926
|
}
|
|
18954
18927
|
return shown;
|
|
18955
18928
|
}
|
|
@@ -18959,11 +18932,11 @@ function parseLimitOpt(cmdName, limitStr, dflt = 30) {
|
|
|
18959
18932
|
try {
|
|
18960
18933
|
n = requireNonNegativeStrictInt("--limit", limitStr);
|
|
18961
18934
|
} catch (e) {
|
|
18962
|
-
|
|
18935
|
+
emitErr(`${cmdName}: --limit must be a positive number, got: "${limitStr}"`);
|
|
18963
18936
|
throw new Error(`invalid --limit: ${limitStr}`, { cause: e });
|
|
18964
18937
|
}
|
|
18965
18938
|
if (n === 0) {
|
|
18966
|
-
|
|
18939
|
+
emitErr(`${cmdName}: --limit must be a positive number, got: "${limitStr}"`);
|
|
18967
18940
|
throw new Error(`invalid --limit: ${limitStr}`);
|
|
18968
18941
|
}
|
|
18969
18942
|
return n;
|
|
@@ -19201,11 +19174,17 @@ function cmdCompactHint(opts) {
|
|
|
19201
19174
|
const cache = sessionId !== null ? loadSessionCache(sessionId) : null;
|
|
19202
19175
|
const transcriptPath = sessionId !== null ? resolveSessionTranscript(sessionId) : null;
|
|
19203
19176
|
const pressure = getContextPressure(cache ?? void 0, transcriptPath ?? void 0);
|
|
19204
|
-
|
|
19177
|
+
let manifest = "";
|
|
19178
|
+
let events = 0;
|
|
19179
|
+
if (sessionId !== null && cache !== null) {
|
|
19180
|
+
loadSessionState(sessionId);
|
|
19181
|
+
manifest = buildManifest(sessionId, process.cwd(), transcriptPath ?? void 0);
|
|
19182
|
+
events = eventCount(cache);
|
|
19183
|
+
}
|
|
19205
19184
|
const manifestTokens = estimateTokens(manifest);
|
|
19206
19185
|
const pct3 = (pressure.fillFraction * 100).toFixed(1);
|
|
19207
19186
|
if (opts.json === true) {
|
|
19208
|
-
const out2 = { tier: pressure.tier, fillFraction: pressure.fillFraction, pct: Number(pct3), manifestTokens, eventCount };
|
|
19187
|
+
const out2 = { tier: pressure.tier, fillFraction: pressure.fillFraction, pct: Number(pct3), manifestTokens, eventCount: events };
|
|
19209
19188
|
if (sessionId !== null) out2["sessionId"] = sessionId;
|
|
19210
19189
|
if (opts.trigger !== void 0) out2["trigger"] = opts.trigger;
|
|
19211
19190
|
process.stdout.write(displaySafeJson(out2) + "\n");
|
|
@@ -19215,7 +19194,7 @@ function cmdCompactHint(opts) {
|
|
|
19215
19194
|
`);
|
|
19216
19195
|
if (sessionId !== null) process.stdout.write(`Session: ${sessionId}
|
|
19217
19196
|
`);
|
|
19218
|
-
process.stdout.write(`Manifest: ${manifestTokens} tokens, ${countNoun(
|
|
19197
|
+
process.stdout.write(`Manifest: ${manifestTokens} tokens, ${countNoun(events, "event")}
|
|
19219
19198
|
`);
|
|
19220
19199
|
if (opts.trigger === "auto") {
|
|
19221
19200
|
const remaining = Math.max(0, Math.round((1 - pressure.fillFraction) * CONTEXT_AUTOCOMPACT_TOKENS));
|
|
@@ -19318,6 +19297,7 @@ function registerSessionCommands(program2, guard) {
|
|
|
19318
19297
|
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
19298
|
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
19299
|
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));
|
|
19300
|
+
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
19301
|
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
19302
|
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
19303
|
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 +19412,15 @@ var BRIDGE_CAPABILITY_MATRIX = [
|
|
|
19432
19412
|
harness: "codex",
|
|
19433
19413
|
label: "Codex CLI",
|
|
19434
19414
|
sourceFile: "src/bridges/codex_install.ts (CODEX_HOOK_EVENTS, CODEX_GLOBAL_HOOK_EVENTS)",
|
|
19435
|
-
verification: "
|
|
19436
|
-
verificationNote:
|
|
19415
|
+
verification: "dogfooded",
|
|
19416
|
+
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
19417
|
implemented: /* @__PURE__ */ new Set(["pre_tool_use", "post_tool_use", "pre_compact", "user_prompt_submit", "subagent_stop"]),
|
|
19438
19418
|
reasons: [
|
|
19439
19419
|
{ events: ["post_tool_use_failure"], reason: NO_SEPARATE_FAILURE_EVENT_REASON },
|
|
19440
|
-
{ events: ["post_compact"], reason: NO_POST_COMPACT_EVENT_REASON },
|
|
19441
19420
|
{ events: ["notification", "stop"], reason: NO_SERVER_HANDLER_REASON },
|
|
19442
19421
|
{
|
|
19443
|
-
events: ["session_start"],
|
|
19444
|
-
reason: "Codex CLI
|
|
19422
|
+
events: ["post_compact", "session_start"],
|
|
19423
|
+
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
19424
|
}
|
|
19446
19425
|
]
|
|
19447
19426
|
},
|
|
@@ -19582,7 +19561,7 @@ var BRIDGE_CAPABILITY_MATRIX = [
|
|
|
19582
19561
|
reasons: [
|
|
19583
19562
|
{
|
|
19584
19563
|
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"
|
|
19564
|
+
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
19565
|
},
|
|
19587
19566
|
{ events: ["post_compact"], reason: NO_POST_COMPACT_EVENT_REASON },
|
|
19588
19567
|
{ events: ["notification", "stop"], reason: NO_SERVER_HANDLER_REASON }
|
|
@@ -19735,25 +19714,25 @@ function installVerificationNotice(harness) {
|
|
|
19735
19714
|
|
|
19736
19715
|
// src/purge.ts
|
|
19737
19716
|
init_define_import_meta_env();
|
|
19738
|
-
import * as
|
|
19739
|
-
import * as
|
|
19717
|
+
import * as fs43 from "node:fs";
|
|
19718
|
+
import * as path39 from "node:path";
|
|
19740
19719
|
function directorySize(root) {
|
|
19741
19720
|
let total = 0;
|
|
19742
19721
|
let entries;
|
|
19743
19722
|
try {
|
|
19744
|
-
entries =
|
|
19723
|
+
entries = fs43.readdirSync(root, { withFileTypes: true });
|
|
19745
19724
|
} catch {
|
|
19746
19725
|
return 0;
|
|
19747
19726
|
}
|
|
19748
19727
|
for (const entry of entries) {
|
|
19749
|
-
const full =
|
|
19728
|
+
const full = path39.join(root, entry.name);
|
|
19750
19729
|
if (entry.isDirectory()) {
|
|
19751
19730
|
total += directorySize(full);
|
|
19752
19731
|
continue;
|
|
19753
19732
|
}
|
|
19754
19733
|
if (!entry.isFile()) continue;
|
|
19755
19734
|
try {
|
|
19756
|
-
total +=
|
|
19735
|
+
total += fs43.statSync(full).size;
|
|
19757
19736
|
} catch {
|
|
19758
19737
|
}
|
|
19759
19738
|
}
|
|
@@ -19772,7 +19751,7 @@ function purgeDataDirectories() {
|
|
|
19772
19751
|
}
|
|
19773
19752
|
const bytes = directorySize(root);
|
|
19774
19753
|
try {
|
|
19775
|
-
|
|
19754
|
+
fs43.rmSync(root, { recursive: true, force: true });
|
|
19776
19755
|
result.removed.push({ path: root, bytes });
|
|
19777
19756
|
} catch (e) {
|
|
19778
19757
|
result.failed.push({ path: root, reason: e instanceof Error ? e.message : String(e) });
|
|
@@ -19919,8 +19898,8 @@ async function getSectionContent(fileId, heading, opts = {}) {
|
|
|
19919
19898
|
|
|
19920
19899
|
// src/cli_bench.ts
|
|
19921
19900
|
init_define_import_meta_env();
|
|
19922
|
-
import * as
|
|
19923
|
-
import * as
|
|
19901
|
+
import * as fs44 from "node:fs";
|
|
19902
|
+
import * as path40 from "node:path";
|
|
19924
19903
|
var ControlFilter = class extends ToolFilter {
|
|
19925
19904
|
constructor(name, transform) {
|
|
19926
19905
|
super();
|
|
@@ -19941,13 +19920,13 @@ var CONTROL_FILTERS = {
|
|
|
19941
19920
|
};
|
|
19942
19921
|
var MAX_BENCH_FILE_BYTES = 5 * 1024 * 1024;
|
|
19943
19922
|
function readCaseFile(id, filePath, what) {
|
|
19944
|
-
const bytes =
|
|
19923
|
+
const bytes = fs44.statSync(filePath).size;
|
|
19945
19924
|
if (bytes > MAX_BENCH_FILE_BYTES) {
|
|
19946
19925
|
throw new Error(
|
|
19947
19926
|
`bench case ${id}: ${what} is ${bytes} bytes, over the ${MAX_BENCH_FILE_BYTES}-byte limit for a corpus file (${filePath})`
|
|
19948
19927
|
);
|
|
19949
19928
|
}
|
|
19950
|
-
return
|
|
19929
|
+
return fs44.readFileSync(filePath, "utf8");
|
|
19951
19930
|
}
|
|
19952
19931
|
function parseCase(id, metaPath, outputPath) {
|
|
19953
19932
|
const metaText = readCaseFile(id, metaPath, "metadata");
|
|
@@ -19982,7 +19961,7 @@ function parseCase(id, metaPath, outputPath) {
|
|
|
19982
19961
|
function loadCorpus(dir) {
|
|
19983
19962
|
let entries;
|
|
19984
19963
|
try {
|
|
19985
|
-
entries =
|
|
19964
|
+
entries = fs44.readdirSync(dir);
|
|
19986
19965
|
} catch {
|
|
19987
19966
|
throw new Error(`bench corpus not found: ${dir}`);
|
|
19988
19967
|
}
|
|
@@ -19990,9 +19969,9 @@ function loadCorpus(dir) {
|
|
|
19990
19969
|
for (const entry of entries.sort()) {
|
|
19991
19970
|
if (!entry.endsWith(".json")) continue;
|
|
19992
19971
|
const id = entry.slice(0, -".json".length);
|
|
19993
|
-
const outputPath =
|
|
19994
|
-
if (!
|
|
19995
|
-
cases.push(parseCase(id,
|
|
19972
|
+
const outputPath = path40.join(dir, `${id}.txt`);
|
|
19973
|
+
if (!fs44.existsSync(outputPath)) throw new Error(`bench case ${id}: missing output file ${outputPath}`);
|
|
19974
|
+
cases.push(parseCase(id, path40.join(dir, entry), outputPath));
|
|
19996
19975
|
}
|
|
19997
19976
|
if (cases.length === 0) throw new Error(`bench corpus is empty: ${dir}`);
|
|
19998
19977
|
return cases;
|
|
@@ -20112,10 +20091,10 @@ function appendTsv(file, report, commit) {
|
|
|
20112
20091
|
report.mustKeepTotal,
|
|
20113
20092
|
report.coveredFilters
|
|
20114
20093
|
].join(" ");
|
|
20115
|
-
const dir =
|
|
20116
|
-
|
|
20117
|
-
const header =
|
|
20118
|
-
|
|
20094
|
+
const dir = path40.dirname(path40.resolve(file));
|
|
20095
|
+
fs44.mkdirSync(dir, { recursive: true });
|
|
20096
|
+
const header = fs44.existsSync(file) ? "" : TSV_HEADER;
|
|
20097
|
+
fs44.appendFileSync(file, header + row + "\n", "utf8");
|
|
20119
20098
|
}
|
|
20120
20099
|
function currentCommit(cwd) {
|
|
20121
20100
|
const opts = cwd === void 0 ? {} : { cwd };
|
|
@@ -20144,7 +20123,7 @@ function runBenchCommand(opts) {
|
|
|
20144
20123
|
var CliError = class extends Error {
|
|
20145
20124
|
};
|
|
20146
20125
|
function out(text) {
|
|
20147
|
-
const payload = colorStdout() ? text :
|
|
20126
|
+
const payload = colorStdout() ? text : stripAnsiEscapes(text);
|
|
20148
20127
|
process.stdout.write(ensureNewline(payload));
|
|
20149
20128
|
}
|
|
20150
20129
|
function err(text) {
|
|
@@ -20155,10 +20134,10 @@ function readBoundedText(text, file) {
|
|
|
20155
20134
|
if (text === void 0 && file === void 0) throw new CliError("provide text or --file");
|
|
20156
20135
|
let value;
|
|
20157
20136
|
if (file !== void 0) {
|
|
20158
|
-
if (
|
|
20137
|
+
if (fs45.statSync(file).size > CONTENT_MAX_INPUT_CHARS) {
|
|
20159
20138
|
throw new CliError(`file exceeds the ${CONTENT_MAX_INPUT_CHARS}-byte safety limit`);
|
|
20160
20139
|
}
|
|
20161
|
-
value =
|
|
20140
|
+
value = fs45.readFileSync(file, "utf8");
|
|
20162
20141
|
} else {
|
|
20163
20142
|
if (text === void 0) throw new CliError("provide text or --file");
|
|
20164
20143
|
value = text;
|
|
@@ -20203,35 +20182,11 @@ function cmdHandoffResolve(name, opts) {
|
|
|
20203
20182
|
if (result === null) throw new CliError(`no local handoff named "${name}" in this project`);
|
|
20204
20183
|
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
20184
|
}
|
|
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
20185
|
async function cmdSemantic(query, opts) {
|
|
20231
20186
|
if (!query && !opts.preflight && !opts.warm) {
|
|
20232
20187
|
throw new CliError("missing required argument: query");
|
|
20233
20188
|
}
|
|
20234
|
-
const limit = opts.limit !== void 0 ?
|
|
20189
|
+
const limit = opts.limit !== void 0 ? requireNonNegativeInt("--limit", opts.limit) : 20;
|
|
20235
20190
|
const { text, code } = await runSemantic(query ?? "", {
|
|
20236
20191
|
limit,
|
|
20237
20192
|
...opts.json === true ? { json: true } : {},
|
|
@@ -20268,7 +20223,7 @@ async function cmdIndex(pathArg, opts = {}) {
|
|
|
20268
20223
|
const ixCfg = loadConfig().indexing;
|
|
20269
20224
|
if ((loadConfig().indexing?.embeddings_enabled ?? true) && embeddingsDepsAvailable(getDb(dbPath))) {
|
|
20270
20225
|
ensureEmbeddingProvenance(getDb(dbPath));
|
|
20271
|
-
pruneUnembeddableChunks(getDb(dbPath), ixCfg.max_chunks_per_file, deleteFileEmbeddings);
|
|
20226
|
+
pruneUnembeddableChunks(getDb(dbPath), ixCfg.max_chunks_per_file, deleteFileEmbeddings, { asset: assetEmbedSha, maxChunks: maxChunksEmbedSha });
|
|
20272
20227
|
}
|
|
20273
20228
|
let indexed = 0;
|
|
20274
20229
|
let failed = 0;
|
|
@@ -20305,7 +20260,8 @@ async function cmdIndex(pathArg, opts = {}) {
|
|
|
20305
20260
|
continue;
|
|
20306
20261
|
}
|
|
20307
20262
|
const sha = fingerprintFile(key);
|
|
20308
|
-
if (sha === null && !
|
|
20263
|
+
if (sha === null && !fs45.existsSync(key)) continue;
|
|
20264
|
+
recordKnownRootThrottled(key, dataDir(), dbPath);
|
|
20309
20265
|
const entry = sha !== null ? getFileEntry(key, dbPath) : null;
|
|
20310
20266
|
const spellingStale = entry !== null && indexedPathSpellingIsStale(entry.filePath, key);
|
|
20311
20267
|
const parseUnchanged = !force && !spellingStale && sha !== null && entry?.sha === sha && entry.parserSha === parserFingerprintForLanguage(entry.language);
|
|
@@ -20341,7 +20297,7 @@ async function cmdIndex(pathArg, opts = {}) {
|
|
|
20341
20297
|
}
|
|
20342
20298
|
continue;
|
|
20343
20299
|
}
|
|
20344
|
-
if (!
|
|
20300
|
+
if (!fs45.existsSync(key)) continue;
|
|
20345
20301
|
}
|
|
20346
20302
|
const embedFresh = parseUnchanged ? embedUnchanged : embedFreshFor(getFileEntry(key, dbPath)?.embedSha);
|
|
20347
20303
|
if (!embedFresh) {
|
|
@@ -20402,7 +20358,7 @@ async function cmdMcpServe() {
|
|
|
20402
20358
|
let StdioServerTransport;
|
|
20403
20359
|
try {
|
|
20404
20360
|
;
|
|
20405
|
-
({ createMcpServer } = await import("./token-goat-chunk-
|
|
20361
|
+
({ createMcpServer } = await import("./token-goat-chunk-GO7OWONJ.mjs"));
|
|
20406
20362
|
({ StdioServerTransport } = await import("./token-goat-chunk-EVC4TOLE.mjs"));
|
|
20407
20363
|
} catch (err2) {
|
|
20408
20364
|
process.stderr.write(
|
|
@@ -20427,11 +20383,11 @@ async function cmdHook(event, opts) {
|
|
|
20427
20383
|
if (typeof opts.harness === "string" && opts.harness.length > 0) {
|
|
20428
20384
|
process.env[ENV_KEYS.HARNESS_OVERRIDE] = opts.harness;
|
|
20429
20385
|
}
|
|
20430
|
-
const { relay } = await import("./token-goat-chunk-
|
|
20386
|
+
const { relay } = await import("./token-goat-chunk-CMHBTXMY.mjs");
|
|
20431
20387
|
await relay(event);
|
|
20432
20388
|
}
|
|
20433
20389
|
function projectHooksCommitNote(pathFiles, hooksConfigPath) {
|
|
20434
|
-
const shim = hooksConfigPath === void 0 ? "" : ` (${displaySafePath(
|
|
20390
|
+
const shim = hooksConfigPath === void 0 ? "" : ` (${displaySafePath(path41.join(path41.dirname(hooksConfigPath), HOOKS_SCRIPT_FILE))} is generated with them)`;
|
|
20435
20391
|
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
20392
|
}
|
|
20437
20393
|
function visualStudioManualSteps(scope) {
|
|
@@ -20464,7 +20420,7 @@ async function cmdInstall(opts) {
|
|
|
20464
20420
|
if (opts.project === true && opts.user === true) {
|
|
20465
20421
|
throw new Error("install takes either -p/--project or --user, not both.");
|
|
20466
20422
|
}
|
|
20467
|
-
await import("./token-goat-chunk-
|
|
20423
|
+
await import("./token-goat-chunk-CMHBTXMY.mjs");
|
|
20468
20424
|
const scope = opts.project === true ? "project" : "user";
|
|
20469
20425
|
if (wantsClaudeCodeBase(opts)) {
|
|
20470
20426
|
const result = installHooks(scope);
|
|
@@ -20610,16 +20566,16 @@ async function cmdInstall(opts) {
|
|
|
20610
20566
|
);
|
|
20611
20567
|
}
|
|
20612
20568
|
try {
|
|
20613
|
-
const skillDir2 =
|
|
20614
|
-
if (
|
|
20615
|
-
const entries =
|
|
20569
|
+
const skillDir2 = path41.join(claudeConfigDir(), "skills");
|
|
20570
|
+
if (fs45.existsSync(skillDir2)) {
|
|
20571
|
+
const entries = fs45.readdirSync(skillDir2, { withFileTypes: true });
|
|
20616
20572
|
const skillNames = [];
|
|
20617
20573
|
const sessionId = getSessionId();
|
|
20618
20574
|
for (const entry of entries) {
|
|
20619
20575
|
if (!entry.isDirectory()) continue;
|
|
20620
|
-
const skillFile =
|
|
20621
|
-
if (
|
|
20622
|
-
const body =
|
|
20576
|
+
const skillFile = path41.join(skillDir2, entry.name, "SKILL.md");
|
|
20577
|
+
if (fs45.existsSync(skillFile)) {
|
|
20578
|
+
const body = fs45.readFileSync(skillFile, "utf-8");
|
|
20623
20579
|
const compact = extractCompactFromMarker(body);
|
|
20624
20580
|
if (compact === null) continue;
|
|
20625
20581
|
const sourceSha = contentHash(body);
|
|
@@ -20630,9 +20586,9 @@ async function cmdInstall(opts) {
|
|
|
20630
20586
|
if (skillNames.length > 0) {
|
|
20631
20587
|
const dir = skillOutputsDir();
|
|
20632
20588
|
ensureDirSync(dir);
|
|
20633
|
-
const pregenPath =
|
|
20589
|
+
const pregenPath = path41.join(dir, "pregen.json");
|
|
20634
20590
|
const pregenData = { ts: Date.now(), names: skillNames };
|
|
20635
|
-
await
|
|
20591
|
+
await fs45.promises.writeFile(pregenPath, JSON.stringify(pregenData, null, 2));
|
|
20636
20592
|
out(`Pre-generated ${skillNames.length} skill compacts.`);
|
|
20637
20593
|
}
|
|
20638
20594
|
}
|
|
@@ -20772,7 +20728,7 @@ function cmdWorkerStatus() {
|
|
|
20772
20728
|
out(isWorkerRunning() ? "Worker is running." : "Worker is not running.");
|
|
20773
20729
|
}
|
|
20774
20730
|
function cmdStats(opts = {}) {
|
|
20775
|
-
const windowDays = opts.windowDays !== void 0 ?
|
|
20731
|
+
const windowDays = opts.windowDays !== void 0 ? requireNonNegativeInt("--window-days", opts.windowDays) : 30;
|
|
20776
20732
|
const statsOpts = {
|
|
20777
20733
|
json: opts.json === true,
|
|
20778
20734
|
windowDays,
|
|
@@ -20812,7 +20768,7 @@ async function cmdDoctor(opts) {
|
|
|
20812
20768
|
}
|
|
20813
20769
|
}
|
|
20814
20770
|
function _applyFiltersAndPrint(content, opts, fenceByProvenance = false, fenceTag = UNTRUSTED_WEB_TAG) {
|
|
20815
|
-
const
|
|
20771
|
+
const emit2 = (text) => {
|
|
20816
20772
|
if (!fenceByProvenance || text === "") {
|
|
20817
20773
|
out(text);
|
|
20818
20774
|
return text;
|
|
@@ -20843,7 +20799,7 @@ function _applyFiltersAndPrint(content, opts, fenceByProvenance = false, fenceTa
|
|
|
20843
20799
|
}
|
|
20844
20800
|
}
|
|
20845
20801
|
if (opts.grep !== void 0 && opts.maxMatches !== void 0) {
|
|
20846
|
-
const cap =
|
|
20802
|
+
const cap = requireNonNegativeInt("--max-matches", opts.maxMatches);
|
|
20847
20803
|
const matched = content === "" ? [] : content.split(/\r?\n/);
|
|
20848
20804
|
if (matched.length > cap) {
|
|
20849
20805
|
content = [...matched.slice(0, cap), "[token-goat: showing first " + cap + " of " + matched.length + " matching lines; raise --max-matches for more]"].join("\n");
|
|
@@ -20851,11 +20807,11 @@ function _applyFiltersAndPrint(content, opts, fenceByProvenance = false, fenceTa
|
|
|
20851
20807
|
}
|
|
20852
20808
|
const rawLines = content.split(/\r?\n/);
|
|
20853
20809
|
if (opts.full === true) {
|
|
20854
|
-
return
|
|
20810
|
+
return emit2(rawLines.join("\n"));
|
|
20855
20811
|
}
|
|
20856
20812
|
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 ?
|
|
20813
|
+
const headN = opts.head !== void 0 ? requireNonNegativeInt("--head", opts.head) : 30;
|
|
20814
|
+
const tailN = opts.tail !== void 0 ? requireNonNegativeInt("--tail", opts.tail) : 80;
|
|
20859
20815
|
const applyElision = (lines2, headN2, tailN2) => lines2.length > headN2 + tailN2 + 1 ? [...lines2.slice(0, headN2), "...(elided)...", ...lines2.slice(lines2.length - tailN2)] : lines2;
|
|
20860
20816
|
const noteLineCap = (which, flag, shown, total) => {
|
|
20861
20817
|
if (shown >= total) return;
|
|
@@ -20874,7 +20830,7 @@ function _applyFiltersAndPrint(content, opts, fenceByProvenance = false, fenceTa
|
|
|
20874
20830
|
result = lines.slice(Math.max(0, lines.length - tailN));
|
|
20875
20831
|
noteLineCap("last", "tail", result.length, lines.length);
|
|
20876
20832
|
}
|
|
20877
|
-
return
|
|
20833
|
+
return emit2(result.join("\n"));
|
|
20878
20834
|
}
|
|
20879
20835
|
function cmdBashOutput(id, opts) {
|
|
20880
20836
|
const parseVerifyThreshold = (optVal) => {
|
|
@@ -20895,7 +20851,7 @@ function cmdBashOutput(id, opts) {
|
|
|
20895
20851
|
}
|
|
20896
20852
|
let content;
|
|
20897
20853
|
try {
|
|
20898
|
-
const st =
|
|
20854
|
+
const st = fs45.statSync(opts.file);
|
|
20899
20855
|
if (st.isFIFO() || st.isSocket()) {
|
|
20900
20856
|
throw new CliError(`--file '${opts.file}' is a special file (FIFO or socket) \u2014 only regular files are supported`);
|
|
20901
20857
|
}
|
|
@@ -20910,7 +20866,7 @@ function cmdBashOutput(id, opts) {
|
|
|
20910
20866
|
`);
|
|
20911
20867
|
}
|
|
20912
20868
|
}
|
|
20913
|
-
content = redactIfDotenv(opts.file, decodeSource(
|
|
20869
|
+
content = redactIfDotenv(opts.file, decodeSource(fs45.readFileSync(opts.file)));
|
|
20914
20870
|
} catch (e) {
|
|
20915
20871
|
if (e instanceof CliError) throw e;
|
|
20916
20872
|
throw new CliError(`cannot read file: ${opts.file}`);
|
|
@@ -20974,15 +20930,15 @@ function cmdMcpOutput(id, opts) {
|
|
|
20974
20930
|
if (opts.file.includes("\0")) {
|
|
20975
20931
|
throw new CliError("--file path contains a null byte");
|
|
20976
20932
|
}
|
|
20977
|
-
if (!
|
|
20933
|
+
if (!fs45.existsSync(opts.file)) {
|
|
20978
20934
|
throw new CliError(`file not found: ${opts.file}`);
|
|
20979
20935
|
}
|
|
20980
20936
|
try {
|
|
20981
|
-
const st =
|
|
20937
|
+
const st = fs45.statSync(opts.file);
|
|
20982
20938
|
if (st.isFIFO() || st.isSocket()) {
|
|
20983
20939
|
throw new CliError(`--file '${opts.file}' is a special file (FIFO or socket) \u2014 only regular files are supported`);
|
|
20984
20940
|
}
|
|
20985
|
-
content = decodeSource(
|
|
20941
|
+
content = decodeSource(fs45.readFileSync(opts.file));
|
|
20986
20942
|
} catch (e) {
|
|
20987
20943
|
if (e instanceof CliError) throw e;
|
|
20988
20944
|
throw new CliError(`cannot read file: ${opts.file}`);
|
|
@@ -21003,7 +20959,7 @@ function cmdMcpOutput(id, opts) {
|
|
|
21003
20959
|
const data = extractJsonFromMcpOutput(content);
|
|
21004
20960
|
let head;
|
|
21005
20961
|
if (opts.head !== void 0) {
|
|
21006
|
-
head =
|
|
20962
|
+
head = requireNonNegativeInt("--head", opts.head);
|
|
21007
20963
|
}
|
|
21008
20964
|
const queryResult = queryJson(data, opts.jsonQuery);
|
|
21009
20965
|
const { head: _omittedHead, ...restOpts } = opts;
|
|
@@ -21055,12 +21011,12 @@ async function cmdCompress(commandArgs, opts = {}) {
|
|
|
21055
21011
|
process.exitCode = 1;
|
|
21056
21012
|
return;
|
|
21057
21013
|
}
|
|
21058
|
-
const bashRunner = await import("./token-goat-chunk-
|
|
21014
|
+
const bashRunner = await import("./token-goat-chunk-4IIU3GNS.mjs");
|
|
21059
21015
|
if (opts.compress === false) {
|
|
21060
21016
|
process.exitCode = bashRunner.runRaw(command, parseTimeout(opts.timeout, bashRunner.DEFAULT_TIMEOUT_SECONDS));
|
|
21061
21017
|
return;
|
|
21062
21018
|
}
|
|
21063
|
-
const maxTokens = opts.maxTokens !== void 0 ?
|
|
21019
|
+
const maxTokens = opts.maxTokens !== void 0 ? requireNonNegativeInt("--max-tokens", opts.maxTokens) : 0;
|
|
21064
21020
|
process.exitCode = await bashRunner.run(command, {
|
|
21065
21021
|
filterName: opts.filter,
|
|
21066
21022
|
timeout: parseTimeout(opts.timeout, bashRunner.DEFAULT_TIMEOUT_SECONDS),
|
|
@@ -21160,7 +21116,7 @@ function buildProgram() {
|
|
|
21160
21116
|
more,
|
|
21161
21117
|
() => runSymbol({
|
|
21162
21118
|
...name !== void 0 ? { name } : {},
|
|
21163
|
-
limit: opts.limit !== void 0 ?
|
|
21119
|
+
limit: opts.limit !== void 0 ? requireNonNegativeInt("--limit", opts.limit) : 20,
|
|
21164
21120
|
...opts.file !== void 0 ? { file: opts.file } : {},
|
|
21165
21121
|
...opts.kind !== void 0 ? { kind: opts.kind } : {},
|
|
21166
21122
|
...projectRoot !== void 0 ? { projectRoot } : {},
|
|
@@ -21202,8 +21158,8 @@ function buildProgram() {
|
|
|
21202
21158
|
return runBrief({
|
|
21203
21159
|
spec,
|
|
21204
21160
|
...opts.json === true ? { json: true } : {},
|
|
21205
|
-
...opts.limit !== void 0 ? { limit:
|
|
21206
|
-
...opts.context !== void 0 ? { context:
|
|
21161
|
+
...opts.limit !== void 0 ? { limit: requireNonNegativeInt("--limit", opts.limit) } : {},
|
|
21162
|
+
...opts.context !== void 0 ? { context: requireNonNegativeInt("--context", opts.context) } : {},
|
|
21207
21163
|
...opts.excludeTests === true ? { excludeTests: true } : {},
|
|
21208
21164
|
...opts.grep !== void 0 ? { grep: opts.grep } : {}
|
|
21209
21165
|
});
|
|
@@ -21211,14 +21167,26 @@ function buildProgram() {
|
|
|
21211
21167
|
);
|
|
21212
21168
|
program2.command("section <spec> [more...]").description(
|
|
21213
21169
|
'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
|
-
|
|
21170
|
+
).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) => {
|
|
21171
|
+
const maxLinesRaw = opts.maxLines ?? opts.head;
|
|
21172
|
+
const maxLines = maxLinesRaw !== void 0 ? requireNonNegativeInt("--max-lines", maxLinesRaw) : void 0;
|
|
21173
|
+
return opts.list === true ? runExit(() => {
|
|
21216
21174
|
emitExtraFileArgsNote("section --list", spec, more, { mergeable: false });
|
|
21217
21175
|
return runListSections({ file: spec, ...opts.json === true ? { json: true } : {}, ...opts.grep !== void 0 ? { grep: opts.grep } : {} });
|
|
21218
21176
|
}) : runExitText(
|
|
21219
|
-
() => noteExtraFileArgs(
|
|
21220
|
-
|
|
21221
|
-
|
|
21177
|
+
() => noteExtraFileArgs(
|
|
21178
|
+
"section",
|
|
21179
|
+
spec,
|
|
21180
|
+
more,
|
|
21181
|
+
() => runSection({
|
|
21182
|
+
spec,
|
|
21183
|
+
...opts.json === true ? { json: true } : {},
|
|
21184
|
+
...maxLines !== void 0 ? { maxLines } : {}
|
|
21185
|
+
}),
|
|
21186
|
+
{ noun: "spec", mergeable: namedSpecsMergeable([spec, ...more]) }
|
|
21187
|
+
)
|
|
21188
|
+
);
|
|
21189
|
+
});
|
|
21222
21190
|
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
21191
|
const registerSymbolListing = (name, description, run2) => {
|
|
21224
21192
|
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 +21198,7 @@ function buildProgram() {
|
|
|
21230
21198
|
() => run2({
|
|
21231
21199
|
file,
|
|
21232
21200
|
...opts.json === true ? { json: true } : {},
|
|
21233
|
-
...opts.minLines !== void 0 ? { minLines:
|
|
21201
|
+
...opts.minLines !== void 0 ? { minLines: requireNonNegativeInt("--min-lines", opts.minLines) } : {},
|
|
21234
21202
|
...opts.grep !== void 0 ? { grep: opts.grep } : {},
|
|
21235
21203
|
...opts.forceRefresh === true ? { forceRefresh: true } : {},
|
|
21236
21204
|
...opts.stats === true ? { stats: true } : {}
|
|
@@ -21259,9 +21227,9 @@ function buildProgram() {
|
|
|
21259
21227
|
spec,
|
|
21260
21228
|
...opts.callers === true ? { callers: true } : {},
|
|
21261
21229
|
...opts.json === true ? { json: true } : {},
|
|
21262
|
-
...opts.limit !== void 0 ? { limit:
|
|
21263
|
-
...opts.top !== void 0 ? { top:
|
|
21264
|
-
...opts.context !== void 0 ? { context:
|
|
21230
|
+
...opts.limit !== void 0 ? { limit: requireNonNegativeInt("--limit", opts.limit) } : {},
|
|
21231
|
+
...opts.top !== void 0 ? { top: requireNonNegativeInt("--top", opts.top) } : {},
|
|
21232
|
+
...opts.context !== void 0 ? { context: requireNonNegativeInt("--context", opts.context) } : {},
|
|
21265
21233
|
...opts.excludeTests === true ? { excludeTests: true } : {},
|
|
21266
21234
|
...opts.grep !== void 0 ? { grep: opts.grep } : {}
|
|
21267
21235
|
});
|
|
@@ -21275,7 +21243,7 @@ function buildProgram() {
|
|
|
21275
21243
|
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
21244
|
(opts) => runExitText(
|
|
21277
21245
|
() => runBenchCommand({
|
|
21278
|
-
corpus: opts.corpus ??
|
|
21246
|
+
corpus: opts.corpus ?? path41.join("tests", "fixtures", "bench"),
|
|
21279
21247
|
...opts.tsv !== void 0 ? { tsv: opts.tsv } : {},
|
|
21280
21248
|
...opts.validate === true ? { validate: true } : {},
|
|
21281
21249
|
...opts.json === true ? { json: true } : {}
|
|
@@ -21309,7 +21277,7 @@ function buildProgram() {
|
|
|
21309
21277
|
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
21278
|
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
21279
|
(opts) => guard(async () => {
|
|
21312
|
-
const { cmdUpgrade } = await import("./token-goat-chunk-
|
|
21280
|
+
const { cmdUpgrade } = await import("./token-goat-chunk-ZJWPJL7O.mjs");
|
|
21313
21281
|
await cmdUpgrade(opts, () => cmdInstall({}));
|
|
21314
21282
|
})()
|
|
21315
21283
|
);
|
|
@@ -21379,6 +21347,9 @@ async function run(argv = process.argv) {
|
|
|
21379
21347
|
}
|
|
21380
21348
|
|
|
21381
21349
|
export {
|
|
21350
|
+
requireInt,
|
|
21351
|
+
requireNonNegativeInt,
|
|
21352
|
+
requirePositiveInt,
|
|
21382
21353
|
expandGlobs,
|
|
21383
21354
|
fenceFileText,
|
|
21384
21355
|
fenceFileFieldIfMatched,
|
|
@@ -21438,9 +21409,6 @@ export {
|
|
|
21438
21409
|
CliError,
|
|
21439
21410
|
out,
|
|
21440
21411
|
err,
|
|
21441
|
-
requireInt2 as requireInt,
|
|
21442
|
-
requireNonNegativeInt2 as requireNonNegativeInt,
|
|
21443
|
-
requirePositiveInt2 as requirePositiveInt,
|
|
21444
21412
|
cmdIndex,
|
|
21445
21413
|
visualStudioManualSteps,
|
|
21446
21414
|
leftoverIntegrations,
|