jinzd-ai-cli 0.4.220 → 0.4.221
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.
- package/dist/{batch-QBSKTLTO.js → batch-LSWWSINO.js} +2 -2
- package/dist/{chunk-IZW5LMI6.js → chunk-4AX2MEJA.js} +3 -3
- package/dist/{chunk-Y25MSSUP.js → chunk-4MOBTDS6.js} +1 -1
- package/dist/{chunk-P4PTXCHY.js → chunk-5BY4XICU.js} +3 -3
- package/dist/{chunk-MC34ISJU.js → chunk-5GTWZ4QF.js} +30 -6
- package/dist/{chunk-P3LKFA54.js → chunk-6SKMGONY.js} +3 -3
- package/dist/{chunk-VHX7KZDY.js → chunk-BYQEWWA4.js} +2 -2
- package/dist/{chunk-P4DYAGUI.js → chunk-OULVIHCT.js} +1 -1
- package/dist/{chunk-5WBNXYDJ.js → chunk-PMTEZTXP.js} +1 -1
- package/dist/{chunk-QZYNRCPX.js → chunk-QDN5G7JN.js} +1 -1
- package/dist/{chunk-ALQN7VUJ.js → chunk-QKJ3MAP7.js} +1 -1
- package/dist/{chunk-A4GUGWEY.js → chunk-QT5FA2ZY.js} +1 -1
- package/dist/{chunk-CAUHLHDR.js → chunk-S5EEKS4P.js} +1 -1
- package/dist/{ci-5SNXGM3M.js → ci-OIFTAJKR.js} +4 -4
- package/dist/{ci-format-57QQTHQE.js → ci-format-H6BLMWQ5.js} +2 -2
- package/dist/{constants-ML5KFEOH.js → constants-EJRLT7DM.js} +1 -1
- package/dist/{doctor-cli-ZRH3XZ3R.js → doctor-cli-EXC7YU5D.js} +4 -4
- package/dist/electron-server.js +73 -44
- package/dist/{hub-IPLMJ6TJ.js → hub-HQDRQBNM.js} +2 -2
- package/dist/index.js +322 -32
- package/dist/{persist-L54DPLI7.js → persist-GTBEKVFL.js} +2 -2
- package/dist/{pr-GJYDAPK4.js → pr-VSZNVKBS.js} +4 -4
- package/dist/{run-tests-GK5AIAV2.js → run-tests-55JGEZYL.js} +1 -1
- package/dist/{run-tests-KLQAI5CX.js → run-tests-OYXK27XH.js} +2 -2
- package/dist/{server-RU36PRSH.js → server-JKNIZ5CB.js} +19 -14
- package/dist/{server-5FZDALHH.js → server-XX6UM4ZQ.js} +4 -4
- package/dist/{task-orchestrator-JMHPVNUO.js → task-orchestrator-F3DUIACA.js} +4 -4
- package/dist/{usage-IRMRCCKN.js → usage-4KFX3HTK.js} +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
scanProject,
|
|
15
15
|
sessionHasMeaningfulContent,
|
|
16
16
|
setupProxy
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-BYQEWWA4.js";
|
|
18
18
|
import {
|
|
19
19
|
buildReviewPrompt,
|
|
20
20
|
buildSecurityReviewPrompt
|
|
@@ -51,15 +51,15 @@ import {
|
|
|
51
51
|
theme,
|
|
52
52
|
undoStack,
|
|
53
53
|
updateMemoryApproval
|
|
54
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-4AX2MEJA.js";
|
|
55
55
|
import "./chunk-K3CF65QH.js";
|
|
56
56
|
import "./chunk-T2NL5ZIA.js";
|
|
57
57
|
import "./chunk-BXP6YZ2P.js";
|
|
58
|
-
import "./chunk-
|
|
58
|
+
import "./chunk-4MOBTDS6.js";
|
|
59
59
|
import {
|
|
60
60
|
SessionManager,
|
|
61
61
|
getContentText
|
|
62
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-5GTWZ4QF.js";
|
|
63
63
|
import {
|
|
64
64
|
CostTracker
|
|
65
65
|
} from "./chunk-CITDVXXM.js";
|
|
@@ -87,7 +87,7 @@ import {
|
|
|
87
87
|
formatDoctorReport,
|
|
88
88
|
loadContextFiles,
|
|
89
89
|
writeCrashLog
|
|
90
|
-
} from "./chunk-
|
|
90
|
+
} from "./chunk-6SKMGONY.js";
|
|
91
91
|
import {
|
|
92
92
|
ProviderRegistry
|
|
93
93
|
} from "./chunk-PUBCJF7E.js";
|
|
@@ -107,7 +107,7 @@ import {
|
|
|
107
107
|
trustHook,
|
|
108
108
|
trustPlugin,
|
|
109
109
|
untrustHook
|
|
110
|
-
} from "./chunk-
|
|
110
|
+
} from "./chunk-QKJ3MAP7.js";
|
|
111
111
|
import {
|
|
112
112
|
CONTENT_ONLY_STREAM_REMINDER,
|
|
113
113
|
TEE_FINAL_USER_NUDGE,
|
|
@@ -129,7 +129,7 @@ import {
|
|
|
129
129
|
} from "./chunk-XPBEJB27.js";
|
|
130
130
|
import {
|
|
131
131
|
ConfigManager
|
|
132
|
-
} from "./chunk-
|
|
132
|
+
} from "./chunk-PMTEZTXP.js";
|
|
133
133
|
import {
|
|
134
134
|
AuthError,
|
|
135
135
|
ProviderError,
|
|
@@ -153,7 +153,7 @@ import {
|
|
|
153
153
|
SKILLS_DIR_NAME,
|
|
154
154
|
VERSION,
|
|
155
155
|
buildUserIdentityPrompt
|
|
156
|
-
} from "./chunk-
|
|
156
|
+
} from "./chunk-QDN5G7JN.js";
|
|
157
157
|
import {
|
|
158
158
|
formatGitContextForPrompt,
|
|
159
159
|
getGitContext,
|
|
@@ -780,6 +780,117 @@ function oneLinePreview(s, max) {
|
|
|
780
780
|
const flat = s.replace(/\s+/g, " ").trim();
|
|
781
781
|
return flat.length > max ? flat.slice(0, max - 1) + "\u2026" : flat;
|
|
782
782
|
}
|
|
783
|
+
var DEFAULT_SESSION_LIST_LIMIT = 50;
|
|
784
|
+
var MAX_TITLE_WIDTH = 40;
|
|
785
|
+
function formatFileSize(bytes) {
|
|
786
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
787
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
788
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
789
|
+
}
|
|
790
|
+
function visualWidth(s) {
|
|
791
|
+
const clean = s.replace(/\x1b\[[0-9;]*m/g, "");
|
|
792
|
+
let w = 0;
|
|
793
|
+
for (const ch of clean) {
|
|
794
|
+
const cp = ch.codePointAt(0);
|
|
795
|
+
if (cp >= 4352 && cp <= 4447 || // Hangul Jamo
|
|
796
|
+
cp >= 11904 && cp <= 42191 || // CJK Radicals … Yi
|
|
797
|
+
cp >= 44032 && cp <= 55203 || // Hangul Syllables
|
|
798
|
+
cp >= 63744 && cp <= 64255 || // CJK Compatibility Ideographs
|
|
799
|
+
cp >= 65072 && cp <= 65135 || // CJK Compatibility Forms
|
|
800
|
+
cp >= 65281 && cp <= 65376 || // Fullwidth Forms
|
|
801
|
+
cp >= 65504 && cp <= 65510 || // Fullwidth Signs
|
|
802
|
+
cp >= 126976 && cp <= 129791 || // Mahjong / Domino / …
|
|
803
|
+
cp >= 131072 && cp <= 196605 || // CJK Extension B+
|
|
804
|
+
cp >= 196608 && cp <= 262141) {
|
|
805
|
+
w += 2;
|
|
806
|
+
} else {
|
|
807
|
+
w += 1;
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
return w;
|
|
811
|
+
}
|
|
812
|
+
function truncateTitle(title, maxWidth) {
|
|
813
|
+
if (visualWidth(title) <= maxWidth) return title;
|
|
814
|
+
let w = 0;
|
|
815
|
+
let end = 0;
|
|
816
|
+
for (const ch of title) {
|
|
817
|
+
const chW = visualWidth(ch);
|
|
818
|
+
if (w + chW > maxWidth - 1) break;
|
|
819
|
+
w += chW;
|
|
820
|
+
end++;
|
|
821
|
+
}
|
|
822
|
+
return title.slice(0, end) + "\u2026";
|
|
823
|
+
}
|
|
824
|
+
function formatSessionDate(date) {
|
|
825
|
+
const pad = (n) => n.toString().padStart(2, "0");
|
|
826
|
+
const ymd = `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
|
|
827
|
+
const hm = `${pad(date.getHours())}:${pad(date.getMinutes())}`;
|
|
828
|
+
const abs = `${ymd} ${hm}`;
|
|
829
|
+
const now = /* @__PURE__ */ new Date();
|
|
830
|
+
const diffMs = now.getTime() - date.getTime();
|
|
831
|
+
const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
|
|
832
|
+
if (diffDays === 0) return `${abs} (today)`;
|
|
833
|
+
if (diffDays === 1) return `${abs} (yesterday)`;
|
|
834
|
+
if (diffDays < 7) return `${abs} (${diffDays} days ago)`;
|
|
835
|
+
return abs;
|
|
836
|
+
}
|
|
837
|
+
function parseSessionListArgs(args) {
|
|
838
|
+
let limit = DEFAULT_SESSION_LIST_LIMIT;
|
|
839
|
+
let all = false;
|
|
840
|
+
const filter = {};
|
|
841
|
+
let search = null;
|
|
842
|
+
let days = null;
|
|
843
|
+
let since = null;
|
|
844
|
+
let sort = { field: "updated", order: "desc" };
|
|
845
|
+
let json = false;
|
|
846
|
+
let stale = null;
|
|
847
|
+
let verbose = false;
|
|
848
|
+
for (let i = 1; i < args.length; i++) {
|
|
849
|
+
const a = args[i];
|
|
850
|
+
if (a === "--all" || a === "-a") {
|
|
851
|
+
all = true;
|
|
852
|
+
} else if ((a === "--limit" || a === "-n") && i + 1 < args.length) {
|
|
853
|
+
const n = Number(args[i + 1]);
|
|
854
|
+
if (Number.isFinite(n) && n > 0) {
|
|
855
|
+
limit = n;
|
|
856
|
+
i++;
|
|
857
|
+
}
|
|
858
|
+
} else if (a === "--filter" && i + 1 < args.length) {
|
|
859
|
+
const val = args[++i];
|
|
860
|
+
const eq = val.indexOf("=");
|
|
861
|
+
if (eq > 0) {
|
|
862
|
+
const key = val.slice(0, eq);
|
|
863
|
+
const vals = val.slice(eq + 1).split(",").map((s) => s.trim().toLowerCase());
|
|
864
|
+
if (key === "provider") filter.provider = vals;
|
|
865
|
+
else if (key === "model") filter.model = vals;
|
|
866
|
+
}
|
|
867
|
+
} else if ((a === "--search" || a === "-s") && i + 1 < args.length) {
|
|
868
|
+
search = args[++i];
|
|
869
|
+
} else if (a === "--days" && i + 1 < args.length) {
|
|
870
|
+
const n = Number(args[++i]);
|
|
871
|
+
if (Number.isFinite(n) && n > 0) days = n;
|
|
872
|
+
} else if (a === "--since" && i + 1 < args.length) {
|
|
873
|
+
since = args[++i];
|
|
874
|
+
} else if (a === "--sort" && i + 1 < args.length) {
|
|
875
|
+
const sv = args[++i];
|
|
876
|
+
const colon = sv.indexOf(":");
|
|
877
|
+
const field = colon > 0 ? sv.slice(0, colon) : sv;
|
|
878
|
+
const order = colon > 0 ? sv.slice(colon + 1) : "desc";
|
|
879
|
+
if (field === "updated" || field === "created" || field === "messages" || field === "size") {
|
|
880
|
+
sort = { field, order: order === "asc" ? "asc" : "desc" };
|
|
881
|
+
}
|
|
882
|
+
} else if (a === "--json") {
|
|
883
|
+
json = true;
|
|
884
|
+
} else if (a === "--verbose" || a === "-v") {
|
|
885
|
+
verbose = true;
|
|
886
|
+
} else if (a === "--stale" && i + 1 < args.length) {
|
|
887
|
+
const n = Number(args[++i]);
|
|
888
|
+
if (Number.isFinite(n) && n > 0) stale = n;
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
if (all) limit = -1;
|
|
892
|
+
return { limit, all, filter, search, days, since, sort, json, stale, verbose };
|
|
893
|
+
}
|
|
783
894
|
function renderTranscriptMessage(msg, renderer) {
|
|
784
895
|
if (msg.role === "user") {
|
|
785
896
|
const text = getContentText(msg.content);
|
|
@@ -1222,7 +1333,7 @@ No commands match "${filter}".
|
|
|
1222
1333
|
{
|
|
1223
1334
|
name: "session",
|
|
1224
1335
|
description: "Session management",
|
|
1225
|
-
usage: "/session new|list|load <id>|show <id> [page]|page <n>|remove <id
|
|
1336
|
+
usage: "/session new|list [--limit N|--all] [--filter k=v] [--search kw] [--days N|--stale N] [--sort f[:o]] [--json] [--verbose]|load <id>|show <id> [page]|page <n>|remove <id>|clean --stale N [--dry-run]",
|
|
1226
1337
|
async execute(args, ctx) {
|
|
1227
1338
|
const sub = args[0];
|
|
1228
1339
|
if (sub === "new") {
|
|
@@ -1233,23 +1344,137 @@ No commands match "${filter}".
|
|
|
1233
1344
|
ctx.clearDevState();
|
|
1234
1345
|
ctx.renderer.printSuccess("New session started.");
|
|
1235
1346
|
} else if (sub === "list") {
|
|
1236
|
-
const
|
|
1237
|
-
|
|
1347
|
+
const opts = parseSessionListArgs(args);
|
|
1348
|
+
const needFileSize = opts.verbose || opts.sort.field === "size";
|
|
1349
|
+
let allSessions = ctx.sessions.listSessions({ includeFileSize: needFileSize });
|
|
1350
|
+
if (allSessions.length === 0) {
|
|
1238
1351
|
ctx.renderer.printInfo("No saved sessions.");
|
|
1239
1352
|
return;
|
|
1240
1353
|
}
|
|
1354
|
+
const hasFilters = opts.filter.provider || opts.filter.model;
|
|
1355
|
+
const hasSearch = !!opts.search;
|
|
1356
|
+
const hasTimeFilter = opts.days !== null || opts.since !== null;
|
|
1357
|
+
const hasStale = opts.stale !== null;
|
|
1358
|
+
if (hasFilters) {
|
|
1359
|
+
const p = opts.filter.provider;
|
|
1360
|
+
const m = opts.filter.model;
|
|
1361
|
+
allSessions = allSessions.filter((s) => {
|
|
1362
|
+
if (p && !p.includes(s.provider.toLowerCase())) return false;
|
|
1363
|
+
if (m && !m.some((kw) => s.model.toLowerCase().includes(kw))) return false;
|
|
1364
|
+
return true;
|
|
1365
|
+
});
|
|
1366
|
+
}
|
|
1367
|
+
if (hasSearch) {
|
|
1368
|
+
const q = opts.search.toLowerCase();
|
|
1369
|
+
allSessions = allSessions.filter(
|
|
1370
|
+
(s) => (s.title ?? "").toLowerCase().includes(q) || s.id.toLowerCase().includes(q)
|
|
1371
|
+
);
|
|
1372
|
+
}
|
|
1373
|
+
if (hasTimeFilter) {
|
|
1374
|
+
const now = Date.now();
|
|
1375
|
+
let cutoff = 0;
|
|
1376
|
+
if (opts.since) {
|
|
1377
|
+
cutoff = new Date(opts.since).getTime();
|
|
1378
|
+
} else if (opts.days !== null) {
|
|
1379
|
+
cutoff = now - opts.days * 24 * 60 * 60 * 1e3;
|
|
1380
|
+
}
|
|
1381
|
+
if (!isNaN(cutoff)) {
|
|
1382
|
+
allSessions = allSessions.filter((s) => s.updated.getTime() >= cutoff);
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
const staleCutoff = hasStale ? Date.now() - opts.stale * 24 * 60 * 60 * 1e3 : 0;
|
|
1386
|
+
if (hasStale) {
|
|
1387
|
+
allSessions = allSessions.filter((s) => s.updated.getTime() < staleCutoff);
|
|
1388
|
+
}
|
|
1389
|
+
const defaultSort = opts.sort.field === "updated" && opts.sort.order === "desc";
|
|
1390
|
+
if (!defaultSort) {
|
|
1391
|
+
const mul = opts.sort.order === "asc" ? 1 : -1;
|
|
1392
|
+
allSessions = [...allSessions].sort((a, b) => {
|
|
1393
|
+
switch (opts.sort.field) {
|
|
1394
|
+
case "created":
|
|
1395
|
+
return (a.created.getTime() - b.created.getTime()) * mul;
|
|
1396
|
+
case "messages":
|
|
1397
|
+
return (a.messageCount - b.messageCount) * mul;
|
|
1398
|
+
case "size":
|
|
1399
|
+
return ((a.fileSize ?? 0) - (b.fileSize ?? 0)) * mul;
|
|
1400
|
+
default:
|
|
1401
|
+
return (a.updated.getTime() - b.updated.getTime()) * mul;
|
|
1402
|
+
}
|
|
1403
|
+
});
|
|
1404
|
+
}
|
|
1405
|
+
const totalCount = allSessions.length;
|
|
1406
|
+
if (totalCount === 0) {
|
|
1407
|
+
ctx.renderer.printInfo("No sessions match the filter criteria.");
|
|
1408
|
+
return;
|
|
1409
|
+
}
|
|
1410
|
+
if (opts.json) {
|
|
1411
|
+
const sliced2 = opts.limit > 0 ? allSessions.slice(0, opts.limit) : allSessions;
|
|
1412
|
+
const payload = sliced2.map((s) => ({
|
|
1413
|
+
id: s.id,
|
|
1414
|
+
title: s.title ?? null,
|
|
1415
|
+
provider: s.provider,
|
|
1416
|
+
model: s.model,
|
|
1417
|
+
messageCount: s.messageCount,
|
|
1418
|
+
created: s.created.toISOString(),
|
|
1419
|
+
updated: s.updated.toISOString(),
|
|
1420
|
+
...needFileSize ? { fileSize: s.fileSize } : {},
|
|
1421
|
+
...s.branchCount !== void 0 ? { branchCount: s.branchCount, activeBranch: s.activeBranch } : {}
|
|
1422
|
+
}));
|
|
1423
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
1424
|
+
if (opts.limit > 0 && totalCount > opts.limit) {
|
|
1425
|
+
console.error(
|
|
1426
|
+
`
|
|
1427
|
+
(truncated: ${opts.limit} of ${totalCount} sessions shown; use --all for full list)`
|
|
1428
|
+
);
|
|
1429
|
+
}
|
|
1430
|
+
return;
|
|
1431
|
+
}
|
|
1432
|
+
const sliced = opts.limit > 0 ? allSessions.slice(0, opts.limit) : allSessions;
|
|
1433
|
+
const headers = ["ID (short)", "Provider", "Model", "Messages"];
|
|
1434
|
+
if (opts.verbose) {
|
|
1435
|
+
headers.push("Size");
|
|
1436
|
+
headers.push("Br");
|
|
1437
|
+
}
|
|
1438
|
+
headers.push("Date", "Title");
|
|
1439
|
+
const rows = sliced.map((s) => {
|
|
1440
|
+
const isStale = hasStale ? s.updated.getTime() < staleCutoff : false;
|
|
1441
|
+
const dim = isStale ? theme.dim : (x) => String(x);
|
|
1442
|
+
const row = [
|
|
1443
|
+
dim(s.id.slice(0, 8)),
|
|
1444
|
+
dim(s.provider),
|
|
1445
|
+
dim(s.model),
|
|
1446
|
+
s.messageCount
|
|
1447
|
+
];
|
|
1448
|
+
if (opts.verbose) {
|
|
1449
|
+
row.push(
|
|
1450
|
+
s.fileSize !== void 0 ? formatFileSize(s.fileSize) : "\u2014",
|
|
1451
|
+
s.branchCount ?? 1
|
|
1452
|
+
);
|
|
1453
|
+
}
|
|
1454
|
+
row.push(
|
|
1455
|
+
formatSessionDate(s.updated),
|
|
1456
|
+
dim(truncateTitle(s.title ?? "(untitled)", MAX_TITLE_WIDTH))
|
|
1457
|
+
);
|
|
1458
|
+
return row;
|
|
1459
|
+
});
|
|
1241
1460
|
console.log();
|
|
1242
|
-
ctx.renderer.printTable(
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1461
|
+
ctx.renderer.printTable(headers, rows);
|
|
1462
|
+
const totalMessages = allSessions.reduce((sum, s) => sum + s.messageCount, 0);
|
|
1463
|
+
const shown = sliced.length;
|
|
1464
|
+
const filterHints = [];
|
|
1465
|
+
if (hasFilters) filterHints.push("filtered");
|
|
1466
|
+
if (hasSearch) filterHints.push("searched");
|
|
1467
|
+
if (hasTimeFilter) filterHints.push("time-limited");
|
|
1468
|
+
if (hasStale) filterHints.push(`stale >${opts.stale}d`);
|
|
1469
|
+
const filterTag = filterHints.length > 0 ? ` (${filterHints.join(", ")})` : "";
|
|
1470
|
+
console.log(
|
|
1471
|
+
theme.dim(
|
|
1472
|
+
` \u2500\u2500 ${shown} of ${totalCount} sessions${filterTag} \xB7 ${totalMessages} messages total`
|
|
1473
|
+
)
|
|
1252
1474
|
);
|
|
1475
|
+
if (shown < totalCount) {
|
|
1476
|
+
console.log(theme.dim(` Use --all to show all, or --limit N to change count.`));
|
|
1477
|
+
}
|
|
1253
1478
|
} else if (sub === "load" || sub === "show") {
|
|
1254
1479
|
const id = args[1];
|
|
1255
1480
|
if (!id) {
|
|
@@ -1337,6 +1562,71 @@ No commands match "${filter}".
|
|
|
1337
1562
|
ctx.clearDevState();
|
|
1338
1563
|
ctx.renderer.printInfo("Current session was deleted \u2014 started a fresh session.");
|
|
1339
1564
|
}
|
|
1565
|
+
} else if (sub === "clean") {
|
|
1566
|
+
let staleDays = 90;
|
|
1567
|
+
let dryRun = false;
|
|
1568
|
+
for (let i = 1; i < args.length; i++) {
|
|
1569
|
+
if (args[i] === "--stale" && i + 1 < args.length) {
|
|
1570
|
+
const n = Number(args[++i]);
|
|
1571
|
+
if (Number.isFinite(n) && n > 0) staleDays = n;
|
|
1572
|
+
} else if (args[i] === "--dry-run") {
|
|
1573
|
+
dryRun = true;
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
const cutoff = Date.now() - staleDays * 24 * 60 * 60 * 1e3;
|
|
1577
|
+
const allSessions = ctx.sessions.listSessions();
|
|
1578
|
+
const stale = allSessions.filter((s) => s.updated.getTime() < cutoff);
|
|
1579
|
+
if (stale.length === 0) {
|
|
1580
|
+
ctx.renderer.printInfo(`No sessions older than ${staleDays} days found.`);
|
|
1581
|
+
return;
|
|
1582
|
+
}
|
|
1583
|
+
console.log();
|
|
1584
|
+
console.log(
|
|
1585
|
+
theme.warning(
|
|
1586
|
+
` Found ${stale.length} session(s) not updated in ${staleDays}+ days:`
|
|
1587
|
+
)
|
|
1588
|
+
);
|
|
1589
|
+
for (const s of stale.slice(0, 20)) {
|
|
1590
|
+
console.log(
|
|
1591
|
+
theme.dim(
|
|
1592
|
+
` ${s.id.slice(0, 12)} ${String(s.messageCount).padStart(4)} msgs ${s.updated.toISOString().slice(0, 10)} ${truncateTitle(s.title ?? "(untitled)", 60)}`
|
|
1593
|
+
)
|
|
1594
|
+
);
|
|
1595
|
+
}
|
|
1596
|
+
if (stale.length > 20) {
|
|
1597
|
+
console.log(theme.dim(` ... and ${stale.length - 20} more`));
|
|
1598
|
+
}
|
|
1599
|
+
if (dryRun) {
|
|
1600
|
+
console.log(
|
|
1601
|
+
theme.info(`
|
|
1602
|
+
--dry-run: no sessions were deleted. Remove --dry-run to actually delete.`)
|
|
1603
|
+
);
|
|
1604
|
+
return;
|
|
1605
|
+
}
|
|
1606
|
+
console.log();
|
|
1607
|
+
const choice = await ctx.select(
|
|
1608
|
+
`Delete all ${stale.length} stale sessions?`,
|
|
1609
|
+
[
|
|
1610
|
+
{ label: "No \u2014 keep them", value: "no" },
|
|
1611
|
+
{ label: "Yes \u2014 delete permanently", value: "yes", hint: "unlinks all stale history files" }
|
|
1612
|
+
]
|
|
1613
|
+
);
|
|
1614
|
+
if (choice !== "yes") {
|
|
1615
|
+
ctx.renderer.printInfo("Cancelled \u2014 no sessions deleted.");
|
|
1616
|
+
return;
|
|
1617
|
+
}
|
|
1618
|
+
let deleted = 0;
|
|
1619
|
+
let failed = 0;
|
|
1620
|
+
for (const s of stale) {
|
|
1621
|
+
if (ctx.sessions.deleteSession(s.id)) {
|
|
1622
|
+
deleted++;
|
|
1623
|
+
} else {
|
|
1624
|
+
failed++;
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
ctx.renderer.printSuccess(
|
|
1628
|
+
`Cleaned up: ${deleted} deleted${failed > 0 ? `, ${failed} failed` : ""}.`
|
|
1629
|
+
);
|
|
1340
1630
|
} else {
|
|
1341
1631
|
ctx.renderer.renderError("Usage: /session new|list|load <id>|show <id> [page]|page <n>|remove <id>");
|
|
1342
1632
|
}
|
|
@@ -1796,7 +2086,7 @@ No tools match "${filter}".
|
|
|
1796
2086
|
const { join: join5 } = await import("path");
|
|
1797
2087
|
const { existsSync: existsSync5 } = await import("fs");
|
|
1798
2088
|
const { getGitRoot: getGitRoot2 } = await import("./git-context-EXOEHQSF.js");
|
|
1799
|
-
const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-
|
|
2089
|
+
const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-EJRLT7DM.js");
|
|
1800
2090
|
const { approveProject, hashMcpFile } = await import("./project-trust-NKYHL3VZ.js");
|
|
1801
2091
|
const cwd = process.cwd();
|
|
1802
2092
|
const projectRoot = getGitRoot2(cwd) ?? cwd;
|
|
@@ -2855,7 +3145,7 @@ ${hint}` : "")
|
|
|
2855
3145
|
usage: "/test [command|filter]",
|
|
2856
3146
|
async execute(args, ctx) {
|
|
2857
3147
|
try {
|
|
2858
|
-
const { executeTests } = await import("./run-tests-
|
|
3148
|
+
const { executeTests } = await import("./run-tests-OYXK27XH.js");
|
|
2859
3149
|
const argStr = args.join(" ").trim();
|
|
2860
3150
|
let testArgs = {};
|
|
2861
3151
|
if (argStr) {
|
|
@@ -7292,7 +7582,7 @@ program.command("web").description("Start Web UI server with browser-based chat
|
|
|
7292
7582
|
console.error("Error: Invalid port number. Must be between 1 and 65535.");
|
|
7293
7583
|
process.exit(1);
|
|
7294
7584
|
}
|
|
7295
|
-
const { startWebServer } = await import("./server-
|
|
7585
|
+
const { startWebServer } = await import("./server-JKNIZ5CB.js");
|
|
7296
7586
|
await startWebServer({ port, host: options.host });
|
|
7297
7587
|
});
|
|
7298
7588
|
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) => {
|
|
@@ -7459,11 +7749,11 @@ program.command("sessions").description("List recent conversation sessions").opt
|
|
|
7459
7749
|
console.log(footer + "\n");
|
|
7460
7750
|
});
|
|
7461
7751
|
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) => {
|
|
7462
|
-
const { runUsageCli } = await import("./usage-
|
|
7752
|
+
const { runUsageCli } = await import("./usage-4KFX3HTK.js");
|
|
7463
7753
|
await runUsageCli(options);
|
|
7464
7754
|
});
|
|
7465
7755
|
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) => {
|
|
7466
|
-
const { runDoctorCli } = await import("./doctor-cli-
|
|
7756
|
+
const { runDoctorCli } = await import("./doctor-cli-EXC7YU5D.js");
|
|
7467
7757
|
const argv = process.argv.slice(2);
|
|
7468
7758
|
await runDoctorCli({
|
|
7469
7759
|
json: !!options.json || argv.includes("--json"),
|
|
@@ -7472,7 +7762,7 @@ program.command("doctor").description("Health check: API keys, config, MCP, rece
|
|
|
7472
7762
|
});
|
|
7473
7763
|
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) => {
|
|
7474
7764
|
try {
|
|
7475
|
-
const batch = await import("./batch-
|
|
7765
|
+
const batch = await import("./batch-LSWWSINO.js");
|
|
7476
7766
|
switch (action) {
|
|
7477
7767
|
case "submit":
|
|
7478
7768
|
if (!arg) {
|
|
@@ -7515,7 +7805,7 @@ program.command("batch <action> [arg] [arg2]").description("Anthropic Message Ba
|
|
|
7515
7805
|
}
|
|
7516
7806
|
});
|
|
7517
7807
|
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) => {
|
|
7518
|
-
const { startMcpServer } = await import("./server-
|
|
7808
|
+
const { startMcpServer } = await import("./server-XX6UM4ZQ.js");
|
|
7519
7809
|
await startMcpServer({
|
|
7520
7810
|
allowDestructive: !!options.allowDestructive,
|
|
7521
7811
|
allowOutsideCwd: !!options.allowOutsideCwd,
|
|
@@ -7528,7 +7818,7 @@ program.command("pr <action> [target]").description("PR review helpers: review |
|
|
|
7528
7818
|
console.error(`Unknown pr action: ${action}. Use review | security-review | summarize.`);
|
|
7529
7819
|
process.exit(1);
|
|
7530
7820
|
}
|
|
7531
|
-
const { runPrCli } = await import("./pr-
|
|
7821
|
+
const { runPrCli } = await import("./pr-VSZNVKBS.js");
|
|
7532
7822
|
const result = await runPrCli({
|
|
7533
7823
|
action,
|
|
7534
7824
|
target,
|
|
@@ -7548,8 +7838,8 @@ program.command("pr <action> [target]").description("PR review helpers: review |
|
|
|
7548
7838
|
process.exit(result.exitCode);
|
|
7549
7839
|
});
|
|
7550
7840
|
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) => {
|
|
7551
|
-
const { runCi } = await import("./ci-
|
|
7552
|
-
const { formatCiResult } = await import("./ci-format-
|
|
7841
|
+
const { runCi } = await import("./ci-OIFTAJKR.js");
|
|
7842
|
+
const { formatCiResult } = await import("./ci-format-H6BLMWQ5.js");
|
|
7553
7843
|
const formats = [options.json, options.markdown, options.sarif].filter(Boolean).length;
|
|
7554
7844
|
if (formats > 1) {
|
|
7555
7845
|
console.error("Choose only one output format: --json, --markdown, or --sarif.");
|
|
@@ -7707,7 +7997,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
|
|
|
7707
7997
|
config.get("customProviders"),
|
|
7708
7998
|
config.getConfigDir()
|
|
7709
7999
|
);
|
|
7710
|
-
const { startHub } = await import("./hub-
|
|
8000
|
+
const { startHub } = await import("./hub-HQDRQBNM.js");
|
|
7711
8001
|
await startHub(
|
|
7712
8002
|
{
|
|
7713
8003
|
topic: topic ?? "",
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import {
|
|
3
3
|
countSeverity,
|
|
4
4
|
runCi
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-5BY4XICU.js";
|
|
6
|
+
import "./chunk-OULVIHCT.js";
|
|
7
7
|
import {
|
|
8
8
|
buildReviewPrompt,
|
|
9
9
|
buildSecurityReviewPrompt,
|
|
@@ -15,11 +15,11 @@ import {
|
|
|
15
15
|
import "./chunk-XPBEJB27.js";
|
|
16
16
|
import {
|
|
17
17
|
ConfigManager
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-PMTEZTXP.js";
|
|
19
19
|
import "./chunk-5ULLIOVC.js";
|
|
20
20
|
import {
|
|
21
21
|
VERSION
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-QDN5G7JN.js";
|
|
23
23
|
import "./chunk-IW3Q7AE5.js";
|
|
24
24
|
|
|
25
25
|
// src/cli/pr.ts
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
import "./chunk-NZ4X6GUC.js";
|
|
8
8
|
import {
|
|
9
9
|
persistDiscussion
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-QT5FA2ZY.js";
|
|
11
11
|
import {
|
|
12
12
|
AuthManager,
|
|
13
13
|
TOKEN_EXPIRY_MS
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
scanDirTree,
|
|
24
24
|
scanProject,
|
|
25
25
|
setupProxy
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-BYQEWWA4.js";
|
|
27
27
|
import {
|
|
28
28
|
buildReviewPrompt,
|
|
29
29
|
buildSecurityReviewPrompt
|
|
@@ -66,15 +66,15 @@ import {
|
|
|
66
66
|
truncateOutput,
|
|
67
67
|
undoStack,
|
|
68
68
|
updateMemoryApproval
|
|
69
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-4AX2MEJA.js";
|
|
70
70
|
import "./chunk-K3CF65QH.js";
|
|
71
71
|
import "./chunk-T2NL5ZIA.js";
|
|
72
72
|
import "./chunk-BXP6YZ2P.js";
|
|
73
|
-
import "./chunk-
|
|
73
|
+
import "./chunk-4MOBTDS6.js";
|
|
74
74
|
import {
|
|
75
75
|
SessionManager,
|
|
76
76
|
getContentText
|
|
77
|
-
} from "./chunk-
|
|
77
|
+
} from "./chunk-5GTWZ4QF.js";
|
|
78
78
|
import {
|
|
79
79
|
computeCost,
|
|
80
80
|
formatCost
|
|
@@ -89,7 +89,7 @@ import {
|
|
|
89
89
|
buildDoctorReport,
|
|
90
90
|
formatDoctorReport,
|
|
91
91
|
loadContextFiles
|
|
92
|
-
} from "./chunk-
|
|
92
|
+
} from "./chunk-6SKMGONY.js";
|
|
93
93
|
import {
|
|
94
94
|
ProviderRegistry
|
|
95
95
|
} from "./chunk-PUBCJF7E.js";
|
|
@@ -107,7 +107,7 @@ import {
|
|
|
107
107
|
runTool,
|
|
108
108
|
setPluginEnabled,
|
|
109
109
|
trustPlugin
|
|
110
|
-
} from "./chunk-
|
|
110
|
+
} from "./chunk-QKJ3MAP7.js";
|
|
111
111
|
import {
|
|
112
112
|
CONTENT_ONLY_STREAM_REMINDER,
|
|
113
113
|
TEE_FINAL_USER_NUDGE,
|
|
@@ -126,7 +126,7 @@ import {
|
|
|
126
126
|
} from "./chunk-XPBEJB27.js";
|
|
127
127
|
import {
|
|
128
128
|
ConfigManager
|
|
129
|
-
} from "./chunk-
|
|
129
|
+
} from "./chunk-PMTEZTXP.js";
|
|
130
130
|
import "./chunk-5ULLIOVC.js";
|
|
131
131
|
import {
|
|
132
132
|
AGENTIC_BEHAVIOR_GUIDELINE,
|
|
@@ -144,7 +144,7 @@ import {
|
|
|
144
144
|
SKILLS_DIR_NAME,
|
|
145
145
|
VERSION,
|
|
146
146
|
buildUserIdentityPrompt
|
|
147
|
-
} from "./chunk-
|
|
147
|
+
} from "./chunk-QDN5G7JN.js";
|
|
148
148
|
import {
|
|
149
149
|
formatGitContextForPrompt,
|
|
150
150
|
getGitContext,
|
|
@@ -2791,7 +2791,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
|
|
|
2791
2791
|
case "test": {
|
|
2792
2792
|
this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
|
|
2793
2793
|
try {
|
|
2794
|
-
const { executeTests } = await import("./run-tests-
|
|
2794
|
+
const { executeTests } = await import("./run-tests-OYXK27XH.js");
|
|
2795
2795
|
const argStr = args.join(" ").trim();
|
|
2796
2796
|
let testArgs = {};
|
|
2797
2797
|
if (argStr) {
|
|
@@ -3214,7 +3214,8 @@ Add .md files to create commands.` });
|
|
|
3214
3214
|
messageCount: s.messageCount,
|
|
3215
3215
|
updated: s.updated instanceof Date ? s.updated.toISOString() : String(s.updated),
|
|
3216
3216
|
isCurrent: s.id === this.sessions.current?.id
|
|
3217
|
-
}))
|
|
3217
|
+
})),
|
|
3218
|
+
totalCount: list.length
|
|
3218
3219
|
});
|
|
3219
3220
|
}
|
|
3220
3221
|
sendToolsList() {
|
|
@@ -3856,18 +3857,22 @@ async function startWebServer(options = {}) {
|
|
|
3856
3857
|
const authUser = req._authUser;
|
|
3857
3858
|
const sm = authUser ? getUserShared(authUser).sessions : sessions;
|
|
3858
3859
|
const list = sm.listSessions();
|
|
3860
|
+
const all = req.query.all === "true";
|
|
3861
|
+
const limit = all ? -1 : Number(req.query.limit) || 50;
|
|
3862
|
+
const sliced = limit > 0 ? list.slice(0, limit) : list;
|
|
3859
3863
|
res.json({
|
|
3860
|
-
sessions:
|
|
3864
|
+
sessions: sliced.map((s) => ({
|
|
3861
3865
|
id: s.id,
|
|
3862
3866
|
title: s.title,
|
|
3863
3867
|
provider: s.provider,
|
|
3864
3868
|
model: s.model,
|
|
3865
3869
|
messageCount: s.messageCount,
|
|
3866
3870
|
updated: s.updated
|
|
3867
|
-
}))
|
|
3871
|
+
})),
|
|
3872
|
+
totalCount: list.length
|
|
3868
3873
|
});
|
|
3869
3874
|
} catch {
|
|
3870
|
-
res.json({ sessions: [] });
|
|
3875
|
+
res.json({ sessions: [], totalCount: 0 });
|
|
3871
3876
|
}
|
|
3872
3877
|
});
|
|
3873
3878
|
app.get("/api/sessions/:id/replay", requireAuth, (req, res) => {
|