jinzd-ai-cli 0.4.307 → 0.4.309

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 (96) hide show
  1. package/README.md +2 -1
  2. package/README.zh-CN.md +1 -1
  3. package/THIRD_PARTY_NOTICES.md +3 -0
  4. package/dist/{agent-client-6GX6QQDU.js → agent-client-TIEAYZXV.js} +4 -1
  5. package/dist/{auth-PE3Z5OHS.js → auth-QTQNZ6IX.js} +2 -2
  6. package/dist/{batch-HMADXNOD.js → batch-H4WWSZQ3.js} +3 -3
  7. package/dist/{chat-index-2D5GK2DB.js → chat-index-7CLR4CBG.js} +4 -3
  8. package/dist/{chat-index-DGUOUUQW.js → chat-index-RLVLQRRC.js} +3 -2
  9. package/dist/{chunk-CIM2PV2F.js → chunk-2E5W2E64.js} +2 -2
  10. package/dist/chunk-2XMUCC42.js +67 -0
  11. package/dist/{chunk-VAV2IJ3R.js → chunk-3CNPJLVI.js} +1 -1
  12. package/dist/{chunk-KRCYR46A.js → chunk-3GEO2LPO.js} +264 -55
  13. package/dist/{chunk-OAXLMF3U.js → chunk-3YVNDYOY.js} +1 -1
  14. package/dist/{chunk-5GQL4TSZ.js → chunk-4BXTGXZ6.js} +2 -2
  15. package/dist/{chunk-RYQBBEMM.js → chunk-4PR5AVJ5.js} +115 -19
  16. package/dist/{chunk-GHWZVPUV.js → chunk-6JHACXB3.js} +7 -5
  17. package/dist/{chunk-IUVDZVZ4.js → chunk-AXTLYOA7.js} +24 -17
  18. package/dist/{chunk-XJOK5353.js → chunk-B3MPYI4E.js} +2 -2
  19. package/dist/chunk-BMLQPSHP.js +69 -0
  20. package/dist/{chunk-NRSYBKWA.js → chunk-C7CKDFJS.js} +1 -1
  21. package/dist/{chunk-SJFZPS65.js → chunk-EAVX3RLD.js} +1 -1
  22. package/dist/{chunk-VXEF2SWG.js → chunk-EHMMBIZT.js} +16 -12
  23. package/dist/chunk-FVXNEZEW.js +161 -0
  24. package/dist/{chunk-AHL6KOGM.js → chunk-HXINWG37.js} +2 -2
  25. package/dist/{chunk-3CKJOTVM.js → chunk-IW6Q66WS.js} +4 -4
  26. package/dist/chunk-JJFJWD35.js +162 -0
  27. package/dist/{chunk-NYNSYLFY.js → chunk-JL44HGZC.js} +1 -1
  28. package/dist/{chunk-3TBXHLSC.js → chunk-K4F7QEGW.js} +1 -1
  29. package/dist/{chunk-NUJTNH76.js → chunk-LBWKMTT3.js} +1 -1
  30. package/dist/{chunk-YKJO3SI4.js → chunk-LONB36SP.js} +16 -3
  31. package/dist/{chunk-WQ3OMEC4.js → chunk-M6HLYG33.js} +1 -1
  32. package/dist/{chunk-I4GQRMFV.js → chunk-M6YV5KSS.js} +6 -4
  33. package/dist/{chunk-KBDKKHXB.js → chunk-O6CGOVD4.js} +2 -2
  34. package/dist/{chunk-L2RJPVHV.js → chunk-O7MMYJAD.js} +266 -512
  35. package/dist/chunk-QMFMST2T.js +39 -0
  36. package/dist/{chunk-AQF6IXSR.js → chunk-RBCKX2FZ.js} +11 -6
  37. package/dist/{chunk-4W6VDVQU.js → chunk-RLERORUI.js} +246 -56
  38. package/dist/{chunk-MI4SFZGX.js → chunk-RMEJR3AW.js} +5 -2
  39. package/dist/{chunk-UFW4S3RU.js → chunk-RVMCY6DP.js} +1 -1
  40. package/dist/{chunk-LF67HWWR.js → chunk-RWRZVQCB.js} +1 -1
  41. package/dist/{chunk-NQJSPMY2.js → chunk-SCG2VBPB.js} +4 -4
  42. package/dist/chunk-SXIJLSVF.js +41 -0
  43. package/dist/{chunk-YFDQIUQ3.js → chunk-T42GXE7Y.js} +18 -18
  44. package/dist/chunk-TDQW2YHK.js +65 -0
  45. package/dist/{chunk-45UVJXFQ.js → chunk-W2UOVGRC.js} +1 -1
  46. package/dist/{ci-QD2Q7NWY.js → ci-H6GPHG4T.js} +7 -7
  47. package/dist/{ci-format-42XIZO5P.js → ci-format-U47GSGYU.js} +2 -2
  48. package/dist/{constants-5CMEFZQB.js → constants-GYJTB6KI.js} +1 -1
  49. package/dist/{constants-NMASHFDL.js → constants-SNJR6546.js} +1 -1
  50. package/dist/doctor-cli-J6LAQ5LU.js +18 -0
  51. package/dist/electron-server.js +922 -842
  52. package/dist/file-checkpoint-64A2AXHE.js +7 -0
  53. package/dist/{file-checkpoint-NKBHGC7L.js → file-checkpoint-VVPUJNCI.js} +2 -1
  54. package/dist/{hub-ZLF6GMQD.js → hub-G5FMMTVZ.js} +3 -3
  55. package/dist/{hub-server-CBKCP5VD.js → hub-server-JLC7CNP7.js} +55 -17
  56. package/dist/index.js +48 -42
  57. package/dist/{indexer-P3FPRTPJ.js → indexer-GKIWSSRP.js} +3 -3
  58. package/dist/indexer-VRXDZ74A.js +10 -0
  59. package/dist/{persist-S77WRVLD.js → persist-ZZXRWFBX.js} +4 -4
  60. package/dist/{persistent-memory-GJE7HKVK.js → persistent-memory-EXJBXL33.js} +3 -3
  61. package/dist/{persistent-memory-MBSBTBGY.js → persistent-memory-LEE454DW.js} +3 -3
  62. package/dist/{pr-SXRW24JG.js → pr-6PUHVJ6K.js} +7 -7
  63. package/dist/{project-trust-MUG325AW.js → project-trust-6CJB5ZMX.js} +1 -1
  64. package/dist/{project-trust-NKYHL3VZ.js → project-trust-KGG2BWKC.js} +1 -1
  65. package/dist/run-tests-2C7MWZBN.js +12 -0
  66. package/dist/run-tests-33ZVQE3Q.js +13 -0
  67. package/dist/{semantic-7GM5M4MU.js → semantic-N227CLSC.js} +4 -4
  68. package/dist/{semantic-QOBAXEQ4.js → semantic-TRQAZSRY.js} +4 -4
  69. package/dist/{server-GGEO7SA2.js → server-AJH5TBVO.js} +231 -103
  70. package/dist/{server-MO3EU2XD.js → server-CYAB56O3.js} +16 -14
  71. package/dist/{store-SIKHCUYJ.js → store-2N6PPPBP.js} +2 -2
  72. package/dist/{store-CMSSWZF7.js → store-76VVFDXM.js} +2 -2
  73. package/dist/{task-orchestrator-JGEEQ2OE.js → task-orchestrator-HNRV3YUD.js} +15 -14
  74. package/dist/{usage-B7RIAPPT.js → usage-ZN5DU6Z7.js} +4 -4
  75. package/dist/{vector-store-JAXWDZYW.js → vector-store-T2DVUMY4.js} +2 -2
  76. package/dist/{vector-store-PWIOQFTP.js → vector-store-V6UGEYWK.js} +2 -2
  77. package/dist/web/client/app.js +7 -0
  78. package/dist/web/client/app.js.br +0 -0
  79. package/dist/web/client/app.js.gz +0 -0
  80. package/dist/web/client/util.js +14 -23
  81. package/dist/web/client/util.js.br +0 -0
  82. package/dist/web/client/util.js.gz +0 -0
  83. package/dist/web/client/vendor/DOMPurify-LICENSE.txt +202 -0
  84. package/dist/web/client/vendor/purify.es.mjs +2722 -0
  85. package/dist/web/client/vendor/purify.es.mjs.br +0 -0
  86. package/dist/web/client/vendor/purify.es.mjs.gz +0 -0
  87. package/package.json +4 -2
  88. package/dist/chunk-4BKXL7SM.js +0 -98
  89. package/dist/chunk-6BUTA5VW.js +0 -38
  90. package/dist/chunk-IW3Q7AE5.js +0 -40
  91. package/dist/chunk-SKET65WZ.js +0 -96
  92. package/dist/doctor-cli-IOVSHBDI.js +0 -18
  93. package/dist/file-checkpoint-CGH6OJVI.js +0 -6
  94. package/dist/indexer-FPKY7LCT.js +0 -10
  95. package/dist/run-tests-EQCAMFQE.js +0 -10
  96. package/dist/run-tests-V3N7YV3P.js +0 -9
@@ -0,0 +1,7 @@
1
+ import {
2
+ fileCheckpoints
3
+ } from "./chunk-FVXNEZEW.js";
4
+ import "./chunk-QMFMST2T.js";
5
+ export {
6
+ fileCheckpoints
7
+ };
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  fileCheckpoints
4
- } from "./chunk-4BKXL7SM.js";
4
+ } from "./chunk-JJFJWD35.js";
5
+ import "./chunk-SXIJLSVF.js";
5
6
  export {
6
7
  fileCheckpoints
7
8
  };
@@ -143,7 +143,7 @@ ${content}`);
143
143
  const state = await runDiscussion(config, providers, options.topic);
144
144
  if (options.save !== false && state.messages.length > 0) {
145
145
  try {
146
- const { persistDiscussion } = await import("./persist-S77WRVLD.js");
146
+ const { persistDiscussion } = await import("./persist-ZZXRWFBX.js");
147
147
  const { path } = await persistDiscussion(state, configManager, defaultProvider, defaultModel);
148
148
  console.log(chalk.dim(`
149
149
  \u{1F4BE} Saved to history \u2014 open it in the Web UI and hit \u{1F3AC} to replay.
@@ -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-JGEEQ2OE.js");
161
+ const { TaskOrchestrator } = await import("./task-orchestrator-HNRV3YUD.js");
162
162
  const orchestrator = new TaskOrchestrator(config, providers, configManager);
163
163
  let interrupted = false;
164
164
  const onSigint = () => {
@@ -194,7 +194,7 @@ async function runTaskMode(config, providers, configManager, topic) {
194
194
  }
195
195
  }
196
196
  async function runDistributedDiscussion(config, providers, topic, port) {
197
- const { HubServer } = await import("./hub-server-CBKCP5VD.js");
197
+ const { HubServer } = await import("./hub-server-JLC7CNP7.js");
198
198
  const hub = new HubServer(config, providers, port);
199
199
  let interrupted = false;
200
200
  const onSigint = () => {
@@ -11,11 +11,15 @@ import {
11
11
  renderSummary,
12
12
  renderUserInterrupt
13
13
  } from "./chunk-NR5U6LVG.js";
14
+ import {
15
+ equalToken
16
+ } from "./chunk-TDQW2YHK.js";
14
17
  import {
15
18
  HubAgent
16
19
  } from "./chunk-C2Z77RTU.js";
17
20
 
18
21
  // src/hub/hub-server.ts
22
+ import { randomBytes, randomUUID } from "crypto";
19
23
  import { WebSocketServer } from "ws";
20
24
  import { createServer } from "http";
21
25
  import chalk from "chalk";
@@ -24,6 +28,7 @@ var HubServer = class {
24
28
  this.config = config;
25
29
  this.providers = providers;
26
30
  this.port = port;
31
+ if (this.token.length < 32) throw new Error("AICLI_HUB_TOKEN must be at least 32 characters");
27
32
  this.unassignedRoles = [...config.roles];
28
33
  }
29
34
  config;
@@ -37,6 +42,10 @@ var HubServer = class {
37
42
  aborted = false;
38
43
  currentTurnResolve = null;
39
44
  topic = "";
45
+ currentTurnSocket = null;
46
+ currentTurnId = "";
47
+ token = process.env.AICLI_HUB_TOKEN || randomBytes(32).toString("base64url");
48
+ host = process.env.AICLI_HUB_HOST || "127.0.0.1";
40
49
  /**
41
50
  * Start the hub server and run the discussion.
42
51
  */
@@ -44,17 +53,19 @@ var HubServer = class {
44
53
  this.topic = topic;
45
54
  assignRoleColors(this.config.roles);
46
55
  this.httpServer = createServer();
47
- this.wss = new WebSocketServer({ server: this.httpServer });
56
+ this.wss = new WebSocketServer({ server: this.httpServer, maxPayload: 256 * 1024, verifyClient: ({ req }) => !req.headers.origin && equalToken(req.headers.authorization?.replace(/^Bearer /, ""), this.token) && (this.wss?.clients.size ?? 0) < this.config.roles.length + 4 });
48
57
  this.wss.on("connection", (ws) => this.handleConnection(ws));
49
- await new Promise((resolve) => {
50
- this.httpServer.listen(this.port, () => resolve());
58
+ await new Promise((resolve, reject) => {
59
+ this.httpServer.once("error", reject);
60
+ this.httpServer.listen(this.port, this.host, () => resolve());
51
61
  });
52
62
  const maxRounds = this.config.maxRounds ?? 10;
53
63
  renderHubBanner(topic, this.config.roles, maxRounds, this.config.contextFiles);
54
- console.log(chalk.bold.cyan(` \u{1F310} Hub server listening on ws://localhost:${this.port}`));
64
+ console.log(chalk.bold.cyan(` \u{1F310} Hub server listening on ws://${this.host}:${this.port}`));
55
65
  console.log(chalk.dim(` Waiting for ${this.config.roles.length} agent(s) to connect...`));
56
66
  console.log(chalk.dim(` Each agent should run: aicli join --port ${this.port}`));
57
67
  console.log();
68
+ console.log(` Set AICLI_HUB_TOKEN=${this.token} in each trusted joining process.`);
58
69
  await this.waitForAgents(topic);
59
70
  await this.runDiscussion(topic, maxRounds);
60
71
  this.shutdown();
@@ -66,6 +77,7 @@ var HubServer = class {
66
77
  }
67
78
  }
68
79
  shutdown() {
80
+ for (const ws of this.wss?.clients ?? []) ws.terminate();
69
81
  for (const agent of this.agents.values()) {
70
82
  try {
71
83
  agent.ws.close();
@@ -77,7 +89,20 @@ var HubServer = class {
77
89
  }
78
90
  // ── Connection Handling ──────────────────────────────────────────
79
91
  handleConnection(ws) {
92
+ const registerTimer = setTimeout(() => {
93
+ if (![...this.agents.values()].some((a) => a.ws === ws)) ws.close(1008, "Registration timeout");
94
+ }, 1e4);
95
+ registerTimer.unref();
96
+ let window = Date.now(), count = 0;
80
97
  ws.on("message", (raw) => {
98
+ if (Date.now() - window >= 1e3) {
99
+ window = Date.now();
100
+ count = 0;
101
+ }
102
+ if (++count > 10) {
103
+ ws.close(1008, "Rate limit");
104
+ return;
105
+ }
81
106
  try {
82
107
  const msg = JSON.parse(raw.toString());
83
108
  this.handleAgentMessage(ws, msg);
@@ -85,11 +110,17 @@ var HubServer = class {
85
110
  this.sendTo(ws, { type: "error", message: "Invalid message format" });
86
111
  }
87
112
  });
113
+ ws.on("error", () => {
114
+ });
88
115
  ws.on("close", () => {
116
+ clearTimeout(registerTimer);
117
+ if (this.currentTurnSocket === ws) this.currentTurnResolve?.({ content: "", passed: true });
89
118
  for (const [roleId, agent] of this.agents) {
90
119
  if (agent.ws === ws) {
91
120
  console.log(chalk.yellow(` \u26A0 Agent "${agent.roleName}" (${roleId}) disconnected`));
92
121
  this.agents.delete(roleId);
122
+ const role = this.config.roles.find((r) => r.id === roleId);
123
+ if (role) this.unassignedRoles.push(role);
93
124
  break;
94
125
  }
95
126
  }
@@ -98,6 +129,11 @@ var HubServer = class {
98
129
  handleAgentMessage(ws, msg) {
99
130
  switch (msg.type) {
100
131
  case "register": {
132
+ if ([...this.agents.values()].some((a) => a.ws === ws)) {
133
+ this.sendTo(ws, { type: "error", message: "Already registered" });
134
+ return;
135
+ }
136
+ if (typeof msg.roleId !== "string" || msg.roleId.length > 100) return;
101
137
  const requestedRole = msg.roleId;
102
138
  const roleIndex = this.unassignedRoles.findIndex((r) => r.id === requestedRole);
103
139
  if (roleIndex === -1) {
@@ -130,7 +166,7 @@ var HubServer = class {
130
166
  break;
131
167
  }
132
168
  case "response": {
133
- if (this.currentTurnResolve) {
169
+ if (this.currentTurnResolve && this.currentTurnSocket === ws && msg.turnId === this.currentTurnId && typeof msg.content === "string" && typeof msg.passed === "boolean") {
134
170
  this.currentTurnResolve({ content: msg.content, passed: msg.passed });
135
171
  this.currentTurnResolve = null;
136
172
  }
@@ -229,19 +265,16 @@ var HubServer = class {
229
265
  await this.generateSummary(topic);
230
266
  }
231
267
  async getRemoteResponse(agent, role, _topic, round, maxRounds) {
232
- this.sendTo(agent.ws, {
233
- type: "your_turn",
234
- round,
235
- maxRounds,
236
- history: this.history.map(serializeMessage)
237
- });
268
+ const turnId = randomUUID();
269
+ this.currentTurnId = turnId;
270
+ this.currentTurnSocket = agent.ws;
271
+ let timer;
238
272
  try {
239
- const response = await Promise.race([
240
- new Promise((resolve) => {
241
- this.currentTurnResolve = resolve;
242
- }),
243
- sleep(12e4).then(() => ({ content: `[${role.name} timed out]`, passed: true }))
244
- ]);
273
+ const response = await new Promise((resolve) => {
274
+ this.currentTurnResolve = resolve;
275
+ timer = setTimeout(() => resolve({ content: "", passed: true }), 12e4);
276
+ this.sendTo(agent.ws, { type: "your_turn", turnId, round, maxRounds, history: this.history.map(serializeMessage) });
277
+ });
245
278
  return {
246
279
  speaker: role.id,
247
280
  speakerName: role.name,
@@ -257,6 +290,11 @@ var HubServer = class {
257
290
  timestamp: /* @__PURE__ */ new Date(),
258
291
  passed: true
259
292
  };
293
+ } finally {
294
+ clearTimeout(timer);
295
+ this.currentTurnResolve = null;
296
+ this.currentTurnSocket = null;
297
+ this.currentTurnId = "";
260
298
  }
261
299
  }
262
300
  async getBuiltinResponse(role, topic, round, maxRounds) {
package/dist/index.js CHANGED
@@ -24,12 +24,12 @@ import {
24
24
  setupProxy,
25
25
  snapshotFile,
26
26
  stripRoutingTags
27
- } from "./chunk-YFDQIUQ3.js";
27
+ } from "./chunk-T42GXE7Y.js";
28
28
  import {
29
29
  CostTracker,
30
30
  getPricing,
31
31
  setCostCurrency
32
- } from "./chunk-YKJO3SI4.js";
32
+ } from "./chunk-LONB36SP.js";
33
33
  import {
34
34
  ToolExecutor,
35
35
  ToolRegistry,
@@ -40,17 +40,14 @@ import {
40
40
  formatPermissionProfileWarning,
41
41
  globToRegex,
42
42
  googleSearchContext,
43
- isInterrupted,
44
43
  isToolCapableProvider,
45
44
  lastResponseStore,
46
- requestInterrupt,
47
- resetInterrupt,
48
45
  rlInternal,
49
46
  setContextWindow,
50
47
  setMaxOutputCap,
51
48
  spawnAgentContext,
52
49
  undoStack
53
- } from "./chunk-L2RJPVHV.js";
50
+ } from "./chunk-O7MMYJAD.js";
54
51
  import "./chunk-HLWUDRBO.js";
55
52
  import {
56
53
  NO_THINKING,
@@ -58,16 +55,16 @@ import {
58
55
  chatParamsFrom,
59
56
  thinkingParamsFor
60
57
  } from "./chunk-6YZEZFX5.js";
61
- import "./chunk-GHWZVPUV.js";
58
+ import "./chunk-6JHACXB3.js";
62
59
  import {
63
60
  countPendingMemories,
64
61
  detectStaleLegacyMarkdownEdit,
65
62
  formatMemoryForPrompt
66
- } from "./chunk-AHL6KOGM.js";
67
- import "./chunk-LF67HWWR.js";
68
- import "./chunk-XJOK5353.js";
69
- import "./chunk-WQ3OMEC4.js";
70
- import "./chunk-NRSYBKWA.js";
63
+ } from "./chunk-HXINWG37.js";
64
+ import "./chunk-RWRZVQCB.js";
65
+ import "./chunk-B3MPYI4E.js";
66
+ import "./chunk-M6HLYG33.js";
67
+ import "./chunk-C7CKDFJS.js";
71
68
  import "./chunk-KHYD3WXE.js";
72
69
  import {
73
70
  initTheme,
@@ -76,30 +73,30 @@ import {
76
73
  import {
77
74
  SessionManager,
78
75
  getContentText
79
- } from "./chunk-IUVDZVZ4.js";
80
- import "./chunk-NYNSYLFY.js";
76
+ } from "./chunk-AXTLYOA7.js";
77
+ import "./chunk-JL44HGZC.js";
81
78
  import {
82
79
  scanString
83
80
  } from "./chunk-3FEZSLGI.js";
84
81
  import {
85
82
  loadContextFiles,
86
83
  writeCrashLog
87
- } from "./chunk-NQJSPMY2.js";
84
+ } from "./chunk-SCG2VBPB.js";
88
85
  import {
89
86
  getActivePluginAssets,
90
87
  getPendingHookTrust,
91
88
  installFlushOnExit,
92
89
  mergePluginHooks,
93
90
  runLifecycleHooks
94
- } from "./chunk-5GQL4TSZ.js";
91
+ } from "./chunk-4BXTGXZ6.js";
95
92
  import "./chunk-RS7SKYTS.js";
96
93
  import {
97
94
  ProviderRegistry,
98
95
  listBuiltInProviderMetadata
99
- } from "./chunk-VXEF2SWG.js";
96
+ } from "./chunk-EHMMBIZT.js";
100
97
  import {
101
98
  ConfigManager
102
- } from "./chunk-AQF6IXSR.js";
99
+ } from "./chunk-RBCKX2FZ.js";
103
100
  import {
104
101
  CONTENT_ONLY_STREAM_REMINDER,
105
102
  TEE_FINAL_USER_NUDGE,
@@ -117,7 +114,7 @@ import {
117
114
  runAgentLoop,
118
115
  stripToolCallReminder,
119
116
  teeStreamErrorSummary
120
- } from "./chunk-MI4SFZGX.js";
117
+ } from "./chunk-RMEJR3AW.js";
121
118
  import {
122
119
  AuthError,
123
120
  ProviderError,
@@ -130,10 +127,14 @@ import {
130
127
  } from "./chunk-HOSJZMQS.js";
131
128
  import {
132
129
  atomicWriteFileSync
133
- } from "./chunk-IW3Q7AE5.js";
130
+ } from "./chunk-BMLQPSHP.js";
134
131
  import "./chunk-XNFIYS7G.js";
135
- import "./chunk-4BKXL7SM.js";
136
- import "./chunk-4W6VDVQU.js";
132
+ import "./chunk-JJFJWD35.js";
133
+ import {
134
+ isInterrupted,
135
+ requestInterrupt,
136
+ resetInterrupt
137
+ } from "./chunk-3GEO2LPO.js";
137
138
  import {
138
139
  AGENTIC_BEHAVIOR_GUIDELINE,
139
140
  AUTHOR,
@@ -151,7 +152,8 @@ import {
151
152
  SKILLS_DIR_NAME,
152
153
  VERSION,
153
154
  buildUserIdentityPrompt
154
- } from "./chunk-VAV2IJ3R.js";
155
+ } from "./chunk-3CNPJLVI.js";
156
+ import "./chunk-SXIJLSVF.js";
155
157
 
156
158
  // src/index.ts
157
159
  import { program } from "commander";
@@ -1075,7 +1077,10 @@ function getVisionModelHint(model, provider) {
1075
1077
  if (bare.includes("vision") || bare.includes("vl") || bare.includes("5v") || // glm-5v-turbo
1076
1078
  bare.endsWith(".6v") || // glm-4.6v
1077
1079
  bare === "glm-5.3-flash" || // GLM-5 系列首个原生多模态(名字里没有 v,得单独认)
1078
- bare.endsWith("-v")) return null;
1080
+ // DeepSeek V4.1 Flash(2026-09)原生多模态。放在这条通用规则里而不是只写进下面的
1081
+ // deepseek 分支,是为了让 OpenRouter 的 `deepseek/deepseek-flash` 也一并放行——
1082
+ // 按 provider 分支写就会重演 v0.4.295「同一个坑换个前缀又漏一次」。
1083
+ bare.startsWith("deepseek-flash") || bare.endsWith("-v")) return null;
1079
1084
  if (provider === "kimi") {
1080
1085
  if (model.startsWith("moonshot-v1-")) {
1081
1086
  const visionModel = model + "-vision-preview";
@@ -1087,7 +1092,8 @@ function getVisionModelHint(model, provider) {
1087
1092
  return `model "${model}" does not support images. Use /model glm-5.3-flash (or glm-4.6v)`;
1088
1093
  }
1089
1094
  if (provider === "deepseek") {
1090
- return `model "${model}" does not support vision. DeepSeek standard models are text-only.`;
1095
+ if (bare.startsWith("deepseek-v4-flash")) return null;
1096
+ return `model "${model}" does not support images. Use /model deepseek-flash (DeepSeek V4.1 Flash)`;
1091
1097
  }
1092
1098
  return `model "${model}" may not support image input`;
1093
1099
  }
@@ -2161,8 +2167,8 @@ Session '${this.resumeSessionId}' not found.
2161
2167
  }
2162
2168
  void (async () => {
2163
2169
  try {
2164
- const { indexProject } = await import("./indexer-P3FPRTPJ.js");
2165
- const { loadIndex } = await import("./store-CMSSWZF7.js");
2170
+ const { indexProject } = await import("./indexer-GKIWSSRP.js");
2171
+ const { loadIndex } = await import("./store-76VVFDXM.js");
2166
2172
  const root = process.cwd();
2167
2173
  const existed = loadIndex(root);
2168
2174
  const { stats } = await indexProject(root);
@@ -2183,7 +2189,7 @@ Session '${this.resumeSessionId}' not found.
2183
2189
  })();
2184
2190
  void (async () => {
2185
2191
  try {
2186
- const { getChatIndexStatus, buildChatIndex } = await import("./chat-index-2D5GK2DB.js");
2192
+ const { getChatIndexStatus, buildChatIndex } = await import("./chat-index-7CLR4CBG.js");
2187
2193
  const initial = getChatIndexStatus();
2188
2194
  this.chatMemoryStatus = {
2189
2195
  exists: initial.exists,
@@ -2230,7 +2236,7 @@ Session '${this.resumeSessionId}' not found.
2230
2236
  }
2231
2237
  let projectMcpServers = {};
2232
2238
  if (projectMcpResult) {
2233
- const { checkTrust } = await import("./project-trust-NKYHL3VZ.js");
2239
+ const { checkTrust } = await import("./project-trust-KGG2BWKC.js");
2234
2240
  const verdict = checkTrust(this.config.getConfigDir(), projectMcpResult.filePath);
2235
2241
  if (verdict.trusted) {
2236
2242
  projectMcpServers = projectMcpResult.servers;
@@ -4056,17 +4062,17 @@ program.command("providers").description("List all AI providers and their config
4056
4062
  }
4057
4063
  console.log();
4058
4064
  });
4059
- program.command("web").description("Start Web UI server with browser-based chat interface").option("--port <number>", "Server port (default: 3000)", "3000").option("--host <name>", "Server host (default: localhost)", "localhost").action(async (options) => {
4065
+ program.command("web").description("Start Web UI server with browser-based chat interface").option("--port <number>", "Server port (default: 3000)", "3000").option("--host <name>", "Server host (default: localhost)", "localhost").option("--external-origin <url>", "Exact browser origin when using a trusted reverse proxy").action(async (options) => {
4060
4066
  const port = parseInt(options.port, 10);
4061
4067
  if (isNaN(port) || port < 1 || port > 65535) {
4062
4068
  console.error("Error: Invalid port number. Must be between 1 and 65535.");
4063
4069
  process.exit(1);
4064
4070
  }
4065
- const { startWebServer } = await import("./server-GGEO7SA2.js");
4066
- await startWebServer({ port, host: options.host });
4071
+ const { startWebServer } = await import("./server-AJH5TBVO.js");
4072
+ await startWebServer({ port, host: options.host, externalOrigin: options.externalOrigin });
4067
4073
  });
4068
4074
  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) => {
4069
- const { AuthManager } = await import("./auth-PE3Z5OHS.js");
4075
+ const { AuthManager } = await import("./auth-QTQNZ6IX.js");
4070
4076
  const config = new ConfigManager();
4071
4077
  const auth = new AuthManager(config.getConfigDir());
4072
4078
  if (!action || action === "list") {
@@ -4229,11 +4235,11 @@ program.command("sessions").description("List recent conversation sessions").opt
4229
4235
  console.log(footer + "\n");
4230
4236
  });
4231
4237
  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) => {
4232
- const { runUsageCli } = await import("./usage-B7RIAPPT.js");
4238
+ const { runUsageCli } = await import("./usage-ZN5DU6Z7.js");
4233
4239
  await runUsageCli(options);
4234
4240
  });
4235
4241
  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) => {
4236
- const { runDoctorCli } = await import("./doctor-cli-IOVSHBDI.js");
4242
+ const { runDoctorCli } = await import("./doctor-cli-J6LAQ5LU.js");
4237
4243
  const argv = process.argv.slice(2);
4238
4244
  await runDoctorCli({
4239
4245
  json: !!options.json || argv.includes("--json"),
@@ -4242,7 +4248,7 @@ program.command("doctor").description("Health check: API keys, config, MCP, rece
4242
4248
  });
4243
4249
  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) => {
4244
4250
  try {
4245
- const batch = await import("./batch-HMADXNOD.js");
4251
+ const batch = await import("./batch-H4WWSZQ3.js");
4246
4252
  switch (action) {
4247
4253
  case "submit":
4248
4254
  if (!arg) {
@@ -4285,7 +4291,7 @@ program.command("batch <action> [arg] [arg2]").description("Anthropic Message Ba
4285
4291
  }
4286
4292
  });
4287
4293
  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) => {
4288
- const { startMcpServer } = await import("./server-MO3EU2XD.js");
4294
+ const { startMcpServer } = await import("./server-CYAB56O3.js");
4289
4295
  await startMcpServer({
4290
4296
  allowDestructive: !!options.allowDestructive,
4291
4297
  allowOutsideCwd: !!options.allowOutsideCwd,
@@ -4298,7 +4304,7 @@ program.command("pr <action> [target]").description("PR review helpers: review |
4298
4304
  console.error(`Unknown pr action: ${action}. Use review | security-review | summarize.`);
4299
4305
  process.exit(1);
4300
4306
  }
4301
- const { runPrCli } = await import("./pr-SXRW24JG.js");
4307
+ const { runPrCli } = await import("./pr-6PUHVJ6K.js");
4302
4308
  const result = await runPrCli({
4303
4309
  action,
4304
4310
  target,
@@ -4318,8 +4324,8 @@ program.command("pr <action> [target]").description("PR review helpers: review |
4318
4324
  process.exit(result.exitCode);
4319
4325
  });
4320
4326
  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) => {
4321
- const { runCi } = await import("./ci-QD2Q7NWY.js");
4322
- const { formatCiResult } = await import("./ci-format-42XIZO5P.js");
4327
+ const { runCi } = await import("./ci-H6GPHG4T.js");
4328
+ const { formatCiResult } = await import("./ci-format-U47GSGYU.js");
4323
4329
  const formats = [options.json, options.markdown, options.sarif].filter(Boolean).length;
4324
4330
  if (formats > 1) {
4325
4331
  console.error("Choose only one output format: --json, --markdown, or --sarif.");
@@ -4478,7 +4484,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
4478
4484
  config.get("customProviders"),
4479
4485
  config.getConfigDir()
4480
4486
  );
4481
- const { startHub } = await import("./hub-ZLF6GMQD.js");
4487
+ const { startHub } = await import("./hub-G5FMMTVZ.js");
4482
4488
  await startHub(
4483
4489
  {
4484
4490
  topic: topic ?? "",
@@ -4514,7 +4520,7 @@ program.command("join").description("Join a running hub as a remote AI agent").o
4514
4520
  config.get("customProviders"),
4515
4521
  config.getConfigDir()
4516
4522
  );
4517
- const { joinHub } = await import("./agent-client-6GX6QQDU.js");
4523
+ const { joinHub } = await import("./agent-client-TIEAYZXV.js");
4518
4524
  await joinHub(
4519
4525
  {
4520
4526
  port: parseInt(options.port ?? "9527", 10),
@@ -2,9 +2,9 @@
2
2
  import {
3
3
  indexProject,
4
4
  updateFile
5
- } from "./chunk-LF67HWWR.js";
6
- import "./chunk-WQ3OMEC4.js";
7
- import "./chunk-IW3Q7AE5.js";
5
+ } from "./chunk-RWRZVQCB.js";
6
+ import "./chunk-M6HLYG33.js";
7
+ import "./chunk-BMLQPSHP.js";
8
8
  export {
9
9
  indexProject,
10
10
  updateFile
@@ -0,0 +1,10 @@
1
+ import {
2
+ indexProject,
3
+ updateFile
4
+ } from "./chunk-RVMCY6DP.js";
5
+ import "./chunk-W2UOVGRC.js";
6
+ import "./chunk-2XMUCC42.js";
7
+ export {
8
+ indexProject,
9
+ updateFile
10
+ };
@@ -2,11 +2,11 @@
2
2
  import {
3
3
  discussionToMessages,
4
4
  persistDiscussion
5
- } from "./chunk-NUJTNH76.js";
6
- import "./chunk-IUVDZVZ4.js";
7
- import "./chunk-NYNSYLFY.js";
5
+ } from "./chunk-LBWKMTT3.js";
6
+ import "./chunk-AXTLYOA7.js";
7
+ import "./chunk-JL44HGZC.js";
8
8
  import "./chunk-3FEZSLGI.js";
9
- import "./chunk-IW3Q7AE5.js";
9
+ import "./chunk-BMLQPSHP.js";
10
10
  export {
11
11
  discussionToMessages,
12
12
  persistDiscussion
@@ -27,11 +27,11 @@ import {
27
27
  touchMemoryReferences,
28
28
  updateMemoryApproval,
29
29
  updateMemoryEntry
30
- } from "./chunk-CIM2PV2F.js";
30
+ } from "./chunk-2E5W2E64.js";
31
31
  import "./chunk-FSC6KEWU.js";
32
- import "./chunk-6BUTA5VW.js";
32
+ import "./chunk-2XMUCC42.js";
33
33
  import "./chunk-CGLYJRFA.js";
34
- import "./chunk-SJFZPS65.js";
34
+ import "./chunk-EAVX3RLD.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-AHL6KOGM.js";
31
+ } from "./chunk-HXINWG37.js";
32
32
  import "./chunk-3FEZSLGI.js";
33
33
  import "./chunk-HOSJZMQS.js";
34
- import "./chunk-IW3Q7AE5.js";
35
- import "./chunk-VAV2IJ3R.js";
34
+ import "./chunk-BMLQPSHP.js";
35
+ import "./chunk-3CNPJLVI.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-3CKJOTVM.js";
6
- import "./chunk-3TBXHLSC.js";
5
+ } from "./chunk-IW6Q66WS.js";
6
+ import "./chunk-K4F7QEGW.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-VXEF2SWG.js";
17
+ } from "./chunk-EHMMBIZT.js";
18
18
  import {
19
19
  ConfigManager
20
- } from "./chunk-AQF6IXSR.js";
21
- import "./chunk-MI4SFZGX.js";
20
+ } from "./chunk-RBCKX2FZ.js";
21
+ import "./chunk-RMEJR3AW.js";
22
22
  import "./chunk-TU3L3PW7.js";
23
- import "./chunk-IW3Q7AE5.js";
23
+ import "./chunk-BMLQPSHP.js";
24
24
  import {
25
25
  VERSION
26
- } from "./chunk-VAV2IJ3R.js";
26
+ } from "./chunk-3CNPJLVI.js";
27
27
 
28
28
  // src/cli/pr.ts
29
29
  import { execFileSync } from "child_process";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  atomicWriteFileSync
3
- } from "./chunk-6BUTA5VW.js";
3
+ } from "./chunk-2XMUCC42.js";
4
4
 
5
5
  // src/mcp/project-trust.ts
6
6
  import { existsSync, readFileSync, mkdirSync } from "fs";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  atomicWriteFileSync
4
- } from "./chunk-IW3Q7AE5.js";
4
+ } from "./chunk-BMLQPSHP.js";
5
5
 
6
6
  // src/mcp/project-trust.ts
7
7
  import { existsSync, readFileSync, mkdirSync } from "fs";
@@ -0,0 +1,12 @@
1
+ import {
2
+ executeTests,
3
+ runTestProcess,
4
+ runTestsTool
5
+ } from "./chunk-RLERORUI.js";
6
+ import "./chunk-QMFMST2T.js";
7
+ import "./chunk-EAVX3RLD.js";
8
+ export {
9
+ executeTests,
10
+ runTestProcess,
11
+ runTestsTool
12
+ };
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ executeTests,
4
+ runTestProcess,
5
+ runTestsTool
6
+ } from "./chunk-3GEO2LPO.js";
7
+ import "./chunk-3CNPJLVI.js";
8
+ import "./chunk-SXIJLSVF.js";
9
+ export {
10
+ executeTests,
11
+ runTestProcess,
12
+ runTestsTool
13
+ };
@@ -5,11 +5,11 @@ import {
5
5
  pathTokens,
6
6
  rebuildSemanticIndex,
7
7
  semanticSearch
8
- } from "./chunk-XJOK5353.js";
9
- import "./chunk-WQ3OMEC4.js";
10
- import "./chunk-NRSYBKWA.js";
8
+ } from "./chunk-B3MPYI4E.js";
9
+ import "./chunk-M6HLYG33.js";
10
+ import "./chunk-C7CKDFJS.js";
11
11
  import "./chunk-KHYD3WXE.js";
12
- import "./chunk-IW3Q7AE5.js";
12
+ import "./chunk-BMLQPSHP.js";
13
13
  export {
14
14
  buildEmbeddingText,
15
15
  hasSemanticIndex,