jinzd-ai-cli 0.4.246 → 0.4.248

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 (48) hide show
  1. package/README.md +8 -3
  2. package/README.zh-CN.md +8 -3
  3. package/dist/{batch-AHW7WALD.js → batch-CC3LCNXM.js} +2 -2
  4. package/dist/{chat-index-ALUHFJKI.js → chat-index-7MMTGQNA.js} +2 -2
  5. package/dist/{chat-index-ML5FF5L6.js → chat-index-Q6BKWWAM.js} +1 -1
  6. package/dist/{chunk-DJDEXHOT.js → chunk-23ZIOVZR.js} +4 -4
  7. package/dist/{chunk-QYQI7ZWK.js → chunk-2QZMITSL.js} +13 -1
  8. package/dist/{chunk-IGPFYNZA.js → chunk-6RPGQ5CG.js} +1 -1
  9. package/dist/{chunk-XK22CVID.js → chunk-BIZFOVNA.js} +1 -1
  10. package/dist/{chunk-YVMACMXW.js → chunk-EWLXBTSC.js} +1 -1
  11. package/dist/{chunk-OMSOAFXY.js → chunk-G77EIVBY.js} +1 -1
  12. package/dist/{chunk-K3CF65QH.js → chunk-GLSR2NR3.js} +1 -1
  13. package/dist/{chunk-CJ3BPLHZ.js → chunk-GS5XW5UJ.js} +1 -1
  14. package/dist/{chunk-E44DTERW.js → chunk-GUOLPI33.js} +3 -0
  15. package/dist/{chunk-6Y42RN5H.js → chunk-HTOKVD7R.js} +4 -4
  16. package/dist/{chunk-DT77O33T.js → chunk-JQXXPTWL.js} +1 -1
  17. package/dist/{chunk-PJ3ONBWZ.js → chunk-NYNSYLFY.js} +1 -1
  18. package/dist/{chunk-KWQKQVPH.js → chunk-OBULDJSU.js} +1 -1
  19. package/dist/{chunk-LEKOBVOQ.js → chunk-OHV7DYIS.js} +4 -5
  20. package/dist/{chunk-LZGPGPA6.js → chunk-PNFQDFHK.js} +1 -1
  21. package/dist/{chunk-BNERFXVO.js → chunk-QCG6UU2S.js} +1 -1
  22. package/dist/{chunk-Z7JROM3J.js → chunk-SAZGFYBU.js} +1 -1
  23. package/dist/{chunk-P2LB6S4I.js → chunk-SHG2QSQA.js} +1 -1
  24. package/dist/{chunk-USJF35NB.js → chunk-U3QWCBRG.js} +1 -1
  25. package/dist/{chunk-GQYRPBIQ.js → chunk-WYRW2W4O.js} +12 -12
  26. package/dist/{chunk-WYNPWHXB.js → chunk-Z4LVPM3N.js} +1 -1
  27. package/dist/{chunk-NV63EYFL.js → chunk-ZWEZNKDW.js} +1 -1
  28. package/dist/{chunk-YQUBYTDR.js → chunk-ZX3ZYRU7.js} +1 -1
  29. package/dist/{ci-VOGIC6S4.js → ci-KFVU4CHS.js} +5 -5
  30. package/dist/{ci-format-BHCSMT5U.js → ci-format-IFFCSCCN.js} +2 -2
  31. package/dist/{constants-J4OLBH72.js → constants-3C4JLZVQ.js} +1 -1
  32. package/dist/{doctor-cli-IR3E3XHB.js → doctor-cli-XJOK5LJZ.js} +5 -5
  33. package/dist/electron-server.js +170 -136
  34. package/dist/{hub-SFFFYMGO.js → hub-6TQFYGZO.js} +2 -2
  35. package/dist/index.js +31 -32
  36. package/dist/{indexer-4WWS3VIL.js → indexer-M2LJGTY2.js} +1 -1
  37. package/dist/{indexer-2AG4G6B5.js → indexer-VZETNE4H.js} +1 -1
  38. package/dist/{persist-WGIJ6RXY.js → persist-A2QSXYFY.js} +3 -3
  39. package/dist/{persistent-memory-EKZ2JF7M.js → persistent-memory-JBWBMA56.js} +2 -2
  40. package/dist/{persistent-memory-3KH2EVHA.js → persistent-memory-QQXFCUNL.js} +2 -2
  41. package/dist/{pr-BNS3OHDM.js → pr-TMPU2U2P.js} +5 -5
  42. package/dist/{run-tests-PW4WC4OG.js → run-tests-2A3CASVZ.js} +2 -2
  43. package/dist/{run-tests-ZKHXKCQB.js → run-tests-NNML2XVV.js} +2 -2
  44. package/dist/{server-D2ID3GYA.js → server-6L5XRY4K.js} +113 -93
  45. package/dist/{server-3HLBEWNZ.js → server-ANNA57CP.js} +8 -8
  46. package/dist/{task-orchestrator-FMCI4RPX.js → task-orchestrator-URY32ZSQ.js} +8 -9
  47. package/dist/{usage-DPLNMDSJ.js → usage-J46NVHYR.js} +4 -4
  48. package/package.json +5 -4
@@ -7,13 +7,13 @@ import {
7
7
  searchCandidates,
8
8
  searchChatMemory,
9
9
  updateSessionInIndex
10
- } from "./chunk-NV63EYFL.js";
10
+ } from "./chunk-ZWEZNKDW.js";
11
11
  import {
12
12
  fileCheckpoints
13
13
  } from "./chunk-SKET65WZ.js";
14
14
  import {
15
15
  indexProject
16
- } from "./chunk-BNERFXVO.js";
16
+ } from "./chunk-QCG6UU2S.js";
17
17
  import {
18
18
  addMemoryEntry,
19
19
  clearMemoryEntries,
@@ -34,14 +34,14 @@ import {
34
34
  touchMemoryReferences,
35
35
  updateMemoryApproval,
36
36
  updateMemoryEntry
37
- } from "./chunk-CJ3BPLHZ.js";
37
+ } from "./chunk-GS5XW5UJ.js";
38
38
  import {
39
39
  redactJson,
40
40
  scanString
41
41
  } from "./chunk-YVTASHS5.js";
42
42
  import {
43
43
  runTestsTool
44
- } from "./chunk-USJF35NB.js";
44
+ } from "./chunk-U3QWCBRG.js";
45
45
  import {
46
46
  AGENTIC_BEHAVIOR_GUIDELINE,
47
47
  APP_NAME,
@@ -73,7 +73,7 @@ import {
73
73
  SUBAGENT_MAX_ROUNDS_LIMIT,
74
74
  VERSION,
75
75
  buildUserIdentityPrompt
76
- } from "./chunk-LZGPGPA6.js";
76
+ } from "./chunk-PNFQDFHK.js";
77
77
  import {
78
78
  hasSemanticIndex,
79
79
  semanticSearch
@@ -91,8 +91,8 @@ import {
91
91
  import express from "express";
92
92
  import { createServer } from "http";
93
93
  import { WebSocketServer } from "ws";
94
- import { join as join27, dirname as dirname10, resolve as resolve12, relative as relative6, sep as sep4 } from "path";
95
- import { existsSync as existsSync31, readFileSync as readFileSync24, readdirSync as readdirSync16, statSync as statSync14, realpathSync as realpathSync3 } from "fs";
94
+ import { join as join25, dirname as dirname10, resolve as resolve10, relative as relative6, sep as sep4 } from "path";
95
+ import { existsSync as existsSync30, readFileSync as readFileSync23, readdirSync as readdirSync15, statSync as statSync13, realpathSync as realpathSync3 } from "fs";
96
96
  import { networkInterfaces } from "os";
97
97
 
98
98
  // src/config/config-manager.ts
@@ -2982,7 +2982,6 @@ var OpenAICompatibleProvider = class extends BaseProvider {
2982
2982
  const message = firstChoice.message;
2983
2983
  const finishReason = firstChoice.finish_reason;
2984
2984
  const usage = toUsage(response.usage);
2985
- const contentStr = typeof message.content === "string" ? message.content : "";
2986
2985
  const hasToolCalls = !!(message.tool_calls && message.tool_calls.length > 0);
2987
2986
  const reasoningContent = message.reasoning_content;
2988
2987
  if (message.tool_calls && message.tool_calls.length > 0) {
@@ -3407,6 +3406,7 @@ var KimiProvider = class _KimiProvider extends OpenAICompatibleProvider {
3407
3406
  * 其他值会收到 400 "invalid temperature: only 1 is allowed for this model"。
3408
3407
  */
3409
3408
  static TEMP_1_MODELS = /* @__PURE__ */ new Set([
3409
+ "kimi-k3",
3410
3410
  "kimi-k2.6",
3411
3411
  "kimi-k2.5",
3412
3412
  "kimi-k2-thinking",
@@ -3433,6 +3433,18 @@ var KimiProvider = class _KimiProvider extends OpenAICompatibleProvider {
3433
3433
  requiresApiKey: true,
3434
3434
  baseUrl: this.defaultBaseUrl,
3435
3435
  models: [
3436
+ // Kimi K3(2026-07 旗舰,1M 上下文,多步推理 + 原生 vision)。
3437
+ // 官方文档核实(platform.kimi.ai/docs/guide/kimi-k3-quickstart):
3438
+ // - contextWindow 1M(1048576);code 就是 `kimi-k3`(UI 名 "K3 · Max" ≠ API code)
3439
+ // - temperature 固定 1.0(已并入 TEMP_1_MODELS)
3440
+ // - vision 走 base64 / ms://file-id(不收公网 URL)——本版未接图片输入路径,仅文本/工具
3441
+ // 默认仍保持 kimi-k2.6(K3 输出 $15/MTok 偏贵,按需 /model kimi-k3)。
3442
+ {
3443
+ id: "kimi-k3",
3444
+ displayName: "Kimi K3",
3445
+ contextWindow: 1048576,
3446
+ supportsStreaming: true
3447
+ },
3436
3448
  // Kimi K2.6 / K2.5 系列(最新一代,推荐)
3437
3449
  {
3438
3450
  id: "kimi-k2.6",
@@ -4996,7 +5008,7 @@ async function execInPool(sessionKey, command, timeout, cwd, abortSignal) {
4996
5008
  const markerStart = `AICLI_MARKER_START:${id}`;
4997
5009
  const markerEnd = `AICLI_MARKER_END:${id}`;
4998
5010
  const wrappedCmd = IS_WINDOWS2 ? `${WIN_UTF8_PREAMBLE} echo "${markerStart}"; ${command}; echo "${markerEnd}:0"` : `echo "${markerStart}"; ${command}; echo "${markerEnd}:$?"`;
4999
- return new Promise((resolve13) => {
5011
+ return new Promise((resolve11) => {
5000
5012
  let stdout = "";
5001
5013
  let stderr = "";
5002
5014
  let timedOut = false;
@@ -5008,11 +5020,11 @@ async function execInPool(sessionKey, command, timeout, cwd, abortSignal) {
5008
5020
  stdout += IS_WINDOWS2 ? decodeWindowsBuffer(chunk) : chunk.toString("utf-8");
5009
5021
  if (!resolved && stdout.includes(markerEndPattern)) {
5010
5022
  const endLine = stdout.split("\n").find((l) => l.includes(markerEndPattern));
5011
- const exitCode = endLine ? parseEndMarker(endLine, markerEndPattern) : null;
5023
+ const exitCode = endLine ? parseEndMarker(endLine) : null;
5012
5024
  stdout = stripMarkerOutput(stdout, markerStartPattern, markerEndPattern);
5013
5025
  resolved = true;
5014
5026
  cleanup();
5015
- resolve13({ stdout, stderr, exitCode, timedOut, aborted });
5027
+ resolve11({ stdout, stderr, exitCode, timedOut, aborted });
5016
5028
  }
5017
5029
  };
5018
5030
  const onErr = (chunk) => {
@@ -5027,7 +5039,7 @@ async function execInPool(sessionKey, command, timeout, cwd, abortSignal) {
5027
5039
  resolved = true;
5028
5040
  stdout = stripMarkerOutput(stdout, markerStartPattern, markerEndPattern);
5029
5041
  cleanup();
5030
- resolve13({ stdout, stderr, exitCode: null, timedOut, aborted });
5042
+ resolve11({ stdout, stderr, exitCode: null, timedOut, aborted });
5031
5043
  killProcessTree(proc);
5032
5044
  pool.delete(sessionKey);
5033
5045
  }, timeout);
@@ -5037,7 +5049,7 @@ async function execInPool(sessionKey, command, timeout, cwd, abortSignal) {
5037
5049
  resolved = true;
5038
5050
  cleanup();
5039
5051
  stdout = stripMarkerOutput(stdout, markerStartPattern, markerEndPattern);
5040
- resolve13({ stdout, stderr, exitCode: null, timedOut, aborted });
5052
+ resolve11({ stdout, stderr, exitCode: null, timedOut, aborted });
5041
5053
  killProcessTree(proc);
5042
5054
  pool.delete(sessionKey);
5043
5055
  };
@@ -5052,7 +5064,7 @@ async function execInPool(sessionKey, command, timeout, cwd, abortSignal) {
5052
5064
  stderr += `
5053
5065
  [pool error] ${err.message}`;
5054
5066
  cleanup();
5055
- resolve13({ stdout, stderr, exitCode: null, timedOut, aborted });
5067
+ resolve11({ stdout, stderr, exitCode: null, timedOut, aborted });
5056
5068
  pool.delete(sessionKey);
5057
5069
  };
5058
5070
  proc.on("error", onError);
@@ -5065,7 +5077,7 @@ async function execInPool(sessionKey, command, timeout, cwd, abortSignal) {
5065
5077
  }
5066
5078
  try {
5067
5079
  proc.stdin?.write(wrappedCmd + "\n");
5068
- } catch (err) {
5080
+ } catch {
5069
5081
  if (!resolved) {
5070
5082
  cleanup();
5071
5083
  pool.delete(sessionKey);
@@ -5073,7 +5085,7 @@ async function execInPool(sessionKey, command, timeout, cwd, abortSignal) {
5073
5085
  }
5074
5086
  });
5075
5087
  }
5076
- function parseEndMarker(line, markerEndPattern) {
5088
+ function parseEndMarker(line) {
5077
5089
  const idx = line.lastIndexOf(":");
5078
5090
  if (idx < 0) return null;
5079
5091
  const code = line.slice(idx + 1).trim();
@@ -7210,7 +7222,7 @@ var ToolExecutor = class {
7210
7222
  };
7211
7223
  }
7212
7224
  if (permission.action === "auto-approve" && networkPermission?.action !== "confirm") {
7213
- this.printToolCall(call);
7225
+ if (!toolCallAlreadyPrinted) this.printToolCall(call);
7214
7226
  try {
7215
7227
  const rawContent = await runTool(tool, call.arguments, call.name);
7216
7228
  const content = truncateOutput(rawContent, call.name);
@@ -7441,7 +7453,7 @@ var ToolExecutor = class {
7441
7453
  rl.resume();
7442
7454
  process.stdout.write(prompt);
7443
7455
  this.confirming = true;
7444
- return new Promise((resolve13) => {
7456
+ return new Promise((resolve11) => {
7445
7457
  let completed = false;
7446
7458
  const cleanup = (result) => {
7447
7459
  if (completed) return;
@@ -7451,7 +7463,7 @@ var ToolExecutor = class {
7451
7463
  rl.pause();
7452
7464
  rlAny.output = savedOutput;
7453
7465
  this.confirming = false;
7454
- resolve13(result);
7466
+ resolve11(result);
7455
7467
  };
7456
7468
  const onLine = (line) => {
7457
7469
  const trimmed = line.trim();
@@ -7625,7 +7637,7 @@ var ToolExecutor = class {
7625
7637
  rl.resume();
7626
7638
  process.stdout.write(color("Proceed? [y/N] (type y + Enter to confirm) "));
7627
7639
  this.confirming = true;
7628
- return new Promise((resolve13) => {
7640
+ return new Promise((resolve11) => {
7629
7641
  let completed = false;
7630
7642
  const cleanup = (answer) => {
7631
7643
  if (completed) return;
@@ -7635,7 +7647,7 @@ var ToolExecutor = class {
7635
7647
  rl.pause();
7636
7648
  rlAny.output = savedOutput;
7637
7649
  this.confirming = false;
7638
- resolve13(answer === "y");
7650
+ resolve11(answer === "y");
7639
7651
  };
7640
7652
  const onLine = (line) => {
7641
7653
  const trimmed = line.trim();
@@ -7816,7 +7828,7 @@ Do NOT split a long document into many write_file(append=true) calls. That patte
7816
7828
  const mode = appendMode ? "appended" : "written";
7817
7829
  void (async () => {
7818
7830
  try {
7819
- const { updateFile } = await import("./indexer-4WWS3VIL.js");
7831
+ const { updateFile } = await import("./indexer-M2LJGTY2.js");
7820
7832
  await updateFile(process.cwd(), filePath);
7821
7833
  } catch {
7822
7834
  }
@@ -8884,7 +8896,7 @@ var runInteractiveTool = {
8884
8896
  PYTHONDONTWRITEBYTECODE: "1"
8885
8897
  };
8886
8898
  const prefixWarnings = [argsTypeWarning, stdinTypeWarning].filter(Boolean).join("");
8887
- return new Promise((resolve13) => {
8899
+ return new Promise((resolve11) => {
8888
8900
  const child = spawn4(executable, cmdArgs.map(String), {
8889
8901
  cwd: process.cwd(),
8890
8902
  env,
@@ -8917,22 +8929,22 @@ var runInteractiveTool = {
8917
8929
  setTimeout(writeNextLine, 400);
8918
8930
  const timer = setTimeout(() => {
8919
8931
  child.kill();
8920
- resolve13(`${prefixWarnings}[Timeout after ${timeout}ms]
8932
+ resolve11(`${prefixWarnings}[Timeout after ${timeout}ms]
8921
8933
  ${buildOutput(stdout, stderr)}`);
8922
8934
  }, timeout);
8923
8935
  child.on("close", (code) => {
8924
8936
  clearTimeout(timer);
8925
8937
  const output = buildOutput(stdout, stderr);
8926
8938
  if (code !== 0 && code !== null) {
8927
- resolve13(`${prefixWarnings}Exit code ${code}:
8939
+ resolve11(`${prefixWarnings}Exit code ${code}:
8928
8940
  ${output}`);
8929
8941
  } else {
8930
- resolve13(`${prefixWarnings}${output || "(no output)"}`);
8942
+ resolve11(`${prefixWarnings}${output || "(no output)"}`);
8931
8943
  }
8932
8944
  });
8933
8945
  child.on("error", (err) => {
8934
8946
  clearTimeout(timer);
8935
- resolve13(
8947
+ resolve11(
8936
8948
  `${prefixWarnings}Failed to start process "${executable}": ${err.message}
8937
8949
  Hint: On Windows, use the full path to the executable, e.g.:
8938
8950
  C:\\Users\\Jinzd\\anaconda3\\envs\\python312\\python.exe`
@@ -9235,7 +9247,7 @@ var webFetchTool = {
9235
9247
  } else {
9236
9248
  const title = extractTitle(rawHtml);
9237
9249
  const desc = extractDescription(rawHtml);
9238
- let body = htmlToText(rawHtml);
9250
+ const body = htmlToText(rawHtml);
9239
9251
  const header = [
9240
9252
  title ? `# ${title}` : "",
9241
9253
  desc ? `> ${desc}` : "",
@@ -9754,7 +9766,7 @@ function promptUser(rl, question) {
9754
9766
  console.log();
9755
9767
  console.log(chalk4.cyan("\u2753 ") + chalk4.bold(question));
9756
9768
  process.stdout.write(chalk4.cyan("> "));
9757
- return new Promise((resolve13) => {
9769
+ return new Promise((resolve11) => {
9758
9770
  let completed = false;
9759
9771
  const cleanup = (answer) => {
9760
9772
  if (completed) return;
@@ -9764,7 +9776,7 @@ function promptUser(rl, question) {
9764
9776
  rl.pause();
9765
9777
  rlAny.output = savedOutput;
9766
9778
  askUserContext.prompting = false;
9767
- resolve13(answer);
9779
+ resolve11(answer);
9768
9780
  };
9769
9781
  const onLine = (line) => {
9770
9782
  cleanup(line);
@@ -12320,7 +12332,7 @@ var McpClient = class {
12320
12332
  // 内部方法:JSON-RPC 通信
12321
12333
  // ══════════════════════════════════════════════════════════════════
12322
12334
  sendRequest(method, params) {
12323
- return new Promise((resolve13, reject) => {
12335
+ return new Promise((resolve11, reject) => {
12324
12336
  if (!this.process?.stdin?.writable) {
12325
12337
  return reject(new Error(`MCP server [${this.serverId}] stdin not writable`));
12326
12338
  }
@@ -12332,19 +12344,18 @@ var McpClient = class {
12332
12344
  method,
12333
12345
  ...params !== void 0 ? { params } : {}
12334
12346
  };
12335
- let timer;
12336
12347
  const cleanup = () => {
12337
12348
  this.pendingRequests.delete(id);
12338
12349
  clearTimeout(timer);
12339
12350
  };
12340
- timer = setTimeout(() => {
12351
+ const timer = setTimeout(() => {
12341
12352
  cleanup();
12342
12353
  reject(new Error(`MCP request [${method}] timed out (internal)`));
12343
12354
  }, MCP_CALL_TIMEOUT * 2);
12344
12355
  this.pendingRequests.set(id, {
12345
12356
  resolve: (result) => {
12346
12357
  cleanup();
12347
- resolve13(result);
12358
+ resolve11(result);
12348
12359
  },
12349
12360
  reject: (error) => {
12350
12361
  cleanup();
@@ -12421,13 +12432,13 @@ var McpClient = class {
12421
12432
  }
12422
12433
  /** Promise 超时包装 */
12423
12434
  withTimeout(promise, ms, label) {
12424
- return new Promise((resolve13, reject) => {
12435
+ return new Promise((resolve11, reject) => {
12425
12436
  const timer = setTimeout(() => {
12426
12437
  reject(new Error(`MCP [${this.serverId}] ${label} timed out after ${ms}ms`));
12427
12438
  }, ms);
12428
12439
  promise.then((val) => {
12429
12440
  clearTimeout(timer);
12430
- resolve13(val);
12441
+ resolve11(val);
12431
12442
  }).catch((err) => {
12432
12443
  clearTimeout(timer);
12433
12444
  reject(err);
@@ -12931,33 +12942,33 @@ var ToolExecutorWeb = class _ToolExecutorWeb {
12931
12942
  }
12932
12943
  /** Resolve a pending confirm from client response */
12933
12944
  resolveConfirm(requestId, approved) {
12934
- const resolve13 = this.pendingConfirms.get(requestId);
12935
- if (resolve13) {
12945
+ const resolve11 = this.pendingConfirms.get(requestId);
12946
+ if (resolve11) {
12936
12947
  this.clearPendingTimer(requestId);
12937
12948
  this.pendingConfirms.delete(requestId);
12938
12949
  this.confirming = false;
12939
- resolve13(approved);
12950
+ resolve11(approved);
12940
12951
  }
12941
12952
  }
12942
12953
  /** Resolve a pending batch confirm from client response */
12943
12954
  resolveBatchConfirm(requestId, decision) {
12944
- const resolve13 = this.pendingBatchConfirms.get(requestId);
12945
- if (resolve13) {
12955
+ const resolve11 = this.pendingBatchConfirms.get(requestId);
12956
+ if (resolve11) {
12946
12957
  this.clearPendingTimer(requestId);
12947
12958
  this.pendingBatchConfirms.delete(requestId);
12948
12959
  this.confirming = false;
12949
12960
  if (decision === "all" || decision === "none") {
12950
- resolve13(decision);
12961
+ resolve11(decision);
12951
12962
  } else {
12952
- resolve13(new Set(decision));
12963
+ resolve11(new Set(decision));
12953
12964
  }
12954
12965
  }
12955
12966
  }
12956
12967
  /** Cancel all pending confirms (e.g., on disconnect) */
12957
12968
  cancelAll() {
12958
- for (const resolve13 of this.pendingConfirms.values()) resolve13(false);
12969
+ for (const resolve11 of this.pendingConfirms.values()) resolve11(false);
12959
12970
  this.pendingConfirms.clear();
12960
- for (const resolve13 of this.pendingBatchConfirms.values()) resolve13("none");
12971
+ for (const resolve11 of this.pendingBatchConfirms.values()) resolve11("none");
12961
12972
  this.pendingBatchConfirms.clear();
12962
12973
  this.confirming = false;
12963
12974
  }
@@ -13033,8 +13044,8 @@ var ToolExecutorWeb = class _ToolExecutorWeb {
13033
13044
  diff: this.getDiffPreview(call)
13034
13045
  };
13035
13046
  this.send(msg);
13036
- return new Promise((resolve13) => {
13037
- this.pendingConfirms.set(requestId, resolve13);
13047
+ return new Promise((resolve11) => {
13048
+ this.pendingConfirms.set(requestId, resolve11);
13038
13049
  this.pendingTimers.set(requestId, setTimeout(() => {
13039
13050
  if (this.pendingConfirms.has(requestId)) {
13040
13051
  this.resolveConfirm(requestId, false);
@@ -13058,8 +13069,8 @@ var ToolExecutorWeb = class _ToolExecutorWeb {
13058
13069
  files
13059
13070
  };
13060
13071
  this.send(msg);
13061
- return new Promise((resolve13) => {
13062
- this.pendingBatchConfirms.set(requestId, resolve13);
13072
+ return new Promise((resolve11) => {
13073
+ this.pendingBatchConfirms.set(requestId, resolve11);
13063
13074
  this.pendingTimers.set(requestId, setTimeout(() => {
13064
13075
  if (this.pendingBatchConfirms.has(requestId)) {
13065
13076
  this.resolveBatchConfirm(requestId, "none");
@@ -13169,7 +13180,7 @@ var ToolExecutorWeb = class _ToolExecutorWeb {
13169
13180
  return { callId: call.id, content: rejectionMsg, isError: true };
13170
13181
  }
13171
13182
  }
13172
- this.sendToolCallStart(call);
13183
+ if (!toolCallStarted) this.sendToolCallStart(call);
13173
13184
  if (this.sessionAutoMode && networkPermission?.action !== "confirm") {
13174
13185
  const classification = defaultActionClassifier.classify(call, dangerLevel, {
13175
13186
  workspaceRoot: this.workspaceRoot,
@@ -13427,6 +13438,9 @@ var PRICING_TABLE = {
13427
13438
  "moonshot-v1-128k": { input: 0.83, output: 0.83 },
13428
13439
  "kimi-k2": { input: 0.6, output: 2.5 },
13429
13440
  "kimi-latest": { input: 0.6, output: 2.5 },
13441
+ // Kimi K3(2026-07 旗舰,1M 上下文)官方定价 platform.kimi.ai/pricing/chat-k3:
13442
+ // 输入 cache-miss $3.00 / cache-hit $0.30,输出 $15.00(/MTok)。
13443
+ "kimi-k3": { input: 3, output: 15, cacheRead: 0.3 },
13430
13444
  // ── Zhipu GLM ─────────────────────────────────────────────────
13431
13445
  "glm-4-plus": { input: 0.7, output: 0.7 },
13432
13446
  "glm-4": { input: 0.14, output: 0.14 },
@@ -13548,7 +13562,7 @@ function autoTrimSessionIfNeeded(session, sizeLimit = SESSION_SIZE_LIMIT) {
13548
13562
  const originalSize = JSON.stringify(session.toJSON()).length;
13549
13563
  if (originalSize <= sizeLimit) return false;
13550
13564
  const snapshotLen = session.messages.length;
13551
- let working = cloneMessages(session.messages.slice(0, snapshotLen));
13565
+ const working = cloneMessages(session.messages.slice(0, snapshotLen));
13552
13566
  let committedSize = originalSize;
13553
13567
  let anyTrim = false;
13554
13568
  let keepRecent = 10;
@@ -15113,7 +15127,7 @@ Cache: write=${cacheCreate} read=${cacheRead}` : "";
15113
15127
  Cost: ${formatCost(cost)}` : "";
15114
15128
  let memoryLine = "";
15115
15129
  try {
15116
- const { countPendingMemories } = await import("./persistent-memory-EKZ2JF7M.js");
15130
+ const { countPendingMemories } = await import("./persistent-memory-JBWBMA56.js");
15117
15131
  const pending = countPendingMemories(ctx.config.getConfigDir());
15118
15132
  if (pending > 0) memoryLine = `
15119
15133
  Memory: \u26A0 ${pending} pending approval \u2014 see the Memory panel or /memory`;
@@ -15420,7 +15434,7 @@ async function handleBranch(args, ctx) {
15420
15434
  return;
15421
15435
  }
15422
15436
  const sub = args[0]?.toLowerCase();
15423
- const resolve13 = (ref) => {
15437
+ const resolve11 = (ref) => {
15424
15438
  const r = session.resolveBranchRef(ref);
15425
15439
  if (r.ok) return r.id;
15426
15440
  if (r.reason === "ambiguous") {
@@ -15474,7 +15488,7 @@ async function handleBranch(args, ctx) {
15474
15488
  ctx.send({ type: "error", message: "Usage: /branch switch <id|title>" });
15475
15489
  return;
15476
15490
  }
15477
- const id = resolve13(ref);
15491
+ const id = resolve11(ref);
15478
15492
  if (!id) return;
15479
15493
  const ok = session.switchBranch(id);
15480
15494
  if (ok) {
@@ -15494,7 +15508,7 @@ async function handleBranch(args, ctx) {
15494
15508
  ctx.send({ type: "error", message: "Usage: /branch delete <id|title>" });
15495
15509
  return;
15496
15510
  }
15497
- const id = resolve13(ref);
15511
+ const id = resolve11(ref);
15498
15512
  if (!id) return;
15499
15513
  const ok = session.deleteBranch(id);
15500
15514
  if (ok) {
@@ -15513,7 +15527,7 @@ async function handleBranch(args, ctx) {
15513
15527
  ctx.send({ type: "error", message: "Usage: /branch rename <id|title> <new title>" });
15514
15528
  return;
15515
15529
  }
15516
- const id = resolve13(ref);
15530
+ const id = resolve11(ref);
15517
15531
  if (!id) return;
15518
15532
  const ok = session.renameBranch(id, title);
15519
15533
  if (ok) {
@@ -15531,7 +15545,7 @@ async function handleBranch(args, ctx) {
15531
15545
  ctx.send({ type: "error", message: "Usage: /branch diff <id|title>" });
15532
15546
  return;
15533
15547
  }
15534
- const id = resolve13(ref);
15548
+ const id = resolve11(ref);
15535
15549
  if (!id) return;
15536
15550
  const d = session.diffBranches(id);
15537
15551
  if (!d) {
@@ -15573,7 +15587,7 @@ async function handleBranch(args, ctx) {
15573
15587
  ctx.send({ type: "error", message: "Usage: /branch cherry-pick <source-id|title> <msg-index>" });
15574
15588
  return;
15575
15589
  }
15576
- const id = resolve13(ref);
15590
+ const id = resolve11(ref);
15577
15591
  if (!id) return;
15578
15592
  const idx = parseInt(idxStr, 10);
15579
15593
  if (Number.isNaN(idx)) {
@@ -15922,7 +15936,7 @@ async function handleSecurityReview(args, ctx) {
15922
15936
  async function handleTest(args, ctx) {
15923
15937
  ctx.send({ type: "info", message: "\u{1F9EA} Running tests..." });
15924
15938
  try {
15925
- const { executeTests } = await import("./run-tests-ZKHXKCQB.js");
15939
+ const { executeTests } = await import("./run-tests-NNML2XVV.js");
15926
15940
  const argStr = args.join(" ").trim();
15927
15941
  let testArgs = {};
15928
15942
  if (argStr) {
@@ -16079,7 +16093,7 @@ async function handleIndex(args, ctx) {
16079
16093
  const sub = (args[0] ?? "status").toLowerCase();
16080
16094
  const root = process.cwd();
16081
16095
  const { loadIndex: loadIndex2, clearIndex } = await import("./store-VO37H6LS.js");
16082
- const { indexProject: indexProject2 } = await import("./indexer-4WWS3VIL.js");
16096
+ const { indexProject: indexProject2 } = await import("./indexer-M2LJGTY2.js");
16083
16097
  const { loadVectorStore, clearVectorStore } = await import("./vector-store-JBAE6PS4.js");
16084
16098
  if (sub === "status") {
16085
16099
  const idx = loadIndex2(root);
@@ -16186,7 +16200,7 @@ async function handleMemory(args, ctx) {
16186
16200
  ctx.handleMemoryManage(sub, args[1], sub === "expire" ? args[2] : void 0);
16187
16201
  } else if (sub === "export") {
16188
16202
  if (args[1] === "md") {
16189
- const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-EKZ2JF7M.js");
16203
+ const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-JBWBMA56.js");
16190
16204
  ctx.send({
16191
16205
  type: "export_data",
16192
16206
  format: "md",
@@ -16552,6 +16566,15 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
16552
16566
  }
16553
16567
 
16554
16568
  // src/web/session-handler.ts
16569
+ var CLI_ONLY_WEB_COMMANDS = /* @__PURE__ */ new Set([
16570
+ "copy",
16571
+ "paste",
16572
+ "exit",
16573
+ "quit",
16574
+ "snapshot",
16575
+ "hooks",
16576
+ "hook"
16577
+ ]);
16555
16578
  var webCommandHandlers = {
16556
16579
  provider: handleProvider,
16557
16580
  model: handleModel,
@@ -16789,10 +16812,10 @@ var SessionHandler = class {
16789
16812
  return;
16790
16813
  }
16791
16814
  case "ask_user_response": {
16792
- const resolve13 = this.pendingAskUser.get(msg.requestId);
16793
- if (resolve13) {
16815
+ const resolve11 = this.pendingAskUser.get(msg.requestId);
16816
+ if (resolve11) {
16794
16817
  this.pendingAskUser.delete(msg.requestId);
16795
- resolve13(msg.answer);
16818
+ resolve11(msg.answer);
16796
16819
  }
16797
16820
  return;
16798
16821
  }
@@ -16805,10 +16828,10 @@ var SessionHandler = class {
16805
16828
  case "memory_manage":
16806
16829
  return this.handleMemoryManage(msg.action, msg.id, msg.expiresAt);
16807
16830
  case "auto_pause_response": {
16808
- const resolve13 = this.pendingAutoPause.get(msg.requestId);
16809
- if (resolve13) {
16831
+ const resolve11 = this.pendingAutoPause.get(msg.requestId);
16832
+ if (resolve11) {
16810
16833
  this.pendingAutoPause.delete(msg.requestId);
16811
- resolve13({ action: msg.action, message: msg.message });
16834
+ resolve11({ action: msg.action, message: msg.message });
16812
16835
  }
16813
16836
  return;
16814
16837
  }
@@ -16823,10 +16846,10 @@ var SessionHandler = class {
16823
16846
  this.hubOrchestrator?.abort();
16824
16847
  return;
16825
16848
  case "hub_steer": {
16826
- const resolve13 = this.pendingHubReview.get(msg.requestId);
16827
- if (resolve13) {
16849
+ const resolve11 = this.pendingHubReview.get(msg.requestId);
16850
+ if (resolve11) {
16828
16851
  this.pendingHubReview.delete(msg.requestId);
16829
- resolve13({ action: msg.action, message: msg.message });
16852
+ resolve11({ action: msg.action, message: msg.message });
16830
16853
  }
16831
16854
  return;
16832
16855
  }
@@ -16839,9 +16862,9 @@ var SessionHandler = class {
16839
16862
  runLifecycleHooks(mergePluginHooks(this.config.get("hooks") ?? void 0, this.config.getConfigDir()), "Stop", { sessionId: this.sessions.current?.id }, { configDir: this.config.getConfigDir() });
16840
16863
  this.toolExecutor.cancelAll();
16841
16864
  if (this.abortController) this.abortController.abort();
16842
- for (const resolve13 of this.pendingAskUser.values()) resolve13(null);
16865
+ for (const resolve11 of this.pendingAskUser.values()) resolve11(null);
16843
16866
  this.pendingAskUser.clear();
16844
- for (const resolve13 of this.pendingAutoPause.values()) resolve13({ action: "stop" });
16867
+ for (const resolve11 of this.pendingAutoPause.values()) resolve11({ action: "stop" });
16845
16868
  this.pendingAutoPause.clear();
16846
16869
  this.saveIfNeeded();
16847
16870
  if (this._bashSessionKey) clearBashSession(this._bashSessionKey);
@@ -16976,9 +16999,9 @@ var SessionHandler = class {
16976
16999
  this.hubOrchestrator = orchestrator;
16977
17000
  orchestrator.onEvent = (event) => this.send({ type: "hub_event", event });
16978
17001
  if (config.humanSteer) {
16979
- orchestrator.onRoundReview = ({ round, maxRounds }) => new Promise((resolve13) => {
17002
+ orchestrator.onRoundReview = ({ round, maxRounds }) => new Promise((resolve11) => {
16980
17003
  const requestId = `hubrev_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
16981
- this.pendingHubReview.set(requestId, resolve13);
17004
+ this.pendingHubReview.set(requestId, resolve11);
16982
17005
  this.send({ type: "hub_review", requestId, round, maxRounds });
16983
17006
  });
16984
17007
  }
@@ -17336,8 +17359,8 @@ Try: /compact to reduce context, /clear to reset, or switch to a larger-context
17336
17359
  onMcpToolUsed: (name) => this.usedMcpToolNames.add(name),
17337
17360
  requestAutoPause: async ({ effectiveRound, maxToolRounds: totalRounds, toolSummary }) => {
17338
17361
  const requestId = `pause_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
17339
- const pauseResp = await new Promise((resolve13) => {
17340
- this.pendingAutoPause.set(requestId, resolve13);
17362
+ const pauseResp = await new Promise((resolve11) => {
17363
+ this.pendingAutoPause.set(requestId, resolve11);
17341
17364
  this.send({
17342
17365
  type: "auto_pause_request",
17343
17366
  requestId,
@@ -17516,8 +17539,8 @@ ${summaryContent}`,
17516
17539
  }
17517
17540
  if (chunk.done) break;
17518
17541
  }
17519
- await new Promise((resolve13, reject) => {
17520
- fileStream.end((err) => err ? reject(err) : resolve13());
17542
+ await new Promise((resolve11, reject) => {
17543
+ fileStream.end((err) => err ? reject(err) : resolve11());
17521
17544
  });
17522
17545
  const verdict = evaluateTeeContent(fullContent, saveToFile, priorContent);
17523
17546
  if (verdict.kind === "reject") {
@@ -17543,7 +17566,7 @@ ${summaryContent}`,
17543
17566
  } catch (err) {
17544
17567
  if (fileStream) {
17545
17568
  try {
17546
- await new Promise((resolve13) => fileStream.end(() => resolve13()));
17569
+ await new Promise((resolve11) => fileStream.end(() => resolve11()));
17547
17570
  } catch {
17548
17571
  }
17549
17572
  }
@@ -17591,6 +17614,13 @@ ${summaryContent}`,
17591
17614
  }
17592
17615
  // ── Commands ─────────────────────────────────────────────────────
17593
17616
  async handleCommand(name, args) {
17617
+ if (CLI_ONLY_WEB_COMMANDS.has(name)) {
17618
+ this.send({
17619
+ type: "error",
17620
+ message: `/${name} is only available in the terminal REPL. Run \`aicli\` in a terminal and use /${name} there.`
17621
+ });
17622
+ return;
17623
+ }
17594
17624
  const handler = webCommandHandlers[name];
17595
17625
  if (handler) {
17596
17626
  await handler(args, this);
@@ -17866,7 +17896,7 @@ Backup saved: ${result.backupPath}` : "";
17866
17896
  return;
17867
17897
  }
17868
17898
  try {
17869
- const { searchChatMemory: searchChatMemory2, loadChatIndex: loadChatIndex2 } = await import("./chat-index-ML5FF5L6.js");
17899
+ const { searchChatMemory: searchChatMemory2, loadChatIndex: loadChatIndex2 } = await import("./chat-index-Q6BKWWAM.js");
17870
17900
  const loaded = loadChatIndex2();
17871
17901
  if (!loaded || loaded.idx.chunks.length === 0) {
17872
17902
  this.send({ type: "memory_hits", query: q, hits: [], indexMissing: true });
@@ -17902,7 +17932,7 @@ Backup saved: ${result.backupPath}` : "";
17902
17932
  }
17903
17933
  async handleMemoryStatus() {
17904
17934
  try {
17905
- const { getChatIndexStatus } = await import("./chat-index-ML5FF5L6.js");
17935
+ const { getChatIndexStatus } = await import("./chat-index-Q6BKWWAM.js");
17906
17936
  const s = getChatIndexStatus();
17907
17937
  this.send({
17908
17938
  type: "memory_status",
@@ -17927,7 +17957,7 @@ Backup saved: ${result.backupPath}` : "";
17927
17957
  type: "info",
17928
17958
  message: full ? "\u{1F9E0} Rebuilding chat memory index (this may take a while on first run \u2014 ~117 MB embedder)." : "\u{1F9E0} Refreshing chat memory index (incremental)\u2026"
17929
17959
  });
17930
- const { buildChatIndex } = await import("./chat-index-ML5FF5L6.js");
17960
+ const { buildChatIndex } = await import("./chat-index-Q6BKWWAM.js");
17931
17961
  const stats = await buildChatIndex({
17932
17962
  full,
17933
17963
  onProgress: (p) => {
@@ -18083,8 +18113,8 @@ async function setupProxy(configProxy) {
18083
18113
  }
18084
18114
 
18085
18115
  // src/web/auth.ts
18086
- import { existsSync as existsSync30, readFileSync as readFileSync23, writeFileSync as writeFileSync5, mkdirSync as mkdirSync15, readdirSync as readdirSync15, copyFileSync } from "fs";
18087
- import { isAbsolute as isAbsolute3, join as join26, relative as relative5 } from "path";
18116
+ import { existsSync as existsSync29, readFileSync as readFileSync22, writeFileSync as writeFileSync4, mkdirSync as mkdirSync15, readdirSync as readdirSync14, copyFileSync } from "fs";
18117
+ import { isAbsolute as isAbsolute3, join as join24, relative as relative5 } from "path";
18088
18118
  import { createHmac, randomBytes, timingSafeEqual, pbkdf2Sync } from "crypto";
18089
18119
  var USERS_FILE = "users.json";
18090
18120
  var TOKEN_EXPIRY_HOURS = 24;
@@ -18099,7 +18129,7 @@ var AuthManager = class {
18099
18129
  db;
18100
18130
  constructor(baseDir) {
18101
18131
  this.baseDir = baseDir;
18102
- this.usersFile = join26(baseDir, USERS_FILE);
18132
+ this.usersFile = join24(baseDir, USERS_FILE);
18103
18133
  this.db = this.loadOrCreate();
18104
18134
  }
18105
18135
  // ── Public API ─────────────────────────────────────────────────
@@ -18128,9 +18158,9 @@ var AuthManager = class {
18128
18158
  }
18129
18159
  const salt = randomBytes(16).toString("hex");
18130
18160
  const passwordHash = this.hashPassword(password, salt);
18131
- const dataDir = join26(USERS_DIR, username);
18132
- const fullDataDir = join26(this.baseDir, dataDir);
18133
- mkdirSync15(join26(fullDataDir, "history"), { recursive: true });
18161
+ const dataDir = join24(USERS_DIR, username);
18162
+ const fullDataDir = join24(this.baseDir, dataDir);
18163
+ mkdirSync15(join24(fullDataDir, "history"), { recursive: true });
18134
18164
  const user = {
18135
18165
  username,
18136
18166
  passwordHash,
@@ -18245,7 +18275,7 @@ var AuthManager = class {
18245
18275
  getUserDataDir(username) {
18246
18276
  const user = this.db.users.find((u) => u.username === username);
18247
18277
  if (!user) throw new Error(`User not found: ${username}`);
18248
- return join26(this.baseDir, user.dataDir);
18278
+ return join24(this.baseDir, user.dataDir);
18249
18279
  }
18250
18280
  /** List all usernames */
18251
18281
  listUsers() {
@@ -18281,30 +18311,30 @@ var AuthManager = class {
18281
18311
  const err = this.register(username, password);
18282
18312
  if (err) return err;
18283
18313
  const userDir = this.getUserDataDir(username);
18284
- const globalConfig = join26(this.baseDir, "config.json");
18285
- if (existsSync30(globalConfig)) {
18314
+ const globalConfig = join24(this.baseDir, "config.json");
18315
+ if (existsSync29(globalConfig)) {
18286
18316
  try {
18287
- const content = readFileSync23(globalConfig, "utf-8");
18288
- writeFileSync5(join26(userDir, "config.json"), content, "utf-8");
18317
+ const content = readFileSync22(globalConfig, "utf-8");
18318
+ writeFileSync4(join24(userDir, "config.json"), content, "utf-8");
18289
18319
  } catch {
18290
18320
  }
18291
18321
  }
18292
- const globalMemory = join26(this.baseDir, "memory.md");
18293
- if (existsSync30(globalMemory)) {
18322
+ const globalMemory = join24(this.baseDir, "memory.md");
18323
+ if (existsSync29(globalMemory)) {
18294
18324
  try {
18295
- const content = readFileSync23(globalMemory, "utf-8");
18296
- writeFileSync5(join26(userDir, "memory.md"), content, "utf-8");
18325
+ const content = readFileSync22(globalMemory, "utf-8");
18326
+ writeFileSync4(join24(userDir, "memory.md"), content, "utf-8");
18297
18327
  } catch {
18298
18328
  }
18299
18329
  }
18300
- const globalHistory = join26(this.baseDir, "history");
18301
- if (existsSync30(globalHistory)) {
18330
+ const globalHistory = join24(this.baseDir, "history");
18331
+ if (existsSync29(globalHistory)) {
18302
18332
  try {
18303
- const files = readdirSync15(globalHistory).filter((f) => f.endsWith(".json"));
18304
- const userHistory = join26(userDir, "history");
18333
+ const files = readdirSync14(globalHistory).filter((f) => f.endsWith(".json"));
18334
+ const userHistory = join24(userDir, "history");
18305
18335
  for (const f of files) {
18306
18336
  try {
18307
- copyFileSync(join26(globalHistory, f), join26(userHistory, f));
18337
+ copyFileSync(join24(globalHistory, f), join24(userHistory, f));
18308
18338
  } catch {
18309
18339
  }
18310
18340
  }
@@ -18315,9 +18345,9 @@ var AuthManager = class {
18315
18345
  }
18316
18346
  // ── Private methods ────────────────────────────────────────────
18317
18347
  loadOrCreate() {
18318
- if (existsSync30(this.usersFile)) {
18348
+ if (existsSync29(this.usersFile)) {
18319
18349
  try {
18320
- const parsed = JSON.parse(readFileSync23(this.usersFile, "utf-8"));
18350
+ const parsed = JSON.parse(readFileSync22(this.usersFile, "utf-8"));
18321
18351
  if (!this.isValidUsersDB(parsed)) {
18322
18352
  throw new Error("database structure is invalid");
18323
18353
  }
@@ -18351,7 +18381,7 @@ var AuthManager = class {
18351
18381
  if (typeof record.username !== "string" || !/^[a-z0-9_-]{2,32}$/.test(record.username) || usernames.has(record.username) || typeof record.passwordHash !== "string" || record.passwordHash.length === 0 || typeof record.salt !== "string" || record.salt.length === 0 || typeof record.createdAt !== "string" || typeof record.dataDir !== "string" || record.dataDir.length === 0 || isAbsolute3(record.dataDir)) {
18352
18382
  return false;
18353
18383
  }
18354
- const dataDirFromBase = relative5(this.baseDir, join26(this.baseDir, record.dataDir));
18384
+ const dataDirFromBase = relative5(this.baseDir, join24(this.baseDir, record.dataDir));
18355
18385
  if (dataDirFromBase.startsWith("..") || isAbsolute3(dataDirFromBase)) return false;
18356
18386
  if (record.hashVersion !== void 0 && record.hashVersion !== 1 && record.hashVersion !== 2) return false;
18357
18387
  if (record.tokensRevokedBefore !== void 0 && !Number.isFinite(record.tokensRevokedBefore)) return false;
@@ -18399,7 +18429,7 @@ function getModuleDir() {
18399
18429
  }
18400
18430
  } catch {
18401
18431
  }
18402
- return resolve12(".");
18432
+ return resolve10(".");
18403
18433
  }
18404
18434
  async function startWebServer(options = {}) {
18405
18435
  const port = options.port ?? 3e3;
@@ -18467,8 +18497,8 @@ async function startWebServer(options = {}) {
18467
18497
  }
18468
18498
  }
18469
18499
  let skillManager = null;
18470
- const skillsDir = join27(config.getConfigDir(), SKILLS_DIR_NAME);
18471
- if (existsSync31(skillsDir)) {
18500
+ const skillsDir = join25(config.getConfigDir(), SKILLS_DIR_NAME);
18501
+ if (existsSync30(skillsDir)) {
18472
18502
  skillManager = new SkillManager(skillsDir, config.get("ui").skillSizeWarn);
18473
18503
  skillManager.loadSkills(pluginAssets.skillDirs);
18474
18504
  const count = skillManager.listSkills().length;
@@ -18519,6 +18549,10 @@ async function startWebServer(options = {}) {
18519
18549
  console.log(` Auth: ${authManager.listUsers().length} user(s) registered`);
18520
18550
  } else {
18521
18551
  console.log(` Auth: disabled (no users registered)`);
18552
+ if (host === "0.0.0.0" || host === "::") {
18553
+ console.log(" WARNING: Web UI is reachable from the network without authentication.");
18554
+ console.log(" Create a user first for LAN/team use: aicli user create <name>");
18555
+ }
18522
18556
  }
18523
18557
  const requireAuth = (req, res, next) => {
18524
18558
  if (!authManager.isEnabled()) return next();
@@ -18539,18 +18573,18 @@ async function startWebServer(options = {}) {
18539
18573
  next();
18540
18574
  };
18541
18575
  const moduleDir = getModuleDir();
18542
- let clientDir = join27(moduleDir, "web", "client");
18543
- if (!existsSync31(clientDir)) {
18544
- clientDir = join27(moduleDir, "client");
18576
+ let clientDir = join25(moduleDir, "web", "client");
18577
+ if (!existsSync30(clientDir)) {
18578
+ clientDir = join25(moduleDir, "client");
18545
18579
  }
18546
- if (!existsSync31(clientDir)) {
18547
- clientDir = join27(moduleDir, "..", "..", "src", "web", "client");
18580
+ if (!existsSync30(clientDir)) {
18581
+ clientDir = join25(moduleDir, "..", "..", "src", "web", "client");
18548
18582
  }
18549
- if (!existsSync31(clientDir)) {
18550
- clientDir = join27(process.cwd(), "src", "web", "client");
18583
+ if (!existsSync30(clientDir)) {
18584
+ clientDir = join25(process.cwd(), "src", "web", "client");
18551
18585
  }
18552
18586
  console.log(` Static files: ${clientDir}`);
18553
- app.use("/vendor", express.static(join27(clientDir, "vendor"), { maxAge: "1y", immutable: true }));
18587
+ app.use("/vendor", express.static(join25(clientDir, "vendor"), { maxAge: "1y", immutable: true }));
18554
18588
  app.use(express.static(clientDir));
18555
18589
  app.get("/api/status", (_req, res) => {
18556
18590
  res.json({
@@ -18617,10 +18651,10 @@ async function startWebServer(options = {}) {
18617
18651
  app.get("/api/files", requireAuth, (req, res) => {
18618
18652
  const cwd = process.cwd();
18619
18653
  const prefix = req.query.prefix || "";
18620
- const targetDir = join27(cwd, prefix);
18654
+ const targetDir = join25(cwd, prefix);
18621
18655
  try {
18622
- const canonicalTarget = realpathSync3(resolve12(targetDir));
18623
- const canonicalCwd = realpathSync3(resolve12(cwd));
18656
+ const canonicalTarget = realpathSync3(resolve10(targetDir));
18657
+ const canonicalCwd = realpathSync3(resolve10(cwd));
18624
18658
  if (!canonicalTarget.startsWith(canonicalCwd + sep4) && canonicalTarget !== canonicalCwd) {
18625
18659
  res.json({ files: [] });
18626
18660
  return;
@@ -18631,10 +18665,10 @@ async function startWebServer(options = {}) {
18631
18665
  }
18632
18666
  try {
18633
18667
  const SKIP = /* @__PURE__ */ new Set(["node_modules", ".git", "dist", "dist-cjs", "release", "__pycache__", ".next", ".nuxt", "coverage", ".cache"]);
18634
- const entries = readdirSync16(targetDir, { withFileTypes: true });
18668
+ const entries = readdirSync15(targetDir, { withFileTypes: true });
18635
18669
  const files = entries.filter((e) => !SKIP.has(e.name) && !e.name.startsWith(".")).slice(0, 50).map((e) => ({
18636
18670
  name: e.name,
18637
- path: relative6(cwd, join27(targetDir, e.name)).replace(/\\/g, "/"),
18671
+ path: relative6(cwd, join25(targetDir, e.name)).replace(/\\/g, "/"),
18638
18672
  isDir: e.isDirectory()
18639
18673
  }));
18640
18674
  res.json({ files });
@@ -18674,8 +18708,8 @@ async function startWebServer(options = {}) {
18674
18708
  try {
18675
18709
  const authUser = req._authUser;
18676
18710
  const histDir = authUser ? getUserShared(authUser).config.getHistoryDir() : config.getHistoryDir();
18677
- const filePath = join27(histDir, `${id}.json`);
18678
- if (!existsSync31(filePath)) {
18711
+ const filePath = join25(histDir, `${id}.json`);
18712
+ if (!existsSync30(filePath)) {
18679
18713
  res.status(404).json({ error: "Session not found" });
18680
18714
  return;
18681
18715
  }
@@ -18690,7 +18724,7 @@ async function startWebServer(options = {}) {
18690
18724
  res.status(404).json({ error: "Session not found" });
18691
18725
  return;
18692
18726
  }
18693
- const data = JSON.parse(readFileSync24(filePath, "utf-8"));
18727
+ const data = JSON.parse(readFileSync23(filePath, "utf-8"));
18694
18728
  res.json({ session: data });
18695
18729
  } catch (err) {
18696
18730
  res.status(500).json({ error: err instanceof Error ? err.message : String(err) });
@@ -18703,10 +18737,10 @@ async function startWebServer(options = {}) {
18703
18737
  return;
18704
18738
  }
18705
18739
  const cwd = process.cwd();
18706
- const fullPath = resolve12(join27(cwd, filePath));
18740
+ const fullPath = resolve10(join25(cwd, filePath));
18707
18741
  try {
18708
18742
  const canonicalFull = realpathSync3(fullPath);
18709
- const canonicalCwd = realpathSync3(resolve12(cwd));
18743
+ const canonicalCwd = realpathSync3(resolve10(cwd));
18710
18744
  if (!canonicalFull.startsWith(canonicalCwd + sep4) && canonicalFull !== canonicalCwd) {
18711
18745
  res.json({ error: "Access denied" });
18712
18746
  return;
@@ -18716,12 +18750,12 @@ async function startWebServer(options = {}) {
18716
18750
  return;
18717
18751
  }
18718
18752
  try {
18719
- const stat = statSync14(fullPath);
18753
+ const stat = statSync13(fullPath);
18720
18754
  if (stat.size > 512 * 1024) {
18721
18755
  res.json({ error: `File too large (${(stat.size / 1024).toFixed(0)} KB, max 512 KB)` });
18722
18756
  return;
18723
18757
  }
18724
- const content = readFileSync24(fullPath, "utf-8");
18758
+ const content = readFileSync23(fullPath, "utf-8");
18725
18759
  res.json({ content, size: stat.size });
18726
18760
  } catch {
18727
18761
  res.json({ error: "Cannot read file" });
@@ -18850,7 +18884,7 @@ async function startWebServer(options = {}) {
18850
18884
  ws.send(JSON.stringify({ type: "auth_result", success: false, error: err }));
18851
18885
  return;
18852
18886
  }
18853
- const newToken = authManager.login(username, password);
18887
+ authManager.login(username, password);
18854
18888
  authenticatedUser = username;
18855
18889
  const userShared = getUserShared(username);
18856
18890
  handler = new SessionHandler(ws, userShared);
@@ -18925,7 +18959,7 @@ async function startWebServer(options = {}) {
18925
18959
  });
18926
18960
  const MAX_PORT_ATTEMPTS = 10;
18927
18961
  let actualPort = port;
18928
- const result = await new Promise((resolve13, reject) => {
18962
+ const result = await new Promise((resolve11, reject) => {
18929
18963
  const tryListen = (attempt) => {
18930
18964
  server.once("error", (err) => {
18931
18965
  if (err.code === "EADDRINUSE" && attempt < MAX_PORT_ATTEMPTS) {
@@ -18956,7 +18990,7 @@ async function startWebServer(options = {}) {
18956
18990
  }
18957
18991
  console.log(` Press Ctrl+C to stop
18958
18992
  `);
18959
- resolve13({ port: actualPort, host, url });
18993
+ resolve11({ port: actualPort, host, url });
18960
18994
  });
18961
18995
  };
18962
18996
  tryListen(1);
@@ -18976,17 +19010,17 @@ function resolveProjectMcpPath() {
18976
19010
  const cwd = process.cwd();
18977
19011
  const gitRoot = getGitRoot(cwd);
18978
19012
  const projectRoot = gitRoot ?? cwd;
18979
- const configPath = join27(projectRoot, MCP_PROJECT_CONFIG_NAME);
18980
- return existsSync31(configPath) ? configPath : null;
19013
+ const configPath = join25(projectRoot, MCP_PROJECT_CONFIG_NAME);
19014
+ return existsSync30(configPath) ? configPath : null;
18981
19015
  }
18982
19016
  function loadProjectMcpConfig() {
18983
19017
  const cwd = process.cwd();
18984
19018
  const gitRoot = getGitRoot(cwd);
18985
19019
  const projectRoot = gitRoot ?? cwd;
18986
- const configPath = join27(projectRoot, MCP_PROJECT_CONFIG_NAME);
18987
- if (!existsSync31(configPath)) return null;
19020
+ const configPath = join25(projectRoot, MCP_PROJECT_CONFIG_NAME);
19021
+ if (!existsSync30(configPath)) return null;
18988
19022
  try {
18989
- const raw = JSON.parse(readFileSync24(configPath, "utf-8"));
19023
+ const raw = JSON.parse(readFileSync23(configPath, "utf-8"));
18990
19024
  return raw.mcpServers ?? raw;
18991
19025
  } catch {
18992
19026
  return null;