token-goat 2.9.26 → 2.9.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -88
- package/SECURITY.md +14 -0
- package/dist/{token-goat-chunk-CQHY4SL7.mjs → token-goat-chunk-4JJBFT7V.mjs} +3 -3
- package/dist/token-goat-chunk-4JMWPWCS.mjs +96 -0
- package/dist/token-goat-chunk-4RN64ZND.mjs +954 -0
- package/dist/{token-goat-chunk-5M3NRJD2.mjs → token-goat-chunk-4STDIGYC.mjs} +2 -2
- package/dist/{token-goat-chunk-BH4ZVRB2.mjs → token-goat-chunk-5NNYIUGV.mjs} +2 -2
- package/dist/{token-goat-chunk-LHUP4DXZ.mjs → token-goat-chunk-66LODAUT.mjs} +1 -1
- package/dist/{token-goat-chunk-M6CVNHTW.mjs → token-goat-chunk-6CCQDAYY.mjs} +69 -566
- package/dist/{token-goat-chunk-62IHOU6L.mjs → token-goat-chunk-6DQNNFJ6.mjs} +5 -3
- package/dist/{token-goat-chunk-H2CPLEMP.mjs → token-goat-chunk-6SGLIPQB.mjs} +40 -20
- package/dist/{token-goat-chunk-MBDJR6HU.mjs → token-goat-chunk-6Z5ULNE5.mjs} +3570 -3970
- package/dist/token-goat-chunk-7MAFDRVR.mjs +47 -0
- package/dist/{token-goat-chunk-POOI26O6.mjs → token-goat-chunk-7R2XYKC5.mjs} +6 -5
- package/dist/{token-goat-chunk-E6B2UFDF.mjs → token-goat-chunk-BCN2YQC6.mjs} +10 -8
- package/dist/token-goat-chunk-BJBRGPBX.mjs +244 -0
- package/dist/{token-goat-chunk-TG5ZPD6B.mjs → token-goat-chunk-CBMY2FGI.mjs} +479 -544
- package/dist/{token-goat-chunk-LRIZ7K3F.mjs → token-goat-chunk-CC2PYJM7.mjs} +2 -1
- package/dist/{token-goat-chunk-7EPYB34H.mjs → token-goat-chunk-D5ICEPSB.mjs} +14 -14
- package/dist/token-goat-chunk-D7GHQKQD.mjs +30 -0
- package/dist/{token-goat-chunk-JALB3KWJ.mjs → token-goat-chunk-EL7M26WP.mjs} +7623 -8462
- package/dist/{token-goat-chunk-ZZT6PVB3.mjs → token-goat-chunk-F7QZRIWM.mjs} +69 -20
- package/dist/{token-goat-chunk-FLEYOCAS.mjs → token-goat-chunk-FSTWAOW6.mjs} +3 -3
- package/dist/token-goat-chunk-GGLEE35R.mjs +564 -0
- package/dist/{token-goat-chunk-IKZLSRII.mjs → token-goat-chunk-HUDC5GS5.mjs} +2 -2
- package/dist/{token-goat-chunk-43JFN26X.mjs → token-goat-chunk-HXNAC4ZF.mjs} +22 -964
- package/dist/token-goat-chunk-I7CB3X4K.mjs +1379 -0
- package/dist/{token-goat-chunk-GKZ2US5B.mjs → token-goat-chunk-IFORDBGC.mjs} +32 -27
- package/dist/{token-goat-chunk-CXBOFPF4.mjs → token-goat-chunk-IHKZ3QNA.mjs} +26 -15
- package/dist/token-goat-chunk-IZXKVT4A.mjs +711 -0
- package/dist/{token-goat-chunk-PAV6NNY7.mjs → token-goat-chunk-JXK2HQXS.mjs} +22 -8
- package/dist/{token-goat-chunk-6E2IDLHF.mjs → token-goat-chunk-L45ZQRT7.mjs} +1 -1
- package/dist/{token-goat-chunk-MDV5VWF4.mjs → token-goat-chunk-L7SDVGBT.mjs} +196 -14
- package/dist/token-goat-chunk-LEG3JNJ6.mjs +139 -0
- package/dist/{token-goat-chunk-7SXPJOSZ.mjs → token-goat-chunk-M56BWPBN.mjs} +1 -1
- package/dist/{token-goat-chunk-G6EYO5CD.mjs → token-goat-chunk-MAMQPC43.mjs} +2 -87
- package/dist/{token-goat-chunk-VVROQBQJ.mjs → token-goat-chunk-MMLMALWK.mjs} +5 -3
- package/dist/{token-goat-chunk-D2X7XN5M.mjs → token-goat-chunk-MVSWBNMD.mjs} +7 -231
- package/dist/{token-goat-chunk-C2PG4K5D.mjs → token-goat-chunk-NILVK7XM.mjs} +4 -4
- package/dist/{token-goat-chunk-BAWKGODL.mjs → token-goat-chunk-Q4S3UQGO.mjs} +1 -1
- package/dist/{token-goat-chunk-MWID3YOY.mjs → token-goat-chunk-QM76S6YS.mjs} +3 -3
- package/dist/{token-goat-chunk-4GEDH2WU.mjs → token-goat-chunk-RJH64KQH.mjs} +81 -70
- package/dist/{token-goat-chunk-STYRLQIW.mjs → token-goat-chunk-RSS3TLXU.mjs} +2 -2
- package/dist/{token-goat-chunk-5BQ7W7D7.mjs → token-goat-chunk-SJEKA7Y2.mjs} +21 -16
- package/dist/{token-goat-chunk-RIB6XY2V.mjs → token-goat-chunk-UBUKHVYW.mjs} +1 -1
- package/dist/{token-goat-chunk-7Y6GWTII.mjs → token-goat-chunk-VE27HPIF.mjs} +14 -10
- package/dist/{token-goat-chunk-RH27ZSPF.mjs → token-goat-chunk-VWZKZPSR.mjs} +100 -23
- package/dist/{token-goat-chunk-L45IWWMC.mjs → token-goat-chunk-XI2VFAV6.mjs} +6 -6
- package/dist/{token-goat-chunk-WNBSCSAI.mjs → token-goat-chunk-XKY4VKJ4.mjs} +1 -1
- package/dist/{token-goat-chunk-L43RKNHA.mjs → token-goat-chunk-YWSP6IU7.mjs} +1 -1
- package/dist/token-goat-hook.mjs +23 -17
- package/dist/token-goat.core.mjs +32 -27
- package/docs/cli.md +32 -21
- package/docs/install.md +2 -0
- package/package.json +1 -1
- package/dist/token-goat-chunk-ADMR3QVF.mjs +0 -41
- package/dist/token-goat-chunk-MZTO4FXH.mjs +0 -26
|
@@ -5,26 +5,30 @@ import {
|
|
|
5
5
|
blobPath,
|
|
6
6
|
isBlobStale,
|
|
7
7
|
loadBlob,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
storeBlob
|
|
9
|
+
} from "./token-goat-chunk-BJBRGPBX.mjs";
|
|
10
|
+
import {
|
|
11
|
+
hasUnquotedOperator
|
|
12
|
+
} from "./token-goat-chunk-4RN64ZND.mjs";
|
|
13
|
+
import {
|
|
14
|
+
redactSecrets
|
|
15
|
+
} from "./token-goat-chunk-MVSWBNMD.mjs";
|
|
12
16
|
import {
|
|
13
17
|
sanitizeFtsQuery
|
|
14
|
-
} from "./token-goat-chunk-
|
|
18
|
+
} from "./token-goat-chunk-HUDC5GS5.mjs";
|
|
15
19
|
import {
|
|
16
20
|
getDb
|
|
17
|
-
} from "./token-goat-chunk-
|
|
21
|
+
} from "./token-goat-chunk-M56BWPBN.mjs";
|
|
18
22
|
import {
|
|
19
23
|
shortFingerprint
|
|
20
|
-
} from "./token-goat-chunk-
|
|
24
|
+
} from "./token-goat-chunk-CC2PYJM7.mjs";
|
|
21
25
|
import {
|
|
22
26
|
registerReset
|
|
23
27
|
} from "./token-goat-chunk-EEIDFMEM.mjs";
|
|
24
28
|
import {
|
|
25
29
|
globalDbPath,
|
|
26
30
|
runGit
|
|
27
|
-
} from "./token-goat-chunk-
|
|
31
|
+
} from "./token-goat-chunk-L45ZQRT7.mjs";
|
|
28
32
|
import {
|
|
29
33
|
normalizePath
|
|
30
34
|
} from "./token-goat-chunk-NMTKNYGF.mjs";
|
|
@@ -32,909 +36,9 @@ import {
|
|
|
32
36
|
init_define_import_meta_env
|
|
33
37
|
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
34
38
|
|
|
35
|
-
// src/tool_filters/helpers.ts
|
|
36
|
-
init_define_import_meta_env();
|
|
37
|
-
import * as fs from "node:fs";
|
|
38
|
-
import * as path from "node:path";
|
|
39
|
-
var DEFAULT_MAX_LINES = 1e3;
|
|
40
|
-
var DEFAULT_MAX_BYTES = 64 * 1024;
|
|
41
|
-
var MAX_INSPECT_BYTES = 2 * 1024 * 1024;
|
|
42
|
-
var DEFAULT_MAX_INPUT_BYTES = 500 * 1024;
|
|
43
|
-
var FALLBACK_MAX_LINE_CHARS = 400;
|
|
44
|
-
var LONG_LINE_MAX_CHARS = 1e3;
|
|
45
|
-
var ELIDED_MARKER_RE = /… \[\d+ chars elided\]/;
|
|
46
|
-
var CLIPPED_MARKER_RE = / \.\.\. \[(\d+) chars clipped\] \.\.\. /;
|
|
47
|
-
function getMaxInputBytes() {
|
|
48
|
-
const raw = process.env["TOKEN_GOAT_FILTER_MAX_BYTES"];
|
|
49
|
-
const v = raw ? Number.parseInt(raw, 10) : 0;
|
|
50
|
-
return Number.isFinite(v) && v > 0 ? v : DEFAULT_MAX_INPUT_BYTES;
|
|
51
|
-
}
|
|
52
|
-
function utf8SafeEnd(buf, n) {
|
|
53
|
-
if (n >= buf.length) return buf.length;
|
|
54
|
-
let end = n;
|
|
55
|
-
while (end > 0 && (buf[end] & 192) === 128) end--;
|
|
56
|
-
return end;
|
|
57
|
-
}
|
|
58
|
-
var INPUT_MAX_LINE_CHARS = 4e3;
|
|
59
|
-
function clipWideLines(text, maxChars = INPUT_MAX_LINE_CHARS) {
|
|
60
|
-
if (text.length <= maxChars) return text;
|
|
61
|
-
let clipped = 0;
|
|
62
|
-
const out = text.split("\n").map((line) => {
|
|
63
|
-
if (line.length <= maxChars) return line;
|
|
64
|
-
clipped += 1;
|
|
65
|
-
const keep = Math.floor(maxChars / 2);
|
|
66
|
-
return line.slice(0, keep) + ` ... [${line.length - maxChars} chars clipped] ... ` + line.slice(line.length - (maxChars - keep));
|
|
67
|
-
});
|
|
68
|
-
return clipped === 0 ? text : out.join("\n");
|
|
69
|
-
}
|
|
70
|
-
function clampKeepingEnds(text, maxBytes) {
|
|
71
|
-
const buf = Buffer.from(text, "utf8");
|
|
72
|
-
if (buf.length <= maxBytes) return null;
|
|
73
|
-
const lines = text.split("\n");
|
|
74
|
-
const budget = maxBytes - Buffer.byteLength(`... [${lines.length} more lines elided by token-goat]
|
|
75
|
-
`, "utf8");
|
|
76
|
-
const half = Math.floor(budget / 2);
|
|
77
|
-
let headEnd = 0;
|
|
78
|
-
for (let used = 0; headEnd < lines.length; headEnd++) {
|
|
79
|
-
const n = Buffer.byteLength(lines[headEnd], "utf8") + 1;
|
|
80
|
-
if (used + n > half) break;
|
|
81
|
-
used += n;
|
|
82
|
-
}
|
|
83
|
-
let tailStart = lines.length;
|
|
84
|
-
for (let used = 0; tailStart > headEnd; tailStart--) {
|
|
85
|
-
const n = Buffer.byteLength(lines[tailStart - 1], "utf8") + 1;
|
|
86
|
-
if (used + n > half) break;
|
|
87
|
-
used += n;
|
|
88
|
-
}
|
|
89
|
-
if (headEnd === 0 && tailStart === lines.length) return buf.subarray(0, utf8SafeEnd(buf, maxBytes)).toString("utf8");
|
|
90
|
-
const elided = tailStart - headEnd;
|
|
91
|
-
return [
|
|
92
|
-
...lines.slice(0, headEnd),
|
|
93
|
-
`... [${elided} more line${elided === 1 ? "" : "s"} elided by token-goat]`,
|
|
94
|
-
...lines.slice(tailStart)
|
|
95
|
-
].join("\n");
|
|
96
|
-
}
|
|
97
|
-
function compressionMarker(filter, pct) {
|
|
98
|
-
return `
|
|
99
|
-
[token-goat: ${filter} filter -${Math.round(pct)}%; disable via TOKEN_GOAT_BASH_COMPRESS]`;
|
|
100
|
-
}
|
|
101
|
-
function combineStreams(stdout, stderr) {
|
|
102
|
-
if (stderr.trim() && stdout.trim()) return `${stdout.replace(/\s+$/, "")}
|
|
103
|
-
---
|
|
104
|
-
${stderr.replace(/\s+$/, "")}`;
|
|
105
|
-
return stdout.trim() ? stdout.replace(/\s+$/, "") : stderr.replace(/\s+$/, "");
|
|
106
|
-
}
|
|
107
|
-
var ERROR_SIGNAL_RE = /error:|Error:|ERROR|FAILED|failed|fatal:|Traceback|exception:|Exception:|AssertionError|assert |panic:/i;
|
|
108
|
-
var TABLE_ROW_ANOMALY_RE = /\b(?:CrashLoopBackOff|ImagePullBackOff|ErrImagePull|CreateContainerError|CreateContainerConfigError|InvalidImageName|RunContainerError|OOMKilled|Evicted|Terminating|ContainerCreating|PodInitializing|NotReady|SchedulingDisabled|Unschedulable|Pending|Failed|Error|Unknown|Unhealthy|DEGRADED|UNAVAILABLE|STOPPED|STOPPING|TERMINATED|TERMINATING|FAILED|ROLLBACK_COMPLETE|ROLLBACK_FAILED|CREATE_FAILED|UPDATE_FAILED|DELETE_FAILED|pending-install|pending-upgrade|pending-rollback|uninstalling)\b|(?<![\w-])(?:failed|unknown)(?![\w-])/;
|
|
109
|
-
var TIMESTAMP_PREFIX_RE = /^\[?\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:\.\d+)?Z?\]?\s*|^\d{2}:\d{2}:\d{2}(?:\.\d+)?\s+/;
|
|
110
|
-
var REDIRECT_TOKEN_RE = /^(\d*)(>>?|<<?).*$|^&>$|^>&.*$/;
|
|
111
|
-
function maskQuotedSpans(cmd) {
|
|
112
|
-
let out = "";
|
|
113
|
-
let i = 0;
|
|
114
|
-
const n = cmd.length;
|
|
115
|
-
while (i < n) {
|
|
116
|
-
const ch = cmd[i];
|
|
117
|
-
if (ch === "\\") {
|
|
118
|
-
out += i + 1 < n ? "xx" : "x";
|
|
119
|
-
i += 2;
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
if (ch === "'") {
|
|
123
|
-
i += 1;
|
|
124
|
-
const end = cmd.indexOf("'", i);
|
|
125
|
-
const stop = end === -1 ? n : end;
|
|
126
|
-
out += "x".repeat(stop - i);
|
|
127
|
-
i = end === -1 ? n : end + 1;
|
|
128
|
-
continue;
|
|
129
|
-
}
|
|
130
|
-
if (ch === '"') {
|
|
131
|
-
i += 1;
|
|
132
|
-
const start = i;
|
|
133
|
-
while (i < n && cmd[i] !== '"') {
|
|
134
|
-
i += cmd[i] === "\\" && i + 1 < n ? 2 : 1;
|
|
135
|
-
}
|
|
136
|
-
out += "x".repeat(i - start);
|
|
137
|
-
if (i < n) i += 1;
|
|
138
|
-
continue;
|
|
139
|
-
}
|
|
140
|
-
out += ch;
|
|
141
|
-
i += 1;
|
|
142
|
-
}
|
|
143
|
-
return out;
|
|
144
|
-
}
|
|
145
|
-
function hasBareBackgroundOrNewline(cmd) {
|
|
146
|
-
if (cmd.includes("\n") || cmd.includes("\r")) return true;
|
|
147
|
-
const masked = maskQuotedSpans(cmd);
|
|
148
|
-
for (let i = 0; i < masked.length; i++) {
|
|
149
|
-
if (masked[i] !== "&") continue;
|
|
150
|
-
if (masked[i + 1] === "&") {
|
|
151
|
-
i++;
|
|
152
|
-
continue;
|
|
153
|
-
}
|
|
154
|
-
if (masked[i - 1] === "&") continue;
|
|
155
|
-
if (isRedirectAmpersand(masked, i)) continue;
|
|
156
|
-
return true;
|
|
157
|
-
}
|
|
158
|
-
return false;
|
|
159
|
-
}
|
|
160
|
-
function isRedirectAmpersand(cmd, index) {
|
|
161
|
-
const before = cmd[index - 1];
|
|
162
|
-
return before === "<" || before === ">" || cmd[index + 1] === ">";
|
|
163
|
-
}
|
|
164
|
-
function hasUnquotedOperator(cmd, ops) {
|
|
165
|
-
const masked = maskQuotedSpans(cmd);
|
|
166
|
-
return ops.some((op) => masked.includes(op));
|
|
167
|
-
}
|
|
168
|
-
var BYTES_ELIDED_MARKER_RE = /\n\.\.\. \[\d+ bytes elided by token-goat\]$/;
|
|
169
|
-
var OWN_TRAILING_NOTICE_RE = /(?:\n(?:\[token-goat: output capped at ~\d+ tokens\]|\.\.\. \[\d+ bytes elided by token-goat\]))+$/;
|
|
170
|
-
function splitOwnTrailingNotices(text) {
|
|
171
|
-
const m = OWN_TRAILING_NOTICE_RE.exec(text);
|
|
172
|
-
return m ? { body: text.slice(0, m.index), notices: m[0] } : { body: text, notices: "" };
|
|
173
|
-
}
|
|
174
|
-
var DIGITS_RE = /\d+/g;
|
|
175
|
-
var CONTROL_CHAR_RE = /[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x9f]/g;
|
|
176
|
-
function utf8Len(s) {
|
|
177
|
-
return Buffer.byteLength(s, "utf8");
|
|
178
|
-
}
|
|
179
|
-
function safeDecode(text) {
|
|
180
|
-
return text.indexOf("\0") === -1 ? text : text.split("\0").join("");
|
|
181
|
-
}
|
|
182
|
-
function sanitizeControlChars(text) {
|
|
183
|
-
return text.replace(CONTROL_CHAR_RE, "");
|
|
184
|
-
}
|
|
185
|
-
function stripProgress(text) {
|
|
186
|
-
if (!text.includes("\r")) return text;
|
|
187
|
-
return text.split("\n").map((line) => {
|
|
188
|
-
const trimmed = line.endsWith("\r") ? line.slice(0, -1) : line;
|
|
189
|
-
return trimmed.includes("\r") ? trimmed.slice(trimmed.lastIndexOf("\r") + 1) : trimmed;
|
|
190
|
-
}).join("\n");
|
|
191
|
-
}
|
|
192
|
-
function normalise(text, opts = {}) {
|
|
193
|
-
if (!text) return "";
|
|
194
|
-
let t = text.replace(/\r\n/g, "\n");
|
|
195
|
-
if (!opts.skipProgress) t = stripProgress(t);
|
|
196
|
-
t = stripAnsiEscapes(t);
|
|
197
|
-
return sanitizeControlChars(t);
|
|
198
|
-
}
|
|
199
|
-
var UUID_RE = /\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/i;
|
|
200
|
-
var LONG_HEX_RE = /\b[0-9a-f]{32,}\b/i;
|
|
201
|
-
var JWT_RE = /\b[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/;
|
|
202
|
-
function hasHighEntropyToken(line) {
|
|
203
|
-
if (UUID_RE.test(line) || LONG_HEX_RE.test(line) || JWT_RE.test(line)) return true;
|
|
204
|
-
for (const tok of line.split(/[\s"'`,;:()[\]{}<>]+/)) {
|
|
205
|
-
if (tok.length < 24) continue;
|
|
206
|
-
if (/[a-z]/.test(tok) && /[A-Z]/.test(tok) && /[0-9]/.test(tok) && /^[A-Za-z0-9+/=_-]+$/.test(tok)) {
|
|
207
|
-
return true;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
return false;
|
|
211
|
-
}
|
|
212
|
-
function dedupeConsecutive(lines, opts = {}) {
|
|
213
|
-
const minRun = opts.minRun ?? 2;
|
|
214
|
-
const fmt = opts.fmt ?? ((line, count2) => `${line} (\xD7${count2})`);
|
|
215
|
-
const entropyBypass = opts.entropyBypass ?? false;
|
|
216
|
-
const out = [];
|
|
217
|
-
let prev = null;
|
|
218
|
-
let count = 0;
|
|
219
|
-
const flush = () => {
|
|
220
|
-
if (prev === null) return;
|
|
221
|
-
if (count >= minRun) out.push(fmt(prev, count));
|
|
222
|
-
else for (let i = 0; i < count; i++) out.push(prev);
|
|
223
|
-
};
|
|
224
|
-
for (const line of lines) {
|
|
225
|
-
if (entropyBypass && hasHighEntropyToken(line)) {
|
|
226
|
-
flush();
|
|
227
|
-
prev = null;
|
|
228
|
-
count = 0;
|
|
229
|
-
out.push(line);
|
|
230
|
-
continue;
|
|
231
|
-
}
|
|
232
|
-
if (line === prev) {
|
|
233
|
-
count += 1;
|
|
234
|
-
continue;
|
|
235
|
-
}
|
|
236
|
-
flush();
|
|
237
|
-
prev = line;
|
|
238
|
-
count = 1;
|
|
239
|
-
}
|
|
240
|
-
flush();
|
|
241
|
-
return out;
|
|
242
|
-
}
|
|
243
|
-
function dedupeNumericRuns(lines, opts = {}) {
|
|
244
|
-
const minRun = opts.minRun ?? 2;
|
|
245
|
-
const arr = Array.from(lines);
|
|
246
|
-
const out = [];
|
|
247
|
-
let i = 0;
|
|
248
|
-
while (i < arr.length) {
|
|
249
|
-
const key = arr[i].replace(DIGITS_RE, "#");
|
|
250
|
-
let j = i + 1;
|
|
251
|
-
while (j < arr.length && arr[j].replace(DIGITS_RE, "#") === key) j += 1;
|
|
252
|
-
const run = j - i;
|
|
253
|
-
if (run >= minRun) {
|
|
254
|
-
out.push(arr[i]);
|
|
255
|
-
out.push(`... [${run - 1} similar lines collapsed by token-goat]`);
|
|
256
|
-
} else {
|
|
257
|
-
for (let k = i; k < j; k++) out.push(arr[k]);
|
|
258
|
-
}
|
|
259
|
-
i = j;
|
|
260
|
-
}
|
|
261
|
-
return out;
|
|
262
|
-
}
|
|
263
|
-
function truncateMiddle(lines, maxLines, opts = {}) {
|
|
264
|
-
if (lines.length <= maxLines) return lines;
|
|
265
|
-
const headRatio = opts.headRatio ?? 0.4;
|
|
266
|
-
const markerFmt = opts.markerFmt ?? ((n) => `... [${n} lines elided by token-goat]`);
|
|
267
|
-
const headKeep = Math.max(1, Math.floor(maxLines * headRatio));
|
|
268
|
-
const tailKeep = Math.max(1, maxLines - headKeep);
|
|
269
|
-
const elided = lines.length - headKeep - tailKeep;
|
|
270
|
-
return [...lines.slice(0, headKeep), markerFmt(elided), ...lines.slice(lines.length - tailKeep)];
|
|
271
|
-
}
|
|
272
|
-
function truncateMiddleSmart(lines, maxLines, opts = {}) {
|
|
273
|
-
if (lines.length <= maxLines) return lines;
|
|
274
|
-
const headKeep = opts.headKeep ?? 10;
|
|
275
|
-
const tailKeep = opts.tailKeep ?? 10;
|
|
276
|
-
const errorContext = opts.errorContext ?? 2;
|
|
277
|
-
const maxErrorLines = opts.maxErrorLines ?? 10;
|
|
278
|
-
const markerFmt = opts.markerFmt ?? ((n) => `--- ${n} lines omitted ---`);
|
|
279
|
-
const errorIndices = [];
|
|
280
|
-
for (let i = 0; i < lines.length; i++) if (ERROR_SIGNAL_RE.test(lines[i])) errorIndices.push(i);
|
|
281
|
-
if (errorIndices.length === 0) return truncateMiddle(lines, maxLines, { markerFmt });
|
|
282
|
-
const total = lines.length;
|
|
283
|
-
const effHead = Math.min(headKeep, Math.floor(total / 4));
|
|
284
|
-
const effTail = Math.min(tailKeep, Math.floor(total / 4));
|
|
285
|
-
const chosenErrors = errorIndices.length <= maxErrorLines ? errorIndices : [
|
|
286
|
-
...errorIndices.slice(0, Math.ceil(maxErrorLines / 2)),
|
|
287
|
-
...errorIndices.slice(errorIndices.length - Math.floor(maxErrorLines / 2))
|
|
288
|
-
];
|
|
289
|
-
const budgetForMiddle = Math.max(0, maxLines - effHead - effTail);
|
|
290
|
-
const half = Math.ceil(chosenErrors.length / 2);
|
|
291
|
-
const front = chosenErrors.slice(0, half);
|
|
292
|
-
const back = chosenErrors.slice(half).reverse();
|
|
293
|
-
const visitOrder = [];
|
|
294
|
-
for (let k = 0; k < Math.max(front.length, back.length); k++) {
|
|
295
|
-
if (k < front.length) visitOrder.push(front[k]);
|
|
296
|
-
if (k < back.length) visitOrder.push(back[k]);
|
|
297
|
-
}
|
|
298
|
-
const middle = /* @__PURE__ */ new Set();
|
|
299
|
-
outer: for (const ei of visitOrder) {
|
|
300
|
-
for (let ci = Math.max(0, ei - errorContext); ci < Math.min(total, ei + errorContext + 1); ci++) {
|
|
301
|
-
if (ci < effHead || ci >= total - effTail) continue;
|
|
302
|
-
if (middle.size >= budgetForMiddle) break outer;
|
|
303
|
-
middle.add(ci);
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
const sortedMiddle = Array.from(middle).sort((a, b) => a - b);
|
|
307
|
-
const result = [];
|
|
308
|
-
const appendSection = (indices) => {
|
|
309
|
-
for (let pos = 0; pos < indices.length; pos++) {
|
|
310
|
-
const idx = indices[pos];
|
|
311
|
-
if (pos > 0) {
|
|
312
|
-
const prevIdx = indices[pos - 1];
|
|
313
|
-
if (idx !== prevIdx + 1) result.push(markerFmt(idx - prevIdx - 1));
|
|
314
|
-
}
|
|
315
|
-
result.push(lines[idx]);
|
|
316
|
-
}
|
|
317
|
-
};
|
|
318
|
-
const headList = Array.from({ length: effHead }, (_, i) => i);
|
|
319
|
-
const tailList = Array.from({ length: effTail }, (_, i) => total - effTail + i);
|
|
320
|
-
appendSection(headList);
|
|
321
|
-
if (sortedMiddle.length) {
|
|
322
|
-
const gapAfterHead = sortedMiddle[0] - (headList.length ? headList[headList.length - 1] : -1) - 1;
|
|
323
|
-
if (gapAfterHead > 0) result.push(markerFmt(gapAfterHead));
|
|
324
|
-
appendSection(sortedMiddle);
|
|
325
|
-
}
|
|
326
|
-
if (tailList.length) {
|
|
327
|
-
const lastKept = sortedMiddle.length ? sortedMiddle[sortedMiddle.length - 1] : headList.length ? headList[headList.length - 1] : -1;
|
|
328
|
-
const gapBeforeTail = tailList[0] - lastKept - 1;
|
|
329
|
-
if (gapBeforeTail > 0) result.push(markerFmt(gapBeforeTail));
|
|
330
|
-
appendSection(tailList);
|
|
331
|
-
}
|
|
332
|
-
return result;
|
|
333
|
-
}
|
|
334
|
-
function capBytes(text, maxBytes) {
|
|
335
|
-
const encoded = Buffer.from(text, "utf8");
|
|
336
|
-
if (encoded.length <= maxBytes) return text;
|
|
337
|
-
const widestMarker = `
|
|
338
|
-
... [${encoded.length} bytes elided by token-goat]`;
|
|
339
|
-
const budget = maxBytes - Buffer.byteLength(widestMarker, "utf8");
|
|
340
|
-
if (budget <= 0) return widestMarker.trim();
|
|
341
|
-
const kept = clampKeepingEnds(text, budget) ?? text;
|
|
342
|
-
return `${kept}
|
|
343
|
-
... [${encoded.length - Buffer.byteLength(kept, "utf8")} bytes elided by token-goat]`;
|
|
344
|
-
}
|
|
345
|
-
function capTokens(text, maxTokens) {
|
|
346
|
-
const clean = stripAnsiEscapes(text);
|
|
347
|
-
if (clean.length / 3.5 <= maxTokens) return text;
|
|
348
|
-
const maxBytes = Math.floor(maxTokens * 3.5);
|
|
349
|
-
let truncated = clampKeepingEnds(clean, maxBytes) ?? clean;
|
|
350
|
-
if (!truncated.includes("[token-goat: output capped at")) {
|
|
351
|
-
truncated = truncated.replace(BYTES_ELIDED_MARKER_RE, "");
|
|
352
|
-
truncated += `
|
|
353
|
-
[token-goat: output capped at ~${maxTokens} tokens]`;
|
|
354
|
-
}
|
|
355
|
-
return truncated;
|
|
356
|
-
}
|
|
357
|
-
function headTailCompress(lines, head, tail, label = "items") {
|
|
358
|
-
const total = lines.length;
|
|
359
|
-
if (total <= head + tail) return lines.join("\n");
|
|
360
|
-
const elided = total - head - tail;
|
|
361
|
-
return [...lines.slice(0, head), `... [${elided} more ${label} elided by token-goat]`, ...lines.slice(total - tail)].join(
|
|
362
|
-
"\n"
|
|
363
|
-
);
|
|
364
|
-
}
|
|
365
|
-
function truncateTableRows(text, maxRows, hint) {
|
|
366
|
-
const lines = text.split("\n");
|
|
367
|
-
const nonEmpty = lines.filter((l) => l.trim());
|
|
368
|
-
if (nonEmpty.length <= maxRows + 1) return text;
|
|
369
|
-
const header = nonEmpty[0];
|
|
370
|
-
const rows = nonEmpty.slice(1);
|
|
371
|
-
const wanted = /* @__PURE__ */ new Set();
|
|
372
|
-
for (let i = 0; i < rows.length && wanted.size < maxRows; i++) {
|
|
373
|
-
if (TABLE_ROW_ANOMALY_RE.test(rows[i])) wanted.add(i);
|
|
374
|
-
}
|
|
375
|
-
const anomalies = wanted.size;
|
|
376
|
-
for (let i = 0; i < rows.length && wanted.size < maxRows; i++) wanted.add(i);
|
|
377
|
-
const kept = [...wanted].sort((a, b) => a - b);
|
|
378
|
-
const elided = rows.length - kept.length;
|
|
379
|
-
const note = anomalies ? `[token-goat: ${elided} more rows; ${anomalies} row(s) kept for a not-ready status, the rest from the top; ${hint}]` : `[token-goat: ${elided} more rows; ${hint}]`;
|
|
380
|
-
return `${[header, ...kept.map((i) => rows[i])].join("\n")}
|
|
381
|
-
${note}`;
|
|
382
|
-
}
|
|
383
|
-
function trimRepeatedPrefix(lines, pattern, keep) {
|
|
384
|
-
const out = [];
|
|
385
|
-
let matched = 0;
|
|
386
|
-
let dropped = 0;
|
|
387
|
-
for (const line of lines) {
|
|
388
|
-
if (pattern.test(line)) {
|
|
389
|
-
matched += 1;
|
|
390
|
-
if (matched <= keep) out.push(line);
|
|
391
|
-
else dropped += 1;
|
|
392
|
-
} else {
|
|
393
|
-
out.push(line);
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
if (dropped) out.push(`[token-goat: +${dropped} more lines matching ${pattern.source}]`);
|
|
397
|
-
return out;
|
|
398
|
-
}
|
|
399
|
-
function stripTimestamps(lines) {
|
|
400
|
-
return lines.map((ln) => ln.replace(TIMESTAMP_PREFIX_RE, ""));
|
|
401
|
-
}
|
|
402
|
-
function splitBlocks(text, blockRe) {
|
|
403
|
-
const blocks = [];
|
|
404
|
-
let current = [];
|
|
405
|
-
for (const line of text.split("\n")) {
|
|
406
|
-
if (blockRe.test(line)) {
|
|
407
|
-
if (current.length) blocks.push(current.join("\n"));
|
|
408
|
-
current = [line];
|
|
409
|
-
} else {
|
|
410
|
-
current.push(line);
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
if (current.length) blocks.push(current.join("\n"));
|
|
414
|
-
return blocks;
|
|
415
|
-
}
|
|
416
|
-
function maybeNote(notes, value, msg) {
|
|
417
|
-
if (value) notes.push(msg);
|
|
418
|
-
}
|
|
419
|
-
function squeezeBlankLines(text) {
|
|
420
|
-
return text.replace(/\n\s*\n\s*\n+/g, "\n\n");
|
|
421
|
-
}
|
|
422
|
-
function preserveStderrOnError(stdout, stderr, exitCode) {
|
|
423
|
-
if (exitCode !== 0 && stderr.trim()) {
|
|
424
|
-
return stdout.trim() ? `${stdout.replace(/\s+$/, "")}
|
|
425
|
-
---
|
|
426
|
-
${stderr.replace(/\s+$/, "")}` : stderr;
|
|
427
|
-
}
|
|
428
|
-
return null;
|
|
429
|
-
}
|
|
430
|
-
var PASSTHROUGH_PREFIXES = /* @__PURE__ */ new Set([
|
|
431
|
-
"sudo",
|
|
432
|
-
"doas",
|
|
433
|
-
"time",
|
|
434
|
-
"nice",
|
|
435
|
-
"ionice",
|
|
436
|
-
"nohup",
|
|
437
|
-
"exec",
|
|
438
|
-
"env",
|
|
439
|
-
"stdbuf",
|
|
440
|
-
"unbuffer",
|
|
441
|
-
"script"
|
|
442
|
-
]);
|
|
443
|
-
var TWO_TOKEN_PREFIXES = {
|
|
444
|
-
python: /* @__PURE__ */ new Set(["-m"]),
|
|
445
|
-
python3: /* @__PURE__ */ new Set(["-m"]),
|
|
446
|
-
py: /* @__PURE__ */ new Set(["-m"]),
|
|
447
|
-
// `tool` is deliberately absent: `uv tool install/upgrade/uninstall/update <bin>`
|
|
448
|
-
// produces uv's own package-management output (handled by UvFilter.matches()'s
|
|
449
|
-
// own `tool` branch on the unstripped argv) -- it must not be consumed here.
|
|
450
|
-
// `uv tool run <bin>` is the one `tool` subcommand that really does execute
|
|
451
|
-
// `<bin>` and stream its output; it gets a dedicated 3-token strip below.
|
|
452
|
-
uv: /* @__PURE__ */ new Set(["run"]),
|
|
453
|
-
uvx: /* @__PURE__ */ new Set(),
|
|
454
|
-
poetry: /* @__PURE__ */ new Set(["run"]),
|
|
455
|
-
rye: /* @__PURE__ */ new Set(["run"]),
|
|
456
|
-
pdm: /* @__PURE__ */ new Set(["run"]),
|
|
457
|
-
pipenv: /* @__PURE__ */ new Set(["run"]),
|
|
458
|
-
npx: /* @__PURE__ */ new Set(),
|
|
459
|
-
pnpm: /* @__PURE__ */ new Set(["exec", "dlx"]),
|
|
460
|
-
yarn: /* @__PURE__ */ new Set(["exec", "dlx"]),
|
|
461
|
-
bundle: /* @__PURE__ */ new Set(["exec"]),
|
|
462
|
-
hatch: /* @__PURE__ */ new Set(["run"])
|
|
463
|
-
// `tox` is deliberately absent: `tox -e py312`'s `-e py312` is an environment
|
|
464
|
-
// selector, not a launcher token, so argv[2] (`py312`) is never a real binary.
|
|
465
|
-
// ToxFilter matches on the unstripped `tox` stem directly (see misc.ts).
|
|
466
|
-
};
|
|
467
|
-
function pathName(p) {
|
|
468
|
-
const norm = p.replace(/\\/g, "/");
|
|
469
|
-
const idx = norm.lastIndexOf("/");
|
|
470
|
-
return idx >= 0 ? norm.slice(idx + 1) : norm;
|
|
471
|
-
}
|
|
472
|
-
function pathStem(p) {
|
|
473
|
-
const name = pathName(p);
|
|
474
|
-
const dot = name.lastIndexOf(".");
|
|
475
|
-
return dot > 0 ? name.slice(0, dot) : name;
|
|
476
|
-
}
|
|
477
|
-
function positionalArgs(args, valueFlags) {
|
|
478
|
-
const out = [];
|
|
479
|
-
for (let i = 0; i < args.length; i++) {
|
|
480
|
-
const a = args[i];
|
|
481
|
-
if (a.startsWith("-")) {
|
|
482
|
-
if (valueFlags?.has(a) === true && i + 1 < args.length) i++;
|
|
483
|
-
continue;
|
|
484
|
-
}
|
|
485
|
-
out.push(a);
|
|
486
|
-
}
|
|
487
|
-
return out;
|
|
488
|
-
}
|
|
489
|
-
var SHORT_FLAGS_WITH_VALUE = /* @__PURE__ */ new Set(["-n", "-c", "-u", "-e"]);
|
|
490
|
-
function stripPrefixes(argv) {
|
|
491
|
-
if (argv.length === 0) return [];
|
|
492
|
-
let out = [...argv];
|
|
493
|
-
for (; ; ) {
|
|
494
|
-
const before = out.length;
|
|
495
|
-
while (out.length && out[0].includes("=") && !out[0].startsWith("-")) {
|
|
496
|
-
const head = out[0].split("=", 1)[0];
|
|
497
|
-
if (head && (/[A-Za-z]/.test(head[0]) || head[0] === "_") && /^[A-Za-z0-9_]+$/.test(head)) out.shift();
|
|
498
|
-
else break;
|
|
499
|
-
}
|
|
500
|
-
while (out.length) {
|
|
501
|
-
if (!PASSTHROUGH_PREFIXES.has(pathStem(out[0]).toLowerCase())) break;
|
|
502
|
-
out.shift();
|
|
503
|
-
while (out.length && out[0].startsWith("-")) {
|
|
504
|
-
const flag = out.shift();
|
|
505
|
-
if (SHORT_FLAGS_WITH_VALUE.has(flag) && out.length) out.shift();
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
if (out.length === before) break;
|
|
509
|
-
}
|
|
510
|
-
if (out.length === 0) return out;
|
|
511
|
-
if (pathStem(out[0]).toLowerCase() === "uv" && out[1] === "tool" && out[2] === "run" && out.length > 3) {
|
|
512
|
-
return skipLauncherOptions(out.slice(3));
|
|
513
|
-
}
|
|
514
|
-
const stem = pathStem(out[0]).toLowerCase();
|
|
515
|
-
const triggers = TWO_TOKEN_PREFIXES[stem];
|
|
516
|
-
if (triggers !== void 0 && out.length >= 2) {
|
|
517
|
-
const nextTok = out[1];
|
|
518
|
-
if (triggers.size === 0 || triggers.has(nextTok)) {
|
|
519
|
-
const consume = triggers.size === 0 ? 1 : 2;
|
|
520
|
-
if (out.length > consume) out = skipLauncherOptions(out.slice(consume));
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
return out;
|
|
524
|
-
}
|
|
525
|
-
var LAUNCHER_VALUE_FLAGS = /* @__PURE__ */ new Set([
|
|
526
|
-
"-p",
|
|
527
|
-
"--package",
|
|
528
|
-
"-c",
|
|
529
|
-
"--call",
|
|
530
|
-
"--userconfig",
|
|
531
|
-
"--cache",
|
|
532
|
-
"--shell",
|
|
533
|
-
"--node-arg",
|
|
534
|
-
"--npm",
|
|
535
|
-
"--with",
|
|
536
|
-
"--with-requirements",
|
|
537
|
-
"--with-editable",
|
|
538
|
-
"--python",
|
|
539
|
-
"--directory",
|
|
540
|
-
"--project",
|
|
541
|
-
"--extra",
|
|
542
|
-
"--group",
|
|
543
|
-
"--index-url",
|
|
544
|
-
"--index",
|
|
545
|
-
"--find-links",
|
|
546
|
-
"--constraint",
|
|
547
|
-
"--override",
|
|
548
|
-
"--filter",
|
|
549
|
-
"--dir",
|
|
550
|
-
"--workspace-root",
|
|
551
|
-
"--shell-mode"
|
|
552
|
-
]);
|
|
553
|
-
function skipLauncherOptions(args) {
|
|
554
|
-
let i = 0;
|
|
555
|
-
while (i < args.length && args[i].startsWith("-") && args[i] !== "--") {
|
|
556
|
-
const flag = args[i];
|
|
557
|
-
i++;
|
|
558
|
-
if (LAUNCHER_VALUE_FLAGS.has(flag) && i < args.length) i++;
|
|
559
|
-
}
|
|
560
|
-
if (i < args.length && args[i] === "--") i++;
|
|
561
|
-
return i < args.length ? args.slice(i) : args;
|
|
562
|
-
}
|
|
563
|
-
var PACKAGE_MANAGER_SCRIPT_STEMS = /* @__PURE__ */ new Set(["npm", "pnpm", "yarn", "bun"]);
|
|
564
|
-
var MAX_SCRIPT_RESOLUTION_DEPTH = 5;
|
|
565
|
-
var COMPOUND_SCRIPT_RE = /&&|\|\||[|;]|`|\$\(/;
|
|
566
|
-
var packageJsonScriptsCache = /* @__PURE__ */ new Map();
|
|
567
|
-
function loadPackageScripts(candidate, stat) {
|
|
568
|
-
const cached = packageJsonScriptsCache.get(candidate);
|
|
569
|
-
if (cached && cached.mtimeMs === stat.mtimeMs) return cached.scripts;
|
|
570
|
-
let scripts = {};
|
|
571
|
-
try {
|
|
572
|
-
const parsed = JSON.parse(fs.readFileSync(candidate, "utf8"));
|
|
573
|
-
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
574
|
-
const raw = parsed["scripts"];
|
|
575
|
-
if (raw && typeof raw === "object" && !Array.isArray(raw)) scripts = raw;
|
|
576
|
-
}
|
|
577
|
-
} catch {
|
|
578
|
-
}
|
|
579
|
-
packageJsonScriptsCache.set(candidate, { mtimeMs: stat.mtimeMs, scripts });
|
|
580
|
-
return scripts;
|
|
581
|
-
}
|
|
582
|
-
function findNearestPackageScripts(startDir) {
|
|
583
|
-
let dir = startDir;
|
|
584
|
-
for (; ; ) {
|
|
585
|
-
const candidate = path.join(dir, "package.json");
|
|
586
|
-
try {
|
|
587
|
-
const stat = fs.statSync(candidate);
|
|
588
|
-
if (stat.isFile()) return loadPackageScripts(candidate, stat);
|
|
589
|
-
} catch {
|
|
590
|
-
}
|
|
591
|
-
const parent = path.dirname(dir);
|
|
592
|
-
if (parent === dir) return null;
|
|
593
|
-
dir = parent;
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
var YARN_BUILTIN_SUBCOMMANDS = /* @__PURE__ */ new Set([
|
|
597
|
-
"access",
|
|
598
|
-
"add",
|
|
599
|
-
"audit",
|
|
600
|
-
"autoclean",
|
|
601
|
-
"bin",
|
|
602
|
-
"cache",
|
|
603
|
-
"check",
|
|
604
|
-
"config",
|
|
605
|
-
"create",
|
|
606
|
-
"dedupe",
|
|
607
|
-
"dlx",
|
|
608
|
-
"exec",
|
|
609
|
-
"explain",
|
|
610
|
-
"generate-lock-entry",
|
|
611
|
-
"global",
|
|
612
|
-
"help",
|
|
613
|
-
"import",
|
|
614
|
-
"info",
|
|
615
|
-
"init",
|
|
616
|
-
"install",
|
|
617
|
-
"licenses",
|
|
618
|
-
"link",
|
|
619
|
-
"list",
|
|
620
|
-
"login",
|
|
621
|
-
"logout",
|
|
622
|
-
"node",
|
|
623
|
-
"npm",
|
|
624
|
-
"outdated",
|
|
625
|
-
"owner",
|
|
626
|
-
"pack",
|
|
627
|
-
"patch",
|
|
628
|
-
"plugin",
|
|
629
|
-
"policies",
|
|
630
|
-
"rebuild",
|
|
631
|
-
"remove",
|
|
632
|
-
"set",
|
|
633
|
-
"stage",
|
|
634
|
-
"tag",
|
|
635
|
-
"team",
|
|
636
|
-
"unlink",
|
|
637
|
-
"unplug",
|
|
638
|
-
"up",
|
|
639
|
-
"upgrade",
|
|
640
|
-
"upgrade-interactive",
|
|
641
|
-
"version",
|
|
642
|
-
"versions",
|
|
643
|
-
"why",
|
|
644
|
-
"workspace",
|
|
645
|
-
"workspaces"
|
|
646
|
-
]);
|
|
647
|
-
function scriptNameFromArgs(stem, args) {
|
|
648
|
-
const [a0, a1] = args;
|
|
649
|
-
if (a0 === void 0) return null;
|
|
650
|
-
switch (stem) {
|
|
651
|
-
case "npm":
|
|
652
|
-
case "pnpm":
|
|
653
|
-
if (a0 === "test" || a0 === "t") return "test";
|
|
654
|
-
if ((a0 === "run" || a0 === "run-script") && a1 !== void 0) return a1;
|
|
655
|
-
return null;
|
|
656
|
-
case "bun":
|
|
657
|
-
if (a0 === "run" && a1 !== void 0) return a1;
|
|
658
|
-
return null;
|
|
659
|
-
case "yarn":
|
|
660
|
-
if (a0 === "run" && a1 !== void 0) return a1;
|
|
661
|
-
if (!a0.startsWith("-") && !YARN_BUILTIN_SUBCOMMANDS.has(a0)) return a0;
|
|
662
|
-
return null;
|
|
663
|
-
default:
|
|
664
|
-
return null;
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
function resolvePackageManagerScript(argv, cwd) {
|
|
668
|
-
try {
|
|
669
|
-
let current = argv;
|
|
670
|
-
let resolvedAny = false;
|
|
671
|
-
for (let depth = 0; depth < MAX_SCRIPT_RESOLUTION_DEPTH; depth++) {
|
|
672
|
-
if (current.length === 0) break;
|
|
673
|
-
const stem = pathStem(current[0]).toLowerCase();
|
|
674
|
-
if (!PACKAGE_MANAGER_SCRIPT_STEMS.has(stem)) break;
|
|
675
|
-
const scriptName = scriptNameFromArgs(stem, current.slice(1));
|
|
676
|
-
if (scriptName === null) break;
|
|
677
|
-
const scripts = findNearestPackageScripts(cwd);
|
|
678
|
-
if (scripts === null) break;
|
|
679
|
-
const scriptCmd = scripts[scriptName];
|
|
680
|
-
if (typeof scriptCmd !== "string" || !scriptCmd.trim()) break;
|
|
681
|
-
if (COMPOUND_SCRIPT_RE.test(scriptCmd)) break;
|
|
682
|
-
let nextArgv;
|
|
683
|
-
try {
|
|
684
|
-
nextArgv = shlexSplit(scriptCmd);
|
|
685
|
-
} catch {
|
|
686
|
-
break;
|
|
687
|
-
}
|
|
688
|
-
if (nextArgv.length === 0) break;
|
|
689
|
-
current = nextArgv;
|
|
690
|
-
resolvedAny = true;
|
|
691
|
-
}
|
|
692
|
-
return resolvedAny ? current : null;
|
|
693
|
-
} catch {
|
|
694
|
-
return null;
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
function shlexSplit(cmd) {
|
|
698
|
-
const tokens = [];
|
|
699
|
-
let cur = "";
|
|
700
|
-
let has = false;
|
|
701
|
-
let i = 0;
|
|
702
|
-
const n = cmd.length;
|
|
703
|
-
while (i < n) {
|
|
704
|
-
const ch = cmd[i];
|
|
705
|
-
if (ch === " " || ch === " " || ch === "\n" || ch === "\r") {
|
|
706
|
-
if (has) {
|
|
707
|
-
tokens.push(cur);
|
|
708
|
-
cur = "";
|
|
709
|
-
has = false;
|
|
710
|
-
}
|
|
711
|
-
i += 1;
|
|
712
|
-
continue;
|
|
713
|
-
}
|
|
714
|
-
has = true;
|
|
715
|
-
if (ch === "\\") {
|
|
716
|
-
if (i + 1 < n) {
|
|
717
|
-
cur += cmd[i + 1];
|
|
718
|
-
i += 2;
|
|
719
|
-
} else {
|
|
720
|
-
i += 1;
|
|
721
|
-
}
|
|
722
|
-
continue;
|
|
723
|
-
}
|
|
724
|
-
if (ch === "'") {
|
|
725
|
-
i += 1;
|
|
726
|
-
const end = cmd.indexOf("'", i);
|
|
727
|
-
if (end === -1) throw new Error("No closing quotation");
|
|
728
|
-
cur += cmd.slice(i, end);
|
|
729
|
-
i = end + 1;
|
|
730
|
-
continue;
|
|
731
|
-
}
|
|
732
|
-
if (ch === '"') {
|
|
733
|
-
i += 1;
|
|
734
|
-
let buf = "";
|
|
735
|
-
while (i < n && cmd[i] !== '"') {
|
|
736
|
-
if (cmd[i] === "\\" && i + 1 < n && (cmd[i + 1] === '"' || cmd[i + 1] === "\\")) {
|
|
737
|
-
buf += cmd[i + 1];
|
|
738
|
-
i += 2;
|
|
739
|
-
} else {
|
|
740
|
-
buf += cmd[i];
|
|
741
|
-
i += 1;
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
if (i >= n) throw new Error("No closing quotation");
|
|
745
|
-
cur += buf;
|
|
746
|
-
i += 1;
|
|
747
|
-
continue;
|
|
748
|
-
}
|
|
749
|
-
cur += ch;
|
|
750
|
-
i += 1;
|
|
751
|
-
}
|
|
752
|
-
if (has) tokens.push(cur);
|
|
753
|
-
return tokens;
|
|
754
|
-
}
|
|
755
|
-
function capLongLines(lines, maxChars = FALLBACK_MAX_LINE_CHARS) {
|
|
756
|
-
return lines.map((line) => {
|
|
757
|
-
if (line.length <= maxChars) return line;
|
|
758
|
-
if (ELIDED_MARKER_RE.test(line)) return line;
|
|
759
|
-
const priorClip = CLIPPED_MARKER_RE.exec(line);
|
|
760
|
-
let cut = maxChars;
|
|
761
|
-
const high = line.charCodeAt(cut - 1);
|
|
762
|
-
const low = line.charCodeAt(cut);
|
|
763
|
-
if (high >= 55296 && high <= 56319 && low >= 56320 && low <= 57343) cut -= 1;
|
|
764
|
-
const carried = priorClip !== null && priorClip.index >= cut ? Number(priorClip[1]) - priorClip[0].length : 0;
|
|
765
|
-
return `${line.slice(0, cut)} \u2026 [${line.length - cut + carried} chars elided]`;
|
|
766
|
-
});
|
|
767
|
-
}
|
|
768
|
-
var GREP_MAX_LINE_CHARS = 1e3;
|
|
769
|
-
var _GREP_PREFIX_BUDGET = 160;
|
|
770
|
-
var _GREP_LINE_PREFIX_RE = /^(?:(?:[A-Za-z]:)?[^:\n]{0,200}?[:-]\d+[:-]|\d+[:-])/;
|
|
771
|
-
var _GREP_BAIL_SHORT = /* @__PURE__ */ new Set(["e", "f", "i", "v", "y", "z", "S", "U"]);
|
|
772
|
-
var _GREP_BAIL_LONG = /* @__PURE__ */ new Set([
|
|
773
|
-
"--regexp",
|
|
774
|
-
"--file",
|
|
775
|
-
"--ignore-case",
|
|
776
|
-
"--invert-match",
|
|
777
|
-
"--null-data",
|
|
778
|
-
"--smart-case",
|
|
779
|
-
"--multiline"
|
|
780
|
-
]);
|
|
781
|
-
var _GREP_VALUE_SHORT = /* @__PURE__ */ new Set(["A", "B", "C", "m", "d", "D"]);
|
|
782
|
-
var _GREP_RG_VALUE_SHORT = /* @__PURE__ */ new Set(["g", "t", "T", "M", "j", "r"]);
|
|
783
|
-
var _GREP_VALUE_LONG = /* @__PURE__ */ new Set([
|
|
784
|
-
"--max-count",
|
|
785
|
-
"--context",
|
|
786
|
-
"--after-context",
|
|
787
|
-
"--before-context",
|
|
788
|
-
"--include",
|
|
789
|
-
"--exclude",
|
|
790
|
-
"--exclude-dir",
|
|
791
|
-
"--glob",
|
|
792
|
-
"--iglob",
|
|
793
|
-
"--type",
|
|
794
|
-
"--type-not",
|
|
795
|
-
"--binary-files",
|
|
796
|
-
"--devices",
|
|
797
|
-
"--directories",
|
|
798
|
-
"--color",
|
|
799
|
-
"--colour",
|
|
800
|
-
"--replace",
|
|
801
|
-
"--max-columns",
|
|
802
|
-
"--threads",
|
|
803
|
-
"--sort",
|
|
804
|
-
"--sortr",
|
|
805
|
-
"--pre",
|
|
806
|
-
"--engine"
|
|
807
|
-
]);
|
|
808
|
-
var _GREP_REGEX_META_RE = /[\\^$.|?*+()[\]{}]/;
|
|
809
|
-
function grepLiteralPattern(argv) {
|
|
810
|
-
if (!argv.length) return null;
|
|
811
|
-
const stem = pathStem(argv[0] ?? "").toLowerCase();
|
|
812
|
-
let rest = argv.slice(1);
|
|
813
|
-
let isRg = stem === "rg";
|
|
814
|
-
if (stem === "git") {
|
|
815
|
-
const gi = rest.indexOf("grep");
|
|
816
|
-
if (gi < 0) return null;
|
|
817
|
-
rest = rest.slice(gi + 1);
|
|
818
|
-
isRg = false;
|
|
819
|
-
}
|
|
820
|
-
let fixed = false;
|
|
821
|
-
let endOfFlags = false;
|
|
822
|
-
let pattern = null;
|
|
823
|
-
for (let i = 0; i < rest.length; i++) {
|
|
824
|
-
const tok = rest[i];
|
|
825
|
-
if (!endOfFlags && tok === "--") {
|
|
826
|
-
endOfFlags = true;
|
|
827
|
-
continue;
|
|
828
|
-
}
|
|
829
|
-
if (!endOfFlags && tok.startsWith("--")) {
|
|
830
|
-
const eq = tok.indexOf("=");
|
|
831
|
-
const name = eq >= 0 ? tok.slice(0, eq) : tok;
|
|
832
|
-
if (_GREP_BAIL_LONG.has(name)) return null;
|
|
833
|
-
if (name === "--fixed-strings") fixed = true;
|
|
834
|
-
else if (eq < 0 && _GREP_VALUE_LONG.has(name)) i++;
|
|
835
|
-
continue;
|
|
836
|
-
}
|
|
837
|
-
if (!endOfFlags && tok.length > 1 && tok.startsWith("-")) {
|
|
838
|
-
const letters = tok.slice(1);
|
|
839
|
-
for (let k = 0; k < letters.length; k++) {
|
|
840
|
-
const ch = letters[k];
|
|
841
|
-
if (_GREP_BAIL_SHORT.has(ch)) return null;
|
|
842
|
-
if (ch === "F") fixed = true;
|
|
843
|
-
if (_GREP_VALUE_SHORT.has(ch) || isRg && _GREP_RG_VALUE_SHORT.has(ch)) {
|
|
844
|
-
if (k === letters.length - 1) i++;
|
|
845
|
-
break;
|
|
846
|
-
}
|
|
847
|
-
}
|
|
848
|
-
continue;
|
|
849
|
-
}
|
|
850
|
-
pattern = tok;
|
|
851
|
-
break;
|
|
852
|
-
}
|
|
853
|
-
if (pattern === null || pattern.length < 3 || pattern.includes("\n")) return null;
|
|
854
|
-
if (!fixed && _GREP_REGEX_META_RE.test(pattern)) return null;
|
|
855
|
-
return pattern;
|
|
856
|
-
}
|
|
857
|
-
function _safeCut(line, idx) {
|
|
858
|
-
if (idx <= 0 || idx >= line.length) return idx;
|
|
859
|
-
const high = line.charCodeAt(idx - 1);
|
|
860
|
-
const low = line.charCodeAt(idx);
|
|
861
|
-
return high >= 55296 && high <= 56319 && low >= 56320 && low <= 57343 ? idx - 1 : idx;
|
|
862
|
-
}
|
|
863
|
-
function clipLongMatchLine(line, pattern, maxChars = GREP_MAX_LINE_CHARS) {
|
|
864
|
-
if (line.length <= maxChars) return line;
|
|
865
|
-
const pm = _GREP_LINE_PREFIX_RE.exec(line);
|
|
866
|
-
const prefixEnd = pm && pm[0].length <= _GREP_PREFIX_BUDGET ? pm[0].length : 0;
|
|
867
|
-
let idx = line.indexOf(pattern, prefixEnd);
|
|
868
|
-
if (idx < 0) idx = line.indexOf(pattern);
|
|
869
|
-
if (idx < 0) return line;
|
|
870
|
-
const matchEnd = idx + pattern.length;
|
|
871
|
-
let clipped;
|
|
872
|
-
if (matchEnd <= maxChars) {
|
|
873
|
-
const cut = _safeCut(line, maxChars);
|
|
874
|
-
clipped = `${line.slice(0, cut)} \u2026 [${line.length - cut} chars elided]`;
|
|
875
|
-
} else {
|
|
876
|
-
const budget = maxChars - prefixEnd;
|
|
877
|
-
if (budget < pattern.length + 40) return line;
|
|
878
|
-
let start = Math.max(prefixEnd, idx - Math.floor((budget - pattern.length) / 2));
|
|
879
|
-
let stop = start + budget;
|
|
880
|
-
if (stop > line.length) {
|
|
881
|
-
stop = line.length;
|
|
882
|
-
start = Math.max(prefixEnd, stop - budget);
|
|
883
|
-
}
|
|
884
|
-
start = _safeCut(line, start);
|
|
885
|
-
stop = _safeCut(line, stop);
|
|
886
|
-
if (start > idx || stop < matchEnd) return line;
|
|
887
|
-
const before = start - prefixEnd;
|
|
888
|
-
const after = line.length - stop;
|
|
889
|
-
clipped = line.slice(0, prefixEnd) + (before > 0 ? `\u2026 [${before} chars elided] \u2026` : "") + line.slice(start, stop) + (after > 0 ? ` \u2026 [${after} chars elided]` : "");
|
|
890
|
-
}
|
|
891
|
-
return clipped.length < line.length ? clipped : line;
|
|
892
|
-
}
|
|
893
|
-
function clipGrepLines(text, argv, maxChars = GREP_MAX_LINE_CHARS) {
|
|
894
|
-
if (text.length <= maxChars) return text;
|
|
895
|
-
const pattern = grepLiteralPattern(argv);
|
|
896
|
-
if (pattern === null) return text;
|
|
897
|
-
let changed = false;
|
|
898
|
-
const out = text.split("\n").map((line) => {
|
|
899
|
-
const clipped = clipLongMatchLine(line, pattern, maxChars);
|
|
900
|
-
if (clipped !== line) changed = true;
|
|
901
|
-
return clipped;
|
|
902
|
-
});
|
|
903
|
-
return changed ? out.join("\n") : text;
|
|
904
|
-
}
|
|
905
|
-
function fallbackTruncate(stdout, stderr, maxLines) {
|
|
906
|
-
const half = Math.floor(maxLines / 2);
|
|
907
|
-
const outLines = truncateMiddle(capLongLines(dedupeConsecutive(stdout.split("\n"))), half);
|
|
908
|
-
const errLines = truncateMiddle(capLongLines(dedupeConsecutive(stderr.split("\n"))), half);
|
|
909
|
-
if (stderr) return `${outLines.join("\n")}
|
|
910
|
-
---
|
|
911
|
-
${errLines.join("\n")}`;
|
|
912
|
-
return outLines.join("\n");
|
|
913
|
-
}
|
|
914
|
-
function compressBashOutput(stdout, stderr) {
|
|
915
|
-
let body = dedupeConsecutive(stdout.split("\n"), { entropyBypass: true }).join("\n");
|
|
916
|
-
if (stderr.trim()) {
|
|
917
|
-
const err = dedupeConsecutive(stderr.split("\n"), { entropyBypass: true }).join("\n");
|
|
918
|
-
body = `${body.replace(/\s+$/, "")}
|
|
919
|
-
---
|
|
920
|
-
${err.replace(/\s+$/, "")}`;
|
|
921
|
-
}
|
|
922
|
-
return body;
|
|
923
|
-
}
|
|
924
|
-
function dedupeCombinedOutput(text) {
|
|
925
|
-
return squeezeBlankLines(dedupeConsecutive(text.split("\n")).join("\n"));
|
|
926
|
-
}
|
|
927
|
-
function compressTestOutput(lines, maxLines = 300) {
|
|
928
|
-
const deduped = dedupeNumericRuns(lines, { minRun: 5 });
|
|
929
|
-
return truncateMiddle(deduped, maxLines).join("\n");
|
|
930
|
-
}
|
|
931
|
-
function byteLength(s) {
|
|
932
|
-
return utf8Len(s);
|
|
933
|
-
}
|
|
934
|
-
|
|
935
39
|
// src/bash_output_cache.ts
|
|
936
40
|
init_define_import_meta_env();
|
|
937
|
-
import { readdirSync, readFileSync
|
|
41
|
+
import { readdirSync, readFileSync, statSync } from "fs";
|
|
938
42
|
import { resolve } from "path";
|
|
939
43
|
|
|
940
44
|
// src/hints/lang_patterns.ts
|
|
@@ -1214,14 +318,14 @@ function getMonitoringRecallHint(cmd) {
|
|
|
1214
318
|
|
|
1215
319
|
// src/recall_index.ts
|
|
1216
320
|
init_define_import_meta_env();
|
|
1217
|
-
import * as
|
|
321
|
+
import * as fs from "node:fs";
|
|
1218
322
|
function subdirForCacheType(cacheType) {
|
|
1219
323
|
return cacheType === "web" ? "web_outputs" : "bash_outputs";
|
|
1220
324
|
}
|
|
1221
325
|
function blobStillExists(cacheType, id) {
|
|
1222
326
|
try {
|
|
1223
327
|
const p = blobPath(subdirForCacheType(cacheType), id);
|
|
1224
|
-
return p !== null &&
|
|
328
|
+
return p !== null && fs.existsSync(p);
|
|
1225
329
|
} catch {
|
|
1226
330
|
return false;
|
|
1227
331
|
}
|
|
@@ -1438,11 +542,11 @@ function gitStateFingerprintSync(cwd) {
|
|
|
1438
542
|
}
|
|
1439
543
|
}
|
|
1440
544
|
var DIR_FINGERPRINT_LISTING_CAP_ENTRIES = 1e4;
|
|
1441
|
-
function dirStateFingerprintSync(
|
|
545
|
+
function dirStateFingerprintSync(path) {
|
|
1442
546
|
try {
|
|
1443
|
-
const stat =
|
|
547
|
+
const stat = statSync(path);
|
|
1444
548
|
if (!stat.isDirectory()) return null;
|
|
1445
|
-
const entries = readdirSync(
|
|
549
|
+
const entries = readdirSync(path);
|
|
1446
550
|
if (entries.length <= DIR_FINGERPRINT_LISTING_CAP_ENTRIES) {
|
|
1447
551
|
return shortFingerprint(entries.slice().sort().join("\0"));
|
|
1448
552
|
}
|
|
@@ -1452,12 +556,12 @@ function dirStateFingerprintSync(path2) {
|
|
|
1452
556
|
}
|
|
1453
557
|
}
|
|
1454
558
|
var FILE_FINGERPRINT_CONTENT_CAP_BYTES = 2 * 1024 * 1024;
|
|
1455
|
-
function fileStateFingerprintSync(
|
|
559
|
+
function fileStateFingerprintSync(path) {
|
|
1456
560
|
try {
|
|
1457
|
-
const stat =
|
|
561
|
+
const stat = statSync(path);
|
|
1458
562
|
if (!stat.isFile()) return null;
|
|
1459
563
|
if (stat.size <= FILE_FINGERPRINT_CONTENT_CAP_BYTES) {
|
|
1460
|
-
return shortFingerprint(
|
|
564
|
+
return shortFingerprint(readFileSync(path));
|
|
1461
565
|
}
|
|
1462
566
|
return shortFingerprint(`${stat.mtimeMs}\0${stat.size}`);
|
|
1463
567
|
} catch {
|
|
@@ -1473,7 +577,7 @@ function depLockfileFingerprintSync(cmd, cwd) {
|
|
|
1473
577
|
if (!candidates) return null;
|
|
1474
578
|
for (const lockfile of candidates) {
|
|
1475
579
|
try {
|
|
1476
|
-
const content =
|
|
580
|
+
const content = readFileSync(resolve(cwd, lockfile));
|
|
1477
581
|
return shortFingerprint(content);
|
|
1478
582
|
} catch {
|
|
1479
583
|
continue;
|
|
@@ -1745,52 +849,6 @@ registerReset(() => {
|
|
|
1745
849
|
});
|
|
1746
850
|
|
|
1747
851
|
export {
|
|
1748
|
-
DEFAULT_MAX_LINES,
|
|
1749
|
-
DEFAULT_MAX_BYTES,
|
|
1750
|
-
MAX_INSPECT_BYTES,
|
|
1751
|
-
LONG_LINE_MAX_CHARS,
|
|
1752
|
-
getMaxInputBytes,
|
|
1753
|
-
INPUT_MAX_LINE_CHARS,
|
|
1754
|
-
clipWideLines,
|
|
1755
|
-
clampKeepingEnds,
|
|
1756
|
-
compressionMarker,
|
|
1757
|
-
combineStreams,
|
|
1758
|
-
ERROR_SIGNAL_RE,
|
|
1759
|
-
TIMESTAMP_PREFIX_RE,
|
|
1760
|
-
REDIRECT_TOKEN_RE,
|
|
1761
|
-
hasBareBackgroundOrNewline,
|
|
1762
|
-
isRedirectAmpersand,
|
|
1763
|
-
hasUnquotedOperator,
|
|
1764
|
-
splitOwnTrailingNotices,
|
|
1765
|
-
safeDecode,
|
|
1766
|
-
normalise,
|
|
1767
|
-
hasHighEntropyToken,
|
|
1768
|
-
dedupeConsecutive,
|
|
1769
|
-
truncateMiddleSmart,
|
|
1770
|
-
capBytes,
|
|
1771
|
-
capTokens,
|
|
1772
|
-
headTailCompress,
|
|
1773
|
-
truncateTableRows,
|
|
1774
|
-
trimRepeatedPrefix,
|
|
1775
|
-
stripTimestamps,
|
|
1776
|
-
splitBlocks,
|
|
1777
|
-
maybeNote,
|
|
1778
|
-
squeezeBlankLines,
|
|
1779
|
-
preserveStderrOnError,
|
|
1780
|
-
pathName,
|
|
1781
|
-
pathStem,
|
|
1782
|
-
positionalArgs,
|
|
1783
|
-
stripPrefixes,
|
|
1784
|
-
resolvePackageManagerScript,
|
|
1785
|
-
shlexSplit,
|
|
1786
|
-
capLongLines,
|
|
1787
|
-
clipLongMatchLine,
|
|
1788
|
-
clipGrepLines,
|
|
1789
|
-
fallbackTruncate,
|
|
1790
|
-
compressBashOutput,
|
|
1791
|
-
dedupeCombinedOutput,
|
|
1792
|
-
compressTestOutput,
|
|
1793
|
-
byteLength,
|
|
1794
852
|
isLockFile,
|
|
1795
853
|
isManifestFile,
|
|
1796
854
|
isInBuildDir,
|