token-goat 2.9.26 → 2.9.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/README.md +30 -88
  2. package/SECURITY.md +14 -0
  3. package/dist/{token-goat-chunk-OZRSREKR.mjs → token-goat-chunk-2AWQ2R5X.mjs} +2 -2
  4. package/dist/{token-goat-chunk-BH4ZVRB2.mjs → token-goat-chunk-2NNUA2LR.mjs} +4 -4
  5. package/dist/token-goat-chunk-2WOUYWLM.mjs +955 -0
  6. package/dist/{token-goat-chunk-IKZLSRII.mjs → token-goat-chunk-435UQTKD.mjs} +5 -3
  7. package/dist/{token-goat-chunk-62IHOU6L.mjs → token-goat-chunk-44BM7DDQ.mjs} +5 -3
  8. package/dist/token-goat-chunk-52NSDWYY.mjs +96 -0
  9. package/dist/{token-goat-chunk-CXBOFPF4.mjs → token-goat-chunk-67BNIKKO.mjs} +32 -18
  10. package/dist/{token-goat-chunk-XBESNWEX.mjs → token-goat-chunk-6AK46ZT7.mjs} +2 -3
  11. package/dist/{token-goat-chunk-7SXPJOSZ.mjs → token-goat-chunk-7CPMDFGB.mjs} +166 -40
  12. package/dist/token-goat-chunk-ASLWOQ3I.mjs +14 -0
  13. package/dist/{token-goat-chunk-MWID3YOY.mjs → token-goat-chunk-BGYOZ6DO.mjs} +6 -4
  14. package/dist/{token-goat-chunk-PAV6NNY7.mjs → token-goat-chunk-C5YPNZKQ.mjs} +22 -8
  15. package/dist/{token-goat-chunk-D2X7XN5M.mjs → token-goat-chunk-CIQ2FTY3.mjs} +23 -242
  16. package/dist/token-goat-chunk-D4ETHJD6.mjs +246 -0
  17. package/dist/{token-goat-chunk-7Y6GWTII.mjs → token-goat-chunk-DNRPXHYH.mjs} +25 -17
  18. package/dist/{token-goat-chunk-L43RKNHA.mjs → token-goat-chunk-DNSPXQXQ.mjs} +2 -2
  19. package/dist/token-goat-chunk-DPNLUJWB.mjs +220 -0
  20. package/dist/token-goat-chunk-E4ZOJIZK.mjs +1382 -0
  21. package/dist/token-goat-chunk-E5TK5DNO.mjs +718 -0
  22. package/dist/{token-goat-chunk-VVROQBQJ.mjs → token-goat-chunk-EUSDXRXU.mjs} +62 -12
  23. package/dist/{token-goat-chunk-POOI26O6.mjs → token-goat-chunk-FTP4U4QA.mjs} +12 -8
  24. package/dist/token-goat-chunk-G23DWHV4.mjs +142 -0
  25. package/dist/{token-goat-chunk-MDV5VWF4.mjs → token-goat-chunk-G7IWXCFF.mjs} +223 -15
  26. package/dist/{token-goat-chunk-C2PG4K5D.mjs → token-goat-chunk-GLXRTTLE.mjs} +7 -5
  27. package/dist/{token-goat-chunk-M6CVNHTW.mjs → token-goat-chunk-H5J3C56Q.mjs} +95 -573
  28. package/dist/{token-goat-chunk-BAWKGODL.mjs → token-goat-chunk-HNFZZHFW.mjs} +2 -2
  29. package/dist/{token-goat-chunk-TG5ZPD6B.mjs → token-goat-chunk-HUYUHODZ.mjs} +1036 -759
  30. package/dist/token-goat-chunk-IVE6U7KV.mjs +53 -0
  31. package/dist/{token-goat-chunk-ZZT6PVB3.mjs → token-goat-chunk-IVWI2OCK.mjs} +72 -45
  32. package/dist/{token-goat-chunk-GMOUBOX4.mjs → token-goat-chunk-JTKCQMQA.mjs} +37 -5
  33. package/dist/{token-goat-chunk-H2CPLEMP.mjs → token-goat-chunk-KOPIR3KZ.mjs} +46 -23
  34. package/dist/token-goat-chunk-L7H3U27L.mjs +35 -0
  35. package/dist/{token-goat-chunk-FLEYOCAS.mjs → token-goat-chunk-LZNBQTDK.mjs} +6 -4
  36. package/dist/token-goat-chunk-MELOKFDJ.mjs +199 -0
  37. package/dist/{token-goat-chunk-RH27ZSPF.mjs → token-goat-chunk-NMBWLRHW.mjs} +164 -50
  38. package/dist/{token-goat-chunk-43JFN26X.mjs → token-goat-chunk-O6I2XU4P.mjs} +27 -967
  39. package/dist/{token-goat-chunk-G6EYO5CD.mjs → token-goat-chunk-ONXH6NZ5.mjs} +2 -87
  40. package/dist/token-goat-chunk-ORNFMIER.mjs +295 -0
  41. package/dist/{token-goat-chunk-LHUP4DXZ.mjs → token-goat-chunk-PGTH2U4C.mjs} +1 -1
  42. package/dist/{token-goat-chunk-5BQ7W7D7.mjs → token-goat-chunk-PKRWMHVP.mjs} +76 -59
  43. package/dist/{token-goat-chunk-DA43OE7L.mjs → token-goat-chunk-PQ53BSCF.mjs} +1 -1
  44. package/dist/{token-goat-chunk-STYRLQIW.mjs → token-goat-chunk-PYSUADX4.mjs} +2 -2
  45. package/dist/{token-goat-chunk-JALB3KWJ.mjs → token-goat-chunk-QO3LXVVR.mjs} +4247 -5005
  46. package/dist/{token-goat-chunk-L45IWWMC.mjs → token-goat-chunk-RLP6J7WR.mjs} +6 -6
  47. package/dist/token-goat-chunk-RQGGMPCR.mjs +205 -0
  48. package/dist/{token-goat-chunk-MBDJR6HU.mjs → token-goat-chunk-RTMVLHWX.mjs} +3708 -4003
  49. package/dist/{token-goat-chunk-E3K3BTEQ.mjs → token-goat-chunk-S4VSXURL.mjs} +8 -6
  50. package/dist/{token-goat-chunk-LKSXAMJB.mjs → token-goat-chunk-SE6E4BKJ.mjs} +1 -1
  51. package/dist/token-goat-chunk-TCQANXYC.mjs +351 -0
  52. package/dist/token-goat-chunk-TDUT2CL6.mjs +564 -0
  53. package/dist/{token-goat-chunk-LRIZ7K3F.mjs → token-goat-chunk-TGOXNAHW.mjs} +54 -111
  54. package/dist/{token-goat-chunk-WNBSCSAI.mjs → token-goat-chunk-UA5BKWWQ.mjs} +1 -1
  55. package/dist/{token-goat-chunk-RIB6XY2V.mjs → token-goat-chunk-UXSXQQIY.mjs} +1 -1
  56. package/dist/{token-goat-chunk-7EPYB34H.mjs → token-goat-chunk-VMFWNHGR.mjs} +84 -73
  57. package/dist/token-goat-chunk-VQ6F6T7X.mjs +36 -0
  58. package/dist/{token-goat-chunk-5M3NRJD2.mjs → token-goat-chunk-VZQEWRVH.mjs} +6 -4
  59. package/dist/{token-goat-chunk-OSUFN2FV.mjs → token-goat-chunk-XB5KKOCG.mjs} +5 -25
  60. package/dist/{token-goat-chunk-6E2IDLHF.mjs → token-goat-chunk-XYWPOSCN.mjs} +57 -615
  61. package/dist/{token-goat-chunk-CQHY4SL7.mjs → token-goat-chunk-YAGLESS3.mjs} +8 -5
  62. package/dist/token-goat-chunk-YKSRAWUU.mjs +33 -0
  63. package/dist/{token-goat-chunk-F2ARFHLJ.mjs → token-goat-chunk-YOOVFPTP.mjs} +2 -2
  64. package/dist/{token-goat-chunk-EEIDFMEM.mjs → token-goat-chunk-YZAAZU2S.mjs} +12 -3
  65. package/dist/token-goat-chunk-Z6KBMOBI.mjs +53 -0
  66. package/dist/{token-goat-chunk-4GEDH2WU.mjs → token-goat-chunk-ZER6EAXZ.mjs} +81 -70
  67. package/dist/token-goat-hook-client.cjs +475 -0
  68. package/dist/token-goat-hook-client.mjs +26 -0
  69. package/dist/token-goat-hook.mjs +31 -21
  70. package/dist/token-goat.core.mjs +9 -39
  71. package/docs/C4_RUNTIME_ARCHITECTURE.md +2 -2
  72. package/docs/cli.md +35 -23
  73. package/docs/install.md +18 -14
  74. package/package.json +1 -1
  75. package/dist/token-goat-chunk-ADMR3QVF.mjs +0 -41
  76. package/dist/token-goat-chunk-E6B2UFDF.mjs +0 -30
  77. package/dist/token-goat-chunk-GKZ2US5B.mjs +0 -187
  78. package/dist/token-goat-chunk-MZTO4FXH.mjs +0 -26
@@ -0,0 +1,53 @@
1
+ import { createRequire as __cjsRequire } from 'node:module';
2
+ const require = __cjsRequire(import.meta.url);
3
+ import {
4
+ init_define_import_meta_env
5
+ } from "./token-goat-chunk-A37V4PBF.mjs";
6
+
7
+ // src/env.ts
8
+ init_define_import_meta_env();
9
+ var FALSY_ENV_VALUES = /* @__PURE__ */ new Set(["0", "false", "no", "off"]);
10
+ var TRUTHY_ENV_VALUES = /* @__PURE__ */ new Set(["1", "true", "yes", "on"]);
11
+ function envStr(key, defaultVal) {
12
+ const raw = process.env[key];
13
+ if (raw === void 0) return defaultVal;
14
+ const trimmed = raw.trim();
15
+ return trimmed === "" ? defaultVal : trimmed;
16
+ }
17
+ function envBool(key, defaultVal) {
18
+ const raw = process.env[key];
19
+ if (raw === void 0) return defaultVal;
20
+ const norm = raw.trim().toLowerCase();
21
+ if (norm === "") return defaultVal;
22
+ if (TRUTHY_ENV_VALUES.has(norm)) return true;
23
+ if (FALSY_ENV_VALUES.has(norm)) return false;
24
+ return defaultVal;
25
+ }
26
+ function envInt(key, defaultVal, min, max) {
27
+ const raw = process.env[key];
28
+ if (raw === void 0) return defaultVal;
29
+ const norm = raw.trim();
30
+ if (norm === "") return defaultVal;
31
+ if (!/^[+-]?\d+$/.test(norm)) return defaultVal;
32
+ const val = parseInt(norm, 10);
33
+ if (!Number.isFinite(val)) return defaultVal;
34
+ let clamped = val;
35
+ if (min !== void 0) clamped = Math.max(min, clamped);
36
+ if (max !== void 0) clamped = Math.min(max, clamped);
37
+ return clamped;
38
+ }
39
+ function envStrList(key, defaultVal, delimiter) {
40
+ const raw = process.env[key];
41
+ if (raw === void 0) return defaultVal;
42
+ const entries = raw.split(delimiter).map((s) => s.trim()).filter((s) => s !== "");
43
+ return entries.length > 0 ? entries : defaultVal;
44
+ }
45
+
46
+ export {
47
+ FALSY_ENV_VALUES,
48
+ TRUTHY_ENV_VALUES,
49
+ envStr,
50
+ envBool,
51
+ envInt,
52
+ envStrList
53
+ };
@@ -1,25 +1,29 @@
1
1
  import { createRequire as __cjsRequire } from 'node:module';
2
2
  const require = __cjsRequire(import.meta.url);
3
3
  import {
4
- ToolFilter,
4
+ deliveredOutputBytes
5
+ } from "./token-goat-chunk-L7H3U27L.mjs";
6
+ import {
7
+ PassthroughFilter,
5
8
  compressedTokensSaved,
6
9
  deliverCompressed,
7
10
  dispatchArgv,
8
11
  filterByName,
9
12
  selectFilter
10
- } from "./token-goat-chunk-4GEDH2WU.mjs";
13
+ } from "./token-goat-chunk-ZER6EAXZ.mjs";
11
14
  import {
12
- capTokens,
13
- shlexSplit,
14
15
  storeBashOutputSync
15
- } from "./token-goat-chunk-43JFN26X.mjs";
16
+ } from "./token-goat-chunk-O6I2XU4P.mjs";
17
+ import {
18
+ capTokens,
19
+ shlexSplit
20
+ } from "./token-goat-chunk-2WOUYWLM.mjs";
16
21
  import {
17
22
  recordStat
18
- } from "./token-goat-chunk-D2X7XN5M.mjs";
23
+ } from "./token-goat-chunk-CIQ2FTY3.mjs";
19
24
  import {
20
- detectHarness,
21
25
  loadConfig
22
- } from "./token-goat-chunk-LRIZ7K3F.mjs";
26
+ } from "./token-goat-chunk-TGOXNAHW.mjs";
23
27
  import {
24
28
  init_define_import_meta_env
25
29
  } from "./token-goat-chunk-A37V4PBF.mjs";
@@ -29,28 +33,6 @@ init_define_import_meta_env();
29
33
  import { spawn, spawnSync } from "node:child_process";
30
34
  import * as os from "node:os";
31
35
 
32
- // src/delivery_cap.ts
33
- init_define_import_meta_env();
34
- var CLAUDE_CODE_BASH_OUTPUT_CAP_BYTES = 2e4;
35
- var CLAUDE_CODE_PERSISTED_PREVIEW_BYTES = 2048;
36
- function bashOutputCapBytes(harness = detectHarness()) {
37
- return harness === "claudecode" ? CLAUDE_CODE_BASH_OUTPUT_CAP_BYTES : null;
38
- }
39
- function clipToDeliveryCap(text, reserveBytes) {
40
- const cap = bashOutputCapBytes();
41
- const room = cap === null ? null : cap - reserveBytes;
42
- if (room === null || room <= 0 || Buffer.byteLength(text, "utf-8") <= room) return { text, clipped: false };
43
- const sliced = Buffer.from(text, "utf-8").subarray(0, room).toString("utf-8");
44
- const lastNewline = sliced.lastIndexOf("\n");
45
- return { text: lastNewline > 0 ? sliced.slice(0, lastNewline) : sliced, clipped: true };
46
- }
47
- function deliveredOutputBytes(originalBytes, harness) {
48
- const cap = bashOutputCapBytes(harness);
49
- if (cap === null) return Math.max(0, originalBytes);
50
- if (originalBytes <= cap) return Math.max(0, originalBytes);
51
- return CLAUDE_CODE_PERSISTED_PREVIEW_BYTES;
52
- }
53
-
54
36
  // src/shell.ts
55
37
  init_define_import_meta_env();
56
38
  import * as fs from "node:fs";
@@ -108,11 +90,41 @@ function wrappedShell() {
108
90
  function canRunWrappedShell() {
109
91
  return process.platform !== "win32" || resolveWindowsBash() !== null;
110
92
  }
93
+ function resolvePowerShell(env = process.env, isExe = isExecutable) {
94
+ const override = env["TOKEN_GOAT_POWERSHELL"] || env["TOKEN_GOAT_PWSH"];
95
+ if (override && isExe(override)) return override;
96
+ if (process.platform === "win32") {
97
+ for (const dir of (env["PATH"] ?? "").split(path.delimiter)) {
98
+ if (!dir) continue;
99
+ const cand = path.join(dir, "pwsh.exe");
100
+ if (isExe(cand)) return cand;
101
+ }
102
+ const systemRoot = env["SystemRoot"] ?? env["windir"] ?? "C:\\Windows";
103
+ const defaultPs = path.join(systemRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe");
104
+ if (isExe(defaultPs)) return defaultPs;
105
+ return "powershell.exe";
106
+ }
107
+ for (const dir of (env["PATH"] ?? "").split(path.delimiter)) {
108
+ if (!dir) continue;
109
+ const cand = path.join(dir, "pwsh");
110
+ if (isExe(cand)) return cand;
111
+ }
112
+ for (const cand of ["/usr/bin/pwsh", "/usr/local/bin/pwsh", "/opt/microsoft/powershell/7/pwsh"]) {
113
+ if (isExe(cand)) return cand;
114
+ }
115
+ return "pwsh";
116
+ }
117
+ function canRunPowerShell(env = process.env, isExe = isExecutable) {
118
+ if (process.platform === "win32") return true;
119
+ try {
120
+ const ps = resolvePowerShell(env, isExe);
121
+ return isExe(ps);
122
+ } catch {
123
+ return false;
124
+ }
125
+ }
111
126
 
112
127
  // src/bash_runner.ts
113
- var IdentityFilter = class extends ToolFilter {
114
- name = "passthrough";
115
- };
116
128
  var DEFAULT_TIMEOUT_SECONDS = 600;
117
129
  var MAX_CAPTURE_BYTES = 32 * 1024 * 1024;
118
130
  var MIN_RECORD_STAT_BYTES = 32;
@@ -180,8 +192,22 @@ function resolveFilter(command, filterName, cwd) {
180
192
  function baseSpawnOptions(timeout, cwd) {
181
193
  return { timeout: timeout * 1e3, cwd };
182
194
  }
183
- function spawnTarget(command, nativeShell) {
184
- const shell = nativeShell ? true : wrappedShell();
195
+ function spawnTarget(command, nativeShell, shellType) {
196
+ if (shellType === "pwsh" || shellType === "powershell") {
197
+ const ps = resolvePowerShell();
198
+ return {
199
+ file: ps,
200
+ args: [
201
+ "-NoProfile",
202
+ "-NonInteractive",
203
+ "-Command",
204
+ "$c = $env:TG_CMD; Remove-Item Env:\\TG_CMD -ErrorAction SilentlyContinue; [scriptblock]::Create($c).Invoke(); if ($LASTEXITCODE -ne $null -and $LASTEXITCODE -ne 0) { exit $LASTEXITCODE }"
205
+ ],
206
+ shell: false,
207
+ cmdEnv: { TG_CMD: command }
208
+ };
209
+ }
210
+ const shell = nativeShell || shellType === "native" ? true : wrappedShell();
185
211
  if (typeof shell === "string") return { file: shell, args: ["-c", 'eval "$TG_CMD"'], shell: false, cmdEnv: { TG_CMD: command } };
186
212
  return { file: command, args: [], shell };
187
213
  }
@@ -214,17 +240,17 @@ async function run(command, opts = {}) {
214
240
  const { filter, argv } = resolveFilter(command, opts.filterName, opts.cwd);
215
241
  if (filter === null) {
216
242
  if ((opts.maxTokens ?? 0) > 0 || opts.quietSuccess) {
217
- return wrapAndCompress(command, argv, new IdentityFilter(), timeout, resolveProfile(opts.compressionProfile), opts);
243
+ return wrapAndCompress(command, argv, new PassthroughFilter(), timeout, resolveProfile(opts.compressionProfile), opts);
218
244
  }
219
- return passthrough(command, timeout, opts.cwd, opts.env, opts.nativeShell);
245
+ return passthrough(command, timeout, opts.cwd, opts.env, opts.nativeShell, opts.shellType);
220
246
  }
221
247
  return wrapAndCompress(command, argv, filter, timeout, resolveProfile(opts.compressionProfile), opts);
222
248
  }
223
- function runRaw(command, timeout = DEFAULT_TIMEOUT_SECONDS) {
224
- return passthrough(command, timeout, void 0, void 0);
249
+ function runRaw(command, timeout = DEFAULT_TIMEOUT_SECONDS, nativeShell, shellType) {
250
+ return passthrough(command, timeout, void 0, void 0, nativeShell, shellType);
225
251
  }
226
- function passthrough(command, timeout, cwd, env, nativeShell) {
227
- const { file, args, shell, cmdEnv } = spawnTarget(command, nativeShell);
252
+ function passthrough(command, timeout, cwd, env, nativeShell, shellType) {
253
+ const { file, args, shell, cmdEnv } = spawnTarget(command, nativeShell, shellType);
228
254
  const result = spawnSync(file, args, {
229
255
  ...baseSpawnOptions(timeout, cwd),
230
256
  shell,
@@ -247,7 +273,7 @@ async function wrapAndCompress(command, argv, filter, timeout, profile, opts) {
247
273
  const writeStdout = opts.writeStdout ?? ((s) => process.stdout.write(s));
248
274
  const writeStderr = opts.writeStderr ?? ((s) => process.stderr.write(s));
249
275
  const startTime = Date.now();
250
- const { file, args, shell, cmdEnv } = spawnTarget(command, opts.nativeShell);
276
+ const { file, args, shell, cmdEnv } = spawnTarget(command, opts.nativeShell, opts.shellType);
251
277
  const stdoutSink = new CaptureSink(MAX_CAPTURE_BYTES);
252
278
  const stderrSink = new CaptureSink(MAX_CAPTURE_BYTES);
253
279
  let timedOut = false;
@@ -311,11 +337,13 @@ async function wrapAndCompress(command, argv, filter, timeout, profile, opts) {
311
337
  let text = delivered;
312
338
  const maxTokens = opts.maxTokens ?? 0;
313
339
  if (maxTokens > 0) text = capTokens(text, maxTokens);
340
+ const capped = text !== delivered;
314
341
  let body = text + marker;
315
- if (applied) {
342
+ if (applied || capped) {
316
343
  const fullRaw = (stdoutText + (stderrText ? "\n" + stderrText : "")).trim();
317
344
  const recallId = storeBashOutputSync(command, fullRaw, exitCode, opts.cwd ?? null);
318
345
  body += "\n[token-goat] full output: bash-output " + recallId + " --full";
346
+ if (opts.capHint) body += "\n[token-goat] " + opts.capHint;
319
347
  }
320
348
  writeStdout(body.endsWith("\n") ? body : body + "\n");
321
349
  if (applied) recordSavings(compressed);
@@ -329,9 +357,8 @@ function recordSavings(result) {
329
357
  }
330
358
 
331
359
  export {
332
- clipToDeliveryCap,
333
- deliveredOutputBytes,
334
360
  canRunWrappedShell,
361
+ canRunPowerShell,
335
362
  DEFAULT_TIMEOUT_SECONDS,
336
363
  MAX_CAPTURE_BYTES,
337
364
  DEFAULT_HEARTBEAT_INTERVAL_MS,
@@ -24,6 +24,7 @@ function climbsBetweenRungs(previous, elapsed) {
24
24
  }
25
25
  var PROBE_TERMINATORS = ["!", "a", "0", " ", "\uFFFF", "\n", "\u2028"];
26
26
  var PROBE_BUDGET_MS = 25;
27
+ var LINEAR_BY_CONSTRUCTION_EXCLUDES = /[*+?{|]/;
27
28
  var MAX_COUNTED_REPEAT = 8;
28
29
  var LITERAL_RUN_ATOM = /[^\\()[\]{}|^$*+?]/;
29
30
  var QUANTIFIER_AT = /^[*+?{]/;
@@ -38,6 +39,22 @@ function timeMatch(re, input) {
38
39
  again.test(input);
39
40
  return { ms: Math.min(first, performance.now() - restarted), matched };
40
41
  }
42
+ function confirmed(re, input, first) {
43
+ const again = timeMatch(re, input);
44
+ return again.ms < first.ms ? { ms: again.ms, matched: first.matched } : first;
45
+ }
46
+ function remeasuredForProjection(re, timings, inputs) {
47
+ const hi = timings.length - 1;
48
+ const hiLength = PROBE_LENGTHS[hi];
49
+ const lo = hiLength === void 0 ? -1 : PROBE_LENGTHS.findIndex((l) => l * 2 >= hiLength);
50
+ const out = [...timings];
51
+ for (const i of /* @__PURE__ */ new Set([lo, hi])) {
52
+ const input = inputs[i];
53
+ const ms = out[i];
54
+ if (input !== void 0 && ms !== void 0) out[i] = Math.min(ms, timeMatch(re, input).ms);
55
+ }
56
+ return out;
57
+ }
41
58
  var ESCAPE_SAMPLES = {
42
59
  s: " ",
43
60
  S: "a",
@@ -207,15 +224,24 @@ function climbsPastBudget(re) {
207
224
  const candidates = [tail, ...PROBE_TERMINATORS.filter((t) => t !== tail)];
208
225
  let swept;
209
226
  const timings = [];
227
+ const inputs = [];
210
228
  let previous;
211
229
  for (const length of PROBE_LENGTHS) {
212
230
  let failing;
213
231
  let last;
232
+ let failingInput = "";
233
+ let lastInput = "";
214
234
  const attempt = (candidate) => {
215
- const m = timeMatch(re, body(length) + candidate);
235
+ const input = body(length) + candidate;
236
+ let m = timeMatch(re, input);
237
+ if (m.ms > PROBE_BUDGET_MS) m = confirmed(re, input, m);
216
238
  last = m;
239
+ lastInput = input;
217
240
  if (m.ms > PROBE_BUDGET_MS) return "over-budget";
218
- if (!m.matched) failing = m;
241
+ if (!m.matched) {
242
+ failing = m;
243
+ failingInput = input;
244
+ }
219
245
  return m;
220
246
  };
221
247
  for (const candidate of swept === void 0 ? candidates : [swept, ...candidates]) {
@@ -235,12 +261,17 @@ function climbsPastBudget(re) {
235
261
  sweptMs += Date.now() - sweepStarted;
236
262
  }
237
263
  if (failing !== void 0) falsified = true;
238
- const elapsed = (failing ?? last).ms;
239
- if (climbsBetweenRungs(previous, elapsed)) return "ratio";
264
+ let elapsed = (failing ?? last).ms;
265
+ const rungInput = failing !== void 0 ? failingInput : lastInput;
266
+ if (climbsBetweenRungs(previous, elapsed)) {
267
+ elapsed = confirmed(re, rungInput, { ms: elapsed, matched: false }).ms;
268
+ if (climbsBetweenRungs(previous, elapsed)) return "ratio";
269
+ }
240
270
  previous = elapsed;
241
271
  timings.push(elapsed);
272
+ inputs.push(rungInput);
242
273
  }
243
- if (projectsPastBudget(timings)) return "projection";
274
+ if (projectsPastBudget(timings) && projectsPastBudget(remeasuredForProjection(re, timings, inputs))) return "projection";
244
275
  }
245
276
  if (!falsified && QUANTIFIED_GROUP.test(re.source)) return "unfalsifiable";
246
277
  return null;
@@ -353,6 +384,7 @@ function compileGuardedRegex(pattern, flags = "") {
353
384
  } catch (e) {
354
385
  return { ok: false, reason: e instanceof Error ? e.message : "is not a valid regular expression" };
355
386
  }
387
+ if (!LINEAR_BY_CONSTRUCTION_EXCLUDES.test(pattern)) return { ok: true, re };
356
388
  const cause = growsExponentially(re);
357
389
  if (cause !== null) {
358
390
  return {
@@ -25,11 +25,11 @@ import {
25
25
  extractSwift,
26
26
  extractThrift,
27
27
  extractWgsl
28
- } from "./token-goat-chunk-LHUP4DXZ.mjs";
28
+ } from "./token-goat-chunk-PGTH2U4C.mjs";
29
29
  import {
30
30
  extractShellBannerHeading
31
- } from "./token-goat-chunk-7EPYB34H.mjs";
32
- import "./token-goat-chunk-IKZLSRII.mjs";
31
+ } from "./token-goat-chunk-VMFWNHGR.mjs";
32
+ import "./token-goat-chunk-435UQTKD.mjs";
33
33
  import {
34
34
  GENERIC_CLAUSE,
35
35
  assignBraceBlockSpans,
@@ -59,18 +59,21 @@ import {
59
59
  stripMultilineStringSpan,
60
60
  stripStringLiterals,
61
61
  stripXmlComments
62
- } from "./token-goat-chunk-7SXPJOSZ.mjs";
63
- import "./token-goat-chunk-LRIZ7K3F.mjs";
64
- import "./token-goat-chunk-EEIDFMEM.mjs";
65
- import "./token-goat-chunk-OSUFN2FV.mjs";
62
+ } from "./token-goat-chunk-7CPMDFGB.mjs";
63
+ import "./token-goat-chunk-TGOXNAHW.mjs";
64
+ import "./token-goat-chunk-XB5KKOCG.mjs";
65
+ import "./token-goat-chunk-YZAAZU2S.mjs";
66
+ import "./token-goat-chunk-IVE6U7KV.mjs";
66
67
  import {
67
68
  countContentLines,
68
69
  escapeRegExp,
69
70
  pushAll
70
- } from "./token-goat-chunk-6E2IDLHF.mjs";
71
+ } from "./token-goat-chunk-XYWPOSCN.mjs";
72
+ import "./token-goat-chunk-TCQANXYC.mjs";
71
73
  import "./token-goat-chunk-NMTKNYGF.mjs";
74
+ import "./token-goat-chunk-MELOKFDJ.mjs";
72
75
  import "./token-goat-chunk-Y4AFKTHK.mjs";
73
- import "./token-goat-chunk-GMOUBOX4.mjs";
76
+ import "./token-goat-chunk-JTKCQMQA.mjs";
74
77
  import {
75
78
  init_define_import_meta_env
76
79
  } from "./token-goat-chunk-A37V4PBF.mjs";
@@ -3704,6 +3707,7 @@ function stripLeadingAttributes2(text) {
3704
3707
  var FUNC_RE7 = new RegExp(`^(?:function|filter|workflow|configuration)\\s+(?:(?:global|local|script|private):)?(${FUNC_IDENT})`, "i");
3705
3708
  var CLASS_RE5 = new RegExp(`^(class|enum)\\s+(${IDENT2})`, "i");
3706
3709
  var PESTER_RE = /^(Describe|Context|It)\b(?:\s+-[A-Za-z0-9_-]+(?:\s+(?:'[^']*'|"[^"]*"|[^\s{]+))?)*\s*(?:'([^']*)'|"([^"]*)"|([A-Za-z0-9_.-]+))/i;
3710
+ var PESTER_SETUP_RE = /^(BeforeAll|BeforeEach|AfterAll|AfterEach)\b(?:\s+-[A-Za-z0-9_-]+(?:\s+(?:'[^']*'|"[^"]*"|[^\s{]+))?)*\s*(?:'([^']*)'|"([^"]*)"|([A-Za-z0-9_.-]+))?/i;
3707
3711
  var METHOD_NAME_RE = new RegExp(
3708
3712
  `^(?!(?:if|elseif|else|while|for|foreach|do|switch|return|throw|try|catch|finally|param|begin|process|end)\\b)(${IDENT2})\\s*\\(`,
3709
3713
  "i"
@@ -3773,32 +3777,51 @@ function extractPowershell(content, filePath) {
3773
3777
  if (!stripped) {
3774
3778
  continue;
3775
3779
  }
3776
- if (braceDepth === 0 && currentClass === null) {
3780
+ const isPesterScope = openBlocks.some((b) => b.kind === "test" || b.kind === "context" || b.kind === "setup" || b.kind === "describe");
3781
+ if ((braceDepth === 0 || isPesterScope) && currentClass === null) {
3777
3782
  const funcMatch = FUNC_RE7.exec(stripped);
3778
3783
  if (funcMatch) {
3779
3784
  const fname = funcMatch[1] ?? "";
3780
3785
  if (symbols.length < MAX_SYMBOLS9) {
3781
3786
  const pushIdx = symbols.length;
3782
- symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, line.trimEnd().slice(0, 200), void 0, lines, "hash"));
3787
+ const parentBlock = [...openBlocks].reverse().find((b) => b.kind === "test" || b.kind === "context" || b.kind === "setup" || b.kind === "describe");
3788
+ const parentName = parentBlock !== void 0 ? symbols[parentBlock.symbolIndex]?.name : void 0;
3789
+ symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, line.trimEnd().slice(0, 200), parentName, lines, "hash"));
3783
3790
  openBlocks.push({ symbolIndex: pushIdx, kind: "function", braceDepth, entered: false });
3784
3791
  }
3785
3792
  }
3786
3793
  }
3787
3794
  if (currentClass === null) {
3788
- const pesterTrigger = /^(?:Describe|Context|It)\b/i.exec(stripped);
3795
+ const pesterTrigger = /^(?:Describe|Context|It|BeforeAll|BeforeEach|AfterAll|AfterEach)\b/i.exec(stripped);
3789
3796
  if (pesterTrigger) {
3790
3797
  const rawLine = sourceLine.trimStart();
3791
- const pesterMatch = PESTER_RE.exec(rawLine);
3792
- if (pesterMatch) {
3793
- const blockType = (pesterMatch[1] ?? "").toLowerCase();
3794
- const testName = (pesterMatch[2] ?? pesterMatch[3] ?? pesterMatch[4] ?? "").trim();
3795
- if (testName && symbols.length < MAX_SYMBOLS9) {
3796
- const kind = blockType === "context" ? "context" : "test";
3797
- const parentBlock = [...openBlocks].reverse().find((b) => b.kind === "test" || b.kind === "context");
3798
- const parentName = parentBlock !== void 0 ? symbols[parentBlock.symbolIndex]?.name : void 0;
3799
- const pushIdx = symbols.length;
3800
- symbols.push(makeLineSymbol(filePath, testName, kind, lineNum, sourceLine.trimEnd().slice(0, 200), parentName, lines, "hash"));
3801
- openBlocks.push({ symbolIndex: pushIdx, kind, braceDepth, entered: false });
3798
+ const isSetupBlock = /^(?:BeforeAll|BeforeEach|AfterAll|AfterEach)\b/i.test(stripped);
3799
+ if (isSetupBlock) {
3800
+ const pesterMatch = PESTER_SETUP_RE.exec(rawLine);
3801
+ if (pesterMatch) {
3802
+ const explicitName = (pesterMatch[2] ?? pesterMatch[3] ?? pesterMatch[4] ?? "").trim();
3803
+ const testName = explicitName || (pesterMatch[1] ?? "BeforeAll");
3804
+ if (testName && symbols.length < MAX_SYMBOLS9) {
3805
+ const parentBlock = [...openBlocks].reverse().find((b) => b.kind === "test" || b.kind === "context" || b.kind === "setup" || b.kind === "describe");
3806
+ const parentName = parentBlock !== void 0 ? symbols[parentBlock.symbolIndex]?.name : void 0;
3807
+ const pushIdx = symbols.length;
3808
+ symbols.push(makeLineSymbol(filePath, testName, "setup", lineNum, sourceLine.trimEnd().slice(0, 200), parentName, lines, "hash"));
3809
+ openBlocks.push({ symbolIndex: pushIdx, kind: "setup", braceDepth, entered: false });
3810
+ }
3811
+ }
3812
+ } else {
3813
+ const pesterMatch = PESTER_RE.exec(rawLine);
3814
+ if (pesterMatch) {
3815
+ const blockType = (pesterMatch[1] ?? "").toLowerCase();
3816
+ const testName = (pesterMatch[2] ?? pesterMatch[3] ?? pesterMatch[4] ?? "").trim();
3817
+ if (testName && symbols.length < MAX_SYMBOLS9) {
3818
+ const kind = blockType === "context" ? "context" : "test";
3819
+ const parentBlock = [...openBlocks].reverse().find((b) => b.kind === "test" || b.kind === "context" || b.kind === "setup" || b.kind === "describe");
3820
+ const parentName = parentBlock !== void 0 ? symbols[parentBlock.symbolIndex]?.name : void 0;
3821
+ const pushIdx = symbols.length;
3822
+ symbols.push(makeLineSymbol(filePath, testName, kind, lineNum, sourceLine.trimEnd().slice(0, 200), parentName, lines, "hash"));
3823
+ openBlocks.push({ symbolIndex: pushIdx, kind, braceDepth, entered: false });
3824
+ }
3802
3825
  }
3803
3826
  }
3804
3827
  }
@@ -0,0 +1,35 @@
1
+ import { createRequire as __cjsRequire } from 'node:module';
2
+ const require = __cjsRequire(import.meta.url);
3
+ import {
4
+ detectHarness
5
+ } from "./token-goat-chunk-TGOXNAHW.mjs";
6
+ import {
7
+ init_define_import_meta_env
8
+ } from "./token-goat-chunk-A37V4PBF.mjs";
9
+
10
+ // src/delivery_cap.ts
11
+ init_define_import_meta_env();
12
+ var CLAUDE_CODE_BASH_OUTPUT_CAP_BYTES = 2e4;
13
+ var CLAUDE_CODE_PERSISTED_PREVIEW_BYTES = 2048;
14
+ function bashOutputCapBytes(harness = detectHarness()) {
15
+ return harness === "claudecode" ? CLAUDE_CODE_BASH_OUTPUT_CAP_BYTES : null;
16
+ }
17
+ function clipToDeliveryCap(text, reserveBytes) {
18
+ const cap = bashOutputCapBytes();
19
+ const room = cap === null ? null : cap - reserveBytes;
20
+ if (room === null || room <= 0 || Buffer.byteLength(text, "utf-8") <= room) return { text, clipped: false };
21
+ const sliced = Buffer.from(text, "utf-8").subarray(0, room).toString("utf-8");
22
+ const lastNewline = sliced.lastIndexOf("\n");
23
+ return { text: lastNewline > 0 ? sliced.slice(0, lastNewline) : sliced, clipped: true };
24
+ }
25
+ function deliveredOutputBytes(originalBytes, harness) {
26
+ const cap = bashOutputCapBytes(harness);
27
+ if (cap === null) return Math.max(0, originalBytes);
28
+ if (originalBytes <= cap) return Math.max(0, originalBytes);
29
+ return CLAUDE_CODE_PERSISTED_PREVIEW_BYTES;
30
+ }
31
+
32
+ export {
33
+ clipToDeliveryCap,
34
+ deliveredOutputBytes
35
+ };
@@ -6,14 +6,16 @@ import {
6
6
  pptxOutline,
7
7
  pptxSlideText,
8
8
  pptxTextGrep
9
- } from "./token-goat-chunk-BAWKGODL.mjs";
10
- import "./token-goat-chunk-RIB6XY2V.mjs";
9
+ } from "./token-goat-chunk-HNFZZHFW.mjs";
10
+ import "./token-goat-chunk-UXSXQQIY.mjs";
11
11
  import "./token-goat-chunk-XTQAOTSO.mjs";
12
12
  import "./token-goat-chunk-AH6QILZM.mjs";
13
- import "./token-goat-chunk-6E2IDLHF.mjs";
13
+ import "./token-goat-chunk-XYWPOSCN.mjs";
14
+ import "./token-goat-chunk-TCQANXYC.mjs";
14
15
  import "./token-goat-chunk-NMTKNYGF.mjs";
16
+ import "./token-goat-chunk-MELOKFDJ.mjs";
15
17
  import "./token-goat-chunk-Y4AFKTHK.mjs";
16
- import "./token-goat-chunk-GMOUBOX4.mjs";
18
+ import "./token-goat-chunk-JTKCQMQA.mjs";
17
19
  import "./token-goat-chunk-A37V4PBF.mjs";
18
20
  export {
19
21
  pptxAllSlidesText,