jinzd-ai-cli 0.4.241 → 0.4.242

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 (42) hide show
  1. package/README.md +2 -2
  2. package/dist/{batch-K66BLTLJ.js → batch-D3UHL432.js} +2 -2
  3. package/dist/{chat-index-7HXBWQFH.js → chat-index-ALUHFJKI.js} +3 -2
  4. package/dist/{chat-index-WYXYD7YP.js → chat-index-ML5FF5L6.js} +2 -1
  5. package/dist/{chunk-NAQPP3GZ.js → chunk-6ZWNXHNH.js} +1 -1
  6. package/dist/chunk-B5TYJO7V.js +123 -0
  7. package/dist/chunk-D27TMEOV.js +327 -0
  8. package/dist/{chunk-2QQKS56X.js → chunk-DT77O33T.js} +1 -1
  9. package/dist/{chunk-GORPFFV4.js → chunk-FEMPCNX3.js} +79 -252
  10. package/dist/{chunk-3AIR7N5M.js → chunk-FRNWQIG6.js} +5 -5
  11. package/dist/{chunk-5MYPIQ3Y.js → chunk-IGPFYNZA.js} +4 -2
  12. package/dist/{chunk-2LLQOMMW.js → chunk-J363BGOH.js} +1 -1
  13. package/dist/{chunk-JMP3LJC2.js → chunk-KWQKQVPH.js} +4 -2
  14. package/dist/{chunk-PGHTAKIA.js → chunk-LHINXQZF.js} +1 -1
  15. package/dist/{chunk-ZPXMT2B6.js → chunk-MC2ZNPBC.js} +4 -163
  16. package/dist/chunk-MKLPAQT6.js +164 -0
  17. package/dist/{chunk-UO3XWZFE.js → chunk-NV63EYFL.js} +3 -119
  18. package/dist/{chunk-CHFFEVVT.js → chunk-OO2PHOXD.js} +3 -3
  19. package/dist/{chunk-KCEO2XJ4.js → chunk-PJ3ONBWZ.js} +0 -119
  20. package/dist/{chunk-LXSUPLCK.js → chunk-PSP6UIKL.js} +2 -2
  21. package/dist/chunk-UWV2NBCO.js +418 -0
  22. package/dist/{chunk-IV6GCDVR.js → chunk-WMAXYDCB.js} +7 -1
  23. package/dist/{chunk-SMQHEJSH.js → chunk-Y4CMNXZH.js} +1 -1
  24. package/dist/chunk-YVTASHS5.js +121 -0
  25. package/dist/{ci-T2ABDMMQ.js → ci-WSED3Z6V.js} +4 -4
  26. package/dist/{ci-format-S2PPU27O.js → ci-format-6AYL2X2J.js} +2 -2
  27. package/dist/{constants-RS7OUU7X.js → constants-FJ3L5GYO.js} +1 -1
  28. package/dist/{doctor-cli-TGAW6RAP.js → doctor-cli-HCP56MKH.js} +4 -4
  29. package/dist/electron-server.js +423 -572
  30. package/dist/{hub-GL5ZU6WS.js → hub-K5MYSVEF.js} +2 -2
  31. package/dist/index.js +203 -58
  32. package/dist/{persist-AMH5SQ4W.js → persist-WGIJ6RXY.js} +4 -3
  33. package/dist/persistent-memory-EYAKL2XA.js +55 -0
  34. package/dist/persistent-memory-HWFNDQFQ.js +53 -0
  35. package/dist/{pr-TJFKUZ4B.js → pr-OICMUN6R.js} +5 -5
  36. package/dist/{run-tests-EWMU34A4.js → run-tests-B3FSE5NV.js} +2 -1
  37. package/dist/{run-tests-KEI7IXTB.js → run-tests-DSEW5HED.js} +2 -2
  38. package/dist/{server-UVS2D4M6.js → server-2FS65CQZ.js} +130 -47
  39. package/dist/{server-E545UIX7.js → server-EDCGPEGC.js} +8 -6
  40. package/dist/{task-orchestrator-PWXV2EBN.js → task-orchestrator-WCZYV3TE.js} +8 -6
  41. package/dist/{usage-EDJ6QOWB.js → usage-WVUYNLOD.js} +2 -2
  42. package/package.json +1 -1
@@ -139,7 +139,7 @@ ${content}`);
139
139
  const state = await runDiscussion(config, providers, options.topic);
140
140
  if (options.save !== false && state.messages.length > 0) {
141
141
  try {
142
- const { persistDiscussion } = await import("./persist-AMH5SQ4W.js");
142
+ const { persistDiscussion } = await import("./persist-WGIJ6RXY.js");
143
143
  const { path } = await persistDiscussion(state, configManager, defaultProvider, defaultModel);
144
144
  console.log(chalk.dim(`
145
145
  \u{1F4BE} Saved to history \u2014 open it in the Web UI and hit \u{1F3AC} to replay.
@@ -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-PWXV2EBN.js");
157
+ const { TaskOrchestrator } = await import("./task-orchestrator-WCZYV3TE.js");
158
158
  const orchestrator = new TaskOrchestrator(config, providers, configManager);
159
159
  let interrupted = false;
160
160
  const onSigint = () => {
package/dist/index.js CHANGED
@@ -1,4 +1,7 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ CostTracker
4
+ } from "./chunk-YVMACMXW.js";
2
5
  import {
3
6
  McpManager,
4
7
  SNAPSHOT_PROMPT,
@@ -14,7 +17,12 @@ import {
14
17
  scanProject,
15
18
  sessionHasMeaningfulContent,
16
19
  setupProxy
17
- } from "./chunk-LXSUPLCK.js";
20
+ } from "./chunk-PSP6UIKL.js";
21
+ import {
22
+ computeCost,
23
+ formatCost,
24
+ getPricing
25
+ } from "./chunk-E44DTERW.js";
18
26
  import {
19
27
  buildReviewPrompt,
20
28
  buildSecurityReviewPrompt
@@ -22,26 +30,17 @@ import {
22
30
  import {
23
31
  ToolExecutor,
24
32
  ToolRegistry,
25
- addMemoryEntry,
26
33
  askUserContext,
27
34
  cleanupAllSessions,
28
35
  cleanupRejectedTeeFile,
29
36
  clearRecentlyDeniedAutoActions,
30
- deleteMemoryEntry,
31
37
  estimateTokens,
32
- expireMemoryEntry,
33
- exportMemoryEntries,
34
- formatMemoryForPrompt,
35
38
  formatPermissionProfileWarning,
36
39
  getRecentlyDeniedAutoActions,
37
40
  googleSearchContext,
38
41
  initTheme,
39
42
  isInterrupted,
40
- isMemoryExpired,
41
43
  lastResponseStore,
42
- listMemoryEntries,
43
- memoryMarkdownPath,
44
- memoryStorePath,
45
44
  renderDiff,
46
45
  requestInterrupt,
47
46
  resetInterrupt,
@@ -50,9 +49,29 @@ import {
50
49
  setMaxOutputCap,
51
50
  spawnAgentContext,
52
51
  theme,
53
- undoStack,
54
- updateMemoryApproval
55
- } from "./chunk-GORPFFV4.js";
52
+ undoStack
53
+ } from "./chunk-FEMPCNX3.js";
54
+ import {
55
+ addMemoryEntry,
56
+ clearMemoryEntries,
57
+ countPendingMemories,
58
+ deleteMemoryEntry,
59
+ detectStaleLegacyMarkdownEdit,
60
+ expireMemoryEntry,
61
+ exportMemoryEntries,
62
+ findSimilarMemory,
63
+ formatMemoryForPrompt,
64
+ isMemoryExpired,
65
+ listMemoryEntries,
66
+ listOrphanedProjectMemories,
67
+ loadMemoryEntries,
68
+ memoryMarkdownPath,
69
+ memoryStorePath,
70
+ parseWritableScope,
71
+ rebindMemoryProject,
72
+ updateMemoryApproval,
73
+ updateMemoryEntry
74
+ } from "./chunk-D27TMEOV.js";
56
75
  import "./chunk-K3CF65QH.js";
57
76
  import "./chunk-UUSRWSSX.js";
58
77
  import "./chunk-CKH4KQ4E.js";
@@ -60,24 +79,19 @@ import "./chunk-BXP6YZ2P.js";
60
79
  import {
61
80
  SessionManager,
62
81
  getContentText
63
- } from "./chunk-JMP3LJC2.js";
64
- import {
65
- CostTracker
66
- } from "./chunk-YVMACMXW.js";
67
- import {
68
- computeCost,
69
- formatCost,
70
- getPricing
71
- } from "./chunk-E44DTERW.js";
82
+ } from "./chunk-KWQKQVPH.js";
72
83
  import {
73
84
  buildDoctorReport,
74
85
  formatDoctorReport,
75
86
  loadContextFiles,
76
87
  writeCrashLog
77
- } from "./chunk-3AIR7N5M.js";
88
+ } from "./chunk-FRNWQIG6.js";
78
89
  import {
79
90
  ProviderRegistry
80
91
  } from "./chunk-QYQI7ZWK.js";
92
+ import {
93
+ ConfigManager
94
+ } from "./chunk-WMAXYDCB.js";
81
95
  import {
82
96
  describePlugin,
83
97
  getActivePluginAssets,
@@ -94,7 +108,7 @@ import {
94
108
  trustHook,
95
109
  trustPlugin,
96
110
  untrustHook
97
- } from "./chunk-2LLQOMMW.js";
111
+ } from "./chunk-J363BGOH.js";
98
112
  import {
99
113
  CONTENT_ONLY_STREAM_REMINDER,
100
114
  TEE_FINAL_USER_NUDGE,
@@ -114,9 +128,6 @@ import {
114
128
  stripToolCallReminder,
115
129
  teeStreamErrorSummary
116
130
  } from "./chunk-O3XSFPYH.js";
117
- import {
118
- ConfigManager
119
- } from "./chunk-IV6GCDVR.js";
120
131
  import {
121
132
  AuthError,
122
133
  ProviderError,
@@ -130,7 +141,7 @@ import {
130
141
  import {
131
142
  fileCheckpoints
132
143
  } from "./chunk-4BKXL7SM.js";
133
- import "./chunk-NAQPP3GZ.js";
144
+ import "./chunk-6ZWNXHNH.js";
134
145
  import {
135
146
  AGENTIC_BEHAVIOR_GUIDELINE,
136
147
  AUTHOR,
@@ -149,18 +160,19 @@ import {
149
160
  SKILLS_DIR_NAME,
150
161
  VERSION,
151
162
  buildUserIdentityPrompt
152
- } from "./chunk-SMQHEJSH.js";
163
+ } from "./chunk-Y4CMNXZH.js";
153
164
  import {
154
165
  buildChatIndex,
155
166
  clearChatIndex,
156
167
  getChatIndexStatus,
157
168
  searchChatMemory
158
- } from "./chunk-5MYPIQ3Y.js";
169
+ } from "./chunk-IGPFYNZA.js";
159
170
  import "./chunk-KHYD3WXE.js";
171
+ import "./chunk-PJ3ONBWZ.js";
160
172
  import {
161
173
  DEFAULT_PATTERNS,
162
174
  scanString
163
- } from "./chunk-KCEO2XJ4.js";
175
+ } from "./chunk-B5TYJO7V.js";
164
176
  import {
165
177
  atomicWriteFileSync
166
178
  } from "./chunk-IW3Q7AE5.js";
@@ -1370,7 +1382,7 @@ No tools match "${filter}".
1370
1382
  const { join: join6 } = await import("path");
1371
1383
  const { existsSync: existsSync5 } = await import("fs");
1372
1384
  const { getGitRoot: getGitRoot2 } = await import("./git-context-EXOEHQSF.js");
1373
- const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-RS7OUU7X.js");
1385
+ const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-FJ3L5GYO.js");
1374
1386
  const { approveProject, hashMcpFile } = await import("./project-trust-NKYHL3VZ.js");
1375
1387
  const cwd = process.cwd();
1376
1388
  const projectRoot = getGitRoot2(cwd) ?? cwd;
@@ -2349,7 +2361,7 @@ function createReviewCommands() {
2349
2361
  usage: "/test [command|filter]",
2350
2362
  async execute(args, ctx) {
2351
2363
  try {
2352
- const { executeTests } = await import("./run-tests-KEI7IXTB.js");
2364
+ const { executeTests } = await import("./run-tests-DSEW5HED.js");
2353
2365
  const argStr = args.join(" ").trim();
2354
2366
  let testArgs = {};
2355
2367
  if (argStr) {
@@ -2554,6 +2566,13 @@ function createMemoryCommands() {
2554
2566
  console.log(" Network : " + (ctx.config.get("networkPolicy")?.enabled ?? false ? "on" : "off"));
2555
2567
  console.log(" AutoMode : " + (ctx.getToolExecutor().sessionAutoMode ? "on" : "off"));
2556
2568
  console.log(" Hooks : " + getPendingHookTrust(mergePluginHooks(ctx.config.get("hooks") ?? void 0, ctx.config.getConfigDir()), ctx.config.getConfigDir()).length + " pending trust");
2569
+ {
2570
+ const memAll = listMemoryEntries(ctx.config.getConfigDir(), { includeExpired: true, includeRejected: true });
2571
+ const memActive = memAll.filter((m) => m.approved && !isMemoryExpired(m)).length;
2572
+ const memPending = memAll.filter((m) => !m.approved && !isMemoryExpired(m)).length;
2573
+ const pendingStr = memPending > 0 ? theme.warning(`${memPending} pending approval \u2014 /memory approve <id>`) : "0 pending";
2574
+ console.log(` Memory : ${memActive} active \xB7 ${pendingStr}`);
2575
+ }
2557
2576
  console.log(` Messages : ${session?.messages.length ?? 0}`);
2558
2577
  console.log(` Session : ${session?.id.slice(0, 8) ?? "none"}`);
2559
2578
  if (layers.length > 0) {
@@ -2698,7 +2717,7 @@ function createMemoryCommands() {
2698
2717
  {
2699
2718
  name: "memory",
2700
2719
  description: "Governed persistent memory + chat memory recall index",
2701
- usage: "/memory [show|add|approve|reject|delete|expire|export|path|rebuild|refresh|status|recall|index-clear]",
2720
+ usage: "/memory [show|add|edit|approve|reject|delete|expire|rebind|clear|export|path|rebuild|refresh|status|recall|index-clear]",
2702
2721
  async execute(args, ctx) {
2703
2722
  const configDir = ctx.config.getConfigDir();
2704
2723
  const sub = args[0] ?? "show";
@@ -2739,7 +2758,18 @@ function createMemoryCommands() {
2739
2758
  const pending = memories.filter((m) => !m.approved && !isMemoryExpired(m)).length;
2740
2759
  console.log(theme.heading("\n\u{1F9E0} Governed Memory"));
2741
2760
  console.log(` active : ${active}`);
2742
- console.log(` pending : ${pending}`);
2761
+ if (pending > 0) {
2762
+ console.log(theme.warning(` pending : ${pending} \u2014 run /memory show, then /memory approve <id>`));
2763
+ } else {
2764
+ console.log(` pending : 0`);
2765
+ }
2766
+ const injected = formatMemoryForPrompt(configDir, process.cwd(), ctx.config.get("memory")?.maxChars);
2767
+ if (injected) {
2768
+ const truncNote = injected.truncated ? theme.warning(` \u26A0 truncated \u2014 only newest ${injected.entryCount} of ${injected.totalCount} injected`) : "";
2769
+ console.log(` injected : ${injected.entryCount} of ${injected.totalCount} (${injected.content.length} chars)${truncNote}`);
2770
+ } else {
2771
+ console.log(` injected : 0`);
2772
+ }
2743
2773
  console.log(` store : ${memoryStorePath(configDir)}`);
2744
2774
  console.log(theme.heading("\n\u{1F9E0} Chat Memory Index"));
2745
2775
  if (!s.exists) {
@@ -2813,15 +2843,42 @@ function createMemoryCommands() {
2813
2843
  const asScope = (value) => value === "personal" || value === "project" || value === "session" || value === "team" ? value : void 0;
2814
2844
  const asSensitivity = (value) => value === "low" || value === "medium" || value === "high" ? value : void 0;
2815
2845
  if (sub === "show" || sub === "view" || sub === "list") {
2816
- const entries = listMemoryEntries(configDir, { includeExpired: true, includeRejected: true });
2846
+ const parsed = parseFlags(args.slice(1));
2847
+ const scopeFilter = asScope(parsed.flags.scope);
2848
+ const searchText = typeof parsed.flags.search === "string" ? parsed.flags.search.toLowerCase() : (parsed.text || void 0)?.toLowerCase();
2849
+ const filters = [];
2850
+ let entries;
2851
+ if (parsed.flags.orphaned === true) {
2852
+ entries = listOrphanedProjectMemories(configDir);
2853
+ filters.push("orphaned");
2854
+ } else {
2855
+ entries = listMemoryEntries(configDir, { includeExpired: true, includeRejected: true });
2856
+ }
2857
+ if (parsed.flags.pending === true) {
2858
+ entries = entries.filter((m) => !m.approved && !isMemoryExpired(m));
2859
+ filters.push("pending");
2860
+ }
2861
+ if (scopeFilter) {
2862
+ entries = entries.filter((m) => m.scope === scopeFilter);
2863
+ filters.push(`scope:${scopeFilter}`);
2864
+ }
2865
+ if (searchText) {
2866
+ entries = entries.filter((m) => m.content.toLowerCase().includes(searchText) || m.id.startsWith(searchText));
2867
+ filters.push(`search:"${searchText}"`);
2868
+ }
2817
2869
  if (entries.length === 0) {
2818
- ctx.renderer.printInfo("Memory is empty");
2870
+ ctx.renderer.printInfo(filters.length > 0 ? `No memory entries match [${filters.join(", ")}]` : "Memory is empty");
2819
2871
  return;
2820
2872
  }
2821
- console.log(theme.heading("\n\u{1F4DD} Governed Persistent Memory:\n") + theme.dim("\u2500".repeat(72)));
2873
+ const filterNote = filters.length > 0 ? theme.dim(` (filtered: ${filters.join(", ")})`) : "";
2874
+ console.log(theme.heading("\n\u{1F4DD} Governed Persistent Memory:") + filterNote + "\n" + theme.dim("\u2500".repeat(72)));
2822
2875
  for (const entry of entries) {
2823
2876
  const status = isMemoryExpired(entry) ? "expired" : entry.approved ? "approved" : "pending";
2824
- const source = entry.sourceSession ? `session ${entry.sourceSession.slice(0, 8)}` : entry.sourceProject ? `project ${entry.sourceProject}` : "manual/tool";
2877
+ const source = [
2878
+ entry.source ?? "unknown",
2879
+ entry.sourceSession ? `session ${entry.sourceSession.slice(0, 8)}` : "",
2880
+ entry.sourceProject ? `project ${entry.sourceProject}` : ""
2881
+ ].filter(Boolean).join(" \xB7 ");
2825
2882
  console.log(theme.accent(` ${entry.id.slice(0, 8)} ${status} scope:${entry.scope} sensitivity:${entry.sensitivity}`));
2826
2883
  console.log(theme.dim(` source: ${source} \xB7 created: ${entry.createdAt.replace("T", " ").slice(0, 19)}${entry.expiresAt ? ` \xB7 expires: ${entry.expiresAt}` : ""}`));
2827
2884
  console.log(" " + entry.content.replace(/\n/g, "\n "));
@@ -2833,12 +2890,14 @@ function createMemoryCommands() {
2833
2890
  } else if (sub === "add") {
2834
2891
  const parsed = parseFlags(args.slice(1));
2835
2892
  if (!parsed.text) {
2836
- ctx.renderer.printInfo("Usage: /memory add [--scope personal|project|session|team] [--sensitivity low|medium|high] [--expires-at ISO] <text>");
2893
+ ctx.renderer.printInfo("Usage: /memory add [--scope personal|project] [--sensitivity low|medium|high] [--expires-at ISO] <text>");
2837
2894
  return;
2838
2895
  }
2839
2896
  try {
2897
+ const similar = findSimilarMemory(loadMemoryEntries(configDir), parsed.text);
2840
2898
  const entry = addMemoryEntry(configDir, parsed.text, {
2841
- scope: asScope(parsed.flags.scope) ?? "personal",
2899
+ scope: parseWritableScope(parsed.flags.scope) ?? "personal",
2900
+ source: "manual",
2842
2901
  sensitivity: asSensitivity(parsed.flags.sensitivity),
2843
2902
  expiresAt: typeof parsed.flags["expires-at"] === "string" ? parsed.flags["expires-at"] : void 0,
2844
2903
  approved: parsed.flags.pending === true ? false : void 0,
@@ -2847,9 +2906,39 @@ function createMemoryCommands() {
2847
2906
  });
2848
2907
  const status = entry.approved ? "approved" : "pending approval";
2849
2908
  ctx.renderer.printSuccess(`Added memory ${entry.id.slice(0, 8)} (${status}, scope:${entry.scope}, sensitivity:${entry.sensitivity})`);
2909
+ if (similar) {
2910
+ ctx.renderer.printInfo(`\u26A0 Similar entry already exists: ${similar.id.slice(0, 8)} \u2014 consider /memory edit ${similar.id.slice(0, 8)} <text> or /memory delete one of them.`);
2911
+ }
2850
2912
  } catch (err) {
2851
2913
  ctx.renderer.renderError(`Failed to write memory: ${err instanceof Error ? err.message : String(err)}`);
2852
2914
  }
2915
+ } else if (sub === "edit") {
2916
+ const id = args[1];
2917
+ const newText = args.slice(2).join(" ").trim();
2918
+ if (!id || !newText) {
2919
+ ctx.renderer.printInfo("Usage: /memory edit <id> <new text>");
2920
+ return;
2921
+ }
2922
+ try {
2923
+ const entry = updateMemoryEntry(configDir, id, newText, { source: "manual", redact: true });
2924
+ const status = entry.approved ? "approved" : "pending approval \u2014 run /memory approve " + entry.id.slice(0, 8);
2925
+ ctx.renderer.printSuccess(`Updated memory ${entry.id.slice(0, 8)} (${status})`);
2926
+ } catch (err) {
2927
+ ctx.renderer.renderError(err instanceof Error ? err.message : String(err));
2928
+ }
2929
+ } else if (sub === "rebind") {
2930
+ const id = args[1];
2931
+ const newPath = args.slice(2).join(" ").trim();
2932
+ if (!id || !newPath) {
2933
+ ctx.renderer.printInfo("Usage: /memory rebind <id> <new project path> (find orphans with /memory show --orphaned)");
2934
+ return;
2935
+ }
2936
+ try {
2937
+ const entry = rebindMemoryProject(configDir, id, newPath);
2938
+ ctx.renderer.printSuccess(`Rebound memory ${entry.id.slice(0, 8)} to project ${entry.sourceProject}`);
2939
+ } catch (err) {
2940
+ ctx.renderer.renderError(err instanceof Error ? err.message : String(err));
2941
+ }
2853
2942
  } else if (sub === "approve" || sub === "reject") {
2854
2943
  const id = args[1];
2855
2944
  if (!id) {
@@ -2887,16 +2976,59 @@ function createMemoryCommands() {
2887
2976
  ctx.renderer.renderError(err instanceof Error ? err.message : String(err));
2888
2977
  }
2889
2978
  } else if (sub === "export") {
2890
- console.log(exportMemoryEntries(configDir, process.cwd()));
2979
+ const parsed = parseFlags(args.slice(1));
2980
+ const format = parsed.flags.format === "md" ? "md" : "json";
2981
+ if (parsed.flags.format && parsed.flags.format !== "md" && parsed.flags.format !== "json") {
2982
+ ctx.renderer.renderError(`Unknown format: ${parsed.flags.format}. Use --format json|md.`);
2983
+ return;
2984
+ }
2985
+ const output = exportMemoryEntries(configDir, process.cwd(), format);
2986
+ const outPath = typeof parsed.flags.out === "string" ? parsed.flags.out : void 0;
2987
+ if (outPath) {
2988
+ try {
2989
+ atomicWriteFileSync(outPath, output);
2990
+ const label = format === "md" ? "active entries (markdown)" : "all entries (json)";
2991
+ ctx.renderer.printSuccess(`Exported ${label} to ${outPath}`);
2992
+ } catch (err) {
2993
+ ctx.renderer.renderError(`Export failed: ${err instanceof Error ? err.message : String(err)}`);
2994
+ }
2995
+ } else {
2996
+ console.log(output);
2997
+ }
2891
2998
  } else if (sub === "clear") {
2892
- atomicWriteFileSync(memoryStorePath(configDir), "");
2893
- atomicWriteFileSync(memoryMarkdownPath(configDir), "");
2894
- ctx.renderer.printSuccess("Memory cleared (memory.jsonl and memory.md emptied)");
2999
+ const all = listMemoryEntries(configDir, { includeExpired: true, includeRejected: true });
3000
+ if (all.length === 0) {
3001
+ ctx.renderer.printInfo("Memory is already empty.");
3002
+ return;
3003
+ }
3004
+ console.log();
3005
+ console.log(theme.warning(` About to permanently clear ALL persistent memory (${all.length} entr${all.length > 1 ? "ies" : "y"}):`));
3006
+ for (const entry of all.slice(0, 5)) {
3007
+ const first = entry.content.split("\n")[0];
3008
+ console.log(theme.dim(` ${entry.id.slice(0, 8)} ${first.length > 60 ? first.slice(0, 60) + "\u2026" : first}`));
3009
+ }
3010
+ if (all.length > 5) console.log(theme.dim(` \u2026 and ${all.length - 5} more`));
3011
+ console.log();
3012
+ const choice = await ctx.select("Clear all persistent memory?", [
3013
+ { label: "No \u2014 keep it", value: "no" },
3014
+ { label: "Yes \u2014 clear all", value: "yes", hint: "a timestamped .bak backup is kept next to memory.jsonl" }
3015
+ ]);
3016
+ if (choice !== "yes") {
3017
+ ctx.renderer.printInfo("Cancelled \u2014 memory kept.");
3018
+ return;
3019
+ }
3020
+ const result = clearMemoryEntries(configDir);
3021
+ ctx.renderer.printSuccess(`Cleared ${result.cleared} memory entr${result.cleared > 1 ? "ies" : "y"}.`);
3022
+ if (result.backupPath) {
3023
+ ctx.renderer.printInfo(`Backup saved: ${result.backupPath}`);
3024
+ }
2895
3025
  } else if (sub === "path") {
2896
3026
  console.log(theme.accent(memoryStorePath(configDir)));
2897
3027
  console.log(theme.dim(memoryMarkdownPath(configDir)));
2898
3028
  } else {
2899
- ctx.renderer.printInfo("Usage: /memory [show|add|approve|reject|delete|expire|export|path|rebuild|refresh|status|recall|index-clear]");
3029
+ ctx.renderer.printInfo(
3030
+ "Governed persistent memory: show [--pending|--orphaned|--scope <s>|--search <text>] | add | edit <id> <text> | approve/reject/delete/expire <id> | rebind <id> <path> | clear | export [--format json|md] [--out <file>] | path\nChat memory index (cross-session recall): rebuild | refresh | status | recall <query> | index-clear"
3031
+ );
2900
3032
  }
2901
3033
  }
2902
3034
  },
@@ -5570,7 +5702,7 @@ var Repl = class {
5570
5702
  return { layers: result.layers, mergedContent: result.mergedContent };
5571
5703
  }
5572
5704
  loadMemoryContent() {
5573
- return formatMemoryForPrompt(this.config.getConfigDir(), process.cwd());
5705
+ return formatMemoryForPrompt(this.config.getConfigDir(), process.cwd(), this.config.get("memory")?.maxChars);
5574
5706
  }
5575
5707
  /**
5576
5708
  * 将项目上下文内容合并到 system prompt。
@@ -5952,8 +6084,21 @@ Session '${this.resumeSessionId}' not found.
5952
6084
  }
5953
6085
  const memoryInfo = this.loadMemoryContent();
5954
6086
  if (memoryInfo) {
6087
+ const truncNote = memoryInfo.truncated ? theme.warning(` \u26A0 truncated: newest ${memoryInfo.entryCount} of ${memoryInfo.totalCount} injected \u2014 /memory show to prune`) : "";
6088
+ process.stdout.write(
6089
+ theme.dim(` \u{1F4DD} Memory loaded: ${memoryInfo.entryCount} entries (${memoryInfo.content.length} chars)`) + truncNote + "\n"
6090
+ );
6091
+ }
6092
+ const pendingMemories = countPendingMemories(this.config.getConfigDir());
6093
+ if (pendingMemories > 0) {
6094
+ process.stdout.write(
6095
+ theme.warning(` \u26A0 ${pendingMemories} memory entr${pendingMemories > 1 ? "ies" : "y"} pending approval \u2014 run /memory show, then /memory approve <id>
6096
+ `)
6097
+ );
6098
+ }
6099
+ if (detectStaleLegacyMarkdownEdit(this.config.getConfigDir())) {
5955
6100
  process.stdout.write(
5956
- theme.dim(` \u{1F4DD} Memory loaded: ${memoryInfo.entryCount} entries (${memoryInfo.content.length} chars)
6101
+ theme.dim(` \u2139 memory.md was edited but is no longer read back (memory.jsonl is the source of truth) \u2014 use /memory add or /memory edit instead
5957
6102
  `)
5958
6103
  );
5959
6104
  }
@@ -6012,7 +6157,7 @@ Session '${this.resumeSessionId}' not found.
6012
6157
  })();
6013
6158
  void (async () => {
6014
6159
  try {
6015
- const { getChatIndexStatus: getChatIndexStatus2, buildChatIndex: buildChatIndex2 } = await import("./chat-index-7HXBWQFH.js");
6160
+ const { getChatIndexStatus: getChatIndexStatus2, buildChatIndex: buildChatIndex2 } = await import("./chat-index-ALUHFJKI.js");
6016
6161
  const initial = getChatIndexStatus2();
6017
6162
  this.chatMemoryStatus = {
6018
6163
  exists: initial.exists,
@@ -7803,7 +7948,7 @@ program.command("web").description("Start Web UI server with browser-based chat
7803
7948
  console.error("Error: Invalid port number. Must be between 1 and 65535.");
7804
7949
  process.exit(1);
7805
7950
  }
7806
- const { startWebServer } = await import("./server-UVS2D4M6.js");
7951
+ const { startWebServer } = await import("./server-2FS65CQZ.js");
7807
7952
  await startWebServer({ port, host: options.host });
7808
7953
  });
7809
7954
  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) => {
@@ -7970,11 +8115,11 @@ program.command("sessions").description("List recent conversation sessions").opt
7970
8115
  console.log(footer + "\n");
7971
8116
  });
7972
8117
  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) => {
7973
- const { runUsageCli } = await import("./usage-EDJ6QOWB.js");
8118
+ const { runUsageCli } = await import("./usage-WVUYNLOD.js");
7974
8119
  await runUsageCli(options);
7975
8120
  });
7976
8121
  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) => {
7977
- const { runDoctorCli } = await import("./doctor-cli-TGAW6RAP.js");
8122
+ const { runDoctorCli } = await import("./doctor-cli-HCP56MKH.js");
7978
8123
  const argv = process.argv.slice(2);
7979
8124
  await runDoctorCli({
7980
8125
  json: !!options.json || argv.includes("--json"),
@@ -7983,7 +8128,7 @@ program.command("doctor").description("Health check: API keys, config, MCP, rece
7983
8128
  });
7984
8129
  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) => {
7985
8130
  try {
7986
- const batch = await import("./batch-K66BLTLJ.js");
8131
+ const batch = await import("./batch-D3UHL432.js");
7987
8132
  switch (action) {
7988
8133
  case "submit":
7989
8134
  if (!arg) {
@@ -8026,7 +8171,7 @@ program.command("batch <action> [arg] [arg2]").description("Anthropic Message Ba
8026
8171
  }
8027
8172
  });
8028
8173
  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) => {
8029
- const { startMcpServer } = await import("./server-E545UIX7.js");
8174
+ const { startMcpServer } = await import("./server-EDCGPEGC.js");
8030
8175
  await startMcpServer({
8031
8176
  allowDestructive: !!options.allowDestructive,
8032
8177
  allowOutsideCwd: !!options.allowOutsideCwd,
@@ -8039,7 +8184,7 @@ program.command("pr <action> [target]").description("PR review helpers: review |
8039
8184
  console.error(`Unknown pr action: ${action}. Use review | security-review | summarize.`);
8040
8185
  process.exit(1);
8041
8186
  }
8042
- const { runPrCli } = await import("./pr-TJFKUZ4B.js");
8187
+ const { runPrCli } = await import("./pr-OICMUN6R.js");
8043
8188
  const result = await runPrCli({
8044
8189
  action,
8045
8190
  target,
@@ -8059,8 +8204,8 @@ program.command("pr <action> [target]").description("PR review helpers: review |
8059
8204
  process.exit(result.exitCode);
8060
8205
  });
8061
8206
  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) => {
8062
- const { runCi } = await import("./ci-T2ABDMMQ.js");
8063
- const { formatCiResult } = await import("./ci-format-S2PPU27O.js");
8207
+ const { runCi } = await import("./ci-WSED3Z6V.js");
8208
+ const { formatCiResult } = await import("./ci-format-6AYL2X2J.js");
8064
8209
  const formats = [options.json, options.markdown, options.sarif].filter(Boolean).length;
8065
8210
  if (formats > 1) {
8066
8211
  console.error("Choose only one output format: --json, --markdown, or --sarif.");
@@ -8218,7 +8363,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
8218
8363
  config.get("customProviders"),
8219
8364
  config.getConfigDir()
8220
8365
  );
8221
- const { startHub } = await import("./hub-GL5ZU6WS.js");
8366
+ const { startHub } = await import("./hub-K5MYSVEF.js");
8222
8367
  await startHub(
8223
8368
  {
8224
8369
  topic: topic ?? "",
@@ -2,9 +2,10 @@
2
2
  import {
3
3
  discussionToMessages,
4
4
  persistDiscussion
5
- } from "./chunk-2QQKS56X.js";
6
- import "./chunk-JMP3LJC2.js";
7
- import "./chunk-KCEO2XJ4.js";
5
+ } from "./chunk-DT77O33T.js";
6
+ import "./chunk-KWQKQVPH.js";
7
+ import "./chunk-PJ3ONBWZ.js";
8
+ import "./chunk-B5TYJO7V.js";
8
9
  import "./chunk-IW3Q7AE5.js";
9
10
  export {
10
11
  discussionToMessages,
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ addMemoryEntry,
4
+ clearMemoryEntries,
5
+ countPendingMemories,
6
+ deleteMemoryEntry,
7
+ detectStaleLegacyMarkdownEdit,
8
+ expireMemoryEntry,
9
+ exportMemoryEntries,
10
+ findSimilarMemory,
11
+ formatMemoryForPrompt,
12
+ getProjectKey,
13
+ isMemoryExpired,
14
+ isMemoryVisibleInProject,
15
+ listMemoryEntries,
16
+ listOrphanedProjectMemories,
17
+ loadMemoryEntries,
18
+ memoryMarkdownPath,
19
+ memoryStorePath,
20
+ parseWritableScope,
21
+ rebindMemoryProject,
22
+ renderMemoryMarkdown,
23
+ syncLegacyMarkdown,
24
+ updateMemoryApproval,
25
+ updateMemoryEntry
26
+ } from "./chunk-D27TMEOV.js";
27
+ import "./chunk-HOSJZMQS.js";
28
+ import "./chunk-Y4CMNXZH.js";
29
+ import "./chunk-B5TYJO7V.js";
30
+ import "./chunk-IW3Q7AE5.js";
31
+ export {
32
+ addMemoryEntry,
33
+ clearMemoryEntries,
34
+ countPendingMemories,
35
+ deleteMemoryEntry,
36
+ detectStaleLegacyMarkdownEdit,
37
+ expireMemoryEntry,
38
+ exportMemoryEntries,
39
+ findSimilarMemory,
40
+ formatMemoryForPrompt,
41
+ getProjectKey,
42
+ isMemoryExpired,
43
+ isMemoryVisibleInProject,
44
+ listMemoryEntries,
45
+ listOrphanedProjectMemories,
46
+ loadMemoryEntries,
47
+ memoryMarkdownPath,
48
+ memoryStorePath,
49
+ parseWritableScope,
50
+ rebindMemoryProject,
51
+ renderMemoryMarkdown,
52
+ syncLegacyMarkdown,
53
+ updateMemoryApproval,
54
+ updateMemoryEntry
55
+ };
@@ -0,0 +1,53 @@
1
+ import {
2
+ addMemoryEntry,
3
+ clearMemoryEntries,
4
+ countPendingMemories,
5
+ deleteMemoryEntry,
6
+ detectStaleLegacyMarkdownEdit,
7
+ expireMemoryEntry,
8
+ exportMemoryEntries,
9
+ findSimilarMemory,
10
+ formatMemoryForPrompt,
11
+ getProjectKey,
12
+ isMemoryExpired,
13
+ isMemoryVisibleInProject,
14
+ listMemoryEntries,
15
+ listOrphanedProjectMemories,
16
+ loadMemoryEntries,
17
+ memoryMarkdownPath,
18
+ memoryStorePath,
19
+ parseWritableScope,
20
+ rebindMemoryProject,
21
+ renderMemoryMarkdown,
22
+ syncLegacyMarkdown,
23
+ updateMemoryApproval,
24
+ updateMemoryEntry
25
+ } from "./chunk-UWV2NBCO.js";
26
+ import "./chunk-YVTASHS5.js";
27
+ import "./chunk-MKLPAQT6.js";
28
+ import "./chunk-6BUTA5VW.js";
29
+ export {
30
+ addMemoryEntry,
31
+ clearMemoryEntries,
32
+ countPendingMemories,
33
+ deleteMemoryEntry,
34
+ detectStaleLegacyMarkdownEdit,
35
+ expireMemoryEntry,
36
+ exportMemoryEntries,
37
+ findSimilarMemory,
38
+ formatMemoryForPrompt,
39
+ getProjectKey,
40
+ isMemoryExpired,
41
+ isMemoryVisibleInProject,
42
+ listMemoryEntries,
43
+ listOrphanedProjectMemories,
44
+ loadMemoryEntries,
45
+ memoryMarkdownPath,
46
+ memoryStorePath,
47
+ parseWritableScope,
48
+ rebindMemoryProject,
49
+ renderMemoryMarkdown,
50
+ syncLegacyMarkdown,
51
+ updateMemoryApproval,
52
+ updateMemoryEntry
53
+ };
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  countSeverity,
4
4
  runCi
5
- } from "./chunk-CHFFEVVT.js";
6
- import "./chunk-PGHTAKIA.js";
5
+ } from "./chunk-OO2PHOXD.js";
6
+ import "./chunk-LHINXQZF.js";
7
7
  import {
8
8
  buildReviewPrompt,
9
9
  buildSecurityReviewPrompt,
@@ -12,14 +12,14 @@ import {
12
12
  import {
13
13
  ProviderRegistry
14
14
  } from "./chunk-QYQI7ZWK.js";
15
- import "./chunk-O3XSFPYH.js";
16
15
  import {
17
16
  ConfigManager
18
- } from "./chunk-IV6GCDVR.js";
17
+ } from "./chunk-WMAXYDCB.js";
18
+ import "./chunk-O3XSFPYH.js";
19
19
  import "./chunk-5ULLIOVC.js";
20
20
  import {
21
21
  VERSION
22
- } from "./chunk-SMQHEJSH.js";
22
+ } from "./chunk-Y4CMNXZH.js";
23
23
  import "./chunk-IW3Q7AE5.js";
24
24
 
25
25
  // src/cli/pr.ts