jinzd-ai-cli 0.4.281 → 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-237ZXBQD.js → batch-SBP6H7IK.js} +2 -2
- package/dist/{chunk-WUIOUJA2.js → chunk-6IRG727F.js} +1 -1
- package/dist/{chunk-FHRIDE2T.js → chunk-7XKIDSJT.js} +4 -4
- package/dist/{chunk-4XJVSMZ6.js → chunk-EVD6CCO2.js} +1 -1
- package/dist/{chunk-BVGSR3BA.js → chunk-GSGJABL6.js} +3 -3
- package/dist/{chunk-J3RWNQOF.js → chunk-HJDJAI7T.js} +1 -1
- package/dist/{chunk-6NO5FZW6.js → chunk-IUVDZVZ4.js} +18 -0
- package/dist/{chunk-2FCKZ3OS.js → chunk-JQU4GYET.js} +1 -1
- package/dist/{chunk-J5TXHFDO.js → chunk-KDXA7RXA.js} +70 -4
- package/dist/{chunk-L7C34TFI.js → chunk-LNUWIY6M.js} +1 -1
- package/dist/{chunk-VB54ILH7.js → chunk-NUJTNH76.js} +1 -1
- package/dist/{chunk-IXEKDAIX.js → chunk-RHSCROLG.js} +1 -1
- package/dist/{chunk-H2VE4TTN.js → chunk-SGUPIQYT.js} +1 -1
- package/dist/{chunk-5GYOQ7EF.js → chunk-TNIMHTKG.js} +1 -1
- package/dist/{chunk-UTJQXG4P.js → chunk-WMHLWCZQ.js} +3 -3
- package/dist/{chunk-JT2A2M4F.js → chunk-YRPL7A3S.js} +1 -1
- package/dist/{ci-LXRTYJ6F.js → ci-VAAMX44S.js} +4 -4
- package/dist/{ci-format-II3OT2VU.js → ci-format-RMULFSB5.js} +2 -2
- package/dist/{constants-X53QCUTP.js → constants-PXLMEBJY.js} +1 -1
- package/dist/{doctor-cli-6JCJEQR4.js → doctor-cli-C2DFYU2M.js} +4 -4
- package/dist/electron-server.js +136 -56
- package/dist/{hub-RXAFF7QI.js → hub-XIU3YTOE.js} +2 -2
- package/dist/index.js +72 -82
- package/dist/{persist-TBQILDSE.js → persist-S77WRVLD.js} +2 -2
- package/dist/{persistent-memory-7CKJLS25.js → persistent-memory-ACXKU6RV.js} +2 -2
- package/dist/{persistent-memory-WAKFKH2I.js → persistent-memory-TA224ZFQ.js} +2 -2
- package/dist/{pr-DZTRHAMG.js → pr-J74HW44E.js} +4 -4
- package/dist/{run-tests-XGCNUT5S.js → run-tests-4KTX5YMO.js} +2 -2
- package/dist/{run-tests-4ESYEROQ.js → run-tests-JLZ2KIGV.js} +2 -2
- package/dist/{server-6RYXFG3H.js → server-226R6675.js} +69 -63
- package/dist/{server-EFA7UP4I.js → server-4CZXYGJN.js} +5 -5
- package/dist/{task-orchestrator-H3AEIHR3.js → task-orchestrator-6C3R7KSK.js} +5 -5
- package/dist/{usage-W7TZWHY7.js → usage-FY3TEJJS.js} +2 -2
- package/package.json +1 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ConfigManager
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-EVD6CCO2.js";
|
|
5
5
|
import "./chunk-TU3L3PW7.js";
|
|
6
6
|
import {
|
|
7
7
|
atomicWriteFileSync
|
|
8
8
|
} from "./chunk-IW3Q7AE5.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-JQU4GYET.js";
|
|
10
10
|
|
|
11
11
|
// src/cli/batch.ts
|
|
12
12
|
import Anthropic from "@anthropic-ai/sdk";
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
searchPersistentMemories,
|
|
12
12
|
touchMemoryReferences,
|
|
13
13
|
updateMemoryEntry
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-SGUPIQYT.js";
|
|
15
15
|
import {
|
|
16
16
|
indexProject
|
|
17
17
|
} from "./chunk-4DEMGCK4.js";
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
runHook,
|
|
31
31
|
runLifecycleHooks,
|
|
32
32
|
runTool
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-LNUWIY6M.js";
|
|
34
34
|
import {
|
|
35
35
|
buildTruncatedArgumentsError,
|
|
36
36
|
getDangerLevel,
|
|
@@ -50,14 +50,14 @@ import {
|
|
|
50
50
|
} from "./chunk-4BKXL7SM.js";
|
|
51
51
|
import {
|
|
52
52
|
runTestsTool
|
|
53
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-HJDJAI7T.js";
|
|
54
54
|
import {
|
|
55
55
|
CONFIG_DIR_NAME,
|
|
56
56
|
DEFAULT_MAX_TOOL_OUTPUT_CHARS_CAP,
|
|
57
57
|
SUBAGENT_ALLOWED_TOOLS,
|
|
58
58
|
SUBAGENT_DEFAULT_MAX_ROUNDS,
|
|
59
59
|
SUBAGENT_MAX_ROUNDS_LIMIT
|
|
60
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-JQU4GYET.js";
|
|
61
61
|
|
|
62
62
|
// src/tools/shell-pool.ts
|
|
63
63
|
import { spawn as spawn2 } from "child_process";
|
|
@@ -8,13 +8,13 @@ import {
|
|
|
8
8
|
listHooks,
|
|
9
9
|
listInstalledPlugins,
|
|
10
10
|
resetStats
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-LNUWIY6M.js";
|
|
12
12
|
import {
|
|
13
13
|
ProviderRegistry
|
|
14
14
|
} from "./chunk-UGY5SVNX.js";
|
|
15
15
|
import {
|
|
16
16
|
ConfigManager
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-EVD6CCO2.js";
|
|
18
18
|
import {
|
|
19
19
|
getGitRoot
|
|
20
20
|
} from "./chunk-HOSJZMQS.js";
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
MCP_PROJECT_CONFIG_NAME,
|
|
27
27
|
MEMORY_FILE_NAME,
|
|
28
28
|
VERSION
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-JQU4GYET.js";
|
|
30
30
|
|
|
31
31
|
// src/diagnostics/doctor-report.ts
|
|
32
32
|
import { existsSync as existsSync3, statSync as statSync2 } from "fs";
|
|
@@ -97,6 +97,24 @@ var Session = class _Session {
|
|
|
97
97
|
this.updated = /* @__PURE__ */ new Date();
|
|
98
98
|
this.dirty = true;
|
|
99
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* 把对话截断到前 `count` 条(`/rewind` 用)。
|
|
102
|
+
*
|
|
103
|
+
* 存在的理由是 `dirty`:`messages` 是个普通公开字段,两端此前都直接
|
|
104
|
+
* `session.messages = session.messages.slice(0, n)`,**不会置脏**——于是 REPL 压根不存,
|
|
105
|
+
* Web 存了也被 `save()` 的 `if (!force && !dirty) return` 跳过。结果 `/rewind` 只改内存,
|
|
106
|
+
* 而它同时真的回退了磁盘上的文件:重启后文件是回退后的、对话是回退前的,
|
|
107
|
+
* 恰恰制造出 rewind 本身要消除的那种不一致(P2-02 第 6 批)。
|
|
108
|
+
*
|
|
109
|
+
* 落在截断点之后的检查点一并丢弃(它们指向已经不存在的消息)。
|
|
110
|
+
*/
|
|
111
|
+
truncateTo(count) {
|
|
112
|
+
const target = Math.max(0, Math.min(count, this.messages.length));
|
|
113
|
+
this.messages = this.messages.slice(0, target);
|
|
114
|
+
this.checkpoints = this.checkpoints.filter((c) => c.messageIndex <= target);
|
|
115
|
+
this.updated = /* @__PURE__ */ new Date();
|
|
116
|
+
this.dirty = true;
|
|
117
|
+
}
|
|
100
118
|
addMessage(message) {
|
|
101
119
|
this.messages.push(message);
|
|
102
120
|
this.updated = /* @__PURE__ */ new Date();
|
|
@@ -5,14 +5,14 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
estimateTokens,
|
|
7
7
|
truncateForPersist
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-7XKIDSJT.js";
|
|
9
9
|
import {
|
|
10
10
|
isMemoryExpired,
|
|
11
11
|
isMemoryStale
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-SGUPIQYT.js";
|
|
13
13
|
import {
|
|
14
14
|
getContentText
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-IUVDZVZ4.js";
|
|
16
16
|
import {
|
|
17
17
|
isCleanDocumentBody,
|
|
18
18
|
stripOuterCodeFence
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
MCP_PROTOCOL_VERSION,
|
|
31
31
|
MCP_TOOL_PREFIX,
|
|
32
32
|
VERSION
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-JQU4GYET.js";
|
|
34
34
|
|
|
35
35
|
// src/mcp/client.ts
|
|
36
36
|
import { spawn } from "child_process";
|
|
@@ -2014,6 +2014,67 @@ function readGitDiff(options = {}) {
|
|
|
2014
2014
|
}).trim();
|
|
2015
2015
|
}
|
|
2016
2016
|
|
|
2017
|
+
// src/core/session-history.ts
|
|
2018
|
+
function parseRewindArgs(args, messageCount) {
|
|
2019
|
+
const sub = args[0];
|
|
2020
|
+
if (!sub || sub.toLowerCase() === "list") return { kind: "list" };
|
|
2021
|
+
const n = Number.parseInt(sub, 10);
|
|
2022
|
+
if (Number.isNaN(n) || n < 1 || n > messageCount) {
|
|
2023
|
+
return { kind: "invalid", message: `Invalid message number: ${sub}. Range: 1-${messageCount}` };
|
|
2024
|
+
}
|
|
2025
|
+
return { kind: "rewind", target: n };
|
|
2026
|
+
}
|
|
2027
|
+
function buildRewindList(messages, checkpointIndices, previewWidth = 70) {
|
|
2028
|
+
return messages.map((m, i) => ({
|
|
2029
|
+
index: i + 1,
|
|
2030
|
+
role: m.role,
|
|
2031
|
+
preview: getContentText(m.content).replace(/\s+/g, " ").trim().slice(0, previewWidth),
|
|
2032
|
+
hasCheckpoint: checkpointIndices.includes(i)
|
|
2033
|
+
}));
|
|
2034
|
+
}
|
|
2035
|
+
function formatRewindReport(report) {
|
|
2036
|
+
const lines = [
|
|
2037
|
+
`\u2713 Rewound to message ${report.target}`,
|
|
2038
|
+
` Messages removed: ${report.messagesRemoved}`
|
|
2039
|
+
];
|
|
2040
|
+
if (report.filesRestored > 0 || report.filesDeleted > 0) {
|
|
2041
|
+
lines.push(` Files restored: ${report.filesRestored}, files deleted: ${report.filesDeleted}`);
|
|
2042
|
+
for (const f of report.files) lines.push(` ${f}`);
|
|
2043
|
+
} else {
|
|
2044
|
+
lines.push(" No file changes to revert.");
|
|
2045
|
+
}
|
|
2046
|
+
return lines;
|
|
2047
|
+
}
|
|
2048
|
+
function resolveForkPoint(session, checkpointName) {
|
|
2049
|
+
const name = checkpointName?.trim();
|
|
2050
|
+
if (!name) {
|
|
2051
|
+
return { ok: true, messageCount: session.messages.length, fromLabel: "current position" };
|
|
2052
|
+
}
|
|
2053
|
+
const cp = session.checkpoints.find((c) => c.name === name);
|
|
2054
|
+
if (!cp) {
|
|
2055
|
+
const available = session.checkpoints.map((c) => c.name);
|
|
2056
|
+
return {
|
|
2057
|
+
ok: false,
|
|
2058
|
+
message: available.length > 0 ? `Checkpoint "${name}" not found. Available: ${available.join(", ")}` : `Checkpoint "${name}" not found. No checkpoints saved. Use /checkpoint save <name> first.`
|
|
2059
|
+
};
|
|
2060
|
+
}
|
|
2061
|
+
return {
|
|
2062
|
+
ok: true,
|
|
2063
|
+
messageCount: cp.messageIndex,
|
|
2064
|
+
fromLabel: `checkpoint "${cp.name}" (${cp.messageIndex} messages)`
|
|
2065
|
+
};
|
|
2066
|
+
}
|
|
2067
|
+
function formatForkReport(report) {
|
|
2068
|
+
return [
|
|
2069
|
+
"Session Forked",
|
|
2070
|
+
` Original: ${report.originalId.slice(0, 8)} "${report.originalTitle}"`,
|
|
2071
|
+
` Forked: ${report.forkedId.slice(0, 8)} "${report.forkedTitle}"`,
|
|
2072
|
+
` From: ${report.fromLabel}`,
|
|
2073
|
+
` Messages: ${report.messageCount} copied, ${report.checkpointCount} checkpoint(s) preserved`,
|
|
2074
|
+
` Use /session load ${report.originalId.slice(0, 8)} to switch back to the original.`
|
|
2075
|
+
];
|
|
2076
|
+
}
|
|
2077
|
+
|
|
2017
2078
|
// src/core/session-cost.ts
|
|
2018
2079
|
function buildSessionCostReport(input) {
|
|
2019
2080
|
const { usage } = input;
|
|
@@ -2072,6 +2133,11 @@ export {
|
|
|
2072
2133
|
clearedSessionMessage,
|
|
2073
2134
|
applyProfileCommand,
|
|
2074
2135
|
readGitDiff,
|
|
2136
|
+
parseRewindArgs,
|
|
2137
|
+
buildRewindList,
|
|
2138
|
+
formatRewindReport,
|
|
2139
|
+
resolveForkPoint,
|
|
2140
|
+
formatForkReport,
|
|
2075
2141
|
scanDirTree,
|
|
2076
2142
|
scanProject,
|
|
2077
2143
|
buildInitPrompt,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
MEMORY_FILE_NAME,
|
|
14
14
|
MEMORY_MAX_CHARS,
|
|
15
15
|
MEMORY_STORE_FILE_NAME
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-JQU4GYET.js";
|
|
17
17
|
|
|
18
18
|
// src/memory/persistent-memory.ts
|
|
19
19
|
import { copyFileSync, existsSync, mkdirSync, readFileSync, statSync } from "fs";
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
evaluateCiGate,
|
|
4
4
|
normalizeCiThresholds
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-YRPL7A3S.js";
|
|
6
6
|
import {
|
|
7
7
|
buildReviewPrompt,
|
|
8
8
|
buildSecurityReviewPrompt,
|
|
@@ -16,10 +16,10 @@ import {
|
|
|
16
16
|
} from "./chunk-UGY5SVNX.js";
|
|
17
17
|
import {
|
|
18
18
|
ConfigManager
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-EVD6CCO2.js";
|
|
20
20
|
import {
|
|
21
21
|
VERSION
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-JQU4GYET.js";
|
|
23
23
|
|
|
24
24
|
// src/cli/ci.ts
|
|
25
25
|
import { execFileSync } from "child_process";
|
|
@@ -3,16 +3,16 @@ import {
|
|
|
3
3
|
CI_COMMENT_MARKER,
|
|
4
4
|
countSeverity,
|
|
5
5
|
runCi
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-WMHLWCZQ.js";
|
|
7
|
+
import "./chunk-YRPL7A3S.js";
|
|
8
8
|
import "./chunk-HLWUDRBO.js";
|
|
9
9
|
import "./chunk-6YZEZFX5.js";
|
|
10
10
|
import "./chunk-UGY5SVNX.js";
|
|
11
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-EVD6CCO2.js";
|
|
12
12
|
import "./chunk-TEXT4DAT.js";
|
|
13
13
|
import "./chunk-TU3L3PW7.js";
|
|
14
14
|
import "./chunk-IW3Q7AE5.js";
|
|
15
|
-
import "./chunk-
|
|
15
|
+
import "./chunk-JQU4GYET.js";
|
|
16
16
|
export {
|
|
17
17
|
CI_COMMENT_MARKER,
|
|
18
18
|
countSeverity,
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
import {
|
|
3
3
|
formatDoctorReport,
|
|
4
4
|
runDoctorCli
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-GSGJABL6.js";
|
|
6
|
+
import "./chunk-LNUWIY6M.js";
|
|
7
7
|
import "./chunk-UGY5SVNX.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-EVD6CCO2.js";
|
|
9
9
|
import "./chunk-TEXT4DAT.js";
|
|
10
10
|
import "./chunk-TU3L3PW7.js";
|
|
11
11
|
import "./chunk-HOSJZMQS.js";
|
|
12
12
|
import "./chunk-IW3Q7AE5.js";
|
|
13
|
-
import "./chunk-
|
|
13
|
+
import "./chunk-JQU4GYET.js";
|
|
14
14
|
export {
|
|
15
15
|
formatDoctorReport,
|
|
16
16
|
runDoctorCli
|
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();
|
|
@@ -16732,6 +16750,67 @@ function clearedSessionMessage(priorSessionId, priorMessageCount = 0) {
|
|
|
16732
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.";
|
|
16733
16751
|
}
|
|
16734
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
|
+
}
|
|
16813
|
+
|
|
16735
16814
|
// src/web/commands/session-commands.ts
|
|
16736
16815
|
async function handleClear(_args, ctx) {
|
|
16737
16816
|
const prior = ctx.sessions.current;
|
|
@@ -16759,7 +16838,7 @@ Cache: write=${cacheCreate} read=${cacheRead}` : "";
|
|
|
16759
16838
|
Cost: ${formatCost(cost)}` : "";
|
|
16760
16839
|
let memoryLine = "";
|
|
16761
16840
|
try {
|
|
16762
|
-
const { countPendingMemories: countPendingMemories2 } = await import("./persistent-memory-
|
|
16841
|
+
const { countPendingMemories: countPendingMemories2 } = await import("./persistent-memory-TA224ZFQ.js");
|
|
16763
16842
|
const pending = countPendingMemories2(ctx.config.getConfigDir());
|
|
16764
16843
|
if (pending > 0) memoryLine = `
|
|
16765
16844
|
Memory: \u26A0 ${pending} pending approval \u2014 see the Memory panel or /memory`;
|
|
@@ -17338,27 +17417,27 @@ async function handleFork(args, ctx) {
|
|
|
17338
17417
|
ctx.send({ type: "info", message: "No active session to fork." });
|
|
17339
17418
|
return;
|
|
17340
17419
|
}
|
|
17341
|
-
const
|
|
17342
|
-
|
|
17343
|
-
|
|
17344
|
-
|
|
17345
|
-
const cp = session.checkpoints.find((c) => c.name === sub);
|
|
17346
|
-
if (!cp) {
|
|
17347
|
-
const available = session.checkpoints.map((c) => c.name);
|
|
17348
|
-
ctx.send({ type: "error", message: available.length > 0 ? `Checkpoint "${sub}" not found. Available: ${available.join(", ")}` : `Checkpoint "${sub}" not found. No checkpoints saved.` });
|
|
17349
|
-
return;
|
|
17350
|
-
}
|
|
17351
|
-
messageCount = cp.messageIndex;
|
|
17352
|
-
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;
|
|
17353
17424
|
}
|
|
17354
17425
|
try {
|
|
17355
|
-
const originalId = session.id
|
|
17356
|
-
const
|
|
17357
|
-
|
|
17358
|
-
|
|
17359
|
-
|
|
17360
|
-
|
|
17361
|
-
|
|
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
|
+
});
|
|
17362
17441
|
ctx.sendSessionMessages();
|
|
17363
17442
|
ctx.sendStatus();
|
|
17364
17443
|
ctx.sendSessionList();
|
|
@@ -17372,41 +17451,42 @@ async function handleRewind(args, ctx) {
|
|
|
17372
17451
|
ctx.send({ type: "info", message: "No messages to rewind." });
|
|
17373
17452
|
return;
|
|
17374
17453
|
}
|
|
17375
|
-
const
|
|
17376
|
-
if (
|
|
17377
|
-
|
|
17378
|
-
`];
|
|
17379
|
-
const cpIndices = (await import("./file-checkpoint-CGH6OJVI.js")).fileCheckpoints.getMessageIndices();
|
|
17380
|
-
for (let i = 0; i < session.messages.length; i++) {
|
|
17381
|
-
const m = session.messages[i];
|
|
17382
|
-
const text = getContentText(m.content).replace(/\n/g, " ").slice(0, 60);
|
|
17383
|
-
const pin = cpIndices.includes(i) ? " \u{1F4CC}" : "";
|
|
17384
|
-
lines.push(` [${i + 1}] ${m.role.padEnd(10)} ${text}${pin}`);
|
|
17385
|
-
}
|
|
17386
|
-
lines.push("", "Usage: /rewind <n> \u2014 rewind to message N", "\u{1F4CC} = file checkpoint");
|
|
17387
|
-
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 });
|
|
17388
17457
|
return;
|
|
17389
17458
|
}
|
|
17390
|
-
const
|
|
17391
|
-
if (
|
|
17392
|
-
|
|
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
|
+
});
|
|
17393
17473
|
return;
|
|
17394
17474
|
}
|
|
17395
|
-
const
|
|
17396
|
-
const
|
|
17397
|
-
|
|
17398
|
-
|
|
17399
|
-
|
|
17400
|
-
|
|
17401
|
-
|
|
17402
|
-
|
|
17403
|
-
|
|
17404
|
-
|
|
17405
|
-
|
|
17406
|
-
|
|
17407
|
-
|
|
17408
|
-
|
|
17409
|
-
|
|
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
|
+
});
|
|
17410
17490
|
ctx.sendSessionMessages();
|
|
17411
17491
|
ctx.sendStatus();
|
|
17412
17492
|
}
|
|
@@ -17666,7 +17746,7 @@ async function handleTest(args, ctx) {
|
|
|
17666
17746
|
const isCommand = argStr.includes(" ") || /^(mvn|gradle|npm|pytest|cargo|go)\b/.test(argStr);
|
|
17667
17747
|
testArgs = isCommand ? { command: argStr } : { filter: argStr };
|
|
17668
17748
|
}
|
|
17669
|
-
const runTests = ctx.runTests ?? (await import("./run-tests-
|
|
17749
|
+
const runTests = ctx.runTests ?? (await import("./run-tests-JLZ2KIGV.js")).executeTests;
|
|
17670
17750
|
const report = await runTests(testArgs);
|
|
17671
17751
|
ctx.send({ type: "info", message: report });
|
|
17672
17752
|
} catch (err) {
|
|
@@ -18002,7 +18082,7 @@ async function handleMemory(args, ctx) {
|
|
|
18002
18082
|
ctx.handleMemoryManage(sub, args[1], sub === "expire" ? args[2] : void 0);
|
|
18003
18083
|
} else if (sub === "export") {
|
|
18004
18084
|
if (args[1] === "md") {
|
|
18005
|
-
const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-
|
|
18085
|
+
const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-TA224ZFQ.js");
|
|
18006
18086
|
ctx.send({
|
|
18007
18087
|
type: "export_data",
|
|
18008
18088
|
format: "md",
|