jinzd-ai-cli 0.4.154 → 0.4.156

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 (33) hide show
  1. package/dist/{batch-W57MV5OT.js → batch-DBOCPVH5.js} +2 -2
  2. package/dist/{chat-index-LUQWWLKO.js → chat-index-2I7ZHRE5.js} +2 -1
  3. package/dist/{chunk-SH7NTECG.js → chunk-3DCAQKVZ.js} +1 -1
  4. package/dist/{chunk-HVNEBTSF.js → chunk-3SQMKA4I.js} +1 -1
  5. package/dist/{chunk-UE26B3RO.js → chunk-3WLEDKOW.js} +1 -1
  6. package/dist/{chunk-2IODI5TI.js → chunk-7OCOFVQP.js} +1 -1
  7. package/dist/{chunk-NP7WOVIH.js → chunk-AACNCJMD.js} +1 -1
  8. package/dist/{chunk-ZAYDVWY4.js → chunk-GQ647SF3.js} +23 -787
  9. package/dist/{chunk-RXM76HB7.js → chunk-MM3F43H6.js} +3 -117
  10. package/dist/chunk-NZ4X6GUC.js +230 -0
  11. package/dist/{chunk-O6MLS5QO.js → chunk-OJL3PY36.js} +0 -226
  12. package/dist/{hub-OP7EWTQQ.js → chunk-Q3ZUDA6S.js} +10 -237
  13. package/dist/chunk-RUJQ5OUB.js +51 -0
  14. package/dist/chunk-SLSWPBK3.js +120 -0
  15. package/dist/chunk-TOTEUETI.js +768 -0
  16. package/dist/{chunk-OSTMMSOV.js → chunk-UAPNBQLU.js} +1 -1
  17. package/dist/{chunk-XWYWASPT.js → chunk-Z2UJDFJK.js} +4 -4
  18. package/dist/{ci-JYZGZSMP.js → ci-AWA6KC3X.js} +3 -3
  19. package/dist/{constants-S4Y6A25E.js → constants-QDTWBWWC.js} +1 -1
  20. package/dist/{doctor-cli-FMTMDO2Z.js → doctor-cli-4MTG6SFH.js} +6 -6
  21. package/dist/electron-server.js +740 -44
  22. package/dist/hub-QRDXG527.js +260 -0
  23. package/dist/{hub-server-OH7AYQIW.js → hub-server-GSTG5MNE.js} +4 -2
  24. package/dist/index.js +50 -44
  25. package/dist/persist-UI6WRBGB.js +12 -0
  26. package/dist/{run-tests-3QAZGHP2.js → run-tests-CNURD2ST.js} +2 -2
  27. package/dist/{run-tests-4XNY7QB4.js → run-tests-NPWSCWP5.js} +1 -1
  28. package/dist/{server-W4TBZN6I.js → server-HFG2SM3Y.js} +6 -5
  29. package/dist/{server-UL42EXOA.js → server-RRUCZMMM.js} +124 -29
  30. package/dist/{task-orchestrator-RLAZK5EB.js → task-orchestrator-GF6ZMNUK.js} +6 -5
  31. package/dist/web/client/app.js +138 -0
  32. package/dist/web/client/index.html +28 -0
  33. package/package.json +1 -1
@@ -0,0 +1,260 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ assignRoleColors,
4
+ renderHubBanner,
5
+ renderHubEvent
6
+ } from "./chunk-OJL3PY36.js";
7
+ import {
8
+ DiscussionOrchestrator,
9
+ getPreset,
10
+ listPresets,
11
+ resolveRoleProviders
12
+ } from "./chunk-Q3ZUDA6S.js";
13
+ import "./chunk-NZ4X6GUC.js";
14
+ import "./chunk-PDX44BCA.js";
15
+
16
+ // src/hub/index.ts
17
+ import { readFileSync, existsSync } from "fs";
18
+ import chalk from "chalk";
19
+ async function startHub(options, configManager, providers) {
20
+ if (options.listPresets) {
21
+ console.log("\n Available discussion presets:\n");
22
+ for (const p of listPresets()) {
23
+ console.log(` ${p.id.padEnd(16)} ${p.name}`);
24
+ console.log(` ${"".padEnd(16)} ${p.description}`);
25
+ for (const r of p.roles) {
26
+ console.log(` ${"".padEnd(18)} \u2022 ${r.name} (${r.id})`);
27
+ }
28
+ console.log();
29
+ }
30
+ return;
31
+ }
32
+ let roles;
33
+ let presetUsed;
34
+ if (options.rolesFile) {
35
+ if (!existsSync(options.rolesFile)) {
36
+ console.error(` \u2717 Roles file not found: ${options.rolesFile}`);
37
+ process.exit(1);
38
+ }
39
+ try {
40
+ const raw = readFileSync(options.rolesFile, "utf-8");
41
+ const parsed = JSON.parse(raw);
42
+ const rawRoles = Array.isArray(parsed) ? parsed : parsed.roles;
43
+ if (!Array.isArray(rawRoles) || rawRoles.length === 0) {
44
+ throw new Error("roles must be a non-empty array");
45
+ }
46
+ roles = rawRoles.map((r) => ({
47
+ id: r.id ?? r.name?.toLowerCase().replace(/\s+/g, "-") ?? "agent",
48
+ name: r.name ?? r.id ?? "Agent",
49
+ persona: r.persona ?? r.description ?? `You are ${r.name ?? "an AI assistant"}.`,
50
+ ...r.provider && { provider: r.provider },
51
+ ...r.model && { model: r.model },
52
+ ...r.color && { color: r.color }
53
+ }));
54
+ } catch (err) {
55
+ console.error(` \u2717 Invalid roles file: ${err.message}`);
56
+ process.exit(1);
57
+ }
58
+ } else {
59
+ const presetId = options.preset ?? "tech-review";
60
+ presetUsed = getPreset(presetId);
61
+ if (!presetUsed) {
62
+ console.error(` \u2717 Preset "${presetId}" not found. Use --presets to list available presets.`);
63
+ process.exit(1);
64
+ }
65
+ roles = presetUsed.roles;
66
+ }
67
+ const defaultProvider = options.provider ?? configManager.get("defaultProvider");
68
+ const allDefaultModels = configManager.get("defaultModels");
69
+ let defaultModel = options.model ?? allDefaultModels[defaultProvider] ?? "";
70
+ if (!defaultModel) {
71
+ try {
72
+ const p = providers.get(defaultProvider);
73
+ defaultModel = p.info.defaultModel;
74
+ } catch {
75
+ console.error(` \u2717 Provider "${defaultProvider}" not configured. Run \`aicli config\` first.`);
76
+ process.exit(1);
77
+ }
78
+ }
79
+ if (!providers.has(defaultProvider)) {
80
+ console.error(` \u2717 Provider "${defaultProvider}" not available. Check API key configuration.`);
81
+ process.exit(1);
82
+ }
83
+ if (!options.topic?.trim()) {
84
+ console.error(" \u2717 Please provide a discussion topic.");
85
+ console.error(' Usage: aicli hub "your topic here"');
86
+ console.error(' aicli hub --preset brainstorm "your topic here"');
87
+ process.exit(1);
88
+ }
89
+ let context;
90
+ const contextFileNames = [];
91
+ if (options.contextFiles && options.contextFiles.length > 0) {
92
+ const parts = [];
93
+ for (const filePath of options.contextFiles) {
94
+ if (!existsSync(filePath)) {
95
+ console.error(` \u2717 Context file not found: ${filePath}`);
96
+ process.exit(1);
97
+ }
98
+ const content = readFileSync(filePath, "utf-8");
99
+ const fileName = filePath.replace(/\\/g, "/").split("/").pop() ?? filePath;
100
+ contextFileNames.push(fileName);
101
+ parts.push(`### ${fileName}
102
+
103
+ ${content}`);
104
+ }
105
+ context = parts.join("\n\n---\n\n");
106
+ }
107
+ {
108
+ const resolution = resolveRoleProviders(
109
+ roles,
110
+ {
111
+ has: (id) => providers.has(id),
112
+ defaultModelFor: (id) => providers.has(id) ? providers.get(id).info.defaultModel : void 0
113
+ },
114
+ defaultProvider,
115
+ defaultModel,
116
+ providers.listAvailable().map((p) => p.info.id),
117
+ options.mix
118
+ );
119
+ roles = resolution.roles;
120
+ for (const w of resolution.warnings) console.error(chalk.yellow(` \u26A0 ${w}`));
121
+ }
122
+ const mode = options.mode ?? "discuss";
123
+ const config = {
124
+ mode,
125
+ roles,
126
+ defaultProvider,
127
+ defaultModel,
128
+ maxRounds: options.maxRounds ?? (mode === "task" ? 15 : 10),
129
+ enableTools: mode === "task",
130
+ maxToolRoundsPerTurn: mode === "task" ? options.taskRounds ?? 30 : void 0,
131
+ context,
132
+ contextFiles: contextFileNames.length > 0 ? contextFileNames : void 0,
133
+ humanSteer: options.steer === true,
134
+ voteConverge: options.vote === true
135
+ };
136
+ if (mode === "discuss") {
137
+ if (options.distributed) {
138
+ await runDistributedDiscussion(config, providers, options.topic, options.port ?? 9527);
139
+ } else {
140
+ const state = await runDiscussion(config, providers, options.topic);
141
+ if (options.save !== false && state.messages.length > 0) {
142
+ try {
143
+ const { persistDiscussion } = await import("./persist-UI6WRBGB.js");
144
+ const { path } = await persistDiscussion(state, configManager, defaultProvider, defaultModel);
145
+ console.log(chalk.dim(`
146
+ \u{1F4BE} Saved to history \u2014 open it in the Web UI and hit \u{1F3AC} to replay.
147
+ ${path}`));
148
+ } catch (err) {
149
+ console.error(chalk.yellow(` \u26A0 Could not save discussion: ${err.message}`));
150
+ }
151
+ }
152
+ }
153
+ } else if (mode === "task") {
154
+ await runTaskMode(config, providers, configManager, options.topic);
155
+ }
156
+ }
157
+ async function runTaskMode(config, providers, configManager, topic) {
158
+ const { TaskOrchestrator } = await import("./task-orchestrator-GF6ZMNUK.js");
159
+ const orchestrator = new TaskOrchestrator(config, providers, configManager);
160
+ let interrupted = false;
161
+ const onSigint = () => {
162
+ if (interrupted) {
163
+ console.log("\n Force exit.");
164
+ process.exit(0);
165
+ }
166
+ interrupted = true;
167
+ orchestrator.abort();
168
+ };
169
+ process.on("SIGINT", onSigint);
170
+ console.log();
171
+ console.log(chalk.bold.white(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
172
+ console.log(chalk.bold.white(" \u2551") + chalk.bold.yellow(" \u{1F680} AI-CLI Multi-Agent Hub \u2014 Task Mode ") + chalk.bold.white("\u2551"));
173
+ console.log(chalk.bold.white(" \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
174
+ console.log(chalk.bold.white(" \u2551") + chalk.dim(` Goal: ${topic.slice(0, 52)}`.padEnd(62)) + chalk.bold.white("\u2551"));
175
+ console.log(chalk.bold.white(" \u2551") + chalk.dim(` Team: ${config.roles.map((r) => r.name).join(", ")}`.slice(0, 62).padEnd(62)) + chalk.bold.white("\u2551"));
176
+ if (config.contextFiles && config.contextFiles.length > 0) {
177
+ console.log(chalk.bold.white(" \u2551") + chalk.dim(` Context: ${config.contextFiles.join(", ")}`.padEnd(62)) + chalk.bold.white("\u2551"));
178
+ }
179
+ console.log(chalk.bold.white(" \u2551") + chalk.dim(` Rounds/task: up to ${config.maxToolRoundsPerTurn ?? 15}`.padEnd(62)) + chalk.bold.white("\u2551"));
180
+ console.log(chalk.bold.white(" \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
181
+ console.log(chalk.bold.white(" \u2551") + chalk.dim(" Plan \u2192 Approve \u2192 Execute \u2192 Review".padEnd(62)) + chalk.bold.white("\u2551"));
182
+ console.log(chalk.bold.white(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
183
+ console.log();
184
+ try {
185
+ await orchestrator.run(topic);
186
+ } catch (err) {
187
+ console.error(chalk.red(`
188
+ \u2717 Task mode error: ${err.message}`));
189
+ } finally {
190
+ process.removeListener("SIGINT", onSigint);
191
+ }
192
+ }
193
+ async function runDistributedDiscussion(config, providers, topic, port) {
194
+ const { HubServer } = await import("./hub-server-GSTG5MNE.js");
195
+ const hub = new HubServer(config, providers, port);
196
+ let interrupted = false;
197
+ const onSigint = () => {
198
+ if (interrupted) {
199
+ console.log("\n Force exit.");
200
+ hub.shutdown();
201
+ process.exit(0);
202
+ }
203
+ interrupted = true;
204
+ hub.abort();
205
+ };
206
+ process.on("SIGINT", onSigint);
207
+ try {
208
+ await hub.start(topic);
209
+ } catch (err) {
210
+ console.error(`
211
+ \u2717 Hub error: ${err.message}`);
212
+ } finally {
213
+ process.removeListener("SIGINT", onSigint);
214
+ }
215
+ }
216
+ async function runDiscussion(config, providers, topic) {
217
+ assignRoleColors(config.roles);
218
+ const orchestrator = new DiscussionOrchestrator(config, providers);
219
+ orchestrator.onEvent = renderHubEvent;
220
+ if (config.humanSteer) {
221
+ const { createInterface } = await import("readline");
222
+ orchestrator.onRoundReview = async ({ round, maxRounds }) => {
223
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
224
+ const answer = await new Promise((resolve) => {
225
+ rl.question(
226
+ chalk.cyan(`
227
+ \u{1F9ED} Round ${round}/${maxRounds} done. Steer next round? `) + chalk.dim("[Enter=continue \xB7 type guidance \xB7 /stop=end] "),
228
+ resolve
229
+ );
230
+ });
231
+ rl.close();
232
+ const t = answer.trim();
233
+ if (t === "/stop" || t.toLowerCase() === "stop") return { action: "stop" };
234
+ return { action: "continue", message: t || void 0 };
235
+ };
236
+ }
237
+ let interrupted = false;
238
+ const onSigint = () => {
239
+ if (interrupted) {
240
+ console.log("\n Force exit.");
241
+ process.exit(0);
242
+ }
243
+ interrupted = true;
244
+ orchestrator.abort();
245
+ };
246
+ process.on("SIGINT", onSigint);
247
+ renderHubBanner(topic, config.roles, config.maxRounds ?? 10, config.contextFiles);
248
+ try {
249
+ return await orchestrator.run(topic);
250
+ } catch (err) {
251
+ console.error(`
252
+ \u2717 Hub error: ${err.message}`);
253
+ return orchestrator.getState();
254
+ } finally {
255
+ process.removeListener("SIGINT", onSigint);
256
+ }
257
+ }
258
+ export {
259
+ startHub
260
+ };
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- HubAgent,
4
3
  assignRoleColors,
5
4
  clearSpeakingLine,
6
5
  renderAgentMessage,
@@ -11,7 +10,10 @@ import {
11
10
  renderRoundHeader,
12
11
  renderSummary,
13
12
  renderUserInterrupt
14
- } from "./chunk-O6MLS5QO.js";
13
+ } from "./chunk-OJL3PY36.js";
14
+ import {
15
+ HubAgent
16
+ } from "./chunk-NZ4X6GUC.js";
15
17
  import "./chunk-PDX44BCA.js";
16
18
 
17
19
  // src/hub/hub-server.ts
package/dist/index.js CHANGED
@@ -6,13 +6,11 @@ import {
6
6
  import {
7
7
  McpManager,
8
8
  SNAPSHOT_PROMPT,
9
- SessionManager,
10
9
  SkillManager,
11
10
  autoTrimSessionIfNeeded,
12
11
  clearDevState,
13
12
  computeCost,
14
13
  formatCost,
15
- getContentText,
16
14
  getPricing,
17
15
  loadDevState,
18
16
  parseSimpleYaml,
@@ -20,12 +18,38 @@ import {
20
18
  saveDevState,
21
19
  sessionHasMeaningfulContent,
22
20
  setupProxy
23
- } from "./chunk-ZAYDVWY4.js";
21
+ } from "./chunk-GQ647SF3.js";
22
+ import {
23
+ ToolExecutor,
24
+ ToolRegistry,
25
+ askUserContext,
26
+ estimateTokens,
27
+ googleSearchContext,
28
+ initTheme,
29
+ isInterrupted,
30
+ lastResponseStore,
31
+ renderDiff,
32
+ requestInterrupt,
33
+ resetInterrupt,
34
+ rlInternal,
35
+ setContextWindow,
36
+ setMaxOutputCap,
37
+ spawnAgentContext,
38
+ theme,
39
+ undoStack
40
+ } from "./chunk-Z2UJDFJK.js";
41
+ import "./chunk-HDSKW7Q3.js";
42
+ import "./chunk-ZWVIDFGY.js";
43
+ import "./chunk-AACNCJMD.js";
44
+ import {
45
+ SessionManager,
46
+ getContentText
47
+ } from "./chunk-TOTEUETI.js";
24
48
  import {
25
49
  getConfigDirUsage,
26
50
  listRecentCrashes,
27
51
  writeCrashLog
28
- } from "./chunk-SH7NTECG.js";
52
+ } from "./chunk-3DCAQKVZ.js";
29
53
  import {
30
54
  CONTENT_ONLY_STREAM_REMINDER,
31
55
  HALLUCINATION_CORRECTION_MESSAGE,
@@ -44,38 +68,16 @@ import {
44
68
  stripPseudoToolCalls,
45
69
  stripToolCallReminder
46
70
  } from "./chunk-AIZOARZY.js";
47
- import {
48
- ConfigManager
49
- } from "./chunk-OSTMMSOV.js";
50
- import {
51
- ToolExecutor,
52
- ToolRegistry,
53
- askUserContext,
54
- estimateTokens,
55
- googleSearchContext,
56
- initTheme,
57
- isInterrupted,
58
- lastResponseStore,
59
- renderDiff,
60
- requestInterrupt,
61
- resetInterrupt,
62
- rlInternal,
63
- setContextWindow,
64
- setMaxOutputCap,
65
- spawnAgentContext,
66
- theme,
67
- undoStack
68
- } from "./chunk-XWYWASPT.js";
69
- import "./chunk-HDSKW7Q3.js";
70
- import "./chunk-ZWVIDFGY.js";
71
- import "./chunk-NP7WOVIH.js";
72
71
  import {
73
72
  getStatsSnapshot,
74
73
  getTopFailingTools,
75
74
  getTopUsedTools,
76
75
  installFlushOnExit
77
- } from "./chunk-HVNEBTSF.js";
76
+ } from "./chunk-3SQMKA4I.js";
78
77
  import "./chunk-NXXNLLSG.js";
78
+ import {
79
+ ConfigManager
80
+ } from "./chunk-UAPNBQLU.js";
79
81
  import {
80
82
  AuthError,
81
83
  ProviderError,
@@ -102,7 +104,7 @@ import {
102
104
  SKILLS_DIR_NAME,
103
105
  VERSION,
104
106
  buildUserIdentityPrompt
105
- } from "./chunk-UE26B3RO.js";
107
+ } from "./chunk-3WLEDKOW.js";
106
108
  import {
107
109
  formatGitContextForPrompt,
108
110
  getGitContext,
@@ -112,14 +114,16 @@ import {
112
114
  fileCheckpoints
113
115
  } from "./chunk-4BKXL7SM.js";
114
116
  import {
115
- DEFAULT_PATTERNS,
116
117
  buildChatIndex,
117
118
  clearChatIndex,
118
119
  getChatIndexStatus,
119
- scanString,
120
120
  searchChatMemory
121
- } from "./chunk-RXM76HB7.js";
121
+ } from "./chunk-MM3F43H6.js";
122
122
  import "./chunk-KHYD3WXE.js";
123
+ import {
124
+ DEFAULT_PATTERNS,
125
+ scanString
126
+ } from "./chunk-SLSWPBK3.js";
123
127
  import "./chunk-VNNYHW6N.js";
124
128
  import "./chunk-OVWE4E46.js";
125
129
  import "./chunk-PDX44BCA.js";
@@ -1769,7 +1773,7 @@ No tools match "${filter}".
1769
1773
  const { join: join6 } = await import("path");
1770
1774
  const { existsSync: existsSync6 } = await import("fs");
1771
1775
  const { getGitRoot: getGitRoot2 } = await import("./git-context-7KIP4X2V.js");
1772
- const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-S4Y6A25E.js");
1776
+ const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-QDTWBWWC.js");
1773
1777
  const { approveProject, hashMcpFile } = await import("./project-trust-IFM7FXEV.js");
1774
1778
  const cwd = process.cwd();
1775
1779
  const projectRoot = getGitRoot2(cwd) ?? cwd;
@@ -2830,7 +2834,7 @@ ${hint}` : "")
2830
2834
  usage: "/test [command|filter]",
2831
2835
  async execute(args, ctx) {
2832
2836
  try {
2833
- const { executeTests } = await import("./run-tests-3QAZGHP2.js");
2837
+ const { executeTests } = await import("./run-tests-CNURD2ST.js");
2834
2838
  const argStr = args.join(" ").trim();
2835
2839
  let testArgs = {};
2836
2840
  if (argStr) {
@@ -5560,7 +5564,7 @@ Session '${this.resumeSessionId}' not found.
5560
5564
  })();
5561
5565
  void (async () => {
5562
5566
  try {
5563
- const { getChatIndexStatus: getChatIndexStatus2, buildChatIndex: buildChatIndex2 } = await import("./chat-index-LUQWWLKO.js");
5567
+ const { getChatIndexStatus: getChatIndexStatus2, buildChatIndex: buildChatIndex2 } = await import("./chat-index-2I7ZHRE5.js");
5564
5568
  const initial = getChatIndexStatus2();
5565
5569
  this.chatMemoryStatus = {
5566
5570
  exists: initial.exists,
@@ -7530,7 +7534,7 @@ program.command("web").description("Start Web UI server with browser-based chat
7530
7534
  console.error("Error: Invalid port number. Must be between 1 and 65535.");
7531
7535
  process.exit(1);
7532
7536
  }
7533
- const { startWebServer } = await import("./server-UL42EXOA.js");
7537
+ const { startWebServer } = await import("./server-RRUCZMMM.js");
7534
7538
  await startWebServer({ port, host: options.host });
7535
7539
  });
7536
7540
  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) => {
@@ -7697,12 +7701,12 @@ program.command("sessions").description("List recent conversation sessions").opt
7697
7701
  console.log(footer + "\n");
7698
7702
  });
7699
7703
  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) => {
7700
- const { runDoctorCli } = await import("./doctor-cli-FMTMDO2Z.js");
7704
+ const { runDoctorCli } = await import("./doctor-cli-4MTG6SFH.js");
7701
7705
  await runDoctorCli({ json: !!options.json, resetStats: !!options.resetStats });
7702
7706
  });
7703
7707
  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) => {
7704
7708
  try {
7705
- const batch = await import("./batch-W57MV5OT.js");
7709
+ const batch = await import("./batch-DBOCPVH5.js");
7706
7710
  switch (action) {
7707
7711
  case "submit":
7708
7712
  if (!arg) {
@@ -7745,7 +7749,7 @@ program.command("batch <action> [arg] [arg2]").description("Anthropic Message Ba
7745
7749
  }
7746
7750
  });
7747
7751
  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) => {
7748
- const { startMcpServer } = await import("./server-W4TBZN6I.js");
7752
+ const { startMcpServer } = await import("./server-HFG2SM3Y.js");
7749
7753
  await startMcpServer({
7750
7754
  allowDestructive: !!options.allowDestructive,
7751
7755
  allowOutsideCwd: !!options.allowOutsideCwd,
@@ -7754,7 +7758,7 @@ program.command("mcp-serve").description("Start an MCP server over STDIO, exposi
7754
7758
  });
7755
7759
  });
7756
7760
  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; diff fetched via `gh pr diff <num>`", (v) => parseInt(v, 10)).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)").action(async (options) => {
7757
- const { runCi } = await import("./ci-JYZGZSMP.js");
7761
+ const { runCi } = await import("./ci-AWA6KC3X.js");
7758
7762
  const result = await runCi({
7759
7763
  pr: options.pr,
7760
7764
  base: options.base,
@@ -7830,6 +7834,7 @@ program.command("help").description("Show a comprehensive guide to all aicli fea
7830
7834
  ` ${Y}--mix [providers]${R} Mixed multi-model: spread providers across roles (e.g. claude,openai,deepseek)`,
7831
7835
  ` ${Y}--steer${R} Human-in-the-loop: steer/stop between rounds`,
7832
7836
  ` ${Y}--vote${R} Convergence voting: 2/3 [CONVERGED] majority ends early`,
7837
+ ` ${Y}--no-save${R} Don't persist discussion to history (saved + replayable by default)`,
7833
7838
  ` ${Y}-c, --context <file>${R} Inject context doc (repeatable: -c a.md -c b.md)`,
7834
7839
  ` ${Y}--task${R} Task mode: agents plan & write code with tools`,
7835
7840
  ` ${Y}--distributed${R} Distributed mode (WebSocket, multi-process)`,
@@ -7887,7 +7892,7 @@ program.command("help").description("Show a comprehensive guide to all aicli fea
7887
7892
  ];
7888
7893
  console.log(lines.join("\n"));
7889
7894
  });
7890
- program.command("hub [topic]").description("Start multi-agent hub (discuss / brainstorm with multiple AI roles)").option("--preset <name>", "Use a built-in role preset (default: tech-review)").option("--roles <file>", "Load roles from a JSON file").option("--provider <name>", "Override default AI provider").option("-m, --model <name>", "Override default model").option("--mix [providers]", "Mixed multi-model: spread configured providers across roles (or --mix claude,openai,deepseek)").option("--steer", "Human-in-the-loop: pause between rounds to inject guidance or stop (discuss mode)").option("--vote", "Convergence voting: agents may [CONVERGED]; 2/3 majority ends early (discuss mode)").option("--max-rounds <n>", "Max discussion rounds (default: 10)").option("--presets", "List available role presets").option("--task", "Task mode: plan \u2192 approve \uFFFD\uFFFD execute with tools (agents write code)").option("--task-rounds <n>", "Max tool-call rounds per task (default: 30)").option("-c, --context <file>", "Inject context document (repeatable: -c a.md -c b.md)", (val, prev) => prev.concat(val), []).option("--distributed", "Start WebSocket server so remote aicli instances can join as agents").option("--port <n>", "WebSocket port for distributed mode (default: 9527)", "9527").action(async (topic, options) => {
7895
+ program.command("hub [topic]").description("Start multi-agent hub (discuss / brainstorm with multiple AI roles)").option("--preset <name>", "Use a built-in role preset (default: tech-review)").option("--roles <file>", "Load roles from a JSON file").option("--provider <name>", "Override default AI provider").option("-m, --model <name>", "Override default model").option("--mix [providers]", "Mixed multi-model: spread configured providers across roles (or --mix claude,openai,deepseek)").option("--steer", "Human-in-the-loop: pause between rounds to inject guidance or stop (discuss mode)").option("--vote", "Convergence voting: agents may [CONVERGED]; 2/3 majority ends early (discuss mode)").option("--no-save", "Do not persist the discussion to ~/.aicli/history (discuss mode saves by default)").option("--max-rounds <n>", "Max discussion rounds (default: 10)").option("--presets", "List available role presets").option("--task", "Task mode: plan \u2192 approve \uFFFD\uFFFD execute with tools (agents write code)").option("--task-rounds <n>", "Max tool-call rounds per task (default: 30)").option("-c, --context <file>", "Inject context document (repeatable: -c a.md -c b.md)", (val, prev) => prev.concat(val), []).option("--distributed", "Start WebSocket server so remote aicli instances can join as agents").option("--port <n>", "WebSocket port for distributed mode (default: 9527)", "9527").action(async (topic, options) => {
7891
7896
  const config = new ConfigManager();
7892
7897
  const registry = new ProviderRegistry();
7893
7898
  await registry.initialize(
@@ -7898,7 +7903,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
7898
7903
  }),
7899
7904
  config.get("customProviders")
7900
7905
  );
7901
- const { startHub } = await import("./hub-OP7EWTQQ.js");
7906
+ const { startHub } = await import("./hub-QRDXG527.js");
7902
7907
  await startHub(
7903
7908
  {
7904
7909
  topic: topic ?? "",
@@ -7909,6 +7914,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
7909
7914
  mix: options.mix,
7910
7915
  steer: options.steer === true,
7911
7916
  vote: options.vote === true,
7917
+ save: options.save !== false,
7912
7918
  mode: options.task === true ? "task" : void 0,
7913
7919
  maxRounds: options.maxRounds ? parseInt(options.maxRounds, 10) : void 0,
7914
7920
  listPresets: options.presets === true,
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ discussionToMessages,
4
+ persistDiscussion
5
+ } from "./chunk-RUJQ5OUB.js";
6
+ import "./chunk-TOTEUETI.js";
7
+ import "./chunk-SLSWPBK3.js";
8
+ import "./chunk-PDX44BCA.js";
9
+ export {
10
+ discussionToMessages,
11
+ persistDiscussion
12
+ };
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  executeTests,
4
4
  runTestsTool
5
- } from "./chunk-NP7WOVIH.js";
6
- import "./chunk-UE26B3RO.js";
5
+ } from "./chunk-AACNCJMD.js";
6
+ import "./chunk-3WLEDKOW.js";
7
7
  import "./chunk-PDX44BCA.js";
8
8
  export {
9
9
  executeTests,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  executeTests,
3
3
  runTestsTool
4
- } from "./chunk-2IODI5TI.js";
4
+ } from "./chunk-7OCOFVQP.js";
5
5
  import "./chunk-3RG5ZIWI.js";
6
6
  export {
7
7
  executeTests,
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ToolRegistry
4
- } from "./chunk-XWYWASPT.js";
4
+ } from "./chunk-Z2UJDFJK.js";
5
5
  import "./chunk-HDSKW7Q3.js";
6
6
  import "./chunk-ZWVIDFGY.js";
7
- import "./chunk-NP7WOVIH.js";
7
+ import "./chunk-AACNCJMD.js";
8
8
  import {
9
9
  runTool
10
- } from "./chunk-HVNEBTSF.js";
10
+ } from "./chunk-3SQMKA4I.js";
11
11
  import {
12
12
  getDangerLevel,
13
13
  schemaToJsonSchema
@@ -15,10 +15,11 @@ import {
15
15
  import "./chunk-2ZD3YTVM.js";
16
16
  import {
17
17
  VERSION
18
- } from "./chunk-UE26B3RO.js";
18
+ } from "./chunk-3WLEDKOW.js";
19
19
  import "./chunk-4BKXL7SM.js";
20
- import "./chunk-RXM76HB7.js";
20
+ import "./chunk-MM3F43H6.js";
21
21
  import "./chunk-KHYD3WXE.js";
22
+ import "./chunk-SLSWPBK3.js";
22
23
  import "./chunk-VNNYHW6N.js";
23
24
  import "./chunk-OVWE4E46.js";
24
25
  import "./chunk-PDX44BCA.js";