claude-sessions-mcp 0.2.2 → 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.
Files changed (119) hide show
  1. package/dist/mcp/index.js +169 -128
  2. package/dist/mcp/index.js.map +1 -1
  3. package/dist/web/client/_app/immutable/assets/0.XO-DXdC4.css +1 -0
  4. package/dist/web/client/_app/immutable/assets/0.XO-DXdC4.css.br +0 -0
  5. package/dist/web/client/_app/immutable/assets/0.XO-DXdC4.css.gz +0 -0
  6. package/dist/web/client/_app/immutable/chunks/B2IHY0Hs.js +1 -0
  7. package/dist/web/client/_app/immutable/chunks/B2IHY0Hs.js.br +0 -0
  8. package/dist/web/client/_app/immutable/chunks/B2IHY0Hs.js.gz +0 -0
  9. package/dist/web/client/_app/immutable/chunks/BCJVXGHY.js +1 -0
  10. package/dist/web/client/_app/immutable/chunks/BCJVXGHY.js.br +0 -0
  11. package/dist/web/client/_app/immutable/chunks/BCJVXGHY.js.gz +0 -0
  12. package/dist/web/client/_app/immutable/chunks/CMwK7N_O.js +1 -0
  13. package/dist/web/client/_app/immutable/chunks/CMwK7N_O.js.br +0 -0
  14. package/dist/web/client/_app/immutable/chunks/CMwK7N_O.js.gz +0 -0
  15. package/dist/web/client/_app/immutable/chunks/CZTho13P.js +1 -0
  16. package/dist/web/client/_app/immutable/chunks/CZTho13P.js.br +0 -0
  17. package/dist/web/client/_app/immutable/chunks/CZTho13P.js.gz +0 -0
  18. package/dist/web/client/_app/immutable/chunks/F-H9hLgW.js +2 -0
  19. package/dist/web/client/_app/immutable/chunks/F-H9hLgW.js.br +0 -0
  20. package/dist/web/client/_app/immutable/chunks/F-H9hLgW.js.gz +0 -0
  21. package/dist/web/client/_app/immutable/chunks/gR9AL7GA.js +2 -0
  22. package/dist/web/client/_app/immutable/chunks/gR9AL7GA.js.br +0 -0
  23. package/dist/web/client/_app/immutable/chunks/gR9AL7GA.js.gz +0 -0
  24. package/dist/web/client/_app/immutable/entry/app.Boej0hfY.js +2 -0
  25. package/dist/web/client/_app/immutable/entry/app.Boej0hfY.js.br +0 -0
  26. package/dist/web/client/_app/immutable/entry/app.Boej0hfY.js.gz +0 -0
  27. package/dist/web/client/_app/immutable/entry/start.CVYJWPd9.js +1 -0
  28. package/dist/web/client/_app/immutable/entry/start.CVYJWPd9.js.br +2 -0
  29. package/dist/web/client/_app/immutable/entry/start.CVYJWPd9.js.gz +0 -0
  30. package/dist/web/client/_app/immutable/nodes/0.Lbeu1dpo.js +1 -0
  31. package/dist/web/client/_app/immutable/nodes/0.Lbeu1dpo.js.br +0 -0
  32. package/dist/web/client/_app/immutable/nodes/0.Lbeu1dpo.js.gz +0 -0
  33. package/dist/web/client/_app/immutable/nodes/1.DvRsCtcA.js +1 -0
  34. package/dist/web/client/_app/immutable/nodes/1.DvRsCtcA.js.br +0 -0
  35. package/dist/web/client/_app/immutable/nodes/1.DvRsCtcA.js.gz +0 -0
  36. package/dist/web/client/_app/immutable/nodes/2.CjVN0Bwe.js +73 -0
  37. package/dist/web/client/_app/immutable/nodes/2.CjVN0Bwe.js.br +0 -0
  38. package/dist/web/client/_app/immutable/nodes/2.CjVN0Bwe.js.gz +0 -0
  39. package/dist/web/client/_app/version.json +1 -1
  40. package/dist/web/client/_app/version.json.br +0 -0
  41. package/dist/web/client/_app/version.json.gz +0 -0
  42. package/dist/web/server/chunks/{0-CSg0FjrW.js → 0-C_hzGzlo.js} +4 -4
  43. package/dist/web/server/chunks/{0-CSg0FjrW.js.map → 0-C_hzGzlo.js.map} +1 -1
  44. package/dist/web/server/chunks/{1-DITZbj6v.js → 1-CSNAjAzD.js} +2 -2
  45. package/dist/web/server/chunks/{1-DITZbj6v.js.map → 1-CSNAjAzD.js.map} +1 -1
  46. package/dist/web/server/chunks/2-D_ZAFGkV.js +9 -0
  47. package/dist/web/server/chunks/{2-DruheCUS.js.map → 2-D_ZAFGkV.js.map} +1 -1
  48. package/dist/web/server/chunks/{_layout.svelte-g4K2eFdi.js → _layout.svelte-BWDuddeu.js} +6 -2
  49. package/dist/web/server/chunks/_layout.svelte-BWDuddeu.js.map +1 -0
  50. package/dist/web/server/chunks/{_page.svelte-Bu5w4fE4.js → _page.svelte-BTPPI5f9.js} +12 -4
  51. package/dist/web/server/chunks/_page.svelte-BTPPI5f9.js.map +1 -0
  52. package/dist/web/server/chunks/{_server.ts-9dSpOSZD.js → _server.ts-B0JVJ9FB.js} +2 -2
  53. package/dist/web/server/chunks/{_server.ts-9dSpOSZD.js.map → _server.ts-B0JVJ9FB.js.map} +1 -1
  54. package/dist/web/server/chunks/{_server.ts-uDQ4gQW0.js → _server.ts-BLGLFyUk.js} +2 -2
  55. package/dist/web/server/chunks/{_server.ts-uDQ4gQW0.js.map → _server.ts-BLGLFyUk.js.map} +1 -1
  56. package/dist/web/server/chunks/{_server.ts-XEsSs7Il.js → _server.ts-BaqmP9oG.js} +2 -2
  57. package/dist/web/server/chunks/{_server.ts-XEsSs7Il.js.map → _server.ts-BaqmP9oG.js.map} +1 -1
  58. package/dist/web/server/chunks/{_server.ts-BoS0ijI9.js → _server.ts-Beze9L3_.js} +2 -2
  59. package/dist/web/server/chunks/{_server.ts-BoS0ijI9.js.map → _server.ts-Beze9L3_.js.map} +1 -1
  60. package/dist/web/server/chunks/{_server.ts-CUFgemWt.js → _server.ts-BlgHsHoW.js} +2 -2
  61. package/dist/web/server/chunks/{_server.ts-CUFgemWt.js.map → _server.ts-BlgHsHoW.js.map} +1 -1
  62. package/dist/web/server/chunks/{_server.ts-DCZgqkA_.js → _server.ts-Cb5-fa8C.js} +2 -2
  63. package/dist/web/server/chunks/{_server.ts-DCZgqkA_.js.map → _server.ts-Cb5-fa8C.js.map} +1 -1
  64. package/dist/web/server/chunks/{_server.ts-zkRNh3d2.js → _server.ts-ChE2aT-W.js} +6 -3
  65. package/dist/web/server/chunks/_server.ts-ChE2aT-W.js.map +1 -0
  66. package/dist/web/server/chunks/{_server.ts-Dq5i1Bg9.js → _server.ts-Cksv90lD.js} +2 -2
  67. package/dist/web/server/chunks/{_server.ts-Dq5i1Bg9.js.map → _server.ts-Cksv90lD.js.map} +1 -1
  68. package/dist/web/server/chunks/_server.ts-D80JJ66s.js +26 -0
  69. package/dist/web/server/chunks/_server.ts-D80JJ66s.js.map +1 -0
  70. package/dist/web/server/chunks/{_server.ts-DNSYjrWg.js → _server.ts-DjWf5N-i.js} +2 -2
  71. package/dist/web/server/chunks/{_server.ts-DNSYjrWg.js.map → _server.ts-DjWf5N-i.js.map} +1 -1
  72. package/dist/web/server/chunks/{session-BAE596_s.js → session-DmOGNZUD.js} +380 -13
  73. package/dist/web/server/chunks/session-DmOGNZUD.js.map +1 -0
  74. package/dist/web/server/index.js +1 -1
  75. package/dist/web/server/index.js.map +1 -1
  76. package/dist/web/server/manifest.js +20 -13
  77. package/dist/web/server/manifest.js.map +1 -1
  78. package/package.json +1 -1
  79. package/dist/web/client/_app/immutable/assets/0.B2Ed6Mpr.css +0 -1
  80. package/dist/web/client/_app/immutable/assets/0.B2Ed6Mpr.css.br +0 -0
  81. package/dist/web/client/_app/immutable/assets/0.B2Ed6Mpr.css.gz +0 -0
  82. package/dist/web/client/_app/immutable/chunks/ChUNEGSF.js +0 -1
  83. package/dist/web/client/_app/immutable/chunks/ChUNEGSF.js.br +0 -0
  84. package/dist/web/client/_app/immutable/chunks/ChUNEGSF.js.gz +0 -0
  85. package/dist/web/client/_app/immutable/chunks/CkYrZ5uP.js +0 -1
  86. package/dist/web/client/_app/immutable/chunks/CkYrZ5uP.js.br +0 -0
  87. package/dist/web/client/_app/immutable/chunks/CkYrZ5uP.js.gz +0 -0
  88. package/dist/web/client/_app/immutable/chunks/DMIwXBU2.js +0 -1
  89. package/dist/web/client/_app/immutable/chunks/DMIwXBU2.js.br +0 -1
  90. package/dist/web/client/_app/immutable/chunks/DMIwXBU2.js.gz +0 -0
  91. package/dist/web/client/_app/immutable/chunks/DhpCfsq_.js +0 -2
  92. package/dist/web/client/_app/immutable/chunks/DhpCfsq_.js.br +0 -0
  93. package/dist/web/client/_app/immutable/chunks/DhpCfsq_.js.gz +0 -0
  94. package/dist/web/client/_app/immutable/chunks/JuVRPOYA.js +0 -1
  95. package/dist/web/client/_app/immutable/chunks/JuVRPOYA.js.br +0 -0
  96. package/dist/web/client/_app/immutable/chunks/JuVRPOYA.js.gz +0 -0
  97. package/dist/web/client/_app/immutable/chunks/qEz027d4.js +0 -1
  98. package/dist/web/client/_app/immutable/chunks/qEz027d4.js.br +0 -0
  99. package/dist/web/client/_app/immutable/chunks/qEz027d4.js.gz +0 -0
  100. package/dist/web/client/_app/immutable/entry/app.BtK9g-Sl.js +0 -2
  101. package/dist/web/client/_app/immutable/entry/app.BtK9g-Sl.js.br +0 -0
  102. package/dist/web/client/_app/immutable/entry/app.BtK9g-Sl.js.gz +0 -0
  103. package/dist/web/client/_app/immutable/entry/start.D-1GJX6_.js +0 -1
  104. package/dist/web/client/_app/immutable/entry/start.D-1GJX6_.js.br +0 -2
  105. package/dist/web/client/_app/immutable/entry/start.D-1GJX6_.js.gz +0 -0
  106. package/dist/web/client/_app/immutable/nodes/0.D-CLOlPL.js +0 -1
  107. package/dist/web/client/_app/immutable/nodes/0.D-CLOlPL.js.br +0 -0
  108. package/dist/web/client/_app/immutable/nodes/0.D-CLOlPL.js.gz +0 -0
  109. package/dist/web/client/_app/immutable/nodes/1.ypm2nJK5.js +0 -1
  110. package/dist/web/client/_app/immutable/nodes/1.ypm2nJK5.js.br +0 -0
  111. package/dist/web/client/_app/immutable/nodes/1.ypm2nJK5.js.gz +0 -0
  112. package/dist/web/client/_app/immutable/nodes/2.CNmGqqiX.js +0 -71
  113. package/dist/web/client/_app/immutable/nodes/2.CNmGqqiX.js.br +0 -0
  114. package/dist/web/client/_app/immutable/nodes/2.CNmGqqiX.js.gz +0 -0
  115. package/dist/web/server/chunks/2-DruheCUS.js +0 -9
  116. package/dist/web/server/chunks/_layout.svelte-g4K2eFdi.js.map +0 -1
  117. package/dist/web/server/chunks/_page.svelte-Bu5w4fE4.js.map +0 -1
  118. package/dist/web/server/chunks/_server.ts-zkRNh3d2.js.map +0 -1
  119. package/dist/web/server/chunks/session-BAE596_s.js.map +0 -1
@@ -3,7 +3,264 @@ import * as fs from 'node:fs/promises';
3
3
  import * as path from 'node:path';
4
4
  import * as os from 'node:os';
5
5
 
6
- const getSessionsDir = () => path.join(os.homedir(), ".claude", "projects");
6
+ const getSessionsDir$1 = () => path.join(os.homedir(), ".claude", "projects");
7
+ const getTodosDir = () => path.join(os.homedir(), ".claude", "todos");
8
+ const findLinkedAgents$1 = (projectName, sessionId) => Effect.gen(function* () {
9
+ const projectPath = path.join(getSessionsDir$1(), projectName);
10
+ const files = yield* Effect.tryPromise(() => fs.readdir(projectPath));
11
+ const agentFiles = files.filter((f) => f.startsWith("agent-") && f.endsWith(".jsonl"));
12
+ const linkedAgents = [];
13
+ for (const agentFile of agentFiles) {
14
+ const filePath = path.join(projectPath, agentFile);
15
+ const content = yield* Effect.tryPromise(() => fs.readFile(filePath, "utf-8"));
16
+ const firstLine = content.split("\n")[0];
17
+ if (firstLine) {
18
+ try {
19
+ const parsed = JSON.parse(firstLine);
20
+ if (parsed.sessionId === sessionId) {
21
+ linkedAgents.push(agentFile.replace(".jsonl", ""));
22
+ }
23
+ } catch {
24
+ }
25
+ }
26
+ }
27
+ return linkedAgents;
28
+ });
29
+ const findOrphanAgents$1 = (projectName) => Effect.gen(function* () {
30
+ const projectPath = path.join(getSessionsDir$1(), projectName);
31
+ const files = yield* Effect.tryPromise(() => fs.readdir(projectPath));
32
+ const sessionIds = new Set(
33
+ files.filter((f) => !f.startsWith("agent-") && f.endsWith(".jsonl")).map((f) => f.replace(".jsonl", ""))
34
+ );
35
+ const agentFiles = files.filter((f) => f.startsWith("agent-") && f.endsWith(".jsonl"));
36
+ const orphanAgents = [];
37
+ for (const agentFile of agentFiles) {
38
+ const filePath = path.join(projectPath, agentFile);
39
+ const content = yield* Effect.tryPromise(() => fs.readFile(filePath, "utf-8"));
40
+ const firstLine = content.split("\n")[0];
41
+ if (firstLine) {
42
+ try {
43
+ const parsed = JSON.parse(firstLine);
44
+ if (parsed.sessionId && !sessionIds.has(parsed.sessionId)) {
45
+ orphanAgents.push({
46
+ agentId: agentFile.replace(".jsonl", ""),
47
+ sessionId: parsed.sessionId
48
+ });
49
+ }
50
+ } catch {
51
+ }
52
+ }
53
+ }
54
+ return orphanAgents;
55
+ });
56
+ const deleteOrphanAgents$1 = (projectName) => Effect.gen(function* () {
57
+ const projectPath = path.join(getSessionsDir$1(), projectName);
58
+ const orphans = yield* findOrphanAgents$1(projectName);
59
+ const backupDir = path.join(projectPath, ".bak");
60
+ yield* Effect.tryPromise(() => fs.mkdir(backupDir, { recursive: true }));
61
+ const deletedAgents = [];
62
+ for (const orphan of orphans) {
63
+ const agentPath = path.join(projectPath, `${orphan.agentId}.jsonl`);
64
+ const agentBackupPath = path.join(backupDir, `${orphan.agentId}.jsonl`);
65
+ yield* Effect.tryPromise(() => fs.rename(agentPath, agentBackupPath));
66
+ deletedAgents.push(orphan.agentId);
67
+ }
68
+ return { success: true, deletedAgents, count: deletedAgents.length };
69
+ });
70
+ const findLinkedTodos = (sessionId, agentIds) => Effect.gen(function* () {
71
+ const todosDir = getTodosDir();
72
+ const exists = yield* Effect.tryPromise(
73
+ () => fs.access(todosDir).then(() => true).catch(() => false)
74
+ );
75
+ if (!exists) {
76
+ return {
77
+ sessionId,
78
+ sessionTodos: [],
79
+ agentTodos: [],
80
+ hasTodos: false
81
+ };
82
+ }
83
+ const sessionTodoPath = path.join(todosDir, `${sessionId}.json`);
84
+ let sessionTodos = [];
85
+ const sessionTodoExists = yield* Effect.tryPromise(
86
+ () => fs.access(sessionTodoPath).then(() => true).catch(() => false)
87
+ );
88
+ if (sessionTodoExists) {
89
+ const content = yield* Effect.tryPromise(() => fs.readFile(sessionTodoPath, "utf-8"));
90
+ try {
91
+ sessionTodos = JSON.parse(content);
92
+ } catch {
93
+ }
94
+ }
95
+ const agentTodos = [];
96
+ for (const agentId of agentIds) {
97
+ const shortAgentId = agentId.replace("agent-", "");
98
+ const agentTodoPath = path.join(todosDir, `${sessionId}-agent-${shortAgentId}.json`);
99
+ const agentTodoExists = yield* Effect.tryPromise(
100
+ () => fs.access(agentTodoPath).then(() => true).catch(() => false)
101
+ );
102
+ if (agentTodoExists) {
103
+ const content = yield* Effect.tryPromise(() => fs.readFile(agentTodoPath, "utf-8"));
104
+ try {
105
+ const todos = JSON.parse(content);
106
+ agentTodos.push({ agentId, todos });
107
+ } catch {
108
+ }
109
+ }
110
+ }
111
+ const hasTodos = sessionTodos.length > 0 || agentTodos.some((at) => at.todos.length > 0);
112
+ return {
113
+ sessionId,
114
+ sessionTodos,
115
+ agentTodos,
116
+ hasTodos
117
+ };
118
+ });
119
+ const sessionHasTodos$1 = (sessionId, agentIds) => Effect.gen(function* () {
120
+ const todosDir = getTodosDir();
121
+ const exists = yield* Effect.tryPromise(
122
+ () => fs.access(todosDir).then(() => true).catch(() => false)
123
+ );
124
+ if (!exists) return false;
125
+ const sessionTodoPath = path.join(todosDir, `${sessionId}.json`);
126
+ const sessionTodoExists = yield* Effect.tryPromise(
127
+ () => fs.access(sessionTodoPath).then(() => true).catch(() => false)
128
+ );
129
+ if (sessionTodoExists) {
130
+ const content = yield* Effect.tryPromise(() => fs.readFile(sessionTodoPath, "utf-8"));
131
+ try {
132
+ const todos = JSON.parse(content);
133
+ if (todos.length > 0) return true;
134
+ } catch {
135
+ }
136
+ }
137
+ for (const agentId of agentIds) {
138
+ const shortAgentId = agentId.replace("agent-", "");
139
+ const agentTodoPath = path.join(todosDir, `${sessionId}-agent-${shortAgentId}.json`);
140
+ const agentTodoExists = yield* Effect.tryPromise(
141
+ () => fs.access(agentTodoPath).then(() => true).catch(() => false)
142
+ );
143
+ if (agentTodoExists) {
144
+ const content = yield* Effect.tryPromise(() => fs.readFile(agentTodoPath, "utf-8"));
145
+ try {
146
+ const todos = JSON.parse(content);
147
+ if (todos.length > 0) return true;
148
+ } catch {
149
+ }
150
+ }
151
+ }
152
+ return false;
153
+ });
154
+ const deleteLinkedTodos$1 = (sessionId, agentIds) => Effect.gen(function* () {
155
+ const todosDir = getTodosDir();
156
+ const exists = yield* Effect.tryPromise(
157
+ () => fs.access(todosDir).then(() => true).catch(() => false)
158
+ );
159
+ if (!exists) return { deletedCount: 0 };
160
+ const backupDir = path.join(todosDir, ".bak");
161
+ yield* Effect.tryPromise(() => fs.mkdir(backupDir, { recursive: true }));
162
+ let deletedCount = 0;
163
+ const sessionTodoPath = path.join(todosDir, `${sessionId}.json`);
164
+ const sessionTodoExists = yield* Effect.tryPromise(
165
+ () => fs.access(sessionTodoPath).then(() => true).catch(() => false)
166
+ );
167
+ if (sessionTodoExists) {
168
+ const backupPath = path.join(backupDir, `${sessionId}.json`);
169
+ yield* Effect.tryPromise(() => fs.rename(sessionTodoPath, backupPath));
170
+ deletedCount++;
171
+ }
172
+ for (const agentId of agentIds) {
173
+ const shortAgentId = agentId.replace("agent-", "");
174
+ const agentTodoPath = path.join(todosDir, `${sessionId}-agent-${shortAgentId}.json`);
175
+ const agentTodoExists = yield* Effect.tryPromise(
176
+ () => fs.access(agentTodoPath).then(() => true).catch(() => false)
177
+ );
178
+ if (agentTodoExists) {
179
+ const backupPath = path.join(backupDir, `${sessionId}-agent-${shortAgentId}.json`);
180
+ yield* Effect.tryPromise(() => fs.rename(agentTodoPath, backupPath));
181
+ deletedCount++;
182
+ }
183
+ }
184
+ return { deletedCount };
185
+ });
186
+ const findOrphanTodos$1 = () => Effect.gen(function* () {
187
+ const todosDir = getTodosDir();
188
+ const sessionsDir = getSessionsDir$1();
189
+ const [todosExists, sessionsExists] = yield* Effect.all([
190
+ Effect.tryPromise(
191
+ () => fs.access(todosDir).then(() => true).catch(() => false)
192
+ ),
193
+ Effect.tryPromise(
194
+ () => fs.access(sessionsDir).then(() => true).catch(() => false)
195
+ )
196
+ ]);
197
+ if (!todosExists || !sessionsExists) return [];
198
+ const todoFiles = yield* Effect.tryPromise(() => fs.readdir(todosDir));
199
+ const jsonFiles = todoFiles.filter((f) => f.endsWith(".json"));
200
+ const validSessionIds = /* @__PURE__ */ new Set();
201
+ const projectEntries = yield* Effect.tryPromise(
202
+ () => fs.readdir(sessionsDir, { withFileTypes: true })
203
+ );
204
+ for (const entry of projectEntries) {
205
+ if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
206
+ const projectPath = path.join(sessionsDir, entry.name);
207
+ const files = yield* Effect.tryPromise(() => fs.readdir(projectPath));
208
+ for (const f of files) {
209
+ if (f.endsWith(".jsonl") && !f.startsWith("agent-")) {
210
+ validSessionIds.add(f.replace(".jsonl", ""));
211
+ }
212
+ }
213
+ }
214
+ const orphans = [];
215
+ for (const todoFile of jsonFiles) {
216
+ const match = todoFile.match(/^([a-f0-9-]+)(?:-agent-[a-f0-9]+)?\.json$/);
217
+ if (match) {
218
+ const sessionId = match[1];
219
+ if (!validSessionIds.has(sessionId)) {
220
+ orphans.push(todoFile);
221
+ }
222
+ }
223
+ }
224
+ return orphans;
225
+ });
226
+ const deleteOrphanTodos$1 = () => Effect.gen(function* () {
227
+ const todosDir = getTodosDir();
228
+ const orphans = yield* findOrphanTodos$1();
229
+ if (orphans.length === 0) return { success: true, deletedCount: 0 };
230
+ const backupDir = path.join(todosDir, ".bak");
231
+ yield* Effect.tryPromise(() => fs.mkdir(backupDir, { recursive: true }));
232
+ let deletedCount = 0;
233
+ for (const orphan of orphans) {
234
+ const filePath = path.join(todosDir, orphan);
235
+ const backupPath = path.join(backupDir, orphan);
236
+ yield* Effect.tryPromise(() => fs.rename(filePath, backupPath));
237
+ deletedCount++;
238
+ }
239
+ return { success: true, deletedCount };
240
+ });
241
+ const shared = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
242
+ __proto__: null,
243
+ deleteLinkedTodos: deleteLinkedTodos$1,
244
+ deleteOrphanAgents: deleteOrphanAgents$1,
245
+ deleteOrphanTodos: deleteOrphanTodos$1,
246
+ findLinkedAgents: findLinkedAgents$1,
247
+ findLinkedTodos,
248
+ findOrphanAgents: findOrphanAgents$1,
249
+ findOrphanTodos: findOrphanTodos$1,
250
+ getSessionsDir: getSessionsDir$1,
251
+ getTodosDir,
252
+ sessionHasTodos: sessionHasTodos$1
253
+ }, Symbol.toStringTag, { value: "Module" }));
254
+ const {
255
+ getSessionsDir,
256
+ findLinkedAgents,
257
+ findOrphanAgents,
258
+ deleteOrphanAgents,
259
+ sessionHasTodos,
260
+ deleteLinkedTodos,
261
+ findOrphanTodos,
262
+ deleteOrphanTodos
263
+ } = shared;
7
264
  const extractTextContent = (message) => {
8
265
  if (!message) return "";
9
266
  const content = message.content;
@@ -71,6 +328,7 @@ const listSessions = (projectName) => Effect.gen(function* () {
71
328
  const userAssistantMessages = messages.filter(
72
329
  (m) => m.type === "user" || m.type === "assistant"
73
330
  );
331
+ const hasSummary = messages.some((m) => m.type === "summary");
74
332
  const firstMessage = userAssistantMessages[0];
75
333
  const lastMessage = userAssistantMessages[userAssistantMessages.length - 1];
76
334
  const title = pipe(
@@ -80,13 +338,14 @@ const listSessions = (projectName) => Effect.gen(function* () {
80
338
  const text = extractTextContent(m.message);
81
339
  return extractTitle(text);
82
340
  }),
83
- Option.getOrElse(() => `Session ${sessionId.slice(0, 8)}`)
341
+ Option.getOrElse(() => hasSummary ? "[Summary Only]" : `Session ${sessionId.slice(0, 8)}`)
84
342
  );
85
343
  return {
86
344
  id: sessionId,
87
345
  projectName,
88
346
  title,
89
- messageCount: userAssistantMessages.length,
347
+ // If session has summary but no user/assistant messages, count as 1
348
+ messageCount: userAssistantMessages.length > 0 ? userAssistantMessages.length : hasSummary ? 1 : 0,
90
349
  createdAt: firstMessage?.timestamp,
91
350
  updatedAt: lastMessage?.timestamp
92
351
  };
@@ -108,17 +367,42 @@ const readSession = (projectName, sessionId) => Effect.gen(function* () {
108
367
  });
109
368
  const deleteSession = (projectName, sessionId) => Effect.gen(function* () {
110
369
  const sessionsDir = getSessionsDir();
111
- const filePath = path.join(sessionsDir, projectName, `${sessionId}.jsonl`);
370
+ const projectPath = path.join(sessionsDir, projectName);
371
+ const filePath = path.join(projectPath, `${sessionId}.jsonl`);
372
+ const linkedAgents = yield* findLinkedAgents(projectName, sessionId);
112
373
  const stat = yield* Effect.tryPromise(() => fs.stat(filePath));
113
374
  if (stat.size === 0) {
114
375
  yield* Effect.tryPromise(() => fs.unlink(filePath));
115
- return { success: true };
376
+ const agentBackupDir2 = path.join(projectPath, ".bak");
377
+ yield* Effect.tryPromise(() => fs.mkdir(agentBackupDir2, { recursive: true }));
378
+ for (const agentId of linkedAgents) {
379
+ const agentPath = path.join(projectPath, `${agentId}.jsonl`);
380
+ const agentBackupPath = path.join(agentBackupDir2, `${agentId}.jsonl`);
381
+ yield* Effect.tryPromise(() => fs.rename(agentPath, agentBackupPath).catch(() => {
382
+ }));
383
+ }
384
+ yield* deleteLinkedTodos(sessionId, linkedAgents);
385
+ return { success: true, deletedAgents: linkedAgents.length };
116
386
  }
117
387
  const backupDir = path.join(sessionsDir, ".bak");
118
388
  yield* Effect.tryPromise(() => fs.mkdir(backupDir, { recursive: true }));
389
+ const agentBackupDir = path.join(projectPath, ".bak");
390
+ yield* Effect.tryPromise(() => fs.mkdir(agentBackupDir, { recursive: true }));
391
+ for (const agentId of linkedAgents) {
392
+ const agentPath = path.join(projectPath, `${agentId}.jsonl`);
393
+ const agentBackupPath = path.join(agentBackupDir, `${agentId}.jsonl`);
394
+ yield* Effect.tryPromise(() => fs.rename(agentPath, agentBackupPath).catch(() => {
395
+ }));
396
+ }
397
+ const todosResult = yield* deleteLinkedTodos(sessionId, linkedAgents);
119
398
  const backupPath = path.join(backupDir, `${projectName}_${sessionId}.jsonl`);
120
399
  yield* Effect.tryPromise(() => fs.rename(filePath, backupPath));
121
- return { success: true, backupPath };
400
+ return {
401
+ success: true,
402
+ backupPath,
403
+ deletedAgents: linkedAgents.length,
404
+ deletedTodos: todosResult.deletedCount
405
+ };
122
406
  });
123
407
  const renameSession = (projectName, sessionId, newTitle) => Effect.gen(function* () {
124
408
  const filePath = path.join(getSessionsDir(), projectName, `${sessionId}.jsonl`);
@@ -193,6 +477,8 @@ const deleteMessage = (projectName, sessionId, messageUuid) => Effect.gen(functi
193
477
  const previewCleanup = (projectName) => Effect.gen(function* () {
194
478
  const projects = yield* listProjects;
195
479
  const targetProjects = projectName ? projects.filter((p) => p.name === projectName) : projects;
480
+ const orphanTodos = yield* findOrphanTodos();
481
+ const orphanTodoCount = orphanTodos.length;
196
482
  const results = yield* Effect.all(
197
483
  targetProjects.map(
198
484
  (project) => Effect.gen(function* () {
@@ -201,15 +487,34 @@ const previewCleanup = (projectName) => Effect.gen(function* () {
201
487
  const invalidSessions = sessions.filter(
202
488
  (s) => s.title?.includes("Invalid API key") || s.title?.includes("API key")
203
489
  );
490
+ let emptyWithTodosCount = 0;
491
+ for (const session of emptySessions) {
492
+ const linkedAgents = yield* findLinkedAgents(project.name, session.id);
493
+ const hasTodos = yield* sessionHasTodos(session.id, linkedAgents);
494
+ if (hasTodos) {
495
+ emptyWithTodosCount++;
496
+ }
497
+ }
498
+ const orphanAgents = yield* findOrphanAgents(project.name);
204
499
  return {
205
500
  project: project.name,
206
501
  emptySessions,
207
- invalidSessions
502
+ invalidSessions,
503
+ emptyWithTodosCount,
504
+ orphanAgentCount: orphanAgents.length,
505
+ orphanTodoCount
506
+ // Include global orphan todo count in first project only
208
507
  };
209
508
  })
210
509
  ),
211
510
  { concurrency: 5 }
212
511
  );
512
+ if (results.length > 0) {
513
+ results[0] = { ...results[0], orphanTodoCount };
514
+ for (let i = 1; i < results.length; i++) {
515
+ results[i] = { ...results[i], orphanTodoCount: 0 };
516
+ }
517
+ }
213
518
  return results;
214
519
  });
215
520
  const isInvalidApiKeyMessage = (msg) => {
@@ -232,7 +537,9 @@ const cleanInvalidMessages = (projectName, sessionId) => Effect.gen(function* ()
232
537
  const userAssistantCount = messages.filter(
233
538
  (m) => m.type === "user" || m.type === "assistant"
234
539
  ).length;
235
- return { removedCount: 0, remainingCount: userAssistantCount };
540
+ const hasSummary2 = messages.some((m) => m.type === "summary");
541
+ const remainingCount2 = userAssistantCount > 0 ? userAssistantCount : hasSummary2 ? 1 : 0;
542
+ return { removedCount: 0, remainingCount: remainingCount2 };
236
543
  }
237
544
  const filtered = [];
238
545
  let lastValidUuid = null;
@@ -252,7 +559,9 @@ const cleanInvalidMessages = (projectName, sessionId) => Effect.gen(function* ()
252
559
  const remainingUserAssistant = filtered.filter(
253
560
  (m) => m.type === "user" || m.type === "assistant"
254
561
  ).length;
255
- return { removedCount: invalidIndices.length, remainingCount: remainingUserAssistant };
562
+ const hasSummary = filtered.some((m) => m.type === "summary");
563
+ const remainingCount = remainingUserAssistant > 0 ? remainingUserAssistant : hasSummary ? 1 : 0;
564
+ return { removedCount: invalidIndices.length, remainingCount };
256
565
  });
257
566
  const getSessionFiles = (projectName, sessionId) => Effect.gen(function* () {
258
567
  const messages = yield* readSession(projectName, sessionId);
@@ -306,6 +615,39 @@ const getSessionFiles = (projectName, sessionId) => Effect.gen(function* () {
306
615
  totalChanges: fileChanges.length
307
616
  };
308
617
  });
618
+ const moveSession = (sourceProject, sessionId, targetProject) => Effect.gen(function* () {
619
+ const sessionsDir = getSessionsDir();
620
+ const sourcePath = path.join(sessionsDir, sourceProject);
621
+ const targetPath = path.join(sessionsDir, targetProject);
622
+ const sourceFile = path.join(sourcePath, `${sessionId}.jsonl`);
623
+ const targetFile = path.join(targetPath, `${sessionId}.jsonl`);
624
+ const sourceExists = yield* Effect.tryPromise(
625
+ () => fs.access(sourceFile).then(() => true).catch(() => false)
626
+ );
627
+ if (!sourceExists) {
628
+ return { success: false, error: "Source session not found" };
629
+ }
630
+ const targetExists = yield* Effect.tryPromise(
631
+ () => fs.access(targetFile).then(() => true).catch(() => false)
632
+ );
633
+ if (targetExists) {
634
+ return { success: false, error: "Session already exists in target project" };
635
+ }
636
+ yield* Effect.tryPromise(() => fs.mkdir(targetPath, { recursive: true }));
637
+ const linkedAgents = yield* findLinkedAgents(sourceProject, sessionId);
638
+ yield* Effect.tryPromise(() => fs.rename(sourceFile, targetFile));
639
+ for (const agentId of linkedAgents) {
640
+ const sourceAgentFile = path.join(sourcePath, `${agentId}.jsonl`);
641
+ const targetAgentFile = path.join(targetPath, `${agentId}.jsonl`);
642
+ const agentExists = yield* Effect.tryPromise(
643
+ () => fs.access(sourceAgentFile).then(() => true).catch(() => false)
644
+ );
645
+ if (agentExists) {
646
+ yield* Effect.tryPromise(() => fs.rename(sourceAgentFile, targetAgentFile));
647
+ }
648
+ }
649
+ return { success: true };
650
+ });
309
651
  const splitSession = (projectName, sessionId, splitAtMessageUuid) => Effect.gen(function* () {
310
652
  const projectPath = path.join(getSessionsDir(), projectName);
311
653
  const filePath = path.join(projectPath, `${sessionId}.jsonl`);
@@ -365,11 +707,19 @@ const splitSession = (projectName, sessionId, splitAtMessageUuid) => Effect.gen(
365
707
  };
366
708
  });
367
709
  const clearSessions = (options) => Effect.gen(function* () {
368
- const { projectName, clearEmpty = true } = options;
710
+ const {
711
+ projectName,
712
+ clearEmpty = true,
713
+ skipWithTodos = true,
714
+ clearOrphanAgents = false,
715
+ clearOrphanTodos = false
716
+ } = options;
369
717
  const projects = yield* listProjects;
370
718
  const targetProjects = projectName ? projects.filter((p) => p.name === projectName) : projects;
371
719
  let deletedSessionCount = 0;
372
720
  let removedMessageCount = 0;
721
+ let deletedOrphanAgentCount = 0;
722
+ let deletedOrphanTodoCount = 0;
373
723
  const sessionsToDelete = [];
374
724
  for (const project of targetProjects) {
375
725
  const projectPath = path.join(getSessionsDir(), project.name);
@@ -393,6 +743,11 @@ const clearSessions = (options) => Effect.gen(function* () {
393
743
  (s) => s.project === project.name && s.sessionId === session.id
394
744
  );
395
745
  if (!alreadyMarked) {
746
+ if (skipWithTodos) {
747
+ const linkedAgents = yield* findLinkedAgents(project.name, session.id);
748
+ const hasTodos = yield* sessionHasTodos(session.id, linkedAgents);
749
+ if (hasTodos) continue;
750
+ }
396
751
  sessionsToDelete.push({ project: project.name, sessionId: session.id });
397
752
  }
398
753
  }
@@ -403,12 +758,24 @@ const clearSessions = (options) => Effect.gen(function* () {
403
758
  yield* deleteSession(project, sessionId);
404
759
  deletedSessionCount++;
405
760
  }
761
+ if (clearOrphanAgents) {
762
+ for (const project of targetProjects) {
763
+ const result = yield* deleteOrphanAgents(project.name);
764
+ deletedOrphanAgentCount += result.count;
765
+ }
766
+ }
767
+ if (clearOrphanTodos) {
768
+ const result = yield* deleteOrphanTodos();
769
+ deletedOrphanTodoCount = result.deletedCount;
770
+ }
406
771
  return {
407
772
  success: true,
408
773
  deletedCount: deletedSessionCount,
409
- removedMessageCount
774
+ removedMessageCount,
775
+ deletedOrphanAgentCount,
776
+ deletedOrphanTodoCount
410
777
  };
411
778
  });
412
779
 
413
- export { listSessions as a, deleteSession as b, clearSessions as c, deleteMessage as d, renameSession as e, getSessionFiles as g, listProjects as l, previewCleanup as p, readSession as r, splitSession as s, updateCustomTitle as u };
414
- //# sourceMappingURL=session-BAE596_s.js.map
780
+ export { listSessions as a, deleteSession as b, clearSessions as c, deleteMessage as d, renameSession as e, getSessionFiles as g, listProjects as l, moveSession as m, previewCleanup as p, readSession as r, splitSession as s, updateCustomTitle as u };
781
+ //# sourceMappingURL=session-DmOGNZUD.js.map