@claude-sessions/web 0.4.6 → 0.4.7-beta.0
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/build/client/_app/immutable/chunks/CBiqUHp4.js +1 -0
- package/build/client/_app/immutable/chunks/CBiqUHp4.js.br +0 -0
- package/build/client/_app/immutable/chunks/CBiqUHp4.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CYKpEMl5.js +1 -0
- package/build/client/_app/immutable/chunks/CYKpEMl5.js.br +0 -0
- package/build/client/_app/immutable/chunks/CYKpEMl5.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DicbBas7.js +1 -0
- package/build/client/_app/immutable/chunks/DicbBas7.js.br +0 -0
- package/build/client/_app/immutable/chunks/DicbBas7.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{aZi3OCpL.js → GmjPUgZ0.js} +30 -26
- package/build/client/_app/immutable/chunks/GmjPUgZ0.js.br +0 -0
- package/build/client/_app/immutable/chunks/GmjPUgZ0.js.gz +0 -0
- package/build/client/_app/immutable/entry/{app.CYY1PZCN.js → app.CMV94ayS.js} +2 -2
- package/build/client/_app/immutable/entry/app.CMV94ayS.js.br +0 -0
- package/build/client/_app/immutable/entry/app.CMV94ayS.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.CgzpSnrE.js +1 -0
- package/build/client/_app/immutable/entry/start.CgzpSnrE.js.br +0 -0
- package/build/client/_app/immutable/entry/start.CgzpSnrE.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{0.B2uv-WBM.js → 0.DVHVg7U5.js} +1 -1
- package/build/client/_app/immutable/nodes/0.DVHVg7U5.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.DVHVg7U5.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{1.BoxEAqK6.js → 1.D0PdYLPm.js} +1 -1
- package/build/client/_app/immutable/nodes/1.D0PdYLPm.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.D0PdYLPm.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.Cs83Zp7C.js +4 -0
- package/build/client/_app/immutable/nodes/2.Cs83Zp7C.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.Cs83Zp7C.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{3.Dj8iwfME.js → 3.BMgB8JW6.js} +1 -1
- package/build/client/_app/immutable/nodes/3.BMgB8JW6.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.BMgB8JW6.js.gz +0 -0
- package/build/client/_app/version.json +1 -1
- package/build/client/_app/version.json.br +0 -0
- package/build/client/_app/version.json.gz +0 -0
- package/build/server/chunks/{0-DChhR3gd.js → 0-CEq226Yu.js} +3 -3
- package/build/server/chunks/0-CEq226Yu.js.map +1 -0
- package/build/server/chunks/{1-BBSPd3nB.js → 1-CZKii7cF.js} +3 -3
- package/build/server/chunks/1-CZKii7cF.js.map +1 -0
- package/build/server/chunks/{2-C20RW_lJ.js → 2-1NHU8T7t.js} +3 -3
- package/build/server/chunks/2-1NHU8T7t.js.map +1 -0
- package/build/server/chunks/{3-D3wL2YSE.js → 3-DHru04k0.js} +3 -3
- package/build/server/chunks/3-DHru04k0.js.map +1 -0
- package/build/server/chunks/{InputModal-1qJGryUa.js → InputModal-B2QW71Rc.js} +2 -2
- package/build/server/chunks/InputModal-B2QW71Rc.js.map +1 -0
- package/build/server/chunks/{Toast-C9b_dWm4.js → Toast-BzqOqKOg.js} +3 -3
- package/build/server/chunks/Toast-BzqOqKOg.js.map +1 -0
- package/build/server/chunks/{_layout.svelte-CdDMC1RI.js → _layout.svelte-CkLZkYhs.js} +7 -7
- package/build/server/chunks/_layout.svelte-CkLZkYhs.js.map +1 -0
- package/build/server/chunks/{_page.svelte-Dx2ikKP_.js → _page.svelte-DSpIiljH.js} +13 -7
- package/build/server/chunks/_page.svelte-DSpIiljH.js.map +1 -0
- package/build/server/chunks/{_page.svelte-CVL9fjg-.js → _page.svelte-DuQWccy1.js} +7 -7
- package/build/server/chunks/_page.svelte-DuQWccy1.js.map +1 -0
- package/build/server/chunks/{_server.ts-DOSGEHuw.js → _server.ts-B-2v0wgR.js} +2 -2
- package/build/server/chunks/{_server.ts-DOSGEHuw.js.map → _server.ts-B-2v0wgR.js.map} +1 -1
- package/build/server/chunks/{_server.ts-BWxgSwZN.js → _server.ts-Ba6jXSm2.js} +2 -2
- package/build/server/chunks/{_server.ts-BWxgSwZN.js.map → _server.ts-Ba6jXSm2.js.map} +1 -1
- package/build/server/chunks/{_server.ts-rTWeIoSC.js → _server.ts-BhA9i-7j.js} +3 -3
- package/build/server/chunks/{_server.ts-rTWeIoSC.js.map → _server.ts-BhA9i-7j.js.map} +1 -1
- package/build/server/chunks/{_server.ts-CrKc6LEy.js → _server.ts-BjynU3C4.js} +2 -2
- package/build/server/chunks/{_server.ts-CrKc6LEy.js.map → _server.ts-BjynU3C4.js.map} +1 -1
- package/build/server/chunks/{_server.ts-F01KLghS.js → _server.ts-C-iKh37d.js} +2 -2
- package/build/server/chunks/{_server.ts-F01KLghS.js.map → _server.ts-C-iKh37d.js.map} +1 -1
- package/build/server/chunks/{_server.ts-COPvamIQ.js → _server.ts-CoLbb7aT.js} +2 -2
- package/build/server/chunks/{_server.ts-COPvamIQ.js.map → _server.ts-CoLbb7aT.js.map} +1 -1
- package/build/server/chunks/{_server.ts-B3M-jxF5.js → _server.ts-CozgvvoX.js} +2 -2
- package/build/server/chunks/{_server.ts-B3M-jxF5.js.map → _server.ts-CozgvvoX.js.map} +1 -1
- package/build/server/chunks/{_server.ts-BGA9W8aM.js → _server.ts-Cy5z0Rsk.js} +2 -2
- package/build/server/chunks/{_server.ts-BGA9W8aM.js.map → _server.ts-Cy5z0Rsk.js.map} +1 -1
- package/build/server/chunks/{_server.ts-QLTE_2dV.js → _server.ts-DCSJsfkA.js} +2 -2
- package/build/server/chunks/{_server.ts-QLTE_2dV.js.map → _server.ts-DCSJsfkA.js.map} +1 -1
- package/build/server/chunks/{_server.ts-DmWsoikX.js → _server.ts-DRrwjyQ0.js} +2 -2
- package/build/server/chunks/{_server.ts-DmWsoikX.js.map → _server.ts-DRrwjyQ0.js.map} +1 -1
- package/build/server/chunks/{_server.ts-C9GYaVf1.js → _server.ts-DcfIBmy4.js} +3 -3
- package/build/server/chunks/_server.ts-DcfIBmy4.js.map +1 -0
- package/build/server/chunks/{_server.ts-BCOHCAjW.js → _server.ts-Dq4A0ML7.js} +2 -2
- package/build/server/chunks/{_server.ts-BCOHCAjW.js.map → _server.ts-Dq4A0ML7.js.map} +1 -1
- package/build/server/chunks/{_server.ts-DP0i5Bdl.js → _server.ts-dEWE9PbU.js} +2 -2
- package/build/server/chunks/{_server.ts-DP0i5Bdl.js.map → _server.ts-dEWE9PbU.js.map} +1 -1
- package/build/server/chunks/{_server.ts-WZF_VFnZ.js → _server.ts-g1VNk1F2.js} +2 -2
- package/build/server/chunks/{_server.ts-WZF_VFnZ.js.map → _server.ts-g1VNk1F2.js.map} +1 -1
- package/build/server/chunks/{_server.ts-C0mKXnG1.js → _server.ts-klbpGqf9.js} +2 -2
- package/build/server/chunks/{_server.ts-C0mKXnG1.js.map → _server.ts-klbpGqf9.js.map} +1 -1
- package/build/server/chunks/{_server.ts-DmN9rdOH.js → _server.ts-xRJQMsoy.js} +3 -3
- package/build/server/chunks/{_server.ts-DmN9rdOH.js.map → _server.ts-xRJQMsoy.js.map} +1 -1
- package/build/server/chunks/{client-BtcIwznP.js → client-CJUAsTTN.js} +3 -3
- package/build/server/chunks/client-CJUAsTTN.js.map +1 -0
- package/build/server/chunks/{error.svelte-B02-pvoO.js → error.svelte-CYLEgCzL.js} +5 -5
- package/build/server/chunks/error.svelte-CYLEgCzL.js.map +1 -0
- package/build/server/chunks/exports-7ECo9oy7.js +102 -0
- package/build/server/chunks/exports-7ECo9oy7.js.map +1 -0
- package/build/server/chunks/{index2-B2Ld-FFX.js → index-CUeePJRv.js} +1145 -68
- package/build/server/chunks/index-CUeePJRv.js.map +1 -0
- package/build/server/chunks/{index3-DNyQGNm8.js → index2-BbHYMsUG.js} +265 -63
- package/build/server/chunks/index2-BbHYMsUG.js.map +1 -0
- package/build/server/chunks/{index4-CfOR2iO6.js → index3-BKokHvI9.js} +3 -3
- package/build/server/chunks/index3-BKokHvI9.js.map +1 -0
- package/build/server/chunks/server-Bf8x1V_n.js +16 -0
- package/build/server/chunks/server-Bf8x1V_n.js.map +1 -0
- package/build/server/chunks/{session-Dxp1vf6f.js → session-BEXBEvJ9.js} +2 -2
- package/build/server/chunks/{session-Dxp1vf6f.js.map → session-BEXBEvJ9.js.map} +1 -1
- package/build/server/index.js +4 -17
- package/build/server/index.js.map +1 -1
- package/build/server/manifest.js +21 -21
- package/build/server/manifest.js.map +1 -1
- package/package.json +3 -2
- package/build/client/_app/immutable/chunks/CiIZzKcO.js +0 -1
- package/build/client/_app/immutable/chunks/CiIZzKcO.js.br +0 -0
- package/build/client/_app/immutable/chunks/CiIZzKcO.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DDmWtjsj.js +0 -1
- package/build/client/_app/immutable/chunks/DDmWtjsj.js.br +0 -0
- package/build/client/_app/immutable/chunks/DDmWtjsj.js.gz +0 -0
- package/build/client/_app/immutable/chunks/aZi3OCpL.js.br +0 -0
- package/build/client/_app/immutable/chunks/aZi3OCpL.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.CYY1PZCN.js.br +0 -0
- package/build/client/_app/immutable/entry/app.CYY1PZCN.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.D84fuMw9.js +0 -1
- package/build/client/_app/immutable/entry/start.D84fuMw9.js.br +0 -2
- package/build/client/_app/immutable/entry/start.D84fuMw9.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.B2uv-WBM.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.B2uv-WBM.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.BoxEAqK6.js.br +0 -3
- package/build/client/_app/immutable/nodes/1.BoxEAqK6.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.mKAMmHlh.js +0 -4
- package/build/client/_app/immutable/nodes/2.mKAMmHlh.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.mKAMmHlh.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.Dj8iwfME.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.Dj8iwfME.js.gz +0 -0
- package/build/server/chunks/0-DChhR3gd.js.map +0 -1
- package/build/server/chunks/1-BBSPd3nB.js.map +0 -1
- package/build/server/chunks/2-C20RW_lJ.js.map +0 -1
- package/build/server/chunks/3-D3wL2YSE.js.map +0 -1
- package/build/server/chunks/InputModal-1qJGryUa.js.map +0 -1
- package/build/server/chunks/Toast-C9b_dWm4.js.map +0 -1
- package/build/server/chunks/_layout.svelte-CdDMC1RI.js.map +0 -1
- package/build/server/chunks/_page.svelte-CVL9fjg-.js.map +0 -1
- package/build/server/chunks/_page.svelte-Dx2ikKP_.js.map +0 -1
- package/build/server/chunks/_server.ts-C9GYaVf1.js.map +0 -1
- package/build/server/chunks/client-BtcIwznP.js.map +0 -1
- package/build/server/chunks/error.svelte-B02-pvoO.js.map +0 -1
- package/build/server/chunks/index2-B2Ld-FFX.js.map +0 -1
- package/build/server/chunks/index3-DNyQGNm8.js.map +0 -1
- package/build/server/chunks/index4-CfOR2iO6.js.map +0 -1
- package/build/server/chunks/root-B5iYE7yO.js +0 -1182
- package/build/server/chunks/root-B5iYE7yO.js.map +0 -1
|
@@ -59,14 +59,13 @@ var extractTitle = (input) => {
|
|
|
59
59
|
text = extractTextContent(input, { stripIdeTags: true });
|
|
60
60
|
}
|
|
61
61
|
if (!text) return "Untitled";
|
|
62
|
-
|
|
63
|
-
if (
|
|
64
|
-
|
|
65
|
-
if (!cleaned) return "Untitled";
|
|
66
|
-
if (cleaned.includes("\n\n")) {
|
|
67
|
-
cleaned = cleaned.split("\n\n")[0];
|
|
62
|
+
let firstParagraph = text.trim();
|
|
63
|
+
if (firstParagraph.includes("\n\n")) {
|
|
64
|
+
firstParagraph = firstParagraph.split("\n\n")[0];
|
|
68
65
|
}
|
|
69
|
-
|
|
66
|
+
const { name, args } = parseCommandMessage(firstParagraph);
|
|
67
|
+
if (name) return args ? `${name} ${args}` : name;
|
|
68
|
+
return firstParagraph || "Untitled";
|
|
70
69
|
};
|
|
71
70
|
var isInvalidApiKeyMessage = (msg) => {
|
|
72
71
|
const text = extractTextContent(msg.message);
|
|
@@ -95,11 +94,12 @@ var getDisplayTitle = (customTitle, currentSummary, title, maxLength = 60, fallb
|
|
|
95
94
|
return currentSummary.length > maxLength ? currentSummary.slice(0, maxLength - 3) + "..." : currentSummary;
|
|
96
95
|
}
|
|
97
96
|
if (title && title !== "Untitled") {
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
const firstParagraph = title.includes("\n\n") ? title.split("\n\n")[0] : title;
|
|
98
|
+
if (firstParagraph.includes("<command-name>")) {
|
|
99
|
+
const { name, args } = parseCommandMessage(firstParagraph);
|
|
100
100
|
if (name) return args ? `${name} ${args}` : name;
|
|
101
101
|
}
|
|
102
|
-
return
|
|
102
|
+
return firstParagraph;
|
|
103
103
|
}
|
|
104
104
|
return fallback;
|
|
105
105
|
};
|
|
@@ -145,27 +145,32 @@ var tryParseJsonLine = (line, lineNumber, filePath) => {
|
|
|
145
145
|
return JSON.parse(line);
|
|
146
146
|
} catch {
|
|
147
147
|
if (filePath) {
|
|
148
|
-
|
|
148
|
+
logger.warn(`Skipping invalid JSON at line ${lineNumber} in ${filePath}`);
|
|
149
149
|
}
|
|
150
150
|
return null;
|
|
151
151
|
}
|
|
152
152
|
};
|
|
153
|
-
var parseJsonlLines = (lines, filePath) => {
|
|
154
|
-
|
|
153
|
+
var parseJsonlLines = (lines, filePath, { strict = false } = {}) => {
|
|
154
|
+
const results = [];
|
|
155
|
+
for (let idx = 0; idx < lines.length; idx++) {
|
|
155
156
|
try {
|
|
156
|
-
|
|
157
|
+
results.push(JSON.parse(lines[idx]));
|
|
157
158
|
} catch (e) {
|
|
158
159
|
const err = e;
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
160
|
+
if (strict) {
|
|
161
|
+
throw new Error(`Failed to parse line ${idx + 1} in ${filePath}: ${err.message}`, {
|
|
162
|
+
cause: e
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
logger.warn(`Skipping malformed line ${idx + 1} in ${filePath}: ${err.message}`);
|
|
162
166
|
}
|
|
163
|
-
}
|
|
167
|
+
}
|
|
168
|
+
return results;
|
|
164
169
|
};
|
|
165
|
-
var readJsonlFile = (filePath) => Effect.gen(function* () {
|
|
170
|
+
var readJsonlFile = (filePath, options) => Effect.gen(function* () {
|
|
166
171
|
const content = yield* Effect.tryPromise(() => fs6.readFile(filePath, "utf-8"));
|
|
167
172
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
168
|
-
return parseJsonlLines(lines, filePath);
|
|
173
|
+
return parseJsonlLines(lines, filePath, options);
|
|
169
174
|
});
|
|
170
175
|
var getTotalTodoCount = (todos) => {
|
|
171
176
|
return todos.sessionTodos.length + todos.agentTodos.reduce((sum, a) => sum + a.todos.length, 0);
|
|
@@ -308,14 +313,14 @@ var resolvePathFromClaudeConfig = async (folderName, fileSystem = fs6) => {
|
|
|
308
313
|
};
|
|
309
314
|
var folderNameToPath = async (folderName) => {
|
|
310
315
|
const homeDir = os.homedir();
|
|
311
|
-
const realPath = getRealPathFromSession(folderName);
|
|
312
|
-
if (realPath) {
|
|
313
|
-
return toRelativePath(realPath, homeDir);
|
|
314
|
-
}
|
|
315
316
|
const configPath = await resolvePathFromClaudeConfig(folderName);
|
|
316
317
|
if (configPath) {
|
|
317
318
|
return toRelativePath(configPath, homeDir);
|
|
318
319
|
}
|
|
320
|
+
const realPath = getRealPathFromSession(folderName);
|
|
321
|
+
if (realPath) {
|
|
322
|
+
return toRelativePath(realPath, homeDir);
|
|
323
|
+
}
|
|
319
324
|
const absolutePath = folderNameToDisplayPath(folderName);
|
|
320
325
|
return toRelativePath(absolutePath, homeDir);
|
|
321
326
|
};
|
|
@@ -990,7 +995,7 @@ var readSession = (projectName, sessionId) => Effect.gen(function* () {
|
|
|
990
995
|
});
|
|
991
996
|
var deleteMessage = (projectName, sessionId, messageUuid, targetType) => Effect.gen(function* () {
|
|
992
997
|
const filePath = path5.join(getSessionsDir(), projectName, `${sessionId}.jsonl`);
|
|
993
|
-
const messages = yield* readJsonlFile(filePath);
|
|
998
|
+
const messages = yield* readJsonlFile(filePath, { strict: true });
|
|
994
999
|
const result = deleteMessageWithChainRepair(messages, messageUuid, targetType);
|
|
995
1000
|
if (!result.deleted) {
|
|
996
1001
|
return { success: false, error: "Message not found" };
|
|
@@ -1001,7 +1006,7 @@ var deleteMessage = (projectName, sessionId, messageUuid, targetType) => Effect.
|
|
|
1001
1006
|
});
|
|
1002
1007
|
var restoreMessage = (projectName, sessionId, message, index) => Effect.gen(function* () {
|
|
1003
1008
|
const filePath = path5.join(getSessionsDir(), projectName, `${sessionId}.jsonl`);
|
|
1004
|
-
const messages = yield* readJsonlFile(filePath);
|
|
1009
|
+
const messages = yield* readJsonlFile(filePath, { strict: true });
|
|
1005
1010
|
const msgUuid = message.uuid ?? message.messageId;
|
|
1006
1011
|
if (!msgUuid) {
|
|
1007
1012
|
return { success: false, error: "Message has no uuid or messageId" };
|
|
@@ -1066,7 +1071,7 @@ var renameSession = (projectName, sessionId, newTitle) => Effect.gen(function* (
|
|
|
1066
1071
|
if (lines.length === 0) {
|
|
1067
1072
|
return { success: false, error: "Empty session" };
|
|
1068
1073
|
}
|
|
1069
|
-
const messages = parseJsonlLines(lines, filePath);
|
|
1074
|
+
const messages = parseJsonlLines(lines, filePath, { strict: true });
|
|
1070
1075
|
const customTitleIdx = messages.findIndex((m) => m.type === "custom-title");
|
|
1071
1076
|
if (customTitleIdx >= 0) {
|
|
1072
1077
|
messages.splice(customTitleIdx, 1);
|
|
@@ -1116,7 +1121,7 @@ var moveSession = (sourceProject, sessionId, targetProject) => Effect.gen(functi
|
|
|
1116
1121
|
var splitSession = (projectName, sessionId, splitAtMessageUuid) => Effect.gen(function* () {
|
|
1117
1122
|
const projectPath = path5.join(getSessionsDir(), projectName);
|
|
1118
1123
|
const filePath = path5.join(projectPath, `${sessionId}.jsonl`);
|
|
1119
|
-
const allMessages = yield* readJsonlFile(filePath);
|
|
1124
|
+
const allMessages = yield* readJsonlFile(filePath, { strict: true });
|
|
1120
1125
|
const splitIndex = allMessages.findIndex((m) => m.uuid === splitAtMessageUuid);
|
|
1121
1126
|
if (splitIndex === -1) {
|
|
1122
1127
|
return { success: false, error: "Message not found" };
|
|
@@ -1163,7 +1168,9 @@ var splitSession = (projectName, sessionId, splitAtMessageUuid) => Effect.gen(fu
|
|
|
1163
1168
|
const agentContent = yield* Effect.tryPromise(() => fs6.readFile(agentPath, "utf-8"));
|
|
1164
1169
|
const agentLines = agentContent.trim().split("\n").filter(Boolean);
|
|
1165
1170
|
if (agentLines.length === 0) continue;
|
|
1166
|
-
const agentMessages = parseJsonlLines(agentLines, agentPath
|
|
1171
|
+
const agentMessages = parseJsonlLines(agentLines, agentPath, {
|
|
1172
|
+
strict: true
|
|
1173
|
+
});
|
|
1167
1174
|
const firstAgentMsg = agentMessages[0];
|
|
1168
1175
|
if (firstAgentMsg.sessionId === sessionId) {
|
|
1169
1176
|
const agentId = agentFile.replace("agent-", "").replace(".jsonl", "");
|
|
@@ -1187,6 +1194,67 @@ var splitSession = (projectName, sessionId, splitAtMessageUuid) => Effect.gen(fu
|
|
|
1187
1194
|
duplicatedSummary: shouldDuplicate
|
|
1188
1195
|
};
|
|
1189
1196
|
});
|
|
1197
|
+
var log2 = createLogger("cache");
|
|
1198
|
+
var CACHE_VERSION = 1;
|
|
1199
|
+
var CACHE_FILENAME = ".tree-cache.json";
|
|
1200
|
+
var getCachePath = (projectName) => path5.join(getSessionsDir(), projectName, CACHE_FILENAME);
|
|
1201
|
+
var loadTreeCache = async (projectName) => {
|
|
1202
|
+
const cachePath = getCachePath(projectName);
|
|
1203
|
+
try {
|
|
1204
|
+
const raw = await fs6.readFile(cachePath, "utf-8");
|
|
1205
|
+
const parsed = JSON.parse(raw);
|
|
1206
|
+
if (parsed.version !== CACHE_VERSION) {
|
|
1207
|
+
log2.debug(`cache version mismatch (${parsed.version} !== ${CACHE_VERSION}), ignoring`);
|
|
1208
|
+
return null;
|
|
1209
|
+
}
|
|
1210
|
+
return parsed;
|
|
1211
|
+
} catch {
|
|
1212
|
+
return null;
|
|
1213
|
+
}
|
|
1214
|
+
};
|
|
1215
|
+
var writeTreeCache = async (projectName, cache) => {
|
|
1216
|
+
const cachePath = getCachePath(projectName);
|
|
1217
|
+
const tmpPath = cachePath + ".tmp";
|
|
1218
|
+
try {
|
|
1219
|
+
await fs6.writeFile(tmpPath, JSON.stringify(cache), "utf-8");
|
|
1220
|
+
await fs6.rename(tmpPath, cachePath);
|
|
1221
|
+
} catch (e) {
|
|
1222
|
+
log2.debug(`failed to write cache: ${e}`);
|
|
1223
|
+
try {
|
|
1224
|
+
await fs6.unlink(tmpPath);
|
|
1225
|
+
} catch {
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
};
|
|
1229
|
+
var validateCache = (cache, sessionFileIds, currentMtimes) => {
|
|
1230
|
+
const cachedIds = new Set(Object.keys(cache.sessions));
|
|
1231
|
+
const currentIds = new Set(sessionFileIds);
|
|
1232
|
+
const changedSessionIds = [];
|
|
1233
|
+
const unchangedSessionIds = [];
|
|
1234
|
+
const newSessionIds = [];
|
|
1235
|
+
const deletedSessionIds = [];
|
|
1236
|
+
for (const id of currentIds) {
|
|
1237
|
+
if (!cachedIds.has(id)) {
|
|
1238
|
+
newSessionIds.push(id);
|
|
1239
|
+
} else {
|
|
1240
|
+
const cachedMtime = cache.sessions[id].fileMtime;
|
|
1241
|
+
const currentMtime = currentMtimes.get(id) ?? 0;
|
|
1242
|
+
if (Math.abs(cachedMtime - currentMtime) <= 1) {
|
|
1243
|
+
unchangedSessionIds.push(id);
|
|
1244
|
+
} else {
|
|
1245
|
+
changedSessionIds.push(id);
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
for (const id of cachedIds) {
|
|
1250
|
+
if (!currentIds.has(id)) {
|
|
1251
|
+
deletedSessionIds.push(id);
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
const isFullHit = changedSessionIds.length === 0 && newSessionIds.length === 0 && deletedSessionIds.length === 0;
|
|
1255
|
+
return { isFullHit, changedSessionIds, unchangedSessionIds, deletedSessionIds, newSessionIds };
|
|
1256
|
+
};
|
|
1257
|
+
var log3 = createLogger("tree");
|
|
1190
1258
|
var sortSessions = (sessions, sort) => {
|
|
1191
1259
|
return sessions.sort((a, b) => {
|
|
1192
1260
|
let comparison = 0;
|
|
@@ -1345,32 +1413,9 @@ var loadSessionTreeDataInternal = (projectName, sessionId, summariesByTargetSess
|
|
|
1345
1413
|
});
|
|
1346
1414
|
var loadSessionTreeData = (projectName, sessionId) => loadSessionTreeDataInternal(projectName, sessionId, void 0);
|
|
1347
1415
|
var DEFAULT_SORT = { field: "summary", order: "desc" };
|
|
1348
|
-
var
|
|
1349
|
-
const project = (yield* listProjects).find((p) => p.name === projectName);
|
|
1350
|
-
if (!project) {
|
|
1351
|
-
return null;
|
|
1352
|
-
}
|
|
1353
|
-
const sort = sortOptions ?? DEFAULT_SORT;
|
|
1354
|
-
const projectPath = path5.join(getSessionsDir(), projectName);
|
|
1355
|
-
const files = yield* Effect.tryPromise(() => fs6.readdir(projectPath));
|
|
1356
|
-
const sessionFiles = files.filter((f) => f.endsWith(".jsonl") && !f.startsWith("agent-"));
|
|
1357
|
-
const fileMtimes = /* @__PURE__ */ new Map();
|
|
1358
|
-
yield* Effect.all(
|
|
1359
|
-
sessionFiles.map(
|
|
1360
|
-
(file) => Effect.gen(function* () {
|
|
1361
|
-
const filePath = path5.join(projectPath, file);
|
|
1362
|
-
try {
|
|
1363
|
-
const stat4 = yield* Effect.tryPromise(() => fs6.stat(filePath));
|
|
1364
|
-
fileMtimes.set(file.replace(".jsonl", ""), stat4.mtimeMs);
|
|
1365
|
-
} catch {
|
|
1366
|
-
}
|
|
1367
|
-
})
|
|
1368
|
-
),
|
|
1369
|
-
{ concurrency: 20 }
|
|
1370
|
-
);
|
|
1416
|
+
var buildPhase1 = (projectPath, allJsonlFiles) => Effect.gen(function* () {
|
|
1371
1417
|
const globalUuidMap = /* @__PURE__ */ new Map();
|
|
1372
1418
|
const allSummaries = [];
|
|
1373
|
-
const allJsonlFiles = files.filter((f) => f.endsWith(".jsonl"));
|
|
1374
1419
|
yield* Effect.all(
|
|
1375
1420
|
allJsonlFiles.map(
|
|
1376
1421
|
(file) => Effect.gen(function* () {
|
|
@@ -1409,6 +1454,9 @@ var loadProjectTreeData = (projectName, sortOptions) => Effect.gen(function* ()
|
|
|
1409
1454
|
),
|
|
1410
1455
|
{ concurrency: 20 }
|
|
1411
1456
|
);
|
|
1457
|
+
return { globalUuidMap, allSummaries };
|
|
1458
|
+
});
|
|
1459
|
+
var buildSummariesByTargetSession = (globalUuidMap, allSummaries) => {
|
|
1412
1460
|
const summariesByTargetSession = /* @__PURE__ */ new Map();
|
|
1413
1461
|
for (const summaryData of allSummaries) {
|
|
1414
1462
|
if (summaryData.leafUuid) {
|
|
@@ -1421,21 +1469,22 @@ var loadProjectTreeData = (projectName, sortOptions) => Effect.gen(function* ()
|
|
|
1421
1469
|
summariesByTargetSession.get(targetSessionId).push({
|
|
1422
1470
|
summary: summaryData.summary,
|
|
1423
1471
|
leafUuid: summaryData.leafUuid,
|
|
1424
|
-
// Use summary's own timestamp for sorting, not the target message's timestamp
|
|
1425
1472
|
timestamp: summaryData.timestamp ?? targetInfo.timestamp,
|
|
1426
1473
|
sourceFile: summaryData.sourceFile
|
|
1427
1474
|
});
|
|
1428
1475
|
}
|
|
1429
1476
|
}
|
|
1430
1477
|
}
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
);
|
|
1478
|
+
return summariesByTargetSession;
|
|
1479
|
+
};
|
|
1480
|
+
var sortSummaries = (summaries) => {
|
|
1481
|
+
return [...summaries].sort((a, b) => {
|
|
1482
|
+
const timestampCmp = (a.timestamp ?? "").localeCompare(b.timestamp ?? "");
|
|
1483
|
+
if (timestampCmp !== 0) return timestampCmp;
|
|
1484
|
+
return (b.sourceFile ?? "").localeCompare(a.sourceFile ?? "");
|
|
1485
|
+
});
|
|
1486
|
+
};
|
|
1487
|
+
var buildProjectTreeResult = (project, sessions, sort) => {
|
|
1439
1488
|
const sortedSessions = sortSessions(sessions, sort);
|
|
1440
1489
|
const filteredSessions = sortedSessions.filter((s) => {
|
|
1441
1490
|
if (isErrorSessionTitle(s.title)) return false;
|
|
@@ -1450,6 +1499,159 @@ var loadProjectTreeData = (projectName, sortOptions) => Effect.gen(function* ()
|
|
|
1450
1499
|
sessionCount: filteredSessions.length,
|
|
1451
1500
|
sessions: filteredSessions
|
|
1452
1501
|
};
|
|
1502
|
+
};
|
|
1503
|
+
var buildTreeCache = (globalUuidMap, allSummaries, sessions, fileMtimes) => {
|
|
1504
|
+
const uuidMapRecord = {};
|
|
1505
|
+
for (const [key, val] of globalUuidMap) {
|
|
1506
|
+
uuidMapRecord[key] = val;
|
|
1507
|
+
}
|
|
1508
|
+
const sessionsRecord = {};
|
|
1509
|
+
for (const s of sessions) {
|
|
1510
|
+
sessionsRecord[s.id] = {
|
|
1511
|
+
fileMtime: fileMtimes.get(s.id) ?? 0,
|
|
1512
|
+
data: s
|
|
1513
|
+
};
|
|
1514
|
+
}
|
|
1515
|
+
return {
|
|
1516
|
+
version: 1,
|
|
1517
|
+
globalUuidMap: uuidMapRecord,
|
|
1518
|
+
allSummaries,
|
|
1519
|
+
sessions: sessionsRecord
|
|
1520
|
+
};
|
|
1521
|
+
};
|
|
1522
|
+
var updateSessionSummaries = (cached, summariesByTargetSession) => {
|
|
1523
|
+
const newSummaries = sortSummaries(summariesByTargetSession.get(cached.id) ?? []);
|
|
1524
|
+
const oldJson = JSON.stringify(cached.summaries);
|
|
1525
|
+
const newJson = JSON.stringify(newSummaries);
|
|
1526
|
+
if (oldJson === newJson) return cached;
|
|
1527
|
+
const newSortTimestamp = getSessionSortTimestamp({
|
|
1528
|
+
summaries: newSummaries,
|
|
1529
|
+
createdAt: cached.createdAt
|
|
1530
|
+
});
|
|
1531
|
+
return {
|
|
1532
|
+
...cached,
|
|
1533
|
+
summaries: newSummaries,
|
|
1534
|
+
currentSummary: newSummaries[0]?.summary,
|
|
1535
|
+
sortTimestamp: newSortTimestamp
|
|
1536
|
+
};
|
|
1537
|
+
};
|
|
1538
|
+
var loadProjectTreeData = (projectName, sortOptions) => Effect.gen(function* () {
|
|
1539
|
+
const projectPath = path5.join(getSessionsDir(), projectName);
|
|
1540
|
+
const exists = yield* Effect.tryPromise(
|
|
1541
|
+
() => fs6.access(projectPath).then(() => true).catch(() => false)
|
|
1542
|
+
);
|
|
1543
|
+
if (!exists) return null;
|
|
1544
|
+
const displayName = yield* Effect.tryPromise(() => folderNameToPath(projectName));
|
|
1545
|
+
const project = { name: projectName, displayName, path: projectPath };
|
|
1546
|
+
const sort = sortOptions ?? DEFAULT_SORT;
|
|
1547
|
+
const files = yield* Effect.tryPromise(() => fs6.readdir(projectPath));
|
|
1548
|
+
const sessionFiles = files.filter((f) => f.endsWith(".jsonl") && !f.startsWith("agent-"));
|
|
1549
|
+
const sessionFileIds = sessionFiles.map((f) => f.replace(".jsonl", ""));
|
|
1550
|
+
const fileMtimes = /* @__PURE__ */ new Map();
|
|
1551
|
+
yield* Effect.all(
|
|
1552
|
+
sessionFiles.map(
|
|
1553
|
+
(file) => Effect.gen(function* () {
|
|
1554
|
+
const filePath = path5.join(projectPath, file);
|
|
1555
|
+
try {
|
|
1556
|
+
const stat4 = yield* Effect.tryPromise(() => fs6.stat(filePath));
|
|
1557
|
+
fileMtimes.set(file.replace(".jsonl", ""), stat4.mtimeMs);
|
|
1558
|
+
} catch {
|
|
1559
|
+
}
|
|
1560
|
+
})
|
|
1561
|
+
),
|
|
1562
|
+
{ concurrency: 20 }
|
|
1563
|
+
);
|
|
1564
|
+
const cache = yield* Effect.tryPromise(() => loadTreeCache(projectName));
|
|
1565
|
+
if (cache) {
|
|
1566
|
+
const validation = validateCache(cache, sessionFileIds, fileMtimes);
|
|
1567
|
+
if (validation.isFullHit) {
|
|
1568
|
+
log3.debug(`cache hit for ${projectName} (${sessionFileIds.length} sessions)`);
|
|
1569
|
+
const sessions = sessionFileIds.map((id) => cache.sessions[id]?.data).filter((s) => s != null);
|
|
1570
|
+
return buildProjectTreeResult(project, sessions, sort);
|
|
1571
|
+
}
|
|
1572
|
+
const changedCount = validation.changedSessionIds.length + validation.newSessionIds.length + validation.deletedSessionIds.length;
|
|
1573
|
+
log3.debug(
|
|
1574
|
+
`cache partial miss for ${projectName}: ${validation.changedSessionIds.length} changed, ${validation.newSessionIds.length} new, ${validation.deletedSessionIds.length} deleted, ${validation.unchangedSessionIds.length} unchanged`
|
|
1575
|
+
);
|
|
1576
|
+
if (changedCount <= sessionFileIds.length / 2) {
|
|
1577
|
+
const result = yield* loadProjectTreeDataIncremental(
|
|
1578
|
+
projectName,
|
|
1579
|
+
projectPath,
|
|
1580
|
+
files,
|
|
1581
|
+
sessionFiles,
|
|
1582
|
+
fileMtimes,
|
|
1583
|
+
cache,
|
|
1584
|
+
validation,
|
|
1585
|
+
project,
|
|
1586
|
+
sort
|
|
1587
|
+
);
|
|
1588
|
+
return result;
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
log3.debug(`full load for ${projectName} (${sessionFileIds.length} sessions)`);
|
|
1592
|
+
return yield* loadProjectTreeDataFull(
|
|
1593
|
+
projectName,
|
|
1594
|
+
projectPath,
|
|
1595
|
+
files,
|
|
1596
|
+
sessionFiles,
|
|
1597
|
+
fileMtimes,
|
|
1598
|
+
project,
|
|
1599
|
+
sort
|
|
1600
|
+
);
|
|
1601
|
+
});
|
|
1602
|
+
var loadProjectTreeDataFull = (projectName, projectPath, files, sessionFiles, fileMtimes, project, sort) => Effect.gen(function* () {
|
|
1603
|
+
const allJsonlFiles = files.filter((f) => f.endsWith(".jsonl"));
|
|
1604
|
+
const { globalUuidMap, allSummaries } = yield* buildPhase1(projectPath, allJsonlFiles);
|
|
1605
|
+
const summariesByTargetSession = buildSummariesByTargetSession(globalUuidMap, allSummaries);
|
|
1606
|
+
const sessions = yield* Effect.all(
|
|
1607
|
+
sessionFiles.map((file) => {
|
|
1608
|
+
const sessionId = file.replace(".jsonl", "");
|
|
1609
|
+
const mtime = fileMtimes.get(sessionId);
|
|
1610
|
+
return loadSessionTreeDataInternal(projectName, sessionId, summariesByTargetSession, mtime);
|
|
1611
|
+
}),
|
|
1612
|
+
{ concurrency: 10 }
|
|
1613
|
+
);
|
|
1614
|
+
const cacheData = buildTreeCache(globalUuidMap, allSummaries, sessions, fileMtimes);
|
|
1615
|
+
writeTreeCache(projectName, cacheData).catch((err) => {
|
|
1616
|
+
log3.debug(`cache write failed for ${projectName}: ${err}`);
|
|
1617
|
+
});
|
|
1618
|
+
return buildProjectTreeResult(project, sessions, sort);
|
|
1619
|
+
});
|
|
1620
|
+
var loadProjectTreeDataIncremental = (projectName, projectPath, files, sessionFiles, fileMtimes, cache, validation, project, sort) => Effect.gen(function* () {
|
|
1621
|
+
const allJsonlFiles = files.filter((f) => f.endsWith(".jsonl"));
|
|
1622
|
+
const { globalUuidMap, allSummaries } = yield* buildPhase1(projectPath, allJsonlFiles);
|
|
1623
|
+
const summariesByTargetSession = buildSummariesByTargetSession(globalUuidMap, allSummaries);
|
|
1624
|
+
const sessionsToLoad = [...validation.changedSessionIds, ...validation.newSessionIds];
|
|
1625
|
+
const loadedSessions = yield* Effect.all(
|
|
1626
|
+
sessionsToLoad.map((sessionId) => {
|
|
1627
|
+
const mtime = fileMtimes.get(sessionId);
|
|
1628
|
+
return loadSessionTreeDataInternal(projectName, sessionId, summariesByTargetSession, mtime);
|
|
1629
|
+
}),
|
|
1630
|
+
{ concurrency: 10 }
|
|
1631
|
+
);
|
|
1632
|
+
const loadedMap = /* @__PURE__ */ new Map();
|
|
1633
|
+
for (const s of loadedSessions) {
|
|
1634
|
+
loadedMap.set(s.id, s);
|
|
1635
|
+
}
|
|
1636
|
+
const allSessions = [];
|
|
1637
|
+
for (const file of sessionFiles) {
|
|
1638
|
+
const sessionId = file.replace(".jsonl", "");
|
|
1639
|
+
const loaded = loadedMap.get(sessionId);
|
|
1640
|
+
if (loaded) {
|
|
1641
|
+
allSessions.push(loaded);
|
|
1642
|
+
} else if (cache.sessions[sessionId]) {
|
|
1643
|
+
const updated = updateSessionSummaries(
|
|
1644
|
+
cache.sessions[sessionId].data,
|
|
1645
|
+
summariesByTargetSession
|
|
1646
|
+
);
|
|
1647
|
+
allSessions.push({ ...updated, fileMtime: fileMtimes.get(sessionId) });
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1650
|
+
const cacheData = buildTreeCache(globalUuidMap, allSummaries, allSessions, fileMtimes);
|
|
1651
|
+
writeTreeCache(projectName, cacheData).catch((err) => {
|
|
1652
|
+
log3.debug(`cache write failed for ${projectName}: ${err}`);
|
|
1653
|
+
});
|
|
1654
|
+
return buildProjectTreeResult(project, allSessions, sort);
|
|
1453
1655
|
});
|
|
1454
1656
|
var cleanInvalidMessages = (projectName, sessionId) => Effect.gen(function* () {
|
|
1455
1657
|
const filePath = path5.join(getSessionsDir(), projectName, `${sessionId}.jsonl`);
|
|
@@ -1752,4 +1954,4 @@ var getSessionFiles = (projectName, sessionId) => Effect.gen(function* () {
|
|
|
1752
1954
|
});
|
|
1753
1955
|
|
|
1754
1956
|
export { sessionHasSubItems as A, getSessionTooltip as B, validateProgressMessages as C, parseCommandMessage as D, deleteMessageWithChainRepair as E, maskHomePath as F, TREE_ICONS as T, listProjects as a, loadProjectTreeData as b, clearSessions as c, deleteMessage as d, listSessions as e, deleteSession as f, readSession as g, getLogger as h, getSessionFiles as i, renameSession as j, getSessionsDir as k, loadAgentMessages as l, moveSession as m, autoRepairChain as n, folderNameToPath as o, previewCleanup as p, expandHomePath as q, restoreMessage as r, searchSessions as s, splitSession as t, loadSessionTreeData as u, validateChain as v, pathToFolderName as w, sortProjects as x, getTotalTodoCount as y, getDisplayTitle as z };
|
|
1755
|
-
//# sourceMappingURL=
|
|
1957
|
+
//# sourceMappingURL=index2-BbHYMsUG.js.map
|