claude-sessions-mcp 0.2.1 → 0.3.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/dist/mcp/index.js +169 -128
- package/dist/mcp/index.js.map +1 -1
- package/dist/web/client/_app/immutable/assets/0.XO-DXdC4.css +1 -0
- package/dist/web/client/_app/immutable/assets/0.XO-DXdC4.css.br +0 -0
- package/dist/web/client/_app/immutable/assets/0.XO-DXdC4.css.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/B2IHY0Hs.js +1 -0
- package/dist/web/client/_app/immutable/chunks/B2IHY0Hs.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/B2IHY0Hs.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/BCJVXGHY.js +1 -0
- package/dist/web/client/_app/immutable/chunks/BCJVXGHY.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/BCJVXGHY.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/CMwK7N_O.js +1 -0
- package/dist/web/client/_app/immutable/chunks/CMwK7N_O.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/CMwK7N_O.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/CZTho13P.js +1 -0
- package/dist/web/client/_app/immutable/chunks/CZTho13P.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/CZTho13P.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/F-H9hLgW.js +2 -0
- package/dist/web/client/_app/immutable/chunks/F-H9hLgW.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/F-H9hLgW.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/gR9AL7GA.js +2 -0
- package/dist/web/client/_app/immutable/chunks/gR9AL7GA.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/gR9AL7GA.js.gz +0 -0
- package/dist/web/client/_app/immutable/entry/app.Boej0hfY.js +2 -0
- package/dist/web/client/_app/immutable/entry/app.Boej0hfY.js.br +0 -0
- package/dist/web/client/_app/immutable/entry/app.Boej0hfY.js.gz +0 -0
- package/dist/web/client/_app/immutable/entry/start.CVYJWPd9.js +1 -0
- package/dist/web/client/_app/immutable/entry/start.CVYJWPd9.js.br +2 -0
- package/dist/web/client/_app/immutable/entry/start.CVYJWPd9.js.gz +0 -0
- package/dist/web/client/_app/immutable/nodes/0.Lbeu1dpo.js +1 -0
- package/dist/web/client/_app/immutable/nodes/0.Lbeu1dpo.js.br +0 -0
- package/dist/web/client/_app/immutable/nodes/0.Lbeu1dpo.js.gz +0 -0
- package/dist/web/client/_app/immutable/nodes/1.DvRsCtcA.js +1 -0
- package/dist/web/client/_app/immutable/nodes/1.DvRsCtcA.js.br +0 -0
- package/dist/web/client/_app/immutable/nodes/1.DvRsCtcA.js.gz +0 -0
- package/dist/web/client/_app/immutable/nodes/2.CjVN0Bwe.js +73 -0
- package/dist/web/client/_app/immutable/nodes/2.CjVN0Bwe.js.br +0 -0
- package/dist/web/client/_app/immutable/nodes/2.CjVN0Bwe.js.gz +0 -0
- package/dist/web/client/_app/version.json +1 -1
- package/dist/web/client/_app/version.json.br +0 -0
- package/dist/web/client/_app/version.json.gz +0 -0
- package/dist/web/server/chunks/{0-CpLgwGZT.js → 0-C_hzGzlo.js} +4 -4
- package/dist/web/server/chunks/{0-CpLgwGZT.js.map → 0-C_hzGzlo.js.map} +1 -1
- package/dist/web/server/chunks/{1-Co8-9FdW.js → 1-CSNAjAzD.js} +2 -2
- package/dist/web/server/chunks/{1-Co8-9FdW.js.map → 1-CSNAjAzD.js.map} +1 -1
- package/dist/web/server/chunks/2-D_ZAFGkV.js +9 -0
- package/dist/web/server/chunks/{2-CXKmp7vO.js.map → 2-D_ZAFGkV.js.map} +1 -1
- package/dist/web/server/chunks/{_layout.svelte-g4K2eFdi.js → _layout.svelte-BWDuddeu.js} +6 -2
- package/dist/web/server/chunks/_layout.svelte-BWDuddeu.js.map +1 -0
- package/dist/web/server/chunks/{_page.svelte-Bu5w4fE4.js → _page.svelte-BTPPI5f9.js} +12 -4
- package/dist/web/server/chunks/_page.svelte-BTPPI5f9.js.map +1 -0
- package/dist/web/server/chunks/{_server.ts-9dSpOSZD.js → _server.ts-B0JVJ9FB.js} +2 -2
- package/dist/web/server/chunks/{_server.ts-9dSpOSZD.js.map → _server.ts-B0JVJ9FB.js.map} +1 -1
- package/dist/web/server/chunks/{_server.ts-uDQ4gQW0.js → _server.ts-BLGLFyUk.js} +2 -2
- package/dist/web/server/chunks/{_server.ts-uDQ4gQW0.js.map → _server.ts-BLGLFyUk.js.map} +1 -1
- package/dist/web/server/chunks/{_server.ts-XEsSs7Il.js → _server.ts-BaqmP9oG.js} +2 -2
- package/dist/web/server/chunks/{_server.ts-XEsSs7Il.js.map → _server.ts-BaqmP9oG.js.map} +1 -1
- package/dist/web/server/chunks/{_server.ts-BoS0ijI9.js → _server.ts-Beze9L3_.js} +2 -2
- package/dist/web/server/chunks/{_server.ts-BoS0ijI9.js.map → _server.ts-Beze9L3_.js.map} +1 -1
- package/dist/web/server/chunks/{_server.ts-C9C0bsVO.js → _server.ts-BlgHsHoW.js} +2 -2
- package/dist/web/server/chunks/{_server.ts-C9C0bsVO.js.map → _server.ts-BlgHsHoW.js.map} +1 -1
- package/dist/web/server/chunks/{_server.ts-DCZgqkA_.js → _server.ts-Cb5-fa8C.js} +2 -2
- package/dist/web/server/chunks/{_server.ts-DCZgqkA_.js.map → _server.ts-Cb5-fa8C.js.map} +1 -1
- package/dist/web/server/chunks/{_server.ts-zkRNh3d2.js → _server.ts-ChE2aT-W.js} +6 -3
- package/dist/web/server/chunks/_server.ts-ChE2aT-W.js.map +1 -0
- package/dist/web/server/chunks/{_server.ts-Dq5i1Bg9.js → _server.ts-Cksv90lD.js} +2 -2
- package/dist/web/server/chunks/{_server.ts-Dq5i1Bg9.js.map → _server.ts-Cksv90lD.js.map} +1 -1
- package/dist/web/server/chunks/_server.ts-D80JJ66s.js +26 -0
- package/dist/web/server/chunks/_server.ts-D80JJ66s.js.map +1 -0
- package/dist/web/server/chunks/{_server.ts-DNSYjrWg.js → _server.ts-DjWf5N-i.js} +2 -2
- package/dist/web/server/chunks/{_server.ts-DNSYjrWg.js.map → _server.ts-DjWf5N-i.js.map} +1 -1
- package/dist/web/server/chunks/{session-BAE596_s.js → session-DmOGNZUD.js} +380 -13
- package/dist/web/server/chunks/session-DmOGNZUD.js.map +1 -0
- package/dist/web/server/index.js +1 -1
- package/dist/web/server/index.js.map +1 -1
- package/dist/web/server/manifest.js +20 -13
- package/dist/web/server/manifest.js.map +1 -1
- package/package.json +1 -1
- package/dist/web/client/_app/immutable/assets/0.bo32IKJI.css +0 -1
- package/dist/web/client/_app/immutable/assets/0.bo32IKJI.css.br +0 -0
- package/dist/web/client/_app/immutable/assets/0.bo32IKJI.css.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/BpzfNVdV.js +0 -1
- package/dist/web/client/_app/immutable/chunks/BpzfNVdV.js.br +0 -1
- package/dist/web/client/_app/immutable/chunks/BpzfNVdV.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/CM_W2Y6b.js +0 -1
- package/dist/web/client/_app/immutable/chunks/CM_W2Y6b.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/CM_W2Y6b.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/CkYrZ5uP.js +0 -1
- package/dist/web/client/_app/immutable/chunks/CkYrZ5uP.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/CkYrZ5uP.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/DhpCfsq_.js +0 -2
- package/dist/web/client/_app/immutable/chunks/DhpCfsq_.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/DhpCfsq_.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/JuVRPOYA.js +0 -1
- package/dist/web/client/_app/immutable/chunks/JuVRPOYA.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/JuVRPOYA.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/qEz027d4.js +0 -1
- package/dist/web/client/_app/immutable/chunks/qEz027d4.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/qEz027d4.js.gz +0 -0
- package/dist/web/client/_app/immutable/entry/app.B3ErwcNl.js +0 -2
- package/dist/web/client/_app/immutable/entry/app.B3ErwcNl.js.br +0 -0
- package/dist/web/client/_app/immutable/entry/app.B3ErwcNl.js.gz +0 -0
- package/dist/web/client/_app/immutable/entry/start.DfAnAPV3.js +0 -1
- package/dist/web/client/_app/immutable/entry/start.DfAnAPV3.js.br +0 -2
- package/dist/web/client/_app/immutable/entry/start.DfAnAPV3.js.gz +0 -0
- package/dist/web/client/_app/immutable/nodes/0.0G4u1RwN.js +0 -1
- package/dist/web/client/_app/immutable/nodes/0.0G4u1RwN.js.br +0 -0
- package/dist/web/client/_app/immutable/nodes/0.0G4u1RwN.js.gz +0 -0
- package/dist/web/client/_app/immutable/nodes/1.BTCUCPE9.js +0 -1
- package/dist/web/client/_app/immutable/nodes/1.BTCUCPE9.js.br +0 -0
- package/dist/web/client/_app/immutable/nodes/1.BTCUCPE9.js.gz +0 -0
- package/dist/web/client/_app/immutable/nodes/2.rvNN8qKE.js +0 -69
- package/dist/web/client/_app/immutable/nodes/2.rvNN8qKE.js.br +0 -0
- package/dist/web/client/_app/immutable/nodes/2.rvNN8qKE.js.gz +0 -0
- package/dist/web/server/chunks/2-CXKmp7vO.js +0 -9
- package/dist/web/server/chunks/_layout.svelte-g4K2eFdi.js.map +0 -1
- package/dist/web/server/chunks/_page.svelte-Bu5w4fE4.js.map +0 -1
- package/dist/web/server/chunks/_server.ts-zkRNh3d2.js.map +0 -1
- package/dist/web/server/chunks/session-BAE596_s.js.map +0 -1
package/dist/mcp/index.js
CHANGED
|
@@ -7,29 +7,131 @@ import {
|
|
|
7
7
|
// src/mcp/index.ts
|
|
8
8
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
9
9
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
10
|
-
import { Effect as
|
|
10
|
+
import { Effect as Effect3 } from "effect";
|
|
11
11
|
import { z } from "zod";
|
|
12
12
|
|
|
13
13
|
// src/lib/session.ts
|
|
14
|
-
import { Effect, pipe, Array as A, Option as O } from "effect";
|
|
14
|
+
import { Effect as Effect2, pipe, Array as A, Option as O } from "effect";
|
|
15
|
+
import * as fs2 from "fs/promises";
|
|
16
|
+
import * as path2 from "path";
|
|
17
|
+
|
|
18
|
+
// src/lib/shared/session-core.ts
|
|
19
|
+
import { Effect } from "effect";
|
|
15
20
|
import * as fs from "fs/promises";
|
|
16
21
|
import * as path from "path";
|
|
17
22
|
import * as os from "os";
|
|
18
23
|
var getSessionsDir = () => path.join(os.homedir(), ".claude", "projects");
|
|
19
|
-
var
|
|
20
|
-
|
|
24
|
+
var getTodosDir = () => path.join(os.homedir(), ".claude", "todos");
|
|
25
|
+
var findLinkedAgents = (projectName, sessionId) => Effect.gen(function* () {
|
|
26
|
+
const projectPath = path.join(getSessionsDir(), projectName);
|
|
27
|
+
const files = yield* Effect.tryPromise(() => fs.readdir(projectPath));
|
|
28
|
+
const agentFiles = files.filter((f) => f.startsWith("agent-") && f.endsWith(".jsonl"));
|
|
29
|
+
const linkedAgents = [];
|
|
30
|
+
for (const agentFile of agentFiles) {
|
|
31
|
+
const filePath = path.join(projectPath, agentFile);
|
|
32
|
+
const content = yield* Effect.tryPromise(() => fs.readFile(filePath, "utf-8"));
|
|
33
|
+
const firstLine = content.split("\n")[0];
|
|
34
|
+
if (firstLine) {
|
|
35
|
+
try {
|
|
36
|
+
const parsed = JSON.parse(firstLine);
|
|
37
|
+
if (parsed.sessionId === sessionId) {
|
|
38
|
+
linkedAgents.push(agentFile.replace(".jsonl", ""));
|
|
39
|
+
}
|
|
40
|
+
} catch {
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return linkedAgents;
|
|
45
|
+
});
|
|
46
|
+
var findOrphanAgents = (projectName) => Effect.gen(function* () {
|
|
47
|
+
const projectPath = path.join(getSessionsDir(), projectName);
|
|
48
|
+
const files = yield* Effect.tryPromise(() => fs.readdir(projectPath));
|
|
49
|
+
const sessionIds = new Set(
|
|
50
|
+
files.filter((f) => !f.startsWith("agent-") && f.endsWith(".jsonl")).map((f) => f.replace(".jsonl", ""))
|
|
51
|
+
);
|
|
52
|
+
const agentFiles = files.filter((f) => f.startsWith("agent-") && f.endsWith(".jsonl"));
|
|
53
|
+
const orphanAgents = [];
|
|
54
|
+
for (const agentFile of agentFiles) {
|
|
55
|
+
const filePath = path.join(projectPath, agentFile);
|
|
56
|
+
const content = yield* Effect.tryPromise(() => fs.readFile(filePath, "utf-8"));
|
|
57
|
+
const firstLine = content.split("\n")[0];
|
|
58
|
+
if (firstLine) {
|
|
59
|
+
try {
|
|
60
|
+
const parsed = JSON.parse(firstLine);
|
|
61
|
+
if (parsed.sessionId && !sessionIds.has(parsed.sessionId)) {
|
|
62
|
+
orphanAgents.push({
|
|
63
|
+
agentId: agentFile.replace(".jsonl", ""),
|
|
64
|
+
sessionId: parsed.sessionId
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
} catch {
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return orphanAgents;
|
|
72
|
+
});
|
|
73
|
+
var deleteOrphanAgents = (projectName) => Effect.gen(function* () {
|
|
74
|
+
const projectPath = path.join(getSessionsDir(), projectName);
|
|
75
|
+
const orphans = yield* findOrphanAgents(projectName);
|
|
76
|
+
const backupDir = path.join(projectPath, ".bak");
|
|
77
|
+
yield* Effect.tryPromise(() => fs.mkdir(backupDir, { recursive: true }));
|
|
78
|
+
const deletedAgents = [];
|
|
79
|
+
for (const orphan of orphans) {
|
|
80
|
+
const agentPath = path.join(projectPath, `${orphan.agentId}.jsonl`);
|
|
81
|
+
const agentBackupPath = path.join(backupDir, `${orphan.agentId}.jsonl`);
|
|
82
|
+
yield* Effect.tryPromise(() => fs.rename(agentPath, agentBackupPath));
|
|
83
|
+
deletedAgents.push(orphan.agentId);
|
|
84
|
+
}
|
|
85
|
+
return { success: true, deletedAgents, count: deletedAgents.length };
|
|
86
|
+
});
|
|
87
|
+
var deleteLinkedTodos = (sessionId, agentIds) => Effect.gen(function* () {
|
|
88
|
+
const todosDir = getTodosDir();
|
|
21
89
|
const exists = yield* Effect.tryPromise(
|
|
22
|
-
() => fs.access(
|
|
90
|
+
() => fs.access(todosDir).then(() => true).catch(() => false)
|
|
91
|
+
);
|
|
92
|
+
if (!exists) return { deletedCount: 0 };
|
|
93
|
+
const backupDir = path.join(todosDir, ".bak");
|
|
94
|
+
yield* Effect.tryPromise(() => fs.mkdir(backupDir, { recursive: true }));
|
|
95
|
+
let deletedCount = 0;
|
|
96
|
+
const sessionTodoPath = path.join(todosDir, `${sessionId}.json`);
|
|
97
|
+
const sessionTodoExists = yield* Effect.tryPromise(
|
|
98
|
+
() => fs.access(sessionTodoPath).then(() => true).catch(() => false)
|
|
99
|
+
);
|
|
100
|
+
if (sessionTodoExists) {
|
|
101
|
+
const backupPath = path.join(backupDir, `${sessionId}.json`);
|
|
102
|
+
yield* Effect.tryPromise(() => fs.rename(sessionTodoPath, backupPath));
|
|
103
|
+
deletedCount++;
|
|
104
|
+
}
|
|
105
|
+
for (const agentId of agentIds) {
|
|
106
|
+
const shortAgentId = agentId.replace("agent-", "");
|
|
107
|
+
const agentTodoPath = path.join(todosDir, `${sessionId}-agent-${shortAgentId}.json`);
|
|
108
|
+
const agentTodoExists = yield* Effect.tryPromise(
|
|
109
|
+
() => fs.access(agentTodoPath).then(() => true).catch(() => false)
|
|
110
|
+
);
|
|
111
|
+
if (agentTodoExists) {
|
|
112
|
+
const backupPath = path.join(backupDir, `${sessionId}-agent-${shortAgentId}.json`);
|
|
113
|
+
yield* Effect.tryPromise(() => fs.rename(agentTodoPath, backupPath));
|
|
114
|
+
deletedCount++;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return { deletedCount };
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// src/lib/session.ts
|
|
121
|
+
var listProjects = Effect2.gen(function* () {
|
|
122
|
+
const sessionsDir = getSessionsDir();
|
|
123
|
+
const exists = yield* Effect2.tryPromise(
|
|
124
|
+
() => fs2.access(sessionsDir).then(() => true).catch(() => false)
|
|
23
125
|
);
|
|
24
126
|
if (!exists) {
|
|
25
127
|
return [];
|
|
26
128
|
}
|
|
27
|
-
const entries = yield*
|
|
28
|
-
const projects = yield*
|
|
129
|
+
const entries = yield* Effect2.tryPromise(() => fs2.readdir(sessionsDir, { withFileTypes: true }));
|
|
130
|
+
const projects = yield* Effect2.all(
|
|
29
131
|
entries.filter((e) => e.isDirectory()).map(
|
|
30
|
-
(entry) =>
|
|
31
|
-
const projectPath =
|
|
32
|
-
const files = yield*
|
|
132
|
+
(entry) => Effect2.gen(function* () {
|
|
133
|
+
const projectPath = path2.join(sessionsDir, entry.name);
|
|
134
|
+
const files = yield* Effect2.tryPromise(() => fs2.readdir(projectPath));
|
|
33
135
|
const sessionFiles = files.filter((f) => f.endsWith(".jsonl"));
|
|
34
136
|
return {
|
|
35
137
|
name: entry.name,
|
|
@@ -42,15 +144,15 @@ var listProjects = Effect.gen(function* () {
|
|
|
42
144
|
);
|
|
43
145
|
return projects;
|
|
44
146
|
});
|
|
45
|
-
var listSessions = (projectName) =>
|
|
46
|
-
const projectPath =
|
|
47
|
-
const files = yield*
|
|
147
|
+
var listSessions = (projectName) => Effect2.gen(function* () {
|
|
148
|
+
const projectPath = path2.join(getSessionsDir(), projectName);
|
|
149
|
+
const files = yield* Effect2.tryPromise(() => fs2.readdir(projectPath));
|
|
48
150
|
const sessionFiles = files.filter((f) => f.endsWith(".jsonl"));
|
|
49
|
-
const sessions = yield*
|
|
151
|
+
const sessions = yield* Effect2.all(
|
|
50
152
|
sessionFiles.map(
|
|
51
|
-
(file) =>
|
|
52
|
-
const filePath =
|
|
53
|
-
const content = yield*
|
|
153
|
+
(file) => Effect2.gen(function* () {
|
|
154
|
+
const filePath = path2.join(projectPath, file);
|
|
155
|
+
const content = yield* Effect2.tryPromise(() => fs2.readFile(filePath, "utf-8"));
|
|
54
156
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
55
157
|
const messages = lines.map((line) => JSON.parse(line));
|
|
56
158
|
const sessionId = file.replace(".jsonl", "");
|
|
@@ -80,54 +182,34 @@ var listSessions = (projectName) => Effect.gen(function* () {
|
|
|
80
182
|
);
|
|
81
183
|
return sessions;
|
|
82
184
|
});
|
|
83
|
-
var readSession = (projectName, sessionId) =>
|
|
84
|
-
const filePath =
|
|
85
|
-
const content = yield*
|
|
185
|
+
var readSession = (projectName, sessionId) => Effect2.gen(function* () {
|
|
186
|
+
const filePath = path2.join(getSessionsDir(), projectName, `${sessionId}.jsonl`);
|
|
187
|
+
const content = yield* Effect2.tryPromise(() => fs2.readFile(filePath, "utf-8"));
|
|
86
188
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
87
189
|
return lines.map((line) => JSON.parse(line));
|
|
88
190
|
});
|
|
89
|
-
var
|
|
90
|
-
const projectPath = path.join(getSessionsDir(), projectName);
|
|
91
|
-
const files = yield* Effect.tryPromise(() => fs.readdir(projectPath));
|
|
92
|
-
const agentFiles = files.filter((f) => f.startsWith("agent-") && f.endsWith(".jsonl"));
|
|
93
|
-
const linkedAgents = [];
|
|
94
|
-
for (const agentFile of agentFiles) {
|
|
95
|
-
const filePath = path.join(projectPath, agentFile);
|
|
96
|
-
const content = yield* Effect.tryPromise(() => fs.readFile(filePath, "utf-8"));
|
|
97
|
-
const firstLine = content.split("\n")[0];
|
|
98
|
-
if (firstLine) {
|
|
99
|
-
try {
|
|
100
|
-
const parsed = JSON.parse(firstLine);
|
|
101
|
-
if (parsed.sessionId === sessionId) {
|
|
102
|
-
linkedAgents.push(agentFile.replace(".jsonl", ""));
|
|
103
|
-
}
|
|
104
|
-
} catch {
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
return linkedAgents;
|
|
109
|
-
});
|
|
110
|
-
var deleteSession = (projectName, sessionId) => Effect.gen(function* () {
|
|
191
|
+
var deleteSession = (projectName, sessionId) => Effect2.gen(function* () {
|
|
111
192
|
const sessionsDir = getSessionsDir();
|
|
112
|
-
const projectPath =
|
|
113
|
-
const filePath =
|
|
114
|
-
const backupDir =
|
|
115
|
-
yield*
|
|
193
|
+
const projectPath = path2.join(sessionsDir, projectName);
|
|
194
|
+
const filePath = path2.join(projectPath, `${sessionId}.jsonl`);
|
|
195
|
+
const backupDir = path2.join(projectPath, ".bak");
|
|
196
|
+
yield* Effect2.tryPromise(() => fs2.mkdir(backupDir, { recursive: true }));
|
|
116
197
|
const linkedAgents = yield* findLinkedAgents(projectName, sessionId);
|
|
117
198
|
const deletedAgents = [];
|
|
118
199
|
for (const agentId of linkedAgents) {
|
|
119
|
-
const agentPath =
|
|
120
|
-
const agentBackupPath =
|
|
121
|
-
yield*
|
|
200
|
+
const agentPath = path2.join(projectPath, `${agentId}.jsonl`);
|
|
201
|
+
const agentBackupPath = path2.join(backupDir, `${agentId}.jsonl`);
|
|
202
|
+
yield* Effect2.tryPromise(() => fs2.rename(agentPath, agentBackupPath));
|
|
122
203
|
deletedAgents.push(agentId);
|
|
123
204
|
}
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
205
|
+
const todosResult = yield* deleteLinkedTodos(sessionId, linkedAgents);
|
|
206
|
+
const backupPath = path2.join(backupDir, `${sessionId}.jsonl`);
|
|
207
|
+
yield* Effect2.tryPromise(() => fs2.rename(filePath, backupPath));
|
|
208
|
+
return { success: true, backupPath, deletedAgents, deletedTodos: todosResult.deletedCount };
|
|
127
209
|
});
|
|
128
|
-
var renameSession = (projectName, sessionId, newTitle) =>
|
|
129
|
-
const filePath =
|
|
130
|
-
const content = yield*
|
|
210
|
+
var renameSession = (projectName, sessionId, newTitle) => Effect2.gen(function* () {
|
|
211
|
+
const filePath = path2.join(getSessionsDir(), projectName, `${sessionId}.jsonl`);
|
|
212
|
+
const content = yield* Effect2.tryPromise(() => fs2.readFile(filePath, "utf-8"));
|
|
131
213
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
132
214
|
if (lines.length === 0) {
|
|
133
215
|
return { success: false, error: "Empty session" };
|
|
@@ -142,12 +224,12 @@ var renameSession = (projectName, sessionId, newTitle) => Effect.gen(function* (
|
|
|
142
224
|
}
|
|
143
225
|
}
|
|
144
226
|
const newContent = messages.map((m) => JSON.stringify(m)).join("\n") + "\n";
|
|
145
|
-
yield*
|
|
227
|
+
yield* Effect2.tryPromise(() => fs2.writeFile(filePath, newContent, "utf-8"));
|
|
146
228
|
return { success: true };
|
|
147
229
|
});
|
|
148
|
-
var deleteMessage = (projectName, sessionId, messageUuid) =>
|
|
149
|
-
const filePath =
|
|
150
|
-
const content = yield*
|
|
230
|
+
var deleteMessage = (projectName, sessionId, messageUuid) => Effect2.gen(function* () {
|
|
231
|
+
const filePath = path2.join(getSessionsDir(), projectName, `${sessionId}.jsonl`);
|
|
232
|
+
const content = yield* Effect2.tryPromise(() => fs2.readFile(filePath, "utf-8"));
|
|
151
233
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
152
234
|
const messages = lines.map((line) => JSON.parse(line));
|
|
153
235
|
const targetIndex = messages.findIndex(
|
|
@@ -164,15 +246,15 @@ var deleteMessage = (projectName, sessionId, messageUuid) => Effect.gen(function
|
|
|
164
246
|
}
|
|
165
247
|
messages.splice(targetIndex, 1);
|
|
166
248
|
const newContent = messages.map((m) => JSON.stringify(m)).join("\n") + "\n";
|
|
167
|
-
yield*
|
|
249
|
+
yield* Effect2.tryPromise(() => fs2.writeFile(filePath, newContent, "utf-8"));
|
|
168
250
|
return { success: true };
|
|
169
251
|
});
|
|
170
|
-
var previewCleanup = (projectName) =>
|
|
252
|
+
var previewCleanup = (projectName) => Effect2.gen(function* () {
|
|
171
253
|
const projects = yield* listProjects;
|
|
172
254
|
const targetProjects = projectName ? projects.filter((p) => p.name === projectName) : projects;
|
|
173
|
-
const results = yield*
|
|
255
|
+
const results = yield* Effect2.all(
|
|
174
256
|
targetProjects.map(
|
|
175
|
-
(project) =>
|
|
257
|
+
(project) => Effect2.gen(function* () {
|
|
176
258
|
const sessions = yield* listSessions(project.name);
|
|
177
259
|
const emptySessions = sessions.filter((s) => s.messageCount === 0);
|
|
178
260
|
const invalidSessions = sessions.filter(
|
|
@@ -189,48 +271,7 @@ var previewCleanup = (projectName) => Effect.gen(function* () {
|
|
|
189
271
|
);
|
|
190
272
|
return results;
|
|
191
273
|
});
|
|
192
|
-
var
|
|
193
|
-
const projectPath = path.join(getSessionsDir(), projectName);
|
|
194
|
-
const files = yield* Effect.tryPromise(() => fs.readdir(projectPath));
|
|
195
|
-
const sessionIds = new Set(
|
|
196
|
-
files.filter((f) => !f.startsWith("agent-") && f.endsWith(".jsonl")).map((f) => f.replace(".jsonl", ""))
|
|
197
|
-
);
|
|
198
|
-
const agentFiles = files.filter((f) => f.startsWith("agent-") && f.endsWith(".jsonl"));
|
|
199
|
-
const orphanAgents = [];
|
|
200
|
-
for (const agentFile of agentFiles) {
|
|
201
|
-
const filePath = path.join(projectPath, agentFile);
|
|
202
|
-
const content = yield* Effect.tryPromise(() => fs.readFile(filePath, "utf-8"));
|
|
203
|
-
const firstLine = content.split("\n")[0];
|
|
204
|
-
if (firstLine) {
|
|
205
|
-
try {
|
|
206
|
-
const parsed = JSON.parse(firstLine);
|
|
207
|
-
if (parsed.sessionId && !sessionIds.has(parsed.sessionId)) {
|
|
208
|
-
orphanAgents.push({
|
|
209
|
-
agentId: agentFile.replace(".jsonl", ""),
|
|
210
|
-
sessionId: parsed.sessionId
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
} catch {
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
return orphanAgents;
|
|
218
|
-
});
|
|
219
|
-
var deleteOrphanAgents = (projectName) => Effect.gen(function* () {
|
|
220
|
-
const projectPath = path.join(getSessionsDir(), projectName);
|
|
221
|
-
const orphans = yield* findOrphanAgents(projectName);
|
|
222
|
-
const backupDir = path.join(projectPath, ".bak");
|
|
223
|
-
yield* Effect.tryPromise(() => fs.mkdir(backupDir, { recursive: true }));
|
|
224
|
-
const deletedAgents = [];
|
|
225
|
-
for (const orphan of orphans) {
|
|
226
|
-
const agentPath = path.join(projectPath, `${orphan.agentId}.jsonl`);
|
|
227
|
-
const agentBackupPath = path.join(backupDir, `${orphan.agentId}.jsonl`);
|
|
228
|
-
yield* Effect.tryPromise(() => fs.rename(agentPath, agentBackupPath));
|
|
229
|
-
deletedAgents.push(orphan.agentId);
|
|
230
|
-
}
|
|
231
|
-
return { success: true, deletedAgents, count: deletedAgents.length };
|
|
232
|
-
});
|
|
233
|
-
var clearSessions = (options) => Effect.gen(function* () {
|
|
274
|
+
var clearSessions = (options) => Effect2.gen(function* () {
|
|
234
275
|
const {
|
|
235
276
|
projectName,
|
|
236
277
|
clearEmpty = true,
|
|
@@ -257,7 +298,7 @@ var clearSessions = (options) => Effect.gen(function* () {
|
|
|
257
298
|
}
|
|
258
299
|
return { success: true, deletedCount, deletedAgentCount };
|
|
259
300
|
});
|
|
260
|
-
var getSessionFiles = (projectName, sessionId) =>
|
|
301
|
+
var getSessionFiles = (projectName, sessionId) => Effect2.gen(function* () {
|
|
261
302
|
const messages = yield* readSession(projectName, sessionId);
|
|
262
303
|
const fileChanges = [];
|
|
263
304
|
const seenFiles = /* @__PURE__ */ new Set();
|
|
@@ -307,10 +348,10 @@ var getSessionFiles = (projectName, sessionId) => Effect.gen(function* () {
|
|
|
307
348
|
totalChanges: fileChanges.length
|
|
308
349
|
};
|
|
309
350
|
});
|
|
310
|
-
var splitSession = (projectName, sessionId, splitAtMessageUuid) =>
|
|
311
|
-
const projectPath =
|
|
312
|
-
const filePath =
|
|
313
|
-
const content = yield*
|
|
351
|
+
var splitSession = (projectName, sessionId, splitAtMessageUuid) => Effect2.gen(function* () {
|
|
352
|
+
const projectPath = path2.join(getSessionsDir(), projectName);
|
|
353
|
+
const filePath = path2.join(projectPath, `${sessionId}.jsonl`);
|
|
354
|
+
const content = yield* Effect2.tryPromise(() => fs2.readFile(filePath, "utf-8"));
|
|
314
355
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
315
356
|
const allMessages = lines.map((line) => JSON.parse(line));
|
|
316
357
|
const splitIndex = allMessages.findIndex((m) => m.uuid === splitAtMessageUuid);
|
|
@@ -331,15 +372,15 @@ var splitSession = (projectName, sessionId, splitAtMessageUuid) => Effect.gen(fu
|
|
|
331
372
|
return updated;
|
|
332
373
|
});
|
|
333
374
|
const remainingContent = remainingMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
|
|
334
|
-
yield*
|
|
335
|
-
const newFilePath =
|
|
375
|
+
yield* Effect2.tryPromise(() => fs2.writeFile(filePath, remainingContent, "utf-8"));
|
|
376
|
+
const newFilePath = path2.join(projectPath, `${newSessionId}.jsonl`);
|
|
336
377
|
const newContent = updatedMovedMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
|
|
337
|
-
yield*
|
|
338
|
-
const agentFiles = yield*
|
|
378
|
+
yield* Effect2.tryPromise(() => fs2.writeFile(newFilePath, newContent, "utf-8"));
|
|
379
|
+
const agentFiles = yield* Effect2.tryPromise(() => fs2.readdir(projectPath));
|
|
339
380
|
const agentJsonlFiles = agentFiles.filter((f) => f.startsWith("agent-") && f.endsWith(".jsonl"));
|
|
340
381
|
for (const agentFile of agentJsonlFiles) {
|
|
341
|
-
const agentPath =
|
|
342
|
-
const agentContent = yield*
|
|
382
|
+
const agentPath = path2.join(projectPath, agentFile);
|
|
383
|
+
const agentContent = yield* Effect2.tryPromise(() => fs2.readFile(agentPath, "utf-8"));
|
|
343
384
|
const agentLines = agentContent.trim().split("\n").filter(Boolean);
|
|
344
385
|
if (agentLines.length === 0) continue;
|
|
345
386
|
const firstAgentMsg = JSON.parse(agentLines[0]);
|
|
@@ -354,7 +395,7 @@ var splitSession = (projectName, sessionId, splitAtMessageUuid) => Effect.gen(fu
|
|
|
354
395
|
return JSON.stringify({ ...msg, sessionId: newSessionId });
|
|
355
396
|
});
|
|
356
397
|
const updatedAgentContent = updatedAgentMessages.join("\n") + "\n";
|
|
357
|
-
yield*
|
|
398
|
+
yield* Effect2.tryPromise(() => fs2.writeFile(agentPath, updatedAgentContent, "utf-8"));
|
|
358
399
|
}
|
|
359
400
|
}
|
|
360
401
|
}
|
|
@@ -365,7 +406,7 @@ var splitSession = (projectName, sessionId, splitAtMessageUuid) => Effect.gen(fu
|
|
|
365
406
|
movedMessageCount: movedMessages.length
|
|
366
407
|
};
|
|
367
408
|
});
|
|
368
|
-
var getSessionDiffSummary = (projectName, sessionId) =>
|
|
409
|
+
var getSessionDiffSummary = (projectName, sessionId) => Effect2.gen(function* () {
|
|
369
410
|
const messages = yield* readSession(projectName, sessionId);
|
|
370
411
|
const title = pipe(
|
|
371
412
|
messages,
|
|
@@ -418,7 +459,7 @@ var server = new McpServer({
|
|
|
418
459
|
version: "0.1.0"
|
|
419
460
|
});
|
|
420
461
|
server.tool("list_projects", "List all Claude Code projects with session counts", {}, async () => {
|
|
421
|
-
const result = await
|
|
462
|
+
const result = await Effect3.runPromise(listProjects);
|
|
422
463
|
return {
|
|
423
464
|
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
424
465
|
};
|
|
@@ -430,7 +471,7 @@ server.tool(
|
|
|
430
471
|
project_name: z.string().describe("Project folder name (e.g., '-Users-young-works-myproject')")
|
|
431
472
|
},
|
|
432
473
|
async ({ project_name }) => {
|
|
433
|
-
const result = await
|
|
474
|
+
const result = await Effect3.runPromise(listSessions(project_name));
|
|
434
475
|
return {
|
|
435
476
|
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
436
477
|
};
|
|
@@ -445,7 +486,7 @@ server.tool(
|
|
|
445
486
|
new_title: z.string().describe("New title to add as prefix")
|
|
446
487
|
},
|
|
447
488
|
async ({ project_name, session_id, new_title }) => {
|
|
448
|
-
const result = await
|
|
489
|
+
const result = await Effect3.runPromise(
|
|
449
490
|
renameSession(project_name, session_id, new_title)
|
|
450
491
|
);
|
|
451
492
|
return {
|
|
@@ -461,7 +502,7 @@ server.tool(
|
|
|
461
502
|
session_id: z.string().describe("Session ID to delete")
|
|
462
503
|
},
|
|
463
504
|
async ({ project_name, session_id }) => {
|
|
464
|
-
const result = await
|
|
505
|
+
const result = await Effect3.runPromise(deleteSession(project_name, session_id));
|
|
465
506
|
return {
|
|
466
507
|
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
467
508
|
};
|
|
@@ -476,7 +517,7 @@ server.tool(
|
|
|
476
517
|
message_uuid: z.string().describe("UUID of the message to delete")
|
|
477
518
|
},
|
|
478
519
|
async ({ project_name, session_id, message_uuid }) => {
|
|
479
|
-
const result = await
|
|
520
|
+
const result = await Effect3.runPromise(
|
|
480
521
|
deleteMessage(project_name, session_id, message_uuid)
|
|
481
522
|
);
|
|
482
523
|
return {
|
|
@@ -491,7 +532,7 @@ server.tool(
|
|
|
491
532
|
project_name: z.string().optional().describe("Optional: filter by project name")
|
|
492
533
|
},
|
|
493
534
|
async ({ project_name }) => {
|
|
494
|
-
const result = await
|
|
535
|
+
const result = await Effect3.runPromise(previewCleanup(project_name));
|
|
495
536
|
return {
|
|
496
537
|
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
497
538
|
};
|
|
@@ -507,7 +548,7 @@ server.tool(
|
|
|
507
548
|
clear_orphan_agents: z.boolean().default(true).describe("Clear orphan agent files whose session no longer exists (default: true)")
|
|
508
549
|
},
|
|
509
550
|
async ({ project_name, clear_empty, clear_invalid, clear_orphan_agents }) => {
|
|
510
|
-
const result = await
|
|
551
|
+
const result = await Effect3.runPromise(
|
|
511
552
|
clearSessions({
|
|
512
553
|
projectName: project_name,
|
|
513
554
|
clearEmpty: clear_empty,
|
|
@@ -528,7 +569,7 @@ server.tool(
|
|
|
528
569
|
session_id: z.string().describe("Session ID")
|
|
529
570
|
},
|
|
530
571
|
async ({ project_name, session_id }) => {
|
|
531
|
-
const result = await
|
|
572
|
+
const result = await Effect3.runPromise(getSessionFiles(project_name, session_id));
|
|
532
573
|
return {
|
|
533
574
|
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
534
575
|
};
|
|
@@ -542,7 +583,7 @@ server.tool(
|
|
|
542
583
|
session_id: z.string().describe("Session ID")
|
|
543
584
|
},
|
|
544
585
|
async ({ project_name, session_id }) => {
|
|
545
|
-
const result = await
|
|
586
|
+
const result = await Effect3.runPromise(getSessionDiffSummary(project_name, session_id));
|
|
546
587
|
return {
|
|
547
588
|
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
548
589
|
};
|
|
@@ -559,7 +600,7 @@ server.tool(
|
|
|
559
600
|
)
|
|
560
601
|
},
|
|
561
602
|
async ({ project_name, session_id, message_uuid }) => {
|
|
562
|
-
const result = await
|
|
603
|
+
const result = await Effect3.runPromise(
|
|
563
604
|
splitSession(project_name, session_id, message_uuid)
|
|
564
605
|
);
|
|
565
606
|
return {
|