jinzd-ai-cli 0.4.278 → 0.4.280

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-7Y4NAA6N.js → batch-F27NOTWC.js} +2 -2
  2. package/dist/{chunk-LTZFUYBT.js → chunk-B3FHA6IN.js} +3 -3
  3. package/dist/{chunk-WOXIKQRI.js → chunk-CP5LAA52.js} +4 -4
  4. package/dist/{chunk-2BYQP6JX.js → chunk-EOP775JU.js} +1 -1
  5. package/dist/{chunk-JJCNNQTU.js → chunk-IIO2SMEJ.js} +354 -3
  6. package/dist/{chunk-H7QC5VMQ.js → chunk-LPZNOYRJ.js} +1 -1
  7. package/dist/{chunk-LOXEYWC3.js → chunk-NHJ4GHL4.js} +1 -1
  8. package/dist/{chunk-SJCOE4C7.js → chunk-PN42JO74.js} +1 -1
  9. package/dist/{chunk-LXXQTWT2.js → chunk-PUC277TH.js} +1 -1
  10. package/dist/{chunk-4Z6GAYB5.js → chunk-TAIZZY3N.js} +3 -3
  11. package/dist/{chunk-X3722RFA.js → chunk-UBPRUSAF.js} +1 -1
  12. package/dist/{chunk-L3CPM472.js → chunk-UMWDNNPS.js} +1 -1
  13. package/dist/{chunk-RFSKPCYC.js → chunk-V7EZ4SDC.js} +1 -1
  14. package/dist/{chunk-SB4XONS4.js → chunk-VQCFEA4Z.js} +1 -1
  15. package/dist/{ci-WDF2CYR4.js → ci-HJ4OVHCM.js} +4 -4
  16. package/dist/{ci-format-7B5VAZGA.js → ci-format-NKJRZ3QI.js} +2 -2
  17. package/dist/{constants-DC3TNLTL.js → constants-6LCZOBJC.js} +1 -1
  18. package/dist/{doctor-cli-CDDG5XOY.js → doctor-cli-7JGPC5G4.js} +4 -4
  19. package/dist/electron-server.js +525 -140
  20. package/dist/{hub-TO7ODOIA.js → hub-NX7HYN7V.js} +1 -1
  21. package/dist/index.js +151 -429
  22. package/dist/{persistent-memory-JCENBMCJ.js → persistent-memory-E6WECUTW.js} +2 -2
  23. package/dist/{persistent-memory-BU63CSGK.js → persistent-memory-MHHX7F25.js} +2 -2
  24. package/dist/{pr-GVSZYX6I.js → pr-GLUFBQLI.js} +4 -4
  25. package/dist/{run-tests-2Q5MJHXB.js → run-tests-LWAFPVS3.js} +2 -2
  26. package/dist/{run-tests-R4IQS6IF.js → run-tests-YPJDOEJA.js} +2 -2
  27. package/dist/{server-KAURBKFI.js → server-CXXYIPMU.js} +226 -145
  28. package/dist/{server-WXLE53HG.js → server-P6DI27CY.js} +5 -5
  29. package/dist/{task-orchestrator-RJ6FXYY5.js → task-orchestrator-FW4LBPTS.js} +5 -5
  30. package/dist/{usage-V3R7DA7M.js → usage-CJUHQDT2.js} +2 -2
  31. package/dist/web/client/app.js +14 -2
  32. package/dist/web/client/app.js.br +0 -0
  33. package/dist/web/client/app.js.gz +0 -0
  34. package/package.json +1 -1
@@ -27,9 +27,9 @@ import {
27
27
  touchMemoryReferences,
28
28
  updateMemoryApproval,
29
29
  updateMemoryEntry
30
- } from "./chunk-LXXQTWT2.js";
30
+ } from "./chunk-PUC277TH.js";
31
31
  import "./chunk-FSC6KEWU.js";
32
- import "./chunk-SJCOE4C7.js";
32
+ import "./chunk-PN42JO74.js";
33
33
  import "./chunk-6BUTA5VW.js";
34
34
  export {
35
35
  addMemoryEntry,
@@ -28,11 +28,11 @@ import {
28
28
  touchMemoryReferences,
29
29
  updateMemoryApproval,
30
30
  updateMemoryEntry
31
- } from "./chunk-RFSKPCYC.js";
31
+ } from "./chunk-V7EZ4SDC.js";
32
32
  import "./chunk-3FEZSLGI.js";
33
33
  import "./chunk-HOSJZMQS.js";
34
34
  import "./chunk-IW3Q7AE5.js";
35
- import "./chunk-X3722RFA.js";
35
+ import "./chunk-UBPRUSAF.js";
36
36
  export {
37
37
  addMemoryEntry,
38
38
  backupMemoryStore,
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  countSeverity,
4
4
  runCi
5
- } from "./chunk-4Z6GAYB5.js";
6
- import "./chunk-H7QC5VMQ.js";
5
+ } from "./chunk-TAIZZY3N.js";
6
+ import "./chunk-LPZNOYRJ.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-2BYQP6JX.js";
20
+ } from "./chunk-EOP775JU.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-X3722RFA.js";
26
+ } from "./chunk-UBPRUSAF.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-LOXEYWC3.js";
5
- import "./chunk-SJCOE4C7.js";
4
+ } from "./chunk-NHJ4GHL4.js";
5
+ import "./chunk-PN42JO74.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-SB4XONS4.js";
6
- import "./chunk-X3722RFA.js";
5
+ } from "./chunk-VQCFEA4Z.js";
6
+ import "./chunk-UBPRUSAF.js";
7
7
  export {
8
8
  executeTests,
9
9
  runTestsTool
@@ -23,6 +23,11 @@ import {
23
23
  autoTrimSessionIfNeeded,
24
24
  buildInitPrompt,
25
25
  buildSessionCostReport,
26
+ buildSessionExport,
27
+ checkpointDeletedMessage,
28
+ checkpointNotFoundMessage,
29
+ checkpointRestoredMessage,
30
+ checkpointSavedMessage,
26
31
  costSourceNote,
27
32
  decideDeferredSave,
28
33
  decideModel,
@@ -30,22 +35,34 @@ import {
30
35
  estimateConversationTokens,
31
36
  evaluateContextPressure,
32
37
  filterMemoryEntries,
38
+ formatCheckpointList,
39
+ formatSessionSummaryLine,
33
40
  loadDevState,
41
+ parseBatchDeleteArgs,
42
+ parseCheckpointCommand,
43
+ parseCleanArgs,
34
44
  parseMemoryShowFilters,
35
45
  parseModelCommand,
36
46
  parseRouteCommand,
47
+ parseSessionListArgs,
37
48
  persistToolRound,
38
49
  readGitDiff,
39
50
  resolveModelSwitch,
40
51
  resolveProviderSwitch,
52
+ resolveSessionRef,
41
53
  routeDecisionRows,
42
54
  routingEmptyRulesNote,
43
55
  scanDirTree,
44
56
  scanProject,
57
+ selectSessions,
58
+ selectStaleSessions,
59
+ sessionListJsonRow,
60
+ sessionListNeedsFileSize,
61
+ sessionListSummary,
45
62
  setupProxy,
46
63
  snapshotFile,
47
64
  stripRoutingTags
48
- } from "./chunk-JJCNNQTU.js";
65
+ } from "./chunk-IIO2SMEJ.js";
49
66
  import {
50
67
  CNY_PER_USD,
51
68
  CostTracker,
@@ -87,7 +104,7 @@ import {
87
104
  spawnAgentContext,
88
105
  truncateOutput,
89
106
  undoStack
90
- } from "./chunk-WOXIKQRI.js";
107
+ } from "./chunk-CP5LAA52.js";
91
108
  import {
92
109
  buildReviewPrompt,
93
110
  buildSecurityReviewPrompt
@@ -114,7 +131,7 @@ import {
114
131
  restoreMemoryEntries,
115
132
  updateMemoryApproval,
116
133
  updateMemoryEntry
117
- } from "./chunk-RFSKPCYC.js";
134
+ } from "./chunk-V7EZ4SDC.js";
118
135
  import "./chunk-4DEMGCK4.js";
119
136
  import "./chunk-UUSRWSSX.js";
120
137
  import "./chunk-CKH4KQ4E.js";
@@ -133,7 +150,7 @@ import {
133
150
  buildDoctorReport,
134
151
  formatDoctorReport,
135
152
  loadContextFiles
136
- } from "./chunk-LTZFUYBT.js";
153
+ } from "./chunk-B3FHA6IN.js";
137
154
  import {
138
155
  describePlugin,
139
156
  getActivePluginAssets,
@@ -148,13 +165,13 @@ import {
148
165
  runTool,
149
166
  setPluginEnabled,
150
167
  trustPlugin
151
- } from "./chunk-L3CPM472.js";
168
+ } from "./chunk-UMWDNNPS.js";
152
169
  import {
153
170
  ProviderRegistry
154
171
  } from "./chunk-UGY5SVNX.js";
155
172
  import {
156
173
  ConfigManager
157
- } from "./chunk-2BYQP6JX.js";
174
+ } from "./chunk-EOP775JU.js";
158
175
  import {
159
176
  CONTENT_ONLY_STREAM_REMINDER,
160
177
  TEE_FINAL_USER_NUDGE,
@@ -184,7 +201,7 @@ import {
184
201
  maskConfigSecrets
185
202
  } from "./chunk-XNFIYS7G.js";
186
203
  import "./chunk-4BKXL7SM.js";
187
- import "./chunk-SB4XONS4.js";
204
+ import "./chunk-VQCFEA4Z.js";
188
205
  import {
189
206
  AGENTIC_BEHAVIOR_GUIDELINE,
190
207
  AUTHOR,
@@ -200,7 +217,7 @@ import {
200
217
  SKILLS_DIR_NAME,
201
218
  VERSION,
202
219
  buildUserIdentityPrompt
203
- } from "./chunk-X3722RFA.js";
220
+ } from "./chunk-UBPRUSAF.js";
204
221
 
205
222
  // src/web/server.ts
206
223
  import express from "express";
@@ -954,7 +971,7 @@ Cache: write=${cacheCreate} read=${cacheRead}` : "";
954
971
  Cost: ${formatCost(cost)}` : "";
955
972
  let memoryLine = "";
956
973
  try {
957
- const { countPendingMemories: countPendingMemories2 } = await import("./persistent-memory-BU63CSGK.js");
974
+ const { countPendingMemories: countPendingMemories2 } = await import("./persistent-memory-MHHX7F25.js");
958
975
  const pending = countPendingMemories2(ctx.config.getConfigDir());
959
976
  if (pending > 0) memoryLine = `
960
977
  Memory: \u26A0 ${pending} pending approval \u2014 see the Memory panel or /memory`;
@@ -997,11 +1014,17 @@ async function handleSession(args, ctx) {
997
1014
  ctx.sendSessionList();
998
1015
  return;
999
1016
  }
1000
- const list = ctx.sessions.listSessions();
1001
- const found = list.find((s) => s.id.startsWith(targetId));
1002
- if (found) {
1017
+ const ref = resolveSessionRef(ctx.sessions.listSessions(), targetId, "most-recent");
1018
+ if (ref.status === "ok") {
1019
+ const found = ref.match;
1003
1020
  ctx.sessions.loadSession(found.id);
1004
1021
  ctx.resetWebSessionUsage();
1022
+ if (ref.message) {
1023
+ ctx.send({
1024
+ type: "info",
1025
+ message: [ref.message, ...ref.ambiguousWith.slice(0, 5).map((m) => ` ${formatSessionSummaryLine(m)}`)].join("\n")
1026
+ });
1027
+ }
1005
1028
  ctx.send({ type: "info", message: `Loaded session: ${found.id.slice(0, 8)} "${found.title ?? ""}" (${found.messageCount} messages)` });
1006
1029
  const loadedSession = ctx.sessions.current;
1007
1030
  if (loadedSession && loadedSession.messages.length > 0) {
@@ -1031,52 +1054,81 @@ async function handleSession(args, ctx) {
1031
1054
  return;
1032
1055
  }
1033
1056
  if (sub === "list") {
1034
- ctx.sendSessionList();
1057
+ if (args.length <= 1) {
1058
+ ctx.sendSessionList();
1059
+ return;
1060
+ }
1061
+ const opts = parseSessionListArgs(args);
1062
+ const all = ctx.sessions.listSessions({ includeFileSize: sessionListNeedsFileSize(opts) });
1063
+ if (all.length === 0) {
1064
+ ctx.send({ type: "info", message: "No saved sessions." });
1065
+ return;
1066
+ }
1067
+ const view = selectSessions(all, opts);
1068
+ if (view.totalCount === 0) {
1069
+ ctx.send({
1070
+ type: "info",
1071
+ message: [...opts.warnings.map((w) => `\u26A0 ${w}`), "No sessions match the filter criteria."].join("\n")
1072
+ });
1073
+ return;
1074
+ }
1075
+ if (opts.json) {
1076
+ ctx.send({
1077
+ type: "info",
1078
+ message: JSON.stringify(view.shown.map((s) => sessionListJsonRow(s, view.needsFileSize)), null, 2)
1079
+ });
1080
+ return;
1081
+ }
1082
+ const lines = [
1083
+ ...opts.warnings.map((w) => `\u26A0 ${w}`),
1084
+ ...view.shown.map((s) => formatSessionSummaryLine(s)),
1085
+ `\u2500\u2500 ${sessionListSummary(view)}`
1086
+ ];
1087
+ if (view.shown.length < view.totalCount) lines.push("Use --all to show all, or --limit N to change count.");
1088
+ ctx.send({ type: "info", message: lines.join("\n") });
1035
1089
  return;
1036
1090
  }
1037
1091
  if (sub === "delete" && args[1]) {
1038
1092
  const targetId = args[1];
1039
1093
  if (targetId === "--filter") {
1040
- let filterMessages;
1041
- for (let i = 1; i < args.length; i++) {
1042
- if (args[i] === "--filter" && i + 1 < args.length) {
1043
- const val = args[i + 1];
1044
- i++;
1045
- const eq = val.indexOf("=");
1046
- if (eq > 0) {
1047
- const key = val.slice(0, eq);
1048
- const vals = val.slice(eq + 1).split(",").map((s) => s.trim().toLowerCase());
1049
- if (key === "messages") {
1050
- const n = Number(vals[0]);
1051
- if (Number.isFinite(n) && n >= 0) filterMessages = n;
1052
- }
1053
- }
1054
- }
1055
- }
1056
- if (filterMessages === void 0) {
1057
- ctx.send({ type: "error", message: "Usage: /session delete --filter messages=N" });
1094
+ const opts = parseBatchDeleteArgs(args);
1095
+ if (opts.error) {
1096
+ ctx.send({ type: "error", message: opts.error });
1058
1097
  return;
1059
1098
  }
1060
- const list2 = ctx.sessions.listSessions();
1061
- const matches = list2.filter((s) => s.messageCount === filterMessages);
1099
+ const matches = ctx.sessions.listSessions().filter((s) => s.messageCount === opts.messages);
1062
1100
  if (matches.length === 0) {
1063
- ctx.send({ type: "info", message: `No sessions with ${filterMessages} message(s) found.` });
1101
+ ctx.send({ type: "info", message: `No sessions with ${opts.messages} message(s) found.` });
1102
+ return;
1103
+ }
1104
+ const preview = [
1105
+ `Found ${matches.length} session(s) with ${opts.messages} message(s):`,
1106
+ ...matches.slice(0, 20).map((s) => ` ${formatSessionSummaryLine(s)}`),
1107
+ ...matches.length > 20 ? [` ... and ${matches.length - 20} more`] : []
1108
+ ];
1109
+ if (opts.dryRun) {
1110
+ ctx.send({
1111
+ type: "info",
1112
+ message: [...preview, "--dry-run: no sessions were deleted. Remove --dry-run to actually delete."].join("\n")
1113
+ });
1064
1114
  return;
1065
1115
  }
1066
1116
  let deleted = 0;
1067
1117
  let failed = 0;
1068
1118
  for (const s of matches) {
1069
- if (ctx.sessions.deleteSession(s.id)) {
1070
- deleted++;
1071
- } else {
1072
- failed++;
1073
- }
1119
+ if (ctx.sessions.deleteSession(s.id)) deleted++;
1120
+ else failed++;
1074
1121
  }
1075
1122
  if (!ctx.sessions.current) {
1076
- ctx.sessions.createSession(ctx.currentProvider, ctx.currentModel);
1123
+ const created = ctx.sessions.createSession(ctx.currentProvider, ctx.currentModel);
1124
+ ctx.unsavedSessions.set(created.id, created);
1077
1125
  ctx.resetWebSessionUsage();
1078
1126
  }
1079
- ctx.send({ type: "info", message: `Deleted ${deleted} session(s) with ${filterMessages} message(s)${failed > 0 ? `, ${failed} failed` : ""}.` });
1127
+ ctx.send({
1128
+ type: "info",
1129
+ message: [...preview, `Deleted ${deleted} session(s)${failed > 0 ? `, ${failed} failed` : ""}.`].join("\n")
1130
+ });
1131
+ ctx.sendStatus();
1080
1132
  ctx.sendSessionList();
1081
1133
  return;
1082
1134
  }
@@ -1085,20 +1137,79 @@ async function handleSession(args, ctx) {
1085
1137
  ctx.unsavedSessions.delete(cachedKey);
1086
1138
  if (ctx.sessions.current?.id === cachedKey) {
1087
1139
  ctx.sessions.clearCurrent();
1140
+ const created = ctx.sessions.createSession(ctx.currentProvider, ctx.currentModel);
1141
+ ctx.unsavedSessions.set(created.id, created);
1142
+ ctx.resetWebSessionUsage();
1143
+ ctx.sendStatus();
1088
1144
  }
1089
1145
  ctx.send({ type: "info", message: `Deleted session: ${cachedKey.slice(0, 8)}` });
1090
1146
  ctx.sendSessionList();
1091
1147
  return;
1092
1148
  }
1093
- const list = ctx.sessions.listSessions();
1094
- const found = list.find((s) => s.id.startsWith(targetId));
1095
- if (found) {
1096
- ctx.sessions.deleteSession(found.id);
1097
- ctx.send({ type: "info", message: `Deleted session: ${found.id.slice(0, 8)}` });
1098
- ctx.sendSessionList();
1099
- } else {
1149
+ const ref = resolveSessionRef(ctx.sessions.listSessions(), targetId, "strict");
1150
+ if (ref.status === "not-found") {
1100
1151
  ctx.send({ type: "error", message: `Session not found: ${targetId}` });
1152
+ return;
1153
+ }
1154
+ if (ref.status === "ambiguous") {
1155
+ ctx.send({
1156
+ type: "error",
1157
+ message: [ref.message, ...ref.matches.slice(0, 10).map((m) => ` ${formatSessionSummaryLine(m)}`)].join("\n")
1158
+ });
1159
+ return;
1160
+ }
1161
+ const wasCurrent = ctx.sessions.current?.id === ref.match.id;
1162
+ if (!ctx.sessions.deleteSession(ref.match.id)) {
1163
+ ctx.send({ type: "error", message: "Delete failed \u2014 session file not found on disk." });
1164
+ return;
1165
+ }
1166
+ ctx.send({ type: "info", message: `Deleted session: ${ref.match.id.slice(0, 8)}` });
1167
+ if (wasCurrent) {
1168
+ const created = ctx.sessions.createSession(ctx.currentProvider, ctx.currentModel);
1169
+ ctx.unsavedSessions.set(created.id, created);
1170
+ ctx.resetWebSessionUsage();
1171
+ ctx.send({ type: "info", message: "Current session was deleted \u2014 started a fresh session." });
1172
+ ctx.sendStatus();
1101
1173
  }
1174
+ ctx.sendSessionList();
1175
+ return;
1176
+ }
1177
+ if (sub === "clean") {
1178
+ const opts = parseCleanArgs(args);
1179
+ const stale = selectStaleSessions(ctx.sessions.listSessions(), opts.staleDays);
1180
+ if (stale.length === 0) {
1181
+ ctx.send({ type: "info", message: `No sessions older than ${opts.staleDays} days found.` });
1182
+ return;
1183
+ }
1184
+ const preview = [
1185
+ `Found ${stale.length} session(s) not updated in ${opts.staleDays}+ days:`,
1186
+ ...stale.slice(0, 20).map((s) => ` ${formatSessionSummaryLine(s)}`),
1187
+ ...stale.length > 20 ? [` ... and ${stale.length - 20} more`] : []
1188
+ ];
1189
+ if (opts.dryRun) {
1190
+ ctx.send({
1191
+ type: "info",
1192
+ message: [...preview, "--dry-run: no sessions were deleted. Remove --dry-run to actually delete."].join("\n")
1193
+ });
1194
+ return;
1195
+ }
1196
+ let deleted = 0;
1197
+ let failed = 0;
1198
+ for (const s of stale) {
1199
+ if (ctx.sessions.deleteSession(s.id)) deleted++;
1200
+ else failed++;
1201
+ }
1202
+ if (!ctx.sessions.current) {
1203
+ const created = ctx.sessions.createSession(ctx.currentProvider, ctx.currentModel);
1204
+ ctx.unsavedSessions.set(created.id, created);
1205
+ ctx.resetWebSessionUsage();
1206
+ ctx.sendStatus();
1207
+ }
1208
+ ctx.send({
1209
+ type: "info",
1210
+ message: [...preview, `Cleaned up: ${deleted} deleted${failed > 0 ? `, ${failed} failed` : ""}.`].join("\n")
1211
+ });
1212
+ ctx.sendSessionList();
1102
1213
  return;
1103
1214
  }
1104
1215
  if (sub === "batch-delete") {
@@ -1122,6 +1233,12 @@ async function handleSession(args, ctx) {
1122
1233
  deleted++;
1123
1234
  }
1124
1235
  }
1236
+ if (!ctx.sessions.current) {
1237
+ const created = ctx.sessions.createSession(ctx.currentProvider, ctx.currentModel);
1238
+ ctx.unsavedSessions.set(created.id, created);
1239
+ ctx.resetWebSessionUsage();
1240
+ ctx.sendStatus();
1241
+ }
1125
1242
  ctx.send({ type: "info", message: `Deleted ${deleted} session(s).` });
1126
1243
  ctx.sendSessionList();
1127
1244
  return;
@@ -1135,26 +1252,40 @@ async function handleSession(args, ctx) {
1135
1252
  }
1136
1253
  const cachedKey = ctx.unsavedSessions.has(targetId) ? targetId : [...ctx.unsavedSessions.keys()].find((k) => k.startsWith(targetId));
1137
1254
  if (cachedKey) {
1138
- const session = ctx.unsavedSessions.get(cachedKey);
1139
- session.title = newTitle;
1255
+ const session2 = ctx.unsavedSessions.get(cachedKey);
1256
+ session2.title = newTitle;
1140
1257
  ctx.send({ type: "info", message: `Renamed session: "${newTitle}"` });
1141
1258
  ctx.sendSessionList();
1142
1259
  return;
1143
1260
  }
1144
- const list = ctx.sessions.listSessions();
1145
- const found = list.find((s) => s.id.startsWith(targetId));
1146
- if (found) {
1147
- const session = ctx.sessions.loadSession(found.id);
1148
- session.title = newTitle;
1149
- ctx.sessions.save();
1150
- ctx.send({ type: "info", message: `Renamed session: "${newTitle}"` });
1151
- ctx.sendSessionList();
1152
- } else {
1261
+ const ref = resolveSessionRef(ctx.sessions.listSessions(), targetId, "strict");
1262
+ if (ref.status === "not-found") {
1153
1263
  ctx.send({ type: "error", message: `Session not found: ${targetId}` });
1264
+ return;
1265
+ }
1266
+ if (ref.status === "ambiguous") {
1267
+ ctx.send({
1268
+ type: "error",
1269
+ message: [ref.message, ...ref.matches.slice(0, 10).map((m) => ` ${formatSessionSummaryLine(m)}`)].join("\n")
1270
+ });
1271
+ return;
1154
1272
  }
1273
+ const priorId = ctx.sessions.current?.id ?? null;
1274
+ const isCurrent = priorId === ref.match.id;
1275
+ const session = isCurrent ? ctx.sessions.current : ctx.sessions.loadSession(ref.match.id);
1276
+ session.title = newTitle;
1277
+ ctx.sessions.save();
1278
+ if (!isCurrent && priorId) {
1279
+ ctx.sessions.loadSession(priorId);
1280
+ }
1281
+ ctx.send({ type: "info", message: `Renamed session: "${newTitle}"` });
1282
+ ctx.sendSessionList();
1155
1283
  return;
1156
1284
  }
1157
- ctx.send({ type: "info", message: "Usage: /session new | list | load <id> | delete <id> | delete --filter messages=N | rename <id> <title>" });
1285
+ ctx.send({
1286
+ type: "info",
1287
+ message: "Usage: /session new | list [--filter k=v] [--search kw] [--limit N|--all] [--sort f[:o]] [--json] | load <id> | delete <id> | delete --filter messages=N [--dry-run] | clean --stale N [--dry-run] | rename <id> <title>"
1288
+ });
1158
1289
  }
1159
1290
  async function handleExport(args, ctx) {
1160
1291
  const format = args[0] === "json" ? "json" : "md";
@@ -1201,56 +1332,36 @@ async function handleCheckpoint(args, ctx) {
1201
1332
  ctx.send({ type: "error", message: "No active session." });
1202
1333
  return;
1203
1334
  }
1204
- const sub = args[0]?.toLowerCase();
1205
- if (!sub || sub === "list") {
1206
- const cps = session.checkpoints;
1207
- if (cps.length === 0) {
1208
- ctx.send({ type: "info", message: "No checkpoints. Use /checkpoint save <name> to create one." });
1209
- } else {
1210
- const lines = [`\u{1F4CC} Checkpoints (${cps.length}):`, ""];
1211
- for (const cp of cps) {
1212
- const ts = cp.timestamp.toLocaleString();
1213
- lines.push(` ${cp.name.padEnd(20)} msg #${cp.messageIndex} ${ts}`);
1214
- }
1215
- ctx.send({ type: "info", message: lines.join("\n") });
1216
- }
1335
+ const intent = parseCheckpointCommand(args);
1336
+ if (intent.kind === "list") {
1337
+ ctx.send({ type: "info", message: formatCheckpointList(session.checkpoints).join("\n") });
1217
1338
  return;
1218
1339
  }
1219
- const cpName = args.slice(1).join(" ").trim();
1220
- if (sub === "save") {
1221
- if (!cpName) {
1222
- ctx.send({ type: "error", message: "Usage: /checkpoint save <name>" });
1223
- return;
1224
- }
1225
- session.createCheckpoint(cpName);
1226
- ctx.send({ type: "info", message: `\u2713 Checkpoint "${cpName}" saved at message #${session.messages.length}` });
1227
- } else if (sub === "restore") {
1228
- if (!cpName) {
1229
- ctx.send({ type: "error", message: "Usage: /checkpoint restore <name>" });
1230
- return;
1231
- }
1232
- const ok = session.restoreCheckpoint(cpName);
1233
- if (ok) {
1234
- ctx.send({ type: "info", message: `\u2713 Restored to checkpoint "${cpName}" (${session.messages.length} messages)` });
1235
- ctx.sendSessionMessages();
1236
- ctx.sendStatus();
1237
- } else {
1238
- ctx.send({ type: "error", message: `Checkpoint "${cpName}" not found.` });
1239
- }
1240
- } else if (sub === "delete") {
1241
- if (!cpName) {
1242
- ctx.send({ type: "error", message: "Usage: /checkpoint delete <name>" });
1340
+ if (intent.kind === "usage" || intent.kind === "unknown") {
1341
+ ctx.send({ type: "error", message: intent.message });
1342
+ return;
1343
+ }
1344
+ if (intent.kind === "save") {
1345
+ session.createCheckpoint(intent.name);
1346
+ ctx.send({ type: "info", message: checkpointSavedMessage(intent.name, session.messages.length) });
1347
+ return;
1348
+ }
1349
+ if (intent.kind === "restore") {
1350
+ if (!session.restoreCheckpoint(intent.name)) {
1351
+ ctx.send({ type: "error", message: checkpointNotFoundMessage(intent.name) });
1243
1352
  return;
1244
1353
  }
1245
- const ok = session.deleteCheckpoint(cpName);
1246
- if (ok) {
1247
- ctx.send({ type: "info", message: `\u2713 Deleted checkpoint "${cpName}"` });
1248
- } else {
1249
- ctx.send({ type: "error", message: `Checkpoint "${cpName}" not found.` });
1250
- }
1251
- } else {
1252
- ctx.send({ type: "error", message: `Unknown subcommand: ${sub}. Use save/restore/list/delete.` });
1354
+ ctx.resetWebSessionUsage();
1355
+ ctx.send({ type: "info", message: checkpointRestoredMessage(intent.name, session.messages.length) });
1356
+ ctx.sendSessionMessages();
1357
+ ctx.sendStatus();
1358
+ return;
1359
+ }
1360
+ if (!session.deleteCheckpoint(intent.name)) {
1361
+ ctx.send({ type: "error", message: checkpointNotFoundMessage(intent.name) });
1362
+ return;
1253
1363
  }
1364
+ ctx.send({ type: "info", message: checkpointDeletedMessage(intent.name) });
1254
1365
  }
1255
1366
  async function handleBranch(args, ctx) {
1256
1367
  const session = ctx.sessions.current;
@@ -1767,7 +1878,7 @@ async function handleTest(args, ctx) {
1767
1878
  const isCommand = argStr.includes(" ") || /^(mvn|gradle|npm|pytest|cargo|go)\b/.test(argStr);
1768
1879
  testArgs = isCommand ? { command: argStr } : { filter: argStr };
1769
1880
  }
1770
- const runTests = ctx.runTests ?? (await import("./run-tests-R4IQS6IF.js")).executeTests;
1881
+ const runTests = ctx.runTests ?? (await import("./run-tests-YPJDOEJA.js")).executeTests;
1771
1882
  const report = await runTests(testArgs);
1772
1883
  ctx.send({ type: "info", message: report });
1773
1884
  } catch (err) {
@@ -2103,7 +2214,7 @@ async function handleMemory(args, ctx) {
2103
2214
  ctx.handleMemoryManage(sub, args[1], sub === "expire" ? args[2] : void 0);
2104
2215
  } else if (sub === "export") {
2105
2216
  if (args[1] === "md") {
2106
- const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-BU63CSGK.js");
2217
+ const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-MHHX7F25.js");
2107
2218
  ctx.send({
2108
2219
  type: "export_data",
2109
2220
  format: "md",
@@ -2359,7 +2470,7 @@ async function handleHelp(_args, ctx) {
2359
2470
  " /think [on|off] \u2014 Toggle extended thinking mode",
2360
2471
  " /plan [execute|exit|status] \u2014 Read-only planning mode (bare /plan enters it)",
2361
2472
  " /route [on|off|show|test <msg>] \u2014 Smart model routing",
2362
- " /session new|list|load|delete <id> \u2014 Session management",
2473
+ " /session new|list [filters]|load <id>|delete <id>|delete --filter messages=N [--dry-run]|clean --stale N [--dry-run]|rename <id> <title> \u2014 Session management",
2363
2474
  " /system [prompt|clear] \u2014 Set/view/reset system prompt",
2364
2475
  " /context [status|reload] \u2014 Show/reload context layers",
2365
2476
  " /status \u2014 Show session info & token usage",
@@ -3760,43 +3871,13 @@ ${summaryContent}`,
3760
3871
  this.send({ type: "info", message: "No messages to export." });
3761
3872
  return;
3762
3873
  }
3763
- const title = session.title ?? "Untitled";
3764
- const timestamp = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
3765
- if (format === "json") {
3766
- const data = {
3767
- title,
3768
- provider: this.currentProvider,
3769
- model: this.currentModel,
3770
- exported: (/* @__PURE__ */ new Date()).toISOString(),
3771
- messages: session.messages.map((m) => ({
3772
- role: m.role,
3773
- content: getContentText(m.content),
3774
- timestamp: m.timestamp?.toISOString()
3775
- }))
3776
- };
3777
- this.send({
3778
- type: "export_data",
3779
- format: "json",
3780
- filename: `aicli-${timestamp}.json`,
3781
- content: JSON.stringify(data, null, 2)
3782
- });
3783
- } else {
3784
- const lines = [`# ${title}`, "", `> Exported: ${(/* @__PURE__ */ new Date()).toLocaleString()} | Provider: ${this.currentProvider} | Model: ${this.currentModel}`, ""];
3785
- for (const m of session.messages) {
3786
- const text = getContentText(m.content);
3787
- if (m.role === "user") {
3788
- lines.push(`## \u{1F9D1} User`, "", text, "");
3789
- } else if (m.role === "assistant") {
3790
- lines.push(`## \u{1F916} Assistant`, "", text, "");
3791
- }
3792
- }
3793
- this.send({
3794
- type: "export_data",
3795
- format: "md",
3796
- filename: `aicli-${timestamp}.md`,
3797
- content: lines.join("\n")
3798
- });
3799
- }
3874
+ const exported = buildSessionExport(session, format);
3875
+ this.send({
3876
+ type: "export_data",
3877
+ format,
3878
+ filename: exported.filename,
3879
+ content: exported.content
3880
+ });
3800
3881
  }
3801
3882
  memoryShow(args = []) {
3802
3883
  const configDir = this.config.getConfigDir();
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ToolRegistry
4
- } from "./chunk-WOXIKQRI.js";
4
+ } from "./chunk-CP5LAA52.js";
5
5
  import "./chunk-GHWZVPUV.js";
6
- import "./chunk-RFSKPCYC.js";
6
+ import "./chunk-V7EZ4SDC.js";
7
7
  import "./chunk-4DEMGCK4.js";
8
8
  import "./chunk-UUSRWSSX.js";
9
9
  import "./chunk-CKH4KQ4E.js";
@@ -14,7 +14,7 @@ import "./chunk-NYNSYLFY.js";
14
14
  import "./chunk-3FEZSLGI.js";
15
15
  import {
16
16
  runTool
17
- } from "./chunk-L3CPM472.js";
17
+ } from "./chunk-UMWDNNPS.js";
18
18
  import {
19
19
  getDangerLevel,
20
20
  schemaToJsonSchema
@@ -23,10 +23,10 @@ import "./chunk-TU3L3PW7.js";
23
23
  import "./chunk-HOSJZMQS.js";
24
24
  import "./chunk-IW3Q7AE5.js";
25
25
  import "./chunk-4BKXL7SM.js";
26
- import "./chunk-SB4XONS4.js";
26
+ import "./chunk-VQCFEA4Z.js";
27
27
  import {
28
28
  VERSION
29
- } from "./chunk-X3722RFA.js";
29
+ } from "./chunk-UBPRUSAF.js";
30
30
 
31
31
  // src/mcp/server.ts
32
32
  import { createInterface } from "readline";