jinzd-ai-cli 0.4.280 → 0.4.282
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-F27NOTWC.js → batch-SBP6H7IK.js} +2 -2
- package/dist/{chunk-NHJ4GHL4.js → chunk-6IRG727F.js} +1 -1
- package/dist/{chunk-CP5LAA52.js → chunk-7XKIDSJT.js} +4 -4
- package/dist/{chunk-EOP775JU.js → chunk-EVD6CCO2.js} +1 -1
- package/dist/{chunk-B3FHA6IN.js → chunk-GSGJABL6.js} +3 -3
- package/dist/{chunk-VQCFEA4Z.js → chunk-HJDJAI7T.js} +1 -1
- package/dist/{chunk-CGDYO52A.js → chunk-IUVDZVZ4.js} +19 -0
- package/dist/{chunk-UBPRUSAF.js → chunk-JQU4GYET.js} +1 -1
- package/dist/{chunk-IIO2SMEJ.js → chunk-KDXA7RXA.js} +74 -4
- package/dist/{chunk-UMWDNNPS.js → chunk-LNUWIY6M.js} +1 -1
- package/dist/{chunk-MX75TNE5.js → chunk-NUJTNH76.js} +1 -1
- package/dist/{chunk-PUC277TH.js → chunk-RHSCROLG.js} +1 -1
- package/dist/{chunk-V7EZ4SDC.js → chunk-SGUPIQYT.js} +1 -1
- package/dist/{chunk-PN42JO74.js → chunk-TNIMHTKG.js} +1 -1
- package/dist/{chunk-TAIZZY3N.js → chunk-WMHLWCZQ.js} +3 -3
- package/dist/{chunk-LPZNOYRJ.js → chunk-YRPL7A3S.js} +1 -1
- package/dist/{ci-HJ4OVHCM.js → ci-VAAMX44S.js} +4 -4
- package/dist/{ci-format-NKJRZ3QI.js → ci-format-RMULFSB5.js} +2 -2
- package/dist/{constants-6LCZOBJC.js → constants-PXLMEBJY.js} +1 -1
- package/dist/{doctor-cli-7JGPC5G4.js → doctor-cli-C2DFYU2M.js} +4 -4
- package/dist/electron-server.js +147 -59
- package/dist/{hub-NX7HYN7V.js → hub-XIU3YTOE.js} +2 -2
- package/dist/index.js +81 -86
- package/dist/{persist-PQM4BRI4.js → persist-S77WRVLD.js} +2 -2
- package/dist/{persistent-memory-MHHX7F25.js → persistent-memory-ACXKU6RV.js} +2 -2
- package/dist/{persistent-memory-E6WECUTW.js → persistent-memory-TA224ZFQ.js} +2 -2
- package/dist/{pr-GLUFBQLI.js → pr-J74HW44E.js} +4 -4
- package/dist/{run-tests-YPJDOEJA.js → run-tests-4KTX5YMO.js} +2 -2
- package/dist/{run-tests-LWAFPVS3.js → run-tests-JLZ2KIGV.js} +2 -2
- package/dist/{server-CXXYIPMU.js → server-226R6675.js} +77 -66
- package/dist/{server-P6DI27CY.js → server-4CZXYGJN.js} +5 -5
- package/dist/{task-orchestrator-FW4LBPTS.js → task-orchestrator-6C3R7KSK.js} +5 -5
- package/dist/{usage-CJUHQDT2.js → usage-FY3TEJJS.js} +2 -2
- 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-RHSCROLG.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-6IRG727F.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-TNIMHTKG.js";
|
|
84
84
|
import {
|
|
85
85
|
hasSemanticIndex,
|
|
86
86
|
semanticSearch
|
|
@@ -4726,6 +4726,24 @@ var Session = class _Session {
|
|
|
4726
4726
|
this.updated = /* @__PURE__ */ new Date();
|
|
4727
4727
|
this.dirty = true;
|
|
4728
4728
|
}
|
|
4729
|
+
/**
|
|
4730
|
+
* 把对话截断到前 `count` 条(`/rewind` 用)。
|
|
4731
|
+
*
|
|
4732
|
+
* 存在的理由是 `dirty`:`messages` 是个普通公开字段,两端此前都直接
|
|
4733
|
+
* `session.messages = session.messages.slice(0, n)`,**不会置脏**——于是 REPL 压根不存,
|
|
4734
|
+
* Web 存了也被 `save()` 的 `if (!force && !dirty) return` 跳过。结果 `/rewind` 只改内存,
|
|
4735
|
+
* 而它同时真的回退了磁盘上的文件:重启后文件是回退后的、对话是回退前的,
|
|
4736
|
+
* 恰恰制造出 rewind 本身要消除的那种不一致(P2-02 第 6 批)。
|
|
4737
|
+
*
|
|
4738
|
+
* 落在截断点之后的检查点一并丢弃(它们指向已经不存在的消息)。
|
|
4739
|
+
*/
|
|
4740
|
+
truncateTo(count) {
|
|
4741
|
+
const target = Math.max(0, Math.min(count, this.messages.length));
|
|
4742
|
+
this.messages = this.messages.slice(0, target);
|
|
4743
|
+
this.checkpoints = this.checkpoints.filter((c) => c.messageIndex <= target);
|
|
4744
|
+
this.updated = /* @__PURE__ */ new Date();
|
|
4745
|
+
this.dirty = true;
|
|
4746
|
+
}
|
|
4729
4747
|
addMessage(message) {
|
|
4730
4748
|
this.messages.push(message);
|
|
4731
4749
|
this.updated = /* @__PURE__ */ new Date();
|
|
@@ -5228,6 +5246,7 @@ var SessionManager = class {
|
|
|
5228
5246
|
/** P1-PERF-03: `force` 跳过脏检查(用于进程退出、fork 等必须落盘场景) */
|
|
5229
5247
|
async save(force = false) {
|
|
5230
5248
|
if (!this._current) return;
|
|
5249
|
+
if (this._current.messages.length === 0) return;
|
|
5231
5250
|
if (!force && !this._current.dirty) return;
|
|
5232
5251
|
mkdirSync3(this.historyDir, { recursive: true });
|
|
5233
5252
|
const filePath = join4(this.historyDir, `${this._current.id}.json`);
|
|
@@ -16727,13 +16746,81 @@ function selectStaleSessions(sessions, staleDays, now = Date.now()) {
|
|
|
16727
16746
|
const cutoff = now - staleDays * 24 * 60 * 60 * 1e3;
|
|
16728
16747
|
return sessions.filter((s) => s.updated.getTime() < cutoff);
|
|
16729
16748
|
}
|
|
16749
|
+
function clearedSessionMessage(priorSessionId, priorMessageCount = 0) {
|
|
16750
|
+
return priorSessionId && priorMessageCount > 0 ? `Started a new session. Previous conversation saved as ${priorSessionId.slice(0, 8)} (${priorMessageCount} messages) \u2014 reload it with /session load ${priorSessionId.slice(0, 8)}.` : "Started a new session.";
|
|
16751
|
+
}
|
|
16752
|
+
|
|
16753
|
+
// src/core/session-history.ts
|
|
16754
|
+
function parseRewindArgs(args, messageCount) {
|
|
16755
|
+
const sub = args[0];
|
|
16756
|
+
if (!sub || sub.toLowerCase() === "list") return { kind: "list" };
|
|
16757
|
+
const n = Number.parseInt(sub, 10);
|
|
16758
|
+
if (Number.isNaN(n) || n < 1 || n > messageCount) {
|
|
16759
|
+
return { kind: "invalid", message: `Invalid message number: ${sub}. Range: 1-${messageCount}` };
|
|
16760
|
+
}
|
|
16761
|
+
return { kind: "rewind", target: n };
|
|
16762
|
+
}
|
|
16763
|
+
function buildRewindList(messages, checkpointIndices, previewWidth = 70) {
|
|
16764
|
+
return messages.map((m, i) => ({
|
|
16765
|
+
index: i + 1,
|
|
16766
|
+
role: m.role,
|
|
16767
|
+
preview: getContentText(m.content).replace(/\s+/g, " ").trim().slice(0, previewWidth),
|
|
16768
|
+
hasCheckpoint: checkpointIndices.includes(i)
|
|
16769
|
+
}));
|
|
16770
|
+
}
|
|
16771
|
+
function formatRewindReport(report) {
|
|
16772
|
+
const lines = [
|
|
16773
|
+
`\u2713 Rewound to message ${report.target}`,
|
|
16774
|
+
` Messages removed: ${report.messagesRemoved}`
|
|
16775
|
+
];
|
|
16776
|
+
if (report.filesRestored > 0 || report.filesDeleted > 0) {
|
|
16777
|
+
lines.push(` Files restored: ${report.filesRestored}, files deleted: ${report.filesDeleted}`);
|
|
16778
|
+
for (const f of report.files) lines.push(` ${f}`);
|
|
16779
|
+
} else {
|
|
16780
|
+
lines.push(" No file changes to revert.");
|
|
16781
|
+
}
|
|
16782
|
+
return lines;
|
|
16783
|
+
}
|
|
16784
|
+
function resolveForkPoint(session, checkpointName) {
|
|
16785
|
+
const name = checkpointName?.trim();
|
|
16786
|
+
if (!name) {
|
|
16787
|
+
return { ok: true, messageCount: session.messages.length, fromLabel: "current position" };
|
|
16788
|
+
}
|
|
16789
|
+
const cp = session.checkpoints.find((c) => c.name === name);
|
|
16790
|
+
if (!cp) {
|
|
16791
|
+
const available = session.checkpoints.map((c) => c.name);
|
|
16792
|
+
return {
|
|
16793
|
+
ok: false,
|
|
16794
|
+
message: available.length > 0 ? `Checkpoint "${name}" not found. Available: ${available.join(", ")}` : `Checkpoint "${name}" not found. No checkpoints saved. Use /checkpoint save <name> first.`
|
|
16795
|
+
};
|
|
16796
|
+
}
|
|
16797
|
+
return {
|
|
16798
|
+
ok: true,
|
|
16799
|
+
messageCount: cp.messageIndex,
|
|
16800
|
+
fromLabel: `checkpoint "${cp.name}" (${cp.messageIndex} messages)`
|
|
16801
|
+
};
|
|
16802
|
+
}
|
|
16803
|
+
function formatForkReport(report) {
|
|
16804
|
+
return [
|
|
16805
|
+
"Session Forked",
|
|
16806
|
+
` Original: ${report.originalId.slice(0, 8)} "${report.originalTitle}"`,
|
|
16807
|
+
` Forked: ${report.forkedId.slice(0, 8)} "${report.forkedTitle}"`,
|
|
16808
|
+
` From: ${report.fromLabel}`,
|
|
16809
|
+
` Messages: ${report.messageCount} copied, ${report.checkpointCount} checkpoint(s) preserved`,
|
|
16810
|
+
` Use /session load ${report.originalId.slice(0, 8)} to switch back to the original.`
|
|
16811
|
+
];
|
|
16812
|
+
}
|
|
16730
16813
|
|
|
16731
16814
|
// src/web/commands/session-commands.ts
|
|
16732
16815
|
async function handleClear(_args, ctx) {
|
|
16816
|
+
const prior = ctx.sessions.current;
|
|
16817
|
+
const priorId = prior?.id ?? null;
|
|
16818
|
+
const priorCount = prior?.messages.length ?? 0;
|
|
16733
16819
|
ctx.saveIfNeeded();
|
|
16734
|
-
ctx.sessions.createSession(ctx.currentProvider, ctx.currentModel);
|
|
16820
|
+
const created = ctx.sessions.createSession(ctx.currentProvider, ctx.currentModel);
|
|
16821
|
+
ctx.unsavedSessions.set(created.id, created);
|
|
16735
16822
|
ctx.resetWebSessionUsage();
|
|
16736
|
-
ctx.send({ type: "info", message:
|
|
16823
|
+
ctx.send({ type: "info", message: clearedSessionMessage(priorId, priorCount) });
|
|
16737
16824
|
ctx.sendStatus();
|
|
16738
16825
|
ctx.sendSessionList();
|
|
16739
16826
|
}
|
|
@@ -16751,7 +16838,7 @@ Cache: write=${cacheCreate} read=${cacheRead}` : "";
|
|
|
16751
16838
|
Cost: ${formatCost(cost)}` : "";
|
|
16752
16839
|
let memoryLine = "";
|
|
16753
16840
|
try {
|
|
16754
|
-
const { countPendingMemories: countPendingMemories2 } = await import("./persistent-memory-
|
|
16841
|
+
const { countPendingMemories: countPendingMemories2 } = await import("./persistent-memory-TA224ZFQ.js");
|
|
16755
16842
|
const pending = countPendingMemories2(ctx.config.getConfigDir());
|
|
16756
16843
|
if (pending > 0) memoryLine = `
|
|
16757
16844
|
Memory: \u26A0 ${pending} pending approval \u2014 see the Memory panel or /memory`;
|
|
@@ -17330,27 +17417,27 @@ async function handleFork(args, ctx) {
|
|
|
17330
17417
|
ctx.send({ type: "info", message: "No active session to fork." });
|
|
17331
17418
|
return;
|
|
17332
17419
|
}
|
|
17333
|
-
const
|
|
17334
|
-
|
|
17335
|
-
|
|
17336
|
-
|
|
17337
|
-
const cp = session.checkpoints.find((c) => c.name === sub);
|
|
17338
|
-
if (!cp) {
|
|
17339
|
-
const available = session.checkpoints.map((c) => c.name);
|
|
17340
|
-
ctx.send({ type: "error", message: available.length > 0 ? `Checkpoint "${sub}" not found. Available: ${available.join(", ")}` : `Checkpoint "${sub}" not found. No checkpoints saved.` });
|
|
17341
|
-
return;
|
|
17342
|
-
}
|
|
17343
|
-
messageCount = cp.messageIndex;
|
|
17344
|
-
fromLabel = `checkpoint "${cp.name}" (${cp.messageIndex} messages)`;
|
|
17420
|
+
const point = resolveForkPoint(session, args.join(" ").trim());
|
|
17421
|
+
if (!point.ok) {
|
|
17422
|
+
ctx.send({ type: "error", message: point.message });
|
|
17423
|
+
return;
|
|
17345
17424
|
}
|
|
17346
17425
|
try {
|
|
17347
|
-
const originalId = session.id
|
|
17348
|
-
const
|
|
17349
|
-
|
|
17350
|
-
|
|
17351
|
-
|
|
17352
|
-
|
|
17353
|
-
|
|
17426
|
+
const originalId = session.id;
|
|
17427
|
+
const originalTitle = session.title ?? "(untitled)";
|
|
17428
|
+
const forked = await ctx.sessions.forkSession(point.messageCount);
|
|
17429
|
+
ctx.send({
|
|
17430
|
+
type: "info",
|
|
17431
|
+
message: formatForkReport({
|
|
17432
|
+
originalId,
|
|
17433
|
+
originalTitle,
|
|
17434
|
+
forkedId: forked.id,
|
|
17435
|
+
forkedTitle: forked.title ?? "(untitled)",
|
|
17436
|
+
fromLabel: point.fromLabel,
|
|
17437
|
+
messageCount: forked.messages.length,
|
|
17438
|
+
checkpointCount: forked.checkpoints.length
|
|
17439
|
+
}).join("\n")
|
|
17440
|
+
});
|
|
17354
17441
|
ctx.sendSessionMessages();
|
|
17355
17442
|
ctx.sendStatus();
|
|
17356
17443
|
ctx.sendSessionList();
|
|
@@ -17364,41 +17451,42 @@ async function handleRewind(args, ctx) {
|
|
|
17364
17451
|
ctx.send({ type: "info", message: "No messages to rewind." });
|
|
17365
17452
|
return;
|
|
17366
17453
|
}
|
|
17367
|
-
const
|
|
17368
|
-
if (
|
|
17369
|
-
|
|
17370
|
-
`];
|
|
17371
|
-
const cpIndices = (await import("./file-checkpoint-CGH6OJVI.js")).fileCheckpoints.getMessageIndices();
|
|
17372
|
-
for (let i = 0; i < session.messages.length; i++) {
|
|
17373
|
-
const m = session.messages[i];
|
|
17374
|
-
const text = getContentText(m.content).replace(/\n/g, " ").slice(0, 60);
|
|
17375
|
-
const pin = cpIndices.includes(i) ? " \u{1F4CC}" : "";
|
|
17376
|
-
lines.push(` [${i + 1}] ${m.role.padEnd(10)} ${text}${pin}`);
|
|
17377
|
-
}
|
|
17378
|
-
lines.push("", "Usage: /rewind <n> \u2014 rewind to message N", "\u{1F4CC} = file checkpoint");
|
|
17379
|
-
ctx.send({ type: "info", message: lines.join("\n") });
|
|
17454
|
+
const intent = parseRewindArgs(args, session.messages.length);
|
|
17455
|
+
if (intent.kind === "invalid") {
|
|
17456
|
+
ctx.send({ type: "error", message: intent.message });
|
|
17380
17457
|
return;
|
|
17381
17458
|
}
|
|
17382
|
-
const
|
|
17383
|
-
if (
|
|
17384
|
-
|
|
17459
|
+
const { fileCheckpoints: fileCheckpoints2 } = await import("./file-checkpoint-CGH6OJVI.js");
|
|
17460
|
+
if (intent.kind === "list") {
|
|
17461
|
+
const rows = buildRewindList(session.messages, fileCheckpoints2.getMessageIndices());
|
|
17462
|
+
ctx.send({
|
|
17463
|
+
type: "info",
|
|
17464
|
+
message: [
|
|
17465
|
+
`Conversation messages (${rows.length} total):`,
|
|
17466
|
+
"",
|
|
17467
|
+
...rows.map((r) => ` [${r.index}] ${r.role.padEnd(10)} ${r.preview}${r.hasCheckpoint ? " \u{1F4CC}" : ""}`),
|
|
17468
|
+
"",
|
|
17469
|
+
"Usage: /rewind <n> \u2014 rewind to message N (1-based)",
|
|
17470
|
+
"\u{1F4CC} = file checkpoint exists at this point"
|
|
17471
|
+
].join("\n")
|
|
17472
|
+
});
|
|
17385
17473
|
return;
|
|
17386
17474
|
}
|
|
17387
|
-
const
|
|
17388
|
-
const
|
|
17389
|
-
|
|
17390
|
-
|
|
17391
|
-
|
|
17392
|
-
|
|
17393
|
-
|
|
17394
|
-
|
|
17395
|
-
|
|
17396
|
-
|
|
17397
|
-
|
|
17398
|
-
|
|
17399
|
-
|
|
17400
|
-
|
|
17401
|
-
|
|
17475
|
+
const messagesRemoved = session.messages.length - intent.target;
|
|
17476
|
+
const result = fileCheckpoints2.restoreToMessageIndex(intent.target);
|
|
17477
|
+
session.truncateTo(intent.target);
|
|
17478
|
+
await ctx.sessions.save();
|
|
17479
|
+
ctx.resetWebSessionUsage();
|
|
17480
|
+
ctx.send({
|
|
17481
|
+
type: "info",
|
|
17482
|
+
message: formatRewindReport({
|
|
17483
|
+
target: intent.target,
|
|
17484
|
+
messagesRemoved,
|
|
17485
|
+
filesRestored: result.restored,
|
|
17486
|
+
filesDeleted: result.deleted,
|
|
17487
|
+
files: result.files
|
|
17488
|
+
}).join("\n")
|
|
17489
|
+
});
|
|
17402
17490
|
ctx.sendSessionMessages();
|
|
17403
17491
|
ctx.sendStatus();
|
|
17404
17492
|
}
|
|
@@ -17658,7 +17746,7 @@ async function handleTest(args, ctx) {
|
|
|
17658
17746
|
const isCommand = argStr.includes(" ") || /^(mvn|gradle|npm|pytest|cargo|go)\b/.test(argStr);
|
|
17659
17747
|
testArgs = isCommand ? { command: argStr } : { filter: argStr };
|
|
17660
17748
|
}
|
|
17661
|
-
const runTests = ctx.runTests ?? (await import("./run-tests-
|
|
17749
|
+
const runTests = ctx.runTests ?? (await import("./run-tests-JLZ2KIGV.js")).executeTests;
|
|
17662
17750
|
const report = await runTests(testArgs);
|
|
17663
17751
|
ctx.send({ type: "info", message: report });
|
|
17664
17752
|
} catch (err) {
|
|
@@ -17994,7 +18082,7 @@ async function handleMemory(args, ctx) {
|
|
|
17994
18082
|
ctx.handleMemoryManage(sub, args[1], sub === "expire" ? args[2] : void 0);
|
|
17995
18083
|
} else if (sub === "export") {
|
|
17996
18084
|
if (args[1] === "md") {
|
|
17997
|
-
const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-
|
|
18085
|
+
const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-TA224ZFQ.js");
|
|
17998
18086
|
ctx.send({
|
|
17999
18087
|
type: "export_data",
|
|
18000
18088
|
format: "md",
|
|
@@ -18433,7 +18521,7 @@ async function handleHelp(_args, ctx) {
|
|
|
18433
18521
|
" /about \u2014 Version & author info",
|
|
18434
18522
|
" /provider <id> \u2014 Switch AI provider",
|
|
18435
18523
|
" /model <id> \u2014 Switch model",
|
|
18436
|
-
" /clear \u2014
|
|
18524
|
+
" /clear \u2014 Start a new session (previous conversation is kept)",
|
|
18437
18525
|
" /compact [hint] \u2014 Compress conversation history",
|
|
18438
18526
|
" /think [on|off] \u2014 Toggle extended thinking mode",
|
|
18439
18527
|
" /plan [execute|exit|status] \u2014 Read-only planning mode (bare /plan enters it)",
|
|
@@ -143,7 +143,7 @@ ${content}`);
|
|
|
143
143
|
const state = await runDiscussion(config, providers, options.topic);
|
|
144
144
|
if (options.save !== false && state.messages.length > 0) {
|
|
145
145
|
try {
|
|
146
|
-
const { persistDiscussion } = await import("./persist-
|
|
146
|
+
const { persistDiscussion } = await import("./persist-S77WRVLD.js");
|
|
147
147
|
const { path } = await persistDiscussion(state, configManager, defaultProvider, defaultModel);
|
|
148
148
|
console.log(chalk.dim(`
|
|
149
149
|
\u{1F4BE} Saved to history \u2014 open it in the Web UI and hit \u{1F3AC} to replay.
|
|
@@ -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-6C3R7KSK.js");
|
|
162
162
|
const orchestrator = new TaskOrchestrator(config, providers, configManager);
|
|
163
163
|
let interrupted = false;
|
|
164
164
|
const onSigint = () => {
|