jinzd-ai-cli 0.4.267 → 0.4.269

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 (31) hide show
  1. package/dist/{batch-GY5MAN5F.js → batch-HUOYPVJQ.js} +2 -2
  2. package/dist/{chunk-THHPKZJ3.js → chunk-3TOMHXDW.js} +1 -1
  3. package/dist/{chunk-7HECI3U5.js → chunk-4HTJMLFY.js} +3 -1
  4. package/dist/{chunk-EWRZMIQE.js → chunk-5IUFUCIT.js} +1 -1
  5. package/dist/{chunk-WPN7LDLM.js → chunk-5PRWBJCI.js} +1 -1
  6. package/dist/{chunk-QN7WD2SM.js → chunk-6PROC2JO.js} +3 -3
  7. package/dist/{chunk-6C6FLDGH.js → chunk-AAERHPBN.js} +1 -1
  8. package/dist/{chunk-5AEOIETL.js → chunk-DJNGUPM3.js} +4 -4
  9. package/dist/{chunk-FI6IWUXW.js → chunk-KIHNZBEA.js} +1 -1
  10. package/dist/{chunk-ARYCWJN6.js → chunk-NVN3FHXI.js} +1 -1
  11. package/dist/{chunk-RVNL7MQG.js → chunk-QPPUYCRF.js} +1 -1
  12. package/dist/{chunk-JH343BDI.js → chunk-S3F5LOV3.js} +313 -2
  13. package/dist/{chunk-XLLUQEGO.js → chunk-V6KQ67VF.js} +1 -1
  14. package/dist/{chunk-5CU72V6P.js → chunk-XJAGGJVU.js} +3 -3
  15. package/dist/{ci-MUEQSNKU.js → ci-4QS2J7BG.js} +4 -4
  16. package/dist/{ci-format-2ZGGSOFK.js → ci-format-6L6M67WC.js} +2 -2
  17. package/dist/{constants-SZTJESDF.js → constants-IO5VJLEE.js} +1 -1
  18. package/dist/{doctor-cli-Z272364P.js → doctor-cli-ZU4E2DDL.js} +4 -4
  19. package/dist/electron-server.js +455 -58
  20. package/dist/{hub-MRLGKMRI.js → hub-AMDWXSKZ.js} +1 -1
  21. package/dist/index.js +117 -245
  22. package/dist/{persistent-memory-3FTOC7QT.js → persistent-memory-52SE5K44.js} +2 -2
  23. package/dist/{persistent-memory-HZASMDJQ.js → persistent-memory-H4DNDIOQ.js} +2 -2
  24. package/dist/{pr-VLLIALRK.js → pr-Z4O5H6I3.js} +4 -4
  25. package/dist/{run-tests-NTDZ6DDU.js → run-tests-FZSYHWYX.js} +2 -2
  26. package/dist/{run-tests-6MWE6D5S.js → run-tests-PYKKYMPA.js} +2 -2
  27. package/dist/{server-IALCWKSU.js → server-WTJSM2MT.js} +147 -41
  28. package/dist/{server-SP3AEHRQ.js → server-ZSTVYSYC.js} +5 -5
  29. package/dist/{task-orchestrator-Q6WFFI4J.js → task-orchestrator-PNLI3V36.js} +5 -5
  30. package/dist/{usage-DJDLHICZ.js → usage-GVFUVYUG.js} +2 -2
  31. package/package.json +1 -1
@@ -27,9 +27,9 @@ import {
27
27
  touchMemoryReferences,
28
28
  updateMemoryApproval,
29
29
  updateMemoryEntry
30
- } from "./chunk-FI6IWUXW.js";
30
+ } from "./chunk-KIHNZBEA.js";
31
31
  import "./chunk-YVTASHS5.js";
32
- import "./chunk-7HECI3U5.js";
32
+ import "./chunk-4HTJMLFY.js";
33
33
  import "./chunk-6BUTA5VW.js";
34
34
  export {
35
35
  addMemoryEntry,
@@ -28,9 +28,9 @@ import {
28
28
  touchMemoryReferences,
29
29
  updateMemoryApproval,
30
30
  updateMemoryEntry
31
- } from "./chunk-RVNL7MQG.js";
31
+ } from "./chunk-QPPUYCRF.js";
32
32
  import "./chunk-HOSJZMQS.js";
33
- import "./chunk-THHPKZJ3.js";
33
+ import "./chunk-3TOMHXDW.js";
34
34
  import "./chunk-B5TYJO7V.js";
35
35
  import "./chunk-IW3Q7AE5.js";
36
36
  export {
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  countSeverity,
4
4
  runCi
5
- } from "./chunk-5CU72V6P.js";
6
- import "./chunk-6C6FLDGH.js";
5
+ } from "./chunk-XJAGGJVU.js";
6
+ import "./chunk-AAERHPBN.js";
7
7
  import {
8
8
  buildReviewPrompt,
9
9
  buildSecurityReviewPrompt,
@@ -17,12 +17,12 @@ import {
17
17
  } from "./chunk-AUEX6RNY.js";
18
18
  import {
19
19
  ConfigManager
20
- } from "./chunk-EWRZMIQE.js";
20
+ } from "./chunk-5IUFUCIT.js";
21
21
  import "./chunk-3OBY7WSS.js";
22
22
  import "./chunk-TU3L3PW7.js";
23
23
  import {
24
24
  VERSION
25
- } from "./chunk-THHPKZJ3.js";
25
+ } from "./chunk-3TOMHXDW.js";
26
26
  import "./chunk-IW3Q7AE5.js";
27
27
 
28
28
  // src/cli/pr.ts
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  executeTests,
4
4
  runTestsTool
5
- } from "./chunk-XLLUQEGO.js";
6
- import "./chunk-THHPKZJ3.js";
5
+ } from "./chunk-V6KQ67VF.js";
6
+ import "./chunk-3TOMHXDW.js";
7
7
  export {
8
8
  executeTests,
9
9
  runTestsTool
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  executeTests,
3
3
  runTestsTool
4
- } from "./chunk-ARYCWJN6.js";
5
- import "./chunk-7HECI3U5.js";
4
+ } from "./chunk-NVN3FHXI.js";
5
+ import "./chunk-4HTJMLFY.js";
6
6
  export {
7
7
  executeTests,
8
8
  runTestsTool
@@ -13,20 +13,28 @@ import {
13
13
  TOKEN_EXPIRY_MS
14
14
  } from "./chunk-RYQBBEMM.js";
15
15
  import {
16
+ AUTO_COMPACT_INSTRUCTION,
16
17
  McpManager,
17
18
  SkillManager,
19
+ applyProfileCommand,
18
20
  applyThinkCommand,
19
21
  autoTrimSessionIfNeeded,
20
22
  buildInitPrompt,
21
23
  buildSessionCostReport,
22
24
  costSourceNote,
25
+ decideModel,
26
+ estimateConversationTokens,
27
+ evaluateContextPressure,
28
+ filterMemoryEntries,
23
29
  loadDevState,
30
+ parseMemoryShowFilters,
24
31
  persistToolRound,
25
32
  readGitDiff,
26
33
  scanDirTree,
27
34
  scanProject,
28
- setupProxy
29
- } from "./chunk-JH343BDI.js";
35
+ setupProxy,
36
+ stripRoutingTags
37
+ } from "./chunk-S3F5LOV3.js";
30
38
  import {
31
39
  CostTracker,
32
40
  computeCost,
@@ -71,7 +79,7 @@ import {
71
79
  spawnAgentContext,
72
80
  truncateOutput,
73
81
  undoStack
74
- } from "./chunk-5AEOIETL.js";
82
+ } from "./chunk-DJNGUPM3.js";
75
83
  import {
76
84
  addMemoryEntry,
77
85
  clearMemoryEntries,
@@ -81,11 +89,12 @@ import {
81
89
  formatMemoryForPrompt,
82
90
  isMemoryExpired,
83
91
  listMemoryEntries,
92
+ listOrphanedProjectMemories,
84
93
  memoryStorePath,
85
94
  parseWritableScope,
86
95
  updateMemoryApproval,
87
96
  updateMemoryEntry
88
- } from "./chunk-RVNL7MQG.js";
97
+ } from "./chunk-QPPUYCRF.js";
89
98
  import "./chunk-GLSR2NR3.js";
90
99
  import "./chunk-UUSRWSSX.js";
91
100
  import "./chunk-CKH4KQ4E.js";
@@ -99,13 +108,13 @@ import {
99
108
  buildDoctorReport,
100
109
  formatDoctorReport,
101
110
  loadContextFiles
102
- } from "./chunk-QN7WD2SM.js";
111
+ } from "./chunk-6PROC2JO.js";
103
112
  import {
104
113
  ProviderRegistry
105
114
  } from "./chunk-AUEX6RNY.js";
106
115
  import {
107
116
  ConfigManager
108
- } from "./chunk-EWRZMIQE.js";
117
+ } from "./chunk-5IUFUCIT.js";
109
118
  import {
110
119
  describePlugin,
111
120
  getActivePluginAssets,
@@ -120,7 +129,7 @@ import {
120
129
  runTool,
121
130
  setPluginEnabled,
122
131
  trustPlugin
123
- } from "./chunk-WPN7LDLM.js";
132
+ } from "./chunk-5PRWBJCI.js";
124
133
  import {
125
134
  CONTENT_ONLY_STREAM_REMINDER,
126
135
  TEE_FINAL_USER_NUDGE,
@@ -145,7 +154,7 @@ import {
145
154
  getGitRoot
146
155
  } from "./chunk-HOSJZMQS.js";
147
156
  import "./chunk-4BKXL7SM.js";
148
- import "./chunk-XLLUQEGO.js";
157
+ import "./chunk-V6KQ67VF.js";
149
158
  import {
150
159
  AGENTIC_BEHAVIOR_GUIDELINE,
151
160
  AUTHOR,
@@ -161,7 +170,7 @@ import {
161
170
  SKILLS_DIR_NAME,
162
171
  VERSION,
163
172
  buildUserIdentityPrompt
164
- } from "./chunk-THHPKZJ3.js";
173
+ } from "./chunk-3TOMHXDW.js";
165
174
  import "./chunk-6RPGQ5CG.js";
166
175
  import "./chunk-KHYD3WXE.js";
167
176
  import "./chunk-NYNSYLFY.js";
@@ -787,6 +796,12 @@ async function handlePlan(args, ctx) {
787
796
  } else if (sub === "execute") {
788
797
  ctx.planMode = false;
789
798
  ctx.send({ type: "info", message: "Plan mode OFF. Executing with all tools enabled." });
799
+ } else if (sub === "status" || sub === "show") {
800
+ ctx.send({ type: "info", message: `Plan mode: ${ctx.planMode ? "ON (read-only tools only)" : "OFF"}` });
801
+ return;
802
+ } else if (sub !== void 0) {
803
+ ctx.send({ type: "error", message: `Unknown /plan option "${sub}" \u2014 expected execute | exit | status` });
804
+ return;
790
805
  } else {
791
806
  ctx.planMode = !ctx.planMode;
792
807
  ctx.send({ type: "info", message: `Plan mode: ${ctx.planMode ? "ON (read-only tools only)" : "OFF"}` });
@@ -835,7 +850,7 @@ Cache: write=${cacheCreate} read=${cacheRead}` : "";
835
850
  Cost: ${formatCost(cost)}` : "";
836
851
  let memoryLine = "";
837
852
  try {
838
- const { countPendingMemories } = await import("./persistent-memory-HZASMDJQ.js");
853
+ const { countPendingMemories } = await import("./persistent-memory-H4DNDIOQ.js");
839
854
  const pending = countPendingMemories(ctx.config.getConfigDir());
840
855
  if (pending > 0) memoryLine = `
841
856
  Memory: \u26A0 ${pending} pending approval \u2014 see the Memory panel or /memory`;
@@ -1648,7 +1663,7 @@ async function handleTest(args, ctx) {
1648
1663
  const isCommand = argStr.includes(" ") || /^(mvn|gradle|npm|pytest|cargo|go)\b/.test(argStr);
1649
1664
  testArgs = isCommand ? { command: argStr } : { filter: argStr };
1650
1665
  }
1651
- const runTests = ctx.runTests ?? (await import("./run-tests-NTDZ6DDU.js")).executeTests;
1666
+ const runTests = ctx.runTests ?? (await import("./run-tests-FZSYHWYX.js")).executeTests;
1652
1667
  const report = await runTests(testArgs);
1653
1668
  ctx.send({ type: "info", message: report });
1654
1669
  } catch (err) {
@@ -1906,7 +1921,7 @@ async function handleMemory(args, ctx) {
1906
1921
  ctx.handleMemoryManage(sub, args[1], sub === "expire" ? args[2] : void 0);
1907
1922
  } else if (sub === "export") {
1908
1923
  if (args[1] === "md") {
1909
- const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-HZASMDJQ.js");
1924
+ const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-H4DNDIOQ.js");
1910
1925
  ctx.send({
1911
1926
  type: "export_data",
1912
1927
  format: "md",
@@ -1926,7 +1941,8 @@ async function handleMemory(args, ctx) {
1926
1941
  });
1927
1942
  }
1928
1943
  } else {
1929
- ctx.memoryShow();
1944
+ const isShow = sub === "show" || sub === "view" || sub === "list";
1945
+ ctx.memoryShow(isShow ? args.slice(1) : args);
1930
1946
  }
1931
1947
  }
1932
1948
  async function handleAddDir(args, ctx) {
@@ -2018,6 +2034,18 @@ async function handleBug(_args, ctx) {
2018
2034
  ];
2019
2035
  ctx.send({ type: "info", message: lines.join("\n") });
2020
2036
  }
2037
+ async function handleProfile(args, ctx) {
2038
+ const outcome = applyProfileCommand(args, ctx.config.get("userProfile") ?? {});
2039
+ if (outcome.profile) {
2040
+ ctx.config.set("userProfile", outcome.profile);
2041
+ ctx.config.save();
2042
+ }
2043
+ const lines = [outcome.summary];
2044
+ for (const [label, value] of outcome.rows) lines.push(` ${label}: ${value}`);
2045
+ for (const line of outcome.details) lines.push(line);
2046
+ ctx.send({ type: outcome.isError ? "error" : "info", message: lines.join("\n") });
2047
+ if (outcome.changed) ctx.sendStatus();
2048
+ }
2021
2049
 
2022
2050
  // src/web/commands/agent-commands.ts
2023
2051
  async function handleAuto(args, ctx) {
@@ -2061,6 +2089,17 @@ async function handlePermissions(args, ctx) {
2061
2089
  }
2062
2090
  async function handleYolo(args, ctx) {
2063
2091
  const sub = args[0]?.toLowerCase();
2092
+ if (sub === "status") {
2093
+ ctx.send({
2094
+ type: "info",
2095
+ message: `YOLO mode: ${ctx.toolExecutor.sessionAutoApprove ? "ON (write tools auto-approved)" : "OFF"}`
2096
+ });
2097
+ return;
2098
+ }
2099
+ if (sub !== void 0 && sub !== "on" && sub !== "off") {
2100
+ ctx.send({ type: "error", message: `Unknown /yolo option "${sub}" \u2014 expected on | off | status` });
2101
+ return;
2102
+ }
2064
2103
  if (sub === "off") {
2065
2104
  ctx.toolExecutor.sessionAutoApprove = false;
2066
2105
  ctx.send({ type: "info", message: "\u{1F512} Auto-approve disabled \u2014 confirmations restored for this session." });
@@ -2272,14 +2311,17 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
2272
2311
  }
2273
2312
 
2274
2313
  // src/web/session-handler.ts
2275
- var CLI_ONLY_WEB_COMMANDS = /* @__PURE__ */ new Set([
2276
- "copy",
2277
- "paste",
2278
- "exit",
2279
- "quit",
2280
- "snapshot",
2281
- "hooks",
2282
- "hook"
2314
+ var CLI_ONLY_WEB_COMMANDS = /* @__PURE__ */ new Map([
2315
+ ["copy", "It copies to the terminal clipboard; use your browser/OS copy instead."],
2316
+ ["paste", "It reads the terminal clipboard; paste directly into the composer instead."],
2317
+ ["exit", "Close the browser tab to end this Web session."],
2318
+ ["quit", "Close the browser tab to end this Web session."],
2319
+ ["snapshot", "Dev-state snapshots are written when the terminal REPL exits."],
2320
+ ["hooks", "Hook trust is granted per machine from the terminal."],
2321
+ ["hook", "Hook trust is granted per machine from the terminal."],
2322
+ // 以下两条并非「终端才有意义」,而是 Web 侧尚未实现——如实说明,别假装是设计。
2323
+ ["route", "Smart model routing is not applied to Web sessions yet (config.routing is REPL-only)."],
2324
+ ["security", "Redaction status and toggles are terminal-only for now; /status shows the current profile."]
2283
2325
  ]);
2284
2326
  var webCommandHandlers = {
2285
2327
  provider: handleProvider,
@@ -2315,6 +2357,7 @@ var webCommandHandlers = {
2315
2357
  config: handleConfig,
2316
2358
  doctor: handleDoctor,
2317
2359
  bug: handleBug,
2360
+ profile: handleProfile,
2318
2361
  auto: handleAuto,
2319
2362
  permissions: handlePermissions,
2320
2363
  yolo: handleYolo,
@@ -2349,17 +2392,18 @@ var SessionHandler = class {
2349
2392
  sessionAccruedCostUsd = 0;
2350
2393
  sessionCostIncomplete = false;
2351
2394
  /** Accumulate a TokenUsage (with optional cache fields) into sessionTokenUsage. */
2352
- addWebSessionUsage(u) {
2395
+ addWebSessionUsage(u, modelOverride) {
2396
+ const usageModel = modelOverride ?? this.currentModel;
2353
2397
  this.sessionTokenUsage.inputTokens += u.inputTokens;
2354
2398
  this.sessionTokenUsage.outputTokens += u.outputTokens;
2355
2399
  this.sessionTokenUsage.cacheCreationTokens += u.cacheCreationTokens ?? 0;
2356
2400
  this.sessionTokenUsage.cacheReadTokens += u.cacheReadTokens ?? 0;
2357
- const priced = this.costTracker.addCost(this.currentProvider, this.currentModel, u);
2401
+ const priced = this.costTracker.addCost(this.currentProvider, usageModel, u);
2358
2402
  if (priced === null) this.sessionCostIncomplete = true;
2359
2403
  else this.sessionAccruedCostUsd += priced;
2360
2404
  const totalTokens = u.inputTokens + u.outputTokens + (u.cacheCreationTokens ?? 0) + (u.cacheReadTokens ?? 0);
2361
- if (totalTokens > 0 && !getPricing(this.currentProvider, this.currentModel)) {
2362
- const key = `${this.currentProvider}/${this.currentModel}`;
2405
+ if (totalTokens > 0 && !getPricing(this.currentProvider, usageModel)) {
2406
+ const key = `${this.currentProvider}/${usageModel}`;
2363
2407
  if (!this.unknownPricingWarnings.has(key)) {
2364
2408
  this.unknownPricingWarnings.add(key);
2365
2409
  this.send({ type: "info", message: `Cost notice: pricing is unknown for ${key}. Tokens are tracked, but cost is excluded from totals. Run /cost or aicli usage to review.` });
@@ -2807,6 +2851,16 @@ var SessionHandler = class {
2807
2851
  } else {
2808
2852
  msgContent = content;
2809
2853
  }
2854
+ const routingDecision = this.computeRoutingDecision(typeof msgContent === "string" ? msgContent : content);
2855
+ if (typeof msgContent === "string") {
2856
+ msgContent = stripRoutingTags(msgContent);
2857
+ } else if (msgContent.length > 0 && msgContent[msgContent.length - 1]?.type === "text") {
2858
+ const last = msgContent[msgContent.length - 1];
2859
+ msgContent = [...msgContent.slice(0, -1), { type: "text", text: stripRoutingTags(last.text) }];
2860
+ }
2861
+ if (routingDecision.overridden) {
2862
+ this.send({ type: "info", message: `\u2192 Routed to ${routingDecision.model} (${routingDecision.reason})` });
2863
+ }
2810
2864
  const userMessage = { role: "user", content: msgContent, timestamp: /* @__PURE__ */ new Date() };
2811
2865
  session.addMessage(userMessage);
2812
2866
  const provider = this.providers.get(this.currentProvider);
@@ -2818,10 +2872,13 @@ var SessionHandler = class {
2818
2872
  const hasToolSupport = typeof provider.chatWithTools === "function";
2819
2873
  const { toolDefs, mcpBudgetNote } = hasToolSupport ? this.getFilteredToolDefs() : { toolDefs: [], mcpBudgetNote: null };
2820
2874
  if (hasToolSupport && toolDefs.length > 0) {
2821
- await this.handleChatWithTools(provider, session.messages, toolDefs, mcpBudgetNote);
2875
+ await this.handleChatWithTools(provider, session.messages, toolDefs, mcpBudgetNote, routingDecision.model);
2822
2876
  } else {
2823
- await this.handleChatSimple(provider, session.messages);
2877
+ await this.handleChatSimple(provider, session.messages, routingDecision.model);
2824
2878
  }
2879
+ await this.checkContextPressure();
2880
+ const budgetWarning = this.costTracker.checkBudget(this.config.get("monthlyBudget"));
2881
+ if (budgetWarning) this.send({ type: "info", message: `\u26A0 ${budgetWarning}` });
2825
2882
  } catch (err) {
2826
2883
  const parts = [];
2827
2884
  let current = err;
@@ -2840,8 +2897,9 @@ var SessionHandler = class {
2840
2897
  this.sendSessionList();
2841
2898
  }
2842
2899
  }
2843
- async handleChatSimple(provider, messages) {
2900
+ async handleChatSimple(provider, messages, modelOverride) {
2844
2901
  const session = this.sessions.current;
2902
+ const effectiveModel = modelOverride ?? this.currentModel;
2845
2903
  const modelParams = this.getModelParams();
2846
2904
  const ac = new AbortController();
2847
2905
  this.abortController = ac;
@@ -2849,7 +2907,7 @@ var SessionHandler = class {
2849
2907
  const { stable: simplStable, volatile: simplVolatile } = this.buildSystemPrompt();
2850
2908
  const stream = provider.chatStream({
2851
2909
  messages,
2852
- model: this.currentModel,
2910
+ model: effectiveModel,
2853
2911
  systemPrompt: simplStable,
2854
2912
  systemPromptVolatile: simplVolatile,
2855
2913
  stream: true,
@@ -2868,7 +2926,7 @@ var SessionHandler = class {
2868
2926
  if (chunk.done) {
2869
2927
  this.send({ type: "response_done", content: fullContent, usage: chunk.usage });
2870
2928
  if (chunk.usage) {
2871
- this.addWebSessionUsage(chunk.usage);
2929
+ this.addWebSessionUsage(chunk.usage, effectiveModel);
2872
2930
  session.addTokenUsage(chunk.usage);
2873
2931
  }
2874
2932
  if (chunk.reasoningContent) simpleReasoning = chunk.reasoningContent;
@@ -2893,8 +2951,9 @@ var SessionHandler = class {
2893
2951
  this.abortController = null;
2894
2952
  }
2895
2953
  }
2896
- async handleChatWithTools(provider, messages, toolDefs, mcpBudgetNote) {
2954
+ async handleChatWithTools(provider, messages, toolDefs, mcpBudgetNote, modelOverride) {
2897
2955
  const session = this.sessions.current;
2956
+ const effectiveModel = modelOverride ?? this.currentModel;
2898
2957
  const apiMessages = [...messages];
2899
2958
  const maxToolRounds = this.config.get("maxToolRounds") ?? DEFAULT_MAX_TOOL_ROUNDS;
2900
2959
  const autoPauseIntervalRaw = this.config.get("autoPauseInterval");
@@ -2924,7 +2983,7 @@ ${mcpBudgetNote}` : "");
2924
2983
  callModel: async (_round, extraMessages) => {
2925
2984
  const chatRequest = {
2926
2985
  messages: apiMessages,
2927
- model: this.currentModel,
2986
+ model: effectiveModel,
2928
2987
  systemPrompt,
2929
2988
  systemPromptVolatile,
2930
2989
  stream: false,
@@ -2969,7 +3028,7 @@ Details: ${errMsg.split("\n")[0]}
2969
3028
  const summaryResult = await provider.chatWithTools(
2970
3029
  {
2971
3030
  messages: apiMessages,
2972
- model: this.currentModel,
3031
+ model: effectiveModel,
2973
3032
  systemPrompt,
2974
3033
  systemPromptVolatile,
2975
3034
  stream: false,
@@ -2985,7 +3044,7 @@ Details: ${errMsg.split("\n")[0]}
2985
3044
  executeTools: async (toolCalls) => {
2986
3045
  googleSearchContext.configManager = this.config;
2987
3046
  spawnAgentContext.provider = provider;
2988
- spawnAgentContext.model = this.currentModel;
3047
+ spawnAgentContext.model = effectiveModel;
2989
3048
  spawnAgentContext.systemPrompt = systemPromptVolatile ? `${systemPrompt}
2990
3049
 
2991
3050
  ---
@@ -3340,10 +3399,11 @@ ${summaryContent}`,
3340
3399
  }
3341
3400
  // ── Commands ─────────────────────────────────────────────────────
3342
3401
  async handleCommand(name, args) {
3343
- if (CLI_ONLY_WEB_COMMANDS.has(name)) {
3402
+ const cliOnlyReason = CLI_ONLY_WEB_COMMANDS.get(name);
3403
+ if (cliOnlyReason) {
3344
3404
  this.send({
3345
3405
  type: "error",
3346
- message: `/${name} is only available in the terminal REPL. Run \`aicli\` in a terminal and use /${name} there.`
3406
+ message: `/${name} is not available in the Web UI. ${cliOnlyReason}`
3347
3407
  });
3348
3408
  return;
3349
3409
  }
@@ -3354,6 +3414,43 @@ ${summaryContent}`,
3354
3414
  this.send({ type: "error", message: `Unknown command: /${name}. Type /help for available commands.` });
3355
3415
  }
3356
3416
  }
3417
+ /**
3418
+ * 到达上下文压力阈值时自动压缩(与 REPL 同一判据,见 core/context-pressure.ts)。
3419
+ * 上下文窗口未知时不动——不基于猜测改用户的对话历史。
3420
+ */
3421
+ /**
3422
+ * 智能模型路由决策(审计附录 D-5)。候选限定在当前 provider 注册的模型内——
3423
+ * 跨 provider 换模型会破坏 API key 与对话连续性。
3424
+ */
3425
+ computeRoutingDecision(userInput) {
3426
+ let availableModels = [];
3427
+ try {
3428
+ availableModels = this.providers.get(this.currentProvider).info.models.map((m) => m.id);
3429
+ } catch {
3430
+ availableModels = [];
3431
+ }
3432
+ return decideModel({
3433
+ userInput,
3434
+ currentModel: this.currentModel,
3435
+ routingConfig: this.config.get("routing"),
3436
+ availableModels
3437
+ });
3438
+ }
3439
+ async checkContextPressure() {
3440
+ const contextWindow = this.getContextWindowSize();
3441
+ const session = this.sessions.current;
3442
+ const pressure = evaluateContextPressure({
3443
+ autoCompactEnabled: this.config.get("autoCompact") === true,
3444
+ estimatedTokens: contextWindow > 0 && session ? estimateConversationTokens({ systemPrompt: this.activeSystemPrompt, messages: session.messages }) : 0,
3445
+ contextWindow
3446
+ });
3447
+ if (!pressure.shouldCompact) return;
3448
+ this.send({
3449
+ type: "info",
3450
+ message: `\u26A0 Context pressure: ~${pressure.percent}% of the ${contextWindow.toLocaleString()}-token window used. Auto-compacting\u2026`
3451
+ });
3452
+ await this.compactSession(AUTO_COMPACT_INSTRUCTION);
3453
+ }
3357
3454
  async compactSession(instruction) {
3358
3455
  const session = this.sessions.current;
3359
3456
  if (!session || session.messages.length < 6) {
@@ -3501,18 +3598,27 @@ ${summaryContent}`,
3501
3598
  });
3502
3599
  }
3503
3600
  }
3504
- memoryShow() {
3601
+ memoryShow(args = []) {
3505
3602
  const configDir = this.config.getConfigDir();
3506
- const entries = listMemoryEntries(configDir, { includeExpired: true, includeRejected: true });
3507
- const content = entries.length === 0 ? "(empty \u2014 no persistent memory entries yet)" : entries.map((entry) => {
3603
+ const filters = parseMemoryShowFilters(args);
3604
+ if (filters.invalidStale) {
3605
+ this.send({ type: "error", message: "Usage: /memory show --stale <days> (positive number)" });
3606
+ return;
3607
+ }
3608
+ const source = filters.orphaned ? listOrphanedProjectMemories(configDir) : listMemoryEntries(configDir, { includeExpired: true, includeRejected: true });
3609
+ const { entries, applied } = filterMemoryEntries(source, filters);
3610
+ const filterNote = applied.length > 0 ? ` (filtered: ${applied.join(", ")})` : "";
3611
+ const content = entries.length === 0 ? applied.length > 0 ? `(no entries match [${applied.join(", ")}])` : "(empty \u2014 no persistent memory entries yet)" : `Governed persistent memory${filterNote}
3612
+
3613
+ ` + entries.map((entry) => {
3508
3614
  const status = isMemoryExpired(entry) ? "expired" : entry.approved ? "approved" : "pending";
3509
- const source = [
3615
+ const source2 = [
3510
3616
  entry.source ?? "unknown",
3511
3617
  entry.sourceSession ? `session ${entry.sourceSession.slice(0, 8)}` : "",
3512
3618
  entry.sourceProject ? `project ${entry.sourceProject}` : ""
3513
3619
  ].filter(Boolean).join(" \xB7 ");
3514
3620
  return `## ${entry.id.slice(0, 8)} \xB7 ${status} \xB7 scope:${entry.scope} \xB7 sensitivity:${entry.sensitivity}
3515
- Source: ${source}
3621
+ Source: ${source2}
3516
3622
  ${entry.content}`;
3517
3623
  }).join("\n\n");
3518
3624
  this.send({
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ToolRegistry
4
- } from "./chunk-5AEOIETL.js";
5
- import "./chunk-RVNL7MQG.js";
4
+ } from "./chunk-DJNGUPM3.js";
5
+ import "./chunk-QPPUYCRF.js";
6
6
  import "./chunk-GLSR2NR3.js";
7
7
  import "./chunk-UUSRWSSX.js";
8
8
  import "./chunk-CKH4KQ4E.js";
@@ -10,7 +10,7 @@ import "./chunk-BXP6YZ2P.js";
10
10
  import "./chunk-5C76XDDF.js";
11
11
  import {
12
12
  runTool
13
- } from "./chunk-WPN7LDLM.js";
13
+ } from "./chunk-5PRWBJCI.js";
14
14
  import {
15
15
  getDangerLevel,
16
16
  schemaToJsonSchema
@@ -18,10 +18,10 @@ import {
18
18
  import "./chunk-TU3L3PW7.js";
19
19
  import "./chunk-HOSJZMQS.js";
20
20
  import "./chunk-4BKXL7SM.js";
21
- import "./chunk-XLLUQEGO.js";
21
+ import "./chunk-V6KQ67VF.js";
22
22
  import {
23
23
  VERSION
24
- } from "./chunk-THHPKZJ3.js";
24
+ } from "./chunk-3TOMHXDW.js";
25
25
  import "./chunk-6RPGQ5CG.js";
26
26
  import "./chunk-KHYD3WXE.js";
27
27
  import "./chunk-NYNSYLFY.js";
@@ -3,8 +3,8 @@ import {
3
3
  ToolRegistry,
4
4
  googleSearchContext,
5
5
  truncateOutput
6
- } from "./chunk-5AEOIETL.js";
7
- import "./chunk-RVNL7MQG.js";
6
+ } from "./chunk-DJNGUPM3.js";
7
+ import "./chunk-QPPUYCRF.js";
8
8
  import "./chunk-GLSR2NR3.js";
9
9
  import "./chunk-UUSRWSSX.js";
10
10
  import "./chunk-CKH4KQ4E.js";
@@ -12,7 +12,7 @@ import "./chunk-BXP6YZ2P.js";
12
12
  import "./chunk-5C76XDDF.js";
13
13
  import {
14
14
  runTool
15
- } from "./chunk-WPN7LDLM.js";
15
+ } from "./chunk-5PRWBJCI.js";
16
16
  import {
17
17
  getDangerLevel,
18
18
  runLeanAgentLoop
@@ -20,10 +20,10 @@ import {
20
20
  import "./chunk-TU3L3PW7.js";
21
21
  import "./chunk-HOSJZMQS.js";
22
22
  import "./chunk-4BKXL7SM.js";
23
- import "./chunk-XLLUQEGO.js";
23
+ import "./chunk-V6KQ67VF.js";
24
24
  import {
25
25
  SUBAGENT_ALLOWED_TOOLS
26
- } from "./chunk-THHPKZJ3.js";
26
+ } from "./chunk-3TOMHXDW.js";
27
27
  import "./chunk-6RPGQ5CG.js";
28
28
  import "./chunk-KHYD3WXE.js";
29
29
  import "./chunk-NYNSYLFY.js";
@@ -6,9 +6,9 @@ import {
6
6
  } from "./chunk-R7GERZDA.js";
7
7
  import {
8
8
  ConfigManager
9
- } from "./chunk-EWRZMIQE.js";
9
+ } from "./chunk-5IUFUCIT.js";
10
10
  import "./chunk-TU3L3PW7.js";
11
- import "./chunk-THHPKZJ3.js";
11
+ import "./chunk-3TOMHXDW.js";
12
12
  import "./chunk-IW3Q7AE5.js";
13
13
 
14
14
  // src/cli/usage.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jinzd-ai-cli",
3
- "version": "0.4.267",
3
+ "version": "0.4.269",
4
4
  "description": "Cross-platform REPL-style AI CLI with multi-provider support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",