jinzd-ai-cli 0.4.281 → 0.4.283

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-237ZXBQD.js → batch-6WWR4P5U.js} +2 -2
  2. package/dist/{chunk-5GYOQ7EF.js → chunk-2YVZTDP4.js} +1 -1
  3. package/dist/{chunk-J3RWNQOF.js → chunk-4J7FIGQD.js} +1 -1
  4. package/dist/{chunk-UTJQXG4P.js → chunk-CUS4FJVP.js} +3 -3
  5. package/dist/{chunk-FHRIDE2T.js → chunk-D7BIF6JO.js} +4 -4
  6. package/dist/{chunk-WUIOUJA2.js → chunk-F3YN754E.js} +1 -1
  7. package/dist/{chunk-6NO5FZW6.js → chunk-IUVDZVZ4.js} +18 -0
  8. package/dist/{chunk-IXEKDAIX.js → chunk-JR2J3V6J.js} +1 -1
  9. package/dist/{chunk-2FCKZ3OS.js → chunk-JSQGDPDK.js} +1 -1
  10. package/dist/{chunk-J5TXHFDO.js → chunk-LXJF46SO.js} +191 -4
  11. package/dist/{chunk-H2VE4TTN.js → chunk-M3UJ2JCW.js} +1 -1
  12. package/dist/{chunk-VB54ILH7.js → chunk-NUJTNH76.js} +1 -1
  13. package/dist/{chunk-4XJVSMZ6.js → chunk-QDOFRKY2.js} +1 -1
  14. package/dist/{chunk-BVGSR3BA.js → chunk-RALUII7R.js} +3 -3
  15. package/dist/{chunk-L7C34TFI.js → chunk-V4IY5CRJ.js} +1 -1
  16. package/dist/{chunk-JT2A2M4F.js → chunk-Z3QNLNSU.js} +1 -1
  17. package/dist/{ci-LXRTYJ6F.js → ci-FTS7XNWA.js} +4 -4
  18. package/dist/{ci-format-II3OT2VU.js → ci-format-N5PXGS7Y.js} +2 -2
  19. package/dist/{constants-X53QCUTP.js → constants-3B5KIPLK.js} +1 -1
  20. package/dist/{doctor-cli-6JCJEQR4.js → doctor-cli-VRMIEREY.js} +4 -4
  21. package/dist/electron-server.js +355 -77
  22. package/dist/{hub-RXAFF7QI.js → hub-TZET5544.js} +2 -2
  23. package/dist/index.js +153 -152
  24. package/dist/{persist-TBQILDSE.js → persist-S77WRVLD.js} +2 -2
  25. package/dist/{persistent-memory-7CKJLS25.js → persistent-memory-3OYRXF2L.js} +2 -2
  26. package/dist/{persistent-memory-WAKFKH2I.js → persistent-memory-IPCUJVWF.js} +2 -2
  27. package/dist/{pr-DZTRHAMG.js → pr-XUXWP52Z.js} +4 -4
  28. package/dist/{run-tests-4ESYEROQ.js → run-tests-3T5WRG62.js} +2 -2
  29. package/dist/{run-tests-XGCNUT5S.js → run-tests-PUOXATHQ.js} +2 -2
  30. package/dist/{server-6RYXFG3H.js → server-4XSDRPZM.js} +176 -82
  31. package/dist/{server-EFA7UP4I.js → server-WGEGVVY5.js} +5 -5
  32. package/dist/{task-orchestrator-H3AEIHR3.js → task-orchestrator-LEW2VSZD.js} +5 -5
  33. package/dist/{usage-W7TZWHY7.js → usage-7VEAXMMP.js} +2 -2
  34. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  AUTO_COMPACT_INSTRUCTION,
4
+ MEMORY_USAGE,
4
5
  McpManager,
5
6
  SNAPSHOT_PROMPT,
6
7
  SkillManager,
@@ -10,6 +11,9 @@ import {
10
11
  armDeferredSave,
11
12
  autoTrimSessionIfNeeded,
12
13
  buildInitPrompt,
14
+ buildMemoryStatusView,
15
+ buildRecallView,
16
+ buildRewindList,
13
17
  buildSessionCostReport,
14
18
  buildSessionExport,
15
19
  checkpointDeletedMessage,
@@ -26,19 +30,26 @@ import {
26
30
  evaluateContextPressure,
27
31
  filterMemoryEntries,
28
32
  formatCheckpointList,
33
+ formatForkReport,
34
+ formatRewindReport,
29
35
  formatSessionSummaryLine,
30
36
  loadDevState,
31
37
  parseBatchDeleteArgs,
32
38
  parseCheckpointCommand,
33
39
  parseCleanArgs,
34
40
  parseExportArgs,
41
+ parseMemoryCommand,
35
42
  parseMemoryShowFilters,
36
43
  parseModelCommand,
44
+ parseRewindArgs,
37
45
  parseRouteCommand,
38
46
  parseSessionListArgs,
39
47
  parseSimpleYaml,
40
48
  persistToolRound,
41
49
  readGitDiff,
50
+ rebuildDoneMessage,
51
+ rebuildStartMessage,
52
+ resolveForkPoint,
42
53
  resolveModelSwitch,
43
54
  resolveProviderSwitch,
44
55
  resolveSessionRef,
@@ -54,7 +65,7 @@ import {
54
65
  setupProxy,
55
66
  snapshotFile,
56
67
  stripRoutingTags
57
- } from "./chunk-J5TXHFDO.js";
68
+ } from "./chunk-LXJF46SO.js";
58
69
  import {
59
70
  CostTracker,
60
71
  computeCost,
@@ -84,7 +95,7 @@ import {
84
95
  setMaxOutputCap,
85
96
  spawnAgentContext,
86
97
  undoStack
87
- } from "./chunk-FHRIDE2T.js";
98
+ } from "./chunk-D7BIF6JO.js";
88
99
  import {
89
100
  buildReviewPrompt,
90
101
  buildSecurityReviewPrompt
@@ -125,7 +136,7 @@ import {
125
136
  touchMemoryReferences,
126
137
  updateMemoryApproval,
127
138
  updateMemoryEntry
128
- } from "./chunk-H2VE4TTN.js";
139
+ } from "./chunk-M3UJ2JCW.js";
129
140
  import "./chunk-4DEMGCK4.js";
130
141
  import "./chunk-UUSRWSSX.js";
131
142
  import "./chunk-CKH4KQ4E.js";
@@ -138,7 +149,7 @@ import {
138
149
  import {
139
150
  SessionManager,
140
151
  getContentText
141
- } from "./chunk-6NO5FZW6.js";
152
+ } from "./chunk-IUVDZVZ4.js";
142
153
  import "./chunk-NYNSYLFY.js";
143
154
  import {
144
155
  DEFAULT_PATTERNS,
@@ -149,7 +160,7 @@ import {
149
160
  formatDoctorReport,
150
161
  loadContextFiles,
151
162
  writeCrashLog
152
- } from "./chunk-BVGSR3BA.js";
163
+ } from "./chunk-RALUII7R.js";
153
164
  import {
154
165
  describePlugin,
155
166
  getActivePluginAssets,
@@ -166,14 +177,14 @@ import {
166
177
  trustHook,
167
178
  trustPlugin,
168
179
  untrustHook
169
- } from "./chunk-L7C34TFI.js";
180
+ } from "./chunk-V4IY5CRJ.js";
170
181
  import {
171
182
  ProviderRegistry,
172
183
  listBuiltInProviderMetadata
173
184
  } from "./chunk-UGY5SVNX.js";
174
185
  import {
175
186
  ConfigManager
176
- } from "./chunk-4XJVSMZ6.js";
187
+ } from "./chunk-QDOFRKY2.js";
177
188
  import {
178
189
  CONTENT_ONLY_STREAM_REMINDER,
179
190
  TEE_FINAL_USER_NUDGE,
@@ -211,7 +222,7 @@ import {
211
222
  import {
212
223
  fileCheckpoints
213
224
  } from "./chunk-4BKXL7SM.js";
214
- import "./chunk-J3RWNQOF.js";
225
+ import "./chunk-4J7FIGQD.js";
215
226
  import {
216
227
  AGENTIC_BEHAVIOR_GUIDELINE,
217
228
  AUTHOR,
@@ -229,7 +240,7 @@ import {
229
240
  SKILLS_DIR_NAME,
230
241
  VERSION,
231
242
  buildUserIdentityPrompt
232
- } from "./chunk-2FCKZ3OS.js";
243
+ } from "./chunk-JSQGDPDK.js";
233
244
 
234
245
  // src/index.ts
235
246
  import { program } from "commander";
@@ -1347,7 +1358,7 @@ No tools match "${filter}".
1347
1358
  const { join: join6 } = await import("path");
1348
1359
  const { existsSync: existsSync6 } = await import("fs");
1349
1360
  const { getGitRoot: getGitRoot2 } = await import("./git-context-EXOEHQSF.js");
1350
- const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-X53QCUTP.js");
1361
+ const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-3B5KIPLK.js");
1351
1362
  const { approveProject, hashMcpFile } = await import("./project-trust-NKYHL3VZ.js");
1352
1363
  const cwd = process.cwd();
1353
1364
  const projectRoot = getGitRoot2(cwd) ?? cwd;
@@ -1937,24 +1948,26 @@ function createReviewCommands() {
1937
1948
  name: "rewind",
1938
1949
  description: "Rewind conversation to a previous message and restore file states",
1939
1950
  usage: "/rewind [list | <n>]",
1940
- execute(args, ctx) {
1951
+ async execute(args, ctx) {
1941
1952
  const session = ctx.sessions.current;
1942
1953
  if (!session || session.messages.length === 0) {
1943
1954
  console.log(theme.dim(" No messages to rewind."));
1944
1955
  return;
1945
1956
  }
1946
- const sub = args[0];
1947
- if (sub === "list" || !sub) {
1948
- const msgs = session.messages;
1957
+ const intent = parseRewindArgs(args, session.messages.length);
1958
+ if (intent.kind === "invalid") {
1959
+ ctx.renderer.renderError(intent.message);
1960
+ return;
1961
+ }
1962
+ if (intent.kind === "list") {
1963
+ const rows = buildRewindList(session.messages, fileCheckpoints.getMessageIndices());
1949
1964
  console.log(theme.heading(`
1950
- Conversation messages (${msgs.length} total):
1965
+ Conversation messages (${rows.length} total):
1951
1966
  `));
1952
- for (let i = 0; i < msgs.length; i++) {
1953
- const m = msgs[i];
1954
- const role = m.role.padEnd(10);
1955
- const text = getContentText(m.content).replace(/\n/g, " ").slice(0, 70);
1956
- const hasCheckpoint = fileCheckpoints.getMessageIndices().includes(i) ? " \u{1F4CC}" : "";
1957
- console.log(theme.dim(` [${String(i + 1).padStart(3)}]`) + ` ${theme.info(role)} ${text}${hasCheckpoint}`);
1967
+ for (const row of rows) {
1968
+ console.log(
1969
+ theme.dim(` [${String(row.index).padStart(3)}]`) + ` ${theme.info(row.role.padEnd(10))} ${row.preview}${row.hasCheckpoint ? " \u{1F4CC}" : ""}`
1970
+ );
1958
1971
  }
1959
1972
  console.log();
1960
1973
  console.log(theme.dim(" Usage: /rewind <n> \u2014 rewind to message N (1-based)"));
@@ -1962,28 +1975,21 @@ function createReviewCommands() {
1962
1975
  console.log();
1963
1976
  return;
1964
1977
  }
1965
- const n = parseInt(sub, 10);
1966
- if (isNaN(n) || n < 1 || n > session.messages.length) {
1967
- ctx.renderer.renderError(`Invalid message number: ${sub}. Range: 1-${session.messages.length}`);
1968
- return;
1969
- }
1970
- const targetIndex = n;
1971
- const messagesRemoved = session.messages.length - targetIndex;
1972
- const { restored, deleted, files } = fileCheckpoints.restoreToMessageIndex(targetIndex);
1973
- session.messages = session.messages.slice(0, targetIndex);
1974
- session.checkpoints = session.checkpoints.filter((c) => c.messageIndex <= targetIndex);
1975
- session.updated = /* @__PURE__ */ new Date();
1978
+ const messagesRemoved = session.messages.length - intent.target;
1979
+ const { restored, deleted, files } = fileCheckpoints.restoreToMessageIndex(intent.target);
1980
+ session.truncateTo(intent.target);
1981
+ await ctx.sessions.save();
1982
+ ctx.resetSessionTokenUsage();
1983
+ const lines = formatRewindReport({
1984
+ target: intent.target,
1985
+ messagesRemoved,
1986
+ filesRestored: restored,
1987
+ filesDeleted: deleted,
1988
+ files
1989
+ });
1976
1990
  console.log(theme.success(`
1977
- \u2713 Rewound to message ${n}`));
1978
- console.log(theme.dim(` Messages removed: ${messagesRemoved}`));
1979
- if (restored > 0 || deleted > 0) {
1980
- console.log(theme.dim(` Files restored: ${restored}, files deleted: ${deleted}`));
1981
- for (const f of files) {
1982
- console.log(theme.dim(` ${f}`));
1983
- }
1984
- } else {
1985
- console.log(theme.dim(" No file changes to revert."));
1986
- }
1991
+ ${lines[0]}`));
1992
+ for (const line of lines.slice(1)) console.log(theme.dim(` ${line}`));
1987
1993
  console.log();
1988
1994
  }
1989
1995
  },
@@ -2267,7 +2273,7 @@ function createReviewCommands() {
2267
2273
  usage: "/test [command|filter]",
2268
2274
  async execute(args, ctx) {
2269
2275
  try {
2270
- const { executeTests } = await import("./run-tests-XGCNUT5S.js");
2276
+ const { executeTests } = await import("./run-tests-PUOXATHQ.js");
2271
2277
  const argStr = args.join(" ").trim();
2272
2278
  let testArgs = {};
2273
2279
  if (argStr) {
@@ -2349,39 +2355,29 @@ Summary: ${fileMap.size} file(s) \u2014 ${newFiles} new, ${modifiedFiles} modifi
2349
2355
  ctx.renderer.printInfo("No active session to fork.");
2350
2356
  return;
2351
2357
  }
2352
- const sub = args.join(" ").trim();
2353
- let messageCount = session.messages.length;
2354
- let fromLabel = "current position";
2355
- if (sub) {
2356
- const cp = session.checkpoints.find((c) => c.name === sub);
2357
- if (!cp) {
2358
- const available = session.checkpoints.map((c) => c.name);
2359
- if (available.length > 0) {
2360
- ctx.renderer.printInfo(
2361
- `Checkpoint "${sub}" not found. Available: ${available.join(", ")}`
2362
- );
2363
- } else {
2364
- ctx.renderer.printInfo(
2365
- `Checkpoint "${sub}" not found. No checkpoints saved. Use /checkpoint save <name> first.`
2366
- );
2367
- }
2368
- return;
2369
- }
2370
- messageCount = cp.messageIndex;
2371
- fromLabel = `checkpoint "${cp.name}" (${cp.messageIndex} messages)`;
2358
+ const point = resolveForkPoint(session, args.join(" ").trim());
2359
+ if (!point.ok) {
2360
+ ctx.renderer.printInfo(point.message);
2361
+ return;
2372
2362
  }
2373
2363
  try {
2374
- const originalId = session.id.slice(0, 8);
2364
+ const originalId = session.id;
2375
2365
  const originalTitle = session.title ?? "(untitled)";
2376
- const forked = await ctx.forkSession(messageCount);
2377
- console.log(theme.heading("\n Session Forked\n"));
2378
- console.log(` ${theme.dim("Original:")} ${theme.accent(originalId)} "${originalTitle}"`);
2379
- console.log(` ${theme.dim("Forked: ")} ${theme.accent(forked.id.slice(0, 8))} "${forked.title ?? "(untitled)"}"`);
2380
- console.log(` ${theme.dim("From: ")} ${fromLabel}`);
2381
- console.log(` ${theme.dim("Messages:")} ${forked.messages.length} copied, ${forked.checkpoints.length} checkpoint(s) preserved`);
2382
- console.log("");
2383
- console.log(theme.dim(` Use /session load ${originalId} to switch back to original.`));
2384
- console.log("");
2366
+ const forked = await ctx.forkSession(point.messageCount);
2367
+ const lines = formatForkReport({
2368
+ originalId,
2369
+ originalTitle,
2370
+ forkedId: forked.id,
2371
+ forkedTitle: forked.title ?? "(untitled)",
2372
+ fromLabel: point.fromLabel,
2373
+ messageCount: forked.messages.length,
2374
+ checkpointCount: forked.checkpoints.length
2375
+ });
2376
+ console.log(theme.heading(`
2377
+ ${lines[0]}
2378
+ `));
2379
+ for (const line of lines.slice(1)) console.log(theme.dim(line));
2380
+ console.log();
2385
2381
  ctx.refreshPrompt();
2386
2382
  } catch (err) {
2387
2383
  ctx.renderer.renderError(
@@ -2626,12 +2622,15 @@ function createMemoryCommands() {
2626
2622
  usage: "/memory [show|add|edit|approve|reject|delete|expire|rebind|clear|backup|restore|export|path|rebuild|refresh|status|recall|index-clear]",
2627
2623
  async execute(args, ctx) {
2628
2624
  const configDir = ctx.config.getConfigDir();
2629
- const sub = args[0] ?? "show";
2630
- if (sub === "rebuild" || sub === "refresh") {
2631
- const full = sub === "rebuild";
2632
- ctx.renderer.printInfo(
2633
- full ? "\u{1F9E0} Rebuilding chat memory index from scratch (this may take a while on first run \u2014 embedding model ~117 MB)\u2026" : "\u{1F9E0} Refreshing chat memory index (incremental)\u2026"
2634
- );
2625
+ const intent = parseMemoryCommand(args);
2626
+ const sub = intent.kind === "manage" ? intent.action : intent.kind;
2627
+ if (intent.kind === "usage") {
2628
+ ctx.renderer.printInfo(intent.message);
2629
+ return;
2630
+ }
2631
+ if (intent.kind === "rebuild") {
2632
+ const full = intent.full;
2633
+ ctx.renderer.printInfo(rebuildStartMessage(full));
2635
2634
  try {
2636
2635
  let lastStage = "";
2637
2636
  const stats = await buildChatIndex({
@@ -2649,95 +2648,99 @@ function createMemoryCommands() {
2649
2648
  }
2650
2649
  }
2651
2650
  });
2652
- ctx.renderer.printSuccess(
2653
- `\u2713 Chat index: ${stats.chunksTotal} chunks (${stats.chunksAdded} new, ${stats.chunksRemoved} removed) across ${stats.sessionsIndexed + stats.sessionsSkipped} sessions (${stats.sessionsIndexed} re-indexed, ${stats.sessionsSkipped} cached) in ${stats.durationMs}ms`
2654
- );
2651
+ ctx.renderer.printSuccess(rebuildDoneMessage(stats));
2655
2652
  } catch (err) {
2656
2653
  ctx.renderer.renderError(`Rebuild failed: ${err instanceof Error ? err.message : String(err)}`);
2657
2654
  }
2658
2655
  return;
2659
2656
  }
2660
- if (sub === "status") {
2661
- const s = getChatIndexStatus();
2657
+ if (intent.kind === "status") {
2662
2658
  const memories = listMemoryEntries(configDir, { includeExpired: true, includeRejected: true });
2663
- const active = memories.filter((m) => m.approved && !isMemoryExpired(m)).length;
2664
- const pending = memories.filter((m) => !m.approved && !isMemoryExpired(m)).length;
2665
- console.log(theme.heading("\n\u{1F9E0} Governed Memory"));
2666
- console.log(` active : ${active}`);
2667
- if (pending > 0) {
2668
- console.log(theme.warning(` pending : ${pending} \u2014 run /memory show --pending, then /memory approve <8-char-id>`));
2669
- } else {
2670
- console.log(` pending : 0`);
2671
- }
2672
2659
  const injected = formatMemoryForPrompt(configDir, process.cwd(), ctx.config.get("memory")?.maxChars);
2673
- if (injected) {
2674
- const truncNote = injected.truncated ? theme.warning(` \u26A0 truncated \u2014 only newest ${injected.entryCount} of ${injected.totalCount} injected`) : "";
2675
- console.log(` injected : ${injected.entryCount} of ${injected.totalCount} (${injected.content.length} chars)${truncNote}`);
2676
- } else {
2677
- console.log(` injected : 0`);
2660
+ const view = buildMemoryStatusView({
2661
+ active: memories.filter((m) => m.approved && !isMemoryExpired(m)).length,
2662
+ pending: memories.filter((m) => !m.approved && !isMemoryExpired(m)).length,
2663
+ injected: injected ? {
2664
+ entryCount: injected.entryCount,
2665
+ totalCount: injected.totalCount,
2666
+ chars: injected.content.length,
2667
+ truncated: injected.truncated
2668
+ } : null,
2669
+ storePath: memoryStorePath(configDir),
2670
+ chatIndex: getChatIndexStatus()
2671
+ });
2672
+ console.log(theme.heading("\n\u{1F9E0} Governed Memory"));
2673
+ for (const row of view.governed) {
2674
+ const line = ` ${row.label.padEnd(13)}: ${row.value}`;
2675
+ console.log(row.warn ? theme.warning(line) : line);
2678
2676
  }
2679
- console.log(` store : ${memoryStorePath(configDir)}`);
2680
2677
  console.log(theme.heading("\n\u{1F9E0} Chat Memory Index"));
2681
- if (!s.exists) {
2682
- console.log(theme.dim(" not built yet \u2014 run /memory rebuild\n"));
2678
+ if (view.chatIndexHint) {
2679
+ console.log(theme.dim(` ${view.chatIndexHint}
2680
+ `));
2683
2681
  return;
2684
2682
  }
2685
- const mb = (n) => `${(n / 1024 / 1024).toFixed(2)} MB`;
2686
- console.log(` chunks : ${s.chunks}`);
2687
- console.log(` sessions : ${s.sessions}`);
2688
- console.log(` built : ${s.built?.replace("T", " ").slice(0, 19) ?? "-"}`);
2689
- console.log(` model : ${s.model ?? "-"}`);
2690
- console.log(` vec file : ${mb(s.vecFileSizeBytes)}`);
2691
- console.log(` chunks file : ${mb(s.chunksFileSizeBytes)}`);
2683
+ for (const row of view.chatIndex) {
2684
+ console.log(` ${row.label.padEnd(13)}: ${row.value}`);
2685
+ }
2692
2686
  console.log();
2693
2687
  return;
2694
2688
  }
2695
- if (sub === "recall") {
2696
- const query = args.slice(1).join(" ").trim();
2697
- if (!query) {
2698
- ctx.renderer.printInfo("Usage: /memory recall <query>");
2699
- return;
2700
- }
2689
+ if (intent.kind === "recall") {
2690
+ const query = intent.query;
2701
2691
  const persistentHits = searchPersistentMemories(configDir, query, process.cwd(), 3);
2702
2692
  if (persistentHits.length > 0) {
2703
2693
  touchMemoryReferences(configDir, persistentHits.map((h) => h.entry.id));
2694
+ }
2695
+ let chatHits = [];
2696
+ try {
2697
+ chatHits = await searchChatMemory(query, { topK: 5, minScore: 0.2 });
2698
+ } catch (err) {
2699
+ ctx.renderer.renderError(`Recall failed: ${err instanceof Error ? err.message : String(err)}`);
2700
+ return;
2701
+ }
2702
+ const view = buildRecallView(
2703
+ query,
2704
+ persistentHits.map((h) => ({
2705
+ id: h.entry.id,
2706
+ scope: h.entry.scope,
2707
+ score: h.score,
2708
+ content: h.entry.content
2709
+ })),
2710
+ chatHits.map((h) => ({
2711
+ timestamp: h.chunk.timestamp,
2712
+ title: h.chunk.sessionTitle ?? h.chunk.sessionId.slice(0, 8),
2713
+ score: h.score,
2714
+ text: h.chunk.text
2715
+ }))
2716
+ );
2717
+ if (view.persistentHeading) {
2704
2718
  console.log(theme.heading(`
2705
- \u{1F4DD} Persistent memory \u2014 ${persistentHits.length} hit(s):
2719
+ ${view.persistentHeading}
2706
2720
  `));
2707
- for (const [i, h] of persistentHits.entries()) {
2708
- console.log(theme.accent(` [${i + 1}] id ${h.entry.id.slice(0, 8)} \xB7 ${h.entry.scope} \xB7 coverage ${h.score.toFixed(2)}`));
2709
- console.log(theme.dim(" ") + h.entry.content.replace(/\n/g, "\n "));
2721
+ for (const hit of view.persistent) {
2722
+ console.log(theme.accent(` ${hit.label}`));
2723
+ console.log(theme.dim(" ") + hit.body.replace(/\n/g, "\n "));
2710
2724
  console.log();
2711
2725
  }
2712
2726
  }
2713
- try {
2714
- const hits = await searchChatMemory(query, { topK: 5, minScore: 0.2 });
2715
- if (hits.length === 0) {
2716
- if (persistentHits.length === 0) {
2717
- console.log(theme.warning(` No memories matched "${query}" (persistent + chat index).`));
2718
- } else {
2719
- console.log(theme.dim(` (no chat-history hits above score 0.20)`));
2720
- }
2721
- console.log();
2722
- return;
2723
- }
2727
+ if (view.chatHeading) {
2724
2728
  console.log(theme.heading(`
2725
- \u{1F9E0} Chat history recall for "${query}" \u2014 ${hits.length} hit(s):
2729
+ ${view.chatHeading}
2726
2730
  `));
2727
- for (const [i, h] of hits.entries()) {
2728
- const ts = h.chunk.timestamp.slice(0, 16).replace("T", " ");
2729
- const title = h.chunk.sessionTitle ?? h.chunk.sessionId.slice(0, 8);
2730
- console.log(theme.accent(` [${i + 1}] ${ts} \xB7 ${title} \xB7 score ${h.score.toFixed(3)}`));
2731
- const body = h.chunk.text.length > 400 ? h.chunk.text.slice(0, 400) + "\u2026" : h.chunk.text;
2732
- console.log(theme.dim(" ") + body.replace(/\n/g, "\n "));
2731
+ for (const hit of view.chat) {
2732
+ console.log(theme.accent(` ${hit.label}`));
2733
+ console.log(theme.dim(" ") + hit.body.replace(/\n/g, "\n "));
2733
2734
  console.log();
2734
2735
  }
2735
- } catch (err) {
2736
- ctx.renderer.renderError(`Recall failed: ${err instanceof Error ? err.message : String(err)}`);
2736
+ }
2737
+ if (view.note) {
2738
+ console.log(view.note.startsWith("No memories") ? theme.warning(` ${view.note}`) : theme.dim(` ${view.note}`));
2739
+ console.log();
2737
2740
  }
2738
2741
  return;
2739
2742
  }
2740
- if (sub === "index-clear") {
2743
+ if (intent.kind === "index-clear") {
2741
2744
  clearChatIndex();
2742
2745
  ctx.renderer.printSuccess("Chat memory index cleared (persistent memory untouched).");
2743
2746
  return;
@@ -2763,7 +2766,7 @@ function createMemoryCommands() {
2763
2766
  return { flags, text: text.join(" ").trim() };
2764
2767
  };
2765
2768
  const asSensitivity = (value) => value === "low" || value === "medium" || value === "high" ? value : void 0;
2766
- if (sub === "show" || sub === "view" || sub === "list") {
2769
+ if (intent.kind === "show") {
2767
2770
  const showFilters = parseMemoryShowFilters(args.slice(1));
2768
2771
  if (showFilters.invalidStale) {
2769
2772
  ctx.renderer.renderError("Usage: /memory show --stale <days> (positive number)");
@@ -2957,9 +2960,7 @@ function createMemoryCommands() {
2957
2960
  console.log(theme.accent(memoryStorePath(configDir)));
2958
2961
  console.log(theme.dim(memoryMarkdownPath(configDir)));
2959
2962
  } else {
2960
- ctx.renderer.printInfo(
2961
- "Governed persistent memory: show [--pending|--orphaned|--stale <days>|--scope <s>|--search <text>] | add | edit <id> <text> | approve/reject/delete/expire <id> | rebind <id> <path> | clear | backup [--out <file>] | restore <file> | export [--format json|md] [--out <file>] | path\nChat memory index (cross-session recall): rebuild | refresh | status | recall <query> | index-clear"
2962
- );
2963
+ ctx.renderer.printInfo(MEMORY_USAGE);
2963
2964
  }
2964
2965
  }
2965
2966
  },
@@ -7274,7 +7275,7 @@ program.command("web").description("Start Web UI server with browser-based chat
7274
7275
  console.error("Error: Invalid port number. Must be between 1 and 65535.");
7275
7276
  process.exit(1);
7276
7277
  }
7277
- const { startWebServer } = await import("./server-6RYXFG3H.js");
7278
+ const { startWebServer } = await import("./server-4XSDRPZM.js");
7278
7279
  await startWebServer({ port, host: options.host });
7279
7280
  });
7280
7281
  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) => {
@@ -7441,11 +7442,11 @@ program.command("sessions").description("List recent conversation sessions").opt
7441
7442
  console.log(footer + "\n");
7442
7443
  });
7443
7444
  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) => {
7444
- const { runUsageCli } = await import("./usage-W7TZWHY7.js");
7445
+ const { runUsageCli } = await import("./usage-7VEAXMMP.js");
7445
7446
  await runUsageCli(options);
7446
7447
  });
7447
7448
  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) => {
7448
- const { runDoctorCli } = await import("./doctor-cli-6JCJEQR4.js");
7449
+ const { runDoctorCli } = await import("./doctor-cli-VRMIEREY.js");
7449
7450
  const argv = process.argv.slice(2);
7450
7451
  await runDoctorCli({
7451
7452
  json: !!options.json || argv.includes("--json"),
@@ -7454,7 +7455,7 @@ program.command("doctor").description("Health check: API keys, config, MCP, rece
7454
7455
  });
7455
7456
  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) => {
7456
7457
  try {
7457
- const batch = await import("./batch-237ZXBQD.js");
7458
+ const batch = await import("./batch-6WWR4P5U.js");
7458
7459
  switch (action) {
7459
7460
  case "submit":
7460
7461
  if (!arg) {
@@ -7497,7 +7498,7 @@ program.command("batch <action> [arg] [arg2]").description("Anthropic Message Ba
7497
7498
  }
7498
7499
  });
7499
7500
  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) => {
7500
- const { startMcpServer } = await import("./server-EFA7UP4I.js");
7501
+ const { startMcpServer } = await import("./server-WGEGVVY5.js");
7501
7502
  await startMcpServer({
7502
7503
  allowDestructive: !!options.allowDestructive,
7503
7504
  allowOutsideCwd: !!options.allowOutsideCwd,
@@ -7510,7 +7511,7 @@ program.command("pr <action> [target]").description("PR review helpers: review |
7510
7511
  console.error(`Unknown pr action: ${action}. Use review | security-review | summarize.`);
7511
7512
  process.exit(1);
7512
7513
  }
7513
- const { runPrCli } = await import("./pr-DZTRHAMG.js");
7514
+ const { runPrCli } = await import("./pr-XUXWP52Z.js");
7514
7515
  const result = await runPrCli({
7515
7516
  action,
7516
7517
  target,
@@ -7530,8 +7531,8 @@ program.command("pr <action> [target]").description("PR review helpers: review |
7530
7531
  process.exit(result.exitCode);
7531
7532
  });
7532
7533
  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) => {
7533
- const { runCi } = await import("./ci-LXRTYJ6F.js");
7534
- const { formatCiResult } = await import("./ci-format-II3OT2VU.js");
7534
+ const { runCi } = await import("./ci-FTS7XNWA.js");
7535
+ const { formatCiResult } = await import("./ci-format-N5PXGS7Y.js");
7535
7536
  const formats = [options.json, options.markdown, options.sarif].filter(Boolean).length;
7536
7537
  if (formats > 1) {
7537
7538
  console.error("Choose only one output format: --json, --markdown, or --sarif.");
@@ -7689,7 +7690,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
7689
7690
  config.get("customProviders"),
7690
7691
  config.getConfigDir()
7691
7692
  );
7692
- const { startHub } = await import("./hub-RXAFF7QI.js");
7693
+ const { startHub } = await import("./hub-TZET5544.js");
7693
7694
  await startHub(
7694
7695
  {
7695
7696
  topic: topic ?? "",
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  discussionToMessages,
4
4
  persistDiscussion
5
- } from "./chunk-VB54ILH7.js";
6
- import "./chunk-6NO5FZW6.js";
5
+ } from "./chunk-NUJTNH76.js";
6
+ import "./chunk-IUVDZVZ4.js";
7
7
  import "./chunk-NYNSYLFY.js";
8
8
  import "./chunk-3FEZSLGI.js";
9
9
  import "./chunk-IW3Q7AE5.js";
@@ -28,11 +28,11 @@ import {
28
28
  touchMemoryReferences,
29
29
  updateMemoryApproval,
30
30
  updateMemoryEntry
31
- } from "./chunk-H2VE4TTN.js";
31
+ } from "./chunk-M3UJ2JCW.js";
32
32
  import "./chunk-3FEZSLGI.js";
33
33
  import "./chunk-HOSJZMQS.js";
34
34
  import "./chunk-IW3Q7AE5.js";
35
- import "./chunk-2FCKZ3OS.js";
35
+ import "./chunk-JSQGDPDK.js";
36
36
  export {
37
37
  addMemoryEntry,
38
38
  backupMemoryStore,
@@ -27,9 +27,9 @@ import {
27
27
  touchMemoryReferences,
28
28
  updateMemoryApproval,
29
29
  updateMemoryEntry
30
- } from "./chunk-IXEKDAIX.js";
30
+ } from "./chunk-JR2J3V6J.js";
31
31
  import "./chunk-FSC6KEWU.js";
32
- import "./chunk-5GYOQ7EF.js";
32
+ import "./chunk-2YVZTDP4.js";
33
33
  import "./chunk-6BUTA5VW.js";
34
34
  export {
35
35
  addMemoryEntry,
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  countSeverity,
4
4
  runCi
5
- } from "./chunk-UTJQXG4P.js";
6
- import "./chunk-JT2A2M4F.js";
5
+ } from "./chunk-CUS4FJVP.js";
6
+ import "./chunk-Z3QNLNSU.js";
7
7
  import {
8
8
  buildReviewPrompt,
9
9
  buildSecurityReviewPrompt,
@@ -17,13 +17,13 @@ import {
17
17
  } from "./chunk-UGY5SVNX.js";
18
18
  import {
19
19
  ConfigManager
20
- } from "./chunk-4XJVSMZ6.js";
20
+ } from "./chunk-QDOFRKY2.js";
21
21
  import "./chunk-TEXT4DAT.js";
22
22
  import "./chunk-TU3L3PW7.js";
23
23
  import "./chunk-IW3Q7AE5.js";
24
24
  import {
25
25
  VERSION
26
- } from "./chunk-2FCKZ3OS.js";
26
+ } from "./chunk-JSQGDPDK.js";
27
27
 
28
28
  // src/cli/pr.ts
29
29
  import { execFileSync } from "child_process";
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  executeTests,
3
3
  runTestsTool
4
- } from "./chunk-WUIOUJA2.js";
5
- import "./chunk-5GYOQ7EF.js";
4
+ } from "./chunk-F3YN754E.js";
5
+ import "./chunk-2YVZTDP4.js";
6
6
  export {
7
7
  executeTests,
8
8
  runTestsTool
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  executeTests,
4
4
  runTestsTool
5
- } from "./chunk-J3RWNQOF.js";
6
- import "./chunk-2FCKZ3OS.js";
5
+ } from "./chunk-4J7FIGQD.js";
6
+ import "./chunk-JSQGDPDK.js";
7
7
  export {
8
8
  executeTests,
9
9
  runTestsTool