token-goat 2.8.0 → 2.8.2
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 +8 -6
- package/dist/{token-goat-chunk-VXSYZGBA.mjs → token-goat-chunk-2MWF3OGR.mjs} +226 -20
- package/dist/{token-goat-chunk-AO6MFFTW.mjs → token-goat-chunk-5MLXFSRI.mjs} +6 -6
- package/dist/{token-goat-chunk-FBGBTICM.mjs → token-goat-chunk-AL644JUV.mjs} +3 -3
- package/dist/{token-goat-chunk-2F6TFBZE.mjs → token-goat-chunk-AM23GDIS.mjs} +121 -15
- package/dist/{token-goat-chunk-4KZILRZN.mjs → token-goat-chunk-BTZSUIYA.mjs} +2 -2
- package/dist/{token-goat-chunk-44Y77VHR.mjs → token-goat-chunk-IVCTQPZD.mjs} +129 -7
- package/dist/{token-goat-chunk-A62K4XW2.mjs → token-goat-chunk-JU7QESB3.mjs} +5 -5
- package/dist/{token-goat-chunk-LVCBDJVE.mjs → token-goat-chunk-KBVN4ELV.mjs} +5 -5
- package/dist/{token-goat-chunk-SRAR6DOK.mjs → token-goat-chunk-LILS6TIU.mjs} +97 -13
- package/dist/{token-goat-chunk-J35AKWEQ.mjs → token-goat-chunk-SE6V7LUZ.mjs} +5 -5
- package/dist/{token-goat-chunk-TUPJRK7R.mjs → token-goat-chunk-TF5NT3H5.mjs} +14 -14
- package/dist/token-goat-hook.mjs +5 -5
- package/dist/token-goat.core.mjs +5 -5
- package/package.json +4 -2
|
@@ -2,6 +2,7 @@ import { createRequire as __cjsRequire } from 'node:module';
|
|
|
2
2
|
const require = __cjsRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
4
|
ALL_SYMBOLS_IN_FILE_LIMIT,
|
|
5
|
+
AMBIGUOUS_HEADING_LIMIT,
|
|
5
6
|
CONTENT_MAX_INPUT_CHARS,
|
|
6
7
|
WHOLE_FILE_NOTE_SYMBOL,
|
|
7
8
|
compressText,
|
|
@@ -60,6 +61,7 @@ import {
|
|
|
60
61
|
runOpenApiOutline,
|
|
61
62
|
runOutline,
|
|
62
63
|
runPdfExtractText,
|
|
64
|
+
runPdfLocate,
|
|
63
65
|
runPdfMeta,
|
|
64
66
|
runPdfOutline,
|
|
65
67
|
runPrSlice,
|
|
@@ -84,7 +86,7 @@ import {
|
|
|
84
86
|
runZipRead,
|
|
85
87
|
symbolNamesInFile,
|
|
86
88
|
upsertNote
|
|
87
|
-
} from "./token-goat-chunk-
|
|
89
|
+
} from "./token-goat-chunk-LILS6TIU.mjs";
|
|
88
90
|
import {
|
|
89
91
|
BASH_OUTPUT_SUBDIR,
|
|
90
92
|
GEMINI_TOOL_NAME_MAP,
|
|
@@ -111,7 +113,7 @@ import {
|
|
|
111
113
|
searchRecall,
|
|
112
114
|
storeWebOutput,
|
|
113
115
|
summarizeResidentContext
|
|
114
|
-
} from "./token-goat-chunk-
|
|
116
|
+
} from "./token-goat-chunk-5MLXFSRI.mjs";
|
|
115
117
|
import {
|
|
116
118
|
AGENT_SALT_MARKER,
|
|
117
119
|
CONTEXT_AUTOCOMPACT_TOKENS,
|
|
@@ -254,7 +256,7 @@ import {
|
|
|
254
256
|
vscodeDecoderConfigured,
|
|
255
257
|
walkProject,
|
|
256
258
|
writeCompact
|
|
257
|
-
} from "./token-goat-chunk-
|
|
259
|
+
} from "./token-goat-chunk-AM23GDIS.mjs";
|
|
258
260
|
import {
|
|
259
261
|
C,
|
|
260
262
|
CONFIG_KEY_ENV_OVERRIDES,
|
|
@@ -307,6 +309,7 @@ import {
|
|
|
307
309
|
parse,
|
|
308
310
|
pushAll,
|
|
309
311
|
readConfigSource,
|
|
312
|
+
readUnmappedTools,
|
|
310
313
|
recordStat,
|
|
311
314
|
redactIfDotenv,
|
|
312
315
|
redactUrlQuery,
|
|
@@ -335,11 +338,14 @@ import {
|
|
|
335
338
|
withFileLock,
|
|
336
339
|
withRetryOnLock,
|
|
337
340
|
writeJsonSettings
|
|
338
|
-
} from "./token-goat-chunk-
|
|
341
|
+
} from "./token-goat-chunk-IVCTQPZD.mjs";
|
|
339
342
|
import {
|
|
340
343
|
__export
|
|
341
344
|
} from "./token-goat-chunk-AEX54RUZ.mjs";
|
|
342
345
|
|
|
346
|
+
// src/cli.ts
|
|
347
|
+
import { randomBytes } from "node:crypto";
|
|
348
|
+
|
|
343
349
|
// node_modules/commander/lib/error.js
|
|
344
350
|
var CommanderError = class extends Error {
|
|
345
351
|
/**
|
|
@@ -4081,7 +4087,8 @@ var PI_EXTENSION_SCRIPT = `// token-goat bridge extension for pi (pi-coding-agen
|
|
|
4081
4087
|
// Bridges pi's extension events to token-goat's subprocess hook protocol.
|
|
4082
4088
|
// https://github.com/DFKHelper/token-goat
|
|
4083
4089
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
4084
|
-
import { spawnSync } from "node:child_process"
|
|
4090
|
+
import { spawnSync } from "node:child_process"
|
|
4091
|
+
import crypto from "node:crypto";
|
|
4085
4092
|
import * as fs from "node:fs";
|
|
4086
4093
|
import * as os from "node:os";
|
|
4087
4094
|
import * as path from "node:path";
|
|
@@ -4540,6 +4547,7 @@ var OPENCODE_PLUGIN_SCRIPT = `// token-goat bridge plugin for opencode
|
|
|
4540
4547
|
// Bridges opencode's plugin hooks to token-goat's subprocess hook protocol.
|
|
4541
4548
|
// https://github.com/DFKHelper/token-goat
|
|
4542
4549
|
import { spawnSync } from "node:child_process"
|
|
4550
|
+
import crypto from "node:crypto"
|
|
4543
4551
|
import fs from "node:fs"
|
|
4544
4552
|
import os from "node:os"
|
|
4545
4553
|
import path from "node:path"
|
|
@@ -5012,11 +5020,23 @@ var NO_SERVER_HANDLER_REASON = "token-goat has no registered server-side handler
|
|
|
5012
5020
|
var NO_POST_COMPACT_EVENT_REASON = "post_compact is a Claude Code event (hook_event_name PostCompact, carrying compact_summary); no equivalent has been confirmed for this harness, so it is left unwired rather than guessed at";
|
|
5013
5021
|
var NO_SEPARATE_FAILURE_EVENT_REASON = "post_tool_use_failure exists because Copilot CLI routes a failed tool result to a separate postToolUseFailure event instead of postToolUse. No separate failure event is wired for this harness, so a failed tool call either arrives on post_tool_use like any other result or is not seen; which of the two has not been checked here";
|
|
5014
5022
|
var COPILOT_NO_POST_COMPACT_REASON = "Copilot CLI has no post-compaction hook: its HookType enum (schemas/api.schema.json, 1.0.79 and 1.0.80) declares preCompact and no postCompact, and both preCompact call sites in app.js await the hook and never assign its result. Whether the summary is reachable another way is open. app.js does emit session.compaction_complete carrying summaryContent, and the session event writer subscribes to '*' -- but emit() vs emitEphemeral() does NOT gate that writer: dispatchEventHandlers runs outside the ephemeral branch in emitInternal, on('*') early-returns past every filter, and the writer's callback applies no filter of its own before handing the JSON to native recordEventJson. The durable-vs-ephemeral decision is in Rust (api_session_event_writer.rs) and was not readable. Nor is the event uniformly summary-bearing: two of the four emit sites are the branches taken when no summary exists, summaryContent is optional in the schema, and the relay session class emits the same event via emitEphemeral. No compaction has ever been observed on the machines checked, so nothing empirical anchors any of it. Context can be written back on the next turn through userPromptSubmitted additionalContext";
|
|
5023
|
+
var VERIFICATION_RANK = {
|
|
5024
|
+
dogfooded: 0,
|
|
5025
|
+
sourced: 1,
|
|
5026
|
+
documented: 2
|
|
5027
|
+
};
|
|
5028
|
+
var VERIFICATION_BLURB = {
|
|
5029
|
+
dogfooded: "driven against the real harness binary",
|
|
5030
|
+
sourced: "wire format read from the harness's own source or declarations, never driven against it",
|
|
5031
|
+
documented: "wired from the harness's documentation only, never driven against it"
|
|
5032
|
+
};
|
|
5015
5033
|
var BRIDGE_CAPABILITY_MATRIX = [
|
|
5016
5034
|
{
|
|
5017
5035
|
harness: "claudecode",
|
|
5018
5036
|
label: "Claude Code",
|
|
5019
5037
|
sourceFile: "src/install.ts (HOOK_EVENT_MAP)",
|
|
5038
|
+
verification: "dogfooded",
|
|
5039
|
+
verificationNote: "The harness this repo is developed and released under; CLAUDE.md requires every CLI/hook change be run against the built binary here before it ships.",
|
|
5020
5040
|
implemented: /* @__PURE__ */ new Set(["pre_tool_use", "post_tool_use", "pre_compact", "post_compact", "user_prompt_submit", "subagent_stop", "session_start"]),
|
|
5021
5041
|
reasons: [
|
|
5022
5042
|
{ events: ["post_tool_use_failure"], reason: NO_SEPARATE_FAILURE_EVENT_REASON },
|
|
@@ -5027,6 +5047,8 @@ var BRIDGE_CAPABILITY_MATRIX = [
|
|
|
5027
5047
|
harness: "codex",
|
|
5028
5048
|
label: "Codex CLI",
|
|
5029
5049
|
sourceFile: "src/bridges/codex_install.ts (CODEX_HOOK_EVENTS, CODEX_GLOBAL_HOOK_EVENTS)",
|
|
5050
|
+
verification: "sourced",
|
|
5051
|
+
verificationNote: "Wire format pinned to Codex 0.137.0+'s declared hookSpecificOutput schema (src/bridges/codex.ts); no run against a Codex binary is recorded here.",
|
|
5030
5052
|
implemented: /* @__PURE__ */ new Set(["pre_tool_use", "post_tool_use", "pre_compact", "user_prompt_submit", "subagent_stop"]),
|
|
5031
5053
|
reasons: [
|
|
5032
5054
|
{ events: ["post_tool_use_failure"], reason: NO_SEPARATE_FAILURE_EVENT_REASON },
|
|
@@ -5042,6 +5064,8 @@ var BRIDGE_CAPABILITY_MATRIX = [
|
|
|
5042
5064
|
harness: "grok",
|
|
5043
5065
|
label: "Grok CLI",
|
|
5044
5066
|
sourceFile: "src/bridges/grok_install.ts (GROK_HOOK_EVENTS)",
|
|
5067
|
+
verification: "dogfooded",
|
|
5068
|
+
verificationNote: "grok 0.2.93, 2026-07-09: observed executing the global settings.json hooks config unmodified and setting GROK_SESSION_ID on every hook subprocess (src/bridges/registry.ts, src/hooks_cli.ts).",
|
|
5045
5069
|
implemented: /* @__PURE__ */ new Set(["pre_tool_use", "post_tool_use", "pre_compact", "user_prompt_submit", "subagent_stop"]),
|
|
5046
5070
|
reasons: [
|
|
5047
5071
|
{ events: ["post_tool_use_failure"], reason: NO_SEPARATE_FAILURE_EVENT_REASON },
|
|
@@ -5106,6 +5130,8 @@ var BRIDGE_CAPABILITY_MATRIX = [
|
|
|
5106
5130
|
harness: "copilot_cli",
|
|
5107
5131
|
label: "Copilot CLI",
|
|
5108
5132
|
sourceFile: "src/bridges/copilot_cli_install.ts (COPILOT_CLI_HOOK_EVENTS), src/bridges/copilot_cli.ts (COPILOT_TO_TG_EVENT)",
|
|
5133
|
+
verification: "dogfooded",
|
|
5134
|
+
verificationNote: "doctor's checkCopilotCli drives the installed shim end to end, and every hook payload field is cross-checked against Copilot's own declarations pinned at 1.0.80 (schemas/copilot_cli.hooks.json).",
|
|
5109
5135
|
implemented: /* @__PURE__ */ new Set([
|
|
5110
5136
|
"session_start",
|
|
5111
5137
|
"pre_tool_use",
|
|
@@ -5128,6 +5154,8 @@ var BRIDGE_CAPABILITY_MATRIX = [
|
|
|
5128
5154
|
harness: "gemini",
|
|
5129
5155
|
label: "Gemini CLI",
|
|
5130
5156
|
sourceFile: "src/bridges/gemini_install.ts (GEMINI_HOOK_EVENTS)",
|
|
5157
|
+
verification: "sourced",
|
|
5158
|
+
verificationNote: "Verified against Gemini CLI's published hooks reference (src/bridges/gemini_install.ts); no run against a Gemini binary is recorded here.",
|
|
5131
5159
|
implemented: /* @__PURE__ */ new Set(["pre_tool_use", "post_tool_use", "pre_compact"]),
|
|
5132
5160
|
reasons: [
|
|
5133
5161
|
{ events: ["post_tool_use_failure"], reason: NO_SEPARATE_FAILURE_EVENT_REASON },
|
|
@@ -5142,6 +5170,8 @@ var BRIDGE_CAPABILITY_MATRIX = [
|
|
|
5142
5170
|
harness: "qwen",
|
|
5143
5171
|
label: "Qwen Code",
|
|
5144
5172
|
sourceFile: "src/bridges/qwen_install.ts (QWEN_HOOK_EVENTS)",
|
|
5173
|
+
verification: "documented",
|
|
5174
|
+
verificationNote: "Wired from QwenLM/qwen-code's hooks.md, which src/bridges/qwen_install.ts states was not live-tested against a running install.",
|
|
5145
5175
|
implemented: /* @__PURE__ */ new Set(["pre_tool_use", "post_tool_use", "pre_compact", "user_prompt_submit", "subagent_stop"]),
|
|
5146
5176
|
reasons: [
|
|
5147
5177
|
{ events: ["post_tool_use_failure"], reason: NO_SEPARATE_FAILURE_EVENT_REASON },
|
|
@@ -5161,6 +5191,8 @@ var BRIDGE_CAPABILITY_MATRIX = [
|
|
|
5161
5191
|
harness: "kimi",
|
|
5162
5192
|
label: "Kimi Code CLI",
|
|
5163
5193
|
sourceFile: "src/bridges/kimi_install.ts (KIMI_EVENT_ARG), src/bridges/kimi.ts (KIMI_HOOK_SCRIPT)",
|
|
5194
|
+
verification: "sourced",
|
|
5195
|
+
verificationNote: "Payload keys and response contract read from MoonshotAI/kimi-code's own source (externalHooksRunner/runner.ts, externalHooksService.ts); no run against a Kimi binary is recorded here.",
|
|
5164
5196
|
implemented: /* @__PURE__ */ new Set(["pre_tool_use", "post_tool_use", "pre_compact", "user_prompt_submit", "subagent_stop", "session_start"]),
|
|
5165
5197
|
reasons: [
|
|
5166
5198
|
{ events: ["post_tool_use_failure"], reason: NO_SEPARATE_FAILURE_EVENT_REASON },
|
|
@@ -5172,6 +5204,8 @@ var BRIDGE_CAPABILITY_MATRIX = [
|
|
|
5172
5204
|
harness: "opencode",
|
|
5173
5205
|
label: "opencode",
|
|
5174
5206
|
sourceFile: "src/bridges/opencode.ts",
|
|
5207
|
+
verification: "sourced",
|
|
5208
|
+
verificationNote: "Tool ids, parameter keys and handler behavior read directly from opencode's own source (src/bridges/opencode.ts); no run against a running gateway is recorded here.",
|
|
5175
5209
|
implemented: /* @__PURE__ */ new Set(["pre_tool_use", "post_tool_use", "pre_compact"]),
|
|
5176
5210
|
reasons: [
|
|
5177
5211
|
{ events: ["post_tool_use_failure"], reason: NO_SEPARATE_FAILURE_EVENT_REASON },
|
|
@@ -5186,6 +5220,8 @@ var BRIDGE_CAPABILITY_MATRIX = [
|
|
|
5186
5220
|
harness: "openclaw",
|
|
5187
5221
|
label: "OpenClaw",
|
|
5188
5222
|
sourceFile: "src/bridges/openclaw.ts",
|
|
5223
|
+
verification: "sourced",
|
|
5224
|
+
verificationNote: "Verified against the live plugin docs and OpenClaw's aristotle-agent/types.ts; the bridge's own note lists what stays unverified without a live instance (built-in tool names, session id).",
|
|
5189
5225
|
implemented: /* @__PURE__ */ new Set(["pre_tool_use", "post_tool_use", "pre_compact"]),
|
|
5190
5226
|
reasons: [
|
|
5191
5227
|
{ events: ["post_tool_use_failure"], reason: NO_SEPARATE_FAILURE_EVENT_REASON },
|
|
@@ -5200,6 +5236,8 @@ var BRIDGE_CAPABILITY_MATRIX = [
|
|
|
5200
5236
|
harness: "pi",
|
|
5201
5237
|
label: "pi (pi-coding-agent)",
|
|
5202
5238
|
sourceFile: "src/bridges/pi.ts",
|
|
5239
|
+
verification: "sourced",
|
|
5240
|
+
verificationNote: "Response shape verified against pi's own TextContent/ImageContent types (src/bridges/pi.ts); no run against a pi binary is recorded here.",
|
|
5203
5241
|
implemented: /* @__PURE__ */ new Set(["pre_tool_use", "post_tool_use", "pre_compact"]),
|
|
5204
5242
|
reasons: [
|
|
5205
5243
|
{ events: ["post_tool_use_failure"], reason: NO_SEPARATE_FAILURE_EVENT_REASON },
|
|
@@ -5223,7 +5261,15 @@ function bridgesStatusToJson(matrix = BRIDGE_CAPABILITY_MATRIX) {
|
|
|
5223
5261
|
reasons[event] = reason;
|
|
5224
5262
|
}
|
|
5225
5263
|
}
|
|
5226
|
-
return {
|
|
5264
|
+
return {
|
|
5265
|
+
harness: row.harness,
|
|
5266
|
+
label: row.label,
|
|
5267
|
+
sourceFile: row.sourceFile,
|
|
5268
|
+
verification: row.verification,
|
|
5269
|
+
verificationNote: row.verificationNote,
|
|
5270
|
+
events,
|
|
5271
|
+
reasons
|
|
5272
|
+
};
|
|
5227
5273
|
});
|
|
5228
5274
|
}
|
|
5229
5275
|
function formatBridgesStatus(matrix = BRIDGE_CAPABILITY_MATRIX) {
|
|
@@ -5234,7 +5280,8 @@ function formatBridgesStatus(matrix = BRIDGE_CAPABILITY_MATRIX) {
|
|
|
5234
5280
|
lines.push("Read-only static analysis of src/bridges/*_install.ts and *.ts -- never invokes a real harness binary.");
|
|
5235
5281
|
lines.push("");
|
|
5236
5282
|
const harnessWidth = Math.max(...matrix.map((r) => r.harness.length), "harness".length);
|
|
5237
|
-
const
|
|
5283
|
+
const verifyWidth = Math.max(...matrix.map((r) => r.verification.length), "verified".length);
|
|
5284
|
+
const header = ["harness".padEnd(harnessWidth), ...HOOK_EVENTS.map((e) => e), "score", "verified".padEnd(verifyWidth)].join(" ");
|
|
5238
5285
|
lines.push(header);
|
|
5239
5286
|
for (const row of matrix) {
|
|
5240
5287
|
const cells = HOOK_EVENTS.map((event) => {
|
|
@@ -5242,7 +5289,16 @@ function formatBridgesStatus(matrix = BRIDGE_CAPABILITY_MATRIX) {
|
|
|
5242
5289
|
return cell.padEnd(event.length);
|
|
5243
5290
|
});
|
|
5244
5291
|
const score = `${row.implemented.size}/${HOOK_EVENTS.length}`;
|
|
5245
|
-
lines.push([row.harness.padEnd(harnessWidth), ...cells, score].join(" "));
|
|
5292
|
+
lines.push([row.harness.padEnd(harnessWidth), ...cells, score, row.verification.padEnd(verifyWidth)].join(" "));
|
|
5293
|
+
}
|
|
5294
|
+
lines.push("");
|
|
5295
|
+
lines.push("## How each row was established");
|
|
5296
|
+
for (const level of Object.keys(VERIFICATION_RANK)) {
|
|
5297
|
+
lines.push(`- ${level}: ${VERIFICATION_BLURB[level]}`);
|
|
5298
|
+
}
|
|
5299
|
+
lines.push("");
|
|
5300
|
+
for (const row of [...matrix].sort((a, b) => VERIFICATION_RANK[a.verification] - VERIFICATION_RANK[b.verification])) {
|
|
5301
|
+
lines.push(`- ${row.harness} (${row.verification}): ${row.verificationNote}`);
|
|
5246
5302
|
}
|
|
5247
5303
|
const gapRows = matrix.filter((r) => r.reasons.length > 0);
|
|
5248
5304
|
if (gapRows.length > 0) {
|
|
@@ -5256,6 +5312,11 @@ function formatBridgesStatus(matrix = BRIDGE_CAPABILITY_MATRIX) {
|
|
|
5256
5312
|
}
|
|
5257
5313
|
return lines.join("\n");
|
|
5258
5314
|
}
|
|
5315
|
+
function installVerificationNotice(harness) {
|
|
5316
|
+
const row = BRIDGE_CAPABILITY_MATRIX.find((r) => r.harness === harness);
|
|
5317
|
+
if (row === void 0 || row.verification === "dogfooded") return null;
|
|
5318
|
+
return `NOTE: the ${row.label} bridge is ${row.verification} -- ${VERIFICATION_BLURB[row.verification]}. If a token-goat feature seems to do nothing here, run \`token-goat doctor\` (its "Tool names" check reports what ${row.label} actually sent) and please open an issue. Details: token-goat bridges-status.`;
|
|
5319
|
+
}
|
|
5259
5320
|
|
|
5260
5321
|
// src/sharepoint_resolve.ts
|
|
5261
5322
|
import * as fs8 from "node:fs";
|
|
@@ -5673,6 +5734,7 @@ function runStats(opts = {}) {
|
|
|
5673
5734
|
by_project: summary.by_project,
|
|
5674
5735
|
by_command: summary.by_command,
|
|
5675
5736
|
by_source: summary.by_source,
|
|
5737
|
+
by_harness: summary.by_harness,
|
|
5676
5738
|
window_days: summary.window_days
|
|
5677
5739
|
};
|
|
5678
5740
|
process.stdout.write(JSON.stringify(out2) + "\n");
|
|
@@ -5767,7 +5829,9 @@ function checkMcpProcessHealth(processes) {
|
|
|
5767
5829
|
const nodeProcesses = processes.filter((process3) => process3.name.toLowerCase() === "node.exe");
|
|
5768
5830
|
const chromeLaunchers = nodeProcesses.filter((process3) => /npx-cli\.js.*chrome-devtools-mcp/i.test(process3.commandLine));
|
|
5769
5831
|
const playwrightLaunchers = nodeProcesses.filter((process3) => /npx-cli\.js.*@playwright[\\/]mcp/i.test(process3.commandLine));
|
|
5770
|
-
const orphanedNodeProcesses = nodeProcesses.filter(
|
|
5832
|
+
const orphanedNodeProcesses = nodeProcesses.filter(
|
|
5833
|
+
(process3) => !byPid.has(process3.parentProcessId) && !/--worker-daemon\b/.test(process3.commandLine)
|
|
5834
|
+
);
|
|
5771
5835
|
const launchers = chromeLaunchers.length + playwrightLaunchers.length;
|
|
5772
5836
|
if (launchers > 2 || orphanedNodeProcesses.length > 0) {
|
|
5773
5837
|
const details = [];
|
|
@@ -6211,6 +6275,38 @@ function checkCompactionChannel(dbPath) {
|
|
|
6211
6275
|
return { name, status: "warn", message: `could not read compaction stats: ${extractErrorMessage(e)}` };
|
|
6212
6276
|
}
|
|
6213
6277
|
}
|
|
6278
|
+
var UNMAPPED_TOOL_SAMPLE = 5;
|
|
6279
|
+
function checkUnmappedTools(dbPath) {
|
|
6280
|
+
const name = "Tool names";
|
|
6281
|
+
if (!fs12.existsSync(dbPath)) {
|
|
6282
|
+
return { name, status: "ok", message: "no database yet" };
|
|
6283
|
+
}
|
|
6284
|
+
try {
|
|
6285
|
+
const rows = readUnmappedTools(dbPath);
|
|
6286
|
+
if (rows.length === 0) {
|
|
6287
|
+
return { name, status: "ok", message: "every tool name seen so far reached a handler that wanted it" };
|
|
6288
|
+
}
|
|
6289
|
+
const nearMisses = rows.filter((r) => r.near_miss !== null && r.near_miss !== void 0);
|
|
6290
|
+
if (nearMisses.length > 0) {
|
|
6291
|
+
const shown2 = nearMisses.slice(0, UNMAPPED_TOOL_SAMPLE).map((r) => `${r.harness} sent "${r.tool_name}" where "${r.near_miss}" is handled (${r.event_name}, ${r.hits}x)`);
|
|
6292
|
+
const more2 = nearMisses.length > UNMAPPED_TOOL_SAMPLE ? ` (+${nearMisses.length - UNMAPPED_TOOL_SAMPLE} more)` : "";
|
|
6293
|
+
return {
|
|
6294
|
+
name,
|
|
6295
|
+
status: "warn",
|
|
6296
|
+
message: `${shown2.join("; ")}${more2} -- these differ only by case or separators, so that bridge's tool-rename step is very likely not being applied and every handler behind those names is inert`
|
|
6297
|
+
};
|
|
6298
|
+
}
|
|
6299
|
+
const shown = rows.slice(0, UNMAPPED_TOOL_SAMPLE).map((r) => `${r.tool_name} (${r.hits}x)`);
|
|
6300
|
+
const more = rows.length > UNMAPPED_TOOL_SAMPLE ? `, +${rows.length - UNMAPPED_TOOL_SAMPLE} more` : "";
|
|
6301
|
+
return {
|
|
6302
|
+
name,
|
|
6303
|
+
status: "ok",
|
|
6304
|
+
message: `${rows.length} tool name(s) seen with no handler, none resembling one token-goat handles: ${shown.join(", ")}${more}`
|
|
6305
|
+
};
|
|
6306
|
+
} catch (e) {
|
|
6307
|
+
return { name, status: "warn", message: `could not read the tool-name histogram: ${extractErrorMessage(e)}` };
|
|
6308
|
+
}
|
|
6309
|
+
}
|
|
6214
6310
|
function runDoctor(dataDir2, configPath2, rootDir, processes) {
|
|
6215
6311
|
const results = [];
|
|
6216
6312
|
const actualDataDir = dataDir2 || dataDir();
|
|
@@ -6223,6 +6319,7 @@ function runDoctor(dataDir2, configPath2, rootDir, processes) {
|
|
|
6223
6319
|
results.push(checkSymbolCount(path11.join(actualDataDir, "global.db"), rootDir));
|
|
6224
6320
|
results.push(checkDirtyQueueHealth(actualDataDir));
|
|
6225
6321
|
results.push(checkCompactionChannel(path11.join(actualDataDir, "global.db")));
|
|
6322
|
+
results.push(checkUnmappedTools(path11.join(actualDataDir, "global.db")));
|
|
6226
6323
|
const actualConfigPath = configPath2 || configPath();
|
|
6227
6324
|
results.push(checkConfigValid(actualConfigPath));
|
|
6228
6325
|
results.push(checkEmbeddings(loadConfig(rootDir)));
|
|
@@ -9118,6 +9215,10 @@ var GO_FAIL = /^--- FAIL:\s+(\S+)/;
|
|
|
9118
9215
|
var CARGO_FAIL = /^test (\S+) \.\.\. FAILED/;
|
|
9119
9216
|
var CARGO_SECTION = /^---- (\S+) (?:stdout|stderr) ----$/;
|
|
9120
9217
|
var CARGO_RESULT = /^test result:/;
|
|
9218
|
+
var VITEST_FAIL_HEADER = /^\s+FAIL\s+(.+?)\s*$/;
|
|
9219
|
+
var VITEST_BANNER = /⎯+\s*Failed Tests\s+\d+\s*⎯+/;
|
|
9220
|
+
var VITEST_SEPARATOR = /^⎯+.*⎯+$/;
|
|
9221
|
+
var VITEST_SUMMARY = /^\s*(Test Files|Tests|Start at|Duration)\s/;
|
|
9121
9222
|
function detectRunner(text) {
|
|
9122
9223
|
if (text.includes("=== FAILURES ===") || text.includes("=== ERRORS ===")) {
|
|
9123
9224
|
return "pytest";
|
|
@@ -9125,6 +9226,9 @@ function detectRunner(text) {
|
|
|
9125
9226
|
if (/\bFAILED\b.+::test_/.test(text) || /short test summary/i.test(text)) {
|
|
9126
9227
|
return "pytest";
|
|
9127
9228
|
}
|
|
9229
|
+
if (VITEST_BANNER.test(text) || /^\s*Test Files\s+/m.test(text) && /^\s*Tests\s+\d+\s+(failed|passed)/m.test(text)) {
|
|
9230
|
+
return "vitest";
|
|
9231
|
+
}
|
|
9128
9232
|
if (/^\s+●\s/m.test(text) || /^FAIL\s+\S+\.test\b/m.test(text)) {
|
|
9129
9233
|
return "jest";
|
|
9130
9234
|
}
|
|
@@ -9249,6 +9353,44 @@ function extractJest(lines) {
|
|
|
9249
9353
|
}
|
|
9250
9354
|
return result;
|
|
9251
9355
|
}
|
|
9356
|
+
function extractVitest(lines) {
|
|
9357
|
+
const result = { runner: "vitest", blocks: [], summaryLines: [], statsLine: "" };
|
|
9358
|
+
let inBlock = false;
|
|
9359
|
+
let currentName = "";
|
|
9360
|
+
let currentBody = [];
|
|
9361
|
+
const flush = () => {
|
|
9362
|
+
if (inBlock && currentName) result.blocks.push({ name: currentName, body: currentBody.join("\n").trimEnd() });
|
|
9363
|
+
inBlock = false;
|
|
9364
|
+
currentName = "";
|
|
9365
|
+
currentBody = [];
|
|
9366
|
+
};
|
|
9367
|
+
for (const line of lines) {
|
|
9368
|
+
const s = line.trimEnd();
|
|
9369
|
+
const header = VITEST_FAIL_HEADER.exec(s);
|
|
9370
|
+
if (header) {
|
|
9371
|
+
flush();
|
|
9372
|
+
currentName = header[1] ?? "";
|
|
9373
|
+
currentBody = [];
|
|
9374
|
+
inBlock = true;
|
|
9375
|
+
result.summaryLines.push(currentName);
|
|
9376
|
+
continue;
|
|
9377
|
+
}
|
|
9378
|
+
if (VITEST_SUMMARY.test(s)) {
|
|
9379
|
+
if (/^\s*Tests\s/.test(s)) result.statsLine = s.trim();
|
|
9380
|
+
flush();
|
|
9381
|
+
continue;
|
|
9382
|
+
}
|
|
9383
|
+
if (inBlock) {
|
|
9384
|
+
if (VITEST_SEPARATOR.test(s)) {
|
|
9385
|
+
flush();
|
|
9386
|
+
continue;
|
|
9387
|
+
}
|
|
9388
|
+
currentBody.push(s);
|
|
9389
|
+
}
|
|
9390
|
+
}
|
|
9391
|
+
flush();
|
|
9392
|
+
return result;
|
|
9393
|
+
}
|
|
9252
9394
|
function extractGo(lines) {
|
|
9253
9395
|
const result = {
|
|
9254
9396
|
runner: "go",
|
|
@@ -9371,6 +9513,9 @@ function extractFailures(text, options) {
|
|
|
9371
9513
|
if (detected === "pytest") {
|
|
9372
9514
|
return extractPytest(lines);
|
|
9373
9515
|
}
|
|
9516
|
+
if (detected === "vitest") {
|
|
9517
|
+
return extractVitest(lines);
|
|
9518
|
+
}
|
|
9374
9519
|
if (detected === "jest") {
|
|
9375
9520
|
return extractJest(lines);
|
|
9376
9521
|
}
|
|
@@ -9836,7 +9981,7 @@ function parseNodeBlock(lines, start) {
|
|
|
9836
9981
|
}
|
|
9837
9982
|
return { block: { frames, exception: header }, nextIndex: i };
|
|
9838
9983
|
}
|
|
9839
|
-
var RUST_PANIC_HEADER_RE = /^thread '[^']*' panicked at (
|
|
9984
|
+
var RUST_PANIC_HEADER_RE = /^thread '[^']*' panicked at ([^:\r\n]+):(\d+):(\d+):\s*$/;
|
|
9840
9985
|
var RUST_BACKTRACE_NOTE_RE = /^note: run with `RUST_BACKTRACE=1`/;
|
|
9841
9986
|
var RUST_BACKTRACE_NUM_RE = /^\s*\d+:\s+(.+)$/;
|
|
9842
9987
|
var RUST_BACKTRACE_AT_RE = /^\s+at\s+(.+):(\d+):(\d+)\s*$/;
|
|
@@ -9882,7 +10027,7 @@ function parseRustBlock(lines, start) {
|
|
|
9882
10027
|
}
|
|
9883
10028
|
return { block: { frames: [panicFrame], exception }, nextIndex: i };
|
|
9884
10029
|
}
|
|
9885
|
-
var JVM_HEADER_RE = /^(?:Exception in thread "[^"]*" )?(?:Caused by: )?((?:[A-Za-z_$][\w$]*\.)+[A-Za-z_$][\w$]*): (.*)$/;
|
|
10030
|
+
var JVM_HEADER_RE = /^(?:Exception in thread "[^"\r\n]*" )?(?:Caused by: )?((?:[A-Za-z_$][\w$]*\.)+[A-Za-z_$][\w$]*): (.*)$/;
|
|
9886
10031
|
var JVM_FRAME_RE = /^\s+at\s+(\S+)\(([^)]*)\)\s*$/;
|
|
9887
10032
|
var JVM_MORE_RE = /^\s*\.\.\.\s+\d+\s+more\s*$/;
|
|
9888
10033
|
function parseJvmFrameLine(line) {
|
|
@@ -13898,7 +14043,7 @@ async function cmdMcpServe() {
|
|
|
13898
14043
|
let StdioServerTransport;
|
|
13899
14044
|
try {
|
|
13900
14045
|
;
|
|
13901
|
-
({ createMcpServer } = await import("./token-goat-chunk-
|
|
14046
|
+
({ createMcpServer } = await import("./token-goat-chunk-AL644JUV.mjs"));
|
|
13902
14047
|
({ StdioServerTransport } = await import("./token-goat-chunk-324QOJYZ.mjs"));
|
|
13903
14048
|
} catch (err2) {
|
|
13904
14049
|
process.stderr.write(
|
|
@@ -13915,11 +14060,15 @@ async function cmdMcpServe() {
|
|
|
13915
14060
|
server.onclose = resolve12;
|
|
13916
14061
|
});
|
|
13917
14062
|
}
|
|
14063
|
+
function printBridgeVerificationNotice(harness) {
|
|
14064
|
+
const notice = installVerificationNotice(harness);
|
|
14065
|
+
if (notice !== null) out(notice);
|
|
14066
|
+
}
|
|
13918
14067
|
async function cmdHook(event, opts) {
|
|
13919
14068
|
if (typeof opts.harness === "string" && opts.harness.length > 0) {
|
|
13920
14069
|
process.env[ENV_KEYS.HARNESS_OVERRIDE] = opts.harness;
|
|
13921
14070
|
}
|
|
13922
|
-
const { relay } = await import("./token-goat-chunk-
|
|
14071
|
+
const { relay } = await import("./token-goat-chunk-JU7QESB3.mjs");
|
|
13923
14072
|
await relay(event);
|
|
13924
14073
|
}
|
|
13925
14074
|
async function cmdInstall(opts) {
|
|
@@ -13946,6 +14095,7 @@ async function cmdInstall(opts) {
|
|
|
13946
14095
|
} else {
|
|
13947
14096
|
out(`Installed token-goat Codex CLI integration \u2192 ${codexResult.configPath}, ${codexResult.agentsPath}`);
|
|
13948
14097
|
}
|
|
14098
|
+
printBridgeVerificationNotice("codex");
|
|
13949
14099
|
}
|
|
13950
14100
|
if (opts.gemini === true) {
|
|
13951
14101
|
const geminiResult = installGemini();
|
|
@@ -13954,6 +14104,7 @@ async function cmdInstall(opts) {
|
|
|
13954
14104
|
} else {
|
|
13955
14105
|
out(`Installed token-goat Gemini CLI integration \u2192 ${geminiResult.settingsPath}`);
|
|
13956
14106
|
}
|
|
14107
|
+
printBridgeVerificationNotice("gemini");
|
|
13957
14108
|
}
|
|
13958
14109
|
if (opts.qwen === true) {
|
|
13959
14110
|
const qwenResult = installQwen();
|
|
@@ -13962,6 +14113,7 @@ async function cmdInstall(opts) {
|
|
|
13962
14113
|
} else {
|
|
13963
14114
|
out(`Installed token-goat Qwen Code integration \u2192 ${qwenResult.settingsPath}`);
|
|
13964
14115
|
}
|
|
14116
|
+
printBridgeVerificationNotice("qwen");
|
|
13965
14117
|
}
|
|
13966
14118
|
if (opts.kimi === true) {
|
|
13967
14119
|
const kimiResult = installKimi();
|
|
@@ -13970,6 +14122,7 @@ async function cmdInstall(opts) {
|
|
|
13970
14122
|
} else {
|
|
13971
14123
|
out(`Installed token-goat Kimi Code integration \u2192 ${kimiResult.configPath}, ${kimiResult.hookScriptPath}, ${kimiResult.agentsPath}, ${kimiResult.skillPath}`);
|
|
13972
14124
|
}
|
|
14125
|
+
printBridgeVerificationNotice("kimi");
|
|
13973
14126
|
}
|
|
13974
14127
|
if (opts.pi === true) {
|
|
13975
14128
|
const piResult = installPi({ local: opts.local === true });
|
|
@@ -13978,6 +14131,7 @@ async function cmdInstall(opts) {
|
|
|
13978
14131
|
} else {
|
|
13979
14132
|
out(`Installed token-goat pi extension \u2192 ${piResult.extensionPath}`);
|
|
13980
14133
|
}
|
|
14134
|
+
printBridgeVerificationNotice("pi");
|
|
13981
14135
|
}
|
|
13982
14136
|
if (opts.openclaw === true) {
|
|
13983
14137
|
const openclawResult = installOpenclaw();
|
|
@@ -13986,6 +14140,7 @@ async function cmdInstall(opts) {
|
|
|
13986
14140
|
} else {
|
|
13987
14141
|
out(`Installed token-goat OpenClaw integration \u2192 ${openclawResult.configPath}, ${openclawResult.pluginPath}`);
|
|
13988
14142
|
}
|
|
14143
|
+
printBridgeVerificationNotice("openclaw");
|
|
13989
14144
|
}
|
|
13990
14145
|
if (opts.copilot === true) {
|
|
13991
14146
|
const copilotResult = installCopilotCli({ local: opts.local === true });
|
|
@@ -13994,6 +14149,7 @@ async function cmdInstall(opts) {
|
|
|
13994
14149
|
} else {
|
|
13995
14150
|
out(`Installed token-goat Copilot CLI integration \u2192 ${copilotResult.configPath}, ${copilotResult.scriptPath}, ${copilotResult.instructionsPath}`);
|
|
13996
14151
|
}
|
|
14152
|
+
printBridgeVerificationNotice("copilot_cli");
|
|
13997
14153
|
}
|
|
13998
14154
|
if (opts.opencode === true) {
|
|
13999
14155
|
const opencodeResult = installOpencode();
|
|
@@ -14002,6 +14158,7 @@ async function cmdInstall(opts) {
|
|
|
14002
14158
|
} else {
|
|
14003
14159
|
out(`Installed token-goat opencode plugin \u2192 ${opencodeResult.pluginPath}`);
|
|
14004
14160
|
}
|
|
14161
|
+
printBridgeVerificationNotice("opencode");
|
|
14005
14162
|
}
|
|
14006
14163
|
if (opts.grok === true) {
|
|
14007
14164
|
const grokResult = installGrok();
|
|
@@ -14010,6 +14167,7 @@ async function cmdInstall(opts) {
|
|
|
14010
14167
|
} else {
|
|
14011
14168
|
out(`Installed token-goat Grok CLI integration \u2192 ${grokResult.configPath}, ${grokResult.hookScriptPath}`);
|
|
14012
14169
|
}
|
|
14170
|
+
printBridgeVerificationNotice("grok");
|
|
14013
14171
|
}
|
|
14014
14172
|
if (opts.vscode === true) {
|
|
14015
14173
|
const vscodeResult = installVscode({ project: opts.project === true });
|
|
@@ -14344,10 +14502,11 @@ function _applyFiltersAndPrint(content, opts, fenceUntrusted = false, fenceTag =
|
|
|
14344
14502
|
content = [...matched.slice(0, cap), "[token-goat: showing first " + cap + " of " + matched.length + " matching lines; raise --max-matches for more]"].join("\n");
|
|
14345
14503
|
}
|
|
14346
14504
|
}
|
|
14347
|
-
const
|
|
14505
|
+
const rawLines = content.split(/\r?\n/);
|
|
14348
14506
|
if (opts.full === true) {
|
|
14349
|
-
return emit2(
|
|
14507
|
+
return emit2(rawLines.join("\n"));
|
|
14350
14508
|
}
|
|
14509
|
+
const lines = rawLines.length > 1 && rawLines[rawLines.length - 1] === "" ? rawLines.slice(0, -1) : rawLines;
|
|
14351
14510
|
const headN = opts.head !== void 0 ? requireNonNegativeInt("--head", opts.head) : 30;
|
|
14352
14511
|
const tailN = opts.tail !== void 0 ? requireNonNegativeInt("--tail", opts.tail) : 80;
|
|
14353
14512
|
const applyElision = (lines2, headN2, tailN2) => lines2.length > headN2 + tailN2 + 1 ? [...lines2.slice(0, headN2), "...(elided)...", ...lines2.slice(lines2.length - tailN2)] : lines2;
|
|
@@ -14431,6 +14590,33 @@ async function cmdPdfExtract(file, opts) {
|
|
|
14431
14590
|
const bytesSaved = Math.max(1, fullSourceBytes - Buffer.byteLength(printed, "utf8"));
|
|
14432
14591
|
recordStat("pdf_extract", bytesSaved, Math.round(bytesSaved / 4));
|
|
14433
14592
|
}
|
|
14593
|
+
async function cmdPdfLocate(file, pattern, opts) {
|
|
14594
|
+
const locateOpts = {
|
|
14595
|
+
ignoreCase: opts.ignoreCase === true
|
|
14596
|
+
};
|
|
14597
|
+
if (opts.maxMatches !== void 0) locateOpts.maxMatches = requirePositiveInt("--max-matches", opts.maxMatches);
|
|
14598
|
+
if (opts.context !== void 0) locateOpts.context = requirePositiveInt("--context", opts.context);
|
|
14599
|
+
if (opts.pages !== void 0) locateOpts.pages = opts.pages;
|
|
14600
|
+
const matches2 = await runPdfLocate(file, pattern, locateOpts);
|
|
14601
|
+
const pages = matches2.map((m) => m.page);
|
|
14602
|
+
let printed;
|
|
14603
|
+
if (opts.json === true) {
|
|
14604
|
+
printed = JSON.stringify({ file, pattern, matchCount: matches2.length, pages, matches: matches2 }, null, 2);
|
|
14605
|
+
out(printed);
|
|
14606
|
+
} else if (matches2.length === 0) {
|
|
14607
|
+
printed = "(no matches)";
|
|
14608
|
+
out(printed);
|
|
14609
|
+
} else {
|
|
14610
|
+
const lines = matches2.map((m) => `p${m.page}: ${m.snippet}`);
|
|
14611
|
+
printed = `${lines.join("\n")}
|
|
14612
|
+
|
|
14613
|
+
${countNoun(matches2.length, "match", "matches")} across ${countNoun(pages.length, "page")}`;
|
|
14614
|
+
out(printed);
|
|
14615
|
+
}
|
|
14616
|
+
const fullSourceBytes = fileSizeOrZero(file);
|
|
14617
|
+
const bytesSaved = Math.max(1, fullSourceBytes - Buffer.byteLength(printed, "utf8"));
|
|
14618
|
+
recordStat("pdf_locate", bytesSaved, Math.round(bytesSaved / 4));
|
|
14619
|
+
}
|
|
14434
14620
|
async function cmdPdfOutline(file, opts) {
|
|
14435
14621
|
const entries = await runPdfOutline(file);
|
|
14436
14622
|
if (entries.length === 0) {
|
|
@@ -14777,7 +14963,7 @@ function emitExtraFileArgsNote(command, first, extras, opts = {}) {
|
|
|
14777
14963
|
}
|
|
14778
14964
|
async function cmdCompress(opts) {
|
|
14779
14965
|
try {
|
|
14780
|
-
const bashRunner = await import("./token-goat-chunk-
|
|
14966
|
+
const bashRunner = await import("./token-goat-chunk-BTZSUIYA.mjs");
|
|
14781
14967
|
if (opts.compress === false) {
|
|
14782
14968
|
process.exitCode = bashRunner.runRaw(opts.cmd, parseTimeout(opts.timeout, bashRunner.DEFAULT_TIMEOUT_SECONDS));
|
|
14783
14969
|
return;
|
|
@@ -15027,8 +15213,13 @@ async function cmdSkillSection(nameHeading, headingArg) {
|
|
|
15027
15213
|
const body = decodeSource(fs27.readFileSync(filePath));
|
|
15028
15214
|
const extracted = extractNamedSection(body, heading);
|
|
15029
15215
|
if (!extracted) {
|
|
15030
|
-
|
|
15031
|
-
|
|
15216
|
+
const messages = [`Section '${heading}' not found in skill '${skillName}'`];
|
|
15217
|
+
const allHeadings = listSections(filePath);
|
|
15218
|
+
const available = filterSimilarHeadings(allHeadings, heading);
|
|
15219
|
+
if (available.length > 0) messages.push(didYouMean(available));
|
|
15220
|
+
else if (allHeadings.length === 0) messages.push(`skill '${skillName}' has no headings`);
|
|
15221
|
+
else messages.push(`Try: token-goat outline ${filePath}`);
|
|
15222
|
+
throw new CliError(messages.join("\n"));
|
|
15032
15223
|
}
|
|
15033
15224
|
out(extracted);
|
|
15034
15225
|
}
|
|
@@ -15041,7 +15232,7 @@ function atomicWriteBuffer(dest, data) {
|
|
|
15041
15232
|
} catch (e) {
|
|
15042
15233
|
if (e.code !== "ENOENT") throw e;
|
|
15043
15234
|
}
|
|
15044
|
-
const rnd =
|
|
15235
|
+
const rnd = randomBytes(4).toString("hex");
|
|
15045
15236
|
const tmp = path27.join(path27.dirname(path27.resolve(dest)), `.tmp.${process.pid}.${rnd}`);
|
|
15046
15237
|
try {
|
|
15047
15238
|
fs27.writeFileSync(tmp, data, { mode: 384 });
|
|
@@ -15081,7 +15272,7 @@ function mapFsError(e, src, dest, srcLabel = "source") {
|
|
|
15081
15272
|
if (fe.code === "ENOENT") {
|
|
15082
15273
|
const errPath = fe.path ?? "";
|
|
15083
15274
|
const isSource = src !== void 0 && path27.resolve(errPath) === path27.resolve(src);
|
|
15084
|
-
if (isSource) throw new CliError(`${srcLabel} file not found: ${src}`);
|
|
15275
|
+
if (isSource) throw new CliError(`${/\bfile$/i.test(srcLabel) ? srcLabel : `${srcLabel} file`} not found: ${src}`);
|
|
15085
15276
|
const destDir = dest ? path27.dirname(path27.resolve(dest)) : path27.dirname(path27.resolve(errPath || "."));
|
|
15086
15277
|
throw new CliError(`destination directory does not exist: ${destDir}`);
|
|
15087
15278
|
}
|
|
@@ -15612,6 +15803,18 @@ function cmdInsertSection(file, opts) {
|
|
|
15612
15803
|
else if (allHeadings.length > 0) messages.push(`Try: token-goat outline ${file}`);
|
|
15613
15804
|
throw new CliError(messages.join("\n"));
|
|
15614
15805
|
}
|
|
15806
|
+
if (result.occurrences !== void 0) {
|
|
15807
|
+
const lines = [
|
|
15808
|
+
`Ambiguous heading '${opts.after}' in '${file}': ${countNoun(result.occurrences.length, "heading")} match. Retry with one of the qualified forms below to pick one:`
|
|
15809
|
+
];
|
|
15810
|
+
for (const [i, line] of result.occurrences.slice(0, AMBIGUOUS_HEADING_LIMIT).entries()) {
|
|
15811
|
+
lines.push(` - line ${line} -> --after "${opts.after}#${i + 1}"`);
|
|
15812
|
+
}
|
|
15813
|
+
if (result.occurrences.length > AMBIGUOUS_HEADING_LIMIT) {
|
|
15814
|
+
lines.push(` (${result.occurrences.length - AMBIGUOUS_HEADING_LIMIT} more not shown)`);
|
|
15815
|
+
}
|
|
15816
|
+
throw new CliError(lines.join("\n"));
|
|
15817
|
+
}
|
|
15615
15818
|
let rawBytes;
|
|
15616
15819
|
try {
|
|
15617
15820
|
rawBytes = fs27.readFileSync(file);
|
|
@@ -16266,6 +16469,9 @@ function buildProgram() {
|
|
|
16266
16469
|
);
|
|
16267
16470
|
program2.command("config-get <file> <key>").description("read one value from a config file (TOML/JSON/YAML/INI)").action((file, key) => runExit(() => runConfigGet({ file, key })));
|
|
16268
16471
|
program2.command("pdf-extract <file>").description("extract plain text from a PDF (optionally --pages N or N-M) instead of a raw Read").option("--pages <spec>", "page range to extract, e.g. 1-5 or 3 (default: all pages)").option("--layout", "heuristic column-aware reading-order reconstruction from text-item coordinates (imperfect on rotated/overlapping text)").option("--head <n>", "show only the first N lines").option("--tail <n>", "show only the last N lines").option("--grep <pattern>", "filter to lines matching this regex").option("--section <heading>", "extract one markdown section by heading").option("--max-matches <n>", "cap the number of --grep matches shown").action(guard(cmdPdfExtract));
|
|
16472
|
+
program2.command("pdf-locate <file> <pattern>").description(
|
|
16473
|
+
"find which pages of a PDF match a regex, with a snippet per match, so you can pdf-extract only those pages instead of the whole document"
|
|
16474
|
+
).option("-i, --ignore-case", "case-insensitive matching").option("--max-matches <n>", "stop after this many page matches (default: 50)").option("--context <n>", "snippet length in characters around each match (default: 80)").option("--pages <spec>", "page range to scan, e.g. 1-5 or 3 (default: all pages)").option("-j, --json", "output as JSON").action(guard(cmdPdfLocate));
|
|
16269
16475
|
program2.command("pdf-outline <file>").description("list a PDF's bookmark/outline tree with page numbers instead of a raw Read").option("-j, --json", "output as JSON").action(guard(cmdPdfOutline));
|
|
16270
16476
|
program2.command("pdf-meta <file>").description("page count, title/author, and whether a PDF has an extractable text layer").option("-j, --json", "output as JSON").action(guard(cmdPdfMeta));
|
|
16271
16477
|
program2.command("image-meta <file>").description("dimensions, byte size, format, and what a shrink would cost -- sharp metadata only, never runs OCR").option("-j, --json", "output as JSON").action(guard(cmdImageMeta));
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
loadBlob,
|
|
9
9
|
sanitizeFtsQuery,
|
|
10
10
|
storeBlob
|
|
11
|
-
} from "./token-goat-chunk-
|
|
11
|
+
} from "./token-goat-chunk-AM23GDIS.mjs";
|
|
12
12
|
import {
|
|
13
13
|
SYMBOL_BODY_CHAR_CAP,
|
|
14
14
|
extractErrorMessage,
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
redactSecrets,
|
|
19
19
|
runGit,
|
|
20
20
|
shortFingerprint
|
|
21
|
-
} from "./token-goat-chunk-
|
|
21
|
+
} from "./token-goat-chunk-IVCTQPZD.mjs";
|
|
22
22
|
import {
|
|
23
23
|
registerReset
|
|
24
24
|
} from "./token-goat-chunk-AO2QD2AG.mjs";
|
|
@@ -404,10 +404,10 @@ var COMMAND_PATTERNS = {
|
|
|
404
404
|
gitImmutable: /^\s*git\s+show\s+[0-9a-f]{40}\b/i,
|
|
405
405
|
gitDiffScoped: /\s--\s+\S/,
|
|
406
406
|
dirListing: /^\s*(?:ls|eza|exa|dir|Get-ChildItem|gci)\b/i,
|
|
407
|
-
depList: /^\s*(?:npm\s+(
|
|
408
|
-
npmInstall: /^\s*npm\s+(
|
|
409
|
-
npmAudit: /^\s*npm\s+(
|
|
410
|
-
npmOutdated: /^\s*npm\s+(
|
|
407
|
+
depList: /^\s*(?:npm\s+(?:--?[a-zA-Z0-9_-]+(?:\s+|=)?)*(?:ls|list)\b|pip\s+(?:--?[a-zA-Z0-9_-]+(?:\s+|=)?)*(?:list|freeze)\b|uv\s+pip\s+(?:--?[a-zA-Z0-9_-]+(?:\s+|=)?)*(?:list|freeze)\b|pnpm\s+(?:--?[a-zA-Z0-9_-]+(?:\s+|=)?)*(?:list|ls)\b|yarn\s+(?:--?[a-zA-Z0-9_-]+(?:\s+|=)?)*(?:list)\b|cargo\s+(?:--?[a-zA-Z0-9_-]+(?:\s+|=)?)*tree\b|bundle\s+(?:--?[a-zA-Z0-9_-]+(?:\s+|=)?)*(?:list|show)\b|composer\s+(?:--?[a-zA-Z0-9_-]+(?:\s+|=)?)*show\b)/i,
|
|
408
|
+
npmInstall: /^\s*npm\s+(?:--?[a-zA-Z0-9_-]+(?:\s+|=)?)*(?:install|ci)\b/i,
|
|
409
|
+
npmAudit: /^\s*npm\s+(?:--?[a-zA-Z0-9_-]+(?:\s+|=)?)*audit\b(?!.*(?:--fix|fix)\b)/i,
|
|
410
|
+
npmOutdated: /^\s*npm\s+(?:--?[a-zA-Z0-9_-]+(?:\s+|=)?)*outdated\b/i,
|
|
411
411
|
envProbe: /^\s*(?:node\s+(?:-v|--version)|npm\s+(?:-v|--version)|python3?\s+(?:(?:-V)\b|--?version)|git\s+--version|uv\s+--version|go\s+version|rustc\s+--version|cargo\s+--version|java\s+--version|ruby\s+--version|gem\s+--version|php\s+--version|which\b|where\b)/i,
|
|
412
412
|
npx: /^\s*npx\s+(?:--?yes\s+)?(?!.*\b(?:install|add|remove|uninstall|i|rm|update|upgrade|set|get|publish|link|ci|audit|shrinkwrap|dedupe|prune|rebuild)\b)/i,
|
|
413
413
|
gitPush: /^\s*git\s+push\b/i,
|