jinzd-ai-cli 0.4.306 → 0.4.308

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.
Files changed (95) hide show
  1. package/README.md +1 -0
  2. package/THIRD_PARTY_NOTICES.md +3 -0
  3. package/dist/{agent-client-6GX6QQDU.js → agent-client-TIEAYZXV.js} +4 -1
  4. package/dist/{auth-PE3Z5OHS.js → auth-QTQNZ6IX.js} +2 -2
  5. package/dist/{batch-JLGWQ7HU.js → batch-S7XLEEOH.js} +3 -3
  6. package/dist/{chat-index-2D5GK2DB.js → chat-index-7CLR4CBG.js} +4 -3
  7. package/dist/{chat-index-DGUOUUQW.js → chat-index-RLVLQRRC.js} +3 -2
  8. package/dist/{chunk-JDT6UG6R.js → chunk-2DYQDLLF.js} +1 -1
  9. package/dist/{chunk-T6WQEQI4.js → chunk-2MNUMLN4.js} +1 -1
  10. package/dist/chunk-2XMUCC42.js +67 -0
  11. package/dist/{chunk-7SSCSSC6.js → chunk-3537CQ5M.js} +2 -2
  12. package/dist/{chunk-OAXLMF3U.js → chunk-3YVNDYOY.js} +1 -1
  13. package/dist/{chunk-RYQBBEMM.js → chunk-4PR5AVJ5.js} +115 -19
  14. package/dist/{chunk-GHWZVPUV.js → chunk-6JHACXB3.js} +7 -5
  15. package/dist/{chunk-WZWRA7R2.js → chunk-7OHXFTZO.js} +2 -2
  16. package/dist/{chunk-IUVDZVZ4.js → chunk-AXTLYOA7.js} +24 -17
  17. package/dist/{chunk-XJOK5353.js → chunk-B3MPYI4E.js} +2 -2
  18. package/dist/{chunk-3RDJEYF7.js → chunk-BGZN4K7Q.js} +4 -4
  19. package/dist/chunk-BMLQPSHP.js +69 -0
  20. package/dist/{chunk-NRSYBKWA.js → chunk-C7CKDFJS.js} +1 -1
  21. package/dist/{chunk-JFNBJHR6.js → chunk-E2PNXNKI.js} +4 -4
  22. package/dist/chunk-FVXNEZEW.js +161 -0
  23. package/dist/{chunk-YKJO3SI4.js → chunk-G6DVGQ4I.js} +1 -1
  24. package/dist/{chunk-AYLK4EGA.js → chunk-HC33C4U3.js} +18 -18
  25. package/dist/chunk-JJFJWD35.js +162 -0
  26. package/dist/{chunk-W6PLV3EY.js → chunk-JJNUASMJ.js} +263 -55
  27. package/dist/{chunk-NYNSYLFY.js → chunk-JL44HGZC.js} +1 -1
  28. package/dist/{chunk-NUJTNH76.js → chunk-LBWKMTT3.js} +1 -1
  29. package/dist/{chunk-LAP7TPPK.js → chunk-LR3TGZWQ.js} +2 -2
  30. package/dist/{chunk-WQ3OMEC4.js → chunk-M6HLYG33.js} +1 -1
  31. package/dist/{chunk-I4GQRMFV.js → chunk-M6YV5KSS.js} +6 -4
  32. package/dist/{chunk-K5SDDTN7.js → chunk-NLK45GUS.js} +1 -1
  33. package/dist/{chunk-KBDKKHXB.js → chunk-O6CGOVD4.js} +2 -2
  34. package/dist/chunk-QMFMST2T.js +39 -0
  35. package/dist/{chunk-MI4SFZGX.js → chunk-RMEJR3AW.js} +5 -2
  36. package/dist/{chunk-UFW4S3RU.js → chunk-RVMCY6DP.js} +1 -1
  37. package/dist/{chunk-LF67HWWR.js → chunk-RWRZVQCB.js} +1 -1
  38. package/dist/chunk-SXIJLSVF.js +41 -0
  39. package/dist/chunk-TDQW2YHK.js +65 -0
  40. package/dist/{chunk-VLDB2SVN.js → chunk-TPTFV3Y6.js} +383 -513
  41. package/dist/{chunk-45UVJXFQ.js → chunk-W2UOVGRC.js} +1 -1
  42. package/dist/{chunk-VXEF2SWG.js → chunk-WT252ZDV.js} +2 -2
  43. package/dist/{chunk-NLB7JZSO.js → chunk-WVEIUSXE.js} +246 -55
  44. package/dist/{chunk-OC2XHG5L.js → chunk-YBZM7PHI.js} +4 -4
  45. package/dist/{ci-6PHEL3C7.js → ci-5HONSUAS.js} +7 -7
  46. package/dist/{ci-format-AZYUP6BL.js → ci-format-URUH3ZZ5.js} +2 -2
  47. package/dist/{constants-CPNWIUGZ.js → constants-BLDBI7IG.js} +1 -1
  48. package/dist/{constants-AXBD2EEB.js → constants-FG27DQMS.js} +1 -1
  49. package/dist/doctor-cli-QQLMNJN7.js +18 -0
  50. package/dist/electron-server.js +1003 -829
  51. package/dist/file-checkpoint-64A2AXHE.js +7 -0
  52. package/dist/{file-checkpoint-NKBHGC7L.js → file-checkpoint-VVPUJNCI.js} +2 -1
  53. package/dist/{hub-DDYAWLF2.js → hub-GGFW3DCC.js} +3 -3
  54. package/dist/{hub-server-CBKCP5VD.js → hub-server-JLC7CNP7.js} +55 -17
  55. package/dist/index.js +42 -40
  56. package/dist/{indexer-P3FPRTPJ.js → indexer-GKIWSSRP.js} +3 -3
  57. package/dist/indexer-VRXDZ74A.js +10 -0
  58. package/dist/{persist-S77WRVLD.js → persist-ZZXRWFBX.js} +4 -4
  59. package/dist/{persistent-memory-XZISXRWT.js → persistent-memory-UNLCXUWH.js} +3 -3
  60. package/dist/{persistent-memory-6XYYOMSC.js → persistent-memory-YYWIN6BG.js} +3 -3
  61. package/dist/{pr-UY4ZCZNI.js → pr-YCFGPFI7.js} +7 -7
  62. package/dist/{project-trust-MUG325AW.js → project-trust-6CJB5ZMX.js} +1 -1
  63. package/dist/{project-trust-NKYHL3VZ.js → project-trust-KGG2BWKC.js} +1 -1
  64. package/dist/run-tests-GHY4BYDE.js +13 -0
  65. package/dist/run-tests-KRNMFXAN.js +12 -0
  66. package/dist/{semantic-7GM5M4MU.js → semantic-N227CLSC.js} +4 -4
  67. package/dist/{semantic-QOBAXEQ4.js → semantic-TRQAZSRY.js} +4 -4
  68. package/dist/{server-6IC33CJK.js → server-73UBHSFV.js} +16 -14
  69. package/dist/{server-DBHLVQVP.js → server-QRAWSG4Z.js} +231 -103
  70. package/dist/{store-SIKHCUYJ.js → store-2N6PPPBP.js} +2 -2
  71. package/dist/{store-CMSSWZF7.js → store-76VVFDXM.js} +2 -2
  72. package/dist/{task-orchestrator-RDDETDW2.js → task-orchestrator-GI3RGLZI.js} +15 -14
  73. package/dist/{usage-D473ZVIP.js → usage-GWTIGZF5.js} +4 -4
  74. package/dist/{vector-store-JAXWDZYW.js → vector-store-T2DVUMY4.js} +2 -2
  75. package/dist/{vector-store-PWIOQFTP.js → vector-store-V6UGEYWK.js} +2 -2
  76. package/dist/web/client/app.js +7 -0
  77. package/dist/web/client/app.js.br +0 -0
  78. package/dist/web/client/app.js.gz +0 -0
  79. package/dist/web/client/util.js +14 -23
  80. package/dist/web/client/util.js.br +0 -0
  81. package/dist/web/client/util.js.gz +0 -0
  82. package/dist/web/client/vendor/DOMPurify-LICENSE.txt +202 -0
  83. package/dist/web/client/vendor/purify.es.mjs +2722 -0
  84. package/dist/web/client/vendor/purify.es.mjs.br +0 -0
  85. package/dist/web/client/vendor/purify.es.mjs.gz +0 -0
  86. package/package.json +4 -2
  87. package/dist/chunk-4BKXL7SM.js +0 -98
  88. package/dist/chunk-6BUTA5VW.js +0 -38
  89. package/dist/chunk-IW3Q7AE5.js +0 -40
  90. package/dist/chunk-SKET65WZ.js +0 -96
  91. package/dist/doctor-cli-DDHHDMMJ.js +0 -18
  92. package/dist/file-checkpoint-CGH6OJVI.js +0 -6
  93. package/dist/indexer-FPKY7LCT.js +0 -10
  94. package/dist/run-tests-BAMLVLO6.js +0 -10
  95. package/dist/run-tests-UEE3OMLS.js +0 -9
@@ -1,16 +1,195 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  TEST_TIMEOUT
4
- } from "./chunk-T6WQEQI4.js";
4
+ } from "./chunk-2MNUMLN4.js";
5
+ import {
6
+ getExecutionConfigDir,
7
+ getExecutionSignal
8
+ } from "./chunk-SXIJLSVF.js";
9
+
10
+ // src/tools/builtin/run-tests.ts
11
+ import { spawn as spawn2 } from "child_process";
12
+
13
+ // src/core/interrupt.ts
14
+ var controller = new AbortController();
15
+ var interrupted = false;
16
+ function currentAbortSignal() {
17
+ return getExecutionSignal() ?? controller.signal;
18
+ }
19
+ function isInterrupted() {
20
+ return interrupted;
21
+ }
22
+ function requestInterrupt() {
23
+ interrupted = true;
24
+ if (!controller.signal.aborted) {
25
+ controller.abort(new DOMException("User interrupted (Ctrl+C)", "AbortError"));
26
+ }
27
+ }
28
+ function resetInterrupt() {
29
+ controller = new AbortController();
30
+ interrupted = false;
31
+ }
32
+
33
+ // src/tools/win-shell.ts
34
+ import { platform } from "os";
35
+ import { spawn } from "child_process";
36
+ var IS_WINDOWS = platform() === "win32";
37
+ var WIN_UTF8_PREAMBLE = "[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; $OutputEncoding = [System.Text.Encoding]::UTF8; ";
38
+ function shellInvocation(command) {
39
+ if (IS_WINDOWS) {
40
+ return {
41
+ shell: "powershell.exe",
42
+ args: ["-NoProfile", "-NonInteractive", "-Command", WIN_UTF8_PREAMBLE + command]
43
+ };
44
+ }
45
+ return { shell: process.env["SHELL"] ?? "/bin/bash", args: ["-c", command] };
46
+ }
47
+ function decodeWindowsBuffer(buf) {
48
+ const utf8 = buf.toString("utf-8");
49
+ if (!utf8.includes("\uFFFD")) return utf8;
50
+ try {
51
+ return new TextDecoder("gbk").decode(buf);
52
+ } catch {
53
+ return utf8;
54
+ }
55
+ }
56
+ var GBK_MOJIBAKE_FINGERPRINTS = [
57
+ "\uFFFD",
58
+ "\u9215",
59
+ "\u951B",
60
+ "\u9983",
61
+ "\u9241",
62
+ "\u6D93",
63
+ "\u935B",
64
+ "\u9428",
65
+ "\u7EFE",
66
+ "\u95AB",
67
+ "\u9593",
68
+ "\u95BF",
69
+ "\u68E3",
70
+ "\u95B4",
71
+ "\u5A11",
72
+ "\u95B8",
73
+ "\u95BB",
74
+ "\u7F01",
75
+ "\u95C1"
76
+ ];
77
+ var gbkReverse = null;
78
+ function gbkReverseMap() {
79
+ if (gbkReverse) return gbkReverse;
80
+ const map = /* @__PURE__ */ new Map();
81
+ try {
82
+ const dec = new TextDecoder("gbk");
83
+ for (let hi = 129; hi <= 254; hi++) {
84
+ for (let lo = 64; lo <= 254; lo++) {
85
+ if (lo === 127) continue;
86
+ const ch = dec.decode(new Uint8Array([hi, lo]));
87
+ if (ch.length === 1 && ch !== "\uFFFD" && !map.has(ch)) map.set(ch, [hi, lo]);
88
+ }
89
+ }
90
+ } catch {
91
+ }
92
+ gbkReverse = map;
93
+ return map;
94
+ }
95
+ function decodeRunAsChinese(bytes) {
96
+ for (let start = 0; start <= 2 && start < bytes.length; start++) {
97
+ for (let end = 0; end <= 2 && bytes.length - end > start; end++) {
98
+ const slice = bytes.slice(start, bytes.length - end);
99
+ if (slice.length < 6) continue;
100
+ try {
101
+ const out = new TextDecoder("utf-8", { fatal: true }).decode(new Uint8Array(slice));
102
+ if (/[一-鿿]/.test(out)) return out;
103
+ } catch {
104
+ }
105
+ }
106
+ }
107
+ return null;
108
+ }
109
+ function recoverGbkMojibake(text) {
110
+ if (!text) return null;
111
+ const map = gbkReverseMap();
112
+ if (map.size === 0) return null;
113
+ let run = [];
114
+ let best = null;
115
+ const flush = () => {
116
+ if (run.length >= 4) {
117
+ const bytes = [];
118
+ for (const p of run) bytes.push(p[0], p[1]);
119
+ const out = decodeRunAsChinese(bytes);
120
+ if (out && (!best || out.length > best.length)) best = out;
121
+ }
122
+ run = [];
123
+ };
124
+ for (const ch of text) {
125
+ const pair = ch.codePointAt(0) < 128 ? void 0 : map.get(ch);
126
+ if (pair) run.push(pair);
127
+ else flush();
128
+ }
129
+ flush();
130
+ return best;
131
+ }
132
+ function looksLikeGbkMojibake(text) {
133
+ if (recoverGbkMojibake(text) !== null) return true;
134
+ let hits = 0;
135
+ for (const ch of GBK_MOJIBAKE_FINGERPRINTS) {
136
+ if (text.includes(ch) && ++hits >= 2) return true;
137
+ }
138
+ return false;
139
+ }
140
+ function killProcessTree(proc, processGroup = false) {
141
+ if (proc.killed || proc.exitCode !== null) return;
142
+ if (IS_WINDOWS && proc.pid) {
143
+ try {
144
+ const tk = spawn("taskkill", ["/PID", String(proc.pid), "/T", "/F"], {
145
+ windowsHide: true,
146
+ stdio: "ignore"
147
+ });
148
+ tk.on("exit", () => {
149
+ try {
150
+ proc.kill();
151
+ } catch {
152
+ }
153
+ });
154
+ tk.on("error", () => {
155
+ try {
156
+ proc.kill();
157
+ } catch {
158
+ }
159
+ });
160
+ } catch {
161
+ try {
162
+ proc.kill();
163
+ } catch {
164
+ }
165
+ }
166
+ return;
167
+ }
168
+ const signal = (value) => {
169
+ if (processGroup && proc.pid) process.kill(-proc.pid, value);
170
+ else proc.kill(value);
171
+ };
172
+ try {
173
+ signal("SIGTERM");
174
+ } catch {
175
+ }
176
+ setTimeout(() => {
177
+ if (processGroup || proc.exitCode === null) {
178
+ try {
179
+ signal("SIGKILL");
180
+ } catch {
181
+ }
182
+ }
183
+ }, 500).unref();
184
+ }
5
185
 
6
186
  // src/tools/builtin/run-tests.ts
7
- import { execSync, spawnSync } from "child_process";
8
187
  import { existsSync, readFileSync, readdirSync } from "fs";
9
188
  import { join } from "path";
10
- import { platform } from "os";
189
+ import { platform as platform2 } from "os";
11
190
  import chalk from "chalk";
12
- var FILTER_WHITELIST = /^[\w.\-/:#\s*?()\[\]@+]{1,200}$/;
13
- var IS_WINDOWS = platform() === "win32";
191
+ var FILTER_WHITELIST = /^[\w.\-/:# *?\[\]@+]{1,200}$/;
192
+ var IS_WINDOWS2 = platform2() === "win32";
14
193
  function detectNodeTestFramework(cwd, pkg) {
15
194
  const devDeps = pkg.devDependencies ?? {};
16
195
  const deps = pkg.dependencies ?? {};
@@ -80,11 +259,11 @@ function safeReadPackageJson(cwd) {
80
259
  }
81
260
  function detectProject(cwd) {
82
261
  if (existsSync(join(cwd, "pom.xml"))) {
83
- return { type: "java", framework: "Maven (JUnit)", command: IS_WINDOWS ? "mvn.cmd test" : "mvn test" };
262
+ return { type: "java", framework: "Maven (JUnit)", command: IS_WINDOWS2 ? "mvn.cmd test" : "mvn test" };
84
263
  }
85
264
  if (existsSync(join(cwd, "build.gradle")) || existsSync(join(cwd, "build.gradle.kts"))) {
86
- const wrapper = IS_WINDOWS ? "gradlew.bat" : "./gradlew";
87
- const cmd = existsSync(join(cwd, IS_WINDOWS ? "gradlew.bat" : "gradlew")) ? `${wrapper} test` : "gradle test";
265
+ const wrapper = IS_WINDOWS2 ? "gradlew.bat" : "./gradlew";
266
+ const cmd = existsSync(join(cwd, IS_WINDOWS2 ? "gradlew.bat" : "gradlew")) ? `${wrapper} test` : "gradle test";
88
267
  return { type: "java", framework: "Gradle (JUnit)", command: cmd };
89
268
  }
90
269
  if (existsSync(join(cwd, "package.json"))) {
@@ -240,7 +419,7 @@ function renderColorReport(summary, framework) {
240
419
  console.log();
241
420
  }
242
421
  function needsWindowsShell(file) {
243
- if (!IS_WINDOWS) return false;
422
+ if (!IS_WINDOWS2) return false;
244
423
  const lower = file.toLowerCase();
245
424
  return lower.endsWith(".cmd") || lower.endsWith(".bat") || lower === "mvn" || lower === "gradle" || lower === "npm" || lower === "npx";
246
425
  }
@@ -307,51 +486,9 @@ Got: ${filter.slice(0, 60)}${filter.length > 60 ? "..." : ""}`;
307
486
  framework = detected.framework;
308
487
  argv = buildArgv(detected, filter);
309
488
  }
310
- let output;
311
- let exitCode = 0;
312
- if (argv) {
313
- const r = spawnSync(argv.file, argv.args, {
314
- cwd,
315
- timeout: TEST_TIMEOUT,
316
- stdio: ["pipe", "pipe", "pipe"],
317
- // shell:false is the default for spawnSync; on Windows .cmd/.bat
318
- // requires shell:true, so we opt-in only for known wrapper names.
319
- shell: needsWindowsShell(argv.file),
320
- env: {
321
- ...process.env,
322
- ...IS_WINDOWS ? {} : { FORCE_COLOR: "0" }
323
- },
324
- encoding: "utf-8",
325
- maxBuffer: 64 * 1024 * 1024
326
- });
327
- if (r.error) {
328
- output = `Failed to launch test runner: ${r.error.message}`;
329
- exitCode = 1;
330
- } else {
331
- exitCode = r.status ?? 1;
332
- output = (r.stdout ?? "") + (r.stderr ? "\n" + r.stderr : "");
333
- }
334
- } else {
335
- try {
336
- const buf = execSync(command, {
337
- cwd,
338
- timeout: TEST_TIMEOUT,
339
- encoding: "buffer",
340
- stdio: ["pipe", "pipe", "pipe"],
341
- env: {
342
- ...process.env,
343
- ...IS_WINDOWS ? {} : { FORCE_COLOR: "0" }
344
- }
345
- });
346
- output = buf.toString("utf-8");
347
- } catch (err) {
348
- const e = err;
349
- exitCode = e.status ?? 1;
350
- const stdout = e.stdout?.toString("utf-8") ?? "";
351
- const stderr = e.stderr?.toString("utf-8") ?? "";
352
- output = stdout + (stderr ? "\n" + stderr : "");
353
- }
354
- }
489
+ const result = await runTestProcess(argv, command, cwd, currentAbortSignal());
490
+ const output = result.output;
491
+ const exitCode = result.exitCode;
355
492
  let summary = {
356
493
  tests: 0,
357
494
  passed: 0,
@@ -390,6 +527,7 @@ Got: ${filter.slice(0, 60)}${filter.length > 60 ? "..." : ""}`;
390
527
  }
391
528
  }
392
529
  }
530
+ if (exitCode !== 0 && summary.failures + summary.errors === 0) summary.errors = 1;
393
531
  renderColorReport(summary, framework);
394
532
  return formatReport(summary, framework, output, exitCode);
395
533
  }
@@ -414,8 +552,78 @@ var runTestsTool = {
414
552
  return executeTests(args);
415
553
  }
416
554
  };
555
+ var MAX_TEST_OUTPUT_BYTES = 4 * 1024 * 1024;
556
+ var activeTestProcesses = 0;
557
+ var activeTestsByOwner = /* @__PURE__ */ new Map();
558
+ async function runTestProcess(argv, command, cwd, signal) {
559
+ if (signal.aborted) throw new Error("Test run cancelled");
560
+ const owner = getExecutionConfigDir();
561
+ if ((activeTestsByOwner.get(owner) ?? 0) >= 2) throw new Error("Test runner capacity reached (2 per user).");
562
+ if (activeTestProcesses >= 4) throw new Error("Test runner capacity reached (4). Try again after a run finishes.");
563
+ activeTestProcesses++;
564
+ activeTestsByOwner.set(owner, (activeTestsByOwner.get(owner) ?? 0) + 1);
565
+ try {
566
+ return await new Promise((resolve, reject) => {
567
+ const child = argv ? spawn2(argv.file, argv.args, { cwd, shell: needsWindowsShell(argv.file), windowsHide: true, detached: !IS_WINDOWS2, stdio: ["ignore", "pipe", "pipe"] }) : spawn2(command, { cwd, shell: true, windowsHide: true, detached: !IS_WINDOWS2, stdio: ["ignore", "pipe", "pipe"] });
568
+ const chunks = [];
569
+ let bytes = 0;
570
+ let stopped = "";
571
+ let settled = false;
572
+ const stop = (reason) => {
573
+ if (stopped) return;
574
+ stopped = reason;
575
+ killProcessTree(child, true);
576
+ };
577
+ const onAbort = () => stop("Test run cancelled");
578
+ const timer = setTimeout(() => stop("Test run timed out"), TEST_TIMEOUT);
579
+ signal.addEventListener("abort", onAbort, { once: true });
580
+ if (signal.aborted) onAbort();
581
+ const append = (chunk) => {
582
+ const take = Math.min(chunk.length, MAX_TEST_OUTPUT_BYTES - bytes);
583
+ if (take > 0) chunks.push(chunk.subarray(0, take));
584
+ bytes += take;
585
+ if (bytes >= MAX_TEST_OUTPUT_BYTES) stop("Test output exceeded 4 MiB limit");
586
+ };
587
+ child.stdout?.on("data", append);
588
+ child.stderr?.on("data", append);
589
+ const clean = () => {
590
+ clearTimeout(timer);
591
+ signal.removeEventListener("abort", onAbort);
592
+ };
593
+ child.once("error", (error) => {
594
+ if (settled) return;
595
+ settled = true;
596
+ clean();
597
+ reject(error);
598
+ });
599
+ child.once("close", (code) => {
600
+ if (settled) return;
601
+ settled = true;
602
+ clean();
603
+ resolve({ output: Buffer.concat(chunks).toString("utf8") + (stopped ? "\n" + stopped : ""), exitCode: stopped ? 1 : code ?? 1 });
604
+ });
605
+ });
606
+ } finally {
607
+ activeTestProcesses--;
608
+ const remaining = (activeTestsByOwner.get(owner) ?? 1) - 1;
609
+ if (remaining) activeTestsByOwner.set(owner, remaining);
610
+ else activeTestsByOwner.delete(owner);
611
+ }
612
+ }
417
613
 
418
614
  export {
615
+ IS_WINDOWS,
616
+ WIN_UTF8_PREAMBLE,
617
+ shellInvocation,
618
+ decodeWindowsBuffer,
619
+ recoverGbkMojibake,
620
+ looksLikeGbkMojibake,
621
+ killProcessTree,
622
+ currentAbortSignal,
623
+ isInterrupted,
624
+ requestInterrupt,
625
+ resetInterrupt,
419
626
  executeTests,
420
- runTestsTool
627
+ runTestsTool,
628
+ runTestProcess
421
629
  };
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  atomicWriteFileSync
4
- } from "./chunk-IW3Q7AE5.js";
4
+ } from "./chunk-BMLQPSHP.js";
5
5
 
6
6
  // src/session/session-index.ts
7
7
  import { existsSync, readFileSync as readFileSync2, readdirSync, statSync } from "fs";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  SessionManager
4
- } from "./chunk-IUVDZVZ4.js";
4
+ } from "./chunk-AXTLYOA7.js";
5
5
 
6
6
  // src/hub/persist.ts
7
7
  import { join } from "path";
@@ -8,12 +8,12 @@ import {
8
8
  } from "./chunk-HOSJZMQS.js";
9
9
  import {
10
10
  atomicWriteFileSync
11
- } from "./chunk-IW3Q7AE5.js";
11
+ } from "./chunk-BMLQPSHP.js";
12
12
  import {
13
13
  MEMORY_FILE_NAME,
14
14
  MEMORY_MAX_CHARS,
15
15
  MEMORY_STORE_FILE_NAME
16
- } from "./chunk-T6WQEQI4.js";
16
+ } from "./chunk-2MNUMLN4.js";
17
17
 
18
18
  // src/memory/persistent-memory.ts
19
19
  import { copyFileSync, existsSync, mkdirSync, readFileSync, statSync } from "fs";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  atomicWriteFileSync
4
- } from "./chunk-IW3Q7AE5.js";
4
+ } from "./chunk-BMLQPSHP.js";
5
5
 
6
6
  // src/symbols/store.ts
7
7
  import fs from "fs";
@@ -8,12 +8,14 @@ import {
8
8
  } from "./chunk-FSC6KEWU.js";
9
9
  import {
10
10
  atomicWriteFileSync
11
- } from "./chunk-6BUTA5VW.js";
11
+ } from "./chunk-2XMUCC42.js";
12
+ import {
13
+ getExecutionConfigDir
14
+ } from "./chunk-QMFMST2T.js";
12
15
 
13
16
  // src/memory/chat-index.ts
14
17
  import fs from "fs";
15
18
  import path from "path";
16
- import os from "os";
17
19
  import crypto from "crypto";
18
20
 
19
21
  // src/session/session-index.ts
@@ -311,7 +313,7 @@ var VEC_MAGIC = 1094929750;
311
313
  var VEC_VERSION = 1;
312
314
  var VEC_HEADER_BYTES = 16;
313
315
  function memoryIndexDir() {
314
- return path.join(os.homedir(), ".aicli", MEMORY_DIR_NAME);
316
+ return path.join(getExecutionConfigDir(), MEMORY_DIR_NAME);
315
317
  }
316
318
  function chunksPath() {
317
319
  return path.join(memoryIndexDir(), CHUNKS_FILE);
@@ -320,7 +322,7 @@ function vectorsPath() {
320
322
  return path.join(memoryIndexDir(), VECTORS_FILE);
321
323
  }
322
324
  function historyDir() {
323
- return path.join(os.homedir(), ".aicli", "history");
325
+ return path.join(getExecutionConfigDir(), "history");
324
326
  }
325
327
  var MAX_CHUNK_CHARS = 1200;
326
328
  var MIN_CHUNK_CHARS = 40;
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  VERSION
4
- } from "./chunk-T6WQEQI4.js";
4
+ } from "./chunk-2MNUMLN4.js";
5
5
 
6
6
  // src/cli/ci-format.ts
7
7
  var DEFAULT_CI_THRESHOLDS = {
@@ -2,7 +2,7 @@ import {
2
2
  loadVectorStore,
3
3
  saveVectorStore,
4
4
  searchVectorStore
5
- } from "./chunk-OAXLMF3U.js";
5
+ } from "./chunk-3YVNDYOY.js";
6
6
  import {
7
7
  EMBEDDING_DIM,
8
8
  embed,
@@ -11,7 +11,7 @@ import {
11
11
  import {
12
12
  loadIndex,
13
13
  symbolFingerprint
14
- } from "./chunk-45UVJXFQ.js";
14
+ } from "./chunk-W2UOVGRC.js";
15
15
 
16
16
  // src/symbols/semantic.ts
17
17
  function pathTokens(absFile, root) {
@@ -0,0 +1,39 @@
1
+ // src/tools/session-context.ts
2
+ import { AsyncLocalStorage } from "async_hooks";
3
+ import { homedir } from "os";
4
+ import { join } from "path";
5
+ var als = new AsyncLocalStorage();
6
+ var defaultState = /* @__PURE__ */ new Map();
7
+ function getExecutionConfigDir() {
8
+ return als.getStore()?.configDir ?? join(homedir(), ".aicli");
9
+ }
10
+ function getExecutionSignal() {
11
+ return als.getStore()?.signal;
12
+ }
13
+ function scopedState(key, create) {
14
+ const state = als.getStore()?.state ?? defaultState;
15
+ if (!state.has(key)) state.set(key, create());
16
+ return state.get(key);
17
+ }
18
+ function runWithExecutionContext(context, fn) {
19
+ return als.run({ sessionKey: DEFAULT_SESSION_KEY, ...als.getStore(), ...context }, fn);
20
+ }
21
+ var DEFAULT_SESSION_KEY = "__default__";
22
+ function getCurrentSessionKey() {
23
+ const ctx = als.getStore();
24
+ if (!ctx || !ctx.sessionKey) return DEFAULT_SESSION_KEY;
25
+ return ctx.sessionKey;
26
+ }
27
+ function runWithSessionKey(sessionKey, fn) {
28
+ const key = sessionKey && sessionKey.length > 0 ? sessionKey : DEFAULT_SESSION_KEY;
29
+ return als.run({ ...als.getStore(), sessionKey: key }, fn);
30
+ }
31
+
32
+ export {
33
+ getExecutionConfigDir,
34
+ getExecutionSignal,
35
+ scopedState,
36
+ runWithExecutionContext,
37
+ getCurrentSessionKey,
38
+ runWithSessionKey
39
+ };
@@ -1146,6 +1146,7 @@ function getDangerLevel(toolName, args) {
1146
1146
  }
1147
1147
  if (toolName === "bash") {
1148
1148
  const cmd = String(args["command"] ?? "");
1149
+ if (/\bgit\s+(?:clean\b|reset\s+--hard\b|push\b[^\n]*(?:--force\b|\s-f\b))/i.test(cmd)) return "destructive";
1149
1150
  if (/\brm\s+[^\n]*(?:-\w*[rRfF]\w*|--recursive|--force)\b/.test(cmd)) return "destructive";
1150
1151
  if (/\brm\s+\S/.test(cmd)) return "destructive";
1151
1152
  if (/\brmdir\b|\bformat\b|\bmkfs\b|\bdd\s+if=|\bshred\b|\bfdisk\b|\bparted\b/.test(cmd)) return "destructive";
@@ -1161,8 +1162,10 @@ function getDangerLevel(toolName, args) {
1161
1162
  if (/\bSet-Content\b|\bOut-File\b|\bAdd-Content\b|\bCopy-Item\b|\bMove-Item\b|\bSet-ItemProperty\b|\bNew-ItemProperty\b/i.test(cmd)) return "write";
1162
1163
  if (/\b(python3?|node|deno|bun|perl|ruby|php|bash|sh|zsh|pwsh|powershell)(\.exe)?\b[^\n]*?\s-(?:Command|EncodedCommand|c|e|p|r)\b/i.test(cmd)) return "write";
1163
1164
  if (/\bcmd(\.exe)?\s+\/[ck]\b/i.test(cmd)) return "write";
1164
- return "safe";
1165
+ if (!/[;&|`$<>\n\r(){}]/.test(cmd) && (/^(?:pwd|ls|cat|head|tail|wc|Get-ChildItem|Get-Location|Get-Content)(?:\s+[\w ./\\:*?=,@'"-]+)?\s*$/i.test(cmd.trim()) || /^echo(?:\s+[\w .,'"-]+)?\s*$/.test(cmd.trim()) || /^(?:node|python3?)\s+(?:-v|--version)\s*$/.test(cmd.trim()) || /^git\s+(?:status|log)(?:\s+(?:--short|--porcelain|--oneline|-\d+))*\s*$/.test(cmd.trim()))) return "safe";
1166
+ return "write";
1165
1167
  }
1168
+ if (toolName === "run_tests") return "write";
1166
1169
  if (toolName === "write_file") return "write";
1167
1170
  if (toolName === "edit_file") return "write";
1168
1171
  if (toolName === "save_last_response") return "write";
@@ -1177,7 +1180,7 @@ function getDangerLevel(toolName, args) {
1177
1180
  if (toolName === "git_commit") return "write";
1178
1181
  if (toolName === "git_status" || toolName === "git_diff" || toolName === "git_log") return "safe";
1179
1182
  if (toolName === "notebook_edit") return "write";
1180
- if (toolName === "read_file" || toolName === "list_dir" || toolName === "grep_files" || toolName === "glob_files" || toolName === "web_fetch" || toolName === "save_memory" || toolName === "ask_user" || toolName === "write_todos" || toolName === "google_search" || toolName === "spawn_agent" || toolName === "run_tests") return "safe";
1183
+ if (toolName === "read_file" || toolName === "list_dir" || toolName === "grep_files" || toolName === "glob_files" || toolName === "web_fetch" || toolName === "save_memory" || toolName === "ask_user" || toolName === "write_todos" || toolName === "google_search" || toolName === "spawn_agent") return "safe";
1181
1184
  return "write";
1182
1185
  }
1183
1186
  function schemaToJsonSchema(schema) {
@@ -5,7 +5,7 @@ import {
5
5
  removeFile,
6
6
  saveIndex,
7
7
  upsertFileSymbols
8
- } from "./chunk-45UVJXFQ.js";
8
+ } from "./chunk-W2UOVGRC.js";
9
9
 
10
10
  // src/symbols/indexer.ts
11
11
  import fs2 from "fs";
@@ -6,7 +6,7 @@ import {
6
6
  removeFile,
7
7
  saveIndex,
8
8
  upsertFileSymbols
9
- } from "./chunk-WQ3OMEC4.js";
9
+ } from "./chunk-M6HLYG33.js";
10
10
 
11
11
  // src/symbols/indexer.ts
12
12
  import fs2 from "fs";
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/tools/session-context.ts
4
+ import { AsyncLocalStorage } from "async_hooks";
5
+ import { homedir } from "os";
6
+ import { join } from "path";
7
+ var als = new AsyncLocalStorage();
8
+ var defaultState = /* @__PURE__ */ new Map();
9
+ function getExecutionConfigDir() {
10
+ return als.getStore()?.configDir ?? join(homedir(), ".aicli");
11
+ }
12
+ function getExecutionSignal() {
13
+ return als.getStore()?.signal;
14
+ }
15
+ function scopedState(key, create) {
16
+ const state = als.getStore()?.state ?? defaultState;
17
+ if (!state.has(key)) state.set(key, create());
18
+ return state.get(key);
19
+ }
20
+ function runWithExecutionContext(context, fn) {
21
+ return als.run({ sessionKey: DEFAULT_SESSION_KEY, ...als.getStore(), ...context }, fn);
22
+ }
23
+ var DEFAULT_SESSION_KEY = "__default__";
24
+ function getCurrentSessionKey() {
25
+ const ctx = als.getStore();
26
+ if (!ctx || !ctx.sessionKey) return DEFAULT_SESSION_KEY;
27
+ return ctx.sessionKey;
28
+ }
29
+ function runWithSessionKey(sessionKey, fn) {
30
+ const key = sessionKey && sessionKey.length > 0 ? sessionKey : DEFAULT_SESSION_KEY;
31
+ return als.run({ ...als.getStore(), sessionKey: key }, fn);
32
+ }
33
+
34
+ export {
35
+ getExecutionConfigDir,
36
+ getExecutionSignal,
37
+ scopedState,
38
+ runWithExecutionContext,
39
+ getCurrentSessionKey,
40
+ runWithSessionKey
41
+ };
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/web/access.ts
4
+ import { randomBytes, timingSafeEqual } from "crypto";
5
+ import { networkInterfaces } from "os";
6
+ function equalToken(a, b) {
7
+ if (typeof a !== "string" || a.length > 4096) return false;
8
+ const left = Buffer.from(a), right = Buffer.from(b);
9
+ return left.length === right.length && timingSafeEqual(left, right);
10
+ }
11
+ var WebAccess = class {
12
+ constructor(host, externalOrigin) {
13
+ this.externalOrigin = externalOrigin;
14
+ if (!["0.0.0.0", "::"].includes(host)) this.hosts.add(host.includes(":") ? `[${host}]` : host.toLowerCase());
15
+ else for (const interfaces of Object.values(networkInterfaces())) for (const entry of interfaces ?? []) {
16
+ this.hosts.add(entry.address.includes(":") ? `[${entry.address}]` : entry.address);
17
+ }
18
+ if (externalOrigin && new URL(externalOrigin).origin !== externalOrigin) throw new Error("External origin must be an exact http(s) origin");
19
+ if (externalOrigin && !/^https?:\/\//.test(externalOrigin)) throw new Error("External origin must use HTTP(S)");
20
+ }
21
+ externalOrigin;
22
+ localToken = randomBytes(32).toString("base64url");
23
+ hosts = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "[::1]"]);
24
+ accepts(req) {
25
+ const host = req.headers.host;
26
+ if (!host) return false;
27
+ try {
28
+ const url = new URL(`http://${host}`);
29
+ const internal = this.hosts.has(url.hostname.toLowerCase()) && Number(url.port || 80) === req.socket.localPort;
30
+ const external = this.externalOrigin && new URL(this.externalOrigin).host === host;
31
+ if (!internal && !external) return false;
32
+ const origin = req.headers.origin;
33
+ return !origin || origin === (external ? this.externalOrigin : `http://${host}`);
34
+ } catch {
35
+ return false;
36
+ }
37
+ }
38
+ };
39
+ var AuthRateLimiter = class {
40
+ ips = /* @__PURE__ */ new Map();
41
+ start = 0;
42
+ count = 0;
43
+ take(ip) {
44
+ const now = Date.now();
45
+ if (now - this.start >= 6e4) {
46
+ this.start = now;
47
+ this.count = 0;
48
+ }
49
+ if (++this.count > 120) return false;
50
+ for (const [key, value] of this.ips) if (now - value.start >= 6e4) this.ips.delete(key);
51
+ let bucket = this.ips.get(ip);
52
+ if (!bucket) {
53
+ if (this.ips.size >= 2048) return false;
54
+ bucket = { start: now, count: 0 };
55
+ this.ips.set(ip, bucket);
56
+ }
57
+ return ++bucket.count <= 30;
58
+ }
59
+ };
60
+
61
+ export {
62
+ equalToken,
63
+ WebAccess,
64
+ AuthRateLimiter
65
+ };