@xiaoso/dsh-tool-plus 0.1.6 → 0.1.7-beta.0
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/THIRD_PARTY_NOTICES.md +9 -3
- package/lib/{abort-Cwwm4Err.mjs → abort-Caqff3M6.mjs} +2 -2
- package/lib/alibaba-coding-plan-DTupMiAi.mjs +73 -0
- package/lib/alibaba-token-plan-CHGyWOfX.mjs +46 -0
- package/lib/alibaba-token-plan-Dj3OZhEE.mjs +82 -0
- package/lib/{amazon-bedrock-TVMpUTRG.mjs → amazon-bedrock-DbFSYXfJ.mjs} +117 -38
- package/lib/{anthropic-BL6LFDQS.mjs → anthropic-CTJ3IQVa.mjs} +675 -166
- package/lib/anthropic-CXfWlp-x.mjs +105 -0
- package/lib/{aws-credentials-B20dliS7.mjs → anthropic-wire-CKuhDwZ1.mjs} +74 -14
- package/lib/{api-key-login-CIDnXeYd.mjs → api-key-validation-CGCJFbFr.mjs} +27 -68
- package/lib/{azure-openai-responses-BkhsLmN3.mjs → azure-openai-responses-ChFbWaGj.mjs} +27 -16
- package/lib/{browser-render-CmgvSNte.mjs → browser-render-9o0Rknop.mjs} +4 -4
- package/lib/bun-shim.mjs +71 -2
- package/lib/{bundled-references-ChZSPDFw.mjs → bundled-references-DY3EJxZV.mjs} +6 -5
- package/lib/cline-pass-Bwg3esu9.mjs +44 -0
- package/lib/cloudflare-ai-gateway-BupNXyKK.mjs +35 -0
- package/lib/cloudflare-ai-gateway-EWo0VkP5.mjs +44 -0
- package/lib/collapse-DOR8sOGf.mjs +2304 -0
- package/lib/coreweave-C82HrLpb.mjs +31 -0
- package/lib/coreweave-Ct8cF-da.mjs +14 -0
- package/lib/{cursor-B6HcmplF.mjs → cursor-B95LzVWV.mjs} +11 -3
- package/lib/{cursor-CRpLpaZ3.mjs → cursor-DJV_dcgB.mjs} +887 -1784
- package/lib/{cursor-B8m6SqAH.mjs → cursor-LKGjucn2.mjs} +48 -38
- package/lib/cursor-proto-B8Wj8bv9.mjs +10513 -0
- package/lib/{deterministic-id-D-yIV_eI.mjs → deterministic-id-CUEIMSqR.mjs} +1 -1
- package/lib/devin-BMTdx_hx.mjs +316 -0
- package/lib/{devin-DUAfvBsW.mjs → devin-DSp0Rw_E.mjs} +172 -86
- package/lib/devin-ExGIghmx.mjs +69 -0
- package/lib/devin-proto-Br8fdyNl.mjs +2888 -0
- package/lib/{dom-CawWi8fa.mjs → dom-DG3sPESc.mjs} +8 -8
- package/lib/effort-BdtQMN-_.mjs +23 -0
- package/lib/{error-C-f_Wnw4.mjs → error-CORgGg5a.mjs} +275 -154
- package/lib/{event-stream-Dh2guZxS.mjs → event-stream-ulcDenZD.mjs} +20 -4
- package/lib/{gemini-headers-DKUShltF.mjs → gemini-headers-Co9cVvex.mjs} +2 -2
- package/lib/{github-copilot-suDymKrx.mjs → github-copilot-Dstq1D3s.mjs} +69 -29
- package/lib/github-copilot-headers-DOh1gt_w.mjs +312 -0
- package/lib/gitlab-duo-DSCMrU0m.mjs +11 -0
- package/lib/google-CtsKkOQK.mjs +38 -0
- package/lib/google-antigravity-z-5KsEci.mjs +252 -0
- package/lib/{google-auth-DYJLM792.mjs → google-auth-ieLBaneO.mjs} +4 -4
- package/lib/{google-gemini-cli-8BT513Ul.mjs → google-gemini-cli-C6NE5mWz.mjs} +28 -54
- package/lib/{google-gemini-cli-D6cSmfvB.mjs → google-gemini-cli-CAIPSl7e.mjs} +23 -29
- package/lib/google-oauth-shared-DhMllAkt.mjs +53 -0
- package/lib/{google-shared-CVbHK5vZ.mjs → google-shared-B0aNCYEH.mjs} +140 -44
- package/lib/{google-validation-Cgbn3tWJ.mjs → google-validation-BEkNs-Bx.mjs} +1 -1
- package/lib/{google-vertex-Bui-ypAe.mjs → google-vertex-Bbd1tYNc.mjs} +8 -8
- package/lib/hosts-00rjRzUD.mjs +203 -0
- package/lib/id-AL5obQzR.mjs +71 -0
- package/lib/{idle-iterator-CYAxUkSD.mjs → idle-iterator-DlUkEfzW.mjs} +3 -3
- package/lib/index.mjs +587 -5266
- package/lib/kilo-ChJL54wq.mjs +81 -0
- package/lib/kimi-C2c_Zq8A.mjs +67 -0
- package/lib/{launch-BmgEUycu.mjs → launch-DKDH71En.mjs} +1 -1
- package/lib/markit-CmRfm4E2.mjs +9885 -0
- package/lib/models-DnXMYGcJ.mjs +381604 -0
- package/lib/muse-code-Di1VZmB1.mjs +143 -0
- package/lib/{ollama-Df9ce-Cp.mjs → ollama-B8ic3sEp.mjs} +15 -30
- package/lib/{openai-codex-CAVI3Me-.mjs → openai-codex-DuJNC99x.mjs} +29 -99
- package/lib/{openai-codex-responses-BcnOotRB.mjs → openai-codex-responses-BL29nh9K.mjs} +204 -116
- package/lib/{openai-completions-Bq4WT47M.mjs → openai-completions-BK2f2dBv.mjs} +152 -82
- package/lib/openai-configuration-update-xMYUjaK_.mjs +150 -0
- package/lib/{openai-reasoning-fallback-DXsfiSXO.mjs → openai-reasoning-fallback-BdB3RCbj.mjs} +106 -12
- package/lib/{openai-responses-Mq_-PjvE.mjs → openai-responses-CGQPlIIy.mjs} +76 -82
- package/lib/{perplexity-XgLF73E7.mjs → perplexity-TBjz3VMB.mjs} +52 -9
- package/lib/{pkce-BlQikGPu.mjs → pkce-BYjmugmw.mjs} +1 -1
- package/lib/protobuf-aab1UGVn.mjs +717 -0
- package/lib/{provider-response-C6vcbQyO.mjs → provider-response-SqKSkkUc.mjs} +1 -1
- package/lib/{proxy-D9lm7ONA.mjs → proxy-5nWqRL1f.mjs} +45 -5
- package/lib/{readability-Cpm-ocau.mjs → readability-uGhqb4GC.mjs} +2 -2
- package/lib/reference-CtvM4zLU.mjs +114 -0
- package/lib/{request-debug-HJMoJncL.mjs → request-debug-NQN0BjHH.mjs} +1 -1
- package/lib/{sanitize-text-CfcXzw5X.mjs → sanitize-text-BCf5KmCf.mjs} +1 -1
- package/lib/{scrapers-Cg5w77td.mjs → scrapers-D8oWspgW.mjs} +12 -12
- package/lib/{src-BcD0_rQR.mjs → src-BwW51vA5.mjs} +979 -388
- package/lib/{sse-debug-CYdjOC96.mjs → sse-debug-B-tkLCPW.mjs} +1 -1
- package/lib/{stream-Bjq8wjfr.mjs → stream-B_7qN-bA.mjs} +3802 -2623
- package/lib/stream-markup-healing-DKT1lnkW.mjs +267 -0
- package/lib/{strict-tool-validation-imVLUcbI.mjs → strict-tool-validation-CBTz1dAA.mjs} +2 -2
- package/lib/taxonomy-DSIM99rS.mjs +15392 -0
- package/lib/{stream-markup-healing-DZ6bVDxH.mjs → thinking-CiLa2LFB.mjs} +31 -186
- package/lib/{turndown-DN7ByzEI.mjs → turndown-DrX1M4WG.mjs} +4 -4
- package/lib/{type-guards-B9VVjRDK.mjs → type-guards-CttAANEx.mjs} +1 -1
- package/lib/{types-DX_bvuus.mjs → types-PVueGi9S.mjs} +2 -2
- package/lib/{utils-C-dSORPa.mjs → utils-CCfhUQen.mjs} +2364 -2676
- package/lib/{utils-Cp2Mxf_U.mjs → utils-CUPhpw9A.mjs} +413 -134
- package/lib/{utils-CQHPEQ3W.mjs → utils-DeWqNWV8.mjs} +2 -2
- package/lib/{vision-guard-mBmtAHx0.mjs → vision-guard-_XwsL1DF.mjs} +14 -29
- package/lib/xai-oauth-CXhnz0gO.mjs +210 -0
- package/lib/{xiaomi-7mE345KX.mjs → xiaomi-psoUItal.mjs} +8 -37
- package/lib/{zai-CeNpMV3W.mjs → zai-ApJ8HBgT.mjs} +8 -71
- package/lib/{zip-BK7UHCwX.mjs → zip-Kd602XNe.mjs} +1 -1
- package/package.json +11 -11
- package/presets/package.json +1 -1
- package/presets/tool-plus-ptc/agent.cordis.yml +1 -1
- package/presets/tool-plus-standard/agent.cordis.yml +1 -1
- package/lib/agent_pb-Rizyt9Zg.mjs +0 -805
- package/lib/anthropic-CDmj476p.mjs +0 -262
- package/lib/api_server_pb-CDZgLMta.mjs +0 -252
- package/lib/callback-server-CFJK-jvK.mjs +0 -398
- package/lib/codex-P1dGpX7G.mjs +0 -54
- package/lib/device-code-CuXTWYwY.mjs +0 -51
- package/lib/devin-BcQwht1W.mjs +0 -114
- package/lib/devin-BvMfGevz.mjs +0 -95
- package/lib/github-copilot-B3kQl0g0.mjs +0 -104
- package/lib/gitlab-duo-BriUTP8k.mjs +0 -155
- package/lib/gitlab-duo-workflow-wK5Ljzmc.mjs +0 -91
- package/lib/google-CE5tFDod.mjs +0 -30
- package/lib/google-antigravity-C1jgNljz.mjs +0 -198
- package/lib/google-oauth-shared-BLVTvokk.mjs +0 -147
- package/lib/grammar-D-NqNUxQ.mjs +0 -49
- package/lib/identity-HNO1Oe9B.mjs +0 -219
- package/lib/kimi-DgcUpPtK.mjs +0 -236
- package/lib/markit-DtGoRE6M.mjs +0 -1417
- package/lib/minimax-code-Y3h5li9N.mjs +0 -53
- package/lib/models-DRA2c_8U.mjs +0 -104660
- package/lib/opencode-BsVw9rCD.mjs +0 -38
- package/lib/to-binary-B1BEBIPC.mjs +0 -6002
- package/lib/wafer-BlhWLweO.mjs +0 -17
- package/lib/xai-oauth-5pORHUrg.mjs +0 -446
|
@@ -17,7 +17,51 @@ import { isPromise } from "node:util/types";
|
|
|
17
17
|
import inspector from "node:inspector";
|
|
18
18
|
import { isMainThread } from "node:worker_threads";
|
|
19
19
|
import * as tls from "node:tls";
|
|
20
|
-
//#region
|
|
20
|
+
//#region src/tools/bash/which.ts
|
|
21
|
+
/**
|
|
22
|
+
* Minimal PATH (+ PATHEXT on Windows) executable lookup — the plugin's single
|
|
23
|
+
* implementation of `Bun.which` semantics on the Node runtime.
|
|
24
|
+
*
|
|
25
|
+
* Two callers, one scanner: DSH code that must resolve executables the way OMP
|
|
26
|
+
* does (procmgr `resolveWindowsShell` for shell discovery, `REJECT_PROMPT_COMMAND`
|
|
27
|
+
* in non-interactive-env) calls `findOnPath` directly, and the bun-shim installs
|
|
28
|
+
* `Bun.which` on top of it — which is also how upstream pi-utils' `$which` lands
|
|
29
|
+
* here (@oh-my-pi/pi-utils src/which.ts:201 calls `Bun.which` on non-darwin).
|
|
30
|
+
* Single implementation — any new caller resolves executables through here,
|
|
31
|
+
* never hand-rolls a PATH walk.
|
|
32
|
+
* @module @xiaoso/dsh-tool-plus/bash/which
|
|
33
|
+
*/
|
|
34
|
+
/** Windows default extension order when PATHEXT is unset. */
|
|
35
|
+
const WIN32_DEFAULT_PATHEXT = ".COM;.EXE;.BAT;.CMD";
|
|
36
|
+
/** True when `command` carries its own directory component. */
|
|
37
|
+
function hasPathSeparator(command) {
|
|
38
|
+
return command.includes("/") || command.includes("\\");
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Resolve `command` against PATH the way `Bun.which` would: absolute/relative
|
|
42
|
+
* candidates are returned as-is when they name an existing file; bare names
|
|
43
|
+
* are looked up in each PATH dir (appending PATHEXT extensions on win32, in
|
|
44
|
+
* order). Returns the first existing regular file, or `undefined`.
|
|
45
|
+
*/
|
|
46
|
+
function findOnPath(command, env = process.env) {
|
|
47
|
+
if (command.length === 0) return void 0;
|
|
48
|
+
if (hasPathSeparator(command)) try {
|
|
49
|
+
return fs.statSync(command).isFile() ? path.resolve(command) : void 0;
|
|
50
|
+
} catch {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const dirs = (env.PATH ?? "").split(path.delimiter).filter(Boolean);
|
|
54
|
+
const extensions = process.platform === "win32" ? (env.PATHEXT && env.PATHEXT.length > 0 ? env.PATHEXT : WIN32_DEFAULT_PATHEXT).split(";").filter(Boolean) : [];
|
|
55
|
+
const candidates = process.platform === "win32" ? [command, ...extensions.map((ext) => command + ext)] : [command];
|
|
56
|
+
for (const dir of dirs) for (const candidate of candidates) {
|
|
57
|
+
const full = path.join(dir, candidate);
|
|
58
|
+
try {
|
|
59
|
+
if (fs.statSync(full).isFile()) return full;
|
|
60
|
+
} catch {}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//#endregion
|
|
64
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/abortable.ts
|
|
21
65
|
var AbortError$1 = class extends Error {
|
|
22
66
|
constructor(signal) {
|
|
23
67
|
assert(signal.aborted, "Abort signal must be aborted");
|
|
@@ -110,7 +154,7 @@ function once(fn) {
|
|
|
110
154
|
};
|
|
111
155
|
}
|
|
112
156
|
//#endregion
|
|
113
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@
|
|
157
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/peek-file.ts
|
|
114
158
|
/**
|
|
115
159
|
* Read the first `maxBytes` of a file (offset 0) and pass that slice to `op`.
|
|
116
160
|
*
|
|
@@ -175,7 +219,7 @@ async function peekFile(filePath, maxBytes, op) {
|
|
|
175
219
|
}
|
|
176
220
|
}
|
|
177
221
|
//#endregion
|
|
178
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@
|
|
222
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/binary.ts
|
|
179
223
|
/**
|
|
180
224
|
* Content-based binary/text classification for files that are about to be
|
|
181
225
|
* decoded as UTF-8 text and shown to a model or user.
|
|
@@ -190,7 +234,11 @@ async function peekFile(filePath, maxBytes, op) {
|
|
|
190
234
|
* if (await isProbablyBinary(path)) return "[binary file omitted]";
|
|
191
235
|
* const text = await Bun.file(path).text();
|
|
192
236
|
*/
|
|
193
|
-
/**
|
|
237
|
+
/**
|
|
238
|
+
* Header window sniffed for the binary heuristic; mirrors git's 8000-byte scan.
|
|
239
|
+
* Exported so callers that already hold the whole file in memory can sniff the
|
|
240
|
+
* identical prefix through {@link isProbablyBinaryHeader} instead of reopening.
|
|
241
|
+
*/
|
|
194
242
|
const BINARY_SNIFF_BYTES = 8192;
|
|
195
243
|
/**
|
|
196
244
|
* Classify an in-memory byte header as binary (non-UTF-8-text).
|
|
@@ -218,9 +266,23 @@ function isProbablyBinary(filePath, maxBytes = BINARY_SNIFF_BYTES) {
|
|
|
218
266
|
return peekFile(filePath, maxBytes, isProbablyBinaryHeader);
|
|
219
267
|
}
|
|
220
268
|
//#endregion
|
|
221
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@
|
|
222
|
-
var version = "
|
|
269
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/package.json
|
|
270
|
+
var version = "18.1.17";
|
|
223
271
|
var engines = { "bun": ">=1.3.14" };
|
|
272
|
+
//#endregion
|
|
273
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/fs-error.ts
|
|
274
|
+
function isFsError(err) {
|
|
275
|
+
return err instanceof Error && "code" in err && typeof err.code === "string";
|
|
276
|
+
}
|
|
277
|
+
function isEnoent(err) {
|
|
278
|
+
return isFsError(err) && err.code === "ENOENT";
|
|
279
|
+
}
|
|
280
|
+
function isEnotdir(err) {
|
|
281
|
+
return isFsError(err) && err.code === "ENOTDIR";
|
|
282
|
+
}
|
|
283
|
+
function hasFsCode(err, code) {
|
|
284
|
+
return isFsError(err) && err.code === code;
|
|
285
|
+
}
|
|
224
286
|
/** Version (e.g. "1.0.0") */
|
|
225
287
|
const VERSION = version;
|
|
226
288
|
/** Default User-Agent header string (e.g. "omp/17.2.12") */
|
|
@@ -311,7 +373,29 @@ function standardizeMacOSPath(p) {
|
|
|
311
373
|
} catch {}
|
|
312
374
|
return p;
|
|
313
375
|
}
|
|
314
|
-
|
|
376
|
+
let projectDir;
|
|
377
|
+
/** Get the project directory. */
|
|
378
|
+
function getProjectDir() {
|
|
379
|
+
if (projectDir === void 0) try {
|
|
380
|
+
projectDir = standardizeMacOSPath(process.cwd());
|
|
381
|
+
} catch {
|
|
382
|
+
const candidates = [
|
|
383
|
+
process.env.PWD,
|
|
384
|
+
os.homedir(),
|
|
385
|
+
os.tmpdir()
|
|
386
|
+
];
|
|
387
|
+
for (const candidate of candidates) {
|
|
388
|
+
if (!candidate || !path.isAbsolute(candidate)) continue;
|
|
389
|
+
try {
|
|
390
|
+
process.chdir(candidate);
|
|
391
|
+
projectDir = standardizeMacOSPath(candidate);
|
|
392
|
+
break;
|
|
393
|
+
} catch {}
|
|
394
|
+
}
|
|
395
|
+
if (projectDir === void 0) throw new Error("Unable to determine an accessible working directory");
|
|
396
|
+
}
|
|
397
|
+
return projectDir;
|
|
398
|
+
}
|
|
315
399
|
/** Get the config directory name relative to home (e.g. ".omp" or PI_CONFIG_DIR override). */
|
|
316
400
|
function getConfigDirName() {
|
|
317
401
|
return process.env.PI_CONFIG_DIR || ".omp";
|
|
@@ -530,7 +614,7 @@ function getInstallId() {
|
|
|
530
614
|
return next;
|
|
531
615
|
}
|
|
532
616
|
//#endregion
|
|
533
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@
|
|
617
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/env.ts
|
|
534
618
|
const ENV_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
535
619
|
/**
|
|
536
620
|
* Strict shell-identifier shape. Used for dotenv keys we accept into
|
|
@@ -557,6 +641,17 @@ function isSafeEnvValue(value) {
|
|
|
557
641
|
function isMacosMallocStackLoggingEnvName(name) {
|
|
558
642
|
return name === "MallocStackLogging" || name === "MallocStackLoggingNoCompact";
|
|
559
643
|
}
|
|
644
|
+
/**
|
|
645
|
+
* True when running inside a WSL (Windows Subsystem for Linux) distribution.
|
|
646
|
+
*
|
|
647
|
+
* WSL reports `linux` for `process.platform`, so the only reliable signal is
|
|
648
|
+
* the `WSL_DISTRO_NAME`/`WSL_INTEROP` variables the interop layer injects.
|
|
649
|
+
* Callers use this to translate Windows drive paths to their `/mnt/<drive>`
|
|
650
|
+
* mounts and to route clipboard access through `powershell.exe`.
|
|
651
|
+
*/
|
|
652
|
+
function isWsl(platform = process.platform, env = process.env) {
|
|
653
|
+
return platform === "linux" && Boolean(env.WSL_DISTRO_NAME || env.WSL_INTEROP);
|
|
654
|
+
}
|
|
560
655
|
function readLaunchEnv() {
|
|
561
656
|
if (process.platform === "linux") try {
|
|
562
657
|
const values = /* @__PURE__ */ new Map();
|
|
@@ -628,7 +723,7 @@ function parseEnvFile(filePath) {
|
|
|
628
723
|
const homeEnv = parseEnvFile(path.join(os.homedir(), ".env"));
|
|
629
724
|
const piEnv = parseEnvFile(path.join(getConfigRootDir(), ".env"));
|
|
630
725
|
const agentEnv = parseEnvFile(path.join(getAgentDir(), ".env"));
|
|
631
|
-
const projectEnv = parseEnvFile(path.join(
|
|
726
|
+
const projectEnv = parseEnvFile(path.join(getProjectDir(), ".env"));
|
|
632
727
|
for (const key of Object.keys(Bun.env)) {
|
|
633
728
|
const value = Bun.env[key];
|
|
634
729
|
if (!isSafeEnvName(key) || isMacosMallocStackLoggingEnvName(key) || value === void 0 || !isSafeEnvValue(value)) delete Bun.env[key];
|
|
@@ -1057,18 +1152,35 @@ function xxHash64Core(bytes, seed) {
|
|
|
1057
1152
|
h ^= h >> 32n;
|
|
1058
1153
|
return h & MASK64;
|
|
1059
1154
|
}
|
|
1060
|
-
|
|
1155
|
+
/**
|
|
1156
|
+
* `Bun.hash(input, seed?)` — FNV-1a 32-bit stand-in, seeded form included.
|
|
1157
|
+
*
|
|
1158
|
+
* The seed is load-bearing: pi-utils folds `command` → `cwd` → `PATH` into one
|
|
1159
|
+
* cache key by re-seeding at each step (@oh-my-pi/pi-utils src/which.ts:207-209),
|
|
1160
|
+
* so a shim that drops the seed collapses every command sharing a PATH onto a
|
|
1161
|
+
* single `$which` cache slot (`$which("b")` returning `a`'s path). FNV steps are
|
|
1162
|
+
* bijections mod 2^32, so distinct seeds stay distinct for equal input — exactly
|
|
1163
|
+
* what a cache key needs. Single-argument values are unchanged (no seed → FNV
|
|
1164
|
+
* offset basis).
|
|
1165
|
+
*/
|
|
1166
|
+
function bunHash(data, seed) {
|
|
1061
1167
|
let bytes;
|
|
1062
1168
|
if (typeof data === "string") bytes = new TextEncoder().encode(data);
|
|
1063
1169
|
else if (data instanceof ArrayBuffer) bytes = new Uint8Array(data);
|
|
1064
1170
|
else bytes = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
1065
|
-
let h =
|
|
1171
|
+
let h = seedToBasis(seed);
|
|
1066
1172
|
for (const b of bytes) {
|
|
1067
1173
|
h ^= b;
|
|
1068
1174
|
h = Math.imul(h, 16777619) >>> 0;
|
|
1069
1175
|
}
|
|
1070
1176
|
return h >>> 0;
|
|
1071
1177
|
}
|
|
1178
|
+
/** Seed → FNV-1a offset basis (non-finite numbers fall back to the default). */
|
|
1179
|
+
function seedToBasis(seed) {
|
|
1180
|
+
if (seed === void 0) return 2166136261;
|
|
1181
|
+
if (typeof seed === "bigint") return Number(BigInt.asUintN(32, seed)) >>> 0;
|
|
1182
|
+
return Number.isFinite(seed) ? Math.trunc(seed) >>> 0 : 2166136261;
|
|
1183
|
+
}
|
|
1072
1184
|
function isWideChar(c) {
|
|
1073
1185
|
return c >= 4352 && (c <= 4447 || c === 9001 || c === 9002 || c >= 11904 && c <= 42191 && c !== 12351 || c >= 44032 && c <= 55203 || c >= 63744 && c <= 64255 || c >= 65040 && c <= 65049 || c >= 65072 && c <= 65135 || c >= 65280 && c <= 65376 || c >= 65504 && c <= 65510 || c >= 127744 && c <= 129791 || c >= 131072 && c <= 262141);
|
|
1074
1186
|
}
|
|
@@ -1399,6 +1511,13 @@ function bunStripANSI(text) {
|
|
|
1399
1511
|
}
|
|
1400
1512
|
return out;
|
|
1401
1513
|
}
|
|
1514
|
+
function bunWhich(command, options) {
|
|
1515
|
+
const cwd = options?.cwd;
|
|
1516
|
+
return findOnPath(cwd !== void 0 && !path.isAbsolute(command) && (command.includes("/") || command.includes("\\")) ? path.resolve(cwd, command) : command, options?.PATH !== void 0 ? {
|
|
1517
|
+
...process.env,
|
|
1518
|
+
PATH: options.PATH
|
|
1519
|
+
} : process.env) ?? null;
|
|
1520
|
+
}
|
|
1402
1521
|
function installBunShim() {
|
|
1403
1522
|
patchBase64();
|
|
1404
1523
|
const g = globalThis;
|
|
@@ -1407,6 +1526,7 @@ function installBunShim() {
|
|
|
1407
1526
|
file: (p) => new BunFileShim(p),
|
|
1408
1527
|
write: bunWrite,
|
|
1409
1528
|
env: process.env,
|
|
1529
|
+
which: bunWhich,
|
|
1410
1530
|
sleep: bunSleep,
|
|
1411
1531
|
hash: bunHash,
|
|
1412
1532
|
randomUUIDv7: bunRandomUUIDv7,
|
|
@@ -1518,7 +1638,7 @@ var CookieMap = class {
|
|
|
1518
1638
|
}
|
|
1519
1639
|
};
|
|
1520
1640
|
//#endregion
|
|
1521
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@
|
|
1641
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/logger/rotating-file.ts
|
|
1522
1642
|
/** Behavior-compatible reimplementation of winston-daily-rotate-file's used surface. */
|
|
1523
1643
|
function isAuditEntry(value) {
|
|
1524
1644
|
if (value === null || typeof value !== "object") return false;
|
|
@@ -1633,7 +1753,7 @@ var RotatingFileSink = class {
|
|
|
1633
1753
|
}
|
|
1634
1754
|
};
|
|
1635
1755
|
//#endregion
|
|
1636
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@
|
|
1756
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/logger.ts
|
|
1637
1757
|
/**
|
|
1638
1758
|
* Centralized logger for omp.
|
|
1639
1759
|
*
|
|
@@ -1708,20 +1828,25 @@ function pruneStaleProcessLogs(dir) {
|
|
|
1708
1828
|
} catch {}
|
|
1709
1829
|
continue;
|
|
1710
1830
|
}
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
});
|
|
1719
|
-
staleLogsByProcessDay.set(key, staleLogs);
|
|
1720
|
-
} catch {}
|
|
1831
|
+
const key = `${pidText}:${logMatch[1]}`;
|
|
1832
|
+
const staleLogs = staleLogsByProcessDay.get(key) ?? [];
|
|
1833
|
+
staleLogs.push({
|
|
1834
|
+
path: entryPath,
|
|
1835
|
+
rollover: Number(logMatch[3] ?? 0)
|
|
1836
|
+
});
|
|
1837
|
+
staleLogsByProcessDay.set(key, staleLogs);
|
|
1721
1838
|
}
|
|
1722
1839
|
for (const staleLogs of staleLogsByProcessDay.values()) {
|
|
1723
|
-
|
|
1724
|
-
|
|
1840
|
+
if (staleLogs.length <= RETAINED_STALE_LOGS_PER_PROCESS_DAY) continue;
|
|
1841
|
+
const ranked = [];
|
|
1842
|
+
for (const stale of staleLogs) try {
|
|
1843
|
+
ranked.push({
|
|
1844
|
+
...stale,
|
|
1845
|
+
mtimeMs: fs.statSync(stale.path).mtimeMs
|
|
1846
|
+
});
|
|
1847
|
+
} catch {}
|
|
1848
|
+
ranked.sort((a, b) => b.mtimeMs - a.mtimeMs || b.rollover - a.rollover || (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));
|
|
1849
|
+
for (const stale of ranked.slice(RETAINED_STALE_LOGS_PER_PROCESS_DAY)) try {
|
|
1725
1850
|
fs.rmSync(stale.path, { force: true });
|
|
1726
1851
|
} catch {}
|
|
1727
1852
|
}
|
|
@@ -1897,7 +2022,7 @@ function time(op, fn, ...args) {
|
|
|
1897
2022
|
}
|
|
1898
2023
|
}
|
|
1899
2024
|
//#endregion
|
|
1900
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@
|
|
2025
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/frontmatter.ts
|
|
1901
2026
|
function stripHtmlComments(content) {
|
|
1902
2027
|
return content.replace(/<!--[\s\S]*?-->/g, "");
|
|
1903
2028
|
}
|
|
@@ -2047,49 +2172,29 @@ function parseFrontmatter(content, options) {
|
|
|
2047
2172
|
};
|
|
2048
2173
|
}
|
|
2049
2174
|
}
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
function isFsError(err) {
|
|
2053
|
-
return err instanceof Error && "code" in err && typeof err.code === "string";
|
|
2054
|
-
}
|
|
2055
|
-
function isEnoent(err) {
|
|
2056
|
-
return isFsError(err) && err.code === "ENOENT";
|
|
2057
|
-
}
|
|
2058
|
-
function isEnotdir(err) {
|
|
2059
|
-
return isFsError(err) && err.code === "ENOTDIR";
|
|
2060
|
-
}
|
|
2061
|
-
function hasFsCode(err, code) {
|
|
2062
|
-
return isFsError(err) && err.code === code;
|
|
2063
|
-
}
|
|
2064
|
-
//#endregion
|
|
2065
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@17.3.5/node_modules/@oh-my-pi/pi-utils/src/json-parse.ts
|
|
2066
|
-
const QUOTE = 34;
|
|
2067
|
-
const BACKSLASH = 92;
|
|
2068
|
-
const U = 117;
|
|
2069
|
-
const SQUOTE = 39;
|
|
2175
|
+
const U$1 = 117;
|
|
2176
|
+
/** Valid chars after `\` in a strict JSON escape: `" \ / b f n r t u`. */
|
|
2070
2177
|
const VALID_ESCAPE_CHAR = /* @__PURE__ */ new Uint8Array(128);
|
|
2071
2178
|
for (const ch of "\"\\/bfnrtu") VALID_ESCAPE_CHAR[ch.charCodeAt(0)] = 1;
|
|
2072
|
-
(() => {
|
|
2073
|
-
const e = [];
|
|
2074
|
-
e[8] = "\\b";
|
|
2075
|
-
e[9] = "\\t";
|
|
2076
|
-
e[10] = "\\n";
|
|
2077
|
-
e[12] = "\\f";
|
|
2078
|
-
e[13] = "\\r";
|
|
2079
|
-
for (let cp = 0; cp <= 31; cp++) e[cp] ??= `\\u${cp.toString(16).padStart(4, "0")}`;
|
|
2080
|
-
return e;
|
|
2081
|
-
})();
|
|
2082
|
-
const HEX4_RE = /^[0-9a-fA-F]{4}$/;
|
|
2083
2179
|
function isHexDigit(cp) {
|
|
2084
2180
|
return cp >= 48 && cp <= 57 || (cp | 32) >= 97 && (cp | 32) <= 102;
|
|
2085
2181
|
}
|
|
2182
|
+
/** JSON insignificant whitespace (RFC 8259 §2). */
|
|
2086
2183
|
function isWhitespace(cp) {
|
|
2087
2184
|
return cp === 32 || cp === 9 || cp === 10 || cp === 13;
|
|
2088
2185
|
}
|
|
2089
2186
|
function isIdentChar(cp) {
|
|
2090
2187
|
return cp >= 48 && cp <= 57 || (cp | 32) >= 97 && (cp | 32) <= 122 || cp === 95 || cp === 36;
|
|
2091
2188
|
}
|
|
2092
|
-
/**
|
|
2189
|
+
/** First char of a numeric token: sign, dot, or digit. */
|
|
2190
|
+
function isNumberStart(cp) {
|
|
2191
|
+
return cp === 45 || cp === 43 || cp === 46 || cp >= 48 && cp <= 57;
|
|
2192
|
+
}
|
|
2193
|
+
/** Chars that may continue a relaxed numeric token: digits, sign, dot, exponent, radix prefix, hex digits. */
|
|
2194
|
+
function isNumberChar(cp) {
|
|
2195
|
+
return cp >= 48 && cp <= 57 || cp === 45 || cp === 43 || cp === 46 || (cp | 32) >= 97 && (cp | 32) <= 102 || (cp | 32) === 120;
|
|
2196
|
+
}
|
|
2197
|
+
/** Keyword literals: standard JSON plus Python `True`/`False`/`None`. */
|
|
2093
2198
|
const KEYWORDS = [
|
|
2094
2199
|
["true", true],
|
|
2095
2200
|
["false", false],
|
|
@@ -2109,216 +2214,129 @@ const NON_RECOVERABLE_BAREWORDS = {
|
|
|
2109
2214
|
"+Infinity": true,
|
|
2110
2215
|
undefined: true
|
|
2111
2216
|
};
|
|
2217
|
+
/** Decode four hex digits at `pos`, or `-1` when fewer than four hex digits are available. */
|
|
2218
|
+
function hex4(s, pos) {
|
|
2219
|
+
if (pos + 4 > s.length) return -1;
|
|
2220
|
+
let value = 0;
|
|
2221
|
+
for (let k = pos; k < pos + 4; k++) {
|
|
2222
|
+
if (!isHexDigit(s.charCodeAt(k))) return -1;
|
|
2223
|
+
value = value << 4 | parseInt(s[k], 16);
|
|
2224
|
+
}
|
|
2225
|
+
return value;
|
|
2226
|
+
}
|
|
2112
2227
|
/**
|
|
2113
|
-
*
|
|
2114
|
-
*
|
|
2115
|
-
*
|
|
2116
|
-
*/
|
|
2117
|
-
const INCOMPLETE = Symbol("incomplete");
|
|
2118
|
-
/**
|
|
2119
|
-
* Recursive-descent parser for a forgiving superset of JSON. Beyond strict JSON
|
|
2120
|
-
* it accepts, and normalizes, the malformations LLM tool-call bodies leak in
|
|
2121
|
-
* practice:
|
|
2122
|
-
*
|
|
2123
|
-
* - single-quoted strings and unquoted object keys (JSON5);
|
|
2124
|
-
* - trailing / stray commas, and `//` + block comments;
|
|
2125
|
-
* - Python literals `True` / `False` / `None` and JS `NaN` / `Infinity`;
|
|
2126
|
-
* - raw control characters and invalid `\x` escapes inside strings (kept literally);
|
|
2127
|
-
* - unescaped quotes inside strings — a quote only closes a string when followed
|
|
2128
|
-
* by a value terminator, recovering apostrophes such as `'it's'`;
|
|
2129
|
-
* - unquoted string values in object/array value position (strict mode only) —
|
|
2130
|
-
* an unrecognized bareword such as `{"paths": packages/foo/*}` is recovered as
|
|
2131
|
-
* a string up to the next `,` / `}` / `]` / newline.
|
|
2132
|
-
*
|
|
2133
|
-
* In `partial` mode an unterminated string/object/array (or a value cut off at
|
|
2134
|
-
* end-of-input) is auto-closed with whatever was parsed so far — for streaming.
|
|
2135
|
-
* In strict mode, end-of-input mid-value and trailing garbage both throw, so a
|
|
2136
|
-
* final parse never silently accepts a half-formed tool call.
|
|
2228
|
+
* Index of the first char at or after `i` that is not whitespace or part of a
|
|
2229
|
+
* `//` line / `/* *\/` block comment. A lone `/` at the end of input is not a
|
|
2230
|
+
* comment and is left in place.
|
|
2137
2231
|
*/
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
}
|
|
2148
|
-
parse() {
|
|
2149
|
-
this.#ws();
|
|
2150
|
-
if (this.#i >= this.#n) {
|
|
2151
|
-
if (this.#partial) return void 0;
|
|
2152
|
-
throw new SyntaxError("Unexpected end of JSON input");
|
|
2153
|
-
}
|
|
2154
|
-
const value = this.#value(false);
|
|
2155
|
-
if (value === INCOMPLETE) return void 0;
|
|
2156
|
-
this.#ws();
|
|
2157
|
-
if (!this.#partial && this.#i < this.#n) throw new SyntaxError(`Unexpected trailing characters at position ${this.#i}`);
|
|
2158
|
-
return value;
|
|
2159
|
-
}
|
|
2160
|
-
#ws() {
|
|
2161
|
-
const s = this.#s;
|
|
2162
|
-
for (;;) {
|
|
2163
|
-
while (this.#i < this.#n && isWhitespace(s.charCodeAt(this.#i))) this.#i++;
|
|
2164
|
-
if (this.#i + 1 < this.#n && s.charCodeAt(this.#i) === 47) {
|
|
2165
|
-
const next = s.charCodeAt(this.#i + 1);
|
|
2166
|
-
if (next === 47) {
|
|
2167
|
-
this.#i += 2;
|
|
2168
|
-
while (this.#i < this.#n && s.charCodeAt(this.#i) !== 10) this.#i++;
|
|
2169
|
-
continue;
|
|
2170
|
-
}
|
|
2171
|
-
if (next === 42) {
|
|
2172
|
-
this.#i += 2;
|
|
2173
|
-
while (this.#i + 1 < this.#n && !(s.charCodeAt(this.#i) === 42 && s.charCodeAt(this.#i + 1) === 47)) this.#i++;
|
|
2174
|
-
this.#i = Math.min(this.#i + 2, this.#n);
|
|
2175
|
-
continue;
|
|
2176
|
-
}
|
|
2177
|
-
}
|
|
2178
|
-
break;
|
|
2179
|
-
}
|
|
2180
|
-
}
|
|
2181
|
-
#value(allowBareword) {
|
|
2182
|
-
const s = this.#s;
|
|
2183
|
-
const c = s[this.#i];
|
|
2184
|
-
if (c === "{") return this.#object();
|
|
2185
|
-
if (c === "[") return this.#array();
|
|
2186
|
-
if (c === "\"" || c === "'") return this.#string(s.charCodeAt(this.#i));
|
|
2187
|
-
const cc = s.charCodeAt(this.#i);
|
|
2188
|
-
if (cc === 45 || cc === 43 || cc === 46 || cc >= 48 && cc <= 57) return this.#number();
|
|
2189
|
-
return this.#keyword(allowBareword);
|
|
2190
|
-
}
|
|
2191
|
-
#object() {
|
|
2192
|
-
this.#i++;
|
|
2193
|
-
const out = {};
|
|
2194
|
-
for (;;) {
|
|
2195
|
-
this.#ws();
|
|
2196
|
-
if (this.#i >= this.#n) {
|
|
2197
|
-
if (this.#partial) return out;
|
|
2198
|
-
throw new SyntaxError("Unterminated object");
|
|
2199
|
-
}
|
|
2200
|
-
const c = this.#s[this.#i];
|
|
2201
|
-
if (c === "}") {
|
|
2202
|
-
this.#i++;
|
|
2203
|
-
return out;
|
|
2204
|
-
}
|
|
2205
|
-
if (c === ",") {
|
|
2206
|
-
this.#i++;
|
|
2232
|
+
function skipInsignificant(s, i) {
|
|
2233
|
+
const n = s.length;
|
|
2234
|
+
for (;;) {
|
|
2235
|
+
while (i < n && isWhitespace(s.charCodeAt(i))) i++;
|
|
2236
|
+
if (i + 1 < n && s.charCodeAt(i) === 47) {
|
|
2237
|
+
const next = s.charCodeAt(i + 1);
|
|
2238
|
+
if (next === 47) {
|
|
2239
|
+
i += 2;
|
|
2240
|
+
while (i < n && s.charCodeAt(i) !== 10) i++;
|
|
2207
2241
|
continue;
|
|
2208
2242
|
}
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
else throw new SyntaxError("Expected ':' in object");
|
|
2214
|
-
this.#ws();
|
|
2215
|
-
if (this.#i >= this.#n) {
|
|
2216
|
-
if (this.#partial) return out;
|
|
2217
|
-
throw new SyntaxError("Expected value after ':'");
|
|
2218
|
-
}
|
|
2219
|
-
const value = this.#value(true);
|
|
2220
|
-
if (value === INCOMPLETE) return out;
|
|
2221
|
-
out[key] = value;
|
|
2222
|
-
this.#ws();
|
|
2223
|
-
const d = this.#i < this.#n ? this.#s[this.#i] : "";
|
|
2224
|
-
if (d === ",") {
|
|
2225
|
-
this.#i++;
|
|
2243
|
+
if (next === 42) {
|
|
2244
|
+
i += 2;
|
|
2245
|
+
while (i + 1 < n && !(s.charCodeAt(i) === 42 && s.charCodeAt(i + 1) === 47)) i++;
|
|
2246
|
+
i = Math.min(i + 2, n);
|
|
2226
2247
|
continue;
|
|
2227
2248
|
}
|
|
2228
|
-
if (d === "}") {
|
|
2229
|
-
this.#i++;
|
|
2230
|
-
return out;
|
|
2231
|
-
}
|
|
2232
|
-
if (this.#partial) return out;
|
|
2233
|
-
throw new SyntaxError("Expected ',' or '}' in object");
|
|
2234
2249
|
}
|
|
2250
|
+
return i;
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
/** Reading of the lookahead past a candidate closing quote. */
|
|
2254
|
+
var QuoteLook = /* @__PURE__ */ function(QuoteLook) {
|
|
2255
|
+
/** A value terminator (or end of input) follows: the quote closes. */
|
|
2256
|
+
QuoteLook[QuoteLook["Closes"] = 0] = "Closes";
|
|
2257
|
+
/** Ordinary content follows: the quote is literal (inner-quote recovery). */
|
|
2258
|
+
QuoteLook[QuoteLook["Inner"] = 1] = "Inner";
|
|
2259
|
+
/** A lone `/` at the buffer edge may still grow into a comment and flip this quote from inner to closing. */
|
|
2260
|
+
QuoteLook[QuoteLook["Undecided"] = 2] = "Undecided";
|
|
2261
|
+
return QuoteLook;
|
|
2262
|
+
}(QuoteLook || {});
|
|
2263
|
+
/**
|
|
2264
|
+
* Cursor over the input with the tolerant token readers. `pos` is the current
|
|
2265
|
+
* offset; readers advance it. In `strict` mode a truncated or malformed token
|
|
2266
|
+
* throws `SyntaxError`; the lenient modes report progress or return
|
|
2267
|
+
* `undefined` so the caller can roll back.
|
|
2268
|
+
*/
|
|
2269
|
+
var JsonLexer = class {
|
|
2270
|
+
src;
|
|
2271
|
+
mode;
|
|
2272
|
+
pos;
|
|
2273
|
+
constructor(src, mode, pos = 0) {
|
|
2274
|
+
this.src = src;
|
|
2275
|
+
this.mode = mode;
|
|
2276
|
+
this.pos = pos;
|
|
2277
|
+
}
|
|
2278
|
+
get atEnd() {
|
|
2279
|
+
return this.pos >= this.src.length;
|
|
2280
|
+
}
|
|
2281
|
+
/** Char code at the cursor; `NaN` at end of input (so every comparison is false). */
|
|
2282
|
+
peek() {
|
|
2283
|
+
return this.src.charCodeAt(this.pos);
|
|
2284
|
+
}
|
|
2285
|
+
/** Skip whitespace plus `//` line and `/* *\/` block comments. */
|
|
2286
|
+
ws() {
|
|
2287
|
+
this.pos = skipInsignificant(this.src, this.pos);
|
|
2235
2288
|
}
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
const c = this.#s[this.#i];
|
|
2246
|
-
if (c === "]") {
|
|
2247
|
-
this.#i++;
|
|
2248
|
-
return out;
|
|
2249
|
-
}
|
|
2250
|
-
if (c === ",") {
|
|
2251
|
-
this.#i++;
|
|
2252
|
-
continue;
|
|
2253
|
-
}
|
|
2254
|
-
const value = this.#value(true);
|
|
2255
|
-
if (value === INCOMPLETE) return out;
|
|
2256
|
-
out.push(value);
|
|
2257
|
-
this.#ws();
|
|
2258
|
-
const d = this.#i < this.#n ? this.#s[this.#i] : "";
|
|
2259
|
-
if (d === ",") {
|
|
2260
|
-
this.#i++;
|
|
2261
|
-
continue;
|
|
2262
|
-
}
|
|
2263
|
-
if (d === "]") {
|
|
2264
|
-
this.#i++;
|
|
2265
|
-
return out;
|
|
2266
|
-
}
|
|
2267
|
-
if (this.#partial) return out;
|
|
2268
|
-
throw new SyntaxError("Expected ',' or ']' in array");
|
|
2269
|
-
}
|
|
2270
|
-
}
|
|
2271
|
-
#key() {
|
|
2272
|
-
const c = this.#s[this.#i];
|
|
2273
|
-
if (c === "\"" || c === "'") return this.#string(this.#s.charCodeAt(this.#i));
|
|
2274
|
-
const start = this.#i;
|
|
2275
|
-
while (this.#i < this.#n) {
|
|
2276
|
-
const ch = this.#s[this.#i];
|
|
2277
|
-
if (ch === ":" || ch === "," || ch === "}" || isWhitespace(this.#s.charCodeAt(this.#i))) break;
|
|
2278
|
-
this.#i++;
|
|
2279
|
-
}
|
|
2280
|
-
if (this.#i === start) {
|
|
2281
|
-
if (this.#partial) return "";
|
|
2282
|
-
throw new SyntaxError("Expected object key");
|
|
2283
|
-
}
|
|
2284
|
-
return this.#s.slice(start, this.#i);
|
|
2285
|
-
}
|
|
2286
|
-
#string(quote) {
|
|
2287
|
-
const s = this.#s;
|
|
2288
|
-
const n = this.#n;
|
|
2289
|
-
let i = this.#i + 1;
|
|
2289
|
+
/**
|
|
2290
|
+
* Read a string starting at the opening `quote`, retaining the information
|
|
2291
|
+
* an incremental consumer needs. Strict mode throws on an unterminated
|
|
2292
|
+
* string; lenient modes consume to the end of input and report progress.
|
|
2293
|
+
*/
|
|
2294
|
+
string(quote) {
|
|
2295
|
+
const s = this.src;
|
|
2296
|
+
const n = s.length;
|
|
2297
|
+
let i = this.pos + 1;
|
|
2290
2298
|
let out = "";
|
|
2291
2299
|
let runStart = i;
|
|
2300
|
+
let unstableFrom = -1;
|
|
2301
|
+
const lenient = quote === 39 || this.mode === "streaming";
|
|
2292
2302
|
while (i < n) {
|
|
2293
2303
|
const cc = s.charCodeAt(i);
|
|
2294
|
-
if (cc !==
|
|
2304
|
+
if (cc !== 92 && cc !== quote) {
|
|
2295
2305
|
i++;
|
|
2296
2306
|
continue;
|
|
2297
2307
|
}
|
|
2298
2308
|
if (cc === quote) {
|
|
2299
|
-
|
|
2309
|
+
const look = lenient ? this.#quoteLookahead(i + 1) : 0;
|
|
2310
|
+
if (look === 0) {
|
|
2300
2311
|
out += s.slice(runStart, i);
|
|
2301
|
-
this
|
|
2302
|
-
return
|
|
2312
|
+
this.pos = i + 1;
|
|
2313
|
+
return {
|
|
2314
|
+
value: out,
|
|
2315
|
+
stableLen: out.length,
|
|
2316
|
+
complete: true
|
|
2317
|
+
};
|
|
2303
2318
|
}
|
|
2319
|
+
if (look === 2 && unstableFrom < 0) unstableFrom = out.length + (i - runStart);
|
|
2304
2320
|
i++;
|
|
2305
2321
|
continue;
|
|
2306
2322
|
}
|
|
2307
2323
|
out += s.slice(runStart, i);
|
|
2324
|
+
const escapeStart = out.length;
|
|
2308
2325
|
i++;
|
|
2309
2326
|
if (i >= n) {
|
|
2327
|
+
if (unstableFrom < 0) unstableFrom = escapeStart;
|
|
2310
2328
|
out += "\\";
|
|
2311
2329
|
runStart = i;
|
|
2312
2330
|
break;
|
|
2313
2331
|
}
|
|
2314
2332
|
switch (s.charCodeAt(i)) {
|
|
2315
|
-
case
|
|
2333
|
+
case 34:
|
|
2316
2334
|
out += "\"";
|
|
2317
2335
|
break;
|
|
2318
|
-
case
|
|
2336
|
+
case 39:
|
|
2319
2337
|
out += "'";
|
|
2320
2338
|
break;
|
|
2321
|
-
case
|
|
2339
|
+
case 92:
|
|
2322
2340
|
out += "\\";
|
|
2323
2341
|
break;
|
|
2324
2342
|
case 47:
|
|
@@ -2339,12 +2357,16 @@ var RelaxedJson = class {
|
|
|
2339
2357
|
case 116:
|
|
2340
2358
|
out += " ";
|
|
2341
2359
|
break;
|
|
2342
|
-
case U: {
|
|
2343
|
-
const
|
|
2344
|
-
if (
|
|
2345
|
-
out += String.fromCharCode(parseInt(hex, 16));
|
|
2360
|
+
case U$1: {
|
|
2361
|
+
const unit = hex4(s, i + 1);
|
|
2362
|
+
if (unit >= 0) {
|
|
2346
2363
|
i += 4;
|
|
2347
|
-
|
|
2364
|
+
out += String.fromCharCode(unit);
|
|
2365
|
+
if (unit >= 55296 && unit < 56320 && this.mode !== "strict" && i + 7 > n && unstableFrom < 0) unstableFrom = escapeStart;
|
|
2366
|
+
} else {
|
|
2367
|
+
if (i + 5 > n && this.mode !== "strict" && unstableFrom < 0) unstableFrom = escapeStart;
|
|
2368
|
+
out += "\\u";
|
|
2369
|
+
}
|
|
2348
2370
|
break;
|
|
2349
2371
|
}
|
|
2350
2372
|
default: out += `\\${s[i]}`;
|
|
@@ -2352,82 +2374,264 @@ var RelaxedJson = class {
|
|
|
2352
2374
|
i++;
|
|
2353
2375
|
runStart = i;
|
|
2354
2376
|
}
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
const
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2377
|
+
if (this.mode === "strict") throw new SyntaxError("Unterminated string");
|
|
2378
|
+
out += s.slice(runStart, n);
|
|
2379
|
+
this.pos = i;
|
|
2380
|
+
return {
|
|
2381
|
+
value: out,
|
|
2382
|
+
stableLen: unstableFrom < 0 ? out.length : unstableFrom,
|
|
2383
|
+
complete: false
|
|
2384
|
+
};
|
|
2385
|
+
}
|
|
2386
|
+
/**
|
|
2387
|
+
* Classify the lookahead after a candidate closing quote: a quote closes a
|
|
2388
|
+
* string only when the next significant char (past whitespace and comments)
|
|
2389
|
+
* ends a value.
|
|
2390
|
+
*/
|
|
2391
|
+
#quoteLookahead(from) {
|
|
2392
|
+
const s = this.src;
|
|
2393
|
+
const k = skipInsignificant(s, from);
|
|
2394
|
+
if (k >= s.length) return 0;
|
|
2395
|
+
const c = s.charCodeAt(k);
|
|
2396
|
+
if (c === 44 || c === 125 || c === 93 || c === 58) return 0;
|
|
2397
|
+
if (c === 47 && k + 1 === s.length && this.mode !== "strict") return 2;
|
|
2398
|
+
return 1;
|
|
2399
|
+
}
|
|
2400
|
+
/**
|
|
2401
|
+
* Read a numeric token with JS `Number()` semantics (decimal with optional
|
|
2402
|
+
* sign / leading or trailing dot / exponent, plus `0x` hex and `0b` binary).
|
|
2403
|
+
* Non-finite or malformed tokens throw in strict mode and return
|
|
2404
|
+
* `undefined` in lenient modes; the cursor is left past the token either way.
|
|
2405
|
+
*/
|
|
2406
|
+
number() {
|
|
2407
|
+
const s = this.src;
|
|
2408
|
+
const start = this.pos;
|
|
2409
|
+
let i = start;
|
|
2410
|
+
while (i < s.length && isNumberChar(s.charCodeAt(i))) i++;
|
|
2411
|
+
this.pos = i;
|
|
2412
|
+
const token = s.slice(start, i);
|
|
2413
|
+
const value = Number(token);
|
|
2414
|
+
if (Number.isFinite(value)) return value;
|
|
2415
|
+
if (this.mode === "strict") throw new SyntaxError(`Invalid number: ${token}`);
|
|
2386
2416
|
}
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2417
|
+
/**
|
|
2418
|
+
* Match a keyword literal at the cursor; consumes only on success and
|
|
2419
|
+
* returns `undefined` otherwise. Requires a non-identifier boundary so
|
|
2420
|
+
* `Truex` / `nullish` are not misread as the keyword followed by junk.
|
|
2421
|
+
*/
|
|
2422
|
+
keyword() {
|
|
2423
|
+
const s = this.src;
|
|
2424
|
+
for (const [word, value] of KEYWORDS) if (s.startsWith(word, this.pos) && !isIdentChar(s.charCodeAt(this.pos + word.length))) {
|
|
2425
|
+
this.pos += word.length;
|
|
2392
2426
|
return value;
|
|
2393
2427
|
}
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2428
|
+
}
|
|
2429
|
+
/** Read an unquoted object key: everything up to `:` / `,` / `}` / whitespace. May be empty. */
|
|
2430
|
+
unquotedKey() {
|
|
2431
|
+
const s = this.src;
|
|
2432
|
+
const start = this.pos;
|
|
2433
|
+
let i = start;
|
|
2434
|
+
while (i < s.length) {
|
|
2435
|
+
const cc = s.charCodeAt(i);
|
|
2436
|
+
if (cc === 58 || cc === 44 || cc === 125 || isWhitespace(cc)) break;
|
|
2437
|
+
i++;
|
|
2397
2438
|
}
|
|
2398
|
-
|
|
2399
|
-
|
|
2439
|
+
this.pos = i;
|
|
2440
|
+
return s.slice(start, i);
|
|
2400
2441
|
}
|
|
2401
2442
|
/**
|
|
2402
|
-
*
|
|
2403
|
-
*
|
|
2404
|
-
*
|
|
2405
|
-
*
|
|
2443
|
+
* Recover an unquoted string value, e.g. `{"paths": packages/foo/*}`:
|
|
2444
|
+
* consume until `,` / `}` / `]` / newline and trim trailing whitespace.
|
|
2445
|
+
* Recovery still fails — so a final parse never accepts a half-formed or
|
|
2446
|
+
* non-finite argument — when the token:
|
|
2406
2447
|
* - hits end-of-input before a delimiter (truncated value);
|
|
2407
|
-
* - contains a `"`, `{`, `[`, or a key-like `:` — this
|
|
2408
|
-
* unquoted keys, so a missed comma (`{"a": foo "b": 1}
|
|
2409
|
-
*
|
|
2410
|
-
*
|
|
2448
|
+
* - contains a `"`, `{`, `[`, or a key-like `:` — this grammar accepts
|
|
2449
|
+
* unquoted keys, so a missed comma (`{"a": foo "b": 1}`) would otherwise
|
|
2450
|
+
* silently swallow the following field. A colon followed by `/` or `\`
|
|
2451
|
+
* stays literal so URL and Windows-path values recover;
|
|
2411
2452
|
* - is a non-finite atom ({@link NON_RECOVERABLE_BAREWORDS}).
|
|
2453
|
+
*
|
|
2454
|
+
* Failure throws in strict mode and returns `undefined` in lenient modes.
|
|
2412
2455
|
*/
|
|
2413
|
-
|
|
2414
|
-
const s = this
|
|
2415
|
-
const start = this
|
|
2456
|
+
bareword() {
|
|
2457
|
+
const s = this.src;
|
|
2458
|
+
const start = this.pos;
|
|
2416
2459
|
let i = start;
|
|
2417
|
-
while (i <
|
|
2460
|
+
while (i < s.length) {
|
|
2418
2461
|
const cc = s.charCodeAt(i);
|
|
2419
2462
|
if (cc === 44 || cc === 125 || cc === 93 || cc === 10 || cc === 13) break;
|
|
2420
|
-
if (cc ===
|
|
2463
|
+
if (cc === 34 || cc === 123 || cc === 91 || cc === 58 && s.charCodeAt(i + 1) !== 47 && s.charCodeAt(i + 1) !== 92) return this.#unexpected(start);
|
|
2421
2464
|
i++;
|
|
2422
2465
|
}
|
|
2423
|
-
if (i >=
|
|
2466
|
+
if (i >= s.length) return this.#unexpected(start);
|
|
2424
2467
|
let end = i;
|
|
2425
2468
|
while (end > start && isWhitespace(s.charCodeAt(end - 1))) end--;
|
|
2426
2469
|
const word = s.slice(start, end);
|
|
2427
|
-
if (NON_RECOVERABLE_BAREWORDS[word])
|
|
2428
|
-
this
|
|
2470
|
+
if (NON_RECOVERABLE_BAREWORDS[word]) return this.#unexpected(start);
|
|
2471
|
+
this.pos = i;
|
|
2429
2472
|
return word;
|
|
2430
2473
|
}
|
|
2474
|
+
#unexpected(at) {
|
|
2475
|
+
if (this.mode === "strict") throw new SyntaxError(`Unexpected token at position ${at}`);
|
|
2476
|
+
}
|
|
2477
|
+
};
|
|
2478
|
+
//#endregion
|
|
2479
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/json-parse.ts
|
|
2480
|
+
const U = 117;
|
|
2481
|
+
(() => {
|
|
2482
|
+
const e = [];
|
|
2483
|
+
e[8] = "\\b";
|
|
2484
|
+
e[9] = "\\t";
|
|
2485
|
+
e[10] = "\\n";
|
|
2486
|
+
e[12] = "\\f";
|
|
2487
|
+
e[13] = "\\r";
|
|
2488
|
+
for (let cp = 0; cp <= 31; cp++) e[cp] ??= `\\u${cp.toString(16).padStart(4, "0")}`;
|
|
2489
|
+
return e;
|
|
2490
|
+
})();
|
|
2491
|
+
/**
|
|
2492
|
+
* Sentinel returned by partial-mode value parsing when an atomic value
|
|
2493
|
+
* (number / keyword) is incomplete at the streaming edge, so the enclosing
|
|
2494
|
+
* object/array rolls back to the last valid prefix instead of committing junk.
|
|
2495
|
+
*/
|
|
2496
|
+
const INCOMPLETE = Symbol("incomplete");
|
|
2497
|
+
/**
|
|
2498
|
+
* Recursive-descent tree builder over the tolerant {@link JsonLexer} grammar
|
|
2499
|
+
* (single quotes, unquoted keys, comments, Python literals, stray commas,
|
|
2500
|
+
* literal invalid escapes, apostrophe recovery, bareword values).
|
|
2501
|
+
*
|
|
2502
|
+
* In `partial` mode (lexer mode `streaming`) an unterminated string/object/array
|
|
2503
|
+
* (or a value cut off at end-of-input) is auto-closed with whatever was parsed
|
|
2504
|
+
* so far, and an incomplete trailing atom rolls the enclosing container back
|
|
2505
|
+
* to its last valid prefix. In strict mode, end-of-input mid-value and trailing
|
|
2506
|
+
* garbage both throw, so a final parse never silently accepts a half-formed
|
|
2507
|
+
* tool call.
|
|
2508
|
+
*/
|
|
2509
|
+
var RelaxedJson = class {
|
|
2510
|
+
#lex;
|
|
2511
|
+
#partial;
|
|
2512
|
+
constructor(source, partial) {
|
|
2513
|
+
this.#lex = new JsonLexer(source, partial ? "streaming" : "strict");
|
|
2514
|
+
this.#partial = partial;
|
|
2515
|
+
}
|
|
2516
|
+
parse() {
|
|
2517
|
+
const lex = this.#lex;
|
|
2518
|
+
lex.ws();
|
|
2519
|
+
if (lex.atEnd) {
|
|
2520
|
+
if (this.#partial) return void 0;
|
|
2521
|
+
throw new SyntaxError("Unexpected end of JSON input");
|
|
2522
|
+
}
|
|
2523
|
+
const value = this.#value(false);
|
|
2524
|
+
if (value === INCOMPLETE) return void 0;
|
|
2525
|
+
lex.ws();
|
|
2526
|
+
if (!this.#partial && !lex.atEnd) throw new SyntaxError(`Unexpected trailing characters at position ${lex.pos}`);
|
|
2527
|
+
return value;
|
|
2528
|
+
}
|
|
2529
|
+
#value(allowBareword) {
|
|
2530
|
+
const lex = this.#lex;
|
|
2531
|
+
const c = lex.peek();
|
|
2532
|
+
if (c === 123) return this.#object();
|
|
2533
|
+
if (c === 91) return this.#array();
|
|
2534
|
+
if (c === 34 || c === 39) return lex.string(c).value;
|
|
2535
|
+
if (isNumberStart(c)) return lex.number() ?? INCOMPLETE;
|
|
2536
|
+
const keyword = lex.keyword();
|
|
2537
|
+
if (keyword !== void 0) return keyword;
|
|
2538
|
+
if (this.#partial) {
|
|
2539
|
+
lex.pos = lex.src.length;
|
|
2540
|
+
return INCOMPLETE;
|
|
2541
|
+
}
|
|
2542
|
+
if (allowBareword) return lex.bareword();
|
|
2543
|
+
throw new SyntaxError(`Unexpected token at position ${lex.pos}`);
|
|
2544
|
+
}
|
|
2545
|
+
#object() {
|
|
2546
|
+
const lex = this.#lex;
|
|
2547
|
+
lex.pos++;
|
|
2548
|
+
const out = {};
|
|
2549
|
+
for (;;) {
|
|
2550
|
+
lex.ws();
|
|
2551
|
+
if (lex.atEnd) {
|
|
2552
|
+
if (this.#partial) return out;
|
|
2553
|
+
throw new SyntaxError("Unterminated object");
|
|
2554
|
+
}
|
|
2555
|
+
const c = lex.peek();
|
|
2556
|
+
if (c === 125) {
|
|
2557
|
+
lex.pos++;
|
|
2558
|
+
return out;
|
|
2559
|
+
}
|
|
2560
|
+
if (c === 44) {
|
|
2561
|
+
lex.pos++;
|
|
2562
|
+
continue;
|
|
2563
|
+
}
|
|
2564
|
+
const key = this.#key();
|
|
2565
|
+
lex.ws();
|
|
2566
|
+
if (lex.peek() === 58) lex.pos++;
|
|
2567
|
+
else if (this.#partial) return out;
|
|
2568
|
+
else throw new SyntaxError("Expected ':' in object");
|
|
2569
|
+
lex.ws();
|
|
2570
|
+
if (lex.atEnd) {
|
|
2571
|
+
if (this.#partial) return out;
|
|
2572
|
+
throw new SyntaxError("Expected value after ':'");
|
|
2573
|
+
}
|
|
2574
|
+
const value = this.#value(true);
|
|
2575
|
+
if (value === INCOMPLETE) return out;
|
|
2576
|
+
out[key] = value;
|
|
2577
|
+
lex.ws();
|
|
2578
|
+
const d = lex.peek();
|
|
2579
|
+
if (d === 44) {
|
|
2580
|
+
lex.pos++;
|
|
2581
|
+
continue;
|
|
2582
|
+
}
|
|
2583
|
+
if (d === 125) {
|
|
2584
|
+
lex.pos++;
|
|
2585
|
+
return out;
|
|
2586
|
+
}
|
|
2587
|
+
if (this.#partial) return out;
|
|
2588
|
+
throw new SyntaxError("Expected ',' or '}' in object");
|
|
2589
|
+
}
|
|
2590
|
+
}
|
|
2591
|
+
#array() {
|
|
2592
|
+
const lex = this.#lex;
|
|
2593
|
+
lex.pos++;
|
|
2594
|
+
const out = [];
|
|
2595
|
+
for (;;) {
|
|
2596
|
+
lex.ws();
|
|
2597
|
+
if (lex.atEnd) {
|
|
2598
|
+
if (this.#partial) return out;
|
|
2599
|
+
throw new SyntaxError("Unterminated array");
|
|
2600
|
+
}
|
|
2601
|
+
const c = lex.peek();
|
|
2602
|
+
if (c === 93) {
|
|
2603
|
+
lex.pos++;
|
|
2604
|
+
return out;
|
|
2605
|
+
}
|
|
2606
|
+
if (c === 44) {
|
|
2607
|
+
lex.pos++;
|
|
2608
|
+
continue;
|
|
2609
|
+
}
|
|
2610
|
+
const value = this.#value(true);
|
|
2611
|
+
if (value === INCOMPLETE) return out;
|
|
2612
|
+
out.push(value);
|
|
2613
|
+
lex.ws();
|
|
2614
|
+
const d = lex.peek();
|
|
2615
|
+
if (d === 44) {
|
|
2616
|
+
lex.pos++;
|
|
2617
|
+
continue;
|
|
2618
|
+
}
|
|
2619
|
+
if (d === 93) {
|
|
2620
|
+
lex.pos++;
|
|
2621
|
+
return out;
|
|
2622
|
+
}
|
|
2623
|
+
if (this.#partial) return out;
|
|
2624
|
+
throw new SyntaxError("Expected ',' or ']' in array");
|
|
2625
|
+
}
|
|
2626
|
+
}
|
|
2627
|
+
#key() {
|
|
2628
|
+
const lex = this.#lex;
|
|
2629
|
+
const c = lex.peek();
|
|
2630
|
+
if (c === 34 || c === 39) return lex.string(c).value;
|
|
2631
|
+
const key = lex.unquotedKey();
|
|
2632
|
+
if (key.length === 0 && !this.#partial) throw new SyntaxError("Expected object key");
|
|
2633
|
+
return key;
|
|
2634
|
+
}
|
|
2431
2635
|
};
|
|
2432
2636
|
/**
|
|
2433
2637
|
* Final-parse a JSON value, repairing the common LLM malformations
|
|
@@ -2535,11 +2739,11 @@ function classifyJsonPrefix(text) {
|
|
|
2535
2739
|
i++;
|
|
2536
2740
|
while (i < n) {
|
|
2537
2741
|
const c = text.charCodeAt(i);
|
|
2538
|
-
if (c ===
|
|
2742
|
+
if (c === 34) {
|
|
2539
2743
|
i++;
|
|
2540
2744
|
return 1;
|
|
2541
2745
|
}
|
|
2542
|
-
if (c ===
|
|
2746
|
+
if (c === 92) {
|
|
2543
2747
|
i++;
|
|
2544
2748
|
if (i >= n) return 0;
|
|
2545
2749
|
const e = text.charCodeAt(i);
|
|
@@ -2625,7 +2829,7 @@ function classifyJsonPrefix(text) {
|
|
|
2625
2829
|
break;
|
|
2626
2830
|
}
|
|
2627
2831
|
let r;
|
|
2628
|
-
if (c ===
|
|
2832
|
+
if (c === 34) r = scanString();
|
|
2629
2833
|
else if (c === 45 || c >= 48 && c <= 57) r = scanNumber();
|
|
2630
2834
|
else if (c === 116 || c === 102 || c === 110) r = scanKeyword();
|
|
2631
2835
|
else return "invalid";
|
|
@@ -2642,7 +2846,7 @@ function classifyJsonPrefix(text) {
|
|
|
2642
2846
|
expect = valueDone();
|
|
2643
2847
|
break;
|
|
2644
2848
|
}
|
|
2645
|
-
if (c !==
|
|
2849
|
+
if (c !== 34) return "invalid";
|
|
2646
2850
|
const r = scanString();
|
|
2647
2851
|
if (r === -1) return "invalid";
|
|
2648
2852
|
if (r === 0) return "prefix";
|
|
@@ -2683,7 +2887,7 @@ function classifyJsonPrefix(text) {
|
|
|
2683
2887
|
}
|
|
2684
2888
|
new Intl.Segmenter();
|
|
2685
2889
|
//#endregion
|
|
2686
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@
|
|
2890
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/mime.ts
|
|
2687
2891
|
const DEFAULT_IMAGE_METADATA_HEADER_BYTES = 262144;
|
|
2688
2892
|
const PNG_MAGIC = Buffer.from([
|
|
2689
2893
|
137,
|
|
@@ -2876,7 +3080,7 @@ function dlopen() {
|
|
|
2876
3080
|
return null;
|
|
2877
3081
|
}
|
|
2878
3082
|
//#endregion
|
|
2879
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@
|
|
3083
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/stderr-guard.ts
|
|
2880
3084
|
/**
|
|
2881
3085
|
* Terminal stderr guard: keeps unmanaged fd-2 writes off the terminal while a
|
|
2882
3086
|
* TUI owns the viewport.
|
|
@@ -2941,6 +3145,10 @@ function restoreTerminalStderr() {
|
|
|
2941
3145
|
}
|
|
2942
3146
|
const callbackList = [];
|
|
2943
3147
|
let cleanupStage = "idle";
|
|
3148
|
+
let cleanupPass = 0;
|
|
3149
|
+
let activeCleanupReason;
|
|
3150
|
+
let activeCleanupKeepAlive = false;
|
|
3151
|
+
let activeLatePromises;
|
|
2944
3152
|
const CLEANUP_DEADLINE_MS = 1e4;
|
|
2945
3153
|
/**
|
|
2946
3154
|
* Symbol stamped by the extension-load guard onto the throwing replacement it
|
|
@@ -2975,13 +3183,26 @@ function exitProcess(code) {
|
|
|
2975
3183
|
}
|
|
2976
3184
|
let cleanupPromise;
|
|
2977
3185
|
const fatalRecoveryHintProviders = /* @__PURE__ */ new Set();
|
|
3186
|
+
function invokeCleanup(registration, reason, keepAlive, pass) {
|
|
3187
|
+
if (registration.cancelled || registration.lastPass === pass) return;
|
|
3188
|
+
if (registration.exitOnly && keepAlive) return;
|
|
3189
|
+
registration.lastPass = pass;
|
|
3190
|
+
return registration.callback(reason);
|
|
3191
|
+
}
|
|
2978
3192
|
/**
|
|
2979
3193
|
* Internal: runs all registered cleanup callbacks for the given reason.
|
|
2980
|
-
* Ensures each
|
|
3194
|
+
* Ensures each registration is invoked at most once per pass, handles errors,
|
|
3195
|
+
* and prevents reentrancy.
|
|
3196
|
+
*
|
|
3197
|
+
* `keepAlive` marks a manual cleanup that keeps the process running (see
|
|
3198
|
+
* {@link cleanup}). Such a pass returns the stage to `idle`; registrations stay
|
|
3199
|
+
* active for later resources and the eventual real exit. Exit-only callbacks
|
|
3200
|
+
* skip keep-alive passes without consuming their registration. An exit-driven
|
|
3201
|
+
* pass instead settles to `complete` and stays there.
|
|
2981
3202
|
*
|
|
2982
3203
|
* Returns a Promise that settles after all cleanups complete or error out.
|
|
2983
3204
|
*/
|
|
2984
|
-
function runCleanup(reason) {
|
|
3205
|
+
function runCleanup(reason, keepAlive = false) {
|
|
2985
3206
|
switch (cleanupStage) {
|
|
2986
3207
|
case "idle":
|
|
2987
3208
|
cleanupStage = "running";
|
|
@@ -2989,10 +3210,24 @@ function runCleanup(reason) {
|
|
|
2989
3210
|
case "running": return cleanupPromise ?? Promise.resolve();
|
|
2990
3211
|
case "complete": return Promise.resolve();
|
|
2991
3212
|
}
|
|
2992
|
-
const
|
|
2993
|
-
|
|
3213
|
+
const pass = ++cleanupPass;
|
|
3214
|
+
activeCleanupReason = reason;
|
|
3215
|
+
activeCleanupKeepAlive = keepAlive;
|
|
3216
|
+
const late = [];
|
|
3217
|
+
activeLatePromises = late;
|
|
3218
|
+
const settle = () => {
|
|
3219
|
+
if (activeLatePromises === late) activeLatePromises = void 0;
|
|
3220
|
+
if (cleanupPass !== pass) return;
|
|
3221
|
+
cleanupStage = keepAlive ? "idle" : "complete";
|
|
3222
|
+
if (keepAlive) {
|
|
3223
|
+
activeCleanupReason = void 0;
|
|
3224
|
+
activeCleanupKeepAlive = false;
|
|
3225
|
+
}
|
|
3226
|
+
};
|
|
3227
|
+
const promises = callbackList.toReversed().map((registration) => {
|
|
3228
|
+
return Promise.try(() => invokeCleanup(registration, reason, keepAlive, pass));
|
|
2994
3229
|
});
|
|
2995
|
-
const cleanupSettled = Promise.allSettled(promises).then((results) => {
|
|
3230
|
+
const cleanupSettled = Promise.allSettled(promises).then(async (results) => {
|
|
2996
3231
|
for (const result of results) if (result.status === "rejected") {
|
|
2997
3232
|
const err = result.reason instanceof Error ? result.reason : new Error(String(result.reason));
|
|
2998
3233
|
error("Cleanup callback failed", {
|
|
@@ -3000,17 +3235,20 @@ function runCleanup(reason) {
|
|
|
3000
3235
|
stack: err.stack
|
|
3001
3236
|
});
|
|
3002
3237
|
}
|
|
3003
|
-
|
|
3238
|
+
while (late.length > 0) await Promise.allSettled(late.splice(0));
|
|
3239
|
+
settle();
|
|
3004
3240
|
});
|
|
3005
3241
|
const deadline = Promise.withResolvers();
|
|
3006
3242
|
const deadlineTimer = setTimeout(() => {
|
|
3007
3243
|
error("Cleanup deadline exceeded; proceeding with exit", { reason });
|
|
3008
|
-
|
|
3244
|
+
settle();
|
|
3009
3245
|
deadline.resolve();
|
|
3010
3246
|
}, CLEANUP_DEADLINE_MS);
|
|
3011
|
-
|
|
3247
|
+
const passPromise = Promise.race([cleanupSettled, deadline.promise]).finally(() => {
|
|
3012
3248
|
clearTimeout(deadlineTimer);
|
|
3249
|
+
if (keepAlive && cleanupPass === pass && cleanupPromise === passPromise) cleanupPromise = void 0;
|
|
3013
3250
|
});
|
|
3251
|
+
cleanupPromise = passPromise;
|
|
3014
3252
|
return cleanupPromise;
|
|
3015
3253
|
}
|
|
3016
3254
|
let inspectorOpened = false;
|
|
@@ -3023,21 +3261,86 @@ function classifyBrokenPipe(err) {
|
|
|
3023
3261
|
if (err.syscall === "send") return "ipc-send";
|
|
3024
3262
|
if (err.syscall === "write") return "stdio-write";
|
|
3025
3263
|
}
|
|
3026
|
-
|
|
3264
|
+
/** Whether an EPIPE came from an IPC `send()` to an optional worker. */
|
|
3265
|
+
function isIpcSendEpipe(err) {
|
|
3266
|
+
return classifyBrokenPipe(err) === "ipc-send";
|
|
3267
|
+
}
|
|
3027
3268
|
/**
|
|
3028
|
-
* Whether
|
|
3029
|
-
*
|
|
3030
|
-
*
|
|
3031
|
-
*
|
|
3269
|
+
* Whether an uncaught error is Bun's asynchronous `ERR_SOCKET_CLOSED` thrown
|
|
3270
|
+
* from inside `node:net` internals with no application frames on the stack.
|
|
3271
|
+
*
|
|
3272
|
+
* Bun ≥1.4 can fire the close callback of an already-closed `node:net` socket
|
|
3273
|
+
* on a fresh stack; the throw bypasses every callsite try/catch and surfaces
|
|
3274
|
+
* here as a process-level uncaughtException. Closing an already-closed socket
|
|
3275
|
+
* is inherently a no-op — the socket owner's own `error`/`close` handlers
|
|
3276
|
+
* still drive recovery — so tearing the session down for it is pure loss.
|
|
3277
|
+
* Only frameless internal stacks qualify: an `ERR_SOCKET_CLOSED` raised
|
|
3278
|
+
* through application code keeps the fatal path.
|
|
3032
3279
|
*/
|
|
3033
|
-
function
|
|
3280
|
+
function isInternalSocketClosedError(err) {
|
|
3281
|
+
if (!(err instanceof Error) || !("code" in err) || err.code !== "ERR_SOCKET_CLOSED") return false;
|
|
3282
|
+
const frames = (err.stack ?? "").split("\n").slice(1);
|
|
3283
|
+
if (frames.length === 0) return false;
|
|
3284
|
+
let hasNetFrame = false;
|
|
3285
|
+
return frames.every((frame) => {
|
|
3286
|
+
const trimmed = frame.trim();
|
|
3287
|
+
if (trimmed === "" || trimmed === "at unknown" || trimmed === "at native") return true;
|
|
3288
|
+
if (!/\(node:[^)]*\)$/.test(trimmed) && !trimmed.startsWith("at node:")) return false;
|
|
3289
|
+
hasNetFrame ||= trimmed.includes("node:net:");
|
|
3290
|
+
return true;
|
|
3291
|
+
}) && hasNetFrame;
|
|
3292
|
+
}
|
|
3293
|
+
/**
|
|
3294
|
+
* Detect Bun's advanced-serialization (structured-clone) IPC decode failure.
|
|
3295
|
+
*
|
|
3296
|
+
* When a worker subprocess spawned with `serialization: "advanced"` sends a
|
|
3297
|
+
* malformed or truncated frame, Bun raises the decode failure as a
|
|
3298
|
+
* process-level `uncaughtException` in the *parent* rather than routing it to
|
|
3299
|
+
* the channel's `ipc()` callback (oven-sh/bun#37287). The error is a bare
|
|
3300
|
+
* `TypeError: Unable to deserialize data.` whose only own property is `message`
|
|
3301
|
+
* — it carries no `code`, no `syscall`, and no `stack`. Matching all four traits
|
|
3302
|
+
* keeps unrelated application `TypeError`s (which always carry a populated
|
|
3303
|
+
* multi-frame stack) on the fatal path, so a genuine bug is never silently
|
|
3304
|
+
* swallowed.
|
|
3305
|
+
*
|
|
3306
|
+
* Every advanced-serialization channel in this process is an optional worker
|
|
3307
|
+
* subsystem (TTS, STT, tiny-title, mnemopi embeddings, JS eval), so one
|
|
3308
|
+
* worker's bad frame must fault only that worker — via its own `onExit`/error
|
|
3309
|
+
* path — never tear down the whole session. Callers log-and-continue instead of
|
|
3310
|
+
* taking the fatal path. Mirrors {@link classifyBrokenPipe} for the send side
|
|
3311
|
+
* (#2997, #9158).
|
|
3312
|
+
*/
|
|
3313
|
+
function isWorkerIpcDeserializeError(err) {
|
|
3314
|
+
return err instanceof TypeError && err.message === "Unable to deserialize data." && !err.stack && !("code" in err) && !("syscall" in err);
|
|
3315
|
+
}
|
|
3316
|
+
/** Recycle callbacks for the active advanced-serialization worker IPC channels. */
|
|
3317
|
+
const workerIpcFaultHandlers = /* @__PURE__ */ new Set();
|
|
3318
|
+
/** Invoke every registered worker IPC fault handler, isolating handler throws. */
|
|
3319
|
+
function faultWorkerIpcChannels(err) {
|
|
3320
|
+
for (const handler of workerIpcFaultHandlers) try {
|
|
3321
|
+
handler(err);
|
|
3322
|
+
} catch (handlerErr) {
|
|
3323
|
+
warn("Worker IPC fault handler threw", { err: handlerErr });
|
|
3324
|
+
}
|
|
3325
|
+
}
|
|
3326
|
+
const EXPECTED_CLEANUP = Symbol.for("omp.expectedCleanupError");
|
|
3327
|
+
function hasExpectedCleanupMarker(reason) {
|
|
3034
3328
|
let current = reason;
|
|
3035
3329
|
for (let depth = 0; depth < 8 && current !== null && typeof current === "object"; depth++) {
|
|
3036
|
-
if (current
|
|
3037
|
-
current = current
|
|
3330
|
+
if (Reflect.get(current, EXPECTED_CLEANUP) === true) return true;
|
|
3331
|
+
current = Reflect.get(current, "cause");
|
|
3038
3332
|
}
|
|
3039
3333
|
return false;
|
|
3040
3334
|
}
|
|
3335
|
+
/**
|
|
3336
|
+
* Whether `reason` (or any object in its bounded `cause` chain) was explicitly
|
|
3337
|
+
* marked via {@link markExpectedCleanupError}. Runtime error names and codes
|
|
3338
|
+
* are intentionally insufficient: unmarked `AbortError` and socket failures
|
|
3339
|
+
* can originate from application code and must remain fatal when unhandled.
|
|
3340
|
+
*/
|
|
3341
|
+
function isExpectedCleanupError(reason) {
|
|
3342
|
+
return hasExpectedCleanupMarker(reason);
|
|
3343
|
+
}
|
|
3041
3344
|
/** Interceptors consulted by the global `unhandledRejection` handler before the fatal path. */
|
|
3042
3345
|
const rejectionInterceptors = /* @__PURE__ */ new Set();
|
|
3043
3346
|
function escapeFatalHintText(value) {
|
|
@@ -3064,15 +3367,16 @@ function formatFatalError(label, err) {
|
|
|
3064
3367
|
const stackLines = (err.stack || "").split("\n").slice(1);
|
|
3065
3368
|
return `\n[${label}] ${name}: ${message}${stackLines.length > 0 ? `\n${stackLines.join("\n")}` : ""}\n`;
|
|
3066
3369
|
}
|
|
3067
|
-
async function exitAfterFatal(
|
|
3370
|
+
async function exitAfterFatal(output, logMessage, err, reason) {
|
|
3068
3371
|
const forcedExit = setTimeout(() => exitProcess(1), CLEANUP_DEADLINE_MS);
|
|
3069
3372
|
try {
|
|
3373
|
+
const cleanup = runCleanup(reason);
|
|
3070
3374
|
restoreTerminalStderr();
|
|
3071
3375
|
try {
|
|
3072
|
-
fs.writeSync(2,
|
|
3376
|
+
fs.writeSync(2, output);
|
|
3073
3377
|
} catch {}
|
|
3074
3378
|
error(logMessage, { err });
|
|
3075
|
-
await
|
|
3379
|
+
await cleanup;
|
|
3076
3380
|
} finally {
|
|
3077
3381
|
clearTimeout(forcedExit);
|
|
3078
3382
|
exitProcess(1);
|
|
@@ -3087,12 +3391,26 @@ if (isMainThread) process.on("SIGINT", async () => {
|
|
|
3087
3391
|
inspector.open(void 0, void 0, false);
|
|
3088
3392
|
const url = inspector.url();
|
|
3089
3393
|
process.stderr.write(`Inspector opened: ${url}\n`);
|
|
3090
|
-
}).on("uncaughtException", async (
|
|
3091
|
-
if (
|
|
3092
|
-
warn("Ignoring expected cleanup exception", { err });
|
|
3394
|
+
}).on("uncaughtException", async (thrown) => {
|
|
3395
|
+
if (hasExpectedCleanupMarker(thrown)) {
|
|
3396
|
+
warn("Ignoring expected cleanup exception", { err: thrown });
|
|
3397
|
+
return;
|
|
3398
|
+
}
|
|
3399
|
+
const err = thrown instanceof Error ? thrown : new Error(String(thrown));
|
|
3400
|
+
if (isIpcSendEpipe(err)) {
|
|
3401
|
+
warn("Ignoring EPIPE from worker IPC send; optional subsystem will self-recover", { err });
|
|
3402
|
+
return;
|
|
3403
|
+
}
|
|
3404
|
+
if (isWorkerIpcDeserializeError(err)) {
|
|
3405
|
+
warn("Malformed worker IPC frame; faulting active worker subsystems", { err });
|
|
3406
|
+
faultWorkerIpcChannels(err);
|
|
3407
|
+
return;
|
|
3408
|
+
}
|
|
3409
|
+
if (isInternalSocketClosedError(err)) {
|
|
3410
|
+
warn("Ignoring async ERR_SOCKET_CLOSED from node:net internals; socket owner recovers itself", { err });
|
|
3093
3411
|
return;
|
|
3094
3412
|
}
|
|
3095
|
-
await exitAfterFatal("Uncaught Exception", "Uncaught exception", err, "uncaught_exception");
|
|
3413
|
+
await exitAfterFatal(`${formatFatalError("Uncaught Exception", err)}${formatFatalRecoveryHints()}`, "Uncaught exception", err, "uncaught_exception");
|
|
3096
3414
|
}).on("unhandledRejection", async (reason) => {
|
|
3097
3415
|
const err = reason instanceof Error ? reason : new Error(String(reason));
|
|
3098
3416
|
if (classifyBrokenPipe(err) === "ipc-send") {
|
|
@@ -3108,7 +3426,7 @@ if (isMainThread) process.on("SIGINT", async () => {
|
|
|
3108
3426
|
} catch (interceptorErr) {
|
|
3109
3427
|
warn("Unhandled-rejection interceptor threw; continuing with fatal path", { err: interceptorErr });
|
|
3110
3428
|
}
|
|
3111
|
-
await exitAfterFatal("Unhandled Rejection", "Unhandled rejection", err, "unhandled_rejection");
|
|
3429
|
+
await exitAfterFatal(`${formatFatalError("Unhandled Rejection", err)}${formatFatalRecoveryHints()}`, "Unhandled rejection", err, "unhandled_rejection");
|
|
3112
3430
|
}).on("exit", async () => {
|
|
3113
3431
|
runCleanup("exit");
|
|
3114
3432
|
}).on("SIGTERM", async () => {
|
|
@@ -3121,8 +3439,72 @@ if (isMainThread) process.on("SIGINT", async () => {
|
|
|
3121
3439
|
else process.on("exit", () => {
|
|
3122
3440
|
runCleanup("exit");
|
|
3123
3441
|
});
|
|
3442
|
+
/**
|
|
3443
|
+
* Registers a cleanup callback for shutdown, signals, fatal errors, and
|
|
3444
|
+
* repeatable manual cleanup passes.
|
|
3445
|
+
*
|
|
3446
|
+
* Registrations persist across keep-alive {@link cleanup} passes and run at
|
|
3447
|
+
* most once per pass. Set `exitOnly` for resources the continuing process still
|
|
3448
|
+
* holds (open databases, cached handles): keep-alive passes skip the callback
|
|
3449
|
+
* without consuming its registration, while the eventual real exit runs it.
|
|
3450
|
+
*
|
|
3451
|
+
* A callback registered during a running keep-alive pass joins future passes;
|
|
3452
|
+
* normal callbacks also run immediately for the current pass. Registrations
|
|
3453
|
+
* made during a real exit run immediately.
|
|
3454
|
+
*
|
|
3455
|
+
* Returns a function that permanently cancels the registration.
|
|
3456
|
+
*/
|
|
3457
|
+
function register(id, callback, options = {}) {
|
|
3458
|
+
const registration = {
|
|
3459
|
+
id,
|
|
3460
|
+
callback,
|
|
3461
|
+
exitOnly: options.exitOnly ?? false,
|
|
3462
|
+
cancelled: false,
|
|
3463
|
+
lastPass: 0
|
|
3464
|
+
};
|
|
3465
|
+
const cancel = () => {
|
|
3466
|
+
registration.cancelled = true;
|
|
3467
|
+
const index = callbackList.indexOf(registration);
|
|
3468
|
+
if (index >= 0) callbackList.splice(index, 1);
|
|
3469
|
+
};
|
|
3470
|
+
const invokeLate = (reason, keepAlive) => {
|
|
3471
|
+
try {
|
|
3472
|
+
const pending = invokeCleanup(registration, reason, keepAlive, cleanupPass);
|
|
3473
|
+
if (!pending) return;
|
|
3474
|
+
const tracked = pending.catch((error$2) => {
|
|
3475
|
+
const err = error$2 instanceof Error ? error$2 : new Error(String(error$2));
|
|
3476
|
+
error("Cleanup callback failed", {
|
|
3477
|
+
err,
|
|
3478
|
+
id,
|
|
3479
|
+
stack: err.stack
|
|
3480
|
+
});
|
|
3481
|
+
});
|
|
3482
|
+
activeLatePromises?.push(tracked);
|
|
3483
|
+
} catch (error$1) {
|
|
3484
|
+
const err = error$1 instanceof Error ? error$1 : new Error(String(error$1));
|
|
3485
|
+
error("Cleanup callback failed", {
|
|
3486
|
+
err,
|
|
3487
|
+
id,
|
|
3488
|
+
stack: err.stack
|
|
3489
|
+
});
|
|
3490
|
+
}
|
|
3491
|
+
};
|
|
3492
|
+
if (cleanupStage === "idle") {
|
|
3493
|
+
callbackList.push(registration);
|
|
3494
|
+
return cancel;
|
|
3495
|
+
}
|
|
3496
|
+
const reason = activeCleanupReason ?? "manual";
|
|
3497
|
+
if (cleanupStage === "running" && activeCleanupKeepAlive) {
|
|
3498
|
+
callbackList.push(registration);
|
|
3499
|
+
if (!registration.exitOnly) invokeLate(reason, true);
|
|
3500
|
+
return cancel;
|
|
3501
|
+
}
|
|
3502
|
+
debug("Cleanup already started; running late callback once", { id });
|
|
3503
|
+
invokeLate(reason, false);
|
|
3504
|
+
return cancel;
|
|
3505
|
+
}
|
|
3124
3506
|
//#endregion
|
|
3125
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@
|
|
3507
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/which.ts
|
|
3126
3508
|
const XCODE_BINS = /* @__PURE__ */ new Set([
|
|
3127
3509
|
"clang",
|
|
3128
3510
|
"clang++",
|
|
@@ -3217,7 +3599,7 @@ function darwinWhich(command, options) {
|
|
|
3217
3599
|
if (isXcodeBin(command)) return getMacosToolPaths().get(command) ?? null;
|
|
3218
3600
|
return null;
|
|
3219
3601
|
}
|
|
3220
|
-
const whichFresh = os.platform() === "darwin" ? darwinWhich : Bun.which;
|
|
3602
|
+
const whichFresh = os.platform() === "darwin" ? darwinWhich : (command, options) => Bun.which(command, options);
|
|
3221
3603
|
function cacheKey$1(command, options) {
|
|
3222
3604
|
if (!options) return command;
|
|
3223
3605
|
if (!options.cwd && !options.PATH) return command;
|
|
@@ -3252,7 +3634,7 @@ function $which(command, options) {
|
|
|
3252
3634
|
return result;
|
|
3253
3635
|
}
|
|
3254
3636
|
//#endregion
|
|
3255
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@
|
|
3637
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/template.ts
|
|
3256
3638
|
/** A string that bypasses HTML escaping when interpolated. */
|
|
3257
3639
|
var SafeString = class {
|
|
3258
3640
|
#value;
|
|
@@ -3703,7 +4085,7 @@ function compile$1(source, options = {}) {
|
|
|
3703
4085
|
root,
|
|
3704
4086
|
data: {
|
|
3705
4087
|
root,
|
|
3706
|
-
...runtime.data
|
|
4088
|
+
...runtime.data
|
|
3707
4089
|
}
|
|
3708
4090
|
};
|
|
3709
4091
|
return renderNodes(nodes, frame, {
|
|
@@ -3741,7 +4123,7 @@ var TemplateEngine = class {
|
|
|
3741
4123
|
root,
|
|
3742
4124
|
data: {
|
|
3743
4125
|
root,
|
|
3744
|
-
...runtime.data
|
|
4126
|
+
...runtime.data
|
|
3745
4127
|
}
|
|
3746
4128
|
};
|
|
3747
4129
|
return renderNodes(nodes, frame, {
|
|
@@ -3754,7 +4136,7 @@ var TemplateEngine = class {
|
|
|
3754
4136
|
}
|
|
3755
4137
|
};
|
|
3756
4138
|
//#endregion
|
|
3757
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@
|
|
4139
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/prompt.ts
|
|
3758
4140
|
const OPENING_XML = /^<([a-z_-]+)(?:\s+[^>]*)?>$/;
|
|
3759
4141
|
/**
|
|
3760
4142
|
* Closing XML tag matcher, manual equivalent of `/^<\/([a-z_-]+)>$/` — avoids a
|
|
@@ -4197,7 +4579,7 @@ function _usingCtx() {
|
|
|
4197
4579
|
};
|
|
4198
4580
|
}
|
|
4199
4581
|
//#endregion
|
|
4200
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@
|
|
4582
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ptree.ts
|
|
4201
4583
|
/**
|
|
4202
4584
|
* Process tree management utilities for Bun subprocesses.
|
|
4203
4585
|
*
|
|
@@ -4206,6 +4588,80 @@ function _usingCtx() {
|
|
|
4206
4588
|
* - Cross-platform tree kill for process groups (Windows taskkill, Unix -pid).
|
|
4207
4589
|
* - Convenience helpers: captureText / execText, AbortSignal, timeouts.
|
|
4208
4590
|
*/
|
|
4591
|
+
const LINUX_SUBREAPER_COMMAND_ENV = "OMP_PTREE_SUBREAPER_COMMAND";
|
|
4592
|
+
const LINUX_SUBREAPER_BUN_BE_BUN_ENV = "OMP_PTREE_SUBREAPER_BUN_BE_BUN";
|
|
4593
|
+
/**
|
|
4594
|
+
* Build the Linux child-subreaper entrypoint.
|
|
4595
|
+
*
|
|
4596
|
+
* @internal Exported so tests can force a missing first libc soname and verify
|
|
4597
|
+
* the loader continues to the next candidate.
|
|
4598
|
+
*/
|
|
4599
|
+
function createLinuxSubreaperScript(libcCandidates = ["libc.so.6", "libc.so"]) {
|
|
4600
|
+
return `
|
|
4601
|
+
import { dlopen, FFIType } from "bun:ffi";
|
|
4602
|
+
|
|
4603
|
+
let libc;
|
|
4604
|
+
for (const soname of ${JSON.stringify(libcCandidates)}) {
|
|
4605
|
+
try {
|
|
4606
|
+
libc = dlopen(soname, {
|
|
4607
|
+
prctl: {
|
|
4608
|
+
args: [FFIType.i32, FFIType.u64, FFIType.u64, FFIType.u64, FFIType.u64],
|
|
4609
|
+
returns: FFIType.i32,
|
|
4610
|
+
},
|
|
4611
|
+
waitpid: {
|
|
4612
|
+
args: [FFIType.i32, FFIType.ptr, FFIType.i32],
|
|
4613
|
+
returns: FFIType.i32,
|
|
4614
|
+
},
|
|
4615
|
+
});
|
|
4616
|
+
break;
|
|
4617
|
+
} catch {}
|
|
4618
|
+
}
|
|
4619
|
+
if (!libc) throw new Error("failed to load libc for Linux child supervision");
|
|
4620
|
+
|
|
4621
|
+
if (libc.symbols.prctl(36, 1, 0, 0, 0) !== 0) {
|
|
4622
|
+
throw new Error("failed to become a Linux child subreaper");
|
|
4623
|
+
}
|
|
4624
|
+
|
|
4625
|
+
const commandJson = Bun.env.${LINUX_SUBREAPER_COMMAND_ENV};
|
|
4626
|
+
if (!commandJson) throw new Error("missing supervised command");
|
|
4627
|
+
const callerBunBeBun = Bun.env.${LINUX_SUBREAPER_BUN_BE_BUN_ENV};
|
|
4628
|
+
delete Bun.env.${LINUX_SUBREAPER_COMMAND_ENV};
|
|
4629
|
+
delete Bun.env.${LINUX_SUBREAPER_BUN_BE_BUN_ENV};
|
|
4630
|
+
if (callerBunBeBun === undefined) delete Bun.env.BUN_BE_BUN;
|
|
4631
|
+
else Bun.env.BUN_BE_BUN = callerBunBeBun;
|
|
4632
|
+
const command = JSON.parse(commandJson);
|
|
4633
|
+
const child = Bun.spawn(command, {
|
|
4634
|
+
stdin: "inherit",
|
|
4635
|
+
stdout: "pipe",
|
|
4636
|
+
stderr: "pipe",
|
|
4637
|
+
windowsHide: true,
|
|
4638
|
+
env: Bun.env,
|
|
4639
|
+
});
|
|
4640
|
+
|
|
4641
|
+
async function relay(stream, destination) {
|
|
4642
|
+
const writer = destination.writer();
|
|
4643
|
+
for await (const chunk of stream) writer.write(chunk);
|
|
4644
|
+
await writer.flush();
|
|
4645
|
+
}
|
|
4646
|
+
|
|
4647
|
+
function hasLiveChildren() {
|
|
4648
|
+
let childPid;
|
|
4649
|
+
do {
|
|
4650
|
+
childPid = libc.symbols.waitpid(-1, null, 1);
|
|
4651
|
+
} while (childPid > 0);
|
|
4652
|
+
return childPid === 0;
|
|
4653
|
+
}
|
|
4654
|
+
|
|
4655
|
+
const [exitCode] = await Promise.all([
|
|
4656
|
+
child.exited,
|
|
4657
|
+
relay(child.stdout, Bun.stdout),
|
|
4658
|
+
relay(child.stderr, Bun.stderr),
|
|
4659
|
+
]);
|
|
4660
|
+
while (hasLiveChildren()) await Bun.sleep(10);
|
|
4661
|
+
process.exit(exitCode ?? 1);
|
|
4662
|
+
`;
|
|
4663
|
+
}
|
|
4664
|
+
const LINUX_SUBREAPER_SCRIPT = createLinuxSubreaperScript();
|
|
4209
4665
|
/**
|
|
4210
4666
|
* Base for all exceptions representing child process nonzero exit, killed, or
|
|
4211
4667
|
* cancellation.
|
|
@@ -4266,10 +4722,21 @@ var ChildProcess = class {
|
|
|
4266
4722
|
#exitReasonPending;
|
|
4267
4723
|
#stderrDone;
|
|
4268
4724
|
#exited;
|
|
4725
|
+
#openPipeReaders = 1;
|
|
4726
|
+
#drainCutoff;
|
|
4727
|
+
#resolveDrainCutoff;
|
|
4728
|
+
#timeoutTimer;
|
|
4269
4729
|
#stderrStream;
|
|
4270
|
-
|
|
4730
|
+
#terminating;
|
|
4731
|
+
#terminateGroup;
|
|
4732
|
+
#hardKillTree;
|
|
4733
|
+
#windowsRootProcess;
|
|
4734
|
+
constructor(proc, exposeStderr, retainFullStderr = exposeStderr, terminateGroup = false, hardKillTree = false) {
|
|
4271
4735
|
this.proc = proc;
|
|
4272
4736
|
this.exposeStderr = exposeStderr;
|
|
4737
|
+
this.#terminateGroup = terminateGroup;
|
|
4738
|
+
this.#hardKillTree = hardKillTree;
|
|
4739
|
+
this.#windowsRootProcess = process.platform === "win32" ? Process.fromPid(proc.pid) ?? void 0 : void 0;
|
|
4273
4740
|
if (retainFullStderr) this.#stderrChunks = [];
|
|
4274
4741
|
const dec = new TextDecoder();
|
|
4275
4742
|
const trim = () => {
|
|
@@ -4281,19 +4748,34 @@ var ChildProcess = class {
|
|
|
4281
4748
|
this.#stderrStream = teeStream;
|
|
4282
4749
|
stderrStream = drainStream;
|
|
4283
4750
|
}
|
|
4751
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
4752
|
+
this.#exited = promise;
|
|
4753
|
+
const drainCutoff = Promise.withResolvers();
|
|
4754
|
+
this.#drainCutoff = drainCutoff.promise;
|
|
4755
|
+
this.#resolveDrainCutoff = drainCutoff.resolve;
|
|
4756
|
+
const pipeCutoff = this.#drainCutoff;
|
|
4284
4757
|
this.#stderrDone = (async () => {
|
|
4758
|
+
const reader = stderrStream.getReader();
|
|
4285
4759
|
try {
|
|
4286
|
-
for
|
|
4287
|
-
|
|
4288
|
-
|
|
4760
|
+
for (;;) {
|
|
4761
|
+
const chunk = await Promise.race([reader.read().then((r) => ({
|
|
4762
|
+
cutoff: false,
|
|
4763
|
+
r
|
|
4764
|
+
})), pipeCutoff.then(() => ({ cutoff: true }))]);
|
|
4765
|
+
if (chunk.cutoff) {
|
|
4766
|
+
await reader.cancel().catch(() => {});
|
|
4767
|
+
break;
|
|
4768
|
+
}
|
|
4769
|
+
if (chunk.r.done) break;
|
|
4770
|
+
this.#stderrChunks?.push(chunk.r.value);
|
|
4771
|
+
this.#stderrTail += dec.decode(chunk.r.value, { stream: true });
|
|
4289
4772
|
trim();
|
|
4290
4773
|
}
|
|
4291
4774
|
} catch {}
|
|
4775
|
+
this.#openPipeReaders--;
|
|
4292
4776
|
this.#stderrTail += dec.decode();
|
|
4293
4777
|
trim();
|
|
4294
4778
|
})();
|
|
4295
|
-
const { promise, resolve, reject } = Promise.withResolvers();
|
|
4296
|
-
this.#exited = promise;
|
|
4297
4779
|
proc.exited.catch(() => null).then(async (exitCode) => {
|
|
4298
4780
|
if (this.#exitReasonPending) {
|
|
4299
4781
|
this.#exitReason = this.#exitReasonPending;
|
|
@@ -4305,6 +4787,11 @@ var ChildProcess = class {
|
|
|
4305
4787
|
return;
|
|
4306
4788
|
}
|
|
4307
4789
|
await this.#stderrDone;
|
|
4790
|
+
if (this.#exitReasonPending) {
|
|
4791
|
+
this.#exitReason = this.#exitReasonPending;
|
|
4792
|
+
reject(this.#exitReasonPending);
|
|
4793
|
+
return;
|
|
4794
|
+
}
|
|
4308
4795
|
if (exitCode !== null) {
|
|
4309
4796
|
this.#exitReason = new NonZeroExitError(exitCode, this.#stderrTail);
|
|
4310
4797
|
resolve(exitCode);
|
|
@@ -4357,36 +4844,131 @@ var ChildProcess = class {
|
|
|
4357
4844
|
return this;
|
|
4358
4845
|
}
|
|
4359
4846
|
kill(reason, gracefulMs) {
|
|
4360
|
-
if (reason && !this.#exitReasonPending)
|
|
4361
|
-
|
|
4847
|
+
if (reason && !this.#exitReasonPending) {
|
|
4848
|
+
this.#exitReasonPending = reason;
|
|
4849
|
+
if (this.proc.exitCode !== null) this.#exitReason = reason;
|
|
4850
|
+
}
|
|
4851
|
+
if (gracefulMs !== void 0 && gracefulMs < 0 && this.#hardKillTree && this.proc.exitCode === null) {
|
|
4852
|
+
const root = Process.fromPid(this.proc.pid);
|
|
4853
|
+
if (root) {
|
|
4854
|
+
root.killTree(9);
|
|
4855
|
+
this.#terminating = Promise.resolve();
|
|
4856
|
+
return;
|
|
4857
|
+
}
|
|
4858
|
+
}
|
|
4859
|
+
if (this.proc.exitCode !== null && this.#terminateGroup && this.#openPipeReaders > 0 && process.platform !== "win32") {
|
|
4860
|
+
try {
|
|
4861
|
+
process.kill(-this.proc.pid, "SIGKILL");
|
|
4862
|
+
} catch {}
|
|
4863
|
+
this.#terminating = Promise.resolve();
|
|
4864
|
+
return;
|
|
4865
|
+
}
|
|
4866
|
+
if (this.proc.exitCode !== null && this.#windowsRootProcess && this.#openPipeReaders > 0) {
|
|
4867
|
+
this.#windowsRootProcess.killTree();
|
|
4868
|
+
this.#terminating = Promise.resolve();
|
|
4869
|
+
return;
|
|
4870
|
+
}
|
|
4871
|
+
if (!this.proc.killed) {
|
|
4872
|
+
const options = gracefulMs === void 0 ? this.#terminateGroup ? { group: true } : void 0 : {
|
|
4873
|
+
gracefulMs,
|
|
4874
|
+
group: this.#terminateGroup
|
|
4875
|
+
};
|
|
4876
|
+
this.#terminating = (this.#windowsRootProcess ?? Process.fromPid(this.proc.pid))?.terminate(options)?.catch((e) => void 0);
|
|
4877
|
+
}
|
|
4878
|
+
}
|
|
4879
|
+
async #throwIfAborted() {
|
|
4880
|
+
const exitReason = this.exitReason;
|
|
4881
|
+
if (!exitReason?.aborted) return;
|
|
4882
|
+
if (this.#terminating) await this.#terminating;
|
|
4883
|
+
throw exitReason;
|
|
4362
4884
|
}
|
|
4363
4885
|
async text() {
|
|
4364
|
-
const p =
|
|
4886
|
+
const p = this.#readStream(this.proc.stdout);
|
|
4365
4887
|
if (this.#nothrow) return p;
|
|
4366
4888
|
const [text] = await Promise.all([p, this.exitedCleanly]);
|
|
4889
|
+
await this.#throwIfAborted();
|
|
4367
4890
|
return text;
|
|
4368
4891
|
}
|
|
4369
|
-
|
|
4370
|
-
|
|
4892
|
+
/**
|
|
4893
|
+
* Read a pipe fully, stopping early only at an explicit command deadline.
|
|
4894
|
+
*/
|
|
4895
|
+
async #readStream(stream) {
|
|
4896
|
+
this.#openPipeReaders++;
|
|
4897
|
+
const reader = stream.getReader();
|
|
4898
|
+
const dec = new TextDecoder();
|
|
4899
|
+
let out = "";
|
|
4900
|
+
try {
|
|
4901
|
+
for (;;) {
|
|
4902
|
+
const chunk = await Promise.race([reader.read().then((r) => ({
|
|
4903
|
+
cutoff: false,
|
|
4904
|
+
r
|
|
4905
|
+
})), this.#drainCutoff.then(() => ({ cutoff: true }))]);
|
|
4906
|
+
if (chunk.cutoff) {
|
|
4907
|
+
await reader.cancel().catch(() => {});
|
|
4908
|
+
break;
|
|
4909
|
+
}
|
|
4910
|
+
if (chunk.r.done) break;
|
|
4911
|
+
out += dec.decode(chunk.r.value, { stream: true });
|
|
4912
|
+
}
|
|
4913
|
+
} catch {}
|
|
4914
|
+
this.#openPipeReaders--;
|
|
4915
|
+
return out + dec.decode();
|
|
4916
|
+
}
|
|
4917
|
+
async #readBytes() {
|
|
4918
|
+
const reader = this.proc.stdout.getReader();
|
|
4919
|
+
this.#openPipeReaders++;
|
|
4920
|
+
const chunks = [];
|
|
4921
|
+
let length = 0;
|
|
4922
|
+
try {
|
|
4923
|
+
for (;;) {
|
|
4924
|
+
const chunk = await Promise.race([reader.read().then((r) => ({
|
|
4925
|
+
cutoff: false,
|
|
4926
|
+
r
|
|
4927
|
+
})), this.#drainCutoff.then(() => ({ cutoff: true }))]);
|
|
4928
|
+
if (chunk.cutoff) {
|
|
4929
|
+
await reader.cancel().catch(() => {});
|
|
4930
|
+
break;
|
|
4931
|
+
}
|
|
4932
|
+
if (chunk.r.done) break;
|
|
4933
|
+
chunks.push(chunk.r.value);
|
|
4934
|
+
length += chunk.r.value.byteLength;
|
|
4935
|
+
}
|
|
4936
|
+
} catch {} finally {
|
|
4937
|
+
this.#openPipeReaders--;
|
|
4938
|
+
reader.releaseLock();
|
|
4939
|
+
}
|
|
4940
|
+
const bytes = new Uint8Array(length);
|
|
4941
|
+
let offset = 0;
|
|
4942
|
+
for (const chunk of chunks) {
|
|
4943
|
+
bytes.set(chunk, offset);
|
|
4944
|
+
offset += chunk.byteLength;
|
|
4945
|
+
}
|
|
4946
|
+
return bytes;
|
|
4947
|
+
}
|
|
4948
|
+
async #readOutputBytes(waitForCleanExit = false) {
|
|
4949
|
+
const p = this.#readBytes();
|
|
4371
4950
|
if (this.#nothrow) return p;
|
|
4372
|
-
const
|
|
4373
|
-
|
|
4951
|
+
const bytes = waitForCleanExit ? (await Promise.all([p, this.exitedCleanly]))[0] : await p;
|
|
4952
|
+
await this.#throwIfAborted();
|
|
4953
|
+
return bytes;
|
|
4954
|
+
}
|
|
4955
|
+
async blob() {
|
|
4956
|
+
return new Blob([await this.#readOutputBytes(true)]);
|
|
4374
4957
|
}
|
|
4375
4958
|
async json() {
|
|
4376
|
-
return new
|
|
4959
|
+
return JSON.parse(new TextDecoder().decode(await this.#readOutputBytes()));
|
|
4377
4960
|
}
|
|
4378
4961
|
async arrayBuffer() {
|
|
4379
|
-
return
|
|
4962
|
+
return (await this.#readOutputBytes()).buffer;
|
|
4380
4963
|
}
|
|
4381
4964
|
async bytes() {
|
|
4382
|
-
|
|
4383
|
-
return body instanceof Uint8Array ? body : new Uint8Array(body);
|
|
4965
|
+
return this.#readOutputBytes();
|
|
4384
4966
|
}
|
|
4385
4967
|
async wait(opts) {
|
|
4386
4968
|
const { allowNonZero = false, allowAbort = false, stderr: stderrMode = "buffer" } = opts ?? {};
|
|
4387
4969
|
const stderrChunks = this.#stderrChunks;
|
|
4388
4970
|
if (stderrMode === "full" && !stderrChunks) throw new Error("Full stderr capture must be requested when spawning the process (pass stderr: \"full\")");
|
|
4389
|
-
const stdoutP =
|
|
4971
|
+
const stdoutP = this.#readStream(this.proc.stdout);
|
|
4390
4972
|
const stderrP = stderrMode === "full" && stderrChunks ? this.#stderrDone.then(() => new TextDecoder().decode(Buffer.concat(stderrChunks))) : this.#stderrDone.then(() => this.#stderrTail);
|
|
4391
4973
|
const [stdout, stderr] = await Promise.all([stdoutP, stderrP]);
|
|
4392
4974
|
let exitError;
|
|
@@ -4396,8 +4978,10 @@ var ChildProcess = class {
|
|
|
4396
4978
|
if (err instanceof Exception) exitError = err;
|
|
4397
4979
|
else throw err;
|
|
4398
4980
|
}
|
|
4981
|
+
this.#clearTimeout();
|
|
4399
4982
|
if (!exitError) exitError = this.exitReason;
|
|
4400
4983
|
if (!exitError && this.exitCode !== null && this.exitCode !== 0) exitError = new NonZeroExitError(this.exitCode, this.#stderrTail);
|
|
4984
|
+
if (exitError?.aborted && this.#terminating) await this.#terminating;
|
|
4401
4985
|
const exitCode = this.exitCode ?? (exitError && !exitError.aborted ? exitError.exitCode : null);
|
|
4402
4986
|
const ok = exitCode === 0;
|
|
4403
4987
|
if (exitError) {
|
|
@@ -4417,12 +5001,20 @@ var ChildProcess = class {
|
|
|
4417
5001
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
4418
5002
|
this.#exited.catch(() => {}).finally(() => signal.removeEventListener("abort", onAbort));
|
|
4419
5003
|
}
|
|
5004
|
+
#clearTimeout() {
|
|
5005
|
+
if (!this.#timeoutTimer) return;
|
|
5006
|
+
clearTimeout(this.#timeoutTimer);
|
|
5007
|
+
this.#timeoutTimer = void 0;
|
|
5008
|
+
}
|
|
4420
5009
|
attachTimeout(ms) {
|
|
4421
5010
|
if (ms <= 0 || this.proc.killed) return;
|
|
4422
5011
|
this.#exited.catch(() => {});
|
|
4423
|
-
|
|
4424
|
-
if (
|
|
4425
|
-
|
|
5012
|
+
const timer = setTimeout(() => {
|
|
5013
|
+
if (this.proc.exitCode === null || this.#openPipeReaders > 0 && (this.#terminateGroup || this.#windowsRootProcess)) this.kill(new TimeoutError(ms, this.#stderrTail), -1);
|
|
5014
|
+
this.#resolveDrainCutoff();
|
|
5015
|
+
}, ms);
|
|
5016
|
+
timer.unref?.();
|
|
5017
|
+
this.#timeoutTimer = timer;
|
|
4426
5018
|
}
|
|
4427
5019
|
[Symbol.dispose]() {
|
|
4428
5020
|
if (this.proc.exitCode !== null) return;
|
|
@@ -4430,14 +5022,27 @@ var ChildProcess = class {
|
|
|
4430
5022
|
}
|
|
4431
5023
|
};
|
|
4432
5024
|
function spawnInternal(cmd, opts, retainFullStderr) {
|
|
4433
|
-
const { timeout = -1, signal, stderr, ...rest } = opts ?? {};
|
|
4434
|
-
const
|
|
5025
|
+
const { timeout = -1, signal, stderr, detached, subreaper = false, ...rest } = opts ?? {};
|
|
5026
|
+
const useSubreaper = subreaper && process.platform === "linux";
|
|
5027
|
+
const commandEnv = rest.env ?? Bun.env;
|
|
5028
|
+
const cp = new ChildProcess(Bun.spawn(useSubreaper ? [
|
|
5029
|
+
process.execPath,
|
|
5030
|
+
"-e",
|
|
5031
|
+
LINUX_SUBREAPER_SCRIPT
|
|
5032
|
+
] : cmd, {
|
|
4435
5033
|
stdin: "ignore",
|
|
4436
5034
|
stdout: "pipe",
|
|
4437
5035
|
stderr: "pipe",
|
|
4438
5036
|
windowsHide: true,
|
|
4439
|
-
|
|
4440
|
-
|
|
5037
|
+
detached,
|
|
5038
|
+
...rest,
|
|
5039
|
+
env: useSubreaper ? {
|
|
5040
|
+
...commandEnv,
|
|
5041
|
+
BUN_BE_BUN: "1",
|
|
5042
|
+
[LINUX_SUBREAPER_COMMAND_ENV]: JSON.stringify(cmd),
|
|
5043
|
+
[LINUX_SUBREAPER_BUN_BE_BUN_ENV]: commandEnv.BUN_BE_BUN
|
|
5044
|
+
} : rest.env
|
|
5045
|
+
}), stderr === "full", retainFullStderr, detached === true, useSubreaper);
|
|
4441
5046
|
if (signal) cp.attachSignal(signal);
|
|
4442
5047
|
if (timeout > 0) cp.attachTimeout(timeout);
|
|
4443
5048
|
return cp;
|
|
@@ -4486,7 +5091,7 @@ function combineSignals(...signals) {
|
|
|
4486
5091
|
}
|
|
4487
5092
|
}
|
|
4488
5093
|
//#endregion
|
|
4489
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@
|
|
5094
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/snowflake.ts
|
|
4490
5095
|
function randu32() {
|
|
4491
5096
|
return crypto.getRandomValues(/* @__PURE__ */ new Uint32Array(1))[0];
|
|
4492
5097
|
}
|
|
@@ -4565,29 +5170,9 @@ let Snowflake;
|
|
|
4565
5170
|
_Snowflake.getDate = getDate;
|
|
4566
5171
|
})(Snowflake || (Snowflake = {}));
|
|
4567
5172
|
//#endregion
|
|
4568
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@
|
|
5173
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/stream.ts
|
|
4569
5174
|
const trailingEvents = /* @__PURE__ */ new WeakSet();
|
|
4570
5175
|
const LF = 10;
|
|
4571
|
-
function parseJsonlChunkCompat(input, beg, end) {
|
|
4572
|
-
if (typeof input === "string") {
|
|
4573
|
-
const { values, error, read, done } = Bun.JSONL.parseChunk(input);
|
|
4574
|
-
return {
|
|
4575
|
-
values,
|
|
4576
|
-
error,
|
|
4577
|
-
read,
|
|
4578
|
-
done
|
|
4579
|
-
};
|
|
4580
|
-
}
|
|
4581
|
-
const start = beg ?? 0;
|
|
4582
|
-
const stop = end ?? input.length;
|
|
4583
|
-
const { values, error, read, done } = Bun.JSONL.parseChunk(input, start, stop);
|
|
4584
|
-
return {
|
|
4585
|
-
values,
|
|
4586
|
-
error,
|
|
4587
|
-
read,
|
|
4588
|
-
done
|
|
4589
|
-
};
|
|
4590
|
-
}
|
|
4591
5176
|
async function* readJsonl(stream, signal) {
|
|
4592
5177
|
const buffer = new ConcatSink();
|
|
4593
5178
|
const source = abortableSource(stream, signal);
|
|
@@ -4597,7 +5182,7 @@ async function* readJsonl(stream, signal) {
|
|
|
4597
5182
|
const tail = buffer.flush();
|
|
4598
5183
|
if (tail) {
|
|
4599
5184
|
buffer.clear();
|
|
4600
|
-
const { values, error, done } =
|
|
5185
|
+
const { values, error, done } = Bun.JSONL.parseChunk(tail, 0, tail.length);
|
|
4601
5186
|
if (values.length > 0) yield* values;
|
|
4602
5187
|
if (error) throw error;
|
|
4603
5188
|
if (!done) throw new Error("JSONL stream ended unexpectedly");
|
|
@@ -4687,8 +5272,14 @@ var ConcatSink = class {
|
|
|
4687
5272
|
return text;
|
|
4688
5273
|
}
|
|
4689
5274
|
*pullJSONL(chunk, beg, end) {
|
|
5275
|
+
const newline = chunk.indexOf(LF, beg);
|
|
5276
|
+
if (newline === -1 || newline >= end) {
|
|
5277
|
+
if (this.isEmpty) this.reset(chunk.subarray(beg, end));
|
|
5278
|
+
else this.append(chunk.subarray(beg, end));
|
|
5279
|
+
return;
|
|
5280
|
+
}
|
|
4690
5281
|
if (this.isEmpty) {
|
|
4691
|
-
const { values, error, read, done } =
|
|
5282
|
+
const { values, error, read, done } = Bun.JSONL.parseChunk(chunk, beg, end);
|
|
4692
5283
|
if (values.length > 0) yield* values;
|
|
4693
5284
|
if (error) throw error;
|
|
4694
5285
|
if (done) return;
|
|
@@ -4700,7 +5291,7 @@ var ConcatSink = class {
|
|
|
4700
5291
|
const space = this.#ensureCapacity(total);
|
|
4701
5292
|
space.set(chunk.subarray(beg, end), offset);
|
|
4702
5293
|
this.#length = total;
|
|
4703
|
-
const { values, error, read, done } =
|
|
5294
|
+
const { values, error, read, done } = Bun.JSONL.parseChunk(space, 0, total);
|
|
4704
5295
|
if (values.length > 0) yield* values;
|
|
4705
5296
|
if (error) throw error;
|
|
4706
5297
|
if (done) {
|
|
@@ -4859,7 +5450,7 @@ async function* readSseEvents(stream, signal) {
|
|
|
4859
5450
|
}
|
|
4860
5451
|
}
|
|
4861
5452
|
//#endregion
|
|
4862
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@
|
|
5453
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/temp.ts
|
|
4863
5454
|
var TempDir = class TempDir {
|
|
4864
5455
|
#path;
|
|
4865
5456
|
constructor(path) {
|
|
@@ -4956,7 +5547,7 @@ function sleepSync(ms) {
|
|
|
4956
5547
|
Atomics.wait(kSleepBuffer, 0, 0, ms);
|
|
4957
5548
|
}
|
|
4958
5549
|
//#endregion
|
|
4959
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@
|
|
5550
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/tls-fetch.ts
|
|
4960
5551
|
/**
|
|
4961
5552
|
* `NODE_EXTRA_CA_CERTS` shim for Bun's `fetch`.
|
|
4962
5553
|
*
|
|
@@ -5065,7 +5656,7 @@ function wrapFetchForExtraCa(fetchImpl) {
|
|
|
5065
5656
|
}, fetchImpl.preconnect ? { preconnect: fetchImpl.preconnect } : {}, { [EXTRA_CA_FETCH_MARKER]: true });
|
|
5066
5657
|
}
|
|
5067
5658
|
//#endregion
|
|
5068
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@
|
|
5659
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/index.ts
|
|
5069
5660
|
function isPlainObject(val) {
|
|
5070
5661
|
return Object.getPrototypeOf(val) === Object.prototype || Array.isArray(val);
|
|
5071
5662
|
}
|
|
@@ -5077,4 +5668,4 @@ function structuredCloneJSON(value) {
|
|
|
5077
5668
|
return JSON.parse(JSON.stringify(value));
|
|
5078
5669
|
}
|
|
5079
5670
|
//#endregion
|
|
5080
|
-
export {
|
|
5671
|
+
export { isEnoent as $, formatCount as A, USER_AGENT as B, warn as C, installBunShim as D, CookieMap as E, $flag as F, getDocsRsCacheDir as G, getAgentDir as H, $pickenv as I, getLogsDir as J, getDocumentConversionCacheDir as K, isBunTestRuntime as L, truncate as M, $env as N, formatAge as O, $envpos as P, hasFsCode as Q, isTerminalHeadless as R, time as S, Cookie as T, getAutoQaDbPath as U, VERSION as V, getDebugLogPath as W, getRemoteDir as X, getPuppeteerDir as Y, getToolsDir as Z, parseStreamingJson as _, readSseEvents as a, findOnPath as at, debug as b, combineSignals as c, $which as d, isEnotdir as et, register as f, parseJsonWithRepair as g, classifyJsonPrefix as h, readJsonl as i, untilAborted as it, formatNumber as j, formatBytes as k, exec as l, readImageMetadata as m, wrapFetchForExtraCa as n, peekFile as nt, readSseJson as o, parseImageMetadata as p, getInstallId as q, TempDir as r, once as rt, Snowflake as s, structuredCloneJSON as t, isProbablyBinary as tt, render as u, parseStreamingJsonThrottled as v, $ as w, error as x, parseFrontmatter as y, isWsl as z };
|