claude-sessions-mcp 0.1.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.
Files changed (92) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +145 -0
  3. package/dist/chunk-D2SPLCNE.js +48 -0
  4. package/dist/chunk-D2SPLCNE.js.map +1 -0
  5. package/dist/mcp/index.d.ts +1 -0
  6. package/dist/mcp/index.js +369 -0
  7. package/dist/mcp/index.js.map +1 -0
  8. package/dist/server.d.ts +10 -0
  9. package/dist/server.js +9 -0
  10. package/dist/server.js.map +1 -0
  11. package/dist/web/client/_app/immutable/assets/0.BNKw18IQ.css +1 -0
  12. package/dist/web/client/_app/immutable/assets/0.BNKw18IQ.css.br +0 -0
  13. package/dist/web/client/_app/immutable/assets/0.BNKw18IQ.css.gz +0 -0
  14. package/dist/web/client/_app/immutable/chunks/9luERNGW.js +1 -0
  15. package/dist/web/client/_app/immutable/chunks/9luERNGW.js.br +0 -0
  16. package/dist/web/client/_app/immutable/chunks/9luERNGW.js.gz +0 -0
  17. package/dist/web/client/_app/immutable/chunks/B4TJWzDE.js +1 -0
  18. package/dist/web/client/_app/immutable/chunks/B4TJWzDE.js.br +0 -0
  19. package/dist/web/client/_app/immutable/chunks/B4TJWzDE.js.gz +0 -0
  20. package/dist/web/client/_app/immutable/chunks/ChOgyrGO.js +2 -0
  21. package/dist/web/client/_app/immutable/chunks/ChOgyrGO.js.br +0 -0
  22. package/dist/web/client/_app/immutable/chunks/ChOgyrGO.js.gz +0 -0
  23. package/dist/web/client/_app/immutable/chunks/DUFLAPco.js +1 -0
  24. package/dist/web/client/_app/immutable/chunks/DUFLAPco.js.br +0 -0
  25. package/dist/web/client/_app/immutable/chunks/DUFLAPco.js.gz +0 -0
  26. package/dist/web/client/_app/immutable/chunks/DbCO4Be8.js +1 -0
  27. package/dist/web/client/_app/immutable/chunks/DbCO4Be8.js.br +1 -0
  28. package/dist/web/client/_app/immutable/chunks/DbCO4Be8.js.gz +0 -0
  29. package/dist/web/client/_app/immutable/entry/app.CQAI9q_h.js +2 -0
  30. package/dist/web/client/_app/immutable/entry/app.CQAI9q_h.js.br +0 -0
  31. package/dist/web/client/_app/immutable/entry/app.CQAI9q_h.js.gz +0 -0
  32. package/dist/web/client/_app/immutable/entry/start.lvsJ5TiJ.js +1 -0
  33. package/dist/web/client/_app/immutable/entry/start.lvsJ5TiJ.js.br +2 -0
  34. package/dist/web/client/_app/immutable/entry/start.lvsJ5TiJ.js.gz +0 -0
  35. package/dist/web/client/_app/immutable/nodes/0.Cd8eOV9t.js +1 -0
  36. package/dist/web/client/_app/immutable/nodes/0.Cd8eOV9t.js.br +0 -0
  37. package/dist/web/client/_app/immutable/nodes/0.Cd8eOV9t.js.gz +0 -0
  38. package/dist/web/client/_app/immutable/nodes/1.DVVhj1K8.js +1 -0
  39. package/dist/web/client/_app/immutable/nodes/1.DVVhj1K8.js.br +0 -0
  40. package/dist/web/client/_app/immutable/nodes/1.DVVhj1K8.js.gz +0 -0
  41. package/dist/web/client/_app/immutable/nodes/2.DqJoUS41.js +1 -0
  42. package/dist/web/client/_app/immutable/nodes/2.DqJoUS41.js.br +0 -0
  43. package/dist/web/client/_app/immutable/nodes/2.DqJoUS41.js.gz +0 -0
  44. package/dist/web/client/_app/version.json +1 -0
  45. package/dist/web/client/_app/version.json.br +0 -0
  46. package/dist/web/client/_app/version.json.gz +0 -0
  47. package/dist/web/client/favicon.png +0 -0
  48. package/dist/web/env.js +45 -0
  49. package/dist/web/handler.js +1390 -0
  50. package/dist/web/index.js +334 -0
  51. package/dist/web/server/chunks/0-D_Gx_HFy.js +17 -0
  52. package/dist/web/server/chunks/0-D_Gx_HFy.js.map +1 -0
  53. package/dist/web/server/chunks/1-B6558drr.js +9 -0
  54. package/dist/web/server/chunks/1-B6558drr.js.map +1 -0
  55. package/dist/web/server/chunks/2-Bx262N6m.js +9 -0
  56. package/dist/web/server/chunks/2-Bx262N6m.js.map +1 -0
  57. package/dist/web/server/chunks/_layout.svelte-Dqh3cdpb.js +28 -0
  58. package/dist/web/server/chunks/_layout.svelte-Dqh3cdpb.js.map +1 -0
  59. package/dist/web/server/chunks/_page.svelte-BzYm1sb_.js +65 -0
  60. package/dist/web/server/chunks/_page.svelte-BzYm1sb_.js.map +1 -0
  61. package/dist/web/server/chunks/_server.ts-BXCTPhzX.js +28 -0
  62. package/dist/web/server/chunks/_server.ts-BXCTPhzX.js.map +1 -0
  63. package/dist/web/server/chunks/_server.ts-Bxqo8tYS.js +14 -0
  64. package/dist/web/server/chunks/_server.ts-Bxqo8tYS.js.map +1 -0
  65. package/dist/web/server/chunks/_server.ts-C5Bf6au4.js +26 -0
  66. package/dist/web/server/chunks/_server.ts-C5Bf6au4.js.map +1 -0
  67. package/dist/web/server/chunks/_server.ts-C88EFL4g.js +19 -0
  68. package/dist/web/server/chunks/_server.ts-C88EFL4g.js.map +1 -0
  69. package/dist/web/server/chunks/_server.ts-D8vMV9FN.js +18 -0
  70. package/dist/web/server/chunks/_server.ts-D8vMV9FN.js.map +1 -0
  71. package/dist/web/server/chunks/_server.ts-DW3OhHzP.js +37 -0
  72. package/dist/web/server/chunks/_server.ts-DW3OhHzP.js.map +1 -0
  73. package/dist/web/server/chunks/_server.ts-Ne8LE0dr.js +18 -0
  74. package/dist/web/server/chunks/_server.ts-Ne8LE0dr.js.map +1 -0
  75. package/dist/web/server/chunks/context-R2425nfV.js +64 -0
  76. package/dist/web/server/chunks/context-R2425nfV.js.map +1 -0
  77. package/dist/web/server/chunks/error.svelte-DazOwnSn.js +45 -0
  78. package/dist/web/server/chunks/error.svelte-DazOwnSn.js.map +1 -0
  79. package/dist/web/server/chunks/exports-BzHwARwz.js +326 -0
  80. package/dist/web/server/chunks/exports-BzHwARwz.js.map +1 -0
  81. package/dist/web/server/chunks/index-CXFDTUAl.js +913 -0
  82. package/dist/web/server/chunks/index-CXFDTUAl.js.map +1 -0
  83. package/dist/web/server/chunks/index-CoD1IJuy.js +190 -0
  84. package/dist/web/server/chunks/index-CoD1IJuy.js.map +1 -0
  85. package/dist/web/server/chunks/session-ioLIuaZI.js +302 -0
  86. package/dist/web/server/chunks/session-ioLIuaZI.js.map +1 -0
  87. package/dist/web/server/index.js +8132 -0
  88. package/dist/web/server/index.js.map +1 -0
  89. package/dist/web/server/manifest.js +95 -0
  90. package/dist/web/server/manifest.js.map +1 -0
  91. package/dist/web/shims.js +32 -0
  92. package/package.json +94 -0
@@ -0,0 +1,302 @@
1
+ import { Effect, pipe, Array as Array$1, Option } from 'effect';
2
+ import * as fs from 'node:fs/promises';
3
+ import * as path from 'node:path';
4
+ import * as os from 'node:os';
5
+
6
+ const getSessionsDir = () => path.join(os.homedir(), ".claude", "projects");
7
+ const extractTextContent = (message) => {
8
+ if (!message) return "";
9
+ const content = message.content;
10
+ if (!content) return "";
11
+ if (typeof content === "string") return content;
12
+ if (Array.isArray(content)) {
13
+ return content.filter((item) => typeof item === "object" && item?.type === "text").map((item) => item.text ?? "").join("");
14
+ }
15
+ return "";
16
+ };
17
+ const extractTitle = (text) => {
18
+ if (!text) return "Untitled";
19
+ let cleaned = text.replace(/<ide_[^>]*>[\s\S]*?<\/ide_[^>]*>/g, "").trim();
20
+ if (!cleaned) return "Untitled";
21
+ if (cleaned.includes("\n\n")) {
22
+ cleaned = cleaned.split("\n\n")[0];
23
+ } else if (cleaned.includes("\n")) {
24
+ cleaned = cleaned.split("\n")[0];
25
+ }
26
+ if (cleaned.length > 100) {
27
+ return cleaned.slice(0, 100) + "...";
28
+ }
29
+ return cleaned || "Untitled";
30
+ };
31
+ const listProjects = Effect.gen(function* () {
32
+ const sessionsDir = getSessionsDir();
33
+ const exists = yield* Effect.tryPromise(
34
+ () => fs.access(sessionsDir).then(() => true).catch(() => false)
35
+ );
36
+ if (!exists) {
37
+ return [];
38
+ }
39
+ const entries = yield* Effect.tryPromise(() => fs.readdir(sessionsDir, { withFileTypes: true }));
40
+ const projects = yield* Effect.all(
41
+ entries.filter((e) => e.isDirectory() && !e.name.startsWith(".")).map(
42
+ (entry) => Effect.gen(function* () {
43
+ const projectPath = path.join(sessionsDir, entry.name);
44
+ const files = yield* Effect.tryPromise(() => fs.readdir(projectPath));
45
+ const sessionFiles = files.filter((f) => f.endsWith(".jsonl") && !f.startsWith("agent-"));
46
+ const displayName = entry.name.replace(/^-/, "/").replace(/--/g, "/.").replace(/-/g, "/");
47
+ return {
48
+ name: entry.name,
49
+ display_name: displayName,
50
+ path: projectPath,
51
+ sessionCount: sessionFiles.length
52
+ };
53
+ })
54
+ ),
55
+ { concurrency: 10 }
56
+ );
57
+ return projects;
58
+ });
59
+ const listSessions = (projectName) => Effect.gen(function* () {
60
+ const projectPath = path.join(getSessionsDir(), projectName);
61
+ const files = yield* Effect.tryPromise(() => fs.readdir(projectPath));
62
+ const sessionFiles = files.filter((f) => f.endsWith(".jsonl") && !f.startsWith("agent-"));
63
+ const sessions = yield* Effect.all(
64
+ sessionFiles.map(
65
+ (file) => Effect.gen(function* () {
66
+ const filePath = path.join(projectPath, file);
67
+ const content = yield* Effect.tryPromise(() => fs.readFile(filePath, "utf-8"));
68
+ const lines = content.trim().split("\n").filter(Boolean);
69
+ const messages = lines.map((line) => JSON.parse(line));
70
+ const sessionId = file.replace(".jsonl", "");
71
+ const userAssistantMessages = messages.filter(
72
+ (m) => m.type === "user" || m.type === "assistant"
73
+ );
74
+ const firstMessage = userAssistantMessages[0];
75
+ const lastMessage = userAssistantMessages[userAssistantMessages.length - 1];
76
+ const title = pipe(
77
+ messages,
78
+ Array$1.findFirst((m) => m.type === "user"),
79
+ Option.map((m) => {
80
+ const text = extractTextContent(m.message);
81
+ return extractTitle(text);
82
+ }),
83
+ Option.getOrElse(() => `Session ${sessionId.slice(0, 8)}`)
84
+ );
85
+ return {
86
+ id: sessionId,
87
+ projectName,
88
+ title,
89
+ messageCount: userAssistantMessages.length,
90
+ createdAt: firstMessage?.timestamp,
91
+ updatedAt: lastMessage?.timestamp
92
+ };
93
+ })
94
+ ),
95
+ { concurrency: 10 }
96
+ );
97
+ return sessions.sort((a, b) => {
98
+ const dateA = a.updatedAt ? new Date(a.updatedAt).getTime() : 0;
99
+ const dateB = b.updatedAt ? new Date(b.updatedAt).getTime() : 0;
100
+ return dateB - dateA;
101
+ });
102
+ });
103
+ const readSession = (projectName, sessionId) => Effect.gen(function* () {
104
+ const filePath = path.join(getSessionsDir(), projectName, `${sessionId}.jsonl`);
105
+ const content = yield* Effect.tryPromise(() => fs.readFile(filePath, "utf-8"));
106
+ const lines = content.trim().split("\n").filter(Boolean);
107
+ return lines.map((line) => JSON.parse(line));
108
+ });
109
+ const deleteSession = (projectName, sessionId) => Effect.gen(function* () {
110
+ const sessionsDir = getSessionsDir();
111
+ const filePath = path.join(sessionsDir, projectName, `${sessionId}.jsonl`);
112
+ const stat = yield* Effect.tryPromise(() => fs.stat(filePath));
113
+ if (stat.size === 0) {
114
+ yield* Effect.tryPromise(() => fs.unlink(filePath));
115
+ return { success: true };
116
+ }
117
+ const backupDir = path.join(sessionsDir, ".bak");
118
+ yield* Effect.tryPromise(() => fs.mkdir(backupDir, { recursive: true }));
119
+ const backupPath = path.join(backupDir, `${projectName}_${sessionId}.jsonl`);
120
+ yield* Effect.tryPromise(() => fs.rename(filePath, backupPath));
121
+ return { success: true, backupPath };
122
+ });
123
+ const renameSession = (projectName, sessionId, newTitle) => Effect.gen(function* () {
124
+ const filePath = path.join(getSessionsDir(), projectName, `${sessionId}.jsonl`);
125
+ const content = yield* Effect.tryPromise(() => fs.readFile(filePath, "utf-8"));
126
+ const lines = content.trim().split("\n").filter(Boolean);
127
+ if (lines.length === 0) {
128
+ return { success: false, error: "Empty session" };
129
+ }
130
+ const messages = lines.map((line) => JSON.parse(line));
131
+ const firstUserIdx = messages.findIndex((m) => m.type === "user");
132
+ if (firstUserIdx === -1) {
133
+ return { success: false, error: "No user message found" };
134
+ }
135
+ const firstMsg = messages[firstUserIdx];
136
+ if (firstMsg?.message?.content && Array.isArray(firstMsg.message.content)) {
137
+ const textIdx = firstMsg.message.content.findIndex(
138
+ (item) => typeof item === "object" && item?.type === "text" && !item.text?.trim().startsWith("<ide_")
139
+ );
140
+ if (textIdx >= 0) {
141
+ const item = firstMsg.message.content[textIdx];
142
+ const oldText = item.text ?? "";
143
+ const cleanedText = oldText.replace(/^[^\n]+\n\n/, "");
144
+ item.text = `${newTitle}
145
+
146
+ ${cleanedText}`;
147
+ }
148
+ }
149
+ const newContent = messages.map((m) => JSON.stringify(m)).join("\n") + "\n";
150
+ yield* Effect.tryPromise(() => fs.writeFile(filePath, newContent, "utf-8"));
151
+ return { success: true };
152
+ });
153
+ const updateCustomTitle = (projectName, sessionId, messageUuid, newTitle) => Effect.gen(function* () {
154
+ const filePath = path.join(getSessionsDir(), projectName, `${sessionId}.jsonl`);
155
+ const content = yield* Effect.tryPromise(() => fs.readFile(filePath, "utf-8"));
156
+ const lines = content.trim().split("\n").filter(Boolean);
157
+ const messages = lines.map((line) => JSON.parse(line));
158
+ const targetIndex = messages.findIndex((m) => m.uuid === messageUuid);
159
+ if (targetIndex === -1) {
160
+ return { success: false, error: "Message not found" };
161
+ }
162
+ const msg = messages[targetIndex];
163
+ if (msg.type !== "custom-title") {
164
+ return { success: false, error: "Message is not a custom-title type" };
165
+ }
166
+ msg.customTitle = newTitle;
167
+ const newContent = messages.map((m) => JSON.stringify(m)).join("\n") + "\n";
168
+ yield* Effect.tryPromise(() => fs.writeFile(filePath, newContent, "utf-8"));
169
+ return { success: true };
170
+ });
171
+ const deleteMessage = (projectName, sessionId, messageUuid) => Effect.gen(function* () {
172
+ const filePath = path.join(getSessionsDir(), projectName, `${sessionId}.jsonl`);
173
+ const content = yield* Effect.tryPromise(() => fs.readFile(filePath, "utf-8"));
174
+ const lines = content.trim().split("\n").filter(Boolean);
175
+ const messages = lines.map((line) => JSON.parse(line));
176
+ const targetIndex = messages.findIndex((m) => m.uuid === messageUuid);
177
+ if (targetIndex === -1) {
178
+ return { success: false, error: "Message not found" };
179
+ }
180
+ const deletedMsg = messages[targetIndex];
181
+ const parentUuid = deletedMsg?.parentUuid;
182
+ const nextMsg = messages[targetIndex + 1];
183
+ if (nextMsg) {
184
+ nextMsg.parentUuid = parentUuid;
185
+ }
186
+ messages.splice(targetIndex, 1);
187
+ const newContent = messages.map((m) => JSON.stringify(m)).join("\n") + "\n";
188
+ yield* Effect.tryPromise(() => fs.writeFile(filePath, newContent, "utf-8"));
189
+ return { success: true };
190
+ });
191
+ const previewCleanup = (projectName) => Effect.gen(function* () {
192
+ const projects = yield* listProjects;
193
+ const targetProjects = projectName ? projects.filter((p) => p.name === projectName) : projects;
194
+ const results = yield* Effect.all(
195
+ targetProjects.map(
196
+ (project) => Effect.gen(function* () {
197
+ const sessions = yield* listSessions(project.name);
198
+ const emptySessions = sessions.filter((s) => s.messageCount === 0);
199
+ const invalidSessions = sessions.filter(
200
+ (s) => s.title?.includes("Invalid API key") || s.title?.includes("API key")
201
+ );
202
+ return {
203
+ project: project.name,
204
+ emptySessions,
205
+ invalidSessions
206
+ };
207
+ })
208
+ ),
209
+ { concurrency: 5 }
210
+ );
211
+ return results;
212
+ });
213
+ const isInvalidApiKeyMessage = (msg) => {
214
+ const text = extractTextContent(msg.message);
215
+ return text.includes("Invalid API key");
216
+ };
217
+ const cleanInvalidMessages = (projectName, sessionId) => Effect.gen(function* () {
218
+ const filePath = path.join(getSessionsDir(), projectName, `${sessionId}.jsonl`);
219
+ const content = yield* Effect.tryPromise(() => fs.readFile(filePath, "utf-8"));
220
+ const lines = content.trim().split("\n").filter(Boolean);
221
+ if (lines.length === 0) return { removedCount: 0, remainingCount: 0 };
222
+ const messages = lines.map((line) => JSON.parse(line));
223
+ const invalidIndices = [];
224
+ messages.forEach((msg, idx) => {
225
+ if (isInvalidApiKeyMessage(msg)) {
226
+ invalidIndices.push(idx);
227
+ }
228
+ });
229
+ if (invalidIndices.length === 0) {
230
+ const userAssistantCount = messages.filter(
231
+ (m) => m.type === "user" || m.type === "assistant"
232
+ ).length;
233
+ return { removedCount: 0, remainingCount: userAssistantCount };
234
+ }
235
+ const filtered = [];
236
+ let lastValidUuid = null;
237
+ for (let i = 0; i < messages.length; i++) {
238
+ if (invalidIndices.includes(i)) {
239
+ continue;
240
+ }
241
+ const msg = messages[i];
242
+ if (msg.parentUuid && invalidIndices.some((idx) => messages[idx]?.uuid === msg.parentUuid)) {
243
+ msg.parentUuid = lastValidUuid;
244
+ }
245
+ filtered.push(msg);
246
+ lastValidUuid = msg.uuid;
247
+ }
248
+ const newContent = filtered.length > 0 ? filtered.map((m) => JSON.stringify(m)).join("\n") + "\n" : "";
249
+ yield* Effect.tryPromise(() => fs.writeFile(filePath, newContent, "utf-8"));
250
+ const remainingUserAssistant = filtered.filter(
251
+ (m) => m.type === "user" || m.type === "assistant"
252
+ ).length;
253
+ return { removedCount: invalidIndices.length, remainingCount: remainingUserAssistant };
254
+ });
255
+ const clearSessions = (options) => Effect.gen(function* () {
256
+ const { projectName, clearEmpty = true } = options;
257
+ const projects = yield* listProjects;
258
+ const targetProjects = projectName ? projects.filter((p) => p.name === projectName) : projects;
259
+ let deletedSessionCount = 0;
260
+ let removedMessageCount = 0;
261
+ const sessionsToDelete = [];
262
+ for (const project of targetProjects) {
263
+ const projectPath = path.join(getSessionsDir(), project.name);
264
+ const files = yield* Effect.tryPromise(() => fs.readdir(projectPath));
265
+ const sessionFiles = files.filter((f) => f.endsWith(".jsonl") && !f.startsWith("agent-"));
266
+ for (const file of sessionFiles) {
267
+ const sessionId = file.replace(".jsonl", "");
268
+ const result = yield* cleanInvalidMessages(project.name, sessionId);
269
+ removedMessageCount += result.removedCount;
270
+ if (result.remainingCount === 0) {
271
+ sessionsToDelete.push({ project: project.name, sessionId });
272
+ }
273
+ }
274
+ }
275
+ if (clearEmpty) {
276
+ for (const project of targetProjects) {
277
+ const sessions = yield* listSessions(project.name);
278
+ for (const session of sessions) {
279
+ if (session.messageCount === 0) {
280
+ const alreadyMarked = sessionsToDelete.some(
281
+ (s) => s.project === project.name && s.sessionId === session.id
282
+ );
283
+ if (!alreadyMarked) {
284
+ sessionsToDelete.push({ project: project.name, sessionId: session.id });
285
+ }
286
+ }
287
+ }
288
+ }
289
+ }
290
+ for (const { project, sessionId } of sessionsToDelete) {
291
+ yield* deleteSession(project, sessionId);
292
+ deletedSessionCount++;
293
+ }
294
+ return {
295
+ success: true,
296
+ deletedCount: deletedSessionCount,
297
+ removedMessageCount
298
+ };
299
+ });
300
+
301
+ export { listSessions as a, deleteSession as b, clearSessions as c, deleteMessage as d, renameSession as e, listProjects as l, previewCleanup as p, readSession as r, updateCustomTitle as u };
302
+ //# sourceMappingURL=session-ioLIuaZI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-ioLIuaZI.js","sources":["../../../../web/.svelte-kit/adapter-node/chunks/session.js"],"sourcesContent":["import { Effect, pipe, Array as Array$1, Option } from \"effect\";\nimport * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nconst getSessionsDir = () => path.join(os.homedir(), \".claude\", \"projects\");\nconst extractTextContent = (message) => {\n if (!message) return \"\";\n const content = message.content;\n if (!content) return \"\";\n if (typeof content === \"string\") return content;\n if (Array.isArray(content)) {\n return content.filter((item) => typeof item === \"object\" && item?.type === \"text\").map((item) => item.text ?? \"\").join(\"\");\n }\n return \"\";\n};\nconst extractTitle = (text) => {\n if (!text) return \"Untitled\";\n let cleaned = text.replace(/<ide_[^>]*>[\\s\\S]*?<\\/ide_[^>]*>/g, \"\").trim();\n if (!cleaned) return \"Untitled\";\n if (cleaned.includes(\"\\n\\n\")) {\n cleaned = cleaned.split(\"\\n\\n\")[0];\n } else if (cleaned.includes(\"\\n\")) {\n cleaned = cleaned.split(\"\\n\")[0];\n }\n if (cleaned.length > 100) {\n return cleaned.slice(0, 100) + \"...\";\n }\n return cleaned || \"Untitled\";\n};\nconst listProjects = Effect.gen(function* () {\n const sessionsDir = getSessionsDir();\n const exists = yield* Effect.tryPromise(\n () => fs.access(sessionsDir).then(() => true).catch(() => false)\n );\n if (!exists) {\n return [];\n }\n const entries = yield* Effect.tryPromise(() => fs.readdir(sessionsDir, { withFileTypes: true }));\n const projects = yield* Effect.all(\n entries.filter((e) => e.isDirectory() && !e.name.startsWith(\".\")).map(\n (entry) => Effect.gen(function* () {\n const projectPath = path.join(sessionsDir, entry.name);\n const files = yield* Effect.tryPromise(() => fs.readdir(projectPath));\n const sessionFiles = files.filter((f) => f.endsWith(\".jsonl\") && !f.startsWith(\"agent-\"));\n const displayName = entry.name.replace(/^-/, \"/\").replace(/--/g, \"/.\").replace(/-/g, \"/\");\n return {\n name: entry.name,\n display_name: displayName,\n path: projectPath,\n sessionCount: sessionFiles.length\n };\n })\n ),\n { concurrency: 10 }\n );\n return projects;\n});\nconst listSessions = (projectName) => Effect.gen(function* () {\n const projectPath = path.join(getSessionsDir(), projectName);\n const files = yield* Effect.tryPromise(() => fs.readdir(projectPath));\n const sessionFiles = files.filter((f) => f.endsWith(\".jsonl\") && !f.startsWith(\"agent-\"));\n const sessions = yield* Effect.all(\n sessionFiles.map(\n (file) => Effect.gen(function* () {\n const filePath = path.join(projectPath, file);\n const content = yield* Effect.tryPromise(() => fs.readFile(filePath, \"utf-8\"));\n const lines = content.trim().split(\"\\n\").filter(Boolean);\n const messages = lines.map((line) => JSON.parse(line));\n const sessionId = file.replace(\".jsonl\", \"\");\n const userAssistantMessages = messages.filter(\n (m) => m.type === \"user\" || m.type === \"assistant\"\n );\n const firstMessage = userAssistantMessages[0];\n const lastMessage = userAssistantMessages[userAssistantMessages.length - 1];\n const title = pipe(\n messages,\n Array$1.findFirst((m) => m.type === \"user\"),\n Option.map((m) => {\n const text = extractTextContent(m.message);\n return extractTitle(text);\n }),\n Option.getOrElse(() => `Session ${sessionId.slice(0, 8)}`)\n );\n return {\n id: sessionId,\n projectName,\n title,\n messageCount: userAssistantMessages.length,\n createdAt: firstMessage?.timestamp,\n updatedAt: lastMessage?.timestamp\n };\n })\n ),\n { concurrency: 10 }\n );\n return sessions.sort((a, b) => {\n const dateA = a.updatedAt ? new Date(a.updatedAt).getTime() : 0;\n const dateB = b.updatedAt ? new Date(b.updatedAt).getTime() : 0;\n return dateB - dateA;\n });\n});\nconst readSession = (projectName, sessionId) => Effect.gen(function* () {\n const filePath = path.join(getSessionsDir(), projectName, `${sessionId}.jsonl`);\n const content = yield* Effect.tryPromise(() => fs.readFile(filePath, \"utf-8\"));\n const lines = content.trim().split(\"\\n\").filter(Boolean);\n return lines.map((line) => JSON.parse(line));\n});\nconst deleteSession = (projectName, sessionId) => Effect.gen(function* () {\n const sessionsDir = getSessionsDir();\n const filePath = path.join(sessionsDir, projectName, `${sessionId}.jsonl`);\n const stat = yield* Effect.tryPromise(() => fs.stat(filePath));\n if (stat.size === 0) {\n yield* Effect.tryPromise(() => fs.unlink(filePath));\n return { success: true };\n }\n const backupDir = path.join(sessionsDir, \".bak\");\n yield* Effect.tryPromise(() => fs.mkdir(backupDir, { recursive: true }));\n const backupPath = path.join(backupDir, `${projectName}_${sessionId}.jsonl`);\n yield* Effect.tryPromise(() => fs.rename(filePath, backupPath));\n return { success: true, backupPath };\n});\nconst renameSession = (projectName, sessionId, newTitle) => Effect.gen(function* () {\n const filePath = path.join(getSessionsDir(), projectName, `${sessionId}.jsonl`);\n const content = yield* Effect.tryPromise(() => fs.readFile(filePath, \"utf-8\"));\n const lines = content.trim().split(\"\\n\").filter(Boolean);\n if (lines.length === 0) {\n return { success: false, error: \"Empty session\" };\n }\n const messages = lines.map((line) => JSON.parse(line));\n const firstUserIdx = messages.findIndex((m) => m.type === \"user\");\n if (firstUserIdx === -1) {\n return { success: false, error: \"No user message found\" };\n }\n const firstMsg = messages[firstUserIdx];\n if (firstMsg?.message?.content && Array.isArray(firstMsg.message.content)) {\n const textIdx = firstMsg.message.content.findIndex(\n (item) => typeof item === \"object\" && item?.type === \"text\" && !item.text?.trim().startsWith(\"<ide_\")\n );\n if (textIdx >= 0) {\n const item = firstMsg.message.content[textIdx];\n const oldText = item.text ?? \"\";\n const cleanedText = oldText.replace(/^[^\\n]+\\n\\n/, \"\");\n item.text = `${newTitle}\n\n${cleanedText}`;\n }\n }\n const newContent = messages.map((m) => JSON.stringify(m)).join(\"\\n\") + \"\\n\";\n yield* Effect.tryPromise(() => fs.writeFile(filePath, newContent, \"utf-8\"));\n return { success: true };\n});\nconst updateCustomTitle = (projectName, sessionId, messageUuid, newTitle) => Effect.gen(function* () {\n const filePath = path.join(getSessionsDir(), projectName, `${sessionId}.jsonl`);\n const content = yield* Effect.tryPromise(() => fs.readFile(filePath, \"utf-8\"));\n const lines = content.trim().split(\"\\n\").filter(Boolean);\n const messages = lines.map((line) => JSON.parse(line));\n const targetIndex = messages.findIndex((m) => m.uuid === messageUuid);\n if (targetIndex === -1) {\n return { success: false, error: \"Message not found\" };\n }\n const msg = messages[targetIndex];\n if (msg.type !== \"custom-title\") {\n return { success: false, error: \"Message is not a custom-title type\" };\n }\n msg.customTitle = newTitle;\n const newContent = messages.map((m) => JSON.stringify(m)).join(\"\\n\") + \"\\n\";\n yield* Effect.tryPromise(() => fs.writeFile(filePath, newContent, \"utf-8\"));\n return { success: true };\n});\nconst deleteMessage = (projectName, sessionId, messageUuid) => Effect.gen(function* () {\n const filePath = path.join(getSessionsDir(), projectName, `${sessionId}.jsonl`);\n const content = yield* Effect.tryPromise(() => fs.readFile(filePath, \"utf-8\"));\n const lines = content.trim().split(\"\\n\").filter(Boolean);\n const messages = lines.map((line) => JSON.parse(line));\n const targetIndex = messages.findIndex((m) => m.uuid === messageUuid);\n if (targetIndex === -1) {\n return { success: false, error: \"Message not found\" };\n }\n const deletedMsg = messages[targetIndex];\n const parentUuid = deletedMsg?.parentUuid;\n const nextMsg = messages[targetIndex + 1];\n if (nextMsg) {\n nextMsg.parentUuid = parentUuid;\n }\n messages.splice(targetIndex, 1);\n const newContent = messages.map((m) => JSON.stringify(m)).join(\"\\n\") + \"\\n\";\n yield* Effect.tryPromise(() => fs.writeFile(filePath, newContent, \"utf-8\"));\n return { success: true };\n});\nconst previewCleanup = (projectName) => Effect.gen(function* () {\n const projects = yield* listProjects;\n const targetProjects = projectName ? projects.filter((p) => p.name === projectName) : projects;\n const results = yield* Effect.all(\n targetProjects.map(\n (project) => Effect.gen(function* () {\n const sessions = yield* listSessions(project.name);\n const emptySessions = sessions.filter((s) => s.messageCount === 0);\n const invalidSessions = sessions.filter(\n (s) => s.title?.includes(\"Invalid API key\") || s.title?.includes(\"API key\")\n );\n return {\n project: project.name,\n emptySessions,\n invalidSessions\n };\n })\n ),\n { concurrency: 5 }\n );\n return results;\n});\nconst isInvalidApiKeyMessage = (msg) => {\n const text = extractTextContent(msg.message);\n return text.includes(\"Invalid API key\");\n};\nconst cleanInvalidMessages = (projectName, sessionId) => Effect.gen(function* () {\n const filePath = path.join(getSessionsDir(), projectName, `${sessionId}.jsonl`);\n const content = yield* Effect.tryPromise(() => fs.readFile(filePath, \"utf-8\"));\n const lines = content.trim().split(\"\\n\").filter(Boolean);\n if (lines.length === 0) return { removedCount: 0, remainingCount: 0 };\n const messages = lines.map((line) => JSON.parse(line));\n const invalidIndices = [];\n messages.forEach((msg, idx) => {\n if (isInvalidApiKeyMessage(msg)) {\n invalidIndices.push(idx);\n }\n });\n if (invalidIndices.length === 0) {\n const userAssistantCount = messages.filter(\n (m) => m.type === \"user\" || m.type === \"assistant\"\n ).length;\n return { removedCount: 0, remainingCount: userAssistantCount };\n }\n const filtered = [];\n let lastValidUuid = null;\n for (let i = 0; i < messages.length; i++) {\n if (invalidIndices.includes(i)) {\n continue;\n }\n const msg = messages[i];\n if (msg.parentUuid && invalidIndices.some((idx) => messages[idx]?.uuid === msg.parentUuid)) {\n msg.parentUuid = lastValidUuid;\n }\n filtered.push(msg);\n lastValidUuid = msg.uuid;\n }\n const newContent = filtered.length > 0 ? filtered.map((m) => JSON.stringify(m)).join(\"\\n\") + \"\\n\" : \"\";\n yield* Effect.tryPromise(() => fs.writeFile(filePath, newContent, \"utf-8\"));\n const remainingUserAssistant = filtered.filter(\n (m) => m.type === \"user\" || m.type === \"assistant\"\n ).length;\n return { removedCount: invalidIndices.length, remainingCount: remainingUserAssistant };\n});\nconst clearSessions = (options) => Effect.gen(function* () {\n const { projectName, clearEmpty = true } = options;\n const projects = yield* listProjects;\n const targetProjects = projectName ? projects.filter((p) => p.name === projectName) : projects;\n let deletedSessionCount = 0;\n let removedMessageCount = 0;\n const sessionsToDelete = [];\n for (const project of targetProjects) {\n const projectPath = path.join(getSessionsDir(), project.name);\n const files = yield* Effect.tryPromise(() => fs.readdir(projectPath));\n const sessionFiles = files.filter((f) => f.endsWith(\".jsonl\") && !f.startsWith(\"agent-\"));\n for (const file of sessionFiles) {\n const sessionId = file.replace(\".jsonl\", \"\");\n const result = yield* cleanInvalidMessages(project.name, sessionId);\n removedMessageCount += result.removedCount;\n if (result.remainingCount === 0) {\n sessionsToDelete.push({ project: project.name, sessionId });\n }\n }\n }\n if (clearEmpty) {\n for (const project of targetProjects) {\n const sessions = yield* listSessions(project.name);\n for (const session of sessions) {\n if (session.messageCount === 0) {\n const alreadyMarked = sessionsToDelete.some(\n (s) => s.project === project.name && s.sessionId === session.id\n );\n if (!alreadyMarked) {\n sessionsToDelete.push({ project: project.name, sessionId: session.id });\n }\n }\n }\n }\n }\n for (const { project, sessionId } of sessionsToDelete) {\n yield* deleteSession(project, sessionId);\n deletedSessionCount++;\n }\n return {\n success: true,\n deletedCount: deletedSessionCount,\n removedMessageCount\n };\n});\nexport {\n listSessions as a,\n deleteSession as b,\n clearSessions as c,\n deleteMessage as d,\n renameSession as e,\n listProjects as l,\n previewCleanup as p,\n readSession as r,\n updateCustomTitle as u\n};\n"],"names":[],"mappings":"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"}