token-goat 2.9.28 → 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.
- package/README.md +2 -0
- package/dist/{token-goat-chunk-OZRSREKR.mjs → token-goat-chunk-2AWQ2R5X.mjs} +2 -2
- package/dist/{token-goat-chunk-5NNYIUGV.mjs → token-goat-chunk-2NNUA2LR.mjs} +4 -4
- package/dist/{token-goat-chunk-4RN64ZND.mjs → token-goat-chunk-2WOUYWLM.mjs} +2 -1
- package/dist/{token-goat-chunk-HUDC5GS5.mjs → token-goat-chunk-435UQTKD.mjs} +5 -3
- package/dist/{token-goat-chunk-6DQNNFJ6.mjs → token-goat-chunk-44BM7DDQ.mjs} +3 -3
- package/dist/{token-goat-chunk-4JMWPWCS.mjs → token-goat-chunk-52NSDWYY.mjs} +2 -2
- package/dist/{token-goat-chunk-IHKZ3QNA.mjs → token-goat-chunk-67BNIKKO.mjs} +19 -16
- package/dist/{token-goat-chunk-XBESNWEX.mjs → token-goat-chunk-6AK46ZT7.mjs} +2 -3
- package/dist/{token-goat-chunk-M56BWPBN.mjs → token-goat-chunk-7CPMDFGB.mjs} +166 -40
- package/dist/token-goat-chunk-ASLWOQ3I.mjs +14 -0
- package/dist/{token-goat-chunk-QM76S6YS.mjs → token-goat-chunk-BGYOZ6DO.mjs} +6 -4
- package/dist/{token-goat-chunk-JXK2HQXS.mjs → token-goat-chunk-C5YPNZKQ.mjs} +3 -3
- package/dist/{token-goat-chunk-MVSWBNMD.mjs → token-goat-chunk-CIQ2FTY3.mjs} +19 -14
- package/dist/{token-goat-chunk-BJBRGPBX.mjs → token-goat-chunk-D4ETHJD6.mjs} +6 -4
- package/dist/{token-goat-chunk-VE27HPIF.mjs → token-goat-chunk-DNRPXHYH.mjs} +21 -17
- package/dist/{token-goat-chunk-YWSP6IU7.mjs → token-goat-chunk-DNSPXQXQ.mjs} +2 -2
- package/dist/token-goat-chunk-DPNLUJWB.mjs +220 -0
- package/dist/{token-goat-chunk-I7CB3X4K.mjs → token-goat-chunk-E4ZOJIZK.mjs} +10 -7
- package/dist/{token-goat-chunk-IZXKVT4A.mjs → token-goat-chunk-E5TK5DNO.mjs} +11 -4
- package/dist/{token-goat-chunk-MMLMALWK.mjs → token-goat-chunk-EUSDXRXU.mjs} +60 -12
- package/dist/{token-goat-chunk-7R2XYKC5.mjs → token-goat-chunk-FTP4U4QA.mjs} +12 -9
- package/dist/{token-goat-chunk-LEG3JNJ6.mjs → token-goat-chunk-G23DWHV4.mjs} +17 -14
- package/dist/{token-goat-chunk-L7SDVGBT.mjs → token-goat-chunk-G7IWXCFF.mjs} +49 -23
- package/dist/{token-goat-chunk-NILVK7XM.mjs → token-goat-chunk-GLXRTTLE.mjs} +7 -5
- package/dist/{token-goat-chunk-6CCQDAYY.mjs → token-goat-chunk-H5J3C56Q.mjs} +35 -16
- package/dist/{token-goat-chunk-Q4S3UQGO.mjs → token-goat-chunk-HNFZZHFW.mjs} +2 -2
- package/dist/{token-goat-chunk-CBMY2FGI.mjs → token-goat-chunk-HUYUHODZ.mjs} +572 -230
- package/dist/token-goat-chunk-IVE6U7KV.mjs +53 -0
- package/dist/{token-goat-chunk-F7QZRIWM.mjs → token-goat-chunk-IVWI2OCK.mjs} +8 -30
- package/dist/{token-goat-chunk-GMOUBOX4.mjs → token-goat-chunk-JTKCQMQA.mjs} +37 -5
- package/dist/{token-goat-chunk-6SGLIPQB.mjs → token-goat-chunk-KOPIR3KZ.mjs} +12 -9
- package/dist/token-goat-chunk-L7H3U27L.mjs +35 -0
- package/dist/{token-goat-chunk-FSTWAOW6.mjs → token-goat-chunk-LZNBQTDK.mjs} +6 -4
- package/dist/token-goat-chunk-MELOKFDJ.mjs +199 -0
- package/dist/{token-goat-chunk-VWZKZPSR.mjs → token-goat-chunk-NMBWLRHW.mjs} +76 -39
- package/dist/{token-goat-chunk-HXNAC4ZF.mjs → token-goat-chunk-O6I2XU4P.mjs} +12 -10
- package/dist/{token-goat-chunk-MAMQPC43.mjs → token-goat-chunk-ONXH6NZ5.mjs} +1 -1
- package/dist/token-goat-chunk-ORNFMIER.mjs +295 -0
- package/dist/{token-goat-chunk-66LODAUT.mjs → token-goat-chunk-PGTH2U4C.mjs} +1 -1
- package/dist/{token-goat-chunk-SJEKA7Y2.mjs → token-goat-chunk-PKRWMHVP.mjs} +76 -64
- package/dist/{token-goat-chunk-DA43OE7L.mjs → token-goat-chunk-PQ53BSCF.mjs} +1 -1
- package/dist/{token-goat-chunk-RSS3TLXU.mjs → token-goat-chunk-PYSUADX4.mjs} +2 -2
- package/dist/{token-goat-chunk-EL7M26WP.mjs → token-goat-chunk-QO3LXVVR.mjs} +185 -104
- package/dist/{token-goat-chunk-XI2VFAV6.mjs → token-goat-chunk-RLP6J7WR.mjs} +6 -6
- package/dist/token-goat-chunk-RQGGMPCR.mjs +205 -0
- package/dist/{token-goat-chunk-6Z5ULNE5.mjs → token-goat-chunk-RTMVLHWX.mjs} +165 -60
- package/dist/{token-goat-chunk-E3K3BTEQ.mjs → token-goat-chunk-S4VSXURL.mjs} +8 -6
- package/dist/{token-goat-chunk-LKSXAMJB.mjs → token-goat-chunk-SE6E4BKJ.mjs} +1 -1
- package/dist/token-goat-chunk-TCQANXYC.mjs +351 -0
- package/dist/{token-goat-chunk-GGLEE35R.mjs → token-goat-chunk-TDUT2CL6.mjs} +7 -7
- package/dist/{token-goat-chunk-CC2PYJM7.mjs → token-goat-chunk-TGOXNAHW.mjs} +54 -112
- package/dist/{token-goat-chunk-XKY4VKJ4.mjs → token-goat-chunk-UA5BKWWQ.mjs} +1 -1
- package/dist/{token-goat-chunk-UBUKHVYW.mjs → token-goat-chunk-UXSXQQIY.mjs} +1 -1
- package/dist/{token-goat-chunk-D5ICEPSB.mjs → token-goat-chunk-VMFWNHGR.mjs} +79 -68
- package/dist/token-goat-chunk-VQ6F6T7X.mjs +36 -0
- package/dist/{token-goat-chunk-4STDIGYC.mjs → token-goat-chunk-VZQEWRVH.mjs} +6 -4
- package/dist/{token-goat-chunk-OSUFN2FV.mjs → token-goat-chunk-XB5KKOCG.mjs} +5 -25
- package/dist/{token-goat-chunk-L45ZQRT7.mjs → token-goat-chunk-XYWPOSCN.mjs} +57 -615
- package/dist/{token-goat-chunk-4JJBFT7V.mjs → token-goat-chunk-YAGLESS3.mjs} +8 -5
- package/dist/token-goat-chunk-YKSRAWUU.mjs +33 -0
- package/dist/{token-goat-chunk-F2ARFHLJ.mjs → token-goat-chunk-YOOVFPTP.mjs} +2 -2
- package/dist/{token-goat-chunk-EEIDFMEM.mjs → token-goat-chunk-YZAAZU2S.mjs} +12 -3
- package/dist/token-goat-chunk-Z6KBMOBI.mjs +53 -0
- package/dist/{token-goat-chunk-RJH64KQH.mjs → token-goat-chunk-ZER6EAXZ.mjs} +3 -3
- package/dist/token-goat-hook-client.cjs +475 -0
- package/dist/token-goat-hook-client.mjs +26 -0
- package/dist/token-goat-hook.mjs +31 -27
- package/dist/token-goat.core.mjs +9 -44
- package/docs/C4_RUNTIME_ARCHITECTURE.md +2 -2
- package/docs/cli.md +3 -2
- package/docs/install.md +16 -14
- package/package.json +1 -1
- package/dist/token-goat-chunk-7MAFDRVR.mjs +0 -47
- package/dist/token-goat-chunk-BCN2YQC6.mjs +0 -32
- package/dist/token-goat-chunk-D7GHQKQD.mjs +0 -30
- package/dist/token-goat-chunk-IFORDBGC.mjs +0 -192
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { createRequire as __cjsRequire } from 'node:module';
|
|
2
|
+
const require = __cjsRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
PROTOCOL_VERSION,
|
|
5
|
+
SERVER_SLOTS,
|
|
6
|
+
configStamp,
|
|
7
|
+
encodeFrame,
|
|
8
|
+
endpointFor,
|
|
9
|
+
envSnapshot,
|
|
10
|
+
frameFits,
|
|
11
|
+
launcherPath,
|
|
12
|
+
mac,
|
|
13
|
+
macMatches,
|
|
14
|
+
markerAgeMs,
|
|
15
|
+
nonce,
|
|
16
|
+
readFrames,
|
|
17
|
+
readMarker,
|
|
18
|
+
readServerKey,
|
|
19
|
+
touchMarker,
|
|
20
|
+
writeFrame
|
|
21
|
+
} from "./token-goat-chunk-DPNLUJWB.mjs";
|
|
22
|
+
import {
|
|
23
|
+
envBool
|
|
24
|
+
} from "./token-goat-chunk-IVE6U7KV.mjs";
|
|
25
|
+
import {
|
|
26
|
+
init_define_import_meta_env
|
|
27
|
+
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
28
|
+
|
|
29
|
+
// src/hook_client.ts
|
|
30
|
+
init_define_import_meta_env();
|
|
31
|
+
import { spawn } from "node:child_process";
|
|
32
|
+
import * as fs from "node:fs";
|
|
33
|
+
import * as net from "node:net";
|
|
34
|
+
var HANDSHAKE_TIMEOUT_MS = 150;
|
|
35
|
+
var FIND_BUDGET_MS = 300;
|
|
36
|
+
var RESPONSE_TIMEOUT_MS = 12e4;
|
|
37
|
+
var CONTROL_WAIT_MS = 1e4;
|
|
38
|
+
var SPAWN_RETRY_MS = 3e4;
|
|
39
|
+
var DISABLED_MARKER_TTL_MS = 10 * 6e4;
|
|
40
|
+
function attempt(slot, key, request, handshakeMs, dir) {
|
|
41
|
+
return new Promise((resolve) => {
|
|
42
|
+
const socket = net.connect(endpointFor(slot, dir));
|
|
43
|
+
const nc = nonce();
|
|
44
|
+
let dispatched = false;
|
|
45
|
+
let settled = false;
|
|
46
|
+
const finish = (outcome) => {
|
|
47
|
+
if (settled) return;
|
|
48
|
+
settled = true;
|
|
49
|
+
clearTimeout(timer);
|
|
50
|
+
socket.destroy();
|
|
51
|
+
resolve(outcome);
|
|
52
|
+
};
|
|
53
|
+
let timer = setTimeout(() => finish({ kind: "busy" }), handshakeMs);
|
|
54
|
+
socket.on("error", (e) => {
|
|
55
|
+
if (dispatched) finish({ kind: "lost" });
|
|
56
|
+
else finish({ kind: e.code === "ENOENT" || e.code === "ECONNREFUSED" ? "absent" : "refused" });
|
|
57
|
+
});
|
|
58
|
+
socket.on("close", () => finish({ kind: dispatched ? "lost" : "refused" }));
|
|
59
|
+
const control = request.kind === "status" || request.kind === "stop";
|
|
60
|
+
socket.on("connect", () => writeFrame(socket, { t: "hello", v: PROTOCOL_VERSION, nc, ...control ? { ctl: true } : {} }));
|
|
61
|
+
let ns = "";
|
|
62
|
+
readFrames(
|
|
63
|
+
socket,
|
|
64
|
+
(msg) => {
|
|
65
|
+
if (msg["t"] === "busy") return finish({ kind: "busy" });
|
|
66
|
+
if (msg["t"] === "stale") return finish({ kind: "stale" });
|
|
67
|
+
if (msg["t"] === "challenge" && !dispatched) {
|
|
68
|
+
ns = typeof msg["ns"] === "string" ? msg["ns"] : "";
|
|
69
|
+
if (ns === "" || msg["v"] !== PROTOCOL_VERSION || !macMatches(mac(key, "S", nc, ns), msg["mac"])) return finish({ kind: "refused" });
|
|
70
|
+
const body = JSON.stringify(request);
|
|
71
|
+
const frame = encodeFrame({ t: "req", mac: mac(key, "C", nc, ns, body), body });
|
|
72
|
+
if (!frameFits(frame)) return finish({ kind: "oversize" });
|
|
73
|
+
dispatched = true;
|
|
74
|
+
clearTimeout(timer);
|
|
75
|
+
timer = setTimeout(() => finish({ kind: "lost" }), RESPONSE_TIMEOUT_MS);
|
|
76
|
+
socket.write(frame);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (msg["t"] === "res" && dispatched) {
|
|
80
|
+
const body = msg["body"];
|
|
81
|
+
if (typeof body !== "string" || !macMatches(mac(key, "R", nc, ns, body), msg["mac"])) return finish({ kind: "lost" });
|
|
82
|
+
try {
|
|
83
|
+
return finish({ kind: "served", reply: JSON.parse(body) });
|
|
84
|
+
} catch {
|
|
85
|
+
return finish({ kind: "lost" });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
finish({ kind: dispatched ? "lost" : "refused" });
|
|
89
|
+
},
|
|
90
|
+
() => finish({ kind: dispatched ? "lost" : "refused" })
|
|
91
|
+
);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
function startServer(slot) {
|
|
95
|
+
const launcher = launcherPath();
|
|
96
|
+
const disabled = markerAgeMs("disabled") < DISABLED_MARKER_TTL_MS && readMarker("disabled") === configStamp();
|
|
97
|
+
if (disabled || markerAgeMs(`spawn-${slot}`) < SPAWN_RETRY_MS || !fs.existsSync(launcher)) return;
|
|
98
|
+
touchMarker(`spawn-${slot}`);
|
|
99
|
+
try {
|
|
100
|
+
spawn(process.execPath, [launcher, "hook-server", "run", "--slot", String(slot)], { detached: true, stdio: "ignore", windowsHide: true }).unref();
|
|
101
|
+
} catch {
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
function serverEnabled() {
|
|
105
|
+
return envBool("TOKEN_GOAT_HOOK_SERVER", true);
|
|
106
|
+
}
|
|
107
|
+
async function callServer(request, opts = {}) {
|
|
108
|
+
if (!serverEnabled()) return void 0;
|
|
109
|
+
const autostart = opts.autostart !== false;
|
|
110
|
+
const key = readServerKey();
|
|
111
|
+
if (key === void 0) {
|
|
112
|
+
if (autostart) startServer(0);
|
|
113
|
+
return void 0;
|
|
114
|
+
}
|
|
115
|
+
const deadline = Date.now() + FIND_BUDGET_MS;
|
|
116
|
+
for (let slot = 0; slot < SERVER_SLOTS && Date.now() < deadline; slot++) {
|
|
117
|
+
const outcome = await attempt(slot, key, request, opts.handshakeMs ?? HANDSHAKE_TIMEOUT_MS);
|
|
118
|
+
if (outcome.kind === "served") return outcome.reply;
|
|
119
|
+
if (outcome.kind === "lost") return "lost";
|
|
120
|
+
if (outcome.kind === "absent") {
|
|
121
|
+
if (autostart) startServer(slot);
|
|
122
|
+
return void 0;
|
|
123
|
+
}
|
|
124
|
+
if (outcome.kind === "stale" || outcome.kind === "oversize") return void 0;
|
|
125
|
+
}
|
|
126
|
+
return void 0;
|
|
127
|
+
}
|
|
128
|
+
async function relayViaServer(event, input, harnessWaitMs) {
|
|
129
|
+
try {
|
|
130
|
+
const request = {
|
|
131
|
+
kind: "hook",
|
|
132
|
+
event,
|
|
133
|
+
input: typeof input === "string" ? input : JSON.stringify(input),
|
|
134
|
+
elapsedMs: performance.now(),
|
|
135
|
+
env: envSnapshot(),
|
|
136
|
+
cwd: process.cwd()
|
|
137
|
+
};
|
|
138
|
+
if (harnessWaitMs !== void 0) request.harnessWaitMs = harnessWaitMs;
|
|
139
|
+
const reply = await callServer(request);
|
|
140
|
+
if (reply === void 0) return void 0;
|
|
141
|
+
if (reply === "lost" || !reply.ok || !("stdout" in reply)) return "{}";
|
|
142
|
+
return reply.stdout;
|
|
143
|
+
} catch {
|
|
144
|
+
return void 0;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
var WARM_CLI_COMMANDS = /* @__PURE__ */ new Set([
|
|
148
|
+
"answer",
|
|
149
|
+
"brief",
|
|
150
|
+
"changed",
|
|
151
|
+
"exports",
|
|
152
|
+
"imports",
|
|
153
|
+
"map",
|
|
154
|
+
"outline",
|
|
155
|
+
"read",
|
|
156
|
+
"refs",
|
|
157
|
+
"section",
|
|
158
|
+
"semantic",
|
|
159
|
+
"skeleton",
|
|
160
|
+
"symbol"
|
|
161
|
+
]);
|
|
162
|
+
function warmCliEligible(argv) {
|
|
163
|
+
const command = argv[2];
|
|
164
|
+
if (command === void 0 || !WARM_CLI_COMMANDS.has(command) || process.stdout.isTTY === true) return false;
|
|
165
|
+
return !argv.slice(3).some((a) => a === "-" || a === "--stdin" || a === "--help" || a === "-h");
|
|
166
|
+
}
|
|
167
|
+
async function runCliViaServer(argv) {
|
|
168
|
+
if (!warmCliEligible(argv)) return false;
|
|
169
|
+
try {
|
|
170
|
+
const reply = await callServer({ kind: "cli", argv: argv.slice(2), env: envSnapshot(), cwd: process.cwd() });
|
|
171
|
+
if (reply === void 0 || reply === "lost" || !reply.ok || !("stdout" in reply)) return false;
|
|
172
|
+
if (reply.stdout !== "") process.stdout.write(reply.stdout);
|
|
173
|
+
if (reply.stderr !== void 0 && reply.stderr !== "") process.stderr.write(reply.stderr);
|
|
174
|
+
process.exitCode = reply.status ?? 0;
|
|
175
|
+
return true;
|
|
176
|
+
} catch {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
async function serverStatuses(dir) {
|
|
181
|
+
return (await queryServers("status", dir)).flatMap(({ reply }) => reply.ok && "info" in reply ? [reply.info] : []);
|
|
182
|
+
}
|
|
183
|
+
async function queryServers(kind, dir) {
|
|
184
|
+
const key = readServerKey(dir);
|
|
185
|
+
if (key === void 0) return [];
|
|
186
|
+
const deadline = Date.now() + CONTROL_WAIT_MS;
|
|
187
|
+
const answered = [];
|
|
188
|
+
for (let slot = 0; slot < SERVER_SLOTS; slot++) {
|
|
189
|
+
let outcome = await attempt(slot, key, { kind }, 2e3, dir);
|
|
190
|
+
while (outcome.kind === "busy" && Date.now() < deadline) outcome = await attempt(slot, key, { kind }, 2e3, dir);
|
|
191
|
+
if (outcome.kind === "served") answered.push({ slot, reply: outcome.reply });
|
|
192
|
+
}
|
|
193
|
+
return answered;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export {
|
|
197
|
+
serverEnabled,
|
|
198
|
+
callServer,
|
|
199
|
+
relayViaServer,
|
|
200
|
+
WARM_CLI_COMMANDS,
|
|
201
|
+
warmCliEligible,
|
|
202
|
+
runCliViaServer,
|
|
203
|
+
serverStatuses,
|
|
204
|
+
queryServers
|
|
205
|
+
};
|
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
import { createRequire as __cjsRequire } from 'node:module';
|
|
2
2
|
const require = __cjsRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
applyExifOrientation,
|
|
5
|
+
calculateFitInside,
|
|
6
|
+
decodeBmp,
|
|
7
|
+
decodeGif,
|
|
8
|
+
decodeJpeg,
|
|
9
|
+
decodePng,
|
|
10
|
+
encodeJpeg,
|
|
11
|
+
encodePng,
|
|
12
|
+
probeBufferMeta,
|
|
13
|
+
resizeRgba
|
|
14
|
+
} from "./token-goat-chunk-RRNZMM3A.mjs";
|
|
3
15
|
import {
|
|
4
16
|
BODY_FIRST_TOOL_RESPONSE_KEYS,
|
|
5
17
|
DELIVERS_CONTENT_RE,
|
|
@@ -18,14 +30,14 @@ import {
|
|
|
18
30
|
replaceToolResponseField,
|
|
19
31
|
stripUnsafeSuggestions,
|
|
20
32
|
vscodeNativeToolInput
|
|
21
|
-
} from "./token-goat-chunk-
|
|
33
|
+
} from "./token-goat-chunk-E5TK5DNO.mjs";
|
|
22
34
|
import {
|
|
23
35
|
isRewriteWorthwhile,
|
|
24
36
|
resolveMinNetSavingsBytes
|
|
25
|
-
} from "./token-goat-chunk-
|
|
37
|
+
} from "./token-goat-chunk-ZER6EAXZ.mjs";
|
|
26
38
|
import {
|
|
27
39
|
foldToolName
|
|
28
|
-
} from "./token-goat-chunk-
|
|
40
|
+
} from "./token-goat-chunk-EUSDXRXU.mjs";
|
|
29
41
|
import {
|
|
30
42
|
contentHash,
|
|
31
43
|
getCompactAnySessionSync,
|
|
@@ -34,7 +46,7 @@ import {
|
|
|
34
46
|
loadSessionCache,
|
|
35
47
|
readAllSessionManifests,
|
|
36
48
|
writeSessionManifest
|
|
37
|
-
} from "./token-goat-chunk-
|
|
49
|
+
} from "./token-goat-chunk-H5J3C56Q.mjs";
|
|
38
50
|
import {
|
|
39
51
|
exportSessionState,
|
|
40
52
|
getCompactedAt,
|
|
@@ -56,10 +68,10 @@ import {
|
|
|
56
68
|
wasFileReadThisSession,
|
|
57
69
|
wasFileTruncatedThisSession,
|
|
58
70
|
wasHintShown
|
|
59
|
-
} from "./token-goat-chunk-
|
|
71
|
+
} from "./token-goat-chunk-TDUT2CL6.mjs";
|
|
60
72
|
import {
|
|
61
73
|
claudeConfigDir
|
|
62
|
-
} from "./token-goat-chunk-
|
|
74
|
+
} from "./token-goat-chunk-ONXH6NZ5.mjs";
|
|
63
75
|
import {
|
|
64
76
|
getBashOutput,
|
|
65
77
|
isGeneratedFile,
|
|
@@ -67,14 +79,14 @@ import {
|
|
|
67
79
|
isLockFile,
|
|
68
80
|
isManifestFile,
|
|
69
81
|
storeBashOutputSync
|
|
70
|
-
} from "./token-goat-chunk-
|
|
82
|
+
} from "./token-goat-chunk-O6I2XU4P.mjs";
|
|
71
83
|
import {
|
|
72
84
|
DEFAULT_MAX_AGE_MS,
|
|
73
85
|
sweepCacheRoots
|
|
74
|
-
} from "./token-goat-chunk-
|
|
86
|
+
} from "./token-goat-chunk-D4ETHJD6.mjs";
|
|
75
87
|
import {
|
|
76
88
|
estimateTokens
|
|
77
|
-
} from "./token-goat-chunk-
|
|
89
|
+
} from "./token-goat-chunk-52NSDWYY.mjs";
|
|
78
90
|
import {
|
|
79
91
|
SOURCE_HINT,
|
|
80
92
|
hasPreciseSecret,
|
|
@@ -83,7 +95,7 @@ import {
|
|
|
83
95
|
redactSecrets,
|
|
84
96
|
savedTokensFromBytes,
|
|
85
97
|
summarize
|
|
86
|
-
} from "./token-goat-chunk-
|
|
98
|
+
} from "./token-goat-chunk-CIQ2FTY3.mjs";
|
|
87
99
|
import {
|
|
88
100
|
parse
|
|
89
101
|
} from "./token-goat-chunk-3BTK54F3.mjs";
|
|
@@ -92,6 +104,7 @@ import {
|
|
|
92
104
|
assetEmbedSha,
|
|
93
105
|
deleteFileEmbeddings,
|
|
94
106
|
deleteFileRows,
|
|
107
|
+
disabledStampCount,
|
|
95
108
|
eachUnfencedLine,
|
|
96
109
|
embedTexts,
|
|
97
110
|
embeddingsDepsAvailable,
|
|
@@ -117,13 +130,13 @@ import {
|
|
|
117
130
|
maxChunksEmbedSha,
|
|
118
131
|
parseSourceSymbolsTreeSitterOnly,
|
|
119
132
|
parserFingerprintForLanguage
|
|
120
|
-
} from "./token-goat-chunk-
|
|
133
|
+
} from "./token-goat-chunk-VMFWNHGR.mjs";
|
|
121
134
|
import {
|
|
122
135
|
getFileEntry,
|
|
123
136
|
pathEqClause,
|
|
124
137
|
projectScopeClause,
|
|
125
138
|
querySymbols
|
|
126
|
-
} from "./token-goat-chunk-
|
|
139
|
+
} from "./token-goat-chunk-435UQTKD.mjs";
|
|
127
140
|
import {
|
|
128
141
|
detectLanguage,
|
|
129
142
|
detectLanguageOfFile,
|
|
@@ -131,7 +144,7 @@ import {
|
|
|
131
144
|
getDb,
|
|
132
145
|
languageHasFlag,
|
|
133
146
|
redactIfDotenv
|
|
134
|
-
} from "./token-goat-chunk-
|
|
147
|
+
} from "./token-goat-chunk-7CPMDFGB.mjs";
|
|
135
148
|
import {
|
|
136
149
|
detectHarness,
|
|
137
150
|
fileIsAbsent,
|
|
@@ -144,34 +157,32 @@ import {
|
|
|
144
157
|
makeProjectAt,
|
|
145
158
|
resolveProjectRoot,
|
|
146
159
|
shortFingerprint
|
|
147
|
-
} from "./token-goat-chunk-
|
|
160
|
+
} from "./token-goat-chunk-TGOXNAHW.mjs";
|
|
148
161
|
import {
|
|
149
162
|
registerReset
|
|
150
|
-
} from "./token-goat-chunk-
|
|
163
|
+
} from "./token-goat-chunk-YZAAZU2S.mjs";
|
|
151
164
|
import {
|
|
152
165
|
IDENTICAL_READ_MIN_BODY_BYTES,
|
|
153
166
|
PER_FILE_COUNTERFACTUAL_CEILING,
|
|
154
|
-
VERSION,
|
|
155
167
|
atomicWriteBytes,
|
|
156
168
|
atomicWriteText,
|
|
157
169
|
containsLineRun,
|
|
158
170
|
countNoun,
|
|
159
|
-
dataDir,
|
|
160
171
|
decodeSource,
|
|
161
172
|
ensureDirSync,
|
|
162
173
|
extractErrorMessage,
|
|
163
|
-
foldPath,
|
|
164
|
-
globalDbPath,
|
|
165
|
-
isNodeModulesPath,
|
|
166
174
|
isTestFile,
|
|
167
175
|
isUnderBlockedRoot,
|
|
168
176
|
isWithinQuietHours,
|
|
169
177
|
runGit,
|
|
170
178
|
sanitizeIdForFilename,
|
|
171
179
|
statSize,
|
|
172
|
-
toKB
|
|
173
|
-
|
|
174
|
-
|
|
180
|
+
toKB
|
|
181
|
+
} from "./token-goat-chunk-XYWPOSCN.mjs";
|
|
182
|
+
import {
|
|
183
|
+
foldPath,
|
|
184
|
+
isNodeModulesPath
|
|
185
|
+
} from "./token-goat-chunk-TCQANXYC.mjs";
|
|
175
186
|
import {
|
|
176
187
|
TOOL_RESULTS_ID_CHARS,
|
|
177
188
|
displaySafeJson,
|
|
@@ -185,17 +196,11 @@ import {
|
|
|
185
196
|
toDisplayPath
|
|
186
197
|
} from "./token-goat-chunk-NMTKNYGF.mjs";
|
|
187
198
|
import {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
decodePng,
|
|
194
|
-
encodeJpeg,
|
|
195
|
-
encodePng,
|
|
196
|
-
probeBufferMeta,
|
|
197
|
-
resizeRgba
|
|
198
|
-
} from "./token-goat-chunk-RRNZMM3A.mjs";
|
|
199
|
+
VERSION,
|
|
200
|
+
dataDir,
|
|
201
|
+
globalDbPath,
|
|
202
|
+
tokenGoatHome
|
|
203
|
+
} from "./token-goat-chunk-MELOKFDJ.mjs";
|
|
199
204
|
import {
|
|
200
205
|
init_define_import_meta_env
|
|
201
206
|
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
@@ -772,8 +777,9 @@ registerHook(
|
|
|
772
777
|
},
|
|
773
778
|
{ advisory: true, followsMatcher: true }
|
|
774
779
|
);
|
|
775
|
-
function categoryStats(category) {
|
|
780
|
+
function categoryStats(category, sessionId) {
|
|
776
781
|
const db = getDb(globalDbPath());
|
|
782
|
+
const scope = sessionId === void 0 ? "harness = ?" : "session_id = ?";
|
|
777
783
|
const row = db.prepare(
|
|
778
784
|
// Three populations, deliberately not pooled. `emitted` is what was shown AND could be scored, so it is the only honest denominator for efficacy: including a row nothing could ever have satisfied would divide a real numerator by partly-imaginary rows. `unobservable` was shown but carried no pointer -- it spent bytes and earned no verdict. `detected` was never shown at all (suppressed, or declined by a net-benefit gate) and spent nothing. bytesEmitted and legacyEmissions span every row, which is correct in each case: the unobservable rows really did cost the agent, and the never-displayed ones are zero-byte, so neither distorts the spend figure. COALESCE on the counts that stay `number`: SUM over no rows is NULL where the COUNT(*) this replaced was 0, and an aggregate query always returns its row, so the `?? default` below would not have caught it.
|
|
779
785
|
`SELECT COALESCE(SUM(CASE WHEN displayed = 1 AND observable = 1 THEN 1 ELSE 0 END), 0) AS emitted,
|
|
@@ -782,8 +788,8 @@ function categoryStats(category) {
|
|
|
782
788
|
COALESCE(SUM(CASE WHEN displayed = 0 THEN 1 ELSE 0 END), 0) AS detected,
|
|
783
789
|
SUM(bytes_emitted) AS bytesEmitted,
|
|
784
790
|
SUM(CASE WHEN bytes_emitted IS NULL THEN 1 ELSE 0 END) AS legacyEmissions
|
|
785
|
-
FROM hint_emissions WHERE category = ? AND
|
|
786
|
-
).get(category, getHarnessName());
|
|
791
|
+
FROM hint_emissions WHERE category = ? AND ${scope}`
|
|
792
|
+
).get(category, sessionId ?? getHarnessName());
|
|
787
793
|
return row ?? { emitted: 0, actedOn: 0, unobservable: 0, detected: 0, bytesEmitted: null, legacyEmissions: 0 };
|
|
788
794
|
}
|
|
789
795
|
function shouldSuppress(category, _sessionId) {
|
|
@@ -810,10 +816,10 @@ function manualMarks(category) {
|
|
|
810
816
|
return { effective: 0, ineffective: 0 };
|
|
811
817
|
}
|
|
812
818
|
}
|
|
813
|
-
function getHintStatsSummary() {
|
|
819
|
+
function getHintStatsSummary(sessionId) {
|
|
814
820
|
const probeThresholds = loadConfig().hints.backoff_thresholds.filter((t) => t > 0);
|
|
815
821
|
return HINT_CATEGORIES.map((category) => {
|
|
816
|
-
const { emitted, actedOn, unobservable, detected, bytesEmitted, legacyEmissions } = categoryStats(category);
|
|
822
|
+
const { emitted, actedOn, unobservable, detected, bytesEmitted, legacyEmissions } = categoryStats(category, sessionId);
|
|
817
823
|
const marks = manualMarks(category);
|
|
818
824
|
const suppressed = shouldSuppress(category, "");
|
|
819
825
|
return {
|
|
@@ -833,13 +839,7 @@ function getHintStatsSummary() {
|
|
|
833
839
|
});
|
|
834
840
|
}
|
|
835
841
|
function getHintStatsTotals() {
|
|
836
|
-
const
|
|
837
|
-
const row = db.prepare(
|
|
838
|
-
`SELECT SUM(bytes_emitted) AS spentBytes, SUM(CASE WHEN bytes_emitted IS NULL THEN 1 ELSE 0 END) AS legacyEmissions
|
|
839
|
-
FROM hint_emissions`
|
|
840
|
-
).get();
|
|
841
|
-
const spentBytes = row?.spentBytes ?? null;
|
|
842
|
-
const legacyEmissions = row?.legacyEmissions ?? 0;
|
|
842
|
+
const { spentBytes, legacyEmissions } = getHintSpendTotals();
|
|
843
843
|
const savedBytes = summarize(0).by_source[SOURCE_HINT]?.bytes_saved ?? 0;
|
|
844
844
|
return {
|
|
845
845
|
savedBytes,
|
|
@@ -847,6 +847,14 @@ function getHintStatsTotals() {
|
|
|
847
847
|
legacyEmissions
|
|
848
848
|
};
|
|
849
849
|
}
|
|
850
|
+
function getHintSpendTotals(sessionId) {
|
|
851
|
+
const db = getDb(globalDbPath());
|
|
852
|
+
const sql = `SELECT SUM(bytes_emitted) AS spentBytes, SUM(CASE WHEN bytes_emitted IS NULL THEN 1 ELSE 0 END) AS legacyEmissions
|
|
853
|
+
FROM hint_emissions`;
|
|
854
|
+
const stmt = db.prepare(sessionId === void 0 ? sql : `${sql} WHERE session_id = ?`);
|
|
855
|
+
const row = sessionId === void 0 ? stmt.get() : stmt.get(sessionId);
|
|
856
|
+
return { spentBytes: row?.spentBytes ?? null, legacyEmissions: row?.legacyEmissions ?? 0 };
|
|
857
|
+
}
|
|
850
858
|
function resetHintStats() {
|
|
851
859
|
const db = getDb(globalDbPath());
|
|
852
860
|
db.exec("DELETE FROM hint_emissions");
|
|
@@ -2151,7 +2159,7 @@ ${dataUrl2}`);
|
|
|
2151
2159
|
}
|
|
2152
2160
|
recordStat("image_shrink", shrinkSaved, shrinkTokens, void 0, basename10);
|
|
2153
2161
|
if (loadConfig().image_shrink.ocr_enabled) {
|
|
2154
|
-
const { ocrImage, isTextHeavy, formatOcrSummary } = await import("./token-goat-chunk-
|
|
2162
|
+
const { ocrImage, isTextHeavy, formatOcrSummary } = await import("./token-goat-chunk-FTP4U4QA.mjs");
|
|
2155
2163
|
const ocr = await ocrImage(result.data);
|
|
2156
2164
|
if (ocr !== null && isTextHeavy(ocr, loadConfig().image_shrink.ocr_min_confidence)) {
|
|
2157
2165
|
const emitted = formatOcrSummary(ocr, basename10, result.originalBytes);
|
|
@@ -3664,7 +3672,8 @@ function bumpAndCheckRetry(dir, absPath) {
|
|
|
3664
3672
|
}
|
|
3665
3673
|
return true;
|
|
3666
3674
|
}
|
|
3667
|
-
function appendToDirtyQueue(dir,
|
|
3675
|
+
function appendToDirtyQueue(dir, ...absPaths) {
|
|
3676
|
+
if (absPaths.length === 0) return true;
|
|
3668
3677
|
const queuePath = dirtyQueuePathFor(dir);
|
|
3669
3678
|
try {
|
|
3670
3679
|
ensureDirSync(path10.dirname(queuePath));
|
|
@@ -3674,9 +3683,11 @@ function appendToDirtyQueue(dir, absPath) {
|
|
|
3674
3683
|
if (existing.length > 0 && !existing.endsWith("\n")) leadingNewline = "\n";
|
|
3675
3684
|
} catch {
|
|
3676
3685
|
}
|
|
3677
|
-
fs13.appendFileSync(queuePath, `${leadingNewline}${encodeDirtyQueueLine(
|
|
3678
|
-
`);
|
|
3686
|
+
fs13.appendFileSync(queuePath, `${leadingNewline}${absPaths.map((p) => `${encodeDirtyQueueLine(p)}
|
|
3687
|
+
`).join("")}`);
|
|
3688
|
+
return true;
|
|
3679
3689
|
} catch {
|
|
3690
|
+
return false;
|
|
3680
3691
|
}
|
|
3681
3692
|
}
|
|
3682
3693
|
function requeueDirtyPath(dir, absPath) {
|
|
@@ -3975,6 +3986,32 @@ var WorkerAlreadyRunningError = class extends Error {
|
|
|
3975
3986
|
this.name = "WorkerAlreadyRunningError";
|
|
3976
3987
|
}
|
|
3977
3988
|
};
|
|
3989
|
+
var WorkerDataDirUnwritableError = class extends Error {
|
|
3990
|
+
constructor(dir, cause) {
|
|
3991
|
+
super(`the data directory ${displaySafeText(dir)} cannot be written (${extractErrorMessage(cause)}), and the worker keeps its pid file, queue and index there; make it writable and run \`token-goat worker start\` again`, { cause });
|
|
3992
|
+
this.name = "WorkerDataDirUnwritableError";
|
|
3993
|
+
}
|
|
3994
|
+
};
|
|
3995
|
+
function dataDirWriteRefusal(dir) {
|
|
3996
|
+
const probe = path10.join(dir, `.write-probe-${process.pid}`);
|
|
3997
|
+
try {
|
|
3998
|
+
fs13.writeFileSync(probe, "");
|
|
3999
|
+
} catch (e) {
|
|
4000
|
+
return e;
|
|
4001
|
+
}
|
|
4002
|
+
try {
|
|
4003
|
+
fs13.rmSync(probe, { force: true });
|
|
4004
|
+
} catch {
|
|
4005
|
+
}
|
|
4006
|
+
return void 0;
|
|
4007
|
+
}
|
|
4008
|
+
function discardSpawnedWorker(child, pid) {
|
|
4009
|
+
try {
|
|
4010
|
+
process.kill(pid);
|
|
4011
|
+
} catch {
|
|
4012
|
+
}
|
|
4013
|
+
child.unref();
|
|
4014
|
+
}
|
|
3978
4015
|
function claimWorkerPidFile(dir, pid) {
|
|
3979
4016
|
const pidPath = workerPidPath(dir);
|
|
3980
4017
|
try {
|
|
@@ -4054,6 +4091,8 @@ function startDetachedWorker(opts) {
|
|
|
4054
4091
|
} catch (e) {
|
|
4055
4092
|
if (e.code !== "EEXIST" || !fs13.existsSync(dir)) throw e;
|
|
4056
4093
|
}
|
|
4094
|
+
const refusal = dataDirWriteRefusal(dir);
|
|
4095
|
+
if (refusal !== void 0) throw new WorkerDataDirUnwritableError(dir, refusal);
|
|
4057
4096
|
const child = spawn(
|
|
4058
4097
|
process.execPath,
|
|
4059
4098
|
[daemonEntryScript(), "--worker-daemon"],
|
|
@@ -4072,12 +4111,15 @@ function startDetachedWorker(opts) {
|
|
|
4072
4111
|
if (pid === void 0) {
|
|
4073
4112
|
throw new Error("startDetachedWorker: spawn produced no pid");
|
|
4074
4113
|
}
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4114
|
+
let claimed;
|
|
4115
|
+
try {
|
|
4116
|
+
claimed = claimWorkerPidFile(dir, pid);
|
|
4117
|
+
} catch (e) {
|
|
4118
|
+
discardSpawnedWorker(child, pid);
|
|
4119
|
+
throw e;
|
|
4120
|
+
}
|
|
4121
|
+
if (!claimed) {
|
|
4122
|
+
discardSpawnedWorker(child, pid);
|
|
4081
4123
|
throw new WorkerAlreadyRunningError();
|
|
4082
4124
|
}
|
|
4083
4125
|
try {
|
|
@@ -4090,12 +4132,39 @@ function startDetachedWorker(opts) {
|
|
|
4090
4132
|
var KNOWN_ROOTS_SWEEP_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
4091
4133
|
var IDLE_VACUUM_INTERVAL_MS = 6 * 60 * 60 * 1e3;
|
|
4092
4134
|
var IDLE_VACUUM_COOLDOWN_MS = 5 * 60 * 1e3;
|
|
4135
|
+
var EMBED_BACKLOG_BATCH = 50;
|
|
4136
|
+
var EMBED_BACKLOG_SCAN = 1e3;
|
|
4137
|
+
function requeueStaleEmbeddings(dir, cursor) {
|
|
4138
|
+
const indexing = loadConfig().indexing;
|
|
4139
|
+
const db = getDb(path10.join(dir, "global.db"));
|
|
4140
|
+
const symbolOnlyKb = indexing?.large_file_symbol_only_kb ?? 0;
|
|
4141
|
+
const maxChunks = indexing?.max_chunks_per_file ?? 0;
|
|
4142
|
+
const rows = db.prepare("SELECT path, sha, embed_sha FROM files WHERE path > ? ORDER BY path LIMIT ?").all(cursor, EMBED_BACKLOG_SCAN);
|
|
4143
|
+
const owed = [];
|
|
4144
|
+
let resumeAfter = null;
|
|
4145
|
+
for (const row of rows) {
|
|
4146
|
+
resumeAfter = row.path;
|
|
4147
|
+
if (isUnderSystemTemp(row.path) || isEmbedFresh(row.embed_sha ?? void 0, row.sha, true, true, symbolOnlyKb, maxChunks)) continue;
|
|
4148
|
+
if (fileIsAbsent(row.path)) continue;
|
|
4149
|
+
owed.push(row.path);
|
|
4150
|
+
if (owed.length === EMBED_BACKLOG_BATCH) break;
|
|
4151
|
+
}
|
|
4152
|
+
if (!appendToDirtyQueue(dir, ...owed)) return cursor;
|
|
4153
|
+
return owed.length === EMBED_BACKLOG_BATCH || rows.length === EMBED_BACKLOG_SCAN ? resumeAfter : null;
|
|
4154
|
+
}
|
|
4155
|
+
function embeddingsReady(dir) {
|
|
4156
|
+
const dbPath = path10.join(dir, "global.db");
|
|
4157
|
+
return fs13.existsSync(dbPath) && loadConfig().indexing?.embeddings_enabled !== false && embeddingsDepsAvailable(getDb(dbPath));
|
|
4158
|
+
}
|
|
4093
4159
|
async function runWorkerLoop(dir, pollIntervalMs, shouldStop = () => false) {
|
|
4094
4160
|
await loadRegexExtractors();
|
|
4095
4161
|
let lastSnapshotCleanupMs = 0;
|
|
4096
4162
|
let lastKnownRootsSweepMs = 0;
|
|
4097
4163
|
let lastIdleVacuumMs = 0;
|
|
4098
4164
|
let lastActiveMs = Date.now();
|
|
4165
|
+
let embedBacklogCursor = "";
|
|
4166
|
+
let embeddingsWereReady = true;
|
|
4167
|
+
let disabledStampsSeen = disabledStampCount();
|
|
4099
4168
|
let ownedPidFile = false;
|
|
4100
4169
|
while (!shouldStop()) {
|
|
4101
4170
|
if (!fs13.existsSync(dir)) break;
|
|
@@ -4109,6 +4178,16 @@ async function runWorkerLoop(dir, pollIntervalMs, shouldStop = () => false) {
|
|
|
4109
4178
|
}
|
|
4110
4179
|
if (processed > 0) {
|
|
4111
4180
|
lastActiveMs = Date.now();
|
|
4181
|
+
} else if (inFlightEmbeddings.size === 0) {
|
|
4182
|
+
try {
|
|
4183
|
+
const ready = embeddingsReady(dir);
|
|
4184
|
+
const stamps = disabledStampCount();
|
|
4185
|
+
if (ready && (!embeddingsWereReady || stamps !== disabledStampsSeen)) embedBacklogCursor = "";
|
|
4186
|
+
embeddingsWereReady = ready;
|
|
4187
|
+
if (ready) disabledStampsSeen = stamps;
|
|
4188
|
+
if (ready && embedBacklogCursor !== null) embedBacklogCursor = requeueStaleEmbeddings(dir, embedBacklogCursor);
|
|
4189
|
+
} catch {
|
|
4190
|
+
}
|
|
4112
4191
|
}
|
|
4113
4192
|
if (Date.now() - lastSnapshotCleanupMs >= SNAPSHOT_CLEANUP_INTERVAL_MS) {
|
|
4114
4193
|
try {
|
|
@@ -4220,7 +4299,18 @@ function appendDirtyPaths(normalizedPaths) {
|
|
|
4220
4299
|
}
|
|
4221
4300
|
const body = normalizedPaths.map((p) => `${encodeDirtyQueueLine(p)}
|
|
4222
4301
|
`).join("");
|
|
4223
|
-
|
|
4302
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
4303
|
+
if (appendToLiveQueue(queuePath, `${dirtyQueueLeadingNewline(queuePath)}${body}`)) return;
|
|
4304
|
+
}
|
|
4305
|
+
}
|
|
4306
|
+
function appendToLiveQueue(queuePath, data) {
|
|
4307
|
+
const fd = fs14.openSync(queuePath, "a");
|
|
4308
|
+
try {
|
|
4309
|
+
fs14.writeFileSync(fd, data);
|
|
4310
|
+
return fs14.statSync(queuePath, { bigint: true, throwIfNoEntry: false })?.ino === fs14.fstatSync(fd, { bigint: true }).ino;
|
|
4311
|
+
} finally {
|
|
4312
|
+
fs14.closeSync(fd);
|
|
4313
|
+
}
|
|
4224
4314
|
}
|
|
4225
4315
|
function appendDirtyPath(normalizedPath) {
|
|
4226
4316
|
appendDirtyPaths([normalizedPath]);
|
|
@@ -4573,6 +4663,14 @@ function isSessionArtifactFile(filePath) {
|
|
|
4573
4663
|
if (new RegExp("[/\\\\]tool-results[/\\\\]" + TOOL_RESULTS_ID_CHARS + "\\.txt$", "i").test(filePath)) return true;
|
|
4574
4664
|
return false;
|
|
4575
4665
|
}
|
|
4666
|
+
function lineWindowBytes(filePath, offset, limit) {
|
|
4667
|
+
try {
|
|
4668
|
+
const lines = fs15.readFileSync(filePath, "utf-8").split("\n").slice(offset - 1, offset - 1 + limit);
|
|
4669
|
+
return lines.reduce((sum, line) => sum + Buffer.byteLength(line, "utf-8") + 1, 0);
|
|
4670
|
+
} catch {
|
|
4671
|
+
return Infinity;
|
|
4672
|
+
}
|
|
4673
|
+
}
|
|
4576
4674
|
function sessionArtifactRecall(rawPath) {
|
|
4577
4675
|
const filePath = displaySafePath(rawPath);
|
|
4578
4676
|
return 'Use `token-goat bash-output --file "' + filePath + '" --tail 50` (or `--grep PATTERN`) to read a slice instead of the full file.';
|
|
@@ -5110,14 +5208,17 @@ function preReadHandlerInner(event) {
|
|
|
5110
5208
|
const isTaskOutput = /[/\\]tasks[/\\][a-z0-9]+\.output$/i.test(normalized);
|
|
5111
5209
|
const label = isTaskOutput ? "Session transcript" : "Tool-result file";
|
|
5112
5210
|
const outputSize = statSize(normalized);
|
|
5113
|
-
|
|
5114
|
-
|
|
5211
|
+
const window = readRequestedSliceWindow(event);
|
|
5212
|
+
const windowBytes = window.limit === void 0 ? void 0 : lineWindowBytes(normalized, window.offset ?? 1, window.limit);
|
|
5213
|
+
if (outputSize !== null && outputSize >= TASK_OUTPUT_DENY_BYTES && (windowBytes === void 0 || windowBytes >= TASK_OUTPUT_DENY_BYTES)) {
|
|
5115
5214
|
const artifactDenyCredit = counterfactualCredit(outputSize);
|
|
5116
5215
|
recordStat("session_hint", artifactDenyCredit, savedTokensFromBytes(artifactDenyCredit), void 0, "artifact-large-deny");
|
|
5216
|
+
const windowNote = windowBytes === void 0 || window.limit === void 0 || !Number.isFinite(windowBytes) ? "" : " Lines " + (window.offset ?? 1) + "-" + ((window.offset ?? 1) + window.limit - 1) + " span " + toKB(windowBytes) + "KB.";
|
|
5117
5217
|
return denyOutput(
|
|
5118
|
-
label + " is large (" + toKB(outputSize) + "KB). " + sessionArtifactRecall(normalized)
|
|
5218
|
+
label + " is large (" + toKB(outputSize) + "KB)." + windowNote + " " + sessionArtifactRecall(normalized) + " A Read with `offset` and `limit` spanning under " + toKB(TASK_OUTPUT_DENY_BYTES) + "KB goes through."
|
|
5119
5219
|
);
|
|
5120
5220
|
}
|
|
5221
|
+
recordActualRead(event, normalized);
|
|
5121
5222
|
return quietContextOutput(label + ": " + sessionArtifactRecall(normalized));
|
|
5122
5223
|
}
|
|
5123
5224
|
}
|
|
@@ -6910,6 +7011,7 @@ export {
|
|
|
6910
7011
|
meetsSavingsFloor,
|
|
6911
7012
|
getHintStatsSummary,
|
|
6912
7013
|
getHintStatsTotals,
|
|
7014
|
+
getHintSpendTotals,
|
|
6913
7015
|
resetHintStats,
|
|
6914
7016
|
markCategoryEffective,
|
|
6915
7017
|
markCategoryIneffective,
|
|
@@ -6922,7 +7024,9 @@ export {
|
|
|
6922
7024
|
servedRunNotice,
|
|
6923
7025
|
planServedElisions,
|
|
6924
7026
|
LARGE_SYMBOL_LINE_THRESHOLD,
|
|
7027
|
+
SLICE_ESTIMATE_SCAN_CAP_BYTES,
|
|
6925
7028
|
buildLineDiff,
|
|
7029
|
+
countTextLines,
|
|
6926
7030
|
visionTokens,
|
|
6927
7031
|
visionTokensSaved,
|
|
6928
7032
|
visionTokensSavedByText,
|
|
@@ -6963,6 +7067,7 @@ export {
|
|
|
6963
7067
|
ensureWorkerAlive,
|
|
6964
7068
|
stopWorker,
|
|
6965
7069
|
WorkerAlreadyRunningError,
|
|
7070
|
+
dataDirWriteRefusal,
|
|
6966
7071
|
startDetachedWorker,
|
|
6967
7072
|
runDetachedWorkerDaemon,
|
|
6968
7073
|
appendDirtyPath,
|