token-goat 2.9.2 → 2.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/README.md +20 -49
  2. package/dist/{token-goat-chunk-Q4LOQY44.mjs → token-goat-chunk-2VVXTAGD.mjs} +137 -12
  3. package/dist/{token-goat-chunk-LEBYARO3.mjs → token-goat-chunk-3UBORD6Z.mjs} +9 -6
  4. package/dist/{token-goat-chunk-LJ3CHCTT.mjs → token-goat-chunk-3XVGPLDS.mjs} +3492 -46
  5. package/dist/{token-goat-chunk-KKIB7O3Z.mjs → token-goat-chunk-6FQMEMWX.mjs} +418 -105
  6. package/dist/{token-goat-chunk-FXAPKVRG.mjs → token-goat-chunk-7A7SBE6R.mjs} +26 -5
  7. package/dist/token-goat-chunk-A37V4PBF.mjs +56 -0
  8. package/dist/{token-goat-chunk-VCNW7BGU.mjs → token-goat-chunk-A4VBNWSL.mjs} +20 -3
  9. package/dist/{token-goat-chunk-G6XLWJWI.mjs → token-goat-chunk-E3K3BTEQ.mjs} +5 -2
  10. package/dist/{token-goat-chunk-AO2QD2AG.mjs → token-goat-chunk-EEIDFMEM.mjs} +4 -0
  11. package/dist/{token-goat-chunk-324QOJYZ.mjs → token-goat-chunk-EVC4TOLE.mjs} +4 -1
  12. package/dist/{token-goat-chunk-WN5T5EW5.mjs → token-goat-chunk-FQD3OB5W.mjs} +98 -2
  13. package/dist/token-goat-chunk-HC5NMGPD.mjs +23 -0
  14. package/dist/{token-goat-chunk-UZ2NFOOZ.mjs → token-goat-chunk-KKHKXUVS.mjs} +154 -8
  15. package/dist/{token-goat-chunk-NY4HYRSK.mjs → token-goat-chunk-LLNA42NI.mjs} +10 -12
  16. package/dist/{token-goat-chunk-5CVKO3DA.mjs → token-goat-chunk-LYWIRYCF.mjs} +5 -2
  17. package/dist/{token-goat-chunk-CGWACYYZ.mjs → token-goat-chunk-OKJX2JWW.mjs} +6 -1
  18. package/dist/{token-goat-chunk-R4SR7MQY.mjs → token-goat-chunk-PXWBHSFB.mjs} +2 -2
  19. package/dist/{token-goat-chunk-JMUBXBG7.mjs → token-goat-chunk-XSSQFI4C.mjs} +7 -7
  20. package/dist/token-goat-hook.mjs +12 -7
  21. package/dist/token-goat.core.mjs +10 -7
  22. package/docs/cli.md +53 -0
  23. package/docs/security.md +6 -2
  24. package/package.json +8 -2
  25. package/dist/token-goat-chunk-AEX54RUZ.mjs +0 -11
  26. package/dist/token-goat-chunk-ZVN5WHTO.mjs +0 -23
@@ -86,7 +86,7 @@ import {
86
86
  runZipRead,
87
87
  symbolNamesInFile,
88
88
  upsertNote
89
- } from "./token-goat-chunk-FXAPKVRG.mjs";
89
+ } from "./token-goat-chunk-7A7SBE6R.mjs";
90
90
  import {
91
91
  DEFAULT_RECONCILE_BUDGET_MS,
92
92
  GEMINI_TOOL_NAME_MAP,
@@ -108,7 +108,7 @@ import {
108
108
  runReconcile,
109
109
  storeWebOutput,
110
110
  summarizeResidentContext
111
- } from "./token-goat-chunk-VCNW7BGU.mjs";
111
+ } from "./token-goat-chunk-A4VBNWSL.mjs";
112
112
  import {
113
113
  AGENT_SALT_MARKER,
114
114
  BASH_OUTPUT_SUBDIR,
@@ -238,10 +238,11 @@ import {
238
238
  visionTokensSavedByText,
239
239
  walkProject,
240
240
  writeCompact
241
- } from "./token-goat-chunk-LJ3CHCTT.mjs";
241
+ } from "./token-goat-chunk-3XVGPLDS.mjs";
242
242
  import {
243
243
  C,
244
244
  CONFIG_KEY_ENV_OVERRIDES,
245
+ CompressedOutput,
245
246
  ENV_KEYS,
246
247
  FILTERS,
247
248
  LOCK_WAIT_MS_HARDENED,
@@ -249,6 +250,8 @@ import {
249
250
  PROJECT_LOCKED_KEYS,
250
251
  PROJECT_LOCKED_SECTIONS,
251
252
  RESET,
253
+ TOOL_FILTERS,
254
+ ToolFilter,
252
255
  VERSION,
253
256
  _useRichStats,
254
257
  anchoredMarkerPattern,
@@ -257,6 +260,7 @@ import {
257
260
  canonicalize,
258
261
  cappedSourceBytesSaved,
259
262
  colorStdout,
263
+ combineStreams,
260
264
  compileCustomPatterns,
261
265
  configPath,
262
266
  copilotCliConfigPath,
@@ -267,6 +271,8 @@ import {
267
271
  dataDir,
268
272
  decodeSource,
269
273
  defaultConfig,
274
+ deliverCompressed,
275
+ detectFromCommand,
270
276
  detectLanguage,
271
277
  detectSourceEncoding,
272
278
  encodeSource,
@@ -358,15 +364,24 @@ import {
358
364
  withFileLock,
359
365
  withRetryOnLock,
360
366
  writeJsonSettings
361
- } from "./token-goat-chunk-UZ2NFOOZ.mjs";
367
+ } from "./token-goat-chunk-KKHKXUVS.mjs";
362
368
  import {
363
- __export
364
- } from "./token-goat-chunk-AEX54RUZ.mjs";
369
+ __export,
370
+ init_define_import_meta_env
371
+ } from "./token-goat-chunk-A37V4PBF.mjs";
365
372
 
366
373
  // src/cli.ts
374
+ init_define_import_meta_env();
367
375
  import { randomBytes } from "node:crypto";
368
376
 
377
+ // node_modules/commander/index.js
378
+ init_define_import_meta_env();
379
+
380
+ // node_modules/commander/lib/argument.js
381
+ init_define_import_meta_env();
382
+
369
383
  // node_modules/commander/lib/error.js
384
+ init_define_import_meta_env();
370
385
  var CommanderError = class extends Error {
371
386
  /**
372
387
  * Constructs the CommanderError class
@@ -517,6 +532,7 @@ function humanReadableArgName(arg) {
517
532
  }
518
533
 
519
534
  // node_modules/commander/lib/command.js
535
+ init_define_import_meta_env();
520
536
  import { EventEmitter } from "node:events";
521
537
  import childProcess from "node:child_process";
522
538
  import path from "node:path";
@@ -525,6 +541,7 @@ import process2 from "node:process";
525
541
  import { stripVTControlCharacters as stripVTControlCharacters2 } from "node:util";
526
542
 
527
543
  // node_modules/commander/lib/help.js
544
+ init_define_import_meta_env();
528
545
  import { stripVTControlCharacters } from "node:util";
529
546
  var Help = class {
530
547
  constructor() {
@@ -1117,6 +1134,7 @@ ${itemIndentStr}`);
1117
1134
  };
1118
1135
 
1119
1136
  // node_modules/commander/lib/option.js
1137
+ init_define_import_meta_env();
1120
1138
  var Option = class {
1121
1139
  /**
1122
1140
  * Initialize a new `Option` with the given `flags` and `description`.
@@ -1423,6 +1441,7 @@ function splitOptionFlags(flags) {
1423
1441
  }
1424
1442
 
1425
1443
  // node_modules/commander/lib/suggestSimilar.js
1444
+ init_define_import_meta_env();
1426
1445
  var maxDistance = 3;
1427
1446
  function editDistance(a, b) {
1428
1447
  if (Math.abs(a.length - b.length) > maxDistance)
@@ -3477,9 +3496,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
3477
3496
  * @param {string} [path]
3478
3497
  * @return {(string|null|Command)}
3479
3498
  */
3480
- executableDir(path30) {
3481
- if (path30 === void 0) return this._executableDir;
3482
- this._executableDir = path30;
3499
+ executableDir(path31) {
3500
+ if (path31 === void 0) return this._executableDir;
3501
+ this._executableDir = path31;
3483
3502
  return this;
3484
3503
  }
3485
3504
  /**
@@ -3735,6 +3754,7 @@ function useColor() {
3735
3754
  var program = new Command();
3736
3755
 
3737
3756
  // src/command_intent.ts
3757
+ init_define_import_meta_env();
3738
3758
  var INTENT_SUGGESTIONS = [
3739
3759
  [
3740
3760
  ["search", "lookup", "query"],
@@ -3778,11 +3798,12 @@ function attemptedCommandName(argv) {
3778
3798
  }
3779
3799
 
3780
3800
  // src/cli.ts
3781
- import * as fs28 from "fs";
3782
- import * as path29 from "path";
3801
+ import * as fs29 from "fs";
3802
+ import * as path30 from "path";
3783
3803
  import { homedir as homedir13 } from "os";
3784
3804
 
3785
3805
  // src/walk_index.ts
3806
+ init_define_import_meta_env();
3786
3807
  import * as fs2 from "node:fs";
3787
3808
  import * as os from "node:os";
3788
3809
  import * as path2 from "node:path";
@@ -3831,6 +3852,7 @@ function collectWalkIndexFiles(root, opts = {}) {
3831
3852
  }
3832
3853
 
3833
3854
  // src/bridges/gemini_install.ts
3855
+ init_define_import_meta_env();
3834
3856
  import * as fs3 from "node:fs";
3835
3857
  import * as os2 from "node:os";
3836
3858
  import * as path3 from "node:path";
@@ -3974,6 +3996,7 @@ function isGeminiInstalled() {
3974
3996
  }
3975
3997
 
3976
3998
  // src/bridges/qwen_install.ts
3999
+ init_define_import_meta_env();
3977
4000
  import * as fs4 from "node:fs";
3978
4001
  import * as os3 from "node:os";
3979
4002
  import * as path4 from "node:path";
@@ -4098,11 +4121,13 @@ function isQwenInstalled() {
4098
4121
  }
4099
4122
 
4100
4123
  // src/bridges/pi_install.ts
4124
+ init_define_import_meta_env();
4101
4125
  import * as fs5 from "node:fs";
4102
4126
  import * as os4 from "node:os";
4103
4127
  import * as path5 from "node:path";
4104
4128
 
4105
4129
  // src/bridges/pi.ts
4130
+ init_define_import_meta_env();
4106
4131
  var PI_EXTENSION_SCRIPT = `// token-goat bridge extension for pi (pi-coding-agent)
4107
4132
  // Bridges pi's extension events to token-goat's subprocess hook protocol.
4108
4133
  // https://github.com/DFKHelper/token-goat
@@ -4493,11 +4518,16 @@ function isPiInstalled(opts = {}) {
4493
4518
  }
4494
4519
 
4495
4520
  // src/bridges/opencode_install.ts
4521
+ init_define_import_meta_env();
4496
4522
  import * as fs6 from "node:fs";
4497
4523
  import * as os5 from "node:os";
4498
4524
  import * as path6 from "node:path";
4499
4525
 
4526
+ // src/bridges/opencode.ts
4527
+ init_define_import_meta_env();
4528
+
4500
4529
  // src/bridges/relay_block.ts
4530
+ init_define_import_meta_env();
4501
4531
  var BRIDGE_RELAY_JS = `// resolveEntryPath reads a sidecar JSON file (token-goat-entry.json, written by
4502
4532
  // the install step next to this plugin file) containing the absolute path to
4503
4533
  // the token-goat CLI entry that was running at install time. Unlike
@@ -4787,11 +4817,13 @@ function isOpencodeInstalled() {
4787
4817
  }
4788
4818
 
4789
4819
  // src/bridges/openclaw_install.ts
4820
+ init_define_import_meta_env();
4790
4821
  import * as fs7 from "node:fs";
4791
4822
  import * as os6 from "node:os";
4792
4823
  import * as path7 from "node:path";
4793
4824
 
4794
4825
  // src/bridges/openclaw.ts
4826
+ init_define_import_meta_env();
4795
4827
  var OPENCLAW_PLUGIN_SCRIPT = `// token-goat bridge plugin for OpenClaw
4796
4828
  // Bridges OpenClaw's tool-call and session hooks to token-goat's subprocess
4797
4829
  // hook protocol. https://github.com/DFKHelper/token-goat
@@ -5098,6 +5130,7 @@ function isOpenclawInstalled() {
5098
5130
  }
5099
5131
 
5100
5132
  // src/bridges_status.ts
5133
+ init_define_import_meta_env();
5101
5134
  var NO_SERVER_HANDLER_REASON = "token-goat has no registered server-side handler for this event (zero registerHook('notification'|'stop', ...) call sites in src/) -- wiring it client-side would currently be a no-op";
5102
5135
  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";
5103
5136
  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";
@@ -5401,6 +5434,7 @@ function installVerificationNotice(harness) {
5401
5434
  }
5402
5435
 
5403
5436
  // src/sharepoint_resolve.ts
5437
+ init_define_import_meta_env();
5404
5438
  import * as fs8 from "node:fs";
5405
5439
  import * as os7 from "node:os";
5406
5440
  import * as path8 from "node:path";
@@ -5508,6 +5542,7 @@ function resolveLocalPath(parsed, env = process.env, home = os7.homedir()) {
5508
5542
  }
5509
5543
 
5510
5544
  // src/video_chapters.ts
5545
+ init_define_import_meta_env();
5511
5546
  import { spawnSync } from "node:child_process";
5512
5547
  var _ffprobeAvailable;
5513
5548
  function isFfprobeAvailable() {
@@ -5555,6 +5590,7 @@ function extractVideoChapters(file) {
5555
5590
  }
5556
5591
 
5557
5592
  // src/transcript_extract.ts
5593
+ init_define_import_meta_env();
5558
5594
  import * as fs9 from "node:fs";
5559
5595
  var TIMESTAMP_RE = /(\d{1,2}:)?(\d{2}):(\d{2})[.,](\d{1,3})/;
5560
5596
  var CUE_LINE_RE = new RegExp(`^\\s*${TIMESTAMP_RE.source}\\s*-->\\s*${TIMESTAMP_RE.source}`);
@@ -5668,6 +5704,7 @@ function formatCues(cues) {
5668
5704
  }
5669
5705
 
5670
5706
  // src/affected.ts
5707
+ init_define_import_meta_env();
5671
5708
  import * as path9 from "node:path";
5672
5709
  var DEFAULT_AFFECTED_DEPTH = 5;
5673
5710
  function emit(text) {
@@ -5769,6 +5806,7 @@ function runAffected(opts) {
5769
5806
  }
5770
5807
 
5771
5808
  // src/purge.ts
5809
+ init_define_import_meta_env();
5772
5810
  import * as fs10 from "node:fs";
5773
5811
  import * as path10 from "node:path";
5774
5812
  function directorySize(root) {
@@ -5822,6 +5860,7 @@ function formatBytes2(bytes) {
5822
5860
  }
5823
5861
 
5824
5862
  // src/cli_stats.ts
5863
+ init_define_import_meta_env();
5825
5864
  import * as fs11 from "node:fs";
5826
5865
  import * as path11 from "node:path";
5827
5866
  function writeRaw(text) {
@@ -5944,6 +5983,7 @@ function runStats(opts = {}) {
5944
5983
  }
5945
5984
 
5946
5985
  // src/cli_doctor.ts
5986
+ init_define_import_meta_env();
5947
5987
  import * as fs12 from "fs";
5948
5988
  import * as os8 from "os";
5949
5989
  import * as path12 from "path";
@@ -6157,19 +6197,19 @@ function checkEmbeddingCoverage(dbPath, rootDir) {
6157
6197
  if (indexedFiles === 0) {
6158
6198
  return { name: "Embedding coverage", status: "ok", message: "no indexed files yet" };
6159
6199
  }
6160
- const pct2 = Math.round(embeddedFiles / indexedFiles * 100);
6200
+ const pct3 = Math.round(embeddedFiles / indexedFiles * 100);
6161
6201
  const sizeKb = cfg.indexing.large_file_symbol_only_kb;
6162
6202
  if (embeddedFiles / indexedFiles < EMBED_COVERAGE_WARN_FRACTION) {
6163
6203
  return {
6164
6204
  name: "Embedding coverage",
6165
6205
  status: "warn",
6166
- message: `only ${embeddedFiles} of ${indexedFiles} indexed file(s) (${pct2}%) have embeddings \u2014 'semantic' searches those files only, and reports finding nothing in the same words it uses after searching everything. Files over indexing.large_file_symbol_only_kb (currently ${sizeKb} KB) are indexed for symbols only and are the usual reason; raise it with 'token-goat config set indexing.large_file_symbol_only_kb <KB>' and re-embed with 'token-goat index --force' to widen coverage. Exact symbol lookups are unaffected`
6206
+ message: `only ${embeddedFiles} of ${indexedFiles} indexed file(s) (${pct3}%) have embeddings \u2014 'semantic' searches those files only, and reports finding nothing in the same words it uses after searching everything. Files over indexing.large_file_symbol_only_kb (currently ${sizeKb} KB) are indexed for symbols only and are the usual reason; raise it with 'token-goat config set indexing.large_file_symbol_only_kb <KB>' and re-embed with 'token-goat index --force' to widen coverage. Exact symbol lookups are unaffected`
6167
6207
  };
6168
6208
  }
6169
6209
  return {
6170
6210
  name: "Embedding coverage",
6171
6211
  status: "ok",
6172
- message: `${embeddedFiles} of ${indexedFiles} indexed file(s) (${pct2}%) have embeddings`
6212
+ message: `${embeddedFiles} of ${indexedFiles} indexed file(s) (${pct3}%) have embeddings`
6173
6213
  };
6174
6214
  } catch (err2) {
6175
6215
  return {
@@ -6689,6 +6729,7 @@ async function runDoctorAndExit(opts) {
6689
6729
  }
6690
6730
 
6691
6731
  // src/capabilities.ts
6732
+ init_define_import_meta_env();
6692
6733
  function collectCapabilities(config = loadConfig()) {
6693
6734
  const online = !config.network.offline;
6694
6735
  return [
@@ -6772,7 +6813,11 @@ function renderCapabilities(caps) {
6772
6813
  return lines.join("\n");
6773
6814
  }
6774
6815
 
6816
+ // src/gdrive.ts
6817
+ init_define_import_meta_env();
6818
+
6775
6819
  // src/webfetch.ts
6820
+ init_define_import_meta_env();
6776
6821
  import { existsSync as existsSync7, readdirSync as readdirSync5, statSync as statSync4, unlinkSync as unlinkSync2 } from "fs";
6777
6822
  import * as http from "http";
6778
6823
  import * as https from "https";
@@ -7231,6 +7276,7 @@ async function getSectionContent(fileId, heading, opts = {}) {
7231
7276
  }
7232
7277
 
7233
7278
  // src/pack.ts
7279
+ init_define_import_meta_env();
7234
7280
  import * as fs13 from "node:fs";
7235
7281
  import * as path14 from "node:path";
7236
7282
 
@@ -7250,8 +7296,13 @@ __export(esm_exports, {
7250
7296
  sep: () => sep2,
7251
7297
  unescape: () => unescape
7252
7298
  });
7299
+ init_define_import_meta_env();
7300
+
7301
+ // node_modules/brace-expansion/dist/esm/index.js
7302
+ init_define_import_meta_env();
7253
7303
 
7254
7304
  // node_modules/balanced-match/dist/esm/index.js
7305
+ init_define_import_meta_env();
7255
7306
  var balanced = (a, b, str) => {
7256
7307
  const ma = a instanceof RegExp ? maybeMatch(a, str) : a;
7257
7308
  const mb2 = b instanceof RegExp ? maybeMatch(b, str) : b;
@@ -7518,6 +7569,7 @@ function expand_(str, max, maxLength, isTop) {
7518
7569
  }
7519
7570
 
7520
7571
  // node_modules/minimatch/dist/esm/assert-valid-pattern.js
7572
+ init_define_import_meta_env();
7521
7573
  var MAX_PATTERN_LENGTH = 1024 * 64;
7522
7574
  var assertValidPattern = (pattern) => {
7523
7575
  if (typeof pattern !== "string") {
@@ -7528,7 +7580,11 @@ var assertValidPattern = (pattern) => {
7528
7580
  }
7529
7581
  };
7530
7582
 
7583
+ // node_modules/minimatch/dist/esm/ast.js
7584
+ init_define_import_meta_env();
7585
+
7531
7586
  // node_modules/minimatch/dist/esm/brace-expressions.js
7587
+ init_define_import_meta_env();
7532
7588
  var posixClasses = {
7533
7589
  "[:alnum:]": ["\\p{L}\\p{Nl}\\p{Nd}", true],
7534
7590
  "[:alpha:]": ["\\p{L}\\p{Nl}", true],
@@ -7638,6 +7694,7 @@ var parseClass = (glob, position) => {
7638
7694
  };
7639
7695
 
7640
7696
  // node_modules/minimatch/dist/esm/unescape.js
7697
+ init_define_import_meta_env();
7641
7698
  var unescape = (s, { windowsPathsNoEscape = false, magicalBraces = true } = {}) => {
7642
7699
  if (magicalBraces) {
7643
7700
  return windowsPathsNoEscape ? s.replace(/\[([^/\\])\]/g, "$1") : s.replace(/((?!\\).|^)\[([^/\\])\]/g, "$1$2").replace(/\\([^/])/g, "$1");
@@ -8290,6 +8347,7 @@ var AST = class {
8290
8347
  _a = AST;
8291
8348
 
8292
8349
  // node_modules/minimatch/dist/esm/escape.js
8350
+ init_define_import_meta_env();
8293
8351
  var escape = (s, { windowsPathsNoEscape = false, magicalBraces = false } = {}) => {
8294
8352
  if (magicalBraces) {
8295
8353
  return windowsPathsNoEscape ? s.replace(/[?*()[\]{}]/g, "[$&]") : s.replace(/[?*()[\]\\{}]/g, "\\$&");
@@ -9565,12 +9623,12 @@ function formatBudgetText(result, contextK) {
9565
9623
  lines.push(` ${e.rel_path.padEnd(colW, " ")} ${String(e.lines).padStart(6, " ")} ${String(e.tokens).padStart(8, " ")}`);
9566
9624
  }
9567
9625
  lines.push(` ${"-".repeat(colW)} ${"-".repeat(6)} ${"-".repeat(8)}`);
9568
- let pct2 = "";
9626
+ let pct3 = "";
9569
9627
  if (contextK) {
9570
- pct2 = ` (${Math.round(result.total_tokens / (contextK * 1e3) * 100)}% of ${contextK}K)`;
9628
+ pct3 = ` (${Math.round(result.total_tokens / (contextK * 1e3) * 100)}% of ${contextK}K)`;
9571
9629
  }
9572
9630
  lines.push(
9573
- ` ${"Total".padEnd(colW, " ")} ${String(result.total_lines).padStart(6, " ")} ${String(result.total_tokens).padStart(8, " ")}${pct2}`
9631
+ ` ${"Total".padEnd(colW, " ")} ${String(result.total_lines).padStart(6, " ")} ${String(result.total_tokens).padStart(8, " ")}${pct3}`
9574
9632
  );
9575
9633
  if (result.skipped.length > 0) {
9576
9634
  const skipped = result.skipped.slice(0, 5).join(", ");
@@ -9582,6 +9640,7 @@ function formatBudgetText(result, contextK) {
9582
9640
  }
9583
9641
 
9584
9642
  // src/failures.ts
9643
+ init_define_import_meta_env();
9585
9644
  function getFailureCount(result) {
9586
9645
  return result.blocks.length || result.summaryLines.length;
9587
9646
  }
@@ -10006,6 +10065,7 @@ function formatFailureDeltaJson(delta, runner) {
10006
10065
  }
10007
10066
 
10008
10067
  // src/failures_state.ts
10068
+ init_define_import_meta_env();
10009
10069
  import * as fs14 from "node:fs";
10010
10070
  import * as path15 from "node:path";
10011
10071
  var KEY_RE = /^[A-Za-z0-9_-]{1,80}$/;
@@ -10051,10 +10111,12 @@ function saveFailureSnapshot(projectHash, key, snapshot) {
10051
10111
  }
10052
10112
 
10053
10113
  // src/text_commands.ts
10114
+ init_define_import_meta_env();
10054
10115
  import * as fs16 from "fs";
10055
10116
  import * as path17 from "path";
10056
10117
 
10057
10118
  // src/project_memory.ts
10119
+ init_define_import_meta_env();
10058
10120
  import * as fs15 from "node:fs";
10059
10121
  import * as path16 from "node:path";
10060
10122
  var MAX_ENTRIES = 30;
@@ -11278,6 +11340,7 @@ function countPackIgnorePatterns(root) {
11278
11340
  }
11279
11341
 
11280
11342
  // src/dep_docs.ts
11343
+ init_define_import_meta_env();
11281
11344
  import { createRequire } from "node:module";
11282
11345
  import * as fs17 from "node:fs";
11283
11346
  import * as path18 from "node:path";
@@ -11565,7 +11628,11 @@ function runDepDocs(opts) {
11565
11628
  return { text, code: 0 };
11566
11629
  }
11567
11630
 
11631
+ // src/cache_session_commands.ts
11632
+ init_define_import_meta_env();
11633
+
11568
11634
  // src/resume.ts
11635
+ init_define_import_meta_env();
11569
11636
  import { readFile } from "node:fs/promises";
11570
11637
  var MAX_RESUME_TOKENS = 2e3;
11571
11638
  var MAX_RESUME_CHARS = MAX_RESUME_TOKENS * 4;
@@ -11905,15 +11972,15 @@ function cmdCompactHint(opts) {
11905
11972
  const pressure = getContextPressure(cache ?? void 0);
11906
11973
  const [manifest, eventCount] = sessionId !== null ? buildManifestWithCount(sessionId) : ["", 0];
11907
11974
  const manifestTokens = estimateTokens(manifest);
11908
- const pct2 = (pressure.fillFraction * 100).toFixed(1);
11975
+ const pct3 = (pressure.fillFraction * 100).toFixed(1);
11909
11976
  if (opts.json === true) {
11910
- const out2 = { tier: pressure.tier, fillFraction: pressure.fillFraction, pct: Number(pct2), manifestTokens, eventCount };
11977
+ const out2 = { tier: pressure.tier, fillFraction: pressure.fillFraction, pct: Number(pct3), manifestTokens, eventCount };
11911
11978
  if (sessionId !== null) out2["sessionId"] = sessionId;
11912
11979
  if (opts.trigger !== void 0) out2["trigger"] = opts.trigger;
11913
11980
  process.stdout.write(JSON.stringify(out2, null, 2) + "\n");
11914
11981
  return;
11915
11982
  }
11916
- process.stdout.write(`Compact hint \u2014 context: ${pressure.tier} (${pct2}% full)
11983
+ process.stdout.write(`Compact hint \u2014 context: ${pressure.tier} (${pct3}% full)
11917
11984
  `);
11918
11985
  if (sessionId !== null) process.stdout.write(`Session: ${sessionId}
11919
11986
  `);
@@ -12000,6 +12067,7 @@ function cmdBaseline(opts) {
12000
12067
  }
12001
12068
 
12002
12069
  // src/index_reclaim.ts
12070
+ init_define_import_meta_env();
12003
12071
  import * as fs18 from "node:fs";
12004
12072
  import * as path19 from "node:path";
12005
12073
  var DERIVED_TABLES = ["chunk_vectors", "chunks", "refs", "symbols", "files"];
@@ -12126,6 +12194,7 @@ function cmdReclaimIndex(opts) {
12126
12194
  }
12127
12195
 
12128
12196
  // src/config_commands.ts
12197
+ init_define_import_meta_env();
12129
12198
  import * as fs19 from "node:fs";
12130
12199
  import * as os9 from "node:os";
12131
12200
  import * as path20 from "node:path";
@@ -12795,6 +12864,7 @@ function cmdHistory(opts) {
12795
12864
  }
12796
12865
 
12797
12866
  // src/cli_bootstrap_audit.ts
12867
+ init_define_import_meta_env();
12798
12868
  import * as fs20 from "node:fs";
12799
12869
  import * as os10 from "node:os";
12800
12870
  import * as path21 from "node:path";
@@ -13011,6 +13081,7 @@ async function runBootstrapAudit(opts = {}) {
13011
13081
  }
13012
13082
 
13013
13083
  // src/cli_memory.ts
13084
+ init_define_import_meta_env();
13014
13085
  import * as fs21 from "node:fs";
13015
13086
  import * as path22 from "node:path";
13016
13087
  function removeExactDupLines(text, report) {
@@ -13130,10 +13201,12 @@ async function runMemoryCommand(opts = {}) {
13130
13201
  }
13131
13202
 
13132
13203
  // src/cli_waste.ts
13204
+ init_define_import_meta_env();
13133
13205
  import * as fs24 from "node:fs";
13134
13206
  import * as path25 from "node:path";
13135
13207
 
13136
13208
  // src/waste.ts
13209
+ init_define_import_meta_env();
13137
13210
  import * as fs22 from "node:fs";
13138
13211
  import * as os11 from "node:os";
13139
13212
  import * as path23 from "node:path";
@@ -13381,6 +13454,7 @@ async function buildWasteReport(transcriptPath, opts = {}) {
13381
13454
  }
13382
13455
 
13383
13456
  // src/copilot_waste.ts
13457
+ init_define_import_meta_env();
13384
13458
  import * as fs23 from "node:fs";
13385
13459
  import * as path24 from "node:path";
13386
13460
  var HOOK_RECORD_TYPES = /* @__PURE__ */ new Set(["hook.start", "hook.end"]);
@@ -13535,10 +13609,10 @@ function printCopilotReport(report) {
13535
13609
  w(` Conversation: ${conversationTokens.toLocaleString()} tok
13536
13610
  `);
13537
13611
  if (total > 0) {
13538
- const pct2 = (fixed / total * 100).toFixed(1);
13612
+ const pct3 = (fixed / total * 100).toFixed(1);
13539
13613
  w(` ${fixed.toLocaleString()} tok of system prompt and tool definitions ships with every
13540
13614
  `);
13541
- w(` request; at shutdown that was ${pct2}% of the context. No hook can reach it: Copilot
13615
+ w(` request; at shutdown that was ${pct3}% of the context. No hook can reach it: Copilot
13542
13616
  `);
13543
13617
  w(" assembles both natively, with nothing between assembly and send. The levers are all\n");
13544
13618
  w(" config: fewer MCP servers and custom tools, and --excluded-tools / --available-tools /\n");
@@ -13598,9 +13672,9 @@ function printCopilotReport(report) {
13598
13672
  `);
13599
13673
  } else {
13600
13674
  for (const block of report.blocks) {
13601
- const pct2 = block.bytes > 0 ? (block.repeatBytes / block.bytes * 100).toFixed(1) : "0.0";
13675
+ const pct3 = block.bytes > 0 ? (block.repeatBytes / block.bytes * 100).toFixed(1) : "0.0";
13602
13676
  w(` ${block.kind}: ${countNoun(block.count, "injection")}, ${formatBytes(block.bytes)}`);
13603
- w(block.repeatBytes > 0 ? `, ${formatBytes(block.repeatBytes)} re-sent verbatim (${pct2}%)
13677
+ w(block.repeatBytes > 0 ? `, ${formatBytes(block.repeatBytes)} re-sent verbatim (${pct3}%)
13604
13678
  ` : "\n");
13605
13679
  }
13606
13680
  }
@@ -13765,6 +13839,7 @@ async function runWasteCommand(opts = {}) {
13765
13839
  }
13766
13840
 
13767
13841
  // src/session_read.ts
13842
+ init_define_import_meta_env();
13768
13843
  import * as fs25 from "node:fs";
13769
13844
  import * as path26 from "node:path";
13770
13845
  import * as readline2 from "node:readline";
@@ -13931,6 +14006,7 @@ function formatSessionSlice(turns) {
13931
14006
  }
13932
14007
 
13933
14008
  // src/session_audit.ts
14009
+ init_define_import_meta_env();
13934
14010
  import * as fs26 from "node:fs";
13935
14011
  import * as os12 from "node:os";
13936
14012
  import * as path27 from "node:path";
@@ -14288,13 +14364,13 @@ async function auditOneFile(filePath, s, toolMap, attachmentMap, hookMap, laneOb
14288
14364
  s.readInterception.readResults += 1;
14289
14365
  const denyTemplate = DENY_TEMPLATES.find((t) => t.re.test(text));
14290
14366
  if (denyTemplate !== void 0) {
14291
- const path30 = readPathById.get(id) ?? "";
14292
- const lastSlash = path30.lastIndexOf("/");
14367
+ const path31 = readPathById.get(id) ?? "";
14368
+ const lastSlash = path31.lastIndexOf("/");
14293
14369
  openDenies.push({
14294
14370
  kind: denyTemplate.kind,
14295
14371
  withheldBytes: parseWithheldBytes(denyTemplate.kind, text),
14296
- path: path30,
14297
- basename: lastSlash === -1 ? path30 : path30.slice(lastSlash + 1),
14372
+ path: path31,
14373
+ basename: lastSlash === -1 ? path31 : path31.slice(lastSlash + 1),
14298
14374
  callIndexAtDeny: perCall.length,
14299
14375
  compactEpochAtOpen: compactEpoch,
14300
14376
  compactEpochAtWindow: null,
@@ -14762,6 +14838,7 @@ function formatSessionAudit(s) {
14762
14838
  }
14763
14839
 
14764
14840
  // src/cli_mcp_audit.ts
14841
+ init_define_import_meta_env();
14765
14842
  import * as fs27 from "node:fs";
14766
14843
  import * as os13 from "node:os";
14767
14844
  import * as path28 from "node:path";
@@ -14915,6 +14992,7 @@ async function runMcpAuditCommand(opts = {}) {
14915
14992
  }
14916
14993
 
14917
14994
  // src/cli_recall.ts
14995
+ init_define_import_meta_env();
14918
14996
  var RECALL_COMMAND = {
14919
14997
  bash: "bash-output",
14920
14998
  web: "web-output",
@@ -14974,7 +15052,231 @@ function runRecallCommand(query, opts = {}) {
14974
15052
  printHits(browse ? void 0 : query, hits);
14975
15053
  }
14976
15054
 
15055
+ // src/cli_bench.ts
15056
+ init_define_import_meta_env();
15057
+ import * as fs28 from "node:fs";
15058
+ import * as path29 from "node:path";
15059
+ var ControlFilter = class extends ToolFilter {
15060
+ constructor(name, transform) {
15061
+ super();
15062
+ this.name = name;
15063
+ this.transform = transform;
15064
+ }
15065
+ name;
15066
+ transform;
15067
+ apply(stdout, stderr, exitCode) {
15068
+ const originalBytes = Buffer.byteLength(stdout, "utf8") + Buffer.byteLength(stderr, "utf8");
15069
+ const text = this.transform(combineStreams(stdout, stderr));
15070
+ return new CompressedOutput(text, originalBytes, Buffer.byteLength(text, "utf8"), this.name, exitCode);
15071
+ }
15072
+ };
15073
+ var CONTROL_FILTERS = {
15074
+ identity: new ControlFilter("control:identity", (s) => s),
15075
+ destroy: new ControlFilter("control:destroy", () => "")
15076
+ };
15077
+ var MAX_BENCH_FILE_BYTES = 5 * 1024 * 1024;
15078
+ function readCaseFile(id, filePath, what) {
15079
+ const bytes = fs28.statSync(filePath).size;
15080
+ if (bytes > MAX_BENCH_FILE_BYTES) {
15081
+ throw new Error(
15082
+ `bench case ${id}: ${what} is ${bytes} bytes, over the ${MAX_BENCH_FILE_BYTES}-byte limit for a corpus file (${filePath})`
15083
+ );
15084
+ }
15085
+ return fs28.readFileSync(filePath, "utf8");
15086
+ }
15087
+ function parseCase(id, metaPath, outputPath) {
15088
+ const metaText = readCaseFile(id, metaPath, "metadata");
15089
+ let raw;
15090
+ try {
15091
+ raw = JSON.parse(metaText);
15092
+ } catch (e) {
15093
+ throw new Error(`bench case ${id}: ${metaPath} is not valid JSON (${e instanceof Error ? e.message : String(e)})`, { cause: e });
15094
+ }
15095
+ if (typeof raw !== "object" || raw === null) throw new Error(`bench case ${id}: expected a JSON object`);
15096
+ const meta = raw;
15097
+ const str = (key) => {
15098
+ const v = meta[key];
15099
+ if (typeof v !== "string" || v.trim() === "") throw new Error(`bench case ${id}: "${key}" must be a non-empty string`);
15100
+ return v;
15101
+ };
15102
+ const mustKeep = meta["mustKeep"];
15103
+ if (!Array.isArray(mustKeep) || mustKeep.some((s) => typeof s !== "string" || s === "")) {
15104
+ throw new Error(`bench case ${id}: "mustKeep" must be an array of non-empty strings`);
15105
+ }
15106
+ const exitCode = meta["exitCode"];
15107
+ if (exitCode !== void 0 && typeof exitCode !== "number") throw new Error(`bench case ${id}: "exitCode" must be a number`);
15108
+ return {
15109
+ id,
15110
+ provenance: str("provenance"),
15111
+ command: str("command"),
15112
+ exitCode: typeof exitCode === "number" ? exitCode : 0,
15113
+ mustKeep,
15114
+ output: readCaseFile(id, outputPath, "output")
15115
+ };
15116
+ }
15117
+ function loadCorpus(dir) {
15118
+ let entries;
15119
+ try {
15120
+ entries = fs28.readdirSync(dir);
15121
+ } catch {
15122
+ throw new Error(`bench corpus not found: ${dir}`);
15123
+ }
15124
+ const cases = [];
15125
+ for (const entry of entries.sort()) {
15126
+ if (!entry.endsWith(".json")) continue;
15127
+ const id = entry.slice(0, -".json".length);
15128
+ const outputPath = path29.join(dir, `${id}.txt`);
15129
+ if (!fs28.existsSync(outputPath)) throw new Error(`bench case ${id}: missing output file ${outputPath}`);
15130
+ cases.push(parseCase(id, path29.join(dir, entry), outputPath));
15131
+ }
15132
+ if (cases.length === 0) throw new Error(`bench corpus is empty: ${dir}`);
15133
+ return cases;
15134
+ }
15135
+ function runCase(c, control = "none") {
15136
+ const detected = detectFromCommand(c.command);
15137
+ const filter2 = control === "none" ? detected?.filter : CONTROL_FILTERS[control];
15138
+ const argv = detected?.argv ?? [];
15139
+ const delivery = filter2 ? deliverCompressed(filter2, c.output, "", c.exitCode, argv) : null;
15140
+ const body = delivery ? delivery.text + delivery.marker : c.output;
15141
+ const originalBytes = Buffer.byteLength(c.output, "utf8");
15142
+ const deliveredBytes = Buffer.byteLength(body, "utf8");
15143
+ const missing = c.mustKeep.filter((needle) => !body.includes(needle));
15144
+ return {
15145
+ id: c.id,
15146
+ command: c.command,
15147
+ filter: filter2?.name ?? null,
15148
+ applied: delivery?.applied ?? false,
15149
+ originalBytes,
15150
+ deliveredBytes,
15151
+ savedPercent: originalBytes > 0 ? 100 * Math.max(0, originalBytes - deliveredBytes) / originalBytes : 0,
15152
+ kept: c.mustKeep.length - missing.length,
15153
+ mustKeepTotal: c.mustKeep.length,
15154
+ missing
15155
+ };
15156
+ }
15157
+ function runCorpus(cases, control = "none") {
15158
+ const results = cases.map((c) => runCase(c, control));
15159
+ const sum = (pick) => results.reduce((n, r) => n + pick(r), 0);
15160
+ const originalBytes = sum((r) => r.originalBytes);
15161
+ const deliveredBytes = sum((r) => r.deliveredBytes);
15162
+ const kept = sum((r) => r.kept);
15163
+ const mustKeepTotal = sum((r) => r.mustKeepTotal);
15164
+ return {
15165
+ cases: results,
15166
+ originalBytes,
15167
+ deliveredBytes,
15168
+ ratioPercent: originalBytes > 0 ? 100 * Math.max(0, originalBytes - deliveredBytes) / originalBytes : 0,
15169
+ kept,
15170
+ mustKeepTotal,
15171
+ appliedCases: results.filter((r) => r.applied).length,
15172
+ coveredFilters: new Set(results.map((r) => r.filter).filter((n) => n !== null)).size,
15173
+ registeredFilters: TOOL_FILTERS.length,
15174
+ fidelityIntact: kept === mustKeepTotal
15175
+ };
15176
+ }
15177
+ var pct2 = (n) => `${n.toFixed(1)}%`;
15178
+ function renderTable(report, floorPercent) {
15179
+ const rows = [...report.cases].sort((a, b) => b.originalBytes - a.originalBytes);
15180
+ const idWidth = Math.max(4, ...rows.map((r) => r.id.length));
15181
+ const filterWidth = Math.max(6, ...rows.map((r) => (r.filter ?? "-").length));
15182
+ const lines = [];
15183
+ const header = `${"case".padEnd(idWidth)} ${"filter".padEnd(filterWidth)} ${"in".padStart(9)} ${"out".padStart(9)} ${"saved".padStart(7)} fidelity`;
15184
+ lines.push(header, "-".repeat(header.length));
15185
+ for (const r of rows) {
15186
+ const saved = r.applied ? pct2(r.savedPercent) : "-";
15187
+ const fidelity = `${r.kept}/${r.mustKeepTotal}${r.missing.length ? " FAIL" : ""}`;
15188
+ lines.push(
15189
+ `${r.id.padEnd(idWidth)} ${(r.filter ?? "-").padEnd(filterWidth)} ${String(r.originalBytes).padStart(9)} ${String(r.deliveredBytes).padStart(9)} ${saved.padStart(7)} ${fidelity}`
15190
+ );
15191
+ }
15192
+ lines.push("-".repeat(header.length));
15193
+ lines.push(
15194
+ `${"TOTAL".padEnd(idWidth)} ${"".padEnd(filterWidth)} ${String(report.originalBytes).padStart(9)} ${String(report.deliveredBytes).padStart(9)} ${pct2(report.ratioPercent).padStart(7)} ${report.kept}/${report.mustKeepTotal}`
15195
+ );
15196
+ lines.push("");
15197
+ lines.push(`ratio ${pct2(report.ratioPercent)} saved (PRIMARY -- must improve; measured floor ${pct2(floorPercent)}, headroom ${pct2(100 - report.ratioPercent)})`);
15198
+ lines.push(`fidelity ${report.kept}/${report.mustKeepTotal} kept (GUARD -- must not regress; any miss exits 1)`);
15199
+ lines.push(`coverage ${report.coveredFilters}/${report.registeredFilters} filters exercised, ${report.appliedCases}/${report.cases.length} cases compressed`);
15200
+ for (const r of report.cases) {
15201
+ for (const needle of r.missing) lines.push(` DROPPED ${r.id}: ${JSON.stringify(needle)}`);
15202
+ }
15203
+ return lines.join("\n");
15204
+ }
15205
+ function renderValidation(cases) {
15206
+ const identity = runCorpus(cases, "identity");
15207
+ const destroy = runCorpus(cases, "destroy");
15208
+ const checks = [
15209
+ {
15210
+ // Not "scores exactly 0%": the unapplied path delivers the streams recombined, which can
15211
+ // differ from the captured bytes by a trailing newline. That is a real property of delivery,
15212
+ // so the floor is measured and reported rather than assumed -- what must hold is that the
15213
+ // net-benefit gate REFUSED every no-op rewrite, which is what makes the floor a floor.
15214
+ label: "floor: the net-benefit gate refuses a no-op filter on every case",
15215
+ ok: identity.appliedCases === 0,
15216
+ detail: `identity control applied to ${identity.appliedCases}/${identity.cases.length} cases, measured floor ${pct2(identity.ratioPercent)}`
15217
+ },
15218
+ {
15219
+ label: "floor: a no-op filter keeps every must-keep line",
15220
+ ok: identity.fidelityIntact,
15221
+ detail: `identity control kept ${identity.kept}/${identity.mustKeepTotal}`
15222
+ },
15223
+ {
15224
+ label: "guard: deleting everything is caught",
15225
+ ok: !destroy.fidelityIntact,
15226
+ detail: `destroy control kept ${destroy.kept}/${destroy.mustKeepTotal} at ${pct2(destroy.ratioPercent)} saved`
15227
+ }
15228
+ ];
15229
+ const failed = checks.filter((c) => !c.ok);
15230
+ const lines = checks.map((c) => `${c.ok ? "ok " : "FAIL"} ${c.label} -- ${c.detail}`);
15231
+ lines.push("");
15232
+ lines.push(
15233
+ failed.length === 0 ? "The corpus discriminates: a ratio measured against it cannot be raised by deleting content." : `${failed.length} control check(s) failed. Do not optimise against this corpus until they pass.`
15234
+ );
15235
+ return { text: lines.join("\n"), code: failed.length === 0 ? 0 : 1 };
15236
+ }
15237
+ var TSV_HEADER = "timestamp commit cases original_bytes delivered_bytes ratio_percent fidelity_kept fidelity_total covered_filters\n";
15238
+ function appendTsv(file, report, commit) {
15239
+ const row = [
15240
+ (/* @__PURE__ */ new Date()).toISOString(),
15241
+ commit,
15242
+ report.cases.length,
15243
+ report.originalBytes,
15244
+ report.deliveredBytes,
15245
+ report.ratioPercent.toFixed(2),
15246
+ report.kept,
15247
+ report.mustKeepTotal,
15248
+ report.coveredFilters
15249
+ ].join(" ");
15250
+ const dir = path29.dirname(path29.resolve(file));
15251
+ fs28.mkdirSync(dir, { recursive: true });
15252
+ const header = fs28.existsSync(file) ? "" : TSV_HEADER;
15253
+ fs28.appendFileSync(file, header + row + "\n", "utf8");
15254
+ }
15255
+ function currentCommit(cwd) {
15256
+ const opts = cwd === void 0 ? {} : { cwd };
15257
+ try {
15258
+ const r = runGit(["rev-parse", "--short", "HEAD"], opts);
15259
+ const sha = r.stdout.trim();
15260
+ if (r.exitCode !== 0 || sha === "") return "unknown";
15261
+ const st = runGit(["status", "--porcelain"], opts);
15262
+ return st.exitCode === 0 && st.stdout.trim() !== "" ? `${sha}-dirty` : sha;
15263
+ } catch {
15264
+ return "unknown";
15265
+ }
15266
+ }
15267
+ function runBenchCommand(opts) {
15268
+ const cases = loadCorpus(opts.corpus);
15269
+ if (opts.validate === true) return renderValidation(cases);
15270
+ const report = runCorpus(cases);
15271
+ if (opts.tsv !== void 0) appendTsv(opts.tsv, report, currentCommit());
15272
+ const code = report.fidelityIntact ? 0 : 1;
15273
+ const floorPercent = runCorpus(cases, "identity").ratioPercent;
15274
+ if (opts.json === true) return { text: JSON.stringify({ ...report, floorPercent }, null, 2), code };
15275
+ return { text: renderTable(report, floorPercent), code };
15276
+ }
15277
+
14977
15278
  // src/cli_hint_stats.ts
15279
+ init_define_import_meta_env();
14978
15280
  function formatSpentCell(row) {
14979
15281
  if (row.emitted === 0) return "n/a";
14980
15282
  if (row.bytesEmitted === null) return "n/a (legacy)";
@@ -14990,9 +15292,9 @@ function printSummary(rows) {
14990
15292
  };
14991
15293
  w(pad("category", 22) + pad("emitted", 9) + pad("acted-on", 10) + pad("efficacy", 10) + pad("suppressed", 17) + pad("manual+", 9) + pad("manual-", 9) + "spent\n");
14992
15294
  for (const row of rows) {
14993
- const pct2 = row.efficacyPct === null ? "n/a" : `${row.efficacyPct}%`;
15295
+ const pct3 = row.efficacyPct === null ? "n/a" : `${row.efficacyPct}%`;
14994
15296
  w(
14995
- pad(row.category, 22) + pad(String(row.emitted), 9) + pad(String(row.actedOn), 10) + pad(pct2, 10) + pad(suppressedCell(row), 17) + pad(String(row.manualEffective), 9) + pad(String(row.manualIneffective), 9) + formatSpentCell(row) + "\n"
15297
+ pad(row.category, 22) + pad(String(row.emitted), 9) + pad(String(row.actedOn), 10) + pad(pct3, 10) + pad(suppressedCell(row), 17) + pad(String(row.manualEffective), 9) + pad(String(row.manualIneffective), 9) + formatSpentCell(row) + "\n"
14996
15298
  );
14997
15299
  }
14998
15300
  }
@@ -15044,6 +15346,7 @@ hints.backoff_thresholds is empty, so suppression here is permanent rather than
15044
15346
  }
15045
15347
 
15046
15348
  // src/cli_statusline.ts
15349
+ init_define_import_meta_env();
15047
15350
  var STDIN_TIMEOUT_MS = 1500;
15048
15351
  function isPlainObject(v) {
15049
15352
  return typeof v === "object" && v !== null && !Array.isArray(v);
@@ -15137,10 +15440,10 @@ function readBoundedText(text, file) {
15137
15440
  if (text === void 0 && file === void 0) throw new CliError("provide text or --file");
15138
15441
  let value;
15139
15442
  if (file !== void 0) {
15140
- if (fs28.statSync(file).size > CONTENT_MAX_INPUT_CHARS) {
15443
+ if (fs29.statSync(file).size > CONTENT_MAX_INPUT_CHARS) {
15141
15444
  throw new CliError(`file exceeds the ${CONTENT_MAX_INPUT_CHARS}-byte safety limit`);
15142
15445
  }
15143
- value = fs28.readFileSync(file, "utf8");
15446
+ value = fs29.readFileSync(file, "utf8");
15144
15447
  } else {
15145
15448
  if (text === void 0) throw new CliError("provide text or --file");
15146
15449
  value = text;
@@ -15278,7 +15581,7 @@ async function cmdIndex(pathArg, opts = {}) {
15278
15581
  continue;
15279
15582
  }
15280
15583
  const sha = fingerprintFile(key);
15281
- if (sha === null && !fs28.existsSync(key)) continue;
15584
+ if (sha === null && !fs29.existsSync(key)) continue;
15282
15585
  const entry = sha !== null ? getFileEntry(key, dbPath) : null;
15283
15586
  const spellingStale = entry !== null && indexedPathSpellingIsStale(entry.filePath, key);
15284
15587
  const parseUnchanged = !force && !spellingStale && sha !== null && entry?.sha === sha && entry.parserSha === PARSER_FINGERPRINT;
@@ -15304,7 +15607,7 @@ async function cmdIndex(pathArg, opts = {}) {
15304
15607
  }
15305
15608
  continue;
15306
15609
  }
15307
- if (!fs28.existsSync(key)) continue;
15610
+ if (!fs29.existsSync(key)) continue;
15308
15611
  }
15309
15612
  if (!embedUnchanged) {
15310
15613
  paintProgress("embedding");
@@ -15364,8 +15667,8 @@ async function cmdMcpServe() {
15364
15667
  let StdioServerTransport;
15365
15668
  try {
15366
15669
  ;
15367
- ({ createMcpServer } = await import("./token-goat-chunk-LEBYARO3.mjs"));
15368
- ({ StdioServerTransport } = await import("./token-goat-chunk-324QOJYZ.mjs"));
15670
+ ({ createMcpServer } = await import("./token-goat-chunk-3UBORD6Z.mjs"));
15671
+ ({ StdioServerTransport } = await import("./token-goat-chunk-EVC4TOLE.mjs"));
15369
15672
  } catch (err2) {
15370
15673
  process.stderr.write(
15371
15674
  `token-goat: mcp-server unavailable (could not load the MCP server modules): ${String(err2)}
@@ -15377,8 +15680,8 @@ async function cmdMcpServe() {
15377
15680
  const server = await createMcpServer();
15378
15681
  const transport = new StdioServerTransport();
15379
15682
  await server.connect(transport);
15380
- await new Promise((resolve14) => {
15381
- server.onclose = resolve14;
15683
+ await new Promise((resolve15) => {
15684
+ server.onclose = resolve15;
15382
15685
  });
15383
15686
  }
15384
15687
  function printBridgeVerificationNotice(harness) {
@@ -15389,7 +15692,7 @@ async function cmdHook(event, opts) {
15389
15692
  if (typeof opts.harness === "string" && opts.harness.length > 0) {
15390
15693
  process.env[ENV_KEYS.HARNESS_OVERRIDE] = opts.harness;
15391
15694
  }
15392
- const { relay } = await import("./token-goat-chunk-ZVN5WHTO.mjs");
15695
+ const { relay } = await import("./token-goat-chunk-HC5NMGPD.mjs");
15393
15696
  await relay(event);
15394
15697
  }
15395
15698
  async function cmdInstall(opts) {
@@ -15502,16 +15805,16 @@ async function cmdInstall(opts) {
15502
15805
  );
15503
15806
  }
15504
15807
  try {
15505
- const skillDir = path29.join(homedir13(), ".claude", "skills");
15506
- if (fs28.existsSync(skillDir)) {
15507
- const entries = fs28.readdirSync(skillDir, { withFileTypes: true });
15808
+ const skillDir = path30.join(homedir13(), ".claude", "skills");
15809
+ if (fs29.existsSync(skillDir)) {
15810
+ const entries = fs29.readdirSync(skillDir, { withFileTypes: true });
15508
15811
  const skillNames = [];
15509
15812
  const sessionId = getSessionId();
15510
15813
  for (const entry of entries) {
15511
15814
  if (!entry.isDirectory()) continue;
15512
- const skillFile = path29.join(skillDir, entry.name, "SKILL.md");
15513
- if (fs28.existsSync(skillFile)) {
15514
- const body = fs28.readFileSync(skillFile, "utf-8");
15815
+ const skillFile = path30.join(skillDir, entry.name, "SKILL.md");
15816
+ if (fs29.existsSync(skillFile)) {
15817
+ const body = fs29.readFileSync(skillFile, "utf-8");
15515
15818
  const compact = extractCompactFromMarker(body);
15516
15819
  if (compact === null) continue;
15517
15820
  const sourceSha = contentHash(body);
@@ -15521,10 +15824,10 @@ async function cmdInstall(opts) {
15521
15824
  }
15522
15825
  if (skillNames.length > 0) {
15523
15826
  const dir = skillOutputsDir();
15524
- await fs28.promises.mkdir(dir, { recursive: true });
15525
- const pregenPath = path29.join(dir, "pregen.json");
15827
+ await fs29.promises.mkdir(dir, { recursive: true });
15828
+ const pregenPath = path30.join(dir, "pregen.json");
15526
15829
  const pregenData = { ts: Date.now(), names: skillNames };
15527
- await fs28.promises.writeFile(pregenPath, JSON.stringify(pregenData, null, 2));
15830
+ await fs29.promises.writeFile(pregenPath, JSON.stringify(pregenData, null, 2));
15528
15831
  out(`Pre-generated ${skillNames.length} skill compacts.`);
15529
15832
  }
15530
15833
  }
@@ -15728,7 +16031,7 @@ ${formatSessionOutline(turns)}`;
15728
16031
  }
15729
16032
  function sessionTranscriptSize(transcriptPath) {
15730
16033
  try {
15731
- return fs28.statSync(transcriptPath).size;
16034
+ return fs29.statSync(transcriptPath).size;
15732
16035
  } catch {
15733
16036
  return 0;
15734
16037
  }
@@ -15858,7 +16161,7 @@ function fenceFileFieldIfMatched(text) {
15858
16161
  }
15859
16162
  function fileSizeOrZero(filePath) {
15860
16163
  try {
15861
- return fs28.statSync(filePath).size;
16164
+ return fs29.statSync(filePath).size;
15862
16165
  } catch {
15863
16166
  return 0;
15864
16167
  }
@@ -15873,11 +16176,11 @@ function cmdBashOutput(id, opts) {
15873
16176
  }
15874
16177
  let content;
15875
16178
  try {
15876
- const st = fs28.statSync(opts.file);
16179
+ const st = fs29.statSync(opts.file);
15877
16180
  if (st.isFIFO() || st.isSocket()) {
15878
16181
  throw new CliError(`--file '${opts.file}' is a special file (FIFO or socket) \u2014 only regular files are supported`);
15879
16182
  }
15880
- content = redactIfDotenv(opts.file, decodeSource(fs28.readFileSync(opts.file)));
16183
+ content = redactIfDotenv(opts.file, decodeSource(fs29.readFileSync(opts.file)));
15881
16184
  } catch (e) {
15882
16185
  if (e instanceof CliError) throw e;
15883
16186
  throw new CliError(`cannot read file: ${opts.file}`);
@@ -15986,9 +16289,9 @@ async function cmdPdfMeta(file, opts = {}) {
15986
16289
  }
15987
16290
  async function cmdImageMeta(file, opts = {}) {
15988
16291
  const meta = await runImageMeta(file);
15989
- if (!meta.sharpAvailable) {
15990
- const msg = "image-meta unavailable (install sharp to use this feature)";
15991
- const text2 = opts.json === true ? JSON.stringify({ bytes: meta.bytes, sharpAvailable: false, error: msg }, null, 2) : `Size: ${meta.bytes} bytes
16292
+ if (!meta.decodable) {
16293
+ const msg = "image-meta unavailable (not a format token-goat can read)";
16294
+ const text2 = opts.json === true ? JSON.stringify({ bytes: meta.bytes, decodable: false, error: msg }, null, 2) : `Size: ${meta.bytes} bytes
15992
16295
  ${msg}`;
15993
16296
  out(text2);
15994
16297
  return;
@@ -16287,7 +16590,7 @@ function readStdinPaths() {
16287
16590
  }
16288
16591
  let raw;
16289
16592
  try {
16290
- raw = fs28.readFileSync(0, "utf8");
16593
+ raw = fs29.readFileSync(0, "utf8");
16291
16594
  } catch (e) {
16292
16595
  throw new CliError(`could not read the file list from stdin: ${extractErrorMessage(e)}`);
16293
16596
  }
@@ -16323,7 +16626,7 @@ function emitExtraFileArgsNote(command, first, extras, opts = {}) {
16323
16626
  }
16324
16627
  async function cmdCompress(opts) {
16325
16628
  try {
16326
- const bashRunner = await import("./token-goat-chunk-NY4HYRSK.mjs");
16629
+ const bashRunner = await import("./token-goat-chunk-LLNA42NI.mjs");
16327
16630
  if (opts.compress === false) {
16328
16631
  process.exitCode = bashRunner.runRaw(opts.cmd, parseTimeout(opts.timeout, bashRunner.DEFAULT_TIMEOUT_SECONDS));
16329
16632
  return;
@@ -16349,7 +16652,7 @@ async function cmdSkillBody(name, opts) {
16349
16652
  if (filePath === null) {
16350
16653
  throw new CliError(`skill '${name}' not found`);
16351
16654
  }
16352
- const body = decodeSource(fs28.readFileSync(filePath));
16655
+ const body = decodeSource(fs29.readFileSync(filePath));
16353
16656
  if (opts.compact === true) {
16354
16657
  const emitted = extractCompactFromMarker(body) ?? body;
16355
16658
  out(emitted);
@@ -16376,7 +16679,7 @@ async function cmdSkillCompact(name, opts) {
16376
16679
  }
16377
16680
  let body2;
16378
16681
  try {
16379
- body2 = decodeSource(fs28.readFileSync(filePath));
16682
+ body2 = decodeSource(fs29.readFileSync(filePath));
16380
16683
  } catch {
16381
16684
  unresolvable++;
16382
16685
  continue;
@@ -16410,19 +16713,19 @@ async function cmdSkillCompact(name, opts) {
16410
16713
  if (!opts.path.trim()) {
16411
16714
  throw new CliError("--path cannot be empty");
16412
16715
  }
16413
- if (!fs28.existsSync(opts.path)) {
16716
+ if (!fs29.existsSync(opts.path)) {
16414
16717
  throw new CliError(`skill file not found: ${opts.path}`);
16415
16718
  }
16416
16719
  try {
16417
- body = fs28.readFileSync(opts.path, "utf-8");
16720
+ body = fs29.readFileSync(opts.path, "utf-8");
16418
16721
  } catch (e) {
16419
16722
  if (e.code === "ENOENT") {
16420
16723
  throw new CliError(`skill file not found: ${opts.path}`);
16421
16724
  }
16422
16725
  throw new CliError(`failed to read skill file '${opts.path}': ${extractErrorMessage(e)}`);
16423
16726
  }
16424
- cacheName = name ?? path29.basename(path29.dirname(path29.resolve(opts.path)));
16425
- sourcePath = path29.resolve(opts.path);
16727
+ cacheName = name ?? path30.basename(path30.dirname(path30.resolve(opts.path)));
16728
+ sourcePath = path30.resolve(opts.path);
16426
16729
  } else {
16427
16730
  if (name === void 0 || !name.trim()) {
16428
16731
  throw new CliError("skill-compact requires a <name> or --path <file>");
@@ -16431,7 +16734,7 @@ async function cmdSkillCompact(name, opts) {
16431
16734
  if (filePath === null) {
16432
16735
  throw new CliError(`skill '${name}' not found`);
16433
16736
  }
16434
- body = fs28.readFileSync(filePath, "utf-8");
16737
+ body = fs29.readFileSync(filePath, "utf-8");
16435
16738
  cacheName = name;
16436
16739
  sourcePath = filePath;
16437
16740
  }
@@ -16563,8 +16866,8 @@ async function cmdSkillDiff(name) {
16563
16866
  }
16564
16867
  const newer = versions[0];
16565
16868
  const older = versions[1];
16566
- const newerBody = await fs28.promises.readFile(path29.resolve(dir, `${newer.outputId}.txt`), "utf-8").catch(() => null);
16567
- const olderBody = await fs28.promises.readFile(path29.resolve(dir, `${older.outputId}.txt`), "utf-8").catch(() => null);
16869
+ const newerBody = await fs29.promises.readFile(path30.resolve(dir, `${newer.outputId}.txt`), "utf-8").catch(() => null);
16870
+ const olderBody = await fs29.promises.readFile(path30.resolve(dir, `${older.outputId}.txt`), "utf-8").catch(() => null);
16568
16871
  if (newerBody === null || olderBody === null) {
16569
16872
  out(`a cached version of '${name}' was evicted while diffing -- try again`);
16570
16873
  return;
@@ -16593,7 +16896,7 @@ async function cmdSkillSection(nameHeading, headingArg) {
16593
16896
  if (!filePath) {
16594
16897
  throw new CliError(`skill '${skillName}' not found`);
16595
16898
  }
16596
- const body = decodeSource(fs28.readFileSync(filePath));
16899
+ const body = decodeSource(fs29.readFileSync(filePath));
16597
16900
  const extracted = extractNamedSection(body, heading);
16598
16901
  if (!extracted) {
16599
16902
  const messages = [`Section '${heading}' not found in skill '${skillName}'`];
@@ -16608,7 +16911,7 @@ async function cmdSkillSection(nameHeading, headingArg) {
16608
16911
  }
16609
16912
  function atomicWriteBuffer(dest, data) {
16610
16913
  try {
16611
- if (fs28.statSync(dest).isDirectory()) {
16914
+ if (fs29.statSync(dest).isDirectory()) {
16612
16915
  const e = Object.assign(new Error(`EISDIR: illegal operation on a directory, open '${dest}'`), { code: "EISDIR", path: dest });
16613
16916
  throw e;
16614
16917
  }
@@ -16616,23 +16919,23 @@ function atomicWriteBuffer(dest, data) {
16616
16919
  if (e.code !== "ENOENT") throw e;
16617
16920
  }
16618
16921
  const rnd = randomBytes(4).toString("hex");
16619
- const tmp = path29.join(path29.dirname(path29.resolve(dest)), `.tmp.${process.pid}.${rnd}`);
16922
+ const tmp = path30.join(path30.dirname(path30.resolve(dest)), `.tmp.${process.pid}.${rnd}`);
16620
16923
  try {
16621
- fs28.writeFileSync(tmp, data, { mode: 384 });
16924
+ fs29.writeFileSync(tmp, data, { mode: 384 });
16622
16925
  try {
16623
- const destMode = fs28.statSync(dest).mode;
16624
- fs28.chmodSync(tmp, destMode);
16926
+ const destMode = fs29.statSync(dest).mode;
16927
+ fs29.chmodSync(tmp, destMode);
16625
16928
  } catch (e) {
16626
16929
  if (e.code !== "ENOENT") throw e;
16627
16930
  }
16628
16931
  withRetryOnLock(() => {
16629
16932
  try {
16630
- fs28.renameSync(tmp, dest);
16933
+ fs29.renameSync(tmp, dest);
16631
16934
  } catch (e) {
16632
16935
  if (e.code === "EXDEV") {
16633
- fs28.copyFileSync(tmp, dest);
16936
+ fs29.copyFileSync(tmp, dest);
16634
16937
  try {
16635
- fs28.unlinkSync(tmp);
16938
+ fs29.unlinkSync(tmp);
16636
16939
  } catch (ue) {
16637
16940
  process.stderr.write(`token-goat write-file: warning: could not remove temp file ${tmp}: ${ue.message}
16638
16941
  `);
@@ -16644,7 +16947,7 @@ function atomicWriteBuffer(dest, data) {
16644
16947
  });
16645
16948
  } catch (e) {
16646
16949
  try {
16647
- fs28.unlinkSync(tmp);
16950
+ fs29.unlinkSync(tmp);
16648
16951
  } catch {
16649
16952
  }
16650
16953
  throw e;
@@ -16654,9 +16957,9 @@ function mapFsError(e, src, dest, srcLabel = "source") {
16654
16957
  const fe = e;
16655
16958
  if (fe.code === "ENOENT") {
16656
16959
  const errPath = fe.path ?? "";
16657
- const isSource = src !== void 0 && path29.resolve(errPath) === path29.resolve(src);
16960
+ const isSource = src !== void 0 && path30.resolve(errPath) === path30.resolve(src);
16658
16961
  if (isSource) throw new CliError(`${/\bfile$/i.test(srcLabel) ? srcLabel : `${srcLabel} file`} not found: ${src}`);
16659
- const destDir = dest ? path29.dirname(path29.resolve(dest)) : path29.dirname(path29.resolve(errPath || "."));
16962
+ const destDir = dest ? path30.dirname(path30.resolve(dest)) : path30.dirname(path30.resolve(errPath || "."));
16660
16963
  throw new CliError(`destination directory does not exist: ${destDir}`);
16661
16964
  }
16662
16965
  if (fe.code === "ENOTDIR") {
@@ -16667,7 +16970,7 @@ function mapFsError(e, src, dest, srcLabel = "source") {
16667
16970
  }
16668
16971
  if (fe.code === "EISDIR") {
16669
16972
  const errPath = fe.path ?? "";
16670
- const isSource = src !== void 0 && (errPath === "" || path29.resolve(errPath) === path29.resolve(src));
16973
+ const isSource = src !== void 0 && (errPath === "" || path30.resolve(errPath) === path30.resolve(src));
16671
16974
  if (isSource) throw new CliError(`source is a directory, not a file: ${src}`);
16672
16975
  throw new CliError(`destination is a directory, not a file: ${dest ?? (errPath || "(unknown)")}`);
16673
16976
  }
@@ -16736,7 +17039,7 @@ function validateWritablePath(dest, label) {
16736
17039
  throw new CliError(`${label} path contains a null byte`);
16737
17040
  }
16738
17041
  if (isWindows()) {
16739
- const base = path29.basename(dest);
17042
+ const base = path30.basename(dest);
16740
17043
  const stem = base.replace(/\.[^.]*$/, "").toUpperCase();
16741
17044
  if (WIN_RESERVED.has(stem)) {
16742
17045
  throw new CliError(`${label} '${base}' is a reserved Windows device name`);
@@ -16766,7 +17069,7 @@ function readFileBoundedRaw(filePath, label, allowStdIn = false) {
16766
17069
  throw new CliError(`${label} ${filePath} requires piped input; use ${altLabel} for interactive use`);
16767
17070
  }
16768
17071
  try {
16769
- const st = fs28.statSync(filePath);
17072
+ const st = fs29.statSync(filePath);
16770
17073
  if (st.isFIFO() || st.isSocket()) {
16771
17074
  throw new CliError(`${label} '${filePath}' is a special file (FIFO or socket) \u2014 only regular files are supported`);
16772
17075
  }
@@ -16774,7 +17077,7 @@ function readFileBoundedRaw(filePath, label, allowStdIn = false) {
16774
17077
  if (st.size > maxBytes) {
16775
17078
  throw new CliError(`${label} '${filePath}' exceeds size limit (${Math.round(st.size / 1024 / 1024)} MB); set TOKEN_GOAT_MAX_STDIN_MB to override`);
16776
17079
  }
16777
- return fs28.readFileSync(filePath);
17080
+ return fs29.readFileSync(filePath);
16778
17081
  } catch (e) {
16779
17082
  if (e instanceof CliError) throw e;
16780
17083
  mapFsError(e, filePath, void 0, label);
@@ -16818,7 +17121,7 @@ function cmdNoteAdd(file, opts) {
16818
17121
  throw new CliError("note content must be valid UTF-8 text");
16819
17122
  }
16820
17123
  const resolvedPath = resolveIndexPath(file);
16821
- if (!fs28.existsSync(resolvedPath)) {
17124
+ if (!fs29.existsSync(resolvedPath)) {
16822
17125
  throw new CliError(`File not found: '${resolvedPath}'`);
16823
17126
  }
16824
17127
  healStaleIndex(resolvedPath);
@@ -16877,7 +17180,7 @@ function cmdWriteFile(dest, opts) {
16877
17180
  throw new CliError(`TOKEN_GOAT_MAX_STDIN_MB must be a positive integer; got '${process.env["TOKEN_GOAT_MAX_STDIN_MB"] ?? ""}'`);
16878
17181
  }
16879
17182
  const maxBytes = maxMB * 1024 * 1024;
16880
- return new Promise((resolve14, reject) => {
17183
+ return new Promise((resolve15, reject) => {
16881
17184
  const chunks = [];
16882
17185
  let totalBytes = 0;
16883
17186
  let settled = false;
@@ -16901,7 +17204,7 @@ function cmdWriteFile(dest, opts) {
16901
17204
  try {
16902
17205
  atomicWriteBuffer(dest, Buffer.concat(chunks));
16903
17206
  enqueueDirtyPathSafe(dest);
16904
- resolve14();
17207
+ resolve15();
16905
17208
  } catch (e) {
16906
17209
  try {
16907
17210
  mapFsError(e, void 0, dest);
@@ -17032,14 +17335,14 @@ function writeReplacedBuffer(file, replacedBuf, preWriteStat) {
17032
17335
  const until = process.env["TOKEN_GOAT_TEST_REPLACE_DELAY_UNTIL"];
17033
17336
  const deadline = Date.now() + testDelayMs;
17034
17337
  if (until !== void 0 && until !== "") {
17035
- while (Date.now() < deadline && !fs28.existsSync(until)) sleepSync(5);
17338
+ while (Date.now() < deadline && !fs29.existsSync(until)) sleepSync(5);
17036
17339
  } else {
17037
17340
  sleepSync(testDelayMs);
17038
17341
  }
17039
17342
  }
17040
17343
  let preRenameStat;
17041
17344
  try {
17042
- preRenameStat = fs28.statSync(file);
17345
+ preRenameStat = fs29.statSync(file);
17043
17346
  } catch {
17044
17347
  }
17045
17348
  if (preRenameStat !== void 0 && (preRenameStat.mtimeMs !== preWriteStat.mtimeMs || preRenameStat.size !== preWriteStat.size)) {
@@ -17080,7 +17383,7 @@ function cmdReplace(file, opts) {
17080
17383
  const targetBuf = readFileBoundedRaw(file, "target file", true);
17081
17384
  let preWriteStat;
17082
17385
  try {
17083
- preWriteStat = fs28.statSync(file);
17386
+ preWriteStat = fs29.statSync(file);
17084
17387
  } catch {
17085
17388
  }
17086
17389
  const usingFrom = opts.oldFrom !== void 0 || opts.newFrom !== void 0;
@@ -17174,7 +17477,7 @@ function cmdInsertSection(file, opts) {
17174
17477
  }
17175
17478
  let preWriteStat;
17176
17479
  try {
17177
- preWriteStat = fs28.statSync(file);
17480
+ preWriteStat = fs29.statSync(file);
17178
17481
  } catch {
17179
17482
  }
17180
17483
  const result = readSection(file, opts.after);
@@ -17200,7 +17503,7 @@ function cmdInsertSection(file, opts) {
17200
17503
  }
17201
17504
  let rawBytes;
17202
17505
  try {
17203
- rawBytes = fs28.readFileSync(file);
17506
+ rawBytes = fs29.readFileSync(file);
17204
17507
  } catch (e) {
17205
17508
  mapFsError(e, void 0, file);
17206
17509
  }
@@ -17216,7 +17519,7 @@ function cmdInsertSection(file, opts) {
17216
17519
  if (preWriteStat !== void 0) {
17217
17520
  let preRenameStat;
17218
17521
  try {
17219
- preRenameStat = fs28.statSync(file);
17522
+ preRenameStat = fs29.statSync(file);
17220
17523
  } catch {
17221
17524
  }
17222
17525
  if (preRenameStat !== void 0 && (preRenameStat.mtimeMs !== preWriteStat.mtimeMs || preRenameStat.size !== preWriteStat.size)) {
@@ -17258,25 +17561,25 @@ ${content}`;
17258
17561
  }
17259
17562
  function expandGlobs(root, patterns, globFnOverride) {
17260
17563
  const out2 = [];
17261
- const globFn = globFnOverride ?? fs28["globSync"];
17564
+ const globFn = globFnOverride ?? fs29["globSync"];
17262
17565
  for (const p of patterns) {
17263
17566
  if (globFn !== void 0 && (p.includes("*") || p.includes("?") || p.includes("{"))) {
17264
17567
  try {
17265
17568
  const hits = globFn(p, { cwd: root });
17266
- for (const h of hits) out2.push(path29.isAbsolute(h) ? h : path29.join(root, h));
17569
+ for (const h of hits) out2.push(path30.isAbsolute(h) ? h : path30.join(root, h));
17267
17570
  continue;
17268
17571
  } catch {
17269
17572
  }
17270
17573
  }
17271
- out2.push(path29.isAbsolute(p) ? p : path29.join(root, p));
17574
+ out2.push(path30.isAbsolute(p) ? p : path30.join(root, p));
17272
17575
  }
17273
17576
  return out2;
17274
17577
  }
17275
17578
  function readIgnoreFile(root) {
17276
- const ignorePath = path29.join(root, ".tokengoatignore");
17579
+ const ignorePath = path30.join(root, ".tokengoatignore");
17277
17580
  let raw;
17278
17581
  try {
17279
- raw = fs28.readFileSync(ignorePath, "utf8");
17582
+ raw = fs29.readFileSync(ignorePath, "utf8");
17280
17583
  } catch {
17281
17584
  return void 0;
17282
17585
  }
@@ -17317,14 +17620,14 @@ function cmdPack(patterns, opts) {
17317
17620
  }
17318
17621
  let instruction;
17319
17622
  if (opts.instructionFile !== void 0) {
17320
- instruction = fs28.readFileSync(opts.instructionFile, "utf8");
17623
+ instruction = fs29.readFileSync(opts.instructionFile, "utf8");
17321
17624
  }
17322
17625
  const formatted = formatPack(result, style, {
17323
17626
  ...opts.lineNumbers === true ? { line_numbers: true } : {},
17324
17627
  ...instruction !== void 0 ? { instruction } : {}
17325
17628
  });
17326
17629
  if (opts.output !== void 0) {
17327
- fs28.writeFileSync(opts.output, formatted, "utf8");
17630
+ fs29.writeFileSync(opts.output, formatted, "utf8");
17328
17631
  } else {
17329
17632
  out(formatted);
17330
17633
  }
@@ -17344,17 +17647,17 @@ function cmdTokens(patterns, opts) {
17344
17647
  if (opts.tree === true) {
17345
17648
  const dirs = /* @__PURE__ */ new Map();
17346
17649
  for (const e of entries) {
17347
- const dir = path29.dirname(e.rel_path);
17650
+ const dir = path30.dirname(e.rel_path);
17348
17651
  if (!dirs.has(dir)) dirs.set(dir, []);
17349
17652
  dirs.get(dir).push(e);
17350
17653
  }
17351
17654
  const lines2 = [];
17352
17655
  for (const [dir, dirEntries] of dirs) {
17353
17656
  const dirTokens = dirEntries.reduce((s, e) => s + e.tokens, 0);
17354
- const pct2 = result.total_tokens > 0 ? Math.round(dirTokens / result.total_tokens * 100) : 0;
17355
- lines2.push(`${dir}/ (${dirTokens} tokens, ${pct2}%)`);
17657
+ const pct3 = result.total_tokens > 0 ? Math.round(dirTokens / result.total_tokens * 100) : 0;
17658
+ lines2.push(`${dir}/ (${dirTokens} tokens, ${pct3}%)`);
17356
17659
  for (const e of dirEntries) {
17357
- lines2.push(` ${path29.basename(e.rel_path).padEnd(30)} ${String(e.tokens).padStart(8)} tokens`);
17660
+ lines2.push(` ${path30.basename(e.rel_path).padEnd(30)} ${String(e.tokens).padStart(8)} tokens`);
17358
17661
  }
17359
17662
  }
17360
17663
  out(lines2.join("\n"));
@@ -17388,7 +17691,7 @@ function cmdBudget(patterns, opts) {
17388
17691
  }
17389
17692
  }
17390
17693
  function cmdFailures(src, opts) {
17391
- const text = src !== void 0 ? fs28.readFileSync(src, "utf8") : fs28.readFileSync(0, "utf8");
17694
+ const text = src !== void 0 ? fs29.readFileSync(src, "utf8") : fs29.readFileSync(0, "utf8");
17392
17695
  const result = extractFailures(text, opts.runner !== void 0 ? { runner: opts.runner } : {});
17393
17696
  if (opts.delta !== true) {
17394
17697
  out(opts.json === true ? formatFailuresJson(result) : formatFailuresText(result));
@@ -17442,7 +17745,7 @@ function generateCompactHelp() {
17442
17745
  "",
17443
17746
  "Compression: compress-text, retrieve, handoff-create, handoff-resolve,",
17444
17747
  " compress, recall, bash-output, web-output, mcp-output, compress-text,",
17445
- " compress",
17748
+ " compress, bench",
17446
17749
  "",
17447
17750
  "Config & Integration: install, uninstall, mcp-serve, mcp-status, hook,",
17448
17751
  " bridges-status, worker, statusline, version, config, config-get,",
@@ -17628,6 +17931,16 @@ function buildProgram() {
17628
17931
  program2.command("bridges-status").description("hook-event parity matrix across every AI-harness bridge (read-only static analysis, never invokes a real harness binary)").option("--json", "emit the matrix as JSON instead of text").action(guard(cmdBridgesStatus));
17629
17932
  program2.command("commands").description("machine-readable manifest of every registered command, its options, and its arguments").option("--json", "emit the manifest as JSON instead of text").option("--grep <pattern>", "filter to commands whose name, description, or aliases match this regex").action(guard(cmdCommands));
17630
17933
  program2.command("mcp-serve").description("run token-goat as an MCP stdio server exposing surgical reads and local compression/handoff tools").action(guard(cmdMcpServe));
17934
+ 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(
17935
+ (opts) => runExitText(
17936
+ () => runBenchCommand({
17937
+ corpus: opts.corpus ?? path30.join("tests", "fixtures", "bench"),
17938
+ ...opts.tsv !== void 0 ? { tsv: opts.tsv } : {},
17939
+ ...opts.validate === true ? { validate: true } : {},
17940
+ ...opts.json === true ? { json: true } : {}
17941
+ })
17942
+ )
17943
+ );
17631
17944
  program2.command("compress-text [text]").description("compress arbitrary local text and print an opaque recovery ID plus compact payload").option("--file <path>", "read text from a local file instead of the argument").option("--payload", "always print the compact payload, even when inlining it costs more tokens than the original text").action(guard(cmdContentCompress));
17632
17945
  program2.command("retrieve <id>").description("retrieve original text previously stored by token-goat compress").option("--head <n>", "show first N lines").option("--tail <n>", "show last N lines").option("--grep <pattern>", "filter lines matching regex").option("--max-matches <n>", "cap --grep output to the first N matching lines").option("--section <heading>", "extract a specific section from the retrieved text").option("--full", "print the entire retrieved text with no head/tail elision (default behaviour when no other flag is given)").action(guard(cmdRetrieve));
17633
17946
  program2.command("handoff-create <name> [text]").description("create a project-local named compressed handoff").option("--file <path>", "read handoff text from a local file instead of the argument").action(guard(cmdHandoffCreate));
@@ -18076,7 +18389,7 @@ async function run(argv = process.argv) {
18076
18389
  return;
18077
18390
  }
18078
18391
  if (argv[2] === "--batch-serve" && typeof argv[3] === "string") {
18079
- const { serveBatch } = await import("./token-goat-chunk-G6XLWJWI.mjs");
18392
+ const { serveBatch } = await import("./token-goat-chunk-E3K3BTEQ.mjs");
18080
18393
  serveBatch(argv[3], (a) => run(a));
18081
18394
  return;
18082
18395
  }