jinzd-ai-cli 0.4.278 → 0.4.279
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-7Y4NAA6N.js → batch-6QZSWCBL.js} +2 -2
- package/dist/{chunk-X3722RFA.js → chunk-2BKRWTEQ.js} +1 -1
- package/dist/{chunk-SJCOE4C7.js → chunk-5XHEXRMN.js} +1 -1
- package/dist/{chunk-RFSKPCYC.js → chunk-6WMT7OQG.js} +1 -1
- package/dist/{chunk-JJCNNQTU.js → chunk-7L4TEK7Q.js} +239 -3
- package/dist/{chunk-LXXQTWT2.js → chunk-CMNXAJLH.js} +1 -1
- package/dist/{chunk-WOXIKQRI.js → chunk-FQJFGGKN.js} +4 -4
- package/dist/{chunk-L3CPM472.js → chunk-IIXZ7IPN.js} +1 -1
- package/dist/{chunk-LTZFUYBT.js → chunk-JLOQBYU4.js} +3 -3
- package/dist/{chunk-4Z6GAYB5.js → chunk-JS6VAPWM.js} +3 -3
- package/dist/{chunk-SB4XONS4.js → chunk-NZPHEUJM.js} +1 -1
- package/dist/{chunk-H7QC5VMQ.js → chunk-RJY3HJS4.js} +1 -1
- package/dist/{chunk-LOXEYWC3.js → chunk-SIVM2YQQ.js} +1 -1
- package/dist/{chunk-2BYQP6JX.js → chunk-UD3BVNC5.js} +1 -1
- package/dist/{ci-WDF2CYR4.js → ci-F4ESOYI5.js} +4 -4
- package/dist/{ci-format-7B5VAZGA.js → ci-format-AIRW3TVQ.js} +2 -2
- package/dist/{constants-DC3TNLTL.js → constants-3VMMZJDS.js} +1 -1
- package/dist/{doctor-cli-CDDG5XOY.js → doctor-cli-WVMEWMYE.js} +4 -4
- package/dist/electron-server.js +398 -58
- package/dist/{hub-TO7ODOIA.js → hub-JJCCCU3O.js} +1 -1
- package/dist/index.js +112 -323
- package/dist/{persistent-memory-BU63CSGK.js → persistent-memory-KSZKM4JG.js} +2 -2
- package/dist/{persistent-memory-JCENBMCJ.js → persistent-memory-QZN4Q3W4.js} +2 -2
- package/dist/{pr-GVSZYX6I.js → pr-GFB5JC26.js} +4 -4
- package/dist/{run-tests-R4IQS6IF.js → run-tests-EL54INOI.js} +2 -2
- package/dist/{run-tests-2Q5MJHXB.js → run-tests-HMHHIG7Y.js} +2 -2
- package/dist/{server-WXLE53HG.js → server-6C7GITHY.js} +5 -5
- package/dist/{server-KAURBKFI.js → server-WUSJWC3A.js} +187 -63
- package/dist/{task-orchestrator-RJ6FXYY5.js → task-orchestrator-C7RUUA2Q.js} +5 -5
- package/dist/{usage-V3R7DA7M.js → usage-CW6BT2UV.js} +2 -2
- package/dist/web/client/app.js +14 -2
- package/dist/web/client/app.js.br +0 -0
- package/dist/web/client/app.js.gz +0 -0
- package/package.json +1 -1
package/dist/electron-server.js
CHANGED
|
@@ -40,14 +40,14 @@ import {
|
|
|
40
40
|
touchMemoryReferences,
|
|
41
41
|
updateMemoryApproval,
|
|
42
42
|
updateMemoryEntry
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-CMNXAJLH.js";
|
|
44
44
|
import {
|
|
45
45
|
redactJson,
|
|
46
46
|
scanString
|
|
47
47
|
} from "./chunk-FSC6KEWU.js";
|
|
48
48
|
import {
|
|
49
49
|
runTestsTool
|
|
50
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-SIVM2YQQ.js";
|
|
51
51
|
import {
|
|
52
52
|
AGENTIC_BEHAVIOR_GUIDELINE,
|
|
53
53
|
APP_NAME,
|
|
@@ -80,7 +80,7 @@ import {
|
|
|
80
80
|
SUBAGENT_MAX_ROUNDS_LIMIT,
|
|
81
81
|
VERSION,
|
|
82
82
|
buildUserIdentityPrompt
|
|
83
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-5XHEXRMN.js";
|
|
84
84
|
import {
|
|
85
85
|
hasSemanticIndex,
|
|
86
86
|
semanticSearch
|
|
@@ -16407,6 +16407,232 @@ function lastAssistantText(messages) {
|
|
|
16407
16407
|
return void 0;
|
|
16408
16408
|
}
|
|
16409
16409
|
|
|
16410
|
+
// src/core/session-command.ts
|
|
16411
|
+
var DEFAULT_SESSION_LIST_LIMIT = 50;
|
|
16412
|
+
function parseSessionListArgs(args) {
|
|
16413
|
+
let limit = DEFAULT_SESSION_LIST_LIMIT;
|
|
16414
|
+
let all = false;
|
|
16415
|
+
const filter = {};
|
|
16416
|
+
const warnings = [];
|
|
16417
|
+
let search = null;
|
|
16418
|
+
let days = null;
|
|
16419
|
+
let since = null;
|
|
16420
|
+
let sort = { field: "updated", order: "desc" };
|
|
16421
|
+
let json = false;
|
|
16422
|
+
let stale = null;
|
|
16423
|
+
let verbose = false;
|
|
16424
|
+
for (let i = 1; i < args.length; i++) {
|
|
16425
|
+
const a = args[i];
|
|
16426
|
+
if (a === "--all" || a === "-a") {
|
|
16427
|
+
all = true;
|
|
16428
|
+
} else if ((a === "--limit" || a === "-n") && i + 1 < args.length) {
|
|
16429
|
+
const n = Number(args[i + 1]);
|
|
16430
|
+
if (Number.isFinite(n) && n > 0) {
|
|
16431
|
+
limit = n;
|
|
16432
|
+
i++;
|
|
16433
|
+
}
|
|
16434
|
+
} else if (a === "--filter" && i + 1 < args.length) {
|
|
16435
|
+
const val = args[++i];
|
|
16436
|
+
const eq = val.indexOf("=");
|
|
16437
|
+
if (eq > 0) {
|
|
16438
|
+
const key = val.slice(0, eq);
|
|
16439
|
+
const vals = val.slice(eq + 1).split(",").map((s) => s.trim().toLowerCase());
|
|
16440
|
+
if (key === "provider") filter.provider = vals;
|
|
16441
|
+
else if (key === "model") filter.model = vals;
|
|
16442
|
+
else if (key === "messages") {
|
|
16443
|
+
const n = Number(vals[0]);
|
|
16444
|
+
if (Number.isFinite(n) && n >= 0) filter.messages = n;
|
|
16445
|
+
else warnings.push(`Invalid filter value for "messages": expected a non-negative integer, got "${vals[0]}"`);
|
|
16446
|
+
} else {
|
|
16447
|
+
warnings.push(`Unknown filter key: "${key}". Supported keys: provider, model, messages`);
|
|
16448
|
+
}
|
|
16449
|
+
} else {
|
|
16450
|
+
warnings.push(`Invalid --filter syntax: "${val}". Expected key=value`);
|
|
16451
|
+
}
|
|
16452
|
+
} else if ((a === "--search" || a === "-s") && i + 1 < args.length) {
|
|
16453
|
+
search = args[++i];
|
|
16454
|
+
} else if (a === "--days" && i + 1 < args.length) {
|
|
16455
|
+
const n = Number(args[++i]);
|
|
16456
|
+
if (Number.isFinite(n) && n > 0) days = n;
|
|
16457
|
+
} else if (a === "--since" && i + 1 < args.length) {
|
|
16458
|
+
since = args[++i];
|
|
16459
|
+
} else if (a === "--sort" && i + 1 < args.length) {
|
|
16460
|
+
const sv = args[++i];
|
|
16461
|
+
const colon = sv.indexOf(":");
|
|
16462
|
+
const field = colon > 0 ? sv.slice(0, colon) : sv;
|
|
16463
|
+
const order = colon > 0 ? sv.slice(colon + 1) : "desc";
|
|
16464
|
+
if (field === "updated" || field === "created" || field === "messages" || field === "size") {
|
|
16465
|
+
sort = { field, order: order === "asc" ? "asc" : "desc" };
|
|
16466
|
+
}
|
|
16467
|
+
} else if (a === "--json") {
|
|
16468
|
+
json = true;
|
|
16469
|
+
} else if (a === "--verbose" || a === "-v") {
|
|
16470
|
+
verbose = true;
|
|
16471
|
+
} else if (a === "--stale" && i + 1 < args.length) {
|
|
16472
|
+
const n = Number(args[++i]);
|
|
16473
|
+
if (Number.isFinite(n) && n > 0) stale = n;
|
|
16474
|
+
}
|
|
16475
|
+
}
|
|
16476
|
+
if (all) limit = -1;
|
|
16477
|
+
return { limit, all, filter, search, days, since, sort, json, stale, verbose, warnings };
|
|
16478
|
+
}
|
|
16479
|
+
function sessionListNeedsFileSize(opts) {
|
|
16480
|
+
return opts.verbose || opts.sort.field === "size";
|
|
16481
|
+
}
|
|
16482
|
+
function selectSessions(sessions, opts, now = Date.now()) {
|
|
16483
|
+
let matched = sessions;
|
|
16484
|
+
const hasFilters = !!opts.filter.provider || !!opts.filter.model || opts.filter.messages !== void 0;
|
|
16485
|
+
const hasSearch = !!opts.search;
|
|
16486
|
+
const hasTimeFilter = opts.days !== null || opts.since !== null;
|
|
16487
|
+
const hasStale = opts.stale !== null;
|
|
16488
|
+
if (hasFilters) {
|
|
16489
|
+
const p = opts.filter.provider;
|
|
16490
|
+
const m = opts.filter.model;
|
|
16491
|
+
const msg = opts.filter.messages;
|
|
16492
|
+
matched = matched.filter((s) => {
|
|
16493
|
+
if (p && !p.includes(s.provider.toLowerCase())) return false;
|
|
16494
|
+
if (m && !m.some((kw) => s.model.toLowerCase().includes(kw))) return false;
|
|
16495
|
+
if (msg !== void 0 && s.messageCount !== msg) return false;
|
|
16496
|
+
return true;
|
|
16497
|
+
});
|
|
16498
|
+
}
|
|
16499
|
+
if (hasSearch) {
|
|
16500
|
+
const q = opts.search.toLowerCase();
|
|
16501
|
+
matched = matched.filter(
|
|
16502
|
+
(s) => (s.title ?? "").toLowerCase().includes(q) || s.id.toLowerCase().includes(q)
|
|
16503
|
+
);
|
|
16504
|
+
}
|
|
16505
|
+
if (hasTimeFilter) {
|
|
16506
|
+
let cutoff = 0;
|
|
16507
|
+
if (opts.since) cutoff = new Date(opts.since).getTime();
|
|
16508
|
+
else if (opts.days !== null) cutoff = now - opts.days * 24 * 60 * 60 * 1e3;
|
|
16509
|
+
if (!Number.isNaN(cutoff)) {
|
|
16510
|
+
matched = matched.filter((s) => s.updated.getTime() >= cutoff);
|
|
16511
|
+
}
|
|
16512
|
+
}
|
|
16513
|
+
const staleCutoff = hasStale ? now - opts.stale * 24 * 60 * 60 * 1e3 : null;
|
|
16514
|
+
if (staleCutoff !== null) {
|
|
16515
|
+
matched = matched.filter((s) => s.updated.getTime() < staleCutoff);
|
|
16516
|
+
}
|
|
16517
|
+
const defaultSort = opts.sort.field === "updated" && opts.sort.order === "desc";
|
|
16518
|
+
if (!defaultSort) {
|
|
16519
|
+
const mul = opts.sort.order === "asc" ? 1 : -1;
|
|
16520
|
+
matched = [...matched].sort((a, b) => {
|
|
16521
|
+
switch (opts.sort.field) {
|
|
16522
|
+
case "created":
|
|
16523
|
+
return (a.created.getTime() - b.created.getTime()) * mul;
|
|
16524
|
+
case "messages":
|
|
16525
|
+
return (a.messageCount - b.messageCount) * mul;
|
|
16526
|
+
case "size":
|
|
16527
|
+
return ((a.fileSize ?? 0) - (b.fileSize ?? 0)) * mul;
|
|
16528
|
+
default:
|
|
16529
|
+
return (a.updated.getTime() - b.updated.getTime()) * mul;
|
|
16530
|
+
}
|
|
16531
|
+
});
|
|
16532
|
+
}
|
|
16533
|
+
const filterTags = [];
|
|
16534
|
+
if (hasFilters) filterTags.push("filtered");
|
|
16535
|
+
if (hasSearch) filterTags.push("searched");
|
|
16536
|
+
if (hasTimeFilter) filterTags.push("time-limited");
|
|
16537
|
+
if (hasStale) filterTags.push(`stale >${opts.stale}d`);
|
|
16538
|
+
return {
|
|
16539
|
+
matched,
|
|
16540
|
+
shown: opts.limit > 0 ? matched.slice(0, opts.limit) : matched,
|
|
16541
|
+
totalCount: matched.length,
|
|
16542
|
+
totalMessages: matched.reduce((sum, s) => sum + s.messageCount, 0),
|
|
16543
|
+
staleCutoff,
|
|
16544
|
+
filterTags,
|
|
16545
|
+
needsFileSize: sessionListNeedsFileSize(opts)
|
|
16546
|
+
};
|
|
16547
|
+
}
|
|
16548
|
+
function sessionListSummary(view) {
|
|
16549
|
+
const tag = view.filterTags.length > 0 ? ` (${view.filterTags.join(", ")})` : "";
|
|
16550
|
+
return `${view.shown.length} of ${view.totalCount} sessions${tag} \xB7 ${view.totalMessages} messages total`;
|
|
16551
|
+
}
|
|
16552
|
+
function sessionListJsonRow(s, includeFileSize) {
|
|
16553
|
+
return {
|
|
16554
|
+
id: s.id,
|
|
16555
|
+
title: s.title ?? null,
|
|
16556
|
+
provider: s.provider,
|
|
16557
|
+
model: s.model,
|
|
16558
|
+
messageCount: s.messageCount,
|
|
16559
|
+
created: s.created.toISOString(),
|
|
16560
|
+
updated: s.updated.toISOString(),
|
|
16561
|
+
...includeFileSize ? { fileSize: s.fileSize } : {},
|
|
16562
|
+
...s.branchCount !== void 0 ? { branchCount: s.branchCount, activeBranch: s.activeBranch } : {}
|
|
16563
|
+
};
|
|
16564
|
+
}
|
|
16565
|
+
function resolveSessionRef(sessions, prefix, policy) {
|
|
16566
|
+
const matches2 = sessions.filter((s) => s.id.startsWith(prefix));
|
|
16567
|
+
if (matches2.length === 0) {
|
|
16568
|
+
return { status: "not-found", message: `Session '${prefix}' not found.` };
|
|
16569
|
+
}
|
|
16570
|
+
if (matches2.length > 1 && policy === "strict") {
|
|
16571
|
+
return {
|
|
16572
|
+
status: "ambiguous",
|
|
16573
|
+
matches: matches2,
|
|
16574
|
+
message: `Ambiguous prefix '${prefix}' matches ${matches2.length} sessions \u2014 be more specific:`
|
|
16575
|
+
};
|
|
16576
|
+
}
|
|
16577
|
+
return {
|
|
16578
|
+
status: "ok",
|
|
16579
|
+
match: matches2[0],
|
|
16580
|
+
ambiguousWith: matches2.length > 1 ? matches2 : [],
|
|
16581
|
+
message: matches2.length > 1 ? `\u26A0 Ambiguous prefix '${prefix}' matches ${matches2.length} sessions \u2014 loading most recent:` : void 0
|
|
16582
|
+
};
|
|
16583
|
+
}
|
|
16584
|
+
function formatSessionSummaryLine(s, titleWidth = 60) {
|
|
16585
|
+
const title = s.title ?? "(untitled)";
|
|
16586
|
+
const shown = title.length > titleWidth ? `${title.slice(0, titleWidth - 1)}\u2026` : title;
|
|
16587
|
+
return `${s.id.slice(0, 12)} ${s.provider}/${s.model} ${String(s.messageCount).padStart(4)} msgs ${s.updated.toISOString().slice(0, 10)} ${shown}`;
|
|
16588
|
+
}
|
|
16589
|
+
function parseBatchDeleteArgs(args) {
|
|
16590
|
+
let messages;
|
|
16591
|
+
let dryRun = false;
|
|
16592
|
+
for (let i = 1; i < args.length; i++) {
|
|
16593
|
+
if (args[i] === "--filter" && i + 1 < args.length) {
|
|
16594
|
+
const val = args[++i];
|
|
16595
|
+
const eq = val.indexOf("=");
|
|
16596
|
+
if (eq <= 0) {
|
|
16597
|
+
return { dryRun, error: `Invalid --filter syntax: "${val}". Expected key=value (e.g., messages=0)` };
|
|
16598
|
+
}
|
|
16599
|
+
const key = val.slice(0, eq);
|
|
16600
|
+
const vals = val.slice(eq + 1).split(",").map((s) => s.trim().toLowerCase());
|
|
16601
|
+
if (key !== "messages") {
|
|
16602
|
+
return { dryRun, error: `Unsupported filter key for delete: "${key}". Only "messages" is supported.` };
|
|
16603
|
+
}
|
|
16604
|
+
const n = Number(vals[0]);
|
|
16605
|
+
if (!Number.isFinite(n) || n < 0) {
|
|
16606
|
+
return { dryRun, error: `Invalid filter value for "messages": expected a non-negative integer, got "${vals[0]}"` };
|
|
16607
|
+
}
|
|
16608
|
+
messages = n;
|
|
16609
|
+
} else if (args[i] === "--dry-run") {
|
|
16610
|
+
dryRun = true;
|
|
16611
|
+
}
|
|
16612
|
+
}
|
|
16613
|
+
if (messages === void 0) {
|
|
16614
|
+
return { dryRun, error: "Usage: /session delete --filter messages=N [--dry-run]" };
|
|
16615
|
+
}
|
|
16616
|
+
return { messages, dryRun };
|
|
16617
|
+
}
|
|
16618
|
+
function parseCleanArgs(args) {
|
|
16619
|
+
let staleDays = 90;
|
|
16620
|
+
let dryRun = false;
|
|
16621
|
+
for (let i = 1; i < args.length; i++) {
|
|
16622
|
+
if (args[i] === "--stale" && i + 1 < args.length) {
|
|
16623
|
+
const n = Number(args[++i]);
|
|
16624
|
+
if (Number.isFinite(n) && n > 0) staleDays = n;
|
|
16625
|
+
} else if (args[i] === "--dry-run") {
|
|
16626
|
+
dryRun = true;
|
|
16627
|
+
}
|
|
16628
|
+
}
|
|
16629
|
+
return { staleDays, dryRun };
|
|
16630
|
+
}
|
|
16631
|
+
function selectStaleSessions(sessions, staleDays, now = Date.now()) {
|
|
16632
|
+
const cutoff = now - staleDays * 24 * 60 * 60 * 1e3;
|
|
16633
|
+
return sessions.filter((s) => s.updated.getTime() < cutoff);
|
|
16634
|
+
}
|
|
16635
|
+
|
|
16410
16636
|
// src/web/commands/session-commands.ts
|
|
16411
16637
|
async function handleClear(_args, ctx) {
|
|
16412
16638
|
ctx.saveIfNeeded();
|
|
@@ -16430,7 +16656,7 @@ Cache: write=${cacheCreate} read=${cacheRead}` : "";
|
|
|
16430
16656
|
Cost: ${formatCost(cost)}` : "";
|
|
16431
16657
|
let memoryLine = "";
|
|
16432
16658
|
try {
|
|
16433
|
-
const { countPendingMemories: countPendingMemories2 } = await import("./persistent-memory-
|
|
16659
|
+
const { countPendingMemories: countPendingMemories2 } = await import("./persistent-memory-QZN4Q3W4.js");
|
|
16434
16660
|
const pending = countPendingMemories2(ctx.config.getConfigDir());
|
|
16435
16661
|
if (pending > 0) memoryLine = `
|
|
16436
16662
|
Memory: \u26A0 ${pending} pending approval \u2014 see the Memory panel or /memory`;
|
|
@@ -16473,11 +16699,17 @@ async function handleSession(args, ctx) {
|
|
|
16473
16699
|
ctx.sendSessionList();
|
|
16474
16700
|
return;
|
|
16475
16701
|
}
|
|
16476
|
-
const
|
|
16477
|
-
|
|
16478
|
-
|
|
16702
|
+
const ref = resolveSessionRef(ctx.sessions.listSessions(), targetId, "most-recent");
|
|
16703
|
+
if (ref.status === "ok") {
|
|
16704
|
+
const found = ref.match;
|
|
16479
16705
|
ctx.sessions.loadSession(found.id);
|
|
16480
16706
|
ctx.resetWebSessionUsage();
|
|
16707
|
+
if (ref.message) {
|
|
16708
|
+
ctx.send({
|
|
16709
|
+
type: "info",
|
|
16710
|
+
message: [ref.message, ...ref.ambiguousWith.slice(0, 5).map((m) => ` ${formatSessionSummaryLine(m)}`)].join("\n")
|
|
16711
|
+
});
|
|
16712
|
+
}
|
|
16481
16713
|
ctx.send({ type: "info", message: `Loaded session: ${found.id.slice(0, 8)} "${found.title ?? ""}" (${found.messageCount} messages)` });
|
|
16482
16714
|
const loadedSession = ctx.sessions.current;
|
|
16483
16715
|
if (loadedSession && loadedSession.messages.length > 0) {
|
|
@@ -16507,52 +16739,81 @@ async function handleSession(args, ctx) {
|
|
|
16507
16739
|
return;
|
|
16508
16740
|
}
|
|
16509
16741
|
if (sub === "list") {
|
|
16510
|
-
|
|
16742
|
+
if (args.length <= 1) {
|
|
16743
|
+
ctx.sendSessionList();
|
|
16744
|
+
return;
|
|
16745
|
+
}
|
|
16746
|
+
const opts = parseSessionListArgs(args);
|
|
16747
|
+
const all = ctx.sessions.listSessions({ includeFileSize: sessionListNeedsFileSize(opts) });
|
|
16748
|
+
if (all.length === 0) {
|
|
16749
|
+
ctx.send({ type: "info", message: "No saved sessions." });
|
|
16750
|
+
return;
|
|
16751
|
+
}
|
|
16752
|
+
const view = selectSessions(all, opts);
|
|
16753
|
+
if (view.totalCount === 0) {
|
|
16754
|
+
ctx.send({
|
|
16755
|
+
type: "info",
|
|
16756
|
+
message: [...opts.warnings.map((w) => `\u26A0 ${w}`), "No sessions match the filter criteria."].join("\n")
|
|
16757
|
+
});
|
|
16758
|
+
return;
|
|
16759
|
+
}
|
|
16760
|
+
if (opts.json) {
|
|
16761
|
+
ctx.send({
|
|
16762
|
+
type: "info",
|
|
16763
|
+
message: JSON.stringify(view.shown.map((s) => sessionListJsonRow(s, view.needsFileSize)), null, 2)
|
|
16764
|
+
});
|
|
16765
|
+
return;
|
|
16766
|
+
}
|
|
16767
|
+
const lines = [
|
|
16768
|
+
...opts.warnings.map((w) => `\u26A0 ${w}`),
|
|
16769
|
+
...view.shown.map((s) => formatSessionSummaryLine(s)),
|
|
16770
|
+
`\u2500\u2500 ${sessionListSummary(view)}`
|
|
16771
|
+
];
|
|
16772
|
+
if (view.shown.length < view.totalCount) lines.push("Use --all to show all, or --limit N to change count.");
|
|
16773
|
+
ctx.send({ type: "info", message: lines.join("\n") });
|
|
16511
16774
|
return;
|
|
16512
16775
|
}
|
|
16513
16776
|
if (sub === "delete" && args[1]) {
|
|
16514
16777
|
const targetId = args[1];
|
|
16515
16778
|
if (targetId === "--filter") {
|
|
16516
|
-
|
|
16517
|
-
|
|
16518
|
-
|
|
16519
|
-
const val = args[i + 1];
|
|
16520
|
-
i++;
|
|
16521
|
-
const eq = val.indexOf("=");
|
|
16522
|
-
if (eq > 0) {
|
|
16523
|
-
const key = val.slice(0, eq);
|
|
16524
|
-
const vals = val.slice(eq + 1).split(",").map((s) => s.trim().toLowerCase());
|
|
16525
|
-
if (key === "messages") {
|
|
16526
|
-
const n = Number(vals[0]);
|
|
16527
|
-
if (Number.isFinite(n) && n >= 0) filterMessages = n;
|
|
16528
|
-
}
|
|
16529
|
-
}
|
|
16530
|
-
}
|
|
16531
|
-
}
|
|
16532
|
-
if (filterMessages === void 0) {
|
|
16533
|
-
ctx.send({ type: "error", message: "Usage: /session delete --filter messages=N" });
|
|
16779
|
+
const opts = parseBatchDeleteArgs(args);
|
|
16780
|
+
if (opts.error) {
|
|
16781
|
+
ctx.send({ type: "error", message: opts.error });
|
|
16534
16782
|
return;
|
|
16535
16783
|
}
|
|
16536
|
-
const
|
|
16537
|
-
const matches2 = list2.filter((s) => s.messageCount === filterMessages);
|
|
16784
|
+
const matches2 = ctx.sessions.listSessions().filter((s) => s.messageCount === opts.messages);
|
|
16538
16785
|
if (matches2.length === 0) {
|
|
16539
|
-
ctx.send({ type: "info", message: `No sessions with ${
|
|
16786
|
+
ctx.send({ type: "info", message: `No sessions with ${opts.messages} message(s) found.` });
|
|
16787
|
+
return;
|
|
16788
|
+
}
|
|
16789
|
+
const preview = [
|
|
16790
|
+
`Found ${matches2.length} session(s) with ${opts.messages} message(s):`,
|
|
16791
|
+
...matches2.slice(0, 20).map((s) => ` ${formatSessionSummaryLine(s)}`),
|
|
16792
|
+
...matches2.length > 20 ? [` ... and ${matches2.length - 20} more`] : []
|
|
16793
|
+
];
|
|
16794
|
+
if (opts.dryRun) {
|
|
16795
|
+
ctx.send({
|
|
16796
|
+
type: "info",
|
|
16797
|
+
message: [...preview, "--dry-run: no sessions were deleted. Remove --dry-run to actually delete."].join("\n")
|
|
16798
|
+
});
|
|
16540
16799
|
return;
|
|
16541
16800
|
}
|
|
16542
16801
|
let deleted = 0;
|
|
16543
16802
|
let failed = 0;
|
|
16544
16803
|
for (const s of matches2) {
|
|
16545
|
-
if (ctx.sessions.deleteSession(s.id))
|
|
16546
|
-
|
|
16547
|
-
} else {
|
|
16548
|
-
failed++;
|
|
16549
|
-
}
|
|
16804
|
+
if (ctx.sessions.deleteSession(s.id)) deleted++;
|
|
16805
|
+
else failed++;
|
|
16550
16806
|
}
|
|
16551
16807
|
if (!ctx.sessions.current) {
|
|
16552
|
-
ctx.sessions.createSession(ctx.currentProvider, ctx.currentModel);
|
|
16808
|
+
const created = ctx.sessions.createSession(ctx.currentProvider, ctx.currentModel);
|
|
16809
|
+
ctx.unsavedSessions.set(created.id, created);
|
|
16553
16810
|
ctx.resetWebSessionUsage();
|
|
16554
16811
|
}
|
|
16555
|
-
ctx.send({
|
|
16812
|
+
ctx.send({
|
|
16813
|
+
type: "info",
|
|
16814
|
+
message: [...preview, `Deleted ${deleted} session(s)${failed > 0 ? `, ${failed} failed` : ""}.`].join("\n")
|
|
16815
|
+
});
|
|
16816
|
+
ctx.sendStatus();
|
|
16556
16817
|
ctx.sendSessionList();
|
|
16557
16818
|
return;
|
|
16558
16819
|
}
|
|
@@ -16561,20 +16822,79 @@ async function handleSession(args, ctx) {
|
|
|
16561
16822
|
ctx.unsavedSessions.delete(cachedKey);
|
|
16562
16823
|
if (ctx.sessions.current?.id === cachedKey) {
|
|
16563
16824
|
ctx.sessions.clearCurrent();
|
|
16825
|
+
const created = ctx.sessions.createSession(ctx.currentProvider, ctx.currentModel);
|
|
16826
|
+
ctx.unsavedSessions.set(created.id, created);
|
|
16827
|
+
ctx.resetWebSessionUsage();
|
|
16828
|
+
ctx.sendStatus();
|
|
16564
16829
|
}
|
|
16565
16830
|
ctx.send({ type: "info", message: `Deleted session: ${cachedKey.slice(0, 8)}` });
|
|
16566
16831
|
ctx.sendSessionList();
|
|
16567
16832
|
return;
|
|
16568
16833
|
}
|
|
16569
|
-
const
|
|
16570
|
-
|
|
16571
|
-
if (found) {
|
|
16572
|
-
ctx.sessions.deleteSession(found.id);
|
|
16573
|
-
ctx.send({ type: "info", message: `Deleted session: ${found.id.slice(0, 8)}` });
|
|
16574
|
-
ctx.sendSessionList();
|
|
16575
|
-
} else {
|
|
16834
|
+
const ref = resolveSessionRef(ctx.sessions.listSessions(), targetId, "strict");
|
|
16835
|
+
if (ref.status === "not-found") {
|
|
16576
16836
|
ctx.send({ type: "error", message: `Session not found: ${targetId}` });
|
|
16837
|
+
return;
|
|
16838
|
+
}
|
|
16839
|
+
if (ref.status === "ambiguous") {
|
|
16840
|
+
ctx.send({
|
|
16841
|
+
type: "error",
|
|
16842
|
+
message: [ref.message, ...ref.matches.slice(0, 10).map((m) => ` ${formatSessionSummaryLine(m)}`)].join("\n")
|
|
16843
|
+
});
|
|
16844
|
+
return;
|
|
16845
|
+
}
|
|
16846
|
+
const wasCurrent = ctx.sessions.current?.id === ref.match.id;
|
|
16847
|
+
if (!ctx.sessions.deleteSession(ref.match.id)) {
|
|
16848
|
+
ctx.send({ type: "error", message: "Delete failed \u2014 session file not found on disk." });
|
|
16849
|
+
return;
|
|
16850
|
+
}
|
|
16851
|
+
ctx.send({ type: "info", message: `Deleted session: ${ref.match.id.slice(0, 8)}` });
|
|
16852
|
+
if (wasCurrent) {
|
|
16853
|
+
const created = ctx.sessions.createSession(ctx.currentProvider, ctx.currentModel);
|
|
16854
|
+
ctx.unsavedSessions.set(created.id, created);
|
|
16855
|
+
ctx.resetWebSessionUsage();
|
|
16856
|
+
ctx.send({ type: "info", message: "Current session was deleted \u2014 started a fresh session." });
|
|
16857
|
+
ctx.sendStatus();
|
|
16858
|
+
}
|
|
16859
|
+
ctx.sendSessionList();
|
|
16860
|
+
return;
|
|
16861
|
+
}
|
|
16862
|
+
if (sub === "clean") {
|
|
16863
|
+
const opts = parseCleanArgs(args);
|
|
16864
|
+
const stale = selectStaleSessions(ctx.sessions.listSessions(), opts.staleDays);
|
|
16865
|
+
if (stale.length === 0) {
|
|
16866
|
+
ctx.send({ type: "info", message: `No sessions older than ${opts.staleDays} days found.` });
|
|
16867
|
+
return;
|
|
16577
16868
|
}
|
|
16869
|
+
const preview = [
|
|
16870
|
+
`Found ${stale.length} session(s) not updated in ${opts.staleDays}+ days:`,
|
|
16871
|
+
...stale.slice(0, 20).map((s) => ` ${formatSessionSummaryLine(s)}`),
|
|
16872
|
+
...stale.length > 20 ? [` ... and ${stale.length - 20} more`] : []
|
|
16873
|
+
];
|
|
16874
|
+
if (opts.dryRun) {
|
|
16875
|
+
ctx.send({
|
|
16876
|
+
type: "info",
|
|
16877
|
+
message: [...preview, "--dry-run: no sessions were deleted. Remove --dry-run to actually delete."].join("\n")
|
|
16878
|
+
});
|
|
16879
|
+
return;
|
|
16880
|
+
}
|
|
16881
|
+
let deleted = 0;
|
|
16882
|
+
let failed = 0;
|
|
16883
|
+
for (const s of stale) {
|
|
16884
|
+
if (ctx.sessions.deleteSession(s.id)) deleted++;
|
|
16885
|
+
else failed++;
|
|
16886
|
+
}
|
|
16887
|
+
if (!ctx.sessions.current) {
|
|
16888
|
+
const created = ctx.sessions.createSession(ctx.currentProvider, ctx.currentModel);
|
|
16889
|
+
ctx.unsavedSessions.set(created.id, created);
|
|
16890
|
+
ctx.resetWebSessionUsage();
|
|
16891
|
+
ctx.sendStatus();
|
|
16892
|
+
}
|
|
16893
|
+
ctx.send({
|
|
16894
|
+
type: "info",
|
|
16895
|
+
message: [...preview, `Cleaned up: ${deleted} deleted${failed > 0 ? `, ${failed} failed` : ""}.`].join("\n")
|
|
16896
|
+
});
|
|
16897
|
+
ctx.sendSessionList();
|
|
16578
16898
|
return;
|
|
16579
16899
|
}
|
|
16580
16900
|
if (sub === "batch-delete") {
|
|
@@ -16598,6 +16918,12 @@ async function handleSession(args, ctx) {
|
|
|
16598
16918
|
deleted++;
|
|
16599
16919
|
}
|
|
16600
16920
|
}
|
|
16921
|
+
if (!ctx.sessions.current) {
|
|
16922
|
+
const created = ctx.sessions.createSession(ctx.currentProvider, ctx.currentModel);
|
|
16923
|
+
ctx.unsavedSessions.set(created.id, created);
|
|
16924
|
+
ctx.resetWebSessionUsage();
|
|
16925
|
+
ctx.sendStatus();
|
|
16926
|
+
}
|
|
16601
16927
|
ctx.send({ type: "info", message: `Deleted ${deleted} session(s).` });
|
|
16602
16928
|
ctx.sendSessionList();
|
|
16603
16929
|
return;
|
|
@@ -16611,26 +16937,40 @@ async function handleSession(args, ctx) {
|
|
|
16611
16937
|
}
|
|
16612
16938
|
const cachedKey = ctx.unsavedSessions.has(targetId) ? targetId : [...ctx.unsavedSessions.keys()].find((k) => k.startsWith(targetId));
|
|
16613
16939
|
if (cachedKey) {
|
|
16614
|
-
const
|
|
16615
|
-
|
|
16940
|
+
const session2 = ctx.unsavedSessions.get(cachedKey);
|
|
16941
|
+
session2.title = newTitle;
|
|
16616
16942
|
ctx.send({ type: "info", message: `Renamed session: "${newTitle}"` });
|
|
16617
16943
|
ctx.sendSessionList();
|
|
16618
16944
|
return;
|
|
16619
16945
|
}
|
|
16620
|
-
const
|
|
16621
|
-
|
|
16622
|
-
if (found) {
|
|
16623
|
-
const session = ctx.sessions.loadSession(found.id);
|
|
16624
|
-
session.title = newTitle;
|
|
16625
|
-
ctx.sessions.save();
|
|
16626
|
-
ctx.send({ type: "info", message: `Renamed session: "${newTitle}"` });
|
|
16627
|
-
ctx.sendSessionList();
|
|
16628
|
-
} else {
|
|
16946
|
+
const ref = resolveSessionRef(ctx.sessions.listSessions(), targetId, "strict");
|
|
16947
|
+
if (ref.status === "not-found") {
|
|
16629
16948
|
ctx.send({ type: "error", message: `Session not found: ${targetId}` });
|
|
16949
|
+
return;
|
|
16950
|
+
}
|
|
16951
|
+
if (ref.status === "ambiguous") {
|
|
16952
|
+
ctx.send({
|
|
16953
|
+
type: "error",
|
|
16954
|
+
message: [ref.message, ...ref.matches.slice(0, 10).map((m) => ` ${formatSessionSummaryLine(m)}`)].join("\n")
|
|
16955
|
+
});
|
|
16956
|
+
return;
|
|
16957
|
+
}
|
|
16958
|
+
const priorId = ctx.sessions.current?.id ?? null;
|
|
16959
|
+
const isCurrent = priorId === ref.match.id;
|
|
16960
|
+
const session = isCurrent ? ctx.sessions.current : ctx.sessions.loadSession(ref.match.id);
|
|
16961
|
+
session.title = newTitle;
|
|
16962
|
+
ctx.sessions.save();
|
|
16963
|
+
if (!isCurrent && priorId) {
|
|
16964
|
+
ctx.sessions.loadSession(priorId);
|
|
16630
16965
|
}
|
|
16966
|
+
ctx.send({ type: "info", message: `Renamed session: "${newTitle}"` });
|
|
16967
|
+
ctx.sendSessionList();
|
|
16631
16968
|
return;
|
|
16632
16969
|
}
|
|
16633
|
-
ctx.send({
|
|
16970
|
+
ctx.send({
|
|
16971
|
+
type: "info",
|
|
16972
|
+
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>"
|
|
16973
|
+
});
|
|
16634
16974
|
}
|
|
16635
16975
|
async function handleExport(args, ctx) {
|
|
16636
16976
|
const format = args[0] === "json" ? "json" : "md";
|
|
@@ -17243,7 +17583,7 @@ async function handleTest(args, ctx) {
|
|
|
17243
17583
|
const isCommand = argStr.includes(" ") || /^(mvn|gradle|npm|pytest|cargo|go)\b/.test(argStr);
|
|
17244
17584
|
testArgs = isCommand ? { command: argStr } : { filter: argStr };
|
|
17245
17585
|
}
|
|
17246
|
-
const runTests = ctx.runTests ?? (await import("./run-tests-
|
|
17586
|
+
const runTests = ctx.runTests ?? (await import("./run-tests-HMHHIG7Y.js")).executeTests;
|
|
17247
17587
|
const report = await runTests(testArgs);
|
|
17248
17588
|
ctx.send({ type: "info", message: report });
|
|
17249
17589
|
} catch (err) {
|
|
@@ -17579,7 +17919,7 @@ async function handleMemory(args, ctx) {
|
|
|
17579
17919
|
ctx.handleMemoryManage(sub, args[1], sub === "expire" ? args[2] : void 0);
|
|
17580
17920
|
} else if (sub === "export") {
|
|
17581
17921
|
if (args[1] === "md") {
|
|
17582
|
-
const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-
|
|
17922
|
+
const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-QZN4Q3W4.js");
|
|
17583
17923
|
ctx.send({
|
|
17584
17924
|
type: "export_data",
|
|
17585
17925
|
format: "md",
|
|
@@ -18023,7 +18363,7 @@ async function handleHelp(_args, ctx) {
|
|
|
18023
18363
|
" /think [on|off] \u2014 Toggle extended thinking mode",
|
|
18024
18364
|
" /plan [execute|exit|status] \u2014 Read-only planning mode (bare /plan enters it)",
|
|
18025
18365
|
" /route [on|off|show|test <msg>] \u2014 Smart model routing",
|
|
18026
|
-
" /session new|list|load
|
|
18366
|
+
" /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",
|
|
18027
18367
|
" /system [prompt|clear] \u2014 Set/view/reset system prompt",
|
|
18028
18368
|
" /context [status|reload] \u2014 Show/reload context layers",
|
|
18029
18369
|
" /status \u2014 Show session info & token usage",
|
|
@@ -158,7 +158,7 @@ ${content}`);
|
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
160
|
async function runTaskMode(config, providers, configManager, topic) {
|
|
161
|
-
const { TaskOrchestrator } = await import("./task-orchestrator-
|
|
161
|
+
const { TaskOrchestrator } = await import("./task-orchestrator-C7RUUA2Q.js");
|
|
162
162
|
const orchestrator = new TaskOrchestrator(config, providers, configManager);
|
|
163
163
|
let interrupted = false;
|
|
164
164
|
const onSigint = () => {
|