jinzd-ai-cli 0.4.320 → 0.4.321

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 (34) hide show
  1. package/dist/{batch-LRYDPB6F.js → batch-EW6QTSE6.js} +2 -2
  2. package/dist/{chunk-4S2XD3M2.js → chunk-2GOBINY4.js} +4 -4
  3. package/dist/{chunk-J7IPNING.js → chunk-2R6Y5SJH.js} +1 -1
  4. package/dist/{chunk-QB3MECZJ.js → chunk-4MO2I5JB.js} +8 -8
  5. package/dist/{chunk-46M65JDN.js → chunk-6RCGQQFM.js} +56 -19
  6. package/dist/{chunk-NOAWUEJJ.js → chunk-6XXHAS5B.js} +1 -1
  7. package/dist/{chunk-WW2LFOWE.js → chunk-7QW3DFYV.js} +1 -1
  8. package/dist/{chunk-DB4HVUPI.js → chunk-COHKPZ2E.js} +1 -1
  9. package/dist/{chunk-WY4IWCQ5.js → chunk-I3GEFCKP.js} +1 -1
  10. package/dist/{chunk-N6YFBRQV.js → chunk-JHSULP5D.js} +1 -1
  11. package/dist/{chunk-P4FJBD2H.js → chunk-LEA4AMXE.js} +1 -1
  12. package/dist/{chunk-46OEMKQX.js → chunk-NFPJ6KUU.js} +8 -4
  13. package/dist/{chunk-SKQUWDRM.js → chunk-VEO2MILP.js} +1 -1
  14. package/dist/{chunk-5VZHSSLW.js → chunk-VS43QMR2.js} +1 -1
  15. package/dist/{chunk-YAMPLTYO.js → chunk-XVB4RARX.js} +74 -1
  16. package/dist/{chunk-TKBWA3XJ.js → chunk-ZDO3XCXL.js} +4 -4
  17. package/dist/{ci-7TSOMDHV.js → ci-EZZD7CMS.js} +5 -5
  18. package/dist/{ci-format-6A2RFYZS.js → ci-format-ZWECV6XI.js} +2 -2
  19. package/dist/{constants-P33UDQVS.js → constants-F2ULZ6W2.js} +1 -1
  20. package/dist/{constants-EHYM2NS5.js → constants-HF5AYLBR.js} +1 -1
  21. package/dist/{doctor-cli-2B72UMZO.js → doctor-cli-QAKYBWLG.js} +5 -5
  22. package/dist/electron-server.js +144 -30
  23. package/dist/{hub-JACLTKYY.js → hub-OYH2UGER.js} +1 -1
  24. package/dist/index.js +29 -20
  25. package/dist/{persistent-memory-ZIM6ICIR.js → persistent-memory-EVZX7SLR.js} +2 -2
  26. package/dist/{persistent-memory-5ICLP275.js → persistent-memory-WNPZSVE4.js} +2 -2
  27. package/dist/{pr-UBGLNROK.js → pr-XPQVXG2G.js} +5 -5
  28. package/dist/{run-tests-HCID73KE.js → run-tests-3SYXE2PJ.js} +2 -2
  29. package/dist/{run-tests-SYJG4S3N.js → run-tests-MFXQ76ZJ.js} +2 -2
  30. package/dist/{server-BVTFIPB2.js → server-AF5PIBUD.js} +5 -5
  31. package/dist/{server-3UEEPEUD.js → server-VOGBRYA5.js} +15 -15
  32. package/dist/{task-orchestrator-6NRCGF5V.js → task-orchestrator-QHJEDRDS.js} +5 -5
  33. package/dist/{usage-6V64TTRE.js → usage-EZOW27TR.js} +3 -3
  34. package/package.json +1 -1
@@ -55,7 +55,7 @@ import {
55
55
  touchMemoryReferences,
56
56
  updateMemoryApproval,
57
57
  updateMemoryEntry
58
- } from "./chunk-WW2LFOWE.js";
58
+ } from "./chunk-7QW3DFYV.js";
59
59
  import {
60
60
  DEFAULT_PATTERNS,
61
61
  redactJson,
@@ -81,7 +81,7 @@ import {
81
81
  recoverGbkMojibake,
82
82
  runTestsTool,
83
83
  shellInvocation
84
- } from "./chunk-N6YFBRQV.js";
84
+ } from "./chunk-JHSULP5D.js";
85
85
  import {
86
86
  getCurrentSessionKey,
87
87
  getExecutionConfigDir,
@@ -123,7 +123,7 @@ import {
123
123
  SUBAGENT_MAX_ROUNDS_LIMIT,
124
124
  VERSION,
125
125
  buildUserIdentityPrompt
126
- } from "./chunk-SKQUWDRM.js";
126
+ } from "./chunk-VEO2MILP.js";
127
127
 
128
128
  // src/web/access.ts
129
129
  import { randomBytes, timingSafeEqual } from "crypto";
@@ -981,17 +981,21 @@ var PRICING_TABLE = {
981
981
  "glm-4.6": { input: 0.6, output: 2.2 },
982
982
  "glm-4.6v": { input: 0.6, output: 2.2 },
983
983
  "glm-5": { input: 0.85, output: 2.85 },
984
- // GLM-5.3(2026-08-14 发布)官方公告口径「与 GLM-5.2 同价」,直连 API $1.40 / $4.40。
984
+ // GLM-5.3:官方定价页(open.bigmodel.cn/pricing,2026-10-08 浏览器读取)——输入 8 元、
985
+ // 输出 28 元、缓存命中 2 元(每百万 token),按 ¥6.9/$1 换算。此前记的 $1.40/$4.40 是
986
+ // Z.ai 国际站的美元价,而本 provider 打的是国内站、按人民币计费,高报约 20%;更大的
987
+ // 偏差在**缓存**:没有 cacheRead 时缓存命中按输入全价算,2026-10-07 审计会话 1474 万
988
+ // 缓存 token 被记成 $21.34,按官方缓存价约 $4.90(2026-10-07 审计 X-03)。
985
989
  // 注意它**始终思考**,思考 token 按输出价计费 —— 实际成本高度取决于 reasoning_effort。
986
- "glm-5.3": { input: 1.4, output: 4.4 },
990
+ "glm-5.3": { input: 8 / CNY_PER_USD, output: 28 / CNY_PER_USD, cacheRead: 2 / CNY_PER_USD },
987
991
  // GLM-5.3-Flash:官方定价页(open.bigmodel.cn/pricing)一手数字——输入 0.8 元、
988
992
  // 输出 2.8 元、缓存命中 0.23 元(每百万 token),按记账汇率 ¥6.9/$1 换算。
989
993
  // **刻意记恢复价而非当前的 5 折限时价**(0.4/1.4/0.115 元):官方只说「限时两周」、
990
994
  // 没公布截止日期,静态表表达不了这个时间维度;高估比低估安全——预算告警早触发
991
995
  // 好过晚触发。折扣期内 `/cost` 会比实际偏高约一倍,这是刻意的取舍。
992
996
  "glm-5.3-flash": { input: 0.116, output: 0.406, cacheRead: 0.033 },
993
- // GLM-5.2(2026-06)官方直连 API 定价 $1.40 / $4.40。
994
- "glm-5.2": { input: 1.4, output: 4.4 },
997
+ // GLM-5.2:与 GLM-5.3 同价(同一定价页:8 / 28 / 缓存命中 2 元),口径修正同上。
998
+ "glm-5.2": { input: 8 / CNY_PER_USD, output: 28 / CNY_PER_USD, cacheRead: 2 / CNY_PER_USD },
995
999
  // GLM-5V-Turbo(2026-04 视觉编程旗舰)官方直连 API 定价 $1.20 / $4.00。
996
1000
  "glm-5v-turbo": { input: 1.2, output: 4 },
997
1001
  "glm-5.1": { input: 0.95, output: 3.15 },
@@ -4773,6 +4777,7 @@ function ollamaNativeBaseUrl(openAiBaseUrl) {
4773
4777
  return openAiBaseUrl.replace(/\/+$/, "").replace(/\/v1$/, "");
4774
4778
  }
4775
4779
  var NATIVE_API_TIMEOUT_MS = 3e3;
4780
+ var SMALL_CONTEXT_WARN = 16384;
4776
4781
  var OllamaProvider = class extends OpenAICompatibleProvider {
4777
4782
  // 用 127.0.0.1 而非 localhost:Node.js 18+ 在 Windows 上优先解析 localhost 为 IPv6 (::1),
4778
4783
  // 但 Ollama 默认只监听 IPv4,导致连接失败。
@@ -4851,12 +4856,13 @@ var OllamaProvider = class extends OpenAICompatibleProvider {
4851
4856
  if (show?.capabilities?.includes("thinking")) thinkingModels.add(id);
4852
4857
  if (running.size === 0 && !show) return;
4853
4858
  const digest = digests.get(id);
4854
- const { contextWindow } = resolveOllamaContextWindow({
4859
+ const { contextWindow, source: source2 } = resolveOllamaContextWindow({
4855
4860
  runningContext: digest && running.get(digest) || running.get(id),
4856
4861
  show,
4857
4862
  fallback: this.estimateContextWindow(id)
4858
4863
  });
4859
4864
  result.set(id, contextWindow);
4865
+ this.contextSources.set(id, source2);
4860
4866
  }));
4861
4867
  return { contextWindows: result, thinkingModels };
4862
4868
  }
@@ -4952,6 +4958,77 @@ var OllamaProvider = class extends OpenAICompatibleProvider {
4952
4958
  const target = norm2(model);
4953
4959
  return this.dynamicModels.some((m) => m.supportsThinking === true && norm2(m.id) === target);
4954
4960
  }
4961
+ // ── 加载后补读真实窗口(2026-10-07 审计 C-01)────────────────────────────
4962
+ //
4963
+ // 上下文窗口只在启动时读一次。模型当时若还没加载,`/api/ps` 里没有它,只能取训练上限
4964
+ // (Qwen3.8 是 262K);而服务端实际开的窗口可能只有它的几十分之一。第一次请求把模型
4965
+ // 加载进来之后若不再读,上下文压力监控、自动压缩与工具预算就整场按那个大数在算——
4966
+ // aicli 以为还有余量,Ollama 早已在悄悄截掉最早的消息(v0.4.311 那次说的正是这个后果)。
4967
+ // 所以每个模型在首次请求之后补读一次 `/api/ps`;读到的窗口若小得连工具定义都放不下,
4968
+ // 提示一次怎么调大。都是后台做,不拖慢这次请求。
4969
+ /** 每个模型的窗口是从哪一级读到的(只有 'running' 是服务端实际值) */
4970
+ contextSources = /* @__PURE__ */ new Map();
4971
+ refreshedAfterLoad = /* @__PURE__ */ new Set();
4972
+ warnedSmallContext = /* @__PURE__ */ new Set();
4973
+ async chat(request) {
4974
+ try {
4975
+ return await super.chat(request);
4976
+ } finally {
4977
+ this.scheduleContextRefresh(request.model);
4978
+ }
4979
+ }
4980
+ async *chatStream(request) {
4981
+ try {
4982
+ yield* super.chatStream(request);
4983
+ } finally {
4984
+ this.scheduleContextRefresh(request.model);
4985
+ }
4986
+ }
4987
+ async chatWithTools(request, tools) {
4988
+ try {
4989
+ return await super.chatWithTools(request, tools);
4990
+ } finally {
4991
+ this.scheduleContextRefresh(request.model);
4992
+ }
4993
+ }
4994
+ async *chatWithToolsStream(request, tools) {
4995
+ try {
4996
+ yield* super.chatWithToolsStream(request, tools);
4997
+ } finally {
4998
+ this.scheduleContextRefresh(request.model);
4999
+ }
5000
+ }
5001
+ scheduleContextRefresh(model) {
5002
+ const key = model.replace(/:latest$/, "");
5003
+ if (this.refreshedAfterLoad.has(key)) return;
5004
+ this.refreshedAfterLoad.add(key);
5005
+ void this.refreshLoadedContext(model).catch(() => {
5006
+ });
5007
+ }
5008
+ /** 补读已加载模型的实际窗口,更新同一份权重(digest 相同)的所有别名。测试可直接 await。 */
5009
+ async refreshLoadedContext(model) {
5010
+ const norm2 = (id2) => id2.replace(/:latest$/, "");
5011
+ const [running, digests] = await Promise.all([this.fetchRunningContexts(), this.fetchDigests()]);
5012
+ const self = this.dynamicModels.find((m) => norm2(m.id) === norm2(model));
5013
+ const id = self?.id ?? model;
5014
+ const digest = digests.get(id);
5015
+ const actual = digest && running.get(digest) || running.get(id);
5016
+ if (!actual) return;
5017
+ for (const m of this.dynamicModels) {
5018
+ if (m.id === id || digest && digests.get(m.id) === digest) {
5019
+ m.contextWindow = actual;
5020
+ this.contextSources.set(m.id, "running");
5021
+ }
5022
+ }
5023
+ if (actual < SMALL_CONTEXT_WARN && !this.warnedSmallContext.has(norm2(id))) {
5024
+ this.warnedSmallContext.add(norm2(id));
5025
+ process.stderr.write(
5026
+ `
5027
+ [ollama] ${id} is loaded with a ${actual.toLocaleString()}-token context window. aicli's tool definitions alone take about 8K tokens, so earlier messages will be silently cut off. Raise it: set OLLAMA_CONTEXT_LENGTH=32768 (or more) for the Ollama server, or add "PARAMETER num_ctx 32768" to the model's Modelfile.
5028
+ `
5029
+ );
5030
+ }
5031
+ }
4955
5032
  /** 实时刷新模型列表 */
4956
5033
  async listModels() {
4957
5034
  await this.tryConnect();
@@ -13487,21 +13564,37 @@ function estimateTokens(text) {
13487
13564
  return Math.ceil(tokens) + 4;
13488
13565
  }
13489
13566
  function estimateToolDefinitionTokens(def) {
13490
- let charCount = def.name.length + def.description.length;
13491
- for (const [key, param] of Object.entries(def.parameters)) {
13492
- charCount += key.length + param.type.length + param.description.length;
13493
- if (param.enum) {
13494
- charCount += param.enum.join(" ").length;
13495
- }
13496
- }
13497
- const structuralOverhead = 40 + Object.keys(def.parameters).length * 30;
13498
- return Math.ceil((charCount + structuralOverhead) * 0.25) + 10;
13567
+ const json = JSON.stringify({ name: def.name, description: def.description, parameters: def.parameters });
13568
+ const cjk = json.match(CJK_REGEX)?.length ?? 0;
13569
+ return Math.ceil((json.length - cjk + 40) / 3.7 + cjk * 1.5);
13499
13570
  }
13500
13571
 
13501
13572
  // src/tools/registry.ts
13502
13573
  import { pathToFileURL } from "url";
13503
13574
  import { existsSync as existsSync19, mkdirSync as mkdirSync9, readdirSync as readdirSync9 } from "fs";
13504
13575
  import { join as join13 } from "path";
13576
+ var TRIMMABLE_BUILTIN_ORDER = [
13577
+ "google_search",
13578
+ "recall_memory",
13579
+ "search_code",
13580
+ "notebook_edit",
13581
+ "spawn_agent",
13582
+ "run_interactive",
13583
+ "save_memory",
13584
+ "find_references",
13585
+ "get_outline",
13586
+ "find_symbol",
13587
+ "task_stop",
13588
+ "task_list",
13589
+ "task_create",
13590
+ "git_log",
13591
+ "git_diff",
13592
+ "git_commit",
13593
+ "git_status",
13594
+ "web_fetch",
13595
+ "web_search",
13596
+ "run_tests"
13597
+ ];
13505
13598
  var ToolRegistry = class {
13506
13599
  tools = /* @__PURE__ */ new Map();
13507
13600
  pluginToolNames = /* @__PURE__ */ new Set();
@@ -13569,7 +13662,7 @@ var ToolRegistry = class {
13569
13662
  totalTokens += estimateToolDefinitionTokens(def);
13570
13663
  }
13571
13664
  if (totalTokens <= tokenBudget) {
13572
- return { definitions: allDefs, trimmedCount: 0, systemNote: null };
13665
+ return { definitions: allDefs, trimmedCount: 0, trimmedBuiltins: [], systemNote: null };
13573
13666
  }
13574
13667
  const builtinDefs = [];
13575
13668
  const mcpDefs = [];
@@ -13581,10 +13674,19 @@ var ToolRegistry = class {
13581
13674
  }
13582
13675
  }
13583
13676
  let budget = tokenBudget;
13584
- for (const def of builtinDefs) {
13585
- budget -= estimateToolDefinitionTokens(def);
13586
- }
13587
- const kept = [...builtinDefs];
13677
+ const trimmedBuiltins = [];
13678
+ let builtinCost = builtinDefs.reduce((n, d) => n + estimateToolDefinitionTokens(d), 0);
13679
+ const keptBuiltins = new Set(builtinDefs.map((d) => d.name));
13680
+ for (const name of TRIMMABLE_BUILTIN_ORDER) {
13681
+ if (builtinCost <= budget) break;
13682
+ const def = builtinDefs.find((d) => d.name === name);
13683
+ if (!def || this.pluginToolNames.has(name)) continue;
13684
+ keptBuiltins.delete(name);
13685
+ trimmedBuiltins.push(name);
13686
+ builtinCost -= estimateToolDefinitionTokens(def);
13687
+ }
13688
+ budget -= builtinCost;
13689
+ const kept = builtinDefs.filter((d) => keptBuiltins.has(d.name));
13588
13690
  const used = usedToolNames ?? /* @__PURE__ */ new Set();
13589
13691
  const remaining = [];
13590
13692
  for (const def of mcpDefs) {
@@ -13606,6 +13708,12 @@ var ToolRegistry = class {
13606
13708
  trimmed++;
13607
13709
  }
13608
13710
  }
13711
+ const notes = [];
13712
+ if (trimmedBuiltins.length > 0) {
13713
+ notes.push(
13714
+ `[Tool Budget] To fit this model's context window, these tools are not available in this session: ${trimmedBuiltins.join(", ")}. Use bash for the equivalent (git commands, grep for symbols, curl for web pages) instead of calling them.`
13715
+ );
13716
+ }
13609
13717
  let systemNote = null;
13610
13718
  if (trimmed > 0) {
13611
13719
  const trimmedServers = /* @__PURE__ */ new Set();
@@ -13618,7 +13726,13 @@ var ToolRegistry = class {
13618
13726
  }
13619
13727
  systemNote = `[MCP Tool Budget] ${trimmed} MCP tool(s) from server(s) [${[...trimmedServers].join(", ")}] were excluded to fit the context window. If you need a specific MCP tool that isn't listed, tell the user to ask for it explicitly.`;
13620
13728
  }
13621
- return { definitions: kept, trimmedCount: trimmed, systemNote };
13729
+ if (systemNote) notes.push(systemNote);
13730
+ return {
13731
+ definitions: kept,
13732
+ trimmedCount: trimmed,
13733
+ trimmedBuiltins,
13734
+ systemNote: notes.length > 0 ? notes.join("\n\n") : null
13735
+ };
13622
13736
  }
13623
13737
  listAll() {
13624
13738
  return [...this.tools.values()];
@@ -17595,7 +17709,7 @@ Cache: write=${cacheCreate} read=${cacheRead}` : "";
17595
17709
  Cost: ${formatCost(cost)}` : "";
17596
17710
  let memoryLine = "";
17597
17711
  try {
17598
- const { countPendingMemories: countPendingMemories2 } = await import("./persistent-memory-ZIM6ICIR.js");
17712
+ const { countPendingMemories: countPendingMemories2 } = await import("./persistent-memory-EVZX7SLR.js");
17599
17713
  const pending = countPendingMemories2(ctx.config.getConfigDir());
17600
17714
  if (pending > 0) memoryLine = `
17601
17715
  Memory: \u26A0 ${pending} pending approval \u2014 see the Memory panel or /memory`;
@@ -18583,7 +18697,7 @@ async function handleTest(args, ctx) {
18583
18697
  const isCommand = argStr.includes(" ") || /^(mvn|gradle|npm|pytest|cargo|go)\b/.test(argStr);
18584
18698
  testArgs = isCommand ? { command: argStr } : { filter: argStr };
18585
18699
  }
18586
- const runTests = ctx.runTests ?? (await import("./run-tests-HCID73KE.js")).executeTests;
18700
+ const runTests = ctx.runTests ?? (await import("./run-tests-3SYXE2PJ.js")).executeTests;
18587
18701
  const report = await runTests(testArgs);
18588
18702
  ctx.send({ type: "info", message: report });
18589
18703
  } catch (err) {
@@ -18974,7 +19088,7 @@ async function handleMemory(args, ctx) {
18974
19088
  }
18975
19089
  if (intent.kind === "status") {
18976
19090
  const { getChatIndexStatus: getChatIndexStatus2 } = await import("./chat-index-RLVLQRRC.js");
18977
- const { listMemoryEntries: listMemoryEntries2, isMemoryExpired: isMemoryExpired2, formatMemoryForPrompt: formatMemoryForPrompt2 } = await import("./persistent-memory-ZIM6ICIR.js");
19091
+ const { listMemoryEntries: listMemoryEntries2, isMemoryExpired: isMemoryExpired2, formatMemoryForPrompt: formatMemoryForPrompt2 } = await import("./persistent-memory-EVZX7SLR.js");
18978
19092
  const memories = listMemoryEntries2(configDir, { includeExpired: true, includeRejected: true });
18979
19093
  const injected = formatMemoryForPrompt2(configDir, process.cwd(), ctx.config.get("memory")?.maxChars);
18980
19094
  const view = buildMemoryStatusView({
@@ -18997,7 +19111,7 @@ async function handleMemory(args, ctx) {
18997
19111
  return;
18998
19112
  }
18999
19113
  if (intent.kind === "recall") {
19000
- const { searchPersistentMemories: searchPersistentMemories2, touchMemoryReferences: touchMemoryReferences2 } = await import("./persistent-memory-ZIM6ICIR.js");
19114
+ const { searchPersistentMemories: searchPersistentMemories2, touchMemoryReferences: touchMemoryReferences2 } = await import("./persistent-memory-EVZX7SLR.js");
19001
19115
  const { searchChatMemory: searchChatMemory2 } = await import("./chat-index-RLVLQRRC.js");
19002
19116
  const persistentHits = searchPersistentMemories2(configDir, intent.query, process.cwd(), 3);
19003
19117
  if (persistentHits.length > 0) {
@@ -19118,7 +19232,7 @@ async function handleMemory(args, ctx) {
19118
19232
  ctx.handleMemoryManage(intent.action, args[1], intent.action === "expire" ? args[2] : void 0);
19119
19233
  } else if (intent.kind === "export") {
19120
19234
  if (args[1] === "md") {
19121
- const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-ZIM6ICIR.js");
19235
+ const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-EVZX7SLR.js");
19122
19236
  ctx.send({
19123
19237
  type: "export_data",
19124
19238
  format: "md",
@@ -20123,7 +20237,7 @@ No tools match "${filter}".
20123
20237
  const { join: join26 } = await import("path");
20124
20238
  const { existsSync: existsSync32 } = await import("fs");
20125
20239
  const { getGitRoot: getGitRoot2 } = await import("./git-context-VNCA2GU7.js");
20126
- const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-EHYM2NS5.js");
20240
+ const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-HF5AYLBR.js");
20127
20241
  const { approveProject, hashMcpFile } = await import("./project-trust-6CJB5ZMX.js");
20128
20242
  const cwd = process.cwd();
20129
20243
  const projectRoot = getGitRoot2(cwd) ?? cwd;
@@ -21042,7 +21156,7 @@ function createReviewCommands() {
21042
21156
  usage: "/test [command|filter]",
21043
21157
  async execute(args, ctx) {
21044
21158
  try {
21045
- const { executeTests } = await import("./run-tests-HCID73KE.js");
21159
+ const { executeTests } = await import("./run-tests-3SYXE2PJ.js");
21046
21160
  const argStr = args.join(" ").trim();
21047
21161
  let testArgs = {};
21048
21162
  if (argStr) {
@@ -158,7 +158,7 @@ ${content}`);
158
158
  }
159
159
  }
160
160
  async function runTaskMode(config, providers, configManager, topic) {
161
- const { TaskOrchestrator } = await import("./task-orchestrator-6NRCGF5V.js");
161
+ const { TaskOrchestrator } = await import("./task-orchestrator-QHJEDRDS.js");
162
162
  const orchestrator = new TaskOrchestrator(config, providers, configManager);
163
163
  let interrupted = false;
164
164
  const onSigint = () => {
package/dist/index.js CHANGED
@@ -24,12 +24,12 @@ import {
24
24
  setupProxy,
25
25
  snapshotFile,
26
26
  stripRoutingTags
27
- } from "./chunk-QB3MECZJ.js";
27
+ } from "./chunk-4MO2I5JB.js";
28
28
  import {
29
29
  CostTracker,
30
30
  getPricing,
31
31
  setCostCurrency
32
- } from "./chunk-46OEMKQX.js";
32
+ } from "./chunk-NFPJ6KUU.js";
33
33
  import {
34
34
  ToolExecutor,
35
35
  ToolRegistry,
@@ -47,7 +47,7 @@ import {
47
47
  setMaxOutputCap,
48
48
  spawnAgentContext,
49
49
  undoStack
50
- } from "./chunk-46M65JDN.js";
50
+ } from "./chunk-6RCGQQFM.js";
51
51
  import "./chunk-HLWUDRBO.js";
52
52
  import {
53
53
  NO_THINKING,
@@ -60,7 +60,7 @@ import {
60
60
  countPendingMemories,
61
61
  detectStaleLegacyMarkdownEdit,
62
62
  formatMemoryForPrompt
63
- } from "./chunk-WY4IWCQ5.js";
63
+ } from "./chunk-I3GEFCKP.js";
64
64
  import "./chunk-RWRZVQCB.js";
65
65
  import "./chunk-B3MPYI4E.js";
66
66
  import "./chunk-M6HLYG33.js";
@@ -81,22 +81,22 @@ import {
81
81
  import {
82
82
  loadContextFiles,
83
83
  writeCrashLog
84
- } from "./chunk-4S2XD3M2.js";
84
+ } from "./chunk-2GOBINY4.js";
85
85
  import {
86
86
  getActivePluginAssets,
87
87
  getPendingHookTrust,
88
88
  installFlushOnExit,
89
89
  mergePluginHooks,
90
90
  runLifecycleHooks
91
- } from "./chunk-5VZHSSLW.js";
91
+ } from "./chunk-VS43QMR2.js";
92
92
  import "./chunk-RS7SKYTS.js";
93
93
  import {
94
94
  ProviderRegistry,
95
95
  listBuiltInProviderMetadata
96
- } from "./chunk-YAMPLTYO.js";
96
+ } from "./chunk-XVB4RARX.js";
97
97
  import {
98
98
  ConfigManager
99
- } from "./chunk-DB4HVUPI.js";
99
+ } from "./chunk-COHKPZ2E.js";
100
100
  import {
101
101
  CONTENT_ONLY_STREAM_REMINDER,
102
102
  TEE_FINAL_USER_NUDGE,
@@ -134,7 +134,7 @@ import {
134
134
  isInterrupted,
135
135
  requestInterrupt,
136
136
  resetInterrupt
137
- } from "./chunk-NOAWUEJJ.js";
137
+ } from "./chunk-6XXHAS5B.js";
138
138
  import {
139
139
  AGENTIC_BEHAVIOR_GUIDELINE,
140
140
  AUTHOR,
@@ -152,7 +152,7 @@ import {
152
152
  SKILLS_DIR_NAME,
153
153
  VERSION,
154
154
  buildUserIdentityPrompt
155
- } from "./chunk-J7IPNING.js";
155
+ } from "./chunk-2R6Y5SJH.js";
156
156
  import "./chunk-SXIJLSVF.js";
157
157
 
158
158
  // src/index.ts
@@ -1627,6 +1627,8 @@ var Repl = class {
1627
1627
  * true 时:工具集过滤为只读工具,system prompt 注入规划说明,提示符加 [PLAN] 标记。
1628
1628
  */
1629
1629
  planMode = false;
1630
+ /** 小窗口裁掉内置工具的提示每个 REPL 只打一次(每轮都会重算预算) */
1631
+ toolBudgetNoticeShown = false;
1630
1632
  /** 技能管理器 */
1631
1633
  skillManager = null;
1632
1634
  customCommandManager = null;
@@ -3147,13 +3149,20 @@ Session '${this.resumeSessionId}' not found.
3147
3149
  const contextWindow = this.getContextWindowSize(effectiveModel);
3148
3150
  if (contextWindow > 0) {
3149
3151
  const toolBudget = Math.floor(contextWindow * 0.2);
3150
- const { definitions, trimmedCount, systemNote } = this.toolRegistry.getDefinitionsWithBudget(toolBudget, usedMcpToolNames);
3152
+ const { definitions, trimmedCount, trimmedBuiltins, systemNote } = this.toolRegistry.getDefinitionsWithBudget(toolBudget, usedMcpToolNames);
3151
3153
  toolDefs = definitions;
3152
3154
  mcpBudgetNote = systemNote;
3153
3155
  if (trimmedCount > 0) {
3154
3156
  process.stderr.write(theme.dim(` [MCP budget] ${trimmedCount} MCP tool(s) trimmed to fit ${toolBudget.toLocaleString()} token budget
3155
3157
  `));
3156
3158
  }
3159
+ if (trimmedBuiltins.length > 0 && !this.toolBudgetNoticeShown) {
3160
+ this.toolBudgetNoticeShown = true;
3161
+ process.stderr.write(theme.dim(
3162
+ ` [tool budget] ${contextWindow.toLocaleString()}-token context: ${trimmedBuiltins.length} builtin tool(s) left out to save room (${trimmedBuiltins.join(", ")})
3163
+ `
3164
+ ));
3165
+ }
3157
3166
  } else {
3158
3167
  toolDefs = this.toolRegistry.getDefinitions();
3159
3168
  }
@@ -4107,7 +4116,7 @@ program.command("web").description("Start Web UI server with browser-based chat
4107
4116
  console.error("Error: Invalid port number. Must be between 1 and 65535.");
4108
4117
  process.exit(1);
4109
4118
  }
4110
- const { startWebServer } = await import("./server-3UEEPEUD.js");
4119
+ const { startWebServer } = await import("./server-VOGBRYA5.js");
4111
4120
  await startWebServer({ port, host: options.host, externalOrigin: options.externalOrigin });
4112
4121
  });
4113
4122
  program.command("user [action] [username]").description("Manage Web UI users (list | create <name> | delete <name> | reset-password <name> | logout-all <name> | migrate <name>)").action(async (action, username) => {
@@ -4274,11 +4283,11 @@ program.command("sessions").description("List recent conversation sessions").opt
4274
4283
  console.log(footer + "\n");
4275
4284
  });
4276
4285
  program.command("usage").description("Show token + cost usage grouped by provider/model (cross-session)").option("--days <n>", "Only the last N days (inclusive of today)").option("--month <ym>", "Only a specific month, format YYYY-MM (e.g. 2026-06)").option("--json", "Output as JSON (for scripting)").action(async (options) => {
4277
- const { runUsageCli } = await import("./usage-6V64TTRE.js");
4286
+ const { runUsageCli } = await import("./usage-EZOW27TR.js");
4278
4287
  await runUsageCli(options);
4279
4288
  });
4280
4289
  program.command("doctor").description("Health check: API keys, config, MCP, recent crashes, tool usage, disk usage").option("--json", "Output as JSON (for scripting)").option("--reset-stats", "Reset accumulated tool usage statistics").action(async (options) => {
4281
- const { runDoctorCli } = await import("./doctor-cli-2B72UMZO.js");
4290
+ const { runDoctorCli } = await import("./doctor-cli-QAKYBWLG.js");
4282
4291
  const argv = process.argv.slice(2);
4283
4292
  await runDoctorCli({
4284
4293
  json: !!options.json || argv.includes("--json"),
@@ -4287,7 +4296,7 @@ program.command("doctor").description("Health check: API keys, config, MCP, rece
4287
4296
  });
4288
4297
  program.command("batch <action> [arg] [arg2]").description("Anthropic Message Batches: submit | list | status <id> | results <id> [out] | cancel <id>").option("--dry-run", "Parse and validate input without submitting (submit only)").action(async (action, arg, arg2, options) => {
4289
4298
  try {
4290
- const batch = await import("./batch-LRYDPB6F.js");
4299
+ const batch = await import("./batch-EW6QTSE6.js");
4291
4300
  switch (action) {
4292
4301
  case "submit":
4293
4302
  if (!arg) {
@@ -4330,7 +4339,7 @@ program.command("batch <action> [arg] [arg2]").description("Anthropic Message Ba
4330
4339
  }
4331
4340
  });
4332
4341
  program.command("mcp-serve").description("Start an MCP server over STDIO, exposing aicli's built-in tools to Claude Desktop / Cursor / other MCP clients").option("--allow-destructive", "Allow bash / run_interactive / task_create (always destructive in MCP mode)").option("--allow-outside-cwd", "Allow tool path arguments to escape the sandbox root \u2014 disabled by default").option("--tools <list>", "Comma-separated whitelist of tools to expose (default: all eligible tools)").option("--cwd <path>", "Working directory AND sandbox root (default: current directory)").action(async (options) => {
4333
- const { startMcpServer } = await import("./server-BVTFIPB2.js");
4342
+ const { startMcpServer } = await import("./server-AF5PIBUD.js");
4334
4343
  await startMcpServer({
4335
4344
  allowDestructive: !!options.allowDestructive,
4336
4345
  allowOutsideCwd: !!options.allowOutsideCwd,
@@ -4343,7 +4352,7 @@ program.command("pr <action> [target]").description("PR review helpers: review |
4343
4352
  console.error(`Unknown pr action: ${action}. Use review | security-review | summarize.`);
4344
4353
  process.exit(1);
4345
4354
  }
4346
- const { runPrCli } = await import("./pr-UBGLNROK.js");
4355
+ const { runPrCli } = await import("./pr-XPQVXG2G.js");
4347
4356
  const result = await runPrCli({
4348
4357
  action,
4349
4358
  target,
@@ -4363,8 +4372,8 @@ program.command("pr <action> [target]").description("PR review helpers: review |
4363
4372
  process.exit(result.exitCode);
4364
4373
  });
4365
4374
  program.command("ci").description("Headless PR review (code + security) \u2014 reads git/gh diff, optionally posts to PR. Designed for GitHub Actions.").option("--pr <num>", "PR number or URL; diff fetched via gh pr diff <value>", (v) => /^#?\d+$/.test(v) ? parseInt(v.replace(/^#/, ""), 10) : v).option("--base <ref>", "Base ref for git diff <ref>...HEAD (ignored when --pr set)").option("--post", "Post review as a PR comment (requires gh CLI + GH_TOKEN, needs --pr)").option("--no-update", "Always create a new comment instead of updating the previous aicli review").option("--skip-code", "Skip the code review section").option("--skip-security", "Skip the security review section").option("--detailed", "Use the detailed code-review prompt").option("--max-diff <n>", "Max diff chars sent to the model (default 30000)", (v) => parseInt(v, 10)).option("--provider <id>", "Override provider (default: config.defaultProvider)").option("--model <id>", "Override model").option("--dry-run", "Print result to stdout instead of posting (overrides --post)").option("--json", "Output a structured JSON report").option("--markdown", "Output Markdown report (default)").option("--sarif", "Output SARIF 2.1.0 for code scanning artifacts").option("--fail-on-security-high", "Fail when the security review contains HIGH/CRITICAL findings (default)").option("--no-fail-on-security-high", "Do not fail on security HIGH/CRITICAL findings").option("--fail-on-test-failure", "Fail when the report mentions test failures (default)").option("--no-fail-on-test-failure", "Do not fail on test failure findings").option("--fail-on-lint-failure", "Fail when the report mentions lint/typecheck failures (default)").option("--no-fail-on-lint-failure", "Do not fail on lint/typecheck failure findings").action(async (options) => {
4366
- const { runCi } = await import("./ci-7TSOMDHV.js");
4367
- const { formatCiResult } = await import("./ci-format-6A2RFYZS.js");
4375
+ const { runCi } = await import("./ci-EZZD7CMS.js");
4376
+ const { formatCiResult } = await import("./ci-format-ZWECV6XI.js");
4368
4377
  const formats = [options.json, options.markdown, options.sarif].filter(Boolean).length;
4369
4378
  if (formats > 1) {
4370
4379
  console.error("Choose only one output format: --json, --markdown, or --sarif.");
@@ -4523,7 +4532,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
4523
4532
  config.get("customProviders"),
4524
4533
  config.getConfigDir()
4525
4534
  );
4526
- const { startHub } = await import("./hub-JACLTKYY.js");
4535
+ const { startHub } = await import("./hub-OYH2UGER.js");
4527
4536
  await startHub(
4528
4537
  {
4529
4538
  topic: topic ?? "",
@@ -27,11 +27,11 @@ import {
27
27
  touchMemoryReferences,
28
28
  updateMemoryApproval,
29
29
  updateMemoryEntry
30
- } from "./chunk-WW2LFOWE.js";
30
+ } from "./chunk-7QW3DFYV.js";
31
31
  import "./chunk-FSC6KEWU.js";
32
32
  import "./chunk-2XMUCC42.js";
33
33
  import "./chunk-CGLYJRFA.js";
34
- import "./chunk-SKQUWDRM.js";
34
+ import "./chunk-VEO2MILP.js";
35
35
  export {
36
36
  addMemoryEntry,
37
37
  backupMemoryStore,
@@ -28,11 +28,11 @@ import {
28
28
  touchMemoryReferences,
29
29
  updateMemoryApproval,
30
30
  updateMemoryEntry
31
- } from "./chunk-WY4IWCQ5.js";
31
+ } from "./chunk-I3GEFCKP.js";
32
32
  import "./chunk-3FEZSLGI.js";
33
33
  import "./chunk-HOSJZMQS.js";
34
34
  import "./chunk-BMLQPSHP.js";
35
- import "./chunk-J7IPNING.js";
35
+ import "./chunk-2R6Y5SJH.js";
36
36
  export {
37
37
  addMemoryEntry,
38
38
  backupMemoryStore,
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  countSeverity,
4
4
  runCi
5
- } from "./chunk-TKBWA3XJ.js";
6
- import "./chunk-P4FJBD2H.js";
5
+ } from "./chunk-ZDO3XCXL.js";
6
+ import "./chunk-LEA4AMXE.js";
7
7
  import {
8
8
  buildReviewPrompt,
9
9
  buildSecurityReviewPrompt,
@@ -14,16 +14,16 @@ import {
14
14
  } from "./chunk-6YZEZFX5.js";
15
15
  import {
16
16
  ProviderRegistry
17
- } from "./chunk-YAMPLTYO.js";
17
+ } from "./chunk-XVB4RARX.js";
18
18
  import {
19
19
  ConfigManager
20
- } from "./chunk-DB4HVUPI.js";
20
+ } from "./chunk-COHKPZ2E.js";
21
21
  import "./chunk-E2W2MI6H.js";
22
22
  import "./chunk-TU3L3PW7.js";
23
23
  import "./chunk-BMLQPSHP.js";
24
24
  import {
25
25
  VERSION
26
- } from "./chunk-J7IPNING.js";
26
+ } from "./chunk-2R6Y5SJH.js";
27
27
 
28
28
  // src/cli/pr.ts
29
29
  import { execFileSync } from "child_process";
@@ -2,9 +2,9 @@ import {
2
2
  executeTests,
3
3
  runTestProcess,
4
4
  runTestsTool
5
- } from "./chunk-N6YFBRQV.js";
5
+ } from "./chunk-JHSULP5D.js";
6
6
  import "./chunk-QMFMST2T.js";
7
- import "./chunk-SKQUWDRM.js";
7
+ import "./chunk-VEO2MILP.js";
8
8
  export {
9
9
  executeTests,
10
10
  runTestProcess,
@@ -3,8 +3,8 @@ import {
3
3
  executeTests,
4
4
  runTestProcess,
5
5
  runTestsTool
6
- } from "./chunk-NOAWUEJJ.js";
7
- import "./chunk-J7IPNING.js";
6
+ } from "./chunk-6XXHAS5B.js";
7
+ import "./chunk-2R6Y5SJH.js";
8
8
  import "./chunk-SXIJLSVF.js";
9
9
  export {
10
10
  executeTests,
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ToolRegistry
4
- } from "./chunk-46M65JDN.js";
4
+ } from "./chunk-6RCGQQFM.js";
5
5
  import "./chunk-6JHACXB3.js";
6
- import "./chunk-WY4IWCQ5.js";
6
+ import "./chunk-I3GEFCKP.js";
7
7
  import "./chunk-RWRZVQCB.js";
8
8
  import "./chunk-B3MPYI4E.js";
9
9
  import "./chunk-M6HLYG33.js";
@@ -14,7 +14,7 @@ import "./chunk-JL44HGZC.js";
14
14
  import "./chunk-3FEZSLGI.js";
15
15
  import {
16
16
  runTool
17
- } from "./chunk-5VZHSSLW.js";
17
+ } from "./chunk-VS43QMR2.js";
18
18
  import "./chunk-RS7SKYTS.js";
19
19
  import {
20
20
  getDangerLevel,
@@ -24,10 +24,10 @@ import "./chunk-TU3L3PW7.js";
24
24
  import "./chunk-HOSJZMQS.js";
25
25
  import "./chunk-BMLQPSHP.js";
26
26
  import "./chunk-JJFJWD35.js";
27
- import "./chunk-NOAWUEJJ.js";
27
+ import "./chunk-6XXHAS5B.js";
28
28
  import {
29
29
  VERSION
30
- } from "./chunk-J7IPNING.js";
30
+ } from "./chunk-2R6Y5SJH.js";
31
31
  import "./chunk-SXIJLSVF.js";
32
32
 
33
33
  // src/mcp/server.ts