jinzd-ai-cli 0.4.277 → 0.4.278

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-2I5TPZA2.js → batch-7Y4NAA6N.js} +2 -2
  2. package/dist/{chunk-OCOGYIRY.js → chunk-2BYQP6JX.js} +1 -1
  3. package/dist/{chunk-I3PYD2YN.js → chunk-4Z6GAYB5.js} +3 -3
  4. package/dist/{chunk-HCF442WL.js → chunk-H7QC5VMQ.js} +1 -1
  5. package/dist/{chunk-HJVKCOAG.js → chunk-JJCNNQTU.js} +183 -3
  6. package/dist/{chunk-UWQCTTP4.js → chunk-L3CPM472.js} +1 -1
  7. package/dist/{chunk-BYNNKJUC.js → chunk-LOXEYWC3.js} +1 -1
  8. package/dist/{chunk-7IPMONKZ.js → chunk-LTZFUYBT.js} +3 -3
  9. package/dist/{chunk-7YYUITED.js → chunk-LXXQTWT2.js} +1 -1
  10. package/dist/{chunk-7BO5H2QI.js → chunk-RFSKPCYC.js} +1 -1
  11. package/dist/{chunk-3VFOXEIL.js → chunk-SB4XONS4.js} +1 -1
  12. package/dist/{chunk-Z752LDYF.js → chunk-SJCOE4C7.js} +1 -1
  13. package/dist/{chunk-KIGKL3PZ.js → chunk-WOXIKQRI.js} +4 -4
  14. package/dist/{chunk-ZP3RCZKM.js → chunk-X3722RFA.js} +1 -1
  15. package/dist/{ci-JFC45LIS.js → ci-WDF2CYR4.js} +4 -4
  16. package/dist/{ci-format-P3LIZHUR.js → ci-format-7B5VAZGA.js} +2 -2
  17. package/dist/{constants-N3CHKZJY.js → constants-DC3TNLTL.js} +1 -1
  18. package/dist/{doctor-cli-Z3TGHTSX.js → doctor-cli-CDDG5XOY.js} +4 -4
  19. package/dist/electron-server.js +307 -49
  20. package/dist/{hub-NEWIFMQ3.js → hub-TO7ODOIA.js} +1 -1
  21. package/dist/index.js +150 -162
  22. package/dist/{persistent-memory-6Q5FDFJ7.js → persistent-memory-BU63CSGK.js} +2 -2
  23. package/dist/{persistent-memory-ZFR5GI7D.js → persistent-memory-JCENBMCJ.js} +2 -2
  24. package/dist/{pr-ZUGSWQ5R.js → pr-GVSZYX6I.js} +4 -4
  25. package/dist/{run-tests-USV7IJ7X.js → run-tests-2Q5MJHXB.js} +2 -2
  26. package/dist/{run-tests-76M6AC3G.js → run-tests-R4IQS6IF.js} +2 -2
  27. package/dist/{server-C523CIGN.js → server-KAURBKFI.js} +148 -54
  28. package/dist/{server-R7D5RR36.js → server-WXLE53HG.js} +5 -5
  29. package/dist/{task-orchestrator-G2MQDNGQ.js → task-orchestrator-RJ6FXYY5.js} +5 -5
  30. package/dist/{usage-EFHXXMYX.js → usage-V3R7DA7M.js} +2 -2
  31. package/dist/web/client/app.js +4 -1
  32. package/dist/web/client/app.js.br +0 -0
  33. package/dist/web/client/app.js.gz +0 -0
  34. package/package.json +1 -1
@@ -16,6 +16,7 @@ import {
16
16
  AUTO_COMPACT_INSTRUCTION,
17
17
  McpManager,
18
18
  SkillManager,
19
+ applyPlanCommand,
19
20
  applyProfileCommand,
20
21
  applyThinkCommand,
21
22
  armDeferredSave,
@@ -25,19 +26,26 @@ import {
25
26
  costSourceNote,
26
27
  decideDeferredSave,
27
28
  decideModel,
29
+ describeRouting,
28
30
  estimateConversationTokens,
29
31
  evaluateContextPressure,
30
32
  filterMemoryEntries,
31
33
  loadDevState,
32
34
  parseMemoryShowFilters,
35
+ parseModelCommand,
36
+ parseRouteCommand,
33
37
  persistToolRound,
34
38
  readGitDiff,
39
+ resolveModelSwitch,
40
+ resolveProviderSwitch,
41
+ routeDecisionRows,
42
+ routingEmptyRulesNote,
35
43
  scanDirTree,
36
44
  scanProject,
37
45
  setupProxy,
38
46
  snapshotFile,
39
47
  stripRoutingTags
40
- } from "./chunk-HJVKCOAG.js";
48
+ } from "./chunk-JJCNNQTU.js";
41
49
  import {
42
50
  CNY_PER_USD,
43
51
  CostTracker,
@@ -79,7 +87,7 @@ import {
79
87
  spawnAgentContext,
80
88
  truncateOutput,
81
89
  undoStack
82
- } from "./chunk-KIGKL3PZ.js";
90
+ } from "./chunk-WOXIKQRI.js";
83
91
  import {
84
92
  buildReviewPrompt,
85
93
  buildSecurityReviewPrompt
@@ -106,7 +114,7 @@ import {
106
114
  restoreMemoryEntries,
107
115
  updateMemoryApproval,
108
116
  updateMemoryEntry
109
- } from "./chunk-7BO5H2QI.js";
117
+ } from "./chunk-RFSKPCYC.js";
110
118
  import "./chunk-4DEMGCK4.js";
111
119
  import "./chunk-UUSRWSSX.js";
112
120
  import "./chunk-CKH4KQ4E.js";
@@ -125,7 +133,7 @@ import {
125
133
  buildDoctorReport,
126
134
  formatDoctorReport,
127
135
  loadContextFiles
128
- } from "./chunk-7IPMONKZ.js";
136
+ } from "./chunk-LTZFUYBT.js";
129
137
  import {
130
138
  describePlugin,
131
139
  getActivePluginAssets,
@@ -140,13 +148,13 @@ import {
140
148
  runTool,
141
149
  setPluginEnabled,
142
150
  trustPlugin
143
- } from "./chunk-UWQCTTP4.js";
151
+ } from "./chunk-L3CPM472.js";
144
152
  import {
145
153
  ProviderRegistry
146
154
  } from "./chunk-UGY5SVNX.js";
147
155
  import {
148
156
  ConfigManager
149
- } from "./chunk-OCOGYIRY.js";
157
+ } from "./chunk-2BYQP6JX.js";
150
158
  import {
151
159
  CONTENT_ONLY_STREAM_REMINDER,
152
160
  TEE_FINAL_USER_NUDGE,
@@ -176,7 +184,7 @@ import {
176
184
  maskConfigSecrets
177
185
  } from "./chunk-XNFIYS7G.js";
178
186
  import "./chunk-4BKXL7SM.js";
179
- import "./chunk-3VFOXEIL.js";
187
+ import "./chunk-SB4XONS4.js";
180
188
  import {
181
189
  AGENTIC_BEHAVIOR_GUIDELINE,
182
190
  AUTHOR,
@@ -192,7 +200,7 @@ import {
192
200
  SKILLS_DIR_NAME,
193
201
  VERSION,
194
202
  buildUserIdentityPrompt
195
- } from "./chunk-ZP3RCZKM.js";
203
+ } from "./chunk-X3722RFA.js";
196
204
 
197
205
  // src/web/server.ts
198
206
  import express from "express";
@@ -721,47 +729,86 @@ import { mkdirSync as mkdirSync2, createWriteStream as createWriteStream2 } from
721
729
  import { dirname as dirname2 } from "path";
722
730
 
723
731
  // src/web/commands/provider-commands.ts
732
+ function syncSessionProvider(ctx) {
733
+ const session = ctx.sessions.current;
734
+ if (!session) return;
735
+ session.updateProvider(ctx.currentProvider, ctx.currentModel);
736
+ ctx.saveIfNeeded();
737
+ }
724
738
  async function handleProvider(args, ctx) {
725
739
  const id = args[0];
726
740
  if (!id) {
727
741
  ctx.send({ type: "error", message: "Usage: /provider <id>" });
728
742
  return;
729
743
  }
730
- const p = ctx.providers.get(id);
731
- if (!p) {
732
- ctx.send({ type: "error", message: `Provider "${id}" not available` });
744
+ const configured = ctx.providers.has(id);
745
+ let availableModels = [];
746
+ let providerDefaultModel = "";
747
+ if (configured) {
748
+ const target = ctx.providers.get(id);
749
+ providerDefaultModel = target.info.defaultModel;
750
+ availableModels = target.info.models.map((m) => m.id);
751
+ if (availableModels.length === 0) {
752
+ try {
753
+ availableModels = (await target.listModels()).map((m) => m.id);
754
+ } catch {
755
+ availableModels = [];
756
+ }
757
+ }
758
+ }
759
+ const outcome = resolveProviderSwitch({
760
+ targetId: id,
761
+ currentProvider: ctx.currentProvider,
762
+ configured,
763
+ availableModels,
764
+ configuredDefaultModel: ctx.config.get("defaultModels")[id],
765
+ providerDefaultModel,
766
+ messageCount: ctx.sessions.current?.messages.length ?? 0
767
+ });
768
+ if (outcome.status === "not-configured" || outcome.status === "no-models") {
769
+ ctx.send({ type: "error", message: outcome.message });
770
+ return;
771
+ }
772
+ if (outcome.status === "unchanged") {
773
+ ctx.send({ type: "info", message: outcome.message });
733
774
  return;
734
775
  }
735
- ctx.currentProvider = id;
736
- ctx.currentModel = p.info.defaultModel;
776
+ ctx.currentProvider = outcome.providerId;
777
+ ctx.currentModel = outcome.model;
737
778
  ctx.updateContextWindow();
738
- ctx.send({ type: "info", message: `Switched to provider: ${id} (${ctx.currentModel})` });
779
+ syncSessionProvider(ctx);
780
+ ctx.send({ type: "info", message: outcome.message });
739
781
  ctx.sendStatus();
740
782
  }
741
783
  async function handleModel(args, ctx) {
742
- const sub = args[0];
743
- if (!sub) {
784
+ const intent = parseModelCommand(args, ctx.currentProvider);
785
+ if (intent.kind === "select") {
744
786
  ctx.send({ type: "error", message: "Usage: /model <id>|refresh [provider]|cache [clear [provider]]" });
745
787
  return;
746
788
  }
747
- if (sub === "refresh") {
748
- const providerId = args[1] ?? ctx.currentProvider;
789
+ if (intent.kind === "refresh") {
790
+ if (!ctx.providers.has(intent.providerId)) {
791
+ ctx.send({ type: "error", message: `Provider is not configured: ${intent.providerId}` });
792
+ return;
793
+ }
749
794
  try {
750
- const models2 = await ctx.providers.refreshModels(providerId);
751
- ctx.send({ type: "info", message: `Refreshed ${models2.length} model(s) for ${providerId}.` });
795
+ const models2 = await ctx.providers.refreshModels(intent.providerId);
796
+ ctx.send({ type: "info", message: `Refreshed ${models2.length} model(s) for ${intent.providerId}.` });
752
797
  ctx.sendStatus();
753
798
  } catch (err) {
754
799
  ctx.send({ type: "error", message: `Model refresh failed: ${err instanceof Error ? err.message : String(err)}` });
755
800
  }
756
801
  return;
757
802
  }
758
- if (sub === "cache") {
759
- if ((args[1] ?? "").toLowerCase() === "clear") {
760
- const providerId = args[2];
761
- ctx.providers.clearModelCache(providerId);
762
- ctx.send({ type: "info", message: providerId ? `Cleared model cache for ${providerId}.` : "Cleared model cache." });
763
- return;
764
- }
803
+ if (intent.kind === "cache-clear") {
804
+ ctx.providers.clearModelCache(intent.providerId);
805
+ ctx.send({
806
+ type: "info",
807
+ message: intent.providerId ? `Cleared model cache for ${intent.providerId}.` : "Cleared model cache."
808
+ });
809
+ return;
810
+ }
811
+ if (intent.kind === "cache-show") {
765
812
  const rows = ctx.providers.getModelCacheStatus();
766
813
  ctx.send({
767
814
  type: "info",
@@ -769,16 +816,25 @@ async function handleModel(args, ctx) {
769
816
  });
770
817
  return;
771
818
  }
772
- const modelId = sub;
773
819
  const models = await ctx.providers.listModels(ctx.currentProvider);
774
- const found = models.find((m) => m.id === modelId);
775
- if (!found) {
776
- ctx.send({ type: "error", message: `Model "${modelId}" not found` });
820
+ const outcome = resolveModelSwitch({
821
+ targetModel: intent.modelId,
822
+ currentModel: ctx.currentModel,
823
+ provider: ctx.currentProvider,
824
+ knownModels: models.map((m) => m.id),
825
+ messageCount: ctx.sessions.current?.messages.length ?? 0
826
+ });
827
+ if (outcome.status === "unchanged") {
828
+ ctx.send({ type: "info", message: outcome.message });
777
829
  return;
778
830
  }
779
- ctx.currentModel = modelId;
831
+ ctx.currentModel = outcome.model;
780
832
  ctx.updateContextWindow();
781
- ctx.send({ type: "info", message: `Switched to model: ${modelId}` });
833
+ syncSessionProvider(ctx);
834
+ ctx.send({
835
+ type: "info",
836
+ message: outcome.warning ? `${outcome.message} \u2014 ${outcome.warning}` : outcome.message
837
+ });
782
838
  ctx.sendStatus();
783
839
  }
784
840
  async function handleThink(args, ctx) {
@@ -788,7 +844,7 @@ async function handleThink(args, ctx) {
788
844
  runtimeEffort: ctx.runtimeThinkingEffort,
789
845
  configuredThinking: modelParams?.thinking,
790
846
  configuredEffort: modelParams?.thinkingEffort,
791
- supportsEffort: ctx.providers.get(ctx.currentProvider)?.supportsReasoningEffort ?? false,
847
+ supportsEffort: ctx.providers.has(ctx.currentProvider) ? ctx.providers.get(ctx.currentProvider).supportsReasoningEffort : false,
792
848
  provider: ctx.currentProvider
793
849
  });
794
850
  if (outcome.changed) {
@@ -802,24 +858,59 @@ async function handleThink(args, ctx) {
802
858
  if (outcome.changed) ctx.sendStatus();
803
859
  }
804
860
  async function handlePlan(args, ctx) {
805
- const sub = args[0];
806
- if (sub === "exit" || sub === "cancel") {
807
- ctx.planMode = false;
808
- ctx.send({ type: "info", message: "Plan mode OFF." });
809
- } else if (sub === "execute") {
810
- ctx.planMode = false;
811
- ctx.send({ type: "info", message: "Plan mode OFF. Executing with all tools enabled." });
812
- } else if (sub === "status" || sub === "show") {
813
- ctx.send({ type: "info", message: `Plan mode: ${ctx.planMode ? "ON (read-only tools only)" : "OFF"}` });
861
+ const outcome = applyPlanCommand(args[0], ctx.planMode);
862
+ if (outcome.changed) ctx.planMode = outcome.planMode;
863
+ ctx.send({
864
+ type: outcome.status === "unknown" ? "error" : "info",
865
+ message: [outcome.summary, ...outcome.details].join(" \u2014 ")
866
+ });
867
+ if (outcome.changed) ctx.sendStatus();
868
+ }
869
+ async function handleRoute(args, ctx) {
870
+ const intent = parseRouteCommand(args);
871
+ const routing = ctx.config.get("routing");
872
+ if (intent.kind === "enable" || intent.kind === "disable") {
873
+ const on = intent.kind === "enable";
874
+ ctx.config.setByPath("routing.enabled", on ? "true" : "false");
875
+ const note = on ? routingEmptyRulesNote(routing) : null;
876
+ ctx.send({
877
+ type: "info",
878
+ message: `Smart model routing ${on ? "enabled" : "disabled"}.` + (note ? `
879
+ ${note}` : "")
880
+ });
881
+ ctx.sendStatus();
814
882
  return;
815
- } else if (sub !== void 0) {
816
- ctx.send({ type: "error", message: `Unknown /plan option "${sub}" \u2014 expected execute | exit | status` });
883
+ }
884
+ if (intent.kind === "usage" || intent.kind === "unknown") {
885
+ ctx.send({ type: "error", message: intent.message });
886
+ return;
887
+ }
888
+ if (intent.kind === "test") {
889
+ const decision = ctx.computeRoutingDecision(intent.message);
890
+ ctx.send({
891
+ type: "info",
892
+ message: routeDecisionRows(intent.message, ctx.currentModel, decision).map((row) => `${row.label}: ${row.value}`).join("\n")
893
+ });
817
894
  return;
895
+ }
896
+ const view = describeRouting({ routing, provider: ctx.currentProvider, currentModel: ctx.currentModel });
897
+ const lines = [
898
+ "Smart Model Routing",
899
+ `Status: ${view.enabled ? "enabled" : "disabled"}`,
900
+ `Provider: ${view.provider}`,
901
+ `Current: ${view.currentModel}`
902
+ ];
903
+ if (view.fallback) lines.push(`Fallback: ${view.fallback}`);
904
+ if (view.noRulesNote) {
905
+ lines.push(view.noRulesNote);
818
906
  } else {
819
- ctx.planMode = !ctx.planMode;
820
- ctx.send({ type: "info", message: `Plan mode: ${ctx.planMode ? "ON (read-only tools only)" : "OFF"}` });
907
+ lines.push("Rules (evaluated top-to-bottom):");
908
+ for (const rule of view.rules) {
909
+ lines.push(` #${rule.index} ${rule.name ? `${rule.name} ` : ""}${rule.condition} \u2192 ${rule.model}`);
910
+ }
821
911
  }
822
- ctx.sendStatus();
912
+ lines.push(view.hint);
913
+ ctx.send({ type: "info", message: lines.join("\n") });
823
914
  }
824
915
 
825
916
  // src/web/commands/_shared.ts
@@ -863,7 +954,7 @@ Cache: write=${cacheCreate} read=${cacheRead}` : "";
863
954
  Cost: ${formatCost(cost)}` : "";
864
955
  let memoryLine = "";
865
956
  try {
866
- const { countPendingMemories: countPendingMemories2 } = await import("./persistent-memory-6Q5FDFJ7.js");
957
+ const { countPendingMemories: countPendingMemories2 } = await import("./persistent-memory-BU63CSGK.js");
867
958
  const pending = countPendingMemories2(ctx.config.getConfigDir());
868
959
  if (pending > 0) memoryLine = `
869
960
  Memory: \u26A0 ${pending} pending approval \u2014 see the Memory panel or /memory`;
@@ -1676,7 +1767,7 @@ async function handleTest(args, ctx) {
1676
1767
  const isCommand = argStr.includes(" ") || /^(mvn|gradle|npm|pytest|cargo|go)\b/.test(argStr);
1677
1768
  testArgs = isCommand ? { command: argStr } : { filter: argStr };
1678
1769
  }
1679
- const runTests = ctx.runTests ?? (await import("./run-tests-76M6AC3G.js")).executeTests;
1770
+ const runTests = ctx.runTests ?? (await import("./run-tests-R4IQS6IF.js")).executeTests;
1680
1771
  const report = await runTests(testArgs);
1681
1772
  ctx.send({ type: "info", message: report });
1682
1773
  } catch (err) {
@@ -2012,7 +2103,7 @@ async function handleMemory(args, ctx) {
2012
2103
  ctx.handleMemoryManage(sub, args[1], sub === "expire" ? args[2] : void 0);
2013
2104
  } else if (sub === "export") {
2014
2105
  if (args[1] === "md") {
2015
- const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-6Q5FDFJ7.js");
2106
+ const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-BU63CSGK.js");
2016
2107
  ctx.send({
2017
2108
  type: "export_data",
2018
2109
  format: "md",
@@ -2266,7 +2357,8 @@ async function handleHelp(_args, ctx) {
2266
2357
  " /clear \u2014 Clear conversation & start new session",
2267
2358
  " /compact [hint] \u2014 Compress conversation history",
2268
2359
  " /think [on|off] \u2014 Toggle extended thinking mode",
2269
- " /plan [enter|exit] \u2014 Toggle read-only planning mode",
2360
+ " /plan [execute|exit|status] \u2014 Read-only planning mode (bare /plan enters it)",
2361
+ " /route [on|off|show|test <msg>] \u2014 Smart model routing",
2270
2362
  " /session new|list|load|delete <id> \u2014 Session management",
2271
2363
  " /system [prompt|clear] \u2014 Set/view/reset system prompt",
2272
2364
  " /context [status|reload] \u2014 Show/reload context layers",
@@ -2403,8 +2495,9 @@ var CLI_ONLY_WEB_COMMANDS = /* @__PURE__ */ new Map([
2403
2495
  ["snapshot", "Dev-state snapshots are written when the terminal REPL exits."],
2404
2496
  ["hooks", "Hook trust is granted per machine from the terminal."],
2405
2497
  ["hook", "Hook trust is granted per machine from the terminal."],
2406
- // 以下两条并非「终端才有意义」,而是 Web 侧尚未实现——如实说明,别假装是设计。
2407
- ["route", "Smart model routing is not applied to Web sessions yet (config.routing is REPL-only)."],
2498
+ // 以下一条并非「终端才有意义」,而是 Web 侧尚未实现——如实说明,别假装是设计。
2499
+ // (`route` 曾在这里,理由写的是「Web 尚未应用智能路由」;v0.4.269 让 routing 在 Web
2500
+ // 上真正生效之后那句话就不再成立,命令已在 Web 实现,见 commands/provider-commands.ts。)
2408
2501
  ["security", "Redaction status and toggles are terminal-only for now; /status shows the current profile."]
2409
2502
  ]);
2410
2503
  var webCommandHandlers = {
@@ -2412,6 +2505,7 @@ var webCommandHandlers = {
2412
2505
  model: handleModel,
2413
2506
  think: handleThink,
2414
2507
  plan: handlePlan,
2508
+ route: handleRoute,
2415
2509
  clear: handleClear,
2416
2510
  compact: handleCompact,
2417
2511
  status: handleStatus,
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ToolRegistry
4
- } from "./chunk-KIGKL3PZ.js";
4
+ } from "./chunk-WOXIKQRI.js";
5
5
  import "./chunk-GHWZVPUV.js";
6
- import "./chunk-7BO5H2QI.js";
6
+ import "./chunk-RFSKPCYC.js";
7
7
  import "./chunk-4DEMGCK4.js";
8
8
  import "./chunk-UUSRWSSX.js";
9
9
  import "./chunk-CKH4KQ4E.js";
@@ -14,7 +14,7 @@ import "./chunk-NYNSYLFY.js";
14
14
  import "./chunk-3FEZSLGI.js";
15
15
  import {
16
16
  runTool
17
- } from "./chunk-UWQCTTP4.js";
17
+ } from "./chunk-L3CPM472.js";
18
18
  import {
19
19
  getDangerLevel,
20
20
  schemaToJsonSchema
@@ -23,10 +23,10 @@ import "./chunk-TU3L3PW7.js";
23
23
  import "./chunk-HOSJZMQS.js";
24
24
  import "./chunk-IW3Q7AE5.js";
25
25
  import "./chunk-4BKXL7SM.js";
26
- import "./chunk-3VFOXEIL.js";
26
+ import "./chunk-SB4XONS4.js";
27
27
  import {
28
28
  VERSION
29
- } from "./chunk-ZP3RCZKM.js";
29
+ } from "./chunk-X3722RFA.js";
30
30
 
31
31
  // src/mcp/server.ts
32
32
  import { createInterface } from "readline";
@@ -4,9 +4,9 @@ import {
4
4
  googleSearchContext,
5
5
  isToolCapableProvider,
6
6
  truncateOutput
7
- } from "./chunk-KIGKL3PZ.js";
7
+ } from "./chunk-WOXIKQRI.js";
8
8
  import "./chunk-GHWZVPUV.js";
9
- import "./chunk-7BO5H2QI.js";
9
+ import "./chunk-RFSKPCYC.js";
10
10
  import "./chunk-4DEMGCK4.js";
11
11
  import "./chunk-UUSRWSSX.js";
12
12
  import "./chunk-CKH4KQ4E.js";
@@ -17,7 +17,7 @@ import "./chunk-NYNSYLFY.js";
17
17
  import "./chunk-3FEZSLGI.js";
18
18
  import {
19
19
  runTool
20
- } from "./chunk-UWQCTTP4.js";
20
+ } from "./chunk-L3CPM472.js";
21
21
  import {
22
22
  getDangerLevel,
23
23
  runLeanAgentLoop
@@ -28,10 +28,10 @@ import {
28
28
  atomicWriteFileSync
29
29
  } from "./chunk-IW3Q7AE5.js";
30
30
  import "./chunk-4BKXL7SM.js";
31
- import "./chunk-3VFOXEIL.js";
31
+ import "./chunk-SB4XONS4.js";
32
32
  import {
33
33
  SUBAGENT_ALLOWED_TOOLS
34
- } from "./chunk-ZP3RCZKM.js";
34
+ } from "./chunk-X3722RFA.js";
35
35
 
36
36
  // src/hub/task-orchestrator.ts
37
37
  import { createInterface } from "readline";
@@ -8,10 +8,10 @@ import {
8
8
  } from "./chunk-DPTEC6AQ.js";
9
9
  import {
10
10
  ConfigManager
11
- } from "./chunk-OCOGYIRY.js";
11
+ } from "./chunk-2BYQP6JX.js";
12
12
  import "./chunk-TU3L3PW7.js";
13
13
  import "./chunk-IW3Q7AE5.js";
14
- import "./chunk-ZP3RCZKM.js";
14
+ import "./chunk-X3722RFA.js";
15
15
 
16
16
  // src/cli/usage.ts
17
17
  function classifyRowCost(row) {
@@ -994,7 +994,10 @@ btnThink.addEventListener('click', () => {
994
994
  });
995
995
 
996
996
  btnPlan.addEventListener('click', () => {
997
- send({ type: 'command', name: 'plan', args: [] });
997
+ // 显式发 toggle:裸 /plan 的语义两端相反(REPL 是「进入」,Web 是切换),已统一为
998
+ // 「进入」,按钮则改用明写的 toggle 由**服务端**按自己的状态翻转——不能拿客户端的
999
+ // active class 当真相,它来自 status 帧,多标签页/换会话时会过期(实测撞到过)。
1000
+ send({ type: 'command', name: 'plan', args: ['toggle'] });
998
1001
  });
999
1002
 
1000
1003
  providerSelect.addEventListener('change', () => {
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jinzd-ai-cli",
3
- "version": "0.4.277",
3
+ "version": "0.4.278",
4
4
  "description": "Cross-platform REPL-style AI CLI with multi-provider support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",