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.
- package/README.md +30 -88
- package/SECURITY.md +14 -0
- package/dist/{token-goat-chunk-OZRSREKR.mjs → token-goat-chunk-2AWQ2R5X.mjs} +2 -2
- package/dist/{token-goat-chunk-BH4ZVRB2.mjs → token-goat-chunk-2NNUA2LR.mjs} +4 -4
- package/dist/token-goat-chunk-2WOUYWLM.mjs +955 -0
- package/dist/{token-goat-chunk-IKZLSRII.mjs → token-goat-chunk-435UQTKD.mjs} +5 -3
- package/dist/{token-goat-chunk-62IHOU6L.mjs → token-goat-chunk-44BM7DDQ.mjs} +5 -3
- package/dist/token-goat-chunk-52NSDWYY.mjs +96 -0
- package/dist/{token-goat-chunk-CXBOFPF4.mjs → token-goat-chunk-67BNIKKO.mjs} +32 -18
- package/dist/{token-goat-chunk-XBESNWEX.mjs → token-goat-chunk-6AK46ZT7.mjs} +2 -3
- package/dist/{token-goat-chunk-7SXPJOSZ.mjs → token-goat-chunk-7CPMDFGB.mjs} +166 -40
- package/dist/token-goat-chunk-ASLWOQ3I.mjs +14 -0
- package/dist/{token-goat-chunk-MWID3YOY.mjs → token-goat-chunk-BGYOZ6DO.mjs} +6 -4
- package/dist/{token-goat-chunk-PAV6NNY7.mjs → token-goat-chunk-C5YPNZKQ.mjs} +22 -8
- package/dist/{token-goat-chunk-D2X7XN5M.mjs → token-goat-chunk-CIQ2FTY3.mjs} +23 -242
- package/dist/token-goat-chunk-D4ETHJD6.mjs +246 -0
- package/dist/{token-goat-chunk-7Y6GWTII.mjs → token-goat-chunk-DNRPXHYH.mjs} +25 -17
- package/dist/{token-goat-chunk-L43RKNHA.mjs → token-goat-chunk-DNSPXQXQ.mjs} +2 -2
- package/dist/token-goat-chunk-DPNLUJWB.mjs +220 -0
- package/dist/token-goat-chunk-E4ZOJIZK.mjs +1382 -0
- package/dist/token-goat-chunk-E5TK5DNO.mjs +718 -0
- package/dist/{token-goat-chunk-VVROQBQJ.mjs → token-goat-chunk-EUSDXRXU.mjs} +62 -12
- package/dist/{token-goat-chunk-POOI26O6.mjs → token-goat-chunk-FTP4U4QA.mjs} +12 -8
- package/dist/token-goat-chunk-G23DWHV4.mjs +142 -0
- package/dist/{token-goat-chunk-MDV5VWF4.mjs → token-goat-chunk-G7IWXCFF.mjs} +223 -15
- package/dist/{token-goat-chunk-C2PG4K5D.mjs → token-goat-chunk-GLXRTTLE.mjs} +7 -5
- package/dist/{token-goat-chunk-M6CVNHTW.mjs → token-goat-chunk-H5J3C56Q.mjs} +95 -573
- package/dist/{token-goat-chunk-BAWKGODL.mjs → token-goat-chunk-HNFZZHFW.mjs} +2 -2
- package/dist/{token-goat-chunk-TG5ZPD6B.mjs → token-goat-chunk-HUYUHODZ.mjs} +1036 -759
- package/dist/token-goat-chunk-IVE6U7KV.mjs +53 -0
- package/dist/{token-goat-chunk-ZZT6PVB3.mjs → token-goat-chunk-IVWI2OCK.mjs} +72 -45
- package/dist/{token-goat-chunk-GMOUBOX4.mjs → token-goat-chunk-JTKCQMQA.mjs} +37 -5
- package/dist/{token-goat-chunk-H2CPLEMP.mjs → token-goat-chunk-KOPIR3KZ.mjs} +46 -23
- package/dist/token-goat-chunk-L7H3U27L.mjs +35 -0
- package/dist/{token-goat-chunk-FLEYOCAS.mjs → token-goat-chunk-LZNBQTDK.mjs} +6 -4
- package/dist/token-goat-chunk-MELOKFDJ.mjs +199 -0
- package/dist/{token-goat-chunk-RH27ZSPF.mjs → token-goat-chunk-NMBWLRHW.mjs} +164 -50
- package/dist/{token-goat-chunk-43JFN26X.mjs → token-goat-chunk-O6I2XU4P.mjs} +27 -967
- package/dist/{token-goat-chunk-G6EYO5CD.mjs → token-goat-chunk-ONXH6NZ5.mjs} +2 -87
- package/dist/token-goat-chunk-ORNFMIER.mjs +295 -0
- package/dist/{token-goat-chunk-LHUP4DXZ.mjs → token-goat-chunk-PGTH2U4C.mjs} +1 -1
- package/dist/{token-goat-chunk-5BQ7W7D7.mjs → token-goat-chunk-PKRWMHVP.mjs} +76 -59
- package/dist/{token-goat-chunk-DA43OE7L.mjs → token-goat-chunk-PQ53BSCF.mjs} +1 -1
- package/dist/{token-goat-chunk-STYRLQIW.mjs → token-goat-chunk-PYSUADX4.mjs} +2 -2
- package/dist/{token-goat-chunk-JALB3KWJ.mjs → token-goat-chunk-QO3LXVVR.mjs} +4247 -5005
- package/dist/{token-goat-chunk-L45IWWMC.mjs → token-goat-chunk-RLP6J7WR.mjs} +6 -6
- package/dist/token-goat-chunk-RQGGMPCR.mjs +205 -0
- package/dist/{token-goat-chunk-MBDJR6HU.mjs → token-goat-chunk-RTMVLHWX.mjs} +3708 -4003
- 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-TDUT2CL6.mjs +564 -0
- package/dist/{token-goat-chunk-LRIZ7K3F.mjs → token-goat-chunk-TGOXNAHW.mjs} +54 -111
- package/dist/{token-goat-chunk-WNBSCSAI.mjs → token-goat-chunk-UA5BKWWQ.mjs} +1 -1
- package/dist/{token-goat-chunk-RIB6XY2V.mjs → token-goat-chunk-UXSXQQIY.mjs} +1 -1
- package/dist/{token-goat-chunk-7EPYB34H.mjs → token-goat-chunk-VMFWNHGR.mjs} +84 -73
- package/dist/token-goat-chunk-VQ6F6T7X.mjs +36 -0
- package/dist/{token-goat-chunk-5M3NRJD2.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-6E2IDLHF.mjs → token-goat-chunk-XYWPOSCN.mjs} +57 -615
- package/dist/{token-goat-chunk-CQHY4SL7.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-4GEDH2WU.mjs → token-goat-chunk-ZER6EAXZ.mjs} +81 -70
- 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 -21
- package/dist/token-goat.core.mjs +9 -39
- package/docs/C4_RUNTIME_ARCHITECTURE.md +2 -2
- package/docs/cli.md +35 -23
- package/docs/install.md +18 -14
- package/package.json +1 -1
- package/dist/token-goat-chunk-ADMR3QVF.mjs +0 -41
- package/dist/token-goat-chunk-E6B2UFDF.mjs +0 -30
- package/dist/token-goat-chunk-GKZ2US5B.mjs +0 -187
- package/dist/token-goat-chunk-MZTO4FXH.mjs +0 -26
|
@@ -0,0 +1,564 @@
|
|
|
1
|
+
import { createRequire as __cjsRequire } from 'node:module';
|
|
2
|
+
const require = __cjsRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
redactSecrets
|
|
5
|
+
} from "./token-goat-chunk-CIQ2FTY3.mjs";
|
|
6
|
+
import {
|
|
7
|
+
shortFingerprint
|
|
8
|
+
} from "./token-goat-chunk-TGOXNAHW.mjs";
|
|
9
|
+
import {
|
|
10
|
+
registerReset
|
|
11
|
+
} from "./token-goat-chunk-YZAAZU2S.mjs";
|
|
12
|
+
import {
|
|
13
|
+
foldPath
|
|
14
|
+
} from "./token-goat-chunk-TCQANXYC.mjs";
|
|
15
|
+
import {
|
|
16
|
+
normalizePath
|
|
17
|
+
} from "./token-goat-chunk-NMTKNYGF.mjs";
|
|
18
|
+
import {
|
|
19
|
+
init_define_import_meta_env
|
|
20
|
+
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
21
|
+
|
|
22
|
+
// src/session.ts
|
|
23
|
+
init_define_import_meta_env();
|
|
24
|
+
import { randomBytes, randomUUID } from "node:crypto";
|
|
25
|
+
import * as fs from "node:fs";
|
|
26
|
+
var _files = /* @__PURE__ */ new Map();
|
|
27
|
+
var _filesAtLoad = /* @__PURE__ */ new Map();
|
|
28
|
+
var _filesFullReadCountAtLoad = /* @__PURE__ */ new Map();
|
|
29
|
+
var _hintsShown = /* @__PURE__ */ new Set();
|
|
30
|
+
var _scheduledPromptCounts = /* @__PURE__ */ new Map();
|
|
31
|
+
var _webFetches = /* @__PURE__ */ new Map();
|
|
32
|
+
var _bashOutputs = /* @__PURE__ */ new Map();
|
|
33
|
+
var _grepQueries = /* @__PURE__ */ new Map();
|
|
34
|
+
var _globQueries = /* @__PURE__ */ new Map();
|
|
35
|
+
var _lastTabContext = null;
|
|
36
|
+
var _seenImageHashes = [];
|
|
37
|
+
var _outstandingAgentSpawns = [];
|
|
38
|
+
var _outstandingAgentSpawnsAtLoad = [];
|
|
39
|
+
var _bashReruns = /* @__PURE__ */ new Set();
|
|
40
|
+
var _curlDownloads = /* @__PURE__ */ new Map();
|
|
41
|
+
var _curlDownloadsAtLoad = /* @__PURE__ */ new Map();
|
|
42
|
+
var _fileLineRanges = /* @__PURE__ */ new Map();
|
|
43
|
+
var _fileServedOutputs = /* @__PURE__ */ new Map();
|
|
44
|
+
var _fileLineRangesAtLoad = /* @__PURE__ */ new Map();
|
|
45
|
+
var _fileServedOutputsAtLoad = /* @__PURE__ */ new Map();
|
|
46
|
+
var _compactedAt = 0;
|
|
47
|
+
var _cliReads = /* @__PURE__ */ new Set();
|
|
48
|
+
var _pendingLargeFileHints = /* @__PURE__ */ new Map();
|
|
49
|
+
var _pendingLargeFileHintsAtLoad = /* @__PURE__ */ new Map();
|
|
50
|
+
var _sessionId = null;
|
|
51
|
+
var _transcriptPath = null;
|
|
52
|
+
function fileSize(absPath) {
|
|
53
|
+
try {
|
|
54
|
+
return fs.statSync(absPath).size;
|
|
55
|
+
} catch {
|
|
56
|
+
return 0;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function resolveFilesKey(normalized) {
|
|
60
|
+
if (_files.has(normalized)) return normalized;
|
|
61
|
+
const folded = foldPath(normalized);
|
|
62
|
+
if (folded === normalized) return normalized;
|
|
63
|
+
for (const existingKey of _files.keys()) {
|
|
64
|
+
if (foldPath(existingKey) === folded) return existingKey;
|
|
65
|
+
}
|
|
66
|
+
return normalized;
|
|
67
|
+
}
|
|
68
|
+
function recordFileRead(filePath, isFullRead = true) {
|
|
69
|
+
const normalized = normalizePath(filePath);
|
|
70
|
+
const key = resolveFilesKey(normalized);
|
|
71
|
+
const now = Date.now();
|
|
72
|
+
const size = fileSize(normalized);
|
|
73
|
+
const prev = _files.get(key);
|
|
74
|
+
if (prev === void 0) {
|
|
75
|
+
_files.set(key, {
|
|
76
|
+
path: key,
|
|
77
|
+
readCount: 1,
|
|
78
|
+
lastReadAt: now,
|
|
79
|
+
wasEdited: false,
|
|
80
|
+
sizeBytes: size,
|
|
81
|
+
...isFullRead ? { lastFullReadAt: now, fullReadCount: 1 } : {}
|
|
82
|
+
});
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
_files.set(key, {
|
|
86
|
+
...prev,
|
|
87
|
+
readCount: prev.readCount + 1,
|
|
88
|
+
lastReadAt: now,
|
|
89
|
+
sizeBytes: size,
|
|
90
|
+
...isFullRead ? { lastFullReadAt: now, fullReadCount: (prev.fullReadCount ?? 0) + 1 } : {}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
var MAX_SYMBOLS_PER_FILE = 25;
|
|
94
|
+
function recordSymbolRead(filePath, symbol) {
|
|
95
|
+
const normalized = normalizePath(filePath);
|
|
96
|
+
const key = resolveFilesKey(normalized);
|
|
97
|
+
const prev = _files.get(key);
|
|
98
|
+
if (prev === void 0) {
|
|
99
|
+
_files.set(key, {
|
|
100
|
+
path: key,
|
|
101
|
+
readCount: 0,
|
|
102
|
+
lastReadAt: Date.now(),
|
|
103
|
+
wasEdited: false,
|
|
104
|
+
sizeBytes: fileSize(normalized),
|
|
105
|
+
symbols_read: [symbol]
|
|
106
|
+
});
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const existing = prev.symbols_read ?? [];
|
|
110
|
+
if (existing.includes(symbol)) return;
|
|
111
|
+
const symbols_read = [...existing, symbol].slice(-MAX_SYMBOLS_PER_FILE);
|
|
112
|
+
_files.set(key, { ...prev, symbols_read });
|
|
113
|
+
}
|
|
114
|
+
function filesReadCountAtLoad() {
|
|
115
|
+
return _filesAtLoad;
|
|
116
|
+
}
|
|
117
|
+
function filesFullReadCountAtLoad() {
|
|
118
|
+
return _filesFullReadCountAtLoad;
|
|
119
|
+
}
|
|
120
|
+
function recordFileEdit(filePath) {
|
|
121
|
+
const normalized = normalizePath(filePath);
|
|
122
|
+
const key = resolveFilesKey(normalized);
|
|
123
|
+
_fileLineRanges.delete(foldPath(normalized));
|
|
124
|
+
const prev = _files.get(key);
|
|
125
|
+
if (prev === void 0) {
|
|
126
|
+
_files.set(key, {
|
|
127
|
+
path: key,
|
|
128
|
+
readCount: 0,
|
|
129
|
+
lastReadAt: 0,
|
|
130
|
+
wasEdited: true,
|
|
131
|
+
sizeBytes: fileSize(normalized)
|
|
132
|
+
});
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
_files.set(key, { ...prev, wasEdited: true });
|
|
136
|
+
}
|
|
137
|
+
function getSessionFiles() {
|
|
138
|
+
return _files;
|
|
139
|
+
}
|
|
140
|
+
function wasFileReadThisSession(filePath) {
|
|
141
|
+
const entry = _files.get(resolveFilesKey(normalizePath(filePath)));
|
|
142
|
+
return entry !== void 0 && entry.readCount > 0 && entry.lastReadAt >= _compactedAt;
|
|
143
|
+
}
|
|
144
|
+
function wasFileFullyReadThisSession(filePath) {
|
|
145
|
+
const entry = _files.get(resolveFilesKey(normalizePath(filePath)));
|
|
146
|
+
return entry !== void 0 && entry.lastFullReadAt !== void 0 && entry.lastFullReadAt >= _compactedAt;
|
|
147
|
+
}
|
|
148
|
+
function getCompactedAt() {
|
|
149
|
+
return _compactedAt;
|
|
150
|
+
}
|
|
151
|
+
function markCompacted(now = Date.now()) {
|
|
152
|
+
if (now <= _compactedAt) return;
|
|
153
|
+
_compactedAt = now;
|
|
154
|
+
_fileLineRanges = /* @__PURE__ */ new Map();
|
|
155
|
+
_fileServedOutputs = /* @__PURE__ */ new Map();
|
|
156
|
+
}
|
|
157
|
+
function getSessionFileEntry(filePath) {
|
|
158
|
+
return _files.get(resolveFilesKey(normalizePath(filePath)));
|
|
159
|
+
}
|
|
160
|
+
function wasHintShown(hintKey) {
|
|
161
|
+
return _hintsShown.has(hintKey);
|
|
162
|
+
}
|
|
163
|
+
function markHintShown(hintKey) {
|
|
164
|
+
_hintsShown.add(hintKey);
|
|
165
|
+
}
|
|
166
|
+
function recordScheduledPrompt(sessionId) {
|
|
167
|
+
const count = (_scheduledPromptCounts.get(sessionId) ?? 0) + 1;
|
|
168
|
+
_scheduledPromptCounts.set(sessionId, count);
|
|
169
|
+
return count;
|
|
170
|
+
}
|
|
171
|
+
function wasCliReadThisSession(cliReadKey) {
|
|
172
|
+
return _cliReads.has(cliReadKey);
|
|
173
|
+
}
|
|
174
|
+
function recordCliRead(cliReadKey) {
|
|
175
|
+
_cliReads.add(cliReadKey);
|
|
176
|
+
}
|
|
177
|
+
function recordLargeFileHintPending(filePath, sizeBytes) {
|
|
178
|
+
_pendingLargeFileHints.set(foldPath(normalizePath(filePath)), sizeBytes);
|
|
179
|
+
}
|
|
180
|
+
function takePendingLargeFileHint(filePath) {
|
|
181
|
+
const key = foldPath(normalizePath(filePath));
|
|
182
|
+
const size = _pendingLargeFileHints.get(key);
|
|
183
|
+
if (size === void 0) return null;
|
|
184
|
+
_pendingLargeFileHints.delete(key);
|
|
185
|
+
return size;
|
|
186
|
+
}
|
|
187
|
+
function consumedPendingLargeFileHintKeys() {
|
|
188
|
+
const consumed = [];
|
|
189
|
+
for (const key of _pendingLargeFileHintsAtLoad.keys()) {
|
|
190
|
+
if (!_pendingLargeFileHints.has(key)) consumed.push(key);
|
|
191
|
+
}
|
|
192
|
+
return consumed;
|
|
193
|
+
}
|
|
194
|
+
function pendingLargeFileHintsAtLoad() {
|
|
195
|
+
return _pendingLargeFileHintsAtLoad;
|
|
196
|
+
}
|
|
197
|
+
var WEB_FETCH_KEY_SEP = "\0";
|
|
198
|
+
function webFetchKey(url, prompt) {
|
|
199
|
+
const digest = shortFingerprint(`${url}${WEB_FETCH_KEY_SEP}${prompt}`);
|
|
200
|
+
return [redactSecrets(url).text, redactSecrets(prompt).text, digest].join(WEB_FETCH_KEY_SEP);
|
|
201
|
+
}
|
|
202
|
+
function recordWebFetch(url, prompt, cacheId) {
|
|
203
|
+
_webFetches.set(webFetchKey(url, prompt), cacheId);
|
|
204
|
+
}
|
|
205
|
+
function migrateCurlDownloadKey(key) {
|
|
206
|
+
if (/^[0-9a-f]{16}$/.test(key)) return key;
|
|
207
|
+
return curlDownloadKey(key);
|
|
208
|
+
}
|
|
209
|
+
function migrateWebFetchKey(key) {
|
|
210
|
+
const parts = key.split(WEB_FETCH_KEY_SEP);
|
|
211
|
+
if (parts.length !== 2) return key;
|
|
212
|
+
return webFetchKey(parts[0] ?? "", parts[1] ?? "");
|
|
213
|
+
}
|
|
214
|
+
function getSessionWebFetches() {
|
|
215
|
+
return _webFetches;
|
|
216
|
+
}
|
|
217
|
+
function recordBashOutput(commandHash, outputId, _sizeBytes) {
|
|
218
|
+
_bashOutputs.set(commandHash, outputId);
|
|
219
|
+
}
|
|
220
|
+
function getSessionBashOutputs() {
|
|
221
|
+
return Array.from(_bashOutputs.entries());
|
|
222
|
+
}
|
|
223
|
+
function recordBashRerun(commandHash) {
|
|
224
|
+
_bashReruns.add(commandHash);
|
|
225
|
+
}
|
|
226
|
+
function getSessionBashReruns() {
|
|
227
|
+
return Array.from(_bashReruns);
|
|
228
|
+
}
|
|
229
|
+
function getBashOutputId(commandHash) {
|
|
230
|
+
return _bashOutputs.get(commandHash) ?? null;
|
|
231
|
+
}
|
|
232
|
+
function recordGrepQuery(signature, matchCount) {
|
|
233
|
+
_grepQueries.set(signature, matchCount);
|
|
234
|
+
}
|
|
235
|
+
function getGrepMatchCount(signature) {
|
|
236
|
+
return _grepQueries.get(signature) ?? null;
|
|
237
|
+
}
|
|
238
|
+
function recordGlobQuery(signature, matchCount) {
|
|
239
|
+
_globQueries.set(signature, matchCount);
|
|
240
|
+
}
|
|
241
|
+
function getGlobMatchCount(signature) {
|
|
242
|
+
return _globQueries.get(signature) ?? null;
|
|
243
|
+
}
|
|
244
|
+
function setLastTabContext(text) {
|
|
245
|
+
_lastTabContext = shortFingerprint(text);
|
|
246
|
+
}
|
|
247
|
+
function lastTabContextMatches(text) {
|
|
248
|
+
return _lastTabContext !== null && _lastTabContext === shortFingerprint(text);
|
|
249
|
+
}
|
|
250
|
+
var MAX_SEEN_IMAGE_HASHES = 16;
|
|
251
|
+
function hasSeenImage(hash) {
|
|
252
|
+
return _seenImageHashes.includes(hash);
|
|
253
|
+
}
|
|
254
|
+
function recordSeenImage(hash) {
|
|
255
|
+
const at = _seenImageHashes.indexOf(hash);
|
|
256
|
+
if (at !== -1) _seenImageHashes.splice(at, 1);
|
|
257
|
+
_seenImageHashes.push(hash);
|
|
258
|
+
if (_seenImageHashes.length > MAX_SEEN_IMAGE_HASHES) {
|
|
259
|
+
_seenImageHashes.splice(0, _seenImageHashes.length - MAX_SEEN_IMAGE_HASHES);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
var MAX_OUTSTANDING_AGENT_SPAWNS = 30;
|
|
263
|
+
function recordOutstandingAgentSpawn(prompt) {
|
|
264
|
+
_outstandingAgentSpawns.push({ prompt: redactSecrets(prompt).text, ts: Date.now() });
|
|
265
|
+
if (_outstandingAgentSpawns.length > MAX_OUTSTANDING_AGENT_SPAWNS) {
|
|
266
|
+
_outstandingAgentSpawns.splice(0, _outstandingAgentSpawns.length - MAX_OUTSTANDING_AGENT_SPAWNS);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
function getOutstandingAgentSpawns() {
|
|
270
|
+
return _outstandingAgentSpawns;
|
|
271
|
+
}
|
|
272
|
+
function removeOutstandingAgentSpawn(finishedPrompt) {
|
|
273
|
+
const idx = _outstandingAgentSpawns.findIndex((e) => finishedPrompt.startsWith(e.prompt));
|
|
274
|
+
if (idx !== -1) _outstandingAgentSpawns.splice(idx, 1);
|
|
275
|
+
}
|
|
276
|
+
function outstandingAgentSpawnKey(prompt, ts) {
|
|
277
|
+
return `${prompt} ${ts}`;
|
|
278
|
+
}
|
|
279
|
+
function outstandingAgentSpawnsAtLoad() {
|
|
280
|
+
return _outstandingAgentSpawnsAtLoad;
|
|
281
|
+
}
|
|
282
|
+
function consumedOutstandingAgentSpawnKeys() {
|
|
283
|
+
const currentKeys = new Set(_outstandingAgentSpawns.map((e) => outstandingAgentSpawnKey(e.prompt, e.ts)));
|
|
284
|
+
const consumed = [];
|
|
285
|
+
for (const e of _outstandingAgentSpawnsAtLoad) {
|
|
286
|
+
const key = outstandingAgentSpawnKey(e.prompt, e.ts);
|
|
287
|
+
if (!currentKeys.has(key)) consumed.push(key);
|
|
288
|
+
}
|
|
289
|
+
return consumed;
|
|
290
|
+
}
|
|
291
|
+
function curlDownloadKey(url) {
|
|
292
|
+
return shortFingerprint(url);
|
|
293
|
+
}
|
|
294
|
+
function recordCurlDownload(url, savedPath) {
|
|
295
|
+
_curlDownloads.set(curlDownloadKey(url), savedPath);
|
|
296
|
+
}
|
|
297
|
+
function getCurlDownloadPath(url) {
|
|
298
|
+
return _curlDownloads.get(curlDownloadKey(url)) ?? null;
|
|
299
|
+
}
|
|
300
|
+
function clearCurlDownload(url) {
|
|
301
|
+
_curlDownloads.delete(curlDownloadKey(url));
|
|
302
|
+
}
|
|
303
|
+
function curlDownloadsAtLoad() {
|
|
304
|
+
return _curlDownloadsAtLoad;
|
|
305
|
+
}
|
|
306
|
+
function consumedCurlDownloadKeys() {
|
|
307
|
+
const consumed = [];
|
|
308
|
+
for (const url of _curlDownloadsAtLoad.keys()) {
|
|
309
|
+
if (!_curlDownloads.has(url)) consumed.push(url);
|
|
310
|
+
}
|
|
311
|
+
return consumed;
|
|
312
|
+
}
|
|
313
|
+
function consumedFileLineRangeKeys() {
|
|
314
|
+
const consumed = [];
|
|
315
|
+
for (const key of _fileLineRangesAtLoad.keys()) {
|
|
316
|
+
if (!_fileLineRanges.has(key)) consumed.push(key);
|
|
317
|
+
}
|
|
318
|
+
return consumed;
|
|
319
|
+
}
|
|
320
|
+
function consumedFileServedOutputKeys() {
|
|
321
|
+
const consumed = [];
|
|
322
|
+
for (const key of _fileServedOutputsAtLoad.keys()) {
|
|
323
|
+
if (!_fileServedOutputs.has(key)) consumed.push(key);
|
|
324
|
+
}
|
|
325
|
+
return consumed;
|
|
326
|
+
}
|
|
327
|
+
var MAX_RANGES_PER_FILE = 64;
|
|
328
|
+
function statIdentity(absPath) {
|
|
329
|
+
try {
|
|
330
|
+
const st = fs.statSync(absPath);
|
|
331
|
+
return { size: st.size, mtimeMs: st.mtimeMs };
|
|
332
|
+
} catch {
|
|
333
|
+
return void 0;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
function recordFileLineRange(filePath, start, end) {
|
|
337
|
+
const normalized = normalizePath(filePath);
|
|
338
|
+
const key = foldPath(normalized);
|
|
339
|
+
const ranges = _fileLineRanges.get(key) ?? [];
|
|
340
|
+
if (!ranges.some(([s, e]) => s === start && e === end)) {
|
|
341
|
+
ranges.push([start, end]);
|
|
342
|
+
if (ranges.length > MAX_RANGES_PER_FILE) ranges.splice(0, ranges.length - MAX_RANGES_PER_FILE);
|
|
343
|
+
_fileLineRanges.set(key, ranges);
|
|
344
|
+
}
|
|
345
|
+
const entryKey = resolveFilesKey(normalized);
|
|
346
|
+
const entry = _files.get(entryKey);
|
|
347
|
+
const identity = statIdentity(normalized);
|
|
348
|
+
if (entry && identity) _files.set(entryKey, { ...entry, rangeFileIdentity: identity });
|
|
349
|
+
}
|
|
350
|
+
function getFileLineRanges(filePath) {
|
|
351
|
+
return _fileLineRanges.get(foldPath(normalizePath(filePath))) ?? [];
|
|
352
|
+
}
|
|
353
|
+
function resetFileLineRanges(filePath) {
|
|
354
|
+
_fileLineRanges.delete(foldPath(normalizePath(filePath)));
|
|
355
|
+
}
|
|
356
|
+
var MAX_SERVED_OUTPUTS_PER_FILE = 8;
|
|
357
|
+
var GENERIC_SERVED_OUTPUT_KEY = "\0<bash-generic-served>";
|
|
358
|
+
var GENERIC_SERVED_OUTPUT_FOLDED_KEY = foldPath(normalizePath(GENERIC_SERVED_OUTPUT_KEY));
|
|
359
|
+
var MAX_GENERIC_SERVED_OUTPUTS = 32;
|
|
360
|
+
function recordFileServedOutput(filePath, outputId) {
|
|
361
|
+
const key = foldPath(normalizePath(filePath));
|
|
362
|
+
const cap = key === GENERIC_SERVED_OUTPUT_FOLDED_KEY ? MAX_GENERIC_SERVED_OUTPUTS : MAX_SERVED_OUTPUTS_PER_FILE;
|
|
363
|
+
const ids = (_fileServedOutputs.get(key) ?? []).filter((id) => id !== outputId);
|
|
364
|
+
ids.push(outputId);
|
|
365
|
+
if (ids.length > cap) ids.splice(0, ids.length - cap);
|
|
366
|
+
_fileServedOutputs.set(key, ids);
|
|
367
|
+
}
|
|
368
|
+
function getFileServedOutputs(filePath) {
|
|
369
|
+
return _fileServedOutputs.get(foldPath(normalizePath(filePath))) ?? [];
|
|
370
|
+
}
|
|
371
|
+
function markFileTruncated(filePath, isFullRead = true) {
|
|
372
|
+
const normalized = normalizePath(filePath);
|
|
373
|
+
const key = resolveFilesKey(normalized);
|
|
374
|
+
const prev = _files.get(key);
|
|
375
|
+
const now = Date.now();
|
|
376
|
+
if (prev === void 0) {
|
|
377
|
+
_files.set(key, {
|
|
378
|
+
path: key,
|
|
379
|
+
readCount: 1,
|
|
380
|
+
lastReadAt: now,
|
|
381
|
+
wasEdited: false,
|
|
382
|
+
sizeBytes: fileSize(normalized),
|
|
383
|
+
wasTruncated: true,
|
|
384
|
+
...isFullRead ? { lastFullReadAt: now, fullReadCount: 1 } : {}
|
|
385
|
+
});
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
_files.set(key, { ...prev, wasTruncated: true });
|
|
389
|
+
}
|
|
390
|
+
function wasFileTruncatedThisSession(filePath) {
|
|
391
|
+
const entry = _files.get(resolveFilesKey(normalizePath(filePath)));
|
|
392
|
+
return entry?.wasTruncated === true;
|
|
393
|
+
}
|
|
394
|
+
function generateSessionId() {
|
|
395
|
+
try {
|
|
396
|
+
return randomUUID();
|
|
397
|
+
} catch {
|
|
398
|
+
return randomBytes(16).toString("hex");
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
function getSessionId() {
|
|
402
|
+
const fromEnv = process.env["CLAUDE_CODE_SESSION_ID"];
|
|
403
|
+
if (fromEnv !== void 0 && fromEnv !== "") return fromEnv;
|
|
404
|
+
_sessionId ??= generateSessionId();
|
|
405
|
+
return _sessionId;
|
|
406
|
+
}
|
|
407
|
+
function setTranscriptPath(path, sessionId) {
|
|
408
|
+
if (path === "") return;
|
|
409
|
+
_transcriptPath = { path, sessionId };
|
|
410
|
+
}
|
|
411
|
+
function getTranscriptPath() {
|
|
412
|
+
if (_transcriptPath === null) return void 0;
|
|
413
|
+
return _transcriptPath.sessionId === getSessionId() ? _transcriptPath.path : void 0;
|
|
414
|
+
}
|
|
415
|
+
function exportSessionState() {
|
|
416
|
+
return {
|
|
417
|
+
files: Array.from(_files.values()),
|
|
418
|
+
hintsShown: Array.from(_hintsShown),
|
|
419
|
+
..._scheduledPromptCounts.size > 0 ? { scheduledPromptCounts: Array.from(_scheduledPromptCounts.entries()) } : {},
|
|
420
|
+
webFetches: Array.from(_webFetches.entries()),
|
|
421
|
+
bashOutputs: Array.from(_bashOutputs.entries()),
|
|
422
|
+
bashReruns: Array.from(_bashReruns),
|
|
423
|
+
curlDownloads: Array.from(_curlDownloads.entries()),
|
|
424
|
+
fileLineRanges: Array.from(_fileLineRanges.entries()),
|
|
425
|
+
..._fileServedOutputs.size > 0 ? { fileServedOutputs: Array.from(_fileServedOutputs.entries()) } : {},
|
|
426
|
+
cliReads: Array.from(_cliReads),
|
|
427
|
+
pendingLargeFileHints: Array.from(_pendingLargeFileHints.entries()),
|
|
428
|
+
grepQueries: Array.from(_grepQueries.entries()),
|
|
429
|
+
globQueries: Array.from(_globQueries.entries()),
|
|
430
|
+
outstandingAgentSpawns: _outstandingAgentSpawns.map((e) => [e.prompt, e.ts]),
|
|
431
|
+
..._lastTabContext !== null ? { lastTabContextDigest: _lastTabContext } : {},
|
|
432
|
+
..._seenImageHashes.length > 0 ? { seenImageHashes: [..._seenImageHashes] } : {},
|
|
433
|
+
..._compactedAt > 0 ? { compactedAt: _compactedAt } : {}
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
function importSessionState(s) {
|
|
437
|
+
_files = /* @__PURE__ */ new Map();
|
|
438
|
+
for (const e of s.files) {
|
|
439
|
+
if (e && typeof e.path === "string") _files.set(e.path, e);
|
|
440
|
+
}
|
|
441
|
+
_filesAtLoad = new Map(Array.from(_files, ([key, e]) => [key, e.readCount]));
|
|
442
|
+
_filesFullReadCountAtLoad = new Map(Array.from(_files, ([key, e]) => [key, e.fullReadCount ?? 0]));
|
|
443
|
+
_hintsShown = new Set(s.hintsShown);
|
|
444
|
+
_scheduledPromptCounts = new Map(s.scheduledPromptCounts ?? []);
|
|
445
|
+
_webFetches = new Map(s.webFetches);
|
|
446
|
+
_bashOutputs = new Map(s.bashOutputs);
|
|
447
|
+
_bashReruns = new Set(s.bashReruns ?? []);
|
|
448
|
+
_curlDownloads = new Map(s.curlDownloads);
|
|
449
|
+
_curlDownloadsAtLoad = new Map(_curlDownloads);
|
|
450
|
+
_fileLineRanges = new Map(s.fileLineRanges ?? []);
|
|
451
|
+
_fileLineRangesAtLoad = new Map(_fileLineRanges);
|
|
452
|
+
_fileServedOutputs = new Map(s.fileServedOutputs ?? []);
|
|
453
|
+
_fileServedOutputsAtLoad = new Map(_fileServedOutputs);
|
|
454
|
+
_cliReads = new Set(s.cliReads ?? []);
|
|
455
|
+
_pendingLargeFileHints = new Map(s.pendingLargeFileHints ?? []);
|
|
456
|
+
_pendingLargeFileHintsAtLoad = new Map(_pendingLargeFileHints);
|
|
457
|
+
_grepQueries = new Map(s.grepQueries ?? []);
|
|
458
|
+
_globQueries = new Map(s.globQueries ?? []);
|
|
459
|
+
_outstandingAgentSpawns = (s.outstandingAgentSpawns ?? []).map(([prompt, ts]) => ({ prompt, ts }));
|
|
460
|
+
_outstandingAgentSpawnsAtLoad = [..._outstandingAgentSpawns];
|
|
461
|
+
_lastTabContext = s.lastTabContextDigest ?? null;
|
|
462
|
+
_seenImageHashes = [...s.seenImageHashes ?? []];
|
|
463
|
+
_compactedAt = s.compactedAt ?? 0;
|
|
464
|
+
}
|
|
465
|
+
registerReset(() => {
|
|
466
|
+
_files = /* @__PURE__ */ new Map();
|
|
467
|
+
_filesAtLoad = /* @__PURE__ */ new Map();
|
|
468
|
+
_filesFullReadCountAtLoad = /* @__PURE__ */ new Map();
|
|
469
|
+
_hintsShown = /* @__PURE__ */ new Set();
|
|
470
|
+
_scheduledPromptCounts = /* @__PURE__ */ new Map();
|
|
471
|
+
_webFetches = /* @__PURE__ */ new Map();
|
|
472
|
+
_bashOutputs = /* @__PURE__ */ new Map();
|
|
473
|
+
_bashReruns = /* @__PURE__ */ new Set();
|
|
474
|
+
_curlDownloads = /* @__PURE__ */ new Map();
|
|
475
|
+
_curlDownloadsAtLoad = /* @__PURE__ */ new Map();
|
|
476
|
+
_fileLineRanges = /* @__PURE__ */ new Map();
|
|
477
|
+
_fileLineRangesAtLoad = /* @__PURE__ */ new Map();
|
|
478
|
+
_fileServedOutputs = /* @__PURE__ */ new Map();
|
|
479
|
+
_fileServedOutputsAtLoad = /* @__PURE__ */ new Map();
|
|
480
|
+
_cliReads = /* @__PURE__ */ new Set();
|
|
481
|
+
_pendingLargeFileHints = /* @__PURE__ */ new Map();
|
|
482
|
+
_pendingLargeFileHintsAtLoad = /* @__PURE__ */ new Map();
|
|
483
|
+
_grepQueries = /* @__PURE__ */ new Map();
|
|
484
|
+
_globQueries = /* @__PURE__ */ new Map();
|
|
485
|
+
_outstandingAgentSpawns = [];
|
|
486
|
+
_outstandingAgentSpawnsAtLoad = [];
|
|
487
|
+
_lastTabContext = null;
|
|
488
|
+
_seenImageHashes = [];
|
|
489
|
+
_compactedAt = 0;
|
|
490
|
+
_sessionId = null;
|
|
491
|
+
_transcriptPath = null;
|
|
492
|
+
}, { perRequest: true });
|
|
493
|
+
|
|
494
|
+
export {
|
|
495
|
+
recordFileRead,
|
|
496
|
+
recordSymbolRead,
|
|
497
|
+
filesReadCountAtLoad,
|
|
498
|
+
filesFullReadCountAtLoad,
|
|
499
|
+
recordFileEdit,
|
|
500
|
+
getSessionFiles,
|
|
501
|
+
wasFileReadThisSession,
|
|
502
|
+
wasFileFullyReadThisSession,
|
|
503
|
+
getCompactedAt,
|
|
504
|
+
markCompacted,
|
|
505
|
+
getSessionFileEntry,
|
|
506
|
+
wasHintShown,
|
|
507
|
+
markHintShown,
|
|
508
|
+
recordScheduledPrompt,
|
|
509
|
+
wasCliReadThisSession,
|
|
510
|
+
recordCliRead,
|
|
511
|
+
recordLargeFileHintPending,
|
|
512
|
+
takePendingLargeFileHint,
|
|
513
|
+
consumedPendingLargeFileHintKeys,
|
|
514
|
+
pendingLargeFileHintsAtLoad,
|
|
515
|
+
WEB_FETCH_KEY_SEP,
|
|
516
|
+
recordWebFetch,
|
|
517
|
+
migrateCurlDownloadKey,
|
|
518
|
+
migrateWebFetchKey,
|
|
519
|
+
getSessionWebFetches,
|
|
520
|
+
recordBashOutput,
|
|
521
|
+
getSessionBashOutputs,
|
|
522
|
+
recordBashRerun,
|
|
523
|
+
getSessionBashReruns,
|
|
524
|
+
getBashOutputId,
|
|
525
|
+
recordGrepQuery,
|
|
526
|
+
getGrepMatchCount,
|
|
527
|
+
recordGlobQuery,
|
|
528
|
+
getGlobMatchCount,
|
|
529
|
+
setLastTabContext,
|
|
530
|
+
lastTabContextMatches,
|
|
531
|
+
MAX_SEEN_IMAGE_HASHES,
|
|
532
|
+
hasSeenImage,
|
|
533
|
+
recordSeenImage,
|
|
534
|
+
MAX_OUTSTANDING_AGENT_SPAWNS,
|
|
535
|
+
recordOutstandingAgentSpawn,
|
|
536
|
+
getOutstandingAgentSpawns,
|
|
537
|
+
removeOutstandingAgentSpawn,
|
|
538
|
+
outstandingAgentSpawnKey,
|
|
539
|
+
outstandingAgentSpawnsAtLoad,
|
|
540
|
+
consumedOutstandingAgentSpawnKeys,
|
|
541
|
+
recordCurlDownload,
|
|
542
|
+
getCurlDownloadPath,
|
|
543
|
+
clearCurlDownload,
|
|
544
|
+
curlDownloadsAtLoad,
|
|
545
|
+
consumedCurlDownloadKeys,
|
|
546
|
+
consumedFileLineRangeKeys,
|
|
547
|
+
consumedFileServedOutputKeys,
|
|
548
|
+
MAX_RANGES_PER_FILE,
|
|
549
|
+
recordFileLineRange,
|
|
550
|
+
getFileLineRanges,
|
|
551
|
+
resetFileLineRanges,
|
|
552
|
+
MAX_SERVED_OUTPUTS_PER_FILE,
|
|
553
|
+
GENERIC_SERVED_OUTPUT_KEY,
|
|
554
|
+
MAX_GENERIC_SERVED_OUTPUTS,
|
|
555
|
+
recordFileServedOutput,
|
|
556
|
+
getFileServedOutputs,
|
|
557
|
+
markFileTruncated,
|
|
558
|
+
wasFileTruncatedThisSession,
|
|
559
|
+
getSessionId,
|
|
560
|
+
setTranscriptPath,
|
|
561
|
+
getTranscriptPath,
|
|
562
|
+
exportSessionState,
|
|
563
|
+
importSessionState
|
|
564
|
+
};
|