jinzd-ai-cli 0.4.268 → 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-2N2YMRX2.js → batch-HUOYPVJQ.js} +2 -2
  2. package/dist/{chunk-UT2WAJJG.js → chunk-3TOMHXDW.js} +1 -1
  3. package/dist/{chunk-EPVJS4F6.js → chunk-4HTJMLFY.js} +1 -1
  4. package/dist/{chunk-VGVKJTHF.js → chunk-5IUFUCIT.js} +1 -1
  5. package/dist/{chunk-2FQGMR34.js → chunk-5PRWBJCI.js} +1 -1
  6. package/dist/{chunk-YLSM7RF6.js → chunk-6PROC2JO.js} +3 -3
  7. package/dist/{chunk-7US7K3CD.js → chunk-AAERHPBN.js} +1 -1
  8. package/dist/{chunk-74BK22BM.js → chunk-DJNGUPM3.js} +4 -4
  9. package/dist/{chunk-RRQZRSXW.js → chunk-KIHNZBEA.js} +1 -1
  10. package/dist/{chunk-XDITAGE5.js → chunk-NVN3FHXI.js} +1 -1
  11. package/dist/{chunk-WNG3YVZX.js → chunk-QPPUYCRF.js} +1 -1
  12. package/dist/{chunk-VNCBY4KY.js → chunk-S3F5LOV3.js} +162 -2
  13. package/dist/{chunk-WWLXW4SY.js → chunk-V6KQ67VF.js} +1 -1
  14. package/dist/{chunk-Z7CZ72RP.js → chunk-XJAGGJVU.js} +3 -3
  15. package/dist/{ci-3RWVJSZ3.js → ci-4QS2J7BG.js} +4 -4
  16. package/dist/{ci-format-M6HVCXCG.js → ci-format-6L6M67WC.js} +2 -2
  17. package/dist/{constants-G6VN7SJL.js → constants-IO5VJLEE.js} +1 -1
  18. package/dist/{doctor-cli-Y3SVVJBO.js → doctor-cli-ZU4E2DDL.js} +4 -4
  19. package/dist/electron-server.js +245 -48
  20. package/dist/{hub-5T5HKOAR.js → hub-AMDWXSKZ.js} +1 -1
  21. package/dist/index.js +64 -153
  22. package/dist/{persistent-memory-YBWIZWQP.js → persistent-memory-52SE5K44.js} +2 -2
  23. package/dist/{persistent-memory-XVSSR277.js → persistent-memory-H4DNDIOQ.js} +2 -2
  24. package/dist/{pr-NF5IWLH3.js → pr-Z4O5H6I3.js} +4 -4
  25. package/dist/{run-tests-33X3D7PV.js → run-tests-FZSYHWYX.js} +2 -2
  26. package/dist/{run-tests-Y44SCLIO.js → run-tests-PYKKYMPA.js} +2 -2
  27. package/dist/{server-NJ3ZNPQW.js → server-WTJSM2MT.js} +79 -31
  28. package/dist/{server-3LERX42X.js → server-ZSTVYSYC.js} +5 -5
  29. package/dist/{task-orchestrator-JN2WFZSF.js → task-orchestrator-PNLI3V36.js} +5 -5
  30. package/dist/{usage-IFTNXTWC.js → usage-GVFUVYUG.js} +2 -2
  31. package/package.json +1 -1
@@ -22,15 +22,19 @@ import {
22
22
  buildInitPrompt,
23
23
  buildSessionCostReport,
24
24
  costSourceNote,
25
+ decideModel,
25
26
  estimateConversationTokens,
26
27
  evaluateContextPressure,
28
+ filterMemoryEntries,
27
29
  loadDevState,
30
+ parseMemoryShowFilters,
28
31
  persistToolRound,
29
32
  readGitDiff,
30
33
  scanDirTree,
31
34
  scanProject,
32
- setupProxy
33
- } from "./chunk-VNCBY4KY.js";
35
+ setupProxy,
36
+ stripRoutingTags
37
+ } from "./chunk-S3F5LOV3.js";
34
38
  import {
35
39
  CostTracker,
36
40
  computeCost,
@@ -75,7 +79,7 @@ import {
75
79
  spawnAgentContext,
76
80
  truncateOutput,
77
81
  undoStack
78
- } from "./chunk-74BK22BM.js";
82
+ } from "./chunk-DJNGUPM3.js";
79
83
  import {
80
84
  addMemoryEntry,
81
85
  clearMemoryEntries,
@@ -85,11 +89,12 @@ import {
85
89
  formatMemoryForPrompt,
86
90
  isMemoryExpired,
87
91
  listMemoryEntries,
92
+ listOrphanedProjectMemories,
88
93
  memoryStorePath,
89
94
  parseWritableScope,
90
95
  updateMemoryApproval,
91
96
  updateMemoryEntry
92
- } from "./chunk-WNG3YVZX.js";
97
+ } from "./chunk-QPPUYCRF.js";
93
98
  import "./chunk-GLSR2NR3.js";
94
99
  import "./chunk-UUSRWSSX.js";
95
100
  import "./chunk-CKH4KQ4E.js";
@@ -103,13 +108,13 @@ import {
103
108
  buildDoctorReport,
104
109
  formatDoctorReport,
105
110
  loadContextFiles
106
- } from "./chunk-YLSM7RF6.js";
111
+ } from "./chunk-6PROC2JO.js";
107
112
  import {
108
113
  ProviderRegistry
109
114
  } from "./chunk-AUEX6RNY.js";
110
115
  import {
111
116
  ConfigManager
112
- } from "./chunk-VGVKJTHF.js";
117
+ } from "./chunk-5IUFUCIT.js";
113
118
  import {
114
119
  describePlugin,
115
120
  getActivePluginAssets,
@@ -124,7 +129,7 @@ import {
124
129
  runTool,
125
130
  setPluginEnabled,
126
131
  trustPlugin
127
- } from "./chunk-2FQGMR34.js";
132
+ } from "./chunk-5PRWBJCI.js";
128
133
  import {
129
134
  CONTENT_ONLY_STREAM_REMINDER,
130
135
  TEE_FINAL_USER_NUDGE,
@@ -149,7 +154,7 @@ import {
149
154
  getGitRoot
150
155
  } from "./chunk-HOSJZMQS.js";
151
156
  import "./chunk-4BKXL7SM.js";
152
- import "./chunk-WWLXW4SY.js";
157
+ import "./chunk-V6KQ67VF.js";
153
158
  import {
154
159
  AGENTIC_BEHAVIOR_GUIDELINE,
155
160
  AUTHOR,
@@ -165,7 +170,7 @@ import {
165
170
  SKILLS_DIR_NAME,
166
171
  VERSION,
167
172
  buildUserIdentityPrompt
168
- } from "./chunk-UT2WAJJG.js";
173
+ } from "./chunk-3TOMHXDW.js";
169
174
  import "./chunk-6RPGQ5CG.js";
170
175
  import "./chunk-KHYD3WXE.js";
171
176
  import "./chunk-NYNSYLFY.js";
@@ -845,7 +850,7 @@ Cache: write=${cacheCreate} read=${cacheRead}` : "";
845
850
  Cost: ${formatCost(cost)}` : "";
846
851
  let memoryLine = "";
847
852
  try {
848
- const { countPendingMemories } = await import("./persistent-memory-XVSSR277.js");
853
+ const { countPendingMemories } = await import("./persistent-memory-H4DNDIOQ.js");
849
854
  const pending = countPendingMemories(ctx.config.getConfigDir());
850
855
  if (pending > 0) memoryLine = `
851
856
  Memory: \u26A0 ${pending} pending approval \u2014 see the Memory panel or /memory`;
@@ -1658,7 +1663,7 @@ async function handleTest(args, ctx) {
1658
1663
  const isCommand = argStr.includes(" ") || /^(mvn|gradle|npm|pytest|cargo|go)\b/.test(argStr);
1659
1664
  testArgs = isCommand ? { command: argStr } : { filter: argStr };
1660
1665
  }
1661
- const runTests = ctx.runTests ?? (await import("./run-tests-33X3D7PV.js")).executeTests;
1666
+ const runTests = ctx.runTests ?? (await import("./run-tests-FZSYHWYX.js")).executeTests;
1662
1667
  const report = await runTests(testArgs);
1663
1668
  ctx.send({ type: "info", message: report });
1664
1669
  } catch (err) {
@@ -1916,7 +1921,7 @@ async function handleMemory(args, ctx) {
1916
1921
  ctx.handleMemoryManage(sub, args[1], sub === "expire" ? args[2] : void 0);
1917
1922
  } else if (sub === "export") {
1918
1923
  if (args[1] === "md") {
1919
- const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-XVSSR277.js");
1924
+ const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-H4DNDIOQ.js");
1920
1925
  ctx.send({
1921
1926
  type: "export_data",
1922
1927
  format: "md",
@@ -1936,7 +1941,8 @@ async function handleMemory(args, ctx) {
1936
1941
  });
1937
1942
  }
1938
1943
  } else {
1939
- ctx.memoryShow();
1944
+ const isShow = sub === "show" || sub === "view" || sub === "list";
1945
+ ctx.memoryShow(isShow ? args.slice(1) : args);
1940
1946
  }
1941
1947
  }
1942
1948
  async function handleAddDir(args, ctx) {
@@ -2386,17 +2392,18 @@ var SessionHandler = class {
2386
2392
  sessionAccruedCostUsd = 0;
2387
2393
  sessionCostIncomplete = false;
2388
2394
  /** Accumulate a TokenUsage (with optional cache fields) into sessionTokenUsage. */
2389
- addWebSessionUsage(u) {
2395
+ addWebSessionUsage(u, modelOverride) {
2396
+ const usageModel = modelOverride ?? this.currentModel;
2390
2397
  this.sessionTokenUsage.inputTokens += u.inputTokens;
2391
2398
  this.sessionTokenUsage.outputTokens += u.outputTokens;
2392
2399
  this.sessionTokenUsage.cacheCreationTokens += u.cacheCreationTokens ?? 0;
2393
2400
  this.sessionTokenUsage.cacheReadTokens += u.cacheReadTokens ?? 0;
2394
- const priced = this.costTracker.addCost(this.currentProvider, this.currentModel, u);
2401
+ const priced = this.costTracker.addCost(this.currentProvider, usageModel, u);
2395
2402
  if (priced === null) this.sessionCostIncomplete = true;
2396
2403
  else this.sessionAccruedCostUsd += priced;
2397
2404
  const totalTokens = u.inputTokens + u.outputTokens + (u.cacheCreationTokens ?? 0) + (u.cacheReadTokens ?? 0);
2398
- if (totalTokens > 0 && !getPricing(this.currentProvider, this.currentModel)) {
2399
- const key = `${this.currentProvider}/${this.currentModel}`;
2405
+ if (totalTokens > 0 && !getPricing(this.currentProvider, usageModel)) {
2406
+ const key = `${this.currentProvider}/${usageModel}`;
2400
2407
  if (!this.unknownPricingWarnings.has(key)) {
2401
2408
  this.unknownPricingWarnings.add(key);
2402
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.` });
@@ -2844,6 +2851,16 @@ var SessionHandler = class {
2844
2851
  } else {
2845
2852
  msgContent = content;
2846
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
+ }
2847
2864
  const userMessage = { role: "user", content: msgContent, timestamp: /* @__PURE__ */ new Date() };
2848
2865
  session.addMessage(userMessage);
2849
2866
  const provider = this.providers.get(this.currentProvider);
@@ -2855,11 +2872,13 @@ var SessionHandler = class {
2855
2872
  const hasToolSupport = typeof provider.chatWithTools === "function";
2856
2873
  const { toolDefs, mcpBudgetNote } = hasToolSupport ? this.getFilteredToolDefs() : { toolDefs: [], mcpBudgetNote: null };
2857
2874
  if (hasToolSupport && toolDefs.length > 0) {
2858
- await this.handleChatWithTools(provider, session.messages, toolDefs, mcpBudgetNote);
2875
+ await this.handleChatWithTools(provider, session.messages, toolDefs, mcpBudgetNote, routingDecision.model);
2859
2876
  } else {
2860
- await this.handleChatSimple(provider, session.messages);
2877
+ await this.handleChatSimple(provider, session.messages, routingDecision.model);
2861
2878
  }
2862
2879
  await this.checkContextPressure();
2880
+ const budgetWarning = this.costTracker.checkBudget(this.config.get("monthlyBudget"));
2881
+ if (budgetWarning) this.send({ type: "info", message: `\u26A0 ${budgetWarning}` });
2863
2882
  } catch (err) {
2864
2883
  const parts = [];
2865
2884
  let current = err;
@@ -2878,8 +2897,9 @@ var SessionHandler = class {
2878
2897
  this.sendSessionList();
2879
2898
  }
2880
2899
  }
2881
- async handleChatSimple(provider, messages) {
2900
+ async handleChatSimple(provider, messages, modelOverride) {
2882
2901
  const session = this.sessions.current;
2902
+ const effectiveModel = modelOverride ?? this.currentModel;
2883
2903
  const modelParams = this.getModelParams();
2884
2904
  const ac = new AbortController();
2885
2905
  this.abortController = ac;
@@ -2887,7 +2907,7 @@ var SessionHandler = class {
2887
2907
  const { stable: simplStable, volatile: simplVolatile } = this.buildSystemPrompt();
2888
2908
  const stream = provider.chatStream({
2889
2909
  messages,
2890
- model: this.currentModel,
2910
+ model: effectiveModel,
2891
2911
  systemPrompt: simplStable,
2892
2912
  systemPromptVolatile: simplVolatile,
2893
2913
  stream: true,
@@ -2906,7 +2926,7 @@ var SessionHandler = class {
2906
2926
  if (chunk.done) {
2907
2927
  this.send({ type: "response_done", content: fullContent, usage: chunk.usage });
2908
2928
  if (chunk.usage) {
2909
- this.addWebSessionUsage(chunk.usage);
2929
+ this.addWebSessionUsage(chunk.usage, effectiveModel);
2910
2930
  session.addTokenUsage(chunk.usage);
2911
2931
  }
2912
2932
  if (chunk.reasoningContent) simpleReasoning = chunk.reasoningContent;
@@ -2931,8 +2951,9 @@ var SessionHandler = class {
2931
2951
  this.abortController = null;
2932
2952
  }
2933
2953
  }
2934
- async handleChatWithTools(provider, messages, toolDefs, mcpBudgetNote) {
2954
+ async handleChatWithTools(provider, messages, toolDefs, mcpBudgetNote, modelOverride) {
2935
2955
  const session = this.sessions.current;
2956
+ const effectiveModel = modelOverride ?? this.currentModel;
2936
2957
  const apiMessages = [...messages];
2937
2958
  const maxToolRounds = this.config.get("maxToolRounds") ?? DEFAULT_MAX_TOOL_ROUNDS;
2938
2959
  const autoPauseIntervalRaw = this.config.get("autoPauseInterval");
@@ -2962,7 +2983,7 @@ ${mcpBudgetNote}` : "");
2962
2983
  callModel: async (_round, extraMessages) => {
2963
2984
  const chatRequest = {
2964
2985
  messages: apiMessages,
2965
- model: this.currentModel,
2986
+ model: effectiveModel,
2966
2987
  systemPrompt,
2967
2988
  systemPromptVolatile,
2968
2989
  stream: false,
@@ -3007,7 +3028,7 @@ Details: ${errMsg.split("\n")[0]}
3007
3028
  const summaryResult = await provider.chatWithTools(
3008
3029
  {
3009
3030
  messages: apiMessages,
3010
- model: this.currentModel,
3031
+ model: effectiveModel,
3011
3032
  systemPrompt,
3012
3033
  systemPromptVolatile,
3013
3034
  stream: false,
@@ -3023,7 +3044,7 @@ Details: ${errMsg.split("\n")[0]}
3023
3044
  executeTools: async (toolCalls) => {
3024
3045
  googleSearchContext.configManager = this.config;
3025
3046
  spawnAgentContext.provider = provider;
3026
- spawnAgentContext.model = this.currentModel;
3047
+ spawnAgentContext.model = effectiveModel;
3027
3048
  spawnAgentContext.systemPrompt = systemPromptVolatile ? `${systemPrompt}
3028
3049
 
3029
3050
  ---
@@ -3397,6 +3418,24 @@ ${summaryContent}`,
3397
3418
  * 到达上下文压力阈值时自动压缩(与 REPL 同一判据,见 core/context-pressure.ts)。
3398
3419
  * 上下文窗口未知时不动——不基于猜测改用户的对话历史。
3399
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
+ }
3400
3439
  async checkContextPressure() {
3401
3440
  const contextWindow = this.getContextWindowSize();
3402
3441
  const session = this.sessions.current;
@@ -3559,18 +3598,27 @@ ${summaryContent}`,
3559
3598
  });
3560
3599
  }
3561
3600
  }
3562
- memoryShow() {
3601
+ memoryShow(args = []) {
3563
3602
  const configDir = this.config.getConfigDir();
3564
- const entries = listMemoryEntries(configDir, { includeExpired: true, includeRejected: true });
3565
- 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) => {
3566
3614
  const status = isMemoryExpired(entry) ? "expired" : entry.approved ? "approved" : "pending";
3567
- const source = [
3615
+ const source2 = [
3568
3616
  entry.source ?? "unknown",
3569
3617
  entry.sourceSession ? `session ${entry.sourceSession.slice(0, 8)}` : "",
3570
3618
  entry.sourceProject ? `project ${entry.sourceProject}` : ""
3571
3619
  ].filter(Boolean).join(" \xB7 ");
3572
3620
  return `## ${entry.id.slice(0, 8)} \xB7 ${status} \xB7 scope:${entry.scope} \xB7 sensitivity:${entry.sensitivity}
3573
- Source: ${source}
3621
+ Source: ${source2}
3574
3622
  ${entry.content}`;
3575
3623
  }).join("\n\n");
3576
3624
  this.send({
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ToolRegistry
4
- } from "./chunk-74BK22BM.js";
5
- import "./chunk-WNG3YVZX.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-2FQGMR34.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-WWLXW4SY.js";
21
+ import "./chunk-V6KQ67VF.js";
22
22
  import {
23
23
  VERSION
24
- } from "./chunk-UT2WAJJG.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-74BK22BM.js";
7
- import "./chunk-WNG3YVZX.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-2FQGMR34.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-WWLXW4SY.js";
23
+ import "./chunk-V6KQ67VF.js";
24
24
  import {
25
25
  SUBAGENT_ALLOWED_TOOLS
26
- } from "./chunk-UT2WAJJG.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-VGVKJTHF.js";
9
+ } from "./chunk-5IUFUCIT.js";
10
10
  import "./chunk-TU3L3PW7.js";
11
- import "./chunk-UT2WAJJG.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.268",
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",