jinzd-ai-cli 0.4.211 → 0.4.213

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 (27) hide show
  1. package/README.md +30 -0
  2. package/README.zh-CN.md +30 -0
  3. package/dist/{batch-DE4RXKZD.js → batch-PKY63TME.js} +2 -2
  4. package/dist/{chat-index-UBCWHBLR.js → chat-index-R2E27VXN.js} +1 -1
  5. package/dist/{chunk-JBWA73GK.js → chunk-7NTFMLJJ.js} +1 -1
  6. package/dist/{chunk-C3OU2OPF.js → chunk-FGUKBIYO.js} +2 -2
  7. package/dist/{chunk-BE6ERF7M.js → chunk-G3PW3AOB.js} +1 -1
  8. package/dist/{chunk-E5XCM4A6.js → chunk-IWLVH32D.js} +1 -1
  9. package/dist/{chunk-ZY2N2N6T.js → chunk-J35V3IAH.js} +1 -1
  10. package/dist/{chunk-UOROWTGG.js → chunk-MRGWPCFQ.js} +26 -3
  11. package/dist/{chunk-W7UKO3PS.js → chunk-OQGVGPEK.js} +5 -0
  12. package/dist/{chunk-ZOPYREL5.js → chunk-THNECAAY.js} +464 -67
  13. package/dist/{chunk-6NS6643Y.js → chunk-UDMU4FUF.js} +1 -1
  14. package/dist/{ci-XMUEX526.js → ci-HBZ6CIW5.js} +2 -2
  15. package/dist/{constants-AWTIQIWG.js → constants-CAUBTSFW.js} +1 -1
  16. package/dist/{doctor-cli-SSI6ETFT.js → doctor-cli-5Z5UWYW6.js} +4 -4
  17. package/dist/electron-server.js +794 -241
  18. package/dist/{hub-INUJND2G.js → hub-ZRADBR76.js} +1 -1
  19. package/dist/index.js +205 -19
  20. package/dist/{run-tests-PACN4UYX.js → run-tests-7J3PNWVS.js} +1 -1
  21. package/dist/{run-tests-3MHWUF43.js → run-tests-DSOJBJWA.js} +2 -2
  22. package/dist/{server-7USZJJAH.js → server-PWBWHVYB.js} +4 -4
  23. package/dist/{server-BTSKOPQI.js → server-U4I7RI42.js} +175 -10
  24. package/dist/{task-orchestrator-OV4O25MX.js → task-orchestrator-RUXWRMQV.js} +4 -4
  25. package/dist/{usage-T2P6FTE7.js → usage-2P6TIBTN.js} +2 -2
  26. package/dist/web/client/app.js +1 -1
  27. package/package.json +1 -1
@@ -154,7 +154,7 @@ ${content}`);
154
154
  }
155
155
  }
156
156
  async function runTaskMode(config, providers, configManager, topic) {
157
- const { TaskOrchestrator } = await import("./task-orchestrator-OV4O25MX.js");
157
+ const { TaskOrchestrator } = await import("./task-orchestrator-RUXWRMQV.js");
158
158
  const orchestrator = new TaskOrchestrator(config, providers, configManager);
159
159
  let interrupted = false;
160
160
  const onSigint = () => {
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  scanProject,
16
16
  sessionHasMeaningfulContent,
17
17
  setupProxy
18
- } from "./chunk-C3OU2OPF.js";
18
+ } from "./chunk-FGUKBIYO.js";
19
19
  import {
20
20
  buildReviewPrompt,
21
21
  buildSecurityReviewPrompt
@@ -25,25 +25,32 @@ import {
25
25
  ToolRegistry,
26
26
  askUserContext,
27
27
  cleanupRejectedTeeFile,
28
+ clearRecentlyDeniedAutoActions,
28
29
  estimateTokens,
29
30
  formatPermissionProfileWarning,
31
+ getPendingHookTrust,
32
+ getRecentlyDeniedAutoActions,
30
33
  googleSearchContext,
31
34
  initTheme,
32
35
  isInterrupted,
33
36
  lastResponseStore,
37
+ listHooks,
34
38
  renderDiff,
35
39
  requestInterrupt,
36
40
  resetInterrupt,
37
41
  rlInternal,
42
+ runLifecycleHooks,
38
43
  setContextWindow,
39
44
  setMaxOutputCap,
40
45
  spawnAgentContext,
41
46
  theme,
42
- undoStack
43
- } from "./chunk-ZOPYREL5.js";
47
+ trustHook,
48
+ undoStack,
49
+ untrustHook
50
+ } from "./chunk-THNECAAY.js";
44
51
  import "./chunk-T2NL5ZIA.js";
45
52
  import "./chunk-BXP6YZ2P.js";
46
- import "./chunk-6NS6643Y.js";
53
+ import "./chunk-UDMU4FUF.js";
47
54
  import {
48
55
  SessionManager,
49
56
  getContentText
@@ -60,7 +67,7 @@ import {
60
67
  getConfigDirUsage,
61
68
  listRecentCrashes,
62
69
  writeCrashLog
63
- } from "./chunk-BE6ERF7M.js";
70
+ } from "./chunk-G3PW3AOB.js";
64
71
  import {
65
72
  ProviderRegistry
66
73
  } from "./chunk-QMXC327F.js";
@@ -69,7 +76,7 @@ import {
69
76
  getTopFailingTools,
70
77
  getTopUsedTools,
71
78
  installFlushOnExit
72
- } from "./chunk-JBWA73GK.js";
79
+ } from "./chunk-7NTFMLJJ.js";
73
80
  import {
74
81
  CONTENT_ONLY_STREAM_REMINDER,
75
82
  TEE_FINAL_USER_NUDGE,
@@ -91,7 +98,7 @@ import {
91
98
  } from "./chunk-XPBEJB27.js";
92
99
  import {
93
100
  ConfigManager
94
- } from "./chunk-UOROWTGG.js";
101
+ } from "./chunk-MRGWPCFQ.js";
95
102
  import {
96
103
  AuthError,
97
104
  ProviderError,
@@ -117,7 +124,7 @@ import {
117
124
  SKILLS_DIR_NAME,
118
125
  VERSION,
119
126
  buildUserIdentityPrompt
120
- } from "./chunk-E5XCM4A6.js";
127
+ } from "./chunk-IWLVH32D.js";
121
128
  import {
122
129
  formatGitContextForPrompt,
123
130
  getGitContext,
@@ -874,7 +881,9 @@ function createDefaultCommands() {
874
881
  ["/route [on|off|show|test <msg>]", "Smart model routing rules"],
875
882
  ["/think [on|off|status]", "Toggle Extended Thinking (deep reasoning)"],
876
883
  ["/plan [execute|exit|status]", "Enter/manage Plan Mode (read-only)"],
877
- ["/yolo [on|off]", "Toggle session auto-approve (skip confirmations)"]
884
+ ["/auto [on|off|status]", "Rule-based low-risk auto approval"],
885
+ ["/permissions recently-denied|clear-denied", "Inspect permission and Auto Mode decisions"],
886
+ ["/yolo [on|off]", "Toggle write auto-approve (destructive still confirms)"]
878
887
  ]
879
888
  },
880
889
  {
@@ -934,6 +943,7 @@ function createDefaultCommands() {
934
943
  ["/config [set|get|show]", "Config wizard / get / set / show all"],
935
944
  ["/profile [show|set|clear]", "View or edit your identity"],
936
945
  ["/security [status|scan|on|off]", "Sensitive-data redaction"],
946
+ ["/hooks [list|trust|untrust]", "Lifecycle hooks and project hook trust"],
937
947
  ["/doctor", "Health check (API keys, config, MCP, crashes, tool stats)"],
938
948
  ["/bug [--copy]", "Generate bug report template"],
939
949
  ["/about", "About ai-cli & author info"],
@@ -1356,6 +1366,8 @@ No commands match "${filter}".
1356
1366
  console.log(` Ctx Win : ${ctxStr}`);
1357
1367
  console.log(" PermProf : " + (ctx.config.get("defaultPermissionProfile") ?? "legacy"));
1358
1368
  console.log(" Network : " + (ctx.config.get("networkPolicy")?.enabled ?? false ? "on" : "off"));
1369
+ console.log(" AutoMode : " + (ctx.getToolExecutor().sessionAutoMode ? "on" : "off"));
1370
+ console.log(" Hooks : " + getPendingHookTrust(ctx.config.get("hooks") ?? void 0, ctx.config.getConfigDir()).length + " pending trust");
1359
1371
  console.log(` Messages : ${session?.messages.length ?? 0}`);
1360
1372
  console.log(` Session : ${session?.id.slice(0, 8) ?? "none"}`);
1361
1373
  if (layers.length > 0) {
@@ -1649,7 +1661,7 @@ No tools match "${filter}".
1649
1661
  const { join: join5 } = await import("path");
1650
1662
  const { existsSync: existsSync5 } = await import("fs");
1651
1663
  const { getGitRoot: getGitRoot2 } = await import("./git-context-EXOEHQSF.js");
1652
- const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-AWTIQIWG.js");
1664
+ const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-CAUBTSFW.js");
1653
1665
  const { approveProject, hashMcpFile } = await import("./project-trust-NKYHL3VZ.js");
1654
1666
  const cwd = process.cwd();
1655
1667
  const projectRoot = getGitRoot2(cwd) ?? cwd;
@@ -2708,7 +2720,7 @@ ${hint}` : "")
2708
2720
  usage: "/test [command|filter]",
2709
2721
  async execute(args, ctx) {
2710
2722
  try {
2711
- const { executeTests } = await import("./run-tests-3MHWUF43.js");
2723
+ const { executeTests } = await import("./run-tests-DSOJBJWA.js");
2712
2724
  const argStr = args.join(" ").trim();
2713
2725
  let testArgs = {};
2714
2726
  if (argStr) {
@@ -3287,6 +3299,71 @@ Summary: ${fileMap.size} file(s) \u2014 ${newFiles} new, ${modifiedFiles} modifi
3287
3299
  }
3288
3300
  }
3289
3301
  },
3302
+ {
3303
+ name: "hooks",
3304
+ description: "Manage lifecycle hooks and project hook trust",
3305
+ usage: "/hooks [list|inspect <id>|trust <id>|untrust <id>|disable]",
3306
+ execute(args, ctx) {
3307
+ const sub = (args[0] || "list").toLowerCase();
3308
+ const hooks = listHooks(ctx.config.get("hooks") ?? void 0, ctx.config.getConfigDir());
3309
+ const findHook = (id) => hooks.find((h) => h.id === id || h.hash.startsWith(id ?? ""));
3310
+ if (sub === "list") {
3311
+ console.log(theme.heading(" Hooks"));
3312
+ if (hooks.length === 0) {
3313
+ console.log(theme.dim(" No hooks configured."));
3314
+ } else {
3315
+ for (const h of hooks) {
3316
+ const trust = h.disabled ? theme.dim("disabled") : h.trusted ? theme.success("trusted") : theme.warning("pending");
3317
+ console.log(` ${h.id.padEnd(18)} ${h.source.padEnd(7)} ${trust} ${h.hash.slice(0, 12)} ${theme.dim(h.command.slice(0, 80))}`);
3318
+ }
3319
+ }
3320
+ console.log();
3321
+ return;
3322
+ }
3323
+ if (sub === "inspect") {
3324
+ const h = findHook(args[1]);
3325
+ if (!h) {
3326
+ console.log(theme.warning(" Hook not found. Use /hooks list."));
3327
+ return;
3328
+ }
3329
+ console.log(theme.heading(" Hook"));
3330
+ console.log(` id : ${h.id}`);
3331
+ console.log(` event : ${h.event}`);
3332
+ console.log(` source : ${h.source}`);
3333
+ console.log(` hash : ${h.hash}`);
3334
+ console.log(` trusted : ${h.trusted ? "yes" : "no"}`);
3335
+ console.log(` disabled: ${h.disabled ? "yes" : "no"}`);
3336
+ console.log(` command : ${h.command}`);
3337
+ console.log();
3338
+ return;
3339
+ }
3340
+ if (sub === "trust" || sub === "untrust") {
3341
+ const h = findHook(args[1]);
3342
+ if (!h) {
3343
+ console.log(theme.warning(" Hook not found. Use /hooks list."));
3344
+ return;
3345
+ }
3346
+ if (sub === "trust") {
3347
+ trustHook(ctx.config.getConfigDir(), h);
3348
+ console.log(theme.success(` \u2713 trusted ${h.id} (${h.hash.slice(0, 12)})`));
3349
+ } else {
3350
+ untrustHook(ctx.config.getConfigDir(), h);
3351
+ console.log(theme.success(` \u2713 untrusted ${h.id}`));
3352
+ }
3353
+ console.log();
3354
+ return;
3355
+ }
3356
+ if (sub === "disable") {
3357
+ const cfg = ctx.config.get("hooks") ?? {};
3358
+ ctx.config.set("hooks", { ...cfg, enabled: false });
3359
+ console.log(theme.success(" \u2713 hooks disabled in user config"));
3360
+ console.log();
3361
+ return;
3362
+ }
3363
+ console.log(theme.warning(" Usage: /hooks [list|inspect <id>|trust <id>|untrust <id>|disable]"));
3364
+ console.log();
3365
+ }
3366
+ },
3290
3367
  {
3291
3368
  name: "security",
3292
3369
  description: "Sensitive-data redaction \u2014 status, scan sessions, toggle on/off",
@@ -3306,6 +3383,8 @@ Summary: ${fileMap.size} file(s) \u2014 ${newFiles} new, ${modifiedFiles} modifi
3306
3383
  console.log(` mode : ${security.mode}`);
3307
3384
  console.log(" profile : " + (ctx.config.get("defaultPermissionProfile") ?? "legacy"));
3308
3385
  console.log(" network : " + (ctx.config.get("networkPolicy")?.enabled ?? false ? "on" : "off"));
3386
+ console.log(" autoMode : " + (ctx.getToolExecutor().sessionAutoMode ? "on" : "off"));
3387
+ console.log(" hooks : " + getPendingHookTrust(ctx.config.get("hooks") ?? void 0, ctx.config.getConfigDir()).length + " pending trust");
3309
3388
  console.log(` patterns : ${DEFAULT_PATTERNS.length} built-in + ${security.customPatterns?.length ?? 0} custom`);
3310
3389
  console.log(` last save : ${ctx.sessions.lastRedactionHits} hit(s) redacted`);
3311
3390
  console.log();
@@ -3377,9 +3456,64 @@ Summary: ${fileMap.size} file(s) \u2014 ${newFiles} new, ${modifiedFiles} modifi
3377
3456
  console.log();
3378
3457
  }
3379
3458
  },
3459
+ {
3460
+ name: "auto",
3461
+ description: "Toggle rule-based Auto Mode for low-risk actions",
3462
+ usage: "/auto [on|off|status]",
3463
+ execute(args, ctx) {
3464
+ const sub = args[0]?.toLowerCase() ?? "status";
3465
+ const executor = ctx.getToolExecutor();
3466
+ if (sub === "on") {
3467
+ executor.sessionAutoMode = true;
3468
+ console.log(theme.warning(" \u26A1 Auto Mode ON \u2014 low-risk actions may auto-run; high-risk actions still confirm or deny."));
3469
+ console.log(theme.dim(" Auto Mode is session-scoped and is not enabled by project config."));
3470
+ } else if (sub === "off") {
3471
+ executor.sessionAutoMode = false;
3472
+ console.log(theme.info(" Auto Mode disabled."));
3473
+ } else if (sub === "status") {
3474
+ console.log(` Auto Mode : ${executor.sessionAutoMode ? theme.warning("on") : theme.dim("off")}`);
3475
+ console.log(theme.dim(" Scope : current session only"));
3476
+ console.log(theme.dim(" Denied : /permissions recently-denied"));
3477
+ } else {
3478
+ console.log(theme.warning(" Usage: /auto [on|off|status]"));
3479
+ }
3480
+ console.log();
3481
+ }
3482
+ },
3483
+ {
3484
+ name: "permissions",
3485
+ description: "Inspect permission and Auto Mode decisions",
3486
+ usage: "/permissions recently-denied|clear-denied",
3487
+ execute(args) {
3488
+ const sub = args[0]?.toLowerCase() ?? "recently-denied";
3489
+ if (sub === "recently-denied") {
3490
+ const rows = getRecentlyDeniedAutoActions();
3491
+ if (rows.length === 0) {
3492
+ console.log(theme.success(" No recently denied Auto Mode actions."));
3493
+ } else {
3494
+ console.log(theme.warning(` Recently denied Auto Mode actions (${rows.length})`));
3495
+ for (const r of rows.slice(0, 20)) {
3496
+ console.log(` - ${r.timestamp} ${theme.error(r.tool)} ${theme.dim(r.ruleId)}`);
3497
+ console.log(` ${r.reason}`);
3498
+ console.log(theme.dim(` ${r.argsPreview}`));
3499
+ }
3500
+ }
3501
+ console.log();
3502
+ return;
3503
+ }
3504
+ if (sub === "clear-denied") {
3505
+ clearRecentlyDeniedAutoActions();
3506
+ console.log(theme.info(" Cleared recently denied Auto Mode actions."));
3507
+ console.log();
3508
+ return;
3509
+ }
3510
+ console.log(theme.warning(" Usage: /permissions recently-denied|clear-denied"));
3511
+ console.log();
3512
+ }
3513
+ },
3380
3514
  {
3381
3515
  name: "yolo",
3382
- description: "Toggle session auto-approve (skip all confirmations)",
3516
+ description: "Toggle session auto-approve for write tools (/yolo)",
3383
3517
  usage: "/yolo [on|off]",
3384
3518
  execute(args, ctx) {
3385
3519
  const sub = args[0]?.toLowerCase();
@@ -4465,6 +4599,7 @@ var Repl = class {
4465
4599
  const permissionProfiles = this.config.get("permissionProfiles") ?? {};
4466
4600
  this.toolExecutor.setConfig({
4467
4601
  hookConfig: this.config.get("hooks") ?? void 0,
4602
+ hookConfigDir: this.config.getConfigDir(),
4468
4603
  permissionRules: this.config.get("permissionRules") ?? [],
4469
4604
  defaultPermission: this.config.get("defaultPermission") ?? "confirm",
4470
4605
  permissionProfileName,
@@ -4473,6 +4608,11 @@ var Repl = class {
4473
4608
  workspaceRoot: process.cwd(),
4474
4609
  networkPolicy: this.config.get("networkPolicy")
4475
4610
  });
4611
+ const pendingHooks = getPendingHookTrust(this.config.get("hooks") ?? void 0, this.config.getConfigDir());
4612
+ if (pendingHooks.length > 0) {
4613
+ process.stderr.write(theme.warning(" \u26A0 " + pendingHooks.length + " project hook(s) require trust. Run /hooks list and /hooks trust <id>.\n"));
4614
+ }
4615
+ runLifecycleHooks(this.config.get("hooks") ?? void 0, "SessionStart", { source: "repl" }, { configDir: this.config.getConfigDir() });
4476
4616
  if (this.config.get("alwaysYolo") === true) {
4477
4617
  this.toolExecutor.sessionAutoApprove = true;
4478
4618
  }
@@ -4944,6 +5084,21 @@ ${skillContent}`);
4944
5084
  );
4945
5085
  return false;
4946
5086
  }
5087
+ const preDecisions = runLifecycleHooks(
5088
+ this.config.get("hooks") ?? void 0,
5089
+ "PreCompact",
5090
+ { sessionId: session.id, messageCount: session.messages.length, instruction },
5091
+ { configDir: this.config.getConfigDir(), onSummary: (msg) => process.stdout.write(theme.dim(" [hook] " + msg) + "\n") }
5092
+ );
5093
+ const preDeny = preDecisions.find((d) => d.action === "deny");
5094
+ if (preDeny) {
5095
+ process.stdout.write(theme.warning(" \u26A0 Compact blocked by hook: " + (preDeny.reason ?? "PreCompact denied") + "\n"));
5096
+ return false;
5097
+ }
5098
+ for (const d of preDecisions) {
5099
+ const warnings = [d.warning, ...d.warnings ?? []].filter(Boolean);
5100
+ for (const w of warnings) process.stdout.write(theme.warning(" \u26A0 Hook warning: " + w + "\n"));
5101
+ }
4947
5102
  const provider = this.providers.get(this.currentProvider);
4948
5103
  const modelParams = this.getModelParams();
4949
5104
  const spinner = this.renderer.showSpinner("Compacting session...");
@@ -5005,6 +5160,12 @@ ${response.content.trim()}
5005
5160
  const tokensBefore = ctxWindow > 0 ? this.estimateConversationTokens() : 0;
5006
5161
  const removedCount = session.compact(summaryMsg, ackMsg, COMPACT_KEEP_LAST);
5007
5162
  const afterCount = session.messages.length;
5163
+ runLifecycleHooks(
5164
+ this.config.get("hooks") ?? void 0,
5165
+ "PostCompact",
5166
+ { sessionId: session.id, beforeCount, afterCount, removedCount, keepLast: COMPACT_KEEP_LAST, instruction },
5167
+ { configDir: this.config.getConfigDir(), onSummary: (msg) => process.stdout.write(theme.dim(" [hook] " + msg) + "\n") }
5168
+ );
5008
5169
  const tokensAfter = ctxWindow > 0 ? this.estimateConversationTokens() : 0;
5009
5170
  const pctBefore = ctxWindow > 0 ? Math.round(tokensBefore / ctxWindow * 100) : 0;
5010
5171
  const pctAfter = ctxWindow > 0 ? Math.round(tokensAfter / ctxWindow * 100) : 0;
@@ -5440,8 +5601,32 @@ Session '${this.resumeSessionId}' not found.
5440
5601
  });
5441
5602
  });
5442
5603
  }
5604
+ runUserPromptHooks(sessionId, userInput) {
5605
+ const promptDecisions = runLifecycleHooks(
5606
+ this.config.get("hooks") ?? void 0,
5607
+ "UserPromptSubmit",
5608
+ { sessionId, prompt: userInput },
5609
+ { configDir: this.config.getConfigDir(), onSummary: (msg) => process.stdout.write(theme.dim(" [hook] " + msg) + "\n") }
5610
+ );
5611
+ const promptDeny = promptDecisions.find((d) => d.action === "deny");
5612
+ if (promptDeny) {
5613
+ process.stdout.write(theme.warning(" \u26A0 Prompt blocked by hook: " + (promptDeny.reason ?? "UserPromptSubmit denied") + "\n"));
5614
+ return false;
5615
+ }
5616
+ for (const d of promptDecisions) {
5617
+ const warnings = [d.warning, ...d.warnings ?? []].filter(Boolean);
5618
+ for (const w of warnings) process.stdout.write(theme.warning(" \u26A0 Hook warning: " + w + "\n"));
5619
+ }
5620
+ const secretHits = scanString(userInput, { customRegexes: [] });
5621
+ if (secretHits.length > 0) {
5622
+ const kinds = [...new Set(secretHits.map((h) => h.kind))].join(", ");
5623
+ process.stdout.write(theme.warning(" \u26A0 Possible secret in prompt (" + kinds + "). It will be sent unless you interrupt now.\n"));
5624
+ }
5625
+ return true;
5626
+ }
5443
5627
  async handleChat(userInput) {
5444
5628
  const session = this.sessions.current;
5629
+ if (!this.runUserPromptHooks(session.id, userInput)) return;
5445
5630
  const { parts, hasImage, refs } = parseAtReferences(userInput, process.cwd());
5446
5631
  for (const ref of refs) {
5447
5632
  if (ref.type === "notfound") {
@@ -6906,6 +7091,7 @@ Tip: You can continue the conversation by asking the AI to proceed.`
6906
7091
  void this.shutdownAsync();
6907
7092
  }
6908
7093
  async shutdownAsync() {
7094
+ runLifecycleHooks(this.config.get("hooks") ?? void 0, "Stop", { sessionId: this.sessions.current?.id }, { configDir: this.config.getConfigDir() });
6909
7095
  this.running = false;
6910
7096
  const sessionId = this.sessions.current?.id;
6911
7097
  if (sessionId) {
@@ -7020,7 +7206,7 @@ program.command("web").description("Start Web UI server with browser-based chat
7020
7206
  console.error("Error: Invalid port number. Must be between 1 and 65535.");
7021
7207
  process.exit(1);
7022
7208
  }
7023
- const { startWebServer } = await import("./server-BTSKOPQI.js");
7209
+ const { startWebServer } = await import("./server-U4I7RI42.js");
7024
7210
  await startWebServer({ port, host: options.host });
7025
7211
  });
7026
7212
  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) => {
@@ -7187,16 +7373,16 @@ program.command("sessions").description("List recent conversation sessions").opt
7187
7373
  console.log(footer + "\n");
7188
7374
  });
7189
7375
  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) => {
7190
- const { runUsageCli } = await import("./usage-T2P6FTE7.js");
7376
+ const { runUsageCli } = await import("./usage-2P6TIBTN.js");
7191
7377
  await runUsageCli(options);
7192
7378
  });
7193
7379
  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) => {
7194
- const { runDoctorCli } = await import("./doctor-cli-SSI6ETFT.js");
7380
+ const { runDoctorCli } = await import("./doctor-cli-5Z5UWYW6.js");
7195
7381
  await runDoctorCli({ json: !!options.json, resetStats: !!options.resetStats });
7196
7382
  });
7197
7383
  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) => {
7198
7384
  try {
7199
- const batch = await import("./batch-DE4RXKZD.js");
7385
+ const batch = await import("./batch-PKY63TME.js");
7200
7386
  switch (action) {
7201
7387
  case "submit":
7202
7388
  if (!arg) {
@@ -7239,7 +7425,7 @@ program.command("batch <action> [arg] [arg2]").description("Anthropic Message Ba
7239
7425
  }
7240
7426
  });
7241
7427
  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) => {
7242
- const { startMcpServer } = await import("./server-7USZJJAH.js");
7428
+ const { startMcpServer } = await import("./server-PWBWHVYB.js");
7243
7429
  await startMcpServer({
7244
7430
  allowDestructive: !!options.allowDestructive,
7245
7431
  allowOutsideCwd: !!options.allowOutsideCwd,
@@ -7248,7 +7434,7 @@ program.command("mcp-serve").description("Start an MCP server over STDIO, exposi
7248
7434
  });
7249
7435
  });
7250
7436
  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) => {
7251
- const { runCi } = await import("./ci-XMUEX526.js");
7437
+ const { runCi } = await import("./ci-HBZ6CIW5.js");
7252
7438
  const result = await runCi({
7253
7439
  pr: options.pr,
7254
7440
  base: options.base,
@@ -7394,7 +7580,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
7394
7580
  }),
7395
7581
  config.get("customProviders")
7396
7582
  );
7397
- const { startHub } = await import("./hub-INUJND2G.js");
7583
+ const { startHub } = await import("./hub-ZRADBR76.js");
7398
7584
  await startHub(
7399
7585
  {
7400
7586
  topic: topic ?? "",
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  executeTests,
3
3
  runTestsTool
4
- } from "./chunk-ZY2N2N6T.js";
4
+ } from "./chunk-J35V3IAH.js";
5
5
  export {
6
6
  executeTests,
7
7
  runTestsTool
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  executeTests,
4
4
  runTestsTool
5
- } from "./chunk-6NS6643Y.js";
6
- import "./chunk-E5XCM4A6.js";
5
+ } from "./chunk-UDMU4FUF.js";
6
+ import "./chunk-IWLVH32D.js";
7
7
  export {
8
8
  executeTests,
9
9
  runTestsTool
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ToolRegistry
4
- } from "./chunk-ZOPYREL5.js";
4
+ } from "./chunk-THNECAAY.js";
5
5
  import "./chunk-T2NL5ZIA.js";
6
6
  import "./chunk-BXP6YZ2P.js";
7
- import "./chunk-6NS6643Y.js";
7
+ import "./chunk-UDMU4FUF.js";
8
8
  import {
9
9
  runTool
10
- } from "./chunk-JBWA73GK.js";
10
+ } from "./chunk-7NTFMLJJ.js";
11
11
  import {
12
12
  getDangerLevel,
13
13
  schemaToJsonSchema
@@ -15,7 +15,7 @@ import {
15
15
  import "./chunk-TZQHYZKT.js";
16
16
  import {
17
17
  VERSION
18
- } from "./chunk-E5XCM4A6.js";
18
+ } from "./chunk-IWLVH32D.js";
19
19
  import "./chunk-4BKXL7SM.js";
20
20
  import "./chunk-TB4W4Y4T.js";
21
21
  import "./chunk-KHYD3WXE.js";