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
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
import { createRequire as __cjsRequire } from 'node:module';
|
|
2
2
|
const require = __cjsRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
stripAnsiEscapes
|
|
7
|
-
} from "./token-goat-chunk-D2X7XN5M.mjs";
|
|
8
|
-
import {
|
|
9
|
-
safeSlice
|
|
10
|
-
} from "./token-goat-chunk-6E2IDLHF.mjs";
|
|
4
|
+
estimateTokensFromLength
|
|
5
|
+
} from "./token-goat-chunk-52NSDWYY.mjs";
|
|
11
6
|
import {
|
|
12
7
|
displaySafeText
|
|
13
8
|
} from "./token-goat-chunk-NMTKNYGF.mjs";
|
|
@@ -25,82 +20,6 @@ function claudeConfigDir(homeDir = os.homedir()) {
|
|
|
25
20
|
return path.join(homeDir, ".claude");
|
|
26
21
|
}
|
|
27
22
|
|
|
28
|
-
// src/overflow_guard.ts
|
|
29
|
-
init_define_import_meta_env();
|
|
30
|
-
function estimateTokensFromLength(length, cls = "text") {
|
|
31
|
-
return Math.max(1, Math.floor(Math.max(0, length) / guardDivisor(cls)) + 1);
|
|
32
|
-
}
|
|
33
|
-
function estimateTokens(text) {
|
|
34
|
-
const stripped = stripAnsiEscapes(text);
|
|
35
|
-
return estimateTokensFromLength(stripped.length, classifyContent(stripped));
|
|
36
|
-
}
|
|
37
|
-
function trimToBudget(text, budgetTokens, command) {
|
|
38
|
-
const markerMarginTokens = 64;
|
|
39
|
-
const strippedAll = stripAnsiEscapes(text);
|
|
40
|
-
const contentClass = classifyContent(strippedAll);
|
|
41
|
-
const totalTokens = estimateTokensFromLength(strippedAll.length, contentClass);
|
|
42
|
-
if (totalTokens <= budgetTokens) {
|
|
43
|
-
return text;
|
|
44
|
-
}
|
|
45
|
-
const lines = text.split("\n");
|
|
46
|
-
if (lines.length > 1 && lines[lines.length - 1] === "") lines.pop();
|
|
47
|
-
const totalLines = lines.length;
|
|
48
|
-
const bodyBudget = Math.max(1, budgetTokens - markerMarginTokens);
|
|
49
|
-
const charBudget = bodyBudget * guardDivisor(contentClass);
|
|
50
|
-
const kept = [];
|
|
51
|
-
let used = 0;
|
|
52
|
-
for (const ln of lines) {
|
|
53
|
-
const stripped = stripAnsiEscapes(ln);
|
|
54
|
-
const cost = ln.length + 1;
|
|
55
|
-
if (kept.length === 0 && cost > charBudget) {
|
|
56
|
-
const truncated = safeSlice(stripped, charBudget);
|
|
57
|
-
kept.push(truncated);
|
|
58
|
-
break;
|
|
59
|
-
}
|
|
60
|
-
if (kept.length > 0 && used + cost > charBudget) {
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
kept.push(ln);
|
|
64
|
-
used += cost;
|
|
65
|
-
}
|
|
66
|
-
const shown = kept.length;
|
|
67
|
-
const hint = getHintFor(command);
|
|
68
|
-
const marker = `[token-goat: output capped at ~${budgetTokens} tokens to protect context \u2014 showing ${shown} of ${totalLines} lines. ${hint}]`;
|
|
69
|
-
return kept.join("\n") + "\n" + marker;
|
|
70
|
-
}
|
|
71
|
-
function capJsonRows(items, budgetTokens) {
|
|
72
|
-
const totalCount = items.length;
|
|
73
|
-
const charBudget = Math.max(1, budgetTokens * guardDivisor());
|
|
74
|
-
const kept = [];
|
|
75
|
-
let used = 0;
|
|
76
|
-
for (const item of items) {
|
|
77
|
-
const cost = JSON.stringify(item).length + 2;
|
|
78
|
-
if (kept.length > 0 && used + cost > charBudget) break;
|
|
79
|
-
kept.push(item);
|
|
80
|
-
used += cost;
|
|
81
|
-
}
|
|
82
|
-
return { items: kept, truncated: kept.length < totalCount, totalCount };
|
|
83
|
-
}
|
|
84
|
-
function getHintFor(command) {
|
|
85
|
-
const cmd = (command || "").toLowerCase().trim();
|
|
86
|
-
if (cmd === "symbol") {
|
|
87
|
-
return "Request a specific method (file.py::Class.method) or use --json for structured access.";
|
|
88
|
-
}
|
|
89
|
-
if (cmd === "heading" || cmd === "section") {
|
|
90
|
-
return "Request a narrower sub-heading, e.g. 'doc.md::Section#2'.";
|
|
91
|
-
}
|
|
92
|
-
if (cmd === "lines") {
|
|
93
|
-
return "Request a smaller line range, e.g. 'file.py@100-150'.";
|
|
94
|
-
}
|
|
95
|
-
if (cmd === "bash-output" || cmd === "web-output") {
|
|
96
|
-
return "Use --grep PATTERN, --section HEADING, or --tail N to narrow the cached output.";
|
|
97
|
-
}
|
|
98
|
-
if (cmd === "semantic") {
|
|
99
|
-
return "Narrow your query text or pass --limit to reduce the number of matches returned.";
|
|
100
|
-
}
|
|
101
|
-
return "Narrow your query or raise overflow_guard max_tokens in config.";
|
|
102
|
-
}
|
|
103
|
-
|
|
104
23
|
// src/resident_context.ts
|
|
105
24
|
init_define_import_meta_env();
|
|
106
25
|
import * as fs from "node:fs";
|
|
@@ -307,10 +226,6 @@ function accumulateResidentLines(lines) {
|
|
|
307
226
|
|
|
308
227
|
export {
|
|
309
228
|
claudeConfigDir,
|
|
310
|
-
estimateTokensFromLength,
|
|
311
|
-
estimateTokens,
|
|
312
|
-
trimToBudget,
|
|
313
|
-
capJsonRows,
|
|
314
229
|
createResidentContextStats,
|
|
315
230
|
accumulateResidentLine,
|
|
316
231
|
summarizeResidentContext,
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import { createRequire as __cjsRequire } from 'node:module';
|
|
2
|
+
const require = __cjsRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
serveOne,
|
|
5
|
+
swapEnv
|
|
6
|
+
} from "./token-goat-chunk-S4VSXURL.mjs";
|
|
7
|
+
import {
|
|
8
|
+
relayInProcess
|
|
9
|
+
} from "./token-goat-chunk-QO3LXVVR.mjs";
|
|
10
|
+
import "./token-goat-chunk-IVWI2OCK.mjs";
|
|
11
|
+
import "./token-goat-chunk-DNRPXHYH.mjs";
|
|
12
|
+
import "./token-goat-chunk-RTMVLHWX.mjs";
|
|
13
|
+
import "./token-goat-chunk-L7H3U27L.mjs";
|
|
14
|
+
import "./token-goat-chunk-RRNZMM3A.mjs";
|
|
15
|
+
import "./token-goat-chunk-E4ZOJIZK.mjs";
|
|
16
|
+
import "./token-goat-chunk-E5TK5DNO.mjs";
|
|
17
|
+
import "./token-goat-chunk-ZER6EAXZ.mjs";
|
|
18
|
+
import "./token-goat-chunk-44BM7DDQ.mjs";
|
|
19
|
+
import "./token-goat-chunk-EUSDXRXU.mjs";
|
|
20
|
+
import "./token-goat-chunk-G7IWXCFF.mjs";
|
|
21
|
+
import "./token-goat-chunk-H5J3C56Q.mjs";
|
|
22
|
+
import "./token-goat-chunk-TDUT2CL6.mjs";
|
|
23
|
+
import "./token-goat-chunk-ONXH6NZ5.mjs";
|
|
24
|
+
import "./token-goat-chunk-O6I2XU4P.mjs";
|
|
25
|
+
import "./token-goat-chunk-D4ETHJD6.mjs";
|
|
26
|
+
import "./token-goat-chunk-52NSDWYY.mjs";
|
|
27
|
+
import "./token-goat-chunk-2WOUYWLM.mjs";
|
|
28
|
+
import "./token-goat-chunk-CIQ2FTY3.mjs";
|
|
29
|
+
import {
|
|
30
|
+
PROTOCOL_VERSION,
|
|
31
|
+
SERVER_SLOTS,
|
|
32
|
+
bundleEntryFiles,
|
|
33
|
+
configStamp,
|
|
34
|
+
endpointFor,
|
|
35
|
+
ensureServerKey,
|
|
36
|
+
mac,
|
|
37
|
+
macMatches,
|
|
38
|
+
nonce,
|
|
39
|
+
readFrames,
|
|
40
|
+
removeMarker,
|
|
41
|
+
serverKeyPath,
|
|
42
|
+
touchMarker,
|
|
43
|
+
writeFrame
|
|
44
|
+
} from "./token-goat-chunk-DPNLUJWB.mjs";
|
|
45
|
+
import "./token-goat-chunk-3BTK54F3.mjs";
|
|
46
|
+
import "./token-goat-chunk-VMFWNHGR.mjs";
|
|
47
|
+
import "./token-goat-chunk-435UQTKD.mjs";
|
|
48
|
+
import "./token-goat-chunk-7CPMDFGB.mjs";
|
|
49
|
+
import {
|
|
50
|
+
hookServerEnabled
|
|
51
|
+
} from "./token-goat-chunk-TGOXNAHW.mjs";
|
|
52
|
+
import "./token-goat-chunk-XB5KKOCG.mjs";
|
|
53
|
+
import {
|
|
54
|
+
clearPerRequestCaches
|
|
55
|
+
} from "./token-goat-chunk-YZAAZU2S.mjs";
|
|
56
|
+
import "./token-goat-chunk-IVE6U7KV.mjs";
|
|
57
|
+
import "./token-goat-chunk-XYWPOSCN.mjs";
|
|
58
|
+
import "./token-goat-chunk-TCQANXYC.mjs";
|
|
59
|
+
import "./token-goat-chunk-NMTKNYGF.mjs";
|
|
60
|
+
import {
|
|
61
|
+
VERSION,
|
|
62
|
+
configPath,
|
|
63
|
+
ensureDataDirPrivate
|
|
64
|
+
} from "./token-goat-chunk-MELOKFDJ.mjs";
|
|
65
|
+
import "./token-goat-chunk-Y4AFKTHK.mjs";
|
|
66
|
+
import "./token-goat-chunk-JTKCQMQA.mjs";
|
|
67
|
+
import {
|
|
68
|
+
init_define_import_meta_env
|
|
69
|
+
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
70
|
+
|
|
71
|
+
// src/hook_server.ts
|
|
72
|
+
init_define_import_meta_env();
|
|
73
|
+
import * as fs from "node:fs";
|
|
74
|
+
import * as net from "node:net";
|
|
75
|
+
import * as os from "node:os";
|
|
76
|
+
var IDLE_EXIT_MS = { primary: 30 * 6e4, overflow: 3 * 6e4 };
|
|
77
|
+
var KEY_CHECK_MS = 2e3;
|
|
78
|
+
var HANDSHAKE_IDLE_MS = 1e4;
|
|
79
|
+
function bundleStamp() {
|
|
80
|
+
return bundleEntryFiles().map((f) => {
|
|
81
|
+
try {
|
|
82
|
+
const st = fs.statSync(f);
|
|
83
|
+
return `${st.size}:${st.mtimeMs}`;
|
|
84
|
+
} catch {
|
|
85
|
+
return "-";
|
|
86
|
+
}
|
|
87
|
+
}).join("|");
|
|
88
|
+
}
|
|
89
|
+
var enabledMemo;
|
|
90
|
+
function stillEnabled() {
|
|
91
|
+
const key = `${process.env["TOKEN_GOAT_HOOK_SERVER"] ?? ""}|${configPath()}|${configStamp()}`;
|
|
92
|
+
if (enabledMemo?.key !== key) enabledMemo = { key, enabled: hookServerEnabled() };
|
|
93
|
+
return enabledMemo.enabled;
|
|
94
|
+
}
|
|
95
|
+
function retirementReason(loadedStamp) {
|
|
96
|
+
if (bundleStamp() !== loadedStamp) return "bundle replaced";
|
|
97
|
+
if (!stillEnabled()) return "disabled";
|
|
98
|
+
return void 0;
|
|
99
|
+
}
|
|
100
|
+
async function handle(request, runCli, send) {
|
|
101
|
+
clearPerRequestCaches();
|
|
102
|
+
if (request.kind === "cli") {
|
|
103
|
+
const res = await serveOne({ id: 0, argv: request.argv, cwd: request.cwd, env: request.env }, runCli, clearPerRequestCaches);
|
|
104
|
+
return send({ ok: true, stdout: res.stdout, stderr: res.stderr, status: res.status });
|
|
105
|
+
}
|
|
106
|
+
const startedAt = performance.now();
|
|
107
|
+
const cwdBefore = process.cwd();
|
|
108
|
+
const restoreEnv = swapEnv(request.env);
|
|
109
|
+
const afterReply = [];
|
|
110
|
+
try {
|
|
111
|
+
process.chdir(request.cwd);
|
|
112
|
+
const payload = JSON.parse(request.input);
|
|
113
|
+
const stdout = await relayInProcess(request.event, payload, request.harnessWaitMs, { elapsedMs: () => request.elapsedMs + (performance.now() - startedAt), afterReply: (work) => afterReply.push(work) });
|
|
114
|
+
send({ ok: true, stdout });
|
|
115
|
+
for (const work of afterReply) work();
|
|
116
|
+
} finally {
|
|
117
|
+
restoreEnv();
|
|
118
|
+
try {
|
|
119
|
+
process.chdir(cwdBefore);
|
|
120
|
+
} catch {
|
|
121
|
+
}
|
|
122
|
+
clearPerRequestCaches();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function listen(server, endpoint) {
|
|
126
|
+
const tryListen = () => new Promise((resolve) => {
|
|
127
|
+
server.once("error", resolve);
|
|
128
|
+
server.listen({ path: endpoint, readableAll: false, writableAll: false }, () => {
|
|
129
|
+
server.removeListener("error", resolve);
|
|
130
|
+
resolve(void 0);
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
return tryListen().then(async (err) => {
|
|
134
|
+
if (err === void 0) return true;
|
|
135
|
+
if (err.code !== "EADDRINUSE" || process.platform === "win32") return false;
|
|
136
|
+
const alive = await new Promise((resolve) => {
|
|
137
|
+
const probe = net.connect(endpoint);
|
|
138
|
+
probe.once("connect", () => {
|
|
139
|
+
probe.destroy();
|
|
140
|
+
resolve(true);
|
|
141
|
+
});
|
|
142
|
+
probe.once("error", () => resolve(false));
|
|
143
|
+
});
|
|
144
|
+
if (alive) return false;
|
|
145
|
+
fs.rmSync(endpoint, { force: true });
|
|
146
|
+
return await tryListen() === void 0;
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
async function runHookServer(slot, runCli) {
|
|
150
|
+
if (!Number.isInteger(slot) || slot < 0 || slot >= SERVER_SLOTS) throw new Error(`--slot must be an integer from 0 to ${SERVER_SLOTS - 1}`);
|
|
151
|
+
if (!hookServerEnabled()) {
|
|
152
|
+
touchMarker("disabled", configStamp());
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
ensureDataDirPrivate();
|
|
156
|
+
const key = ensureServerKey();
|
|
157
|
+
const keyPath = serverKeyPath();
|
|
158
|
+
const loadedStamp = bundleStamp();
|
|
159
|
+
const endpoint = endpointFor(slot);
|
|
160
|
+
process.chdir(os.tmpdir());
|
|
161
|
+
const status = { pid: process.pid, slot, version: VERSION, startedAt: Date.now(), lastUsedAt: Date.now(), served: 0, errors: 0 };
|
|
162
|
+
let busy = false;
|
|
163
|
+
let retiring = false;
|
|
164
|
+
let idleTimer;
|
|
165
|
+
const flushing = /* @__PURE__ */ new Set();
|
|
166
|
+
const awaitingRequest = /* @__PURE__ */ new Set();
|
|
167
|
+
const endWith = (socket, frame) => {
|
|
168
|
+
const flushed = new Promise((resolve) => {
|
|
169
|
+
socket.once("close", () => resolve());
|
|
170
|
+
writeFrame(socket, frame);
|
|
171
|
+
socket.end(() => resolve());
|
|
172
|
+
});
|
|
173
|
+
flushing.add(flushed);
|
|
174
|
+
void flushed.then(() => flushing.delete(flushed));
|
|
175
|
+
};
|
|
176
|
+
let socketIno;
|
|
177
|
+
const ownsEndpoint = () => {
|
|
178
|
+
if (socketIno === void 0) return true;
|
|
179
|
+
try {
|
|
180
|
+
return fs.statSync(endpoint, { bigint: true, throwIfNoEntry: false })?.ino === socketIno;
|
|
181
|
+
} catch {
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
const server = net.createServer((socket) => serveConnection(socket));
|
|
186
|
+
const exitOnceFlushed = () => void Promise.all(flushing).then(() => process.exit(0));
|
|
187
|
+
const stop = () => {
|
|
188
|
+
retiring = true;
|
|
189
|
+
if (idleTimer !== void 0) clearTimeout(idleTimer);
|
|
190
|
+
if (ownsEndpoint()) server.close();
|
|
191
|
+
for (const socket of awaitingRequest) endWith(socket, { t: "stale" });
|
|
192
|
+
awaitingRequest.clear();
|
|
193
|
+
if (!busy) exitOnceFlushed();
|
|
194
|
+
};
|
|
195
|
+
const armIdle = () => {
|
|
196
|
+
if (idleTimer !== void 0) clearTimeout(idleTimer);
|
|
197
|
+
idleTimer = setTimeout(stop, slot === 0 ? IDLE_EXIT_MS.primary : IDLE_EXIT_MS.overflow);
|
|
198
|
+
};
|
|
199
|
+
function serveConnection(socket) {
|
|
200
|
+
let nc = "";
|
|
201
|
+
let ns = "";
|
|
202
|
+
socket.setTimeout(HANDSHAKE_IDLE_MS, () => socket.destroy());
|
|
203
|
+
socket.on("error", () => socket.destroy());
|
|
204
|
+
socket.once("close", () => awaitingRequest.delete(socket));
|
|
205
|
+
const onMessage = (msg) => {
|
|
206
|
+
if (msg["t"] === "hello" && nc === "") {
|
|
207
|
+
if (msg["v"] !== PROTOCOL_VERSION || typeof msg["nc"] !== "string" || msg["nc"] === "") return void socket.destroy();
|
|
208
|
+
const reason = retiring ? "retiring" : retirementReason(loadedStamp);
|
|
209
|
+
if (reason !== void 0) {
|
|
210
|
+
if (reason === "disabled") touchMarker("disabled", configStamp());
|
|
211
|
+
if (reason === "bundle replaced") removeMarker(`spawn-${slot}`);
|
|
212
|
+
writeFrame(socket, { t: "stale" });
|
|
213
|
+
socket.end(() => {
|
|
214
|
+
if (!retiring) stop();
|
|
215
|
+
});
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
if (busy && msg["ctl"] !== true) {
|
|
219
|
+
writeFrame(socket, { t: "busy" });
|
|
220
|
+
return void socket.end();
|
|
221
|
+
}
|
|
222
|
+
nc = msg["nc"];
|
|
223
|
+
ns = nonce();
|
|
224
|
+
writeFrame(socket, { t: "challenge", v: PROTOCOL_VERSION, ns, mac: mac(key, "S", nc, ns) });
|
|
225
|
+
awaitingRequest.add(socket);
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
if (msg["t"] === "req" && ns !== "") {
|
|
229
|
+
const body = msg["body"];
|
|
230
|
+
if (typeof body !== "string" || !macMatches(mac(key, "C", nc, ns, body), msg["mac"])) return void socket.destroy();
|
|
231
|
+
if (!awaitingRequest.delete(socket)) return;
|
|
232
|
+
let request;
|
|
233
|
+
let parseError;
|
|
234
|
+
try {
|
|
235
|
+
request = JSON.parse(body);
|
|
236
|
+
} catch (e) {
|
|
237
|
+
parseError = e;
|
|
238
|
+
}
|
|
239
|
+
const kind = request?.kind;
|
|
240
|
+
if (kind === "status" || kind === "stop") {
|
|
241
|
+
const resBody = JSON.stringify({ ok: true, info: { ...status } });
|
|
242
|
+
endWith(socket, { t: "res", mac: mac(key, "R", nc, ns, resBody), body: resBody });
|
|
243
|
+
if (kind === "stop" && !retiring) stop();
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
if (busy || retiring) {
|
|
247
|
+
writeFrame(socket, { t: retiring ? "stale" : "busy" });
|
|
248
|
+
return void socket.end();
|
|
249
|
+
}
|
|
250
|
+
busy = true;
|
|
251
|
+
socket.setTimeout(0);
|
|
252
|
+
let replied = false;
|
|
253
|
+
const reply = (res) => {
|
|
254
|
+
if (replied) return;
|
|
255
|
+
replied = true;
|
|
256
|
+
const resBody = JSON.stringify(res);
|
|
257
|
+
endWith(socket, { t: "res", mac: mac(key, "R", nc, ns, resBody), body: resBody });
|
|
258
|
+
};
|
|
259
|
+
void (async () => {
|
|
260
|
+
try {
|
|
261
|
+
if (request === void 0) throw parseError;
|
|
262
|
+
await handle(request, runCli, reply);
|
|
263
|
+
status.served++;
|
|
264
|
+
} catch (e) {
|
|
265
|
+
status.errors++;
|
|
266
|
+
reply({ ok: false, error: e instanceof Error ? e.message : String(e) });
|
|
267
|
+
}
|
|
268
|
+
busy = false;
|
|
269
|
+
status.lastUsedAt = Date.now();
|
|
270
|
+
if (retiring) stop();
|
|
271
|
+
else armIdle();
|
|
272
|
+
})();
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
socket.destroy();
|
|
276
|
+
};
|
|
277
|
+
readFrames(socket, onMessage, () => void 0);
|
|
278
|
+
}
|
|
279
|
+
if (!await listen(server, endpoint)) return;
|
|
280
|
+
if (process.platform !== "win32") socketIno = fs.statSync(endpoint, { bigint: true }).ino;
|
|
281
|
+
removeMarker("failed");
|
|
282
|
+
setInterval(() => {
|
|
283
|
+
if (!fs.existsSync(keyPath) || !ownsEndpoint()) stop();
|
|
284
|
+
}, KEY_CHECK_MS).unref();
|
|
285
|
+
if (process.platform !== "win32") {
|
|
286
|
+
try {
|
|
287
|
+
fs.chmodSync(endpoint, 384);
|
|
288
|
+
} catch {
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
armIdle();
|
|
292
|
+
}
|
|
293
|
+
export {
|
|
294
|
+
runHookServer
|
|
295
|
+
};
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
stripMultilineStringSpan,
|
|
11
11
|
stripNestedBlockCommentSpan,
|
|
12
12
|
stripStringLiterals
|
|
13
|
-
} from "./token-goat-chunk-
|
|
13
|
+
} from "./token-goat-chunk-7CPMDFGB.mjs";
|
|
14
14
|
import {
|
|
15
15
|
init_define_import_meta_env
|
|
16
16
|
} from "./token-goat-chunk-A37V4PBF.mjs";
|