@claude-sessions/web 0.3.7 → 0.4.1

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 (176) hide show
  1. package/build/client/_app/immutable/assets/0.B02QGPuL.css +1 -0
  2. package/build/client/_app/immutable/assets/0.B02QGPuL.css.br +0 -0
  3. package/build/client/_app/immutable/assets/0.B02QGPuL.css.gz +0 -0
  4. package/build/client/_app/immutable/chunks/{pOdkXMWy.js → B-Z9hXPk.js} +1 -1
  5. package/build/client/_app/immutable/chunks/B-Z9hXPk.js.br +0 -0
  6. package/build/client/_app/immutable/chunks/B-Z9hXPk.js.gz +0 -0
  7. package/build/client/_app/immutable/chunks/Cr0eW1j3.js +1 -0
  8. package/build/client/_app/immutable/chunks/Cr0eW1j3.js.br +0 -0
  9. package/build/client/_app/immutable/chunks/Cr0eW1j3.js.gz +0 -0
  10. package/build/client/_app/immutable/chunks/{Dbjp-HdT.js → D49tNEXH.js} +1 -1
  11. package/build/client/_app/immutable/chunks/D49tNEXH.js.br +0 -0
  12. package/build/client/_app/immutable/chunks/D49tNEXH.js.gz +0 -0
  13. package/build/client/_app/immutable/chunks/DOXVKi87.js +2 -0
  14. package/build/client/_app/immutable/chunks/DOXVKi87.js.br +0 -0
  15. package/build/client/_app/immutable/chunks/DOXVKi87.js.gz +0 -0
  16. package/build/client/_app/immutable/chunks/DVh32r5c.js +90 -0
  17. package/build/client/_app/immutable/chunks/DVh32r5c.js.br +0 -0
  18. package/build/client/_app/immutable/chunks/DVh32r5c.js.gz +0 -0
  19. package/build/client/_app/immutable/chunks/Dzg_BFdu.js +1 -0
  20. package/build/client/_app/immutable/chunks/Dzg_BFdu.js.br +0 -0
  21. package/build/client/_app/immutable/chunks/Dzg_BFdu.js.gz +0 -0
  22. package/build/client/_app/immutable/chunks/YXuXYbOb.js +1 -0
  23. package/build/client/_app/immutable/chunks/YXuXYbOb.js.br +0 -0
  24. package/build/client/_app/immutable/chunks/YXuXYbOb.js.gz +0 -0
  25. package/build/client/_app/immutable/entry/app.Btq_bE7X.js +2 -0
  26. package/build/client/_app/immutable/entry/app.Btq_bE7X.js.br +0 -0
  27. package/build/client/_app/immutable/entry/app.Btq_bE7X.js.gz +0 -0
  28. package/build/client/_app/immutable/entry/start.DiKqSoAN.js +1 -0
  29. package/build/client/_app/immutable/entry/start.DiKqSoAN.js.br +2 -0
  30. package/build/client/_app/immutable/entry/start.DiKqSoAN.js.gz +0 -0
  31. package/build/client/_app/immutable/nodes/{0.D4LDvqQb.js → 0.CjrUlXhs.js} +1 -1
  32. package/build/client/_app/immutable/nodes/0.CjrUlXhs.js.br +0 -0
  33. package/build/client/_app/immutable/nodes/0.CjrUlXhs.js.gz +0 -0
  34. package/build/client/_app/immutable/nodes/1.C_mir9rr.js +1 -0
  35. package/build/client/_app/immutable/nodes/1.C_mir9rr.js.br +0 -0
  36. package/build/client/_app/immutable/nodes/1.C_mir9rr.js.gz +0 -0
  37. package/build/client/_app/immutable/nodes/2.C1TvKf9x.js +4 -0
  38. package/build/client/_app/immutable/nodes/2.C1TvKf9x.js.br +0 -0
  39. package/build/client/_app/immutable/nodes/2.C1TvKf9x.js.gz +0 -0
  40. package/build/client/_app/immutable/nodes/{3.BqDX5X09.js → 3.C4KCGMhg.js} +1 -1
  41. package/build/client/_app/immutable/nodes/3.C4KCGMhg.js.br +0 -0
  42. package/build/client/_app/immutable/nodes/3.C4KCGMhg.js.gz +0 -0
  43. package/build/client/_app/version.json +1 -1
  44. package/build/client/_app/version.json.br +0 -0
  45. package/build/client/_app/version.json.gz +0 -0
  46. package/build/env.js +51 -2
  47. package/build/handler.js +46 -4
  48. package/build/index.js +25 -14
  49. package/build/server/chunks/0-_4Y5P6Pu.js +17 -0
  50. package/build/server/chunks/{0-DkD09WcK.js.map → 0-_4Y5P6Pu.js.map} +1 -1
  51. package/build/server/chunks/1-BFEz-9-0.js +9 -0
  52. package/build/server/chunks/{1-CjtVgNYW.js.map → 1-BFEz-9-0.js.map} +1 -1
  53. package/build/server/chunks/2-BJBIDU_y.js +9 -0
  54. package/build/server/chunks/{2-wstlfOP5.js.map → 2-BJBIDU_y.js.map} +1 -1
  55. package/build/server/chunks/3-fx1FyCiP.js +9 -0
  56. package/build/server/chunks/{3-Cdn9_0OG.js.map → 3-fx1FyCiP.js.map} +1 -1
  57. package/build/server/chunks/{InputModal-XaplAR5y.js → InputModal-CbpiMXy3.js} +3 -3
  58. package/build/server/chunks/InputModal-CbpiMXy3.js.map +1 -0
  59. package/build/server/chunks/{Toast-ihrVamsT.js → Toast-Crka3UoV.js} +4 -4
  60. package/build/server/chunks/Toast-Crka3UoV.js.map +1 -0
  61. package/build/server/chunks/{_layout.svelte-COfbk473.js → _layout.svelte-IUZv8Y-p.js} +7 -6
  62. package/build/server/chunks/_layout.svelte-IUZv8Y-p.js.map +1 -0
  63. package/build/server/chunks/{_page.svelte-C5Xngf9U.js → _page.svelte-CVZlXeAH.js} +373 -188
  64. package/build/server/chunks/_page.svelte-CVZlXeAH.js.map +1 -0
  65. package/build/server/chunks/{_page.svelte-CKSi7jlX.js → _page.svelte-Hxh7dTyf.js} +8 -7
  66. package/build/server/chunks/_page.svelte-Hxh7dTyf.js.map +1 -0
  67. package/build/server/chunks/{_server.ts-QYg-pRKw.js → _server.ts-B1VENOjw.js} +3 -2
  68. package/build/server/chunks/{_server.ts-QYg-pRKw.js.map → _server.ts-B1VENOjw.js.map} +1 -1
  69. package/build/server/chunks/_server.ts-B2LLvx6I.js +41 -0
  70. package/build/server/chunks/_server.ts-B2LLvx6I.js.map +1 -0
  71. package/build/server/chunks/{_server.ts-C46vcb_V.js → _server.ts-B3x7amtu.js} +3 -2
  72. package/build/server/chunks/{_server.ts-C46vcb_V.js.map → _server.ts-B3x7amtu.js.map} +1 -1
  73. package/build/server/chunks/{_server.ts-DRy1BtKz.js → _server.ts-B7mAMmzV.js} +3 -2
  74. package/build/server/chunks/{_server.ts-DRy1BtKz.js.map → _server.ts-B7mAMmzV.js.map} +1 -1
  75. package/build/server/chunks/{_server.ts-Bzg6xSYv.js → _server.ts-BDo-cBep.js} +3 -2
  76. package/build/server/chunks/{_server.ts-Bzg6xSYv.js.map → _server.ts-BDo-cBep.js.map} +1 -1
  77. package/build/server/chunks/{_server.ts-msjVztXK.js → _server.ts-BEMET_M9.js} +3 -2
  78. package/build/server/chunks/{_server.ts-msjVztXK.js.map → _server.ts-BEMET_M9.js.map} +1 -1
  79. package/build/server/chunks/{_server.ts-a85289si.js → _server.ts-B_tHvJuE.js} +3 -2
  80. package/build/server/chunks/_server.ts-B_tHvJuE.js.map +1 -0
  81. package/build/server/chunks/{_server.ts-CF7wNACi.js → _server.ts-CYy3E-wy.js} +3 -2
  82. package/build/server/chunks/{_server.ts-CF7wNACi.js.map → _server.ts-CYy3E-wy.js.map} +1 -1
  83. package/build/server/chunks/_server.ts-Cn3u85fU.js +26 -0
  84. package/build/server/chunks/_server.ts-Cn3u85fU.js.map +1 -0
  85. package/build/server/chunks/{_server.ts-bj28Awpj.js → _server.ts-CwCozCTU.js} +3 -2
  86. package/build/server/chunks/_server.ts-CwCozCTU.js.map +1 -0
  87. package/build/server/chunks/{_server.ts-IjEZJmtD.js → _server.ts-Cyd5L7R7.js} +3 -2
  88. package/build/server/chunks/{_server.ts-IjEZJmtD.js.map → _server.ts-Cyd5L7R7.js.map} +1 -1
  89. package/build/server/chunks/{_server.ts-BNGntgHD.js → _server.ts-D_nsNW3s.js} +7 -3
  90. package/build/server/chunks/_server.ts-D_nsNW3s.js.map +1 -0
  91. package/build/server/chunks/{_server.ts-CBabn3Le.js → _server.ts-Dm4cFvT_.js} +3 -2
  92. package/build/server/chunks/{_server.ts-CBabn3Le.js.map → _server.ts-Dm4cFvT_.js.map} +1 -1
  93. package/build/server/chunks/{_server.ts-Dtvv8PMc.js → _server.ts-SM5kuocx.js} +3 -2
  94. package/build/server/chunks/{_server.ts-Dtvv8PMc.js.map → _server.ts-SM5kuocx.js.map} +1 -1
  95. package/build/server/chunks/{_server.ts-CBCUnjeX.js → _server.ts-X0UsKGpZ.js} +3 -2
  96. package/build/server/chunks/{_server.ts-CBCUnjeX.js.map → _server.ts-X0UsKGpZ.js.map} +1 -1
  97. package/build/server/chunks/{_server.ts-CFQ3_7g1.js → _server.ts-kaRz-iNE.js} +3 -2
  98. package/build/server/chunks/{_server.ts-CFQ3_7g1.js.map → _server.ts-kaRz-iNE.js.map} +1 -1
  99. package/build/server/chunks/{error.svelte-C43AeaaJ.js → error.svelte-BNCG_dZH.js} +3 -3
  100. package/build/server/chunks/{error.svelte-C43AeaaJ.js.map → error.svelte-BNCG_dZH.js.map} +1 -1
  101. package/build/server/chunks/exports-BXvEiaiv.js.map +1 -1
  102. package/build/server/chunks/{index2-Da0doXJY.js → index-BEaiIYry.js} +388 -4
  103. package/build/server/chunks/index-BEaiIYry.js.map +1 -0
  104. package/build/server/chunks/index-CoD1IJuy.js.map +1 -1
  105. package/build/server/chunks/{index-DzYX9r1_.js → index2-ybZwlzIk.js} +110 -116
  106. package/build/server/chunks/index2-ybZwlzIk.js.map +1 -0
  107. package/build/server/chunks/{index3-DkgTDgY2.js → index3-CcQtlmu9.js} +568 -421
  108. package/build/server/chunks/index3-CcQtlmu9.js.map +1 -0
  109. package/build/server/chunks/{index4-BUZEWk-I.js → index4-B6vRxXfo.js} +2 -2
  110. package/build/server/chunks/index4-B6vRxXfo.js.map +1 -0
  111. package/build/server/chunks/shared-server-DaWdgxVh.js +11 -0
  112. package/build/server/chunks/shared-server-DaWdgxVh.js.map +1 -0
  113. package/build/server/index.js +115 -439
  114. package/build/server/index.js.map +1 -1
  115. package/build/server/manifest.js +21 -21
  116. package/build/server/manifest.js.map +1 -1
  117. package/dist/cli.js +26 -1
  118. package/package.json +18 -18
  119. package/build/client/_app/immutable/assets/0.DYXbBCWs.css +0 -1
  120. package/build/client/_app/immutable/assets/0.DYXbBCWs.css.br +0 -0
  121. package/build/client/_app/immutable/assets/0.DYXbBCWs.css.gz +0 -0
  122. package/build/client/_app/immutable/chunks/CT0aV1AN.js +0 -90
  123. package/build/client/_app/immutable/chunks/CT0aV1AN.js.br +0 -0
  124. package/build/client/_app/immutable/chunks/CT0aV1AN.js.gz +0 -0
  125. package/build/client/_app/immutable/chunks/Ck-YPZB6.js +0 -1
  126. package/build/client/_app/immutable/chunks/Ck-YPZB6.js.br +0 -0
  127. package/build/client/_app/immutable/chunks/Ck-YPZB6.js.gz +0 -0
  128. package/build/client/_app/immutable/chunks/Dbjp-HdT.js.br +0 -0
  129. package/build/client/_app/immutable/chunks/Dbjp-HdT.js.gz +0 -0
  130. package/build/client/_app/immutable/chunks/HaThayHP.js +0 -1
  131. package/build/client/_app/immutable/chunks/HaThayHP.js.br +0 -0
  132. package/build/client/_app/immutable/chunks/HaThayHP.js.gz +0 -0
  133. package/build/client/_app/immutable/chunks/fuY-CvTV.js +0 -1
  134. package/build/client/_app/immutable/chunks/fuY-CvTV.js.br +0 -0
  135. package/build/client/_app/immutable/chunks/fuY-CvTV.js.gz +0 -0
  136. package/build/client/_app/immutable/chunks/nUq5tIUU.js +0 -2
  137. package/build/client/_app/immutable/chunks/nUq5tIUU.js.br +0 -0
  138. package/build/client/_app/immutable/chunks/nUq5tIUU.js.gz +0 -0
  139. package/build/client/_app/immutable/chunks/pOdkXMWy.js.br +0 -0
  140. package/build/client/_app/immutable/chunks/pOdkXMWy.js.gz +0 -0
  141. package/build/client/_app/immutable/entry/app.DMBaTVWt.js +0 -2
  142. package/build/client/_app/immutable/entry/app.DMBaTVWt.js.br +0 -0
  143. package/build/client/_app/immutable/entry/app.DMBaTVWt.js.gz +0 -0
  144. package/build/client/_app/immutable/entry/start.C3tcesOa.js +0 -1
  145. package/build/client/_app/immutable/entry/start.C3tcesOa.js.br +0 -2
  146. package/build/client/_app/immutable/entry/start.C3tcesOa.js.gz +0 -0
  147. package/build/client/_app/immutable/nodes/0.D4LDvqQb.js.br +0 -0
  148. package/build/client/_app/immutable/nodes/0.D4LDvqQb.js.gz +0 -0
  149. package/build/client/_app/immutable/nodes/1.5BEtqK67.js +0 -1
  150. package/build/client/_app/immutable/nodes/1.5BEtqK67.js.br +0 -0
  151. package/build/client/_app/immutable/nodes/1.5BEtqK67.js.gz +0 -0
  152. package/build/client/_app/immutable/nodes/2.C-xl-nxy.js +0 -4
  153. package/build/client/_app/immutable/nodes/2.C-xl-nxy.js.br +0 -0
  154. package/build/client/_app/immutable/nodes/2.C-xl-nxy.js.gz +0 -0
  155. package/build/client/_app/immutable/nodes/3.BqDX5X09.js.br +0 -0
  156. package/build/client/_app/immutable/nodes/3.BqDX5X09.js.gz +0 -0
  157. package/build/server/chunks/0-DkD09WcK.js +0 -17
  158. package/build/server/chunks/1-CjtVgNYW.js +0 -9
  159. package/build/server/chunks/2-wstlfOP5.js +0 -9
  160. package/build/server/chunks/3-Cdn9_0OG.js +0 -9
  161. package/build/server/chunks/InputModal-XaplAR5y.js.map +0 -1
  162. package/build/server/chunks/Toast-ihrVamsT.js.map +0 -1
  163. package/build/server/chunks/_layout.svelte-COfbk473.js.map +0 -1
  164. package/build/server/chunks/_page.svelte-C5Xngf9U.js.map +0 -1
  165. package/build/server/chunks/_page.svelte-CKSi7jlX.js.map +0 -1
  166. package/build/server/chunks/_server.ts-BNGntgHD.js.map +0 -1
  167. package/build/server/chunks/_server.ts-BbeQOMoJ.js +0 -19
  168. package/build/server/chunks/_server.ts-BbeQOMoJ.js.map +0 -1
  169. package/build/server/chunks/_server.ts-CHX8x48n.js +0 -27
  170. package/build/server/chunks/_server.ts-CHX8x48n.js.map +0 -1
  171. package/build/server/chunks/_server.ts-a85289si.js.map +0 -1
  172. package/build/server/chunks/_server.ts-bj28Awpj.js.map +0 -1
  173. package/build/server/chunks/index-DzYX9r1_.js.map +0 -1
  174. package/build/server/chunks/index2-Da0doXJY.js.map +0 -1
  175. package/build/server/chunks/index3-DkgTDgY2.js.map +0 -1
  176. package/build/server/chunks/index4-BUZEWk-I.js.map +0 -1
@@ -1,8 +1,9 @@
1
1
  import * as fs from 'fs';
2
2
  import * as os from 'os';
3
- import * as path4 from 'path';
3
+ import * as path5 from 'path';
4
4
  import { Effect, pipe, Array as Array$1, Option } from 'effect';
5
- import * as fs4 from 'fs/promises';
5
+ import * as fs5 from 'fs/promises';
6
+ import * as crypto from 'crypto';
6
7
 
7
8
  var consoleLogger = {
8
9
  debug: (msg, ...args) => console.debug(`[DEBUG] ${msg}`, ...args),
@@ -18,8 +19,8 @@ var createLogger = (namespace) => ({
18
19
  error: (msg, ...args) => currentLogger.error(`[${namespace}] ${msg}`, ...args)
19
20
  });
20
21
  var log = createLogger("paths");
21
- var getSessionsDir = () => process.env.CLAUDE_SESSIONS_DIR || path4.join(os.homedir(), ".claude", "projects");
22
- var getTodosDir = () => path4.join(os.homedir(), ".claude", "todos");
22
+ var getSessionsDir = () => process.env.CLAUDE_SESSIONS_DIR || path5.join(os.homedir(), ".claude", "projects");
23
+ var getTodosDir = () => path5.join(os.homedir(), ".claude", "todos");
23
24
  var extractCwdFromContent = (content) => {
24
25
  const lines = content.split("\n").filter((l) => l.trim());
25
26
  for (const line of lines) {
@@ -65,7 +66,7 @@ var pathToFolderName = (absolutePath) => {
65
66
  return convertNonAscii(absolutePath).replace(/^\//g, "-").replace(/\/\./g, "--").replace(/\//g, "-").replace(/\./g, "-");
66
67
  };
67
68
  var tryGetCwdFromFile = (filePath, fileSystem = fs, logger2 = log) => {
68
- const basename3 = path4.basename(filePath);
69
+ const basename3 = path5.basename(filePath);
69
70
  try {
70
71
  const content = fileSystem.readFileSync(filePath, "utf-8");
71
72
  const cwd = extractCwdFromContent(content);
@@ -85,12 +86,12 @@ var tryGetCwdFromFile = (filePath, fileSystem = fs, logger2 = log) => {
85
86
  }
86
87
  };
87
88
  var getRealPathFromSession = (folderName, sessionsDir = getSessionsDir(), fileSystem = fs, logger2 = log) => {
88
- const projectDir = path4.join(sessionsDir, folderName);
89
+ const projectDir = path5.join(sessionsDir, folderName);
89
90
  try {
90
91
  const files = fileSystem.readdirSync(projectDir).filter(isSessionFile);
91
92
  const cwdList = [];
92
93
  for (const f of files) {
93
- const cwd = tryGetCwdFromFile(path4.join(projectDir, f), fileSystem, logger2);
94
+ const cwd = tryGetCwdFromFile(path5.join(projectDir, f), fileSystem, logger2);
94
95
  if (cwd !== null) {
95
96
  cwdList.push(cwd);
96
97
  }
@@ -137,14 +138,19 @@ var extractTextContent = (message) => {
137
138
  }
138
139
  return "";
139
140
  };
141
+ var parseCommandMessage = (content) => {
142
+ const name = content?.match(/<command-name>([^<]+)<\/command-name>/)?.[1] ?? "";
143
+ const message = content?.match(/<command-message>([^<]+)<\/command-message>/)?.[1] ?? "";
144
+ return { name, message };
145
+ };
140
146
  var extractTitle = (text) => {
141
147
  if (!text) return "Untitled";
148
+ const { name } = parseCommandMessage(text);
149
+ if (name) return name;
142
150
  let cleaned = text.replace(/<ide_[^>]*>[\s\S]*?<\/ide_[^>]*>/g, "").trim();
143
151
  if (!cleaned) return "Untitled";
144
152
  if (cleaned.includes("\n\n")) {
145
153
  cleaned = cleaned.split("\n\n")[0];
146
- } else if (cleaned.includes("\n")) {
147
- cleaned = cleaned.split("\n")[0];
148
154
  }
149
155
  if (cleaned.length > 100) {
150
156
  return cleaned.slice(0, 100) + "...";
@@ -177,7 +183,13 @@ var getDisplayTitle = (customTitle, currentSummary, title, maxLength = 60, fallb
177
183
  if (currentSummary) {
178
184
  return currentSummary.length > maxLength ? currentSummary.slice(0, maxLength - 3) + "..." : currentSummary;
179
185
  }
180
- if (title && title !== "Untitled") return title;
186
+ if (title && title !== "Untitled") {
187
+ if (title.includes("<command-name>")) {
188
+ const { name } = parseCommandMessage(title);
189
+ if (name) return name;
190
+ }
191
+ return title;
192
+ }
181
193
  return fallback;
182
194
  };
183
195
  var replaceMessageContent = (msg, text) => ({
@@ -231,14 +243,18 @@ var sortProjects = (projects, options = {}) => {
231
243
  return a.displayName.localeCompare(b.displayName);
232
244
  });
233
245
  };
246
+ var getSessionSortTimestamp = (session) => {
247
+ const timestampStr = session.summaries?.[0]?.timestamp ?? session.createdAt;
248
+ return timestampStr ? new Date(timestampStr).getTime() : 0;
249
+ };
234
250
  var findLinkedAgents = (projectName, sessionId) => Effect.gen(function* () {
235
- const projectPath = path4.join(getSessionsDir(), projectName);
236
- const files = yield* Effect.tryPromise(() => fs4.readdir(projectPath));
251
+ const projectPath = path5.join(getSessionsDir(), projectName);
252
+ const files = yield* Effect.tryPromise(() => fs5.readdir(projectPath));
237
253
  const agentFiles = files.filter((f) => f.startsWith("agent-") && f.endsWith(".jsonl"));
238
254
  const linkedAgents = [];
239
255
  for (const agentFile of agentFiles) {
240
- const filePath = path4.join(projectPath, agentFile);
241
- const content = yield* Effect.tryPromise(() => fs4.readFile(filePath, "utf-8"));
256
+ const filePath = path5.join(projectPath, agentFile);
257
+ const content = yield* Effect.tryPromise(() => fs5.readFile(filePath, "utf-8"));
242
258
  const firstLine = content.split("\n")[0];
243
259
  if (firstLine) {
244
260
  try {
@@ -253,21 +269,21 @@ var findLinkedAgents = (projectName, sessionId) => Effect.gen(function* () {
253
269
  return linkedAgents;
254
270
  });
255
271
  var findOrphanAgentsWithPaths = (projectName) => Effect.gen(function* () {
256
- const projectPath = path4.join(getSessionsDir(), projectName);
257
- const files = yield* Effect.tryPromise(() => fs4.readdir(projectPath));
272
+ const projectPath = path5.join(getSessionsDir(), projectName);
273
+ const files = yield* Effect.tryPromise(() => fs5.readdir(projectPath));
258
274
  const sessionIds = new Set(
259
275
  files.filter((f) => !f.startsWith("agent-") && f.endsWith(".jsonl")).map((f) => f.replace(".jsonl", ""))
260
276
  );
261
277
  const orphanAgents = [];
262
278
  const checkAgentFile = async (filePath) => {
263
279
  try {
264
- const content = await fs4.readFile(filePath, "utf-8");
280
+ const content = await fs5.readFile(filePath, "utf-8");
265
281
  const lines = content.split("\n").filter((l) => l.trim());
266
282
  const firstLine = lines[0];
267
283
  if (!firstLine) return null;
268
284
  const parsed = JSON.parse(firstLine);
269
285
  if (parsed.sessionId && !sessionIds.has(parsed.sessionId)) {
270
- const fileName = path4.basename(filePath);
286
+ const fileName = path5.basename(filePath);
271
287
  return {
272
288
  agentId: fileName.replace(".jsonl", ""),
273
289
  sessionId: parsed.sessionId,
@@ -280,27 +296,27 @@ var findOrphanAgentsWithPaths = (projectName) => Effect.gen(function* () {
280
296
  };
281
297
  const rootAgentFiles = files.filter((f) => f.startsWith("agent-") && f.endsWith(".jsonl"));
282
298
  for (const agentFile of rootAgentFiles) {
283
- const filePath = path4.join(projectPath, agentFile);
299
+ const filePath = path5.join(projectPath, agentFile);
284
300
  const orphan = yield* Effect.tryPromise(() => checkAgentFile(filePath));
285
301
  if (orphan) {
286
302
  orphanAgents.push({ ...orphan, filePath });
287
303
  }
288
304
  }
289
305
  for (const entry of files) {
290
- const entryPath = path4.join(projectPath, entry);
291
- const stat3 = yield* Effect.tryPromise(() => fs4.stat(entryPath).catch(() => null));
292
- if (stat3?.isDirectory() && !entry.startsWith(".")) {
293
- const subagentsPath = path4.join(entryPath, "subagents");
306
+ const entryPath = path5.join(projectPath, entry);
307
+ const stat4 = yield* Effect.tryPromise(() => fs5.stat(entryPath).catch(() => null));
308
+ if (stat4?.isDirectory() && !entry.startsWith(".")) {
309
+ const subagentsPath = path5.join(entryPath, "subagents");
294
310
  const subagentsExists = yield* Effect.tryPromise(
295
- () => fs4.stat(subagentsPath).then(() => true).catch(() => false)
311
+ () => fs5.stat(subagentsPath).then(() => true).catch(() => false)
296
312
  );
297
313
  if (subagentsExists) {
298
314
  const subagentFiles = yield* Effect.tryPromise(
299
- () => fs4.readdir(subagentsPath).catch(() => [])
315
+ () => fs5.readdir(subagentsPath).catch(() => [])
300
316
  );
301
317
  for (const subagentFile of subagentFiles) {
302
318
  if (subagentFile.startsWith("agent-") && subagentFile.endsWith(".jsonl")) {
303
- const filePath = path4.join(subagentsPath, subagentFile);
319
+ const filePath = path5.join(subagentsPath, subagentFile);
304
320
  const orphan = yield* Effect.tryPromise(() => checkAgentFile(filePath));
305
321
  if (orphan) {
306
322
  orphanAgents.push({ ...orphan, filePath });
@@ -317,7 +333,7 @@ var findOrphanAgents = (projectName) => Effect.gen(function* () {
317
333
  return orphans.map(({ agentId, sessionId }) => ({ agentId, sessionId }));
318
334
  });
319
335
  var deleteOrphanAgents = (projectName) => Effect.gen(function* () {
320
- const projectPath = path4.join(getSessionsDir(), projectName);
336
+ const projectPath = path5.join(getSessionsDir(), projectName);
321
337
  const orphans = yield* findOrphanAgentsWithPaths(projectName);
322
338
  const deletedAgents = [];
323
339
  const backedUpAgents = [];
@@ -325,40 +341,40 @@ var deleteOrphanAgents = (projectName) => Effect.gen(function* () {
325
341
  let backupDirCreated = false;
326
342
  const foldersToCheck = /* @__PURE__ */ new Set();
327
343
  for (const orphan of orphans) {
328
- const parentDir = path4.dirname(orphan.filePath);
344
+ const parentDir = path5.dirname(orphan.filePath);
329
345
  if (parentDir.endsWith("/subagents") || parentDir.endsWith("\\subagents")) {
330
346
  foldersToCheck.add(parentDir);
331
347
  }
332
348
  if (orphan.lineCount <= 2) {
333
- yield* Effect.tryPromise(() => fs4.unlink(orphan.filePath));
349
+ yield* Effect.tryPromise(() => fs5.unlink(orphan.filePath));
334
350
  deletedAgents.push(orphan.agentId);
335
351
  } else {
336
352
  if (!backupDirCreated) {
337
- const backupDir2 = path4.join(projectPath, ".bak");
338
- yield* Effect.tryPromise(() => fs4.mkdir(backupDir2, { recursive: true }));
353
+ const backupDir2 = path5.join(projectPath, ".bak");
354
+ yield* Effect.tryPromise(() => fs5.mkdir(backupDir2, { recursive: true }));
339
355
  backupDirCreated = true;
340
356
  }
341
- const backupDir = path4.join(projectPath, ".bak");
342
- const agentBackupPath = path4.join(backupDir, `${orphan.agentId}.jsonl`);
343
- yield* Effect.tryPromise(() => fs4.rename(orphan.filePath, agentBackupPath));
357
+ const backupDir = path5.join(projectPath, ".bak");
358
+ const agentBackupPath = path5.join(backupDir, `${orphan.agentId}.jsonl`);
359
+ yield* Effect.tryPromise(() => fs5.rename(orphan.filePath, agentBackupPath));
344
360
  backedUpAgents.push(orphan.agentId);
345
361
  }
346
362
  }
347
363
  for (const subagentsDir of foldersToCheck) {
348
364
  const isEmpty = yield* Effect.tryPromise(async () => {
349
- const files = await fs4.readdir(subagentsDir);
365
+ const files = await fs5.readdir(subagentsDir);
350
366
  return files.length === 0;
351
367
  });
352
368
  if (isEmpty) {
353
- yield* Effect.tryPromise(() => fs4.rmdir(subagentsDir));
369
+ yield* Effect.tryPromise(() => fs5.rmdir(subagentsDir));
354
370
  cleanedFolders.push(subagentsDir);
355
- const sessionDir = path4.dirname(subagentsDir);
371
+ const sessionDir = path5.dirname(subagentsDir);
356
372
  const sessionDirEmpty = yield* Effect.tryPromise(async () => {
357
- const files = await fs4.readdir(sessionDir);
373
+ const files = await fs5.readdir(sessionDir);
358
374
  return files.length === 0;
359
375
  });
360
376
  if (sessionDirEmpty) {
361
- yield* Effect.tryPromise(() => fs4.rmdir(sessionDir));
377
+ yield* Effect.tryPromise(() => fs5.rmdir(sessionDir));
362
378
  cleanedFolders.push(sessionDir);
363
379
  }
364
380
  }
@@ -375,9 +391,9 @@ var deleteOrphanAgents = (projectName) => Effect.gen(function* () {
375
391
  };
376
392
  });
377
393
  var loadAgentMessages = (projectName, _sessionId, agentId) => Effect.gen(function* () {
378
- const projectPath = path4.join(getSessionsDir(), projectName);
379
- const agentFilePath = path4.join(projectPath, `${agentId}.jsonl`);
380
- const content = yield* Effect.tryPromise(() => fs4.readFile(agentFilePath, "utf-8"));
394
+ const projectPath = path5.join(getSessionsDir(), projectName);
395
+ const agentFilePath = path5.join(projectPath, `${agentId}.jsonl`);
396
+ const content = yield* Effect.tryPromise(() => fs5.readFile(agentFilePath, "utf-8"));
381
397
  const lines = content.split("\n").filter((line) => line.trim());
382
398
  const messages = [];
383
399
  for (const line of lines) {
@@ -395,29 +411,24 @@ var loadAgentMessages = (projectName, _sessionId, agentId) => Effect.gen(functio
395
411
  var findLinkedTodos = (sessionId, agentIds = []) => Effect.gen(function* () {
396
412
  const todosDir = getTodosDir();
397
413
  const exists = yield* Effect.tryPromise(
398
- () => fs4.access(todosDir).then(() => true).catch(() => false)
414
+ () => fs5.access(todosDir).then(() => true).catch(() => false)
399
415
  );
400
416
  if (!exists) {
401
- return {
402
- sessionId,
403
- sessionTodos: [],
404
- agentTodos: [],
405
- hasTodos: false
406
- };
417
+ return void 0;
407
418
  }
408
- const sessionTodoPath = path4.join(todosDir, `${sessionId}.json`);
419
+ const sessionTodoPath = path5.join(todosDir, `${sessionId}.json`);
409
420
  let sessionTodos = [];
410
421
  const sessionTodoExists = yield* Effect.tryPromise(
411
- () => fs4.access(sessionTodoPath).then(() => true).catch(() => false)
422
+ () => fs5.access(sessionTodoPath).then(() => true).catch(() => false)
412
423
  );
413
424
  if (sessionTodoExists) {
414
- const content = yield* Effect.tryPromise(() => fs4.readFile(sessionTodoPath, "utf-8"));
425
+ const content = yield* Effect.tryPromise(() => fs5.readFile(sessionTodoPath, "utf-8"));
415
426
  try {
416
427
  sessionTodos = JSON.parse(content);
417
428
  } catch {
418
429
  }
419
430
  }
420
- const allFiles = yield* Effect.tryPromise(() => fs4.readdir(todosDir));
431
+ const allFiles = yield* Effect.tryPromise(() => fs5.readdir(todosDir));
421
432
  const agentTodoPattern = new RegExp(`^${sessionId}-agent-([a-f0-9-]+)\\.json$`);
422
433
  const discoveredAgentIds = new Set(agentIds);
423
434
  for (const file of allFiles) {
@@ -429,12 +440,12 @@ var findLinkedTodos = (sessionId, agentIds = []) => Effect.gen(function* () {
429
440
  const agentTodos = [];
430
441
  for (const agentId of discoveredAgentIds) {
431
442
  const shortAgentId = agentId.replace("agent-", "");
432
- const agentTodoPath = path4.join(todosDir, `${sessionId}-agent-${shortAgentId}.json`);
443
+ const agentTodoPath = path5.join(todosDir, `${sessionId}-agent-${shortAgentId}.json`);
433
444
  const agentTodoExists = yield* Effect.tryPromise(
434
- () => fs4.access(agentTodoPath).then(() => true).catch(() => false)
445
+ () => fs5.access(agentTodoPath).then(() => true).catch(() => false)
435
446
  );
436
447
  if (agentTodoExists) {
437
- const content = yield* Effect.tryPromise(() => fs4.readFile(agentTodoPath, "utf-8"));
448
+ const content = yield* Effect.tryPromise(() => fs5.readFile(agentTodoPath, "utf-8"));
438
449
  try {
439
450
  const todos = JSON.parse(content);
440
451
  if (todos.length > 0) {
@@ -455,22 +466,22 @@ var findLinkedTodos = (sessionId, agentIds = []) => Effect.gen(function* () {
455
466
  var sessionHasTodos = (sessionId, agentIds = []) => Effect.gen(function* () {
456
467
  const todosDir = getTodosDir();
457
468
  const exists = yield* Effect.tryPromise(
458
- () => fs4.access(todosDir).then(() => true).catch(() => false)
469
+ () => fs5.access(todosDir).then(() => true).catch(() => false)
459
470
  );
460
471
  if (!exists) return false;
461
- const sessionTodoPath = path4.join(todosDir, `${sessionId}.json`);
472
+ const sessionTodoPath = path5.join(todosDir, `${sessionId}.json`);
462
473
  const sessionTodoExists = yield* Effect.tryPromise(
463
- () => fs4.access(sessionTodoPath).then(() => true).catch(() => false)
474
+ () => fs5.access(sessionTodoPath).then(() => true).catch(() => false)
464
475
  );
465
476
  if (sessionTodoExists) {
466
- const content = yield* Effect.tryPromise(() => fs4.readFile(sessionTodoPath, "utf-8"));
477
+ const content = yield* Effect.tryPromise(() => fs5.readFile(sessionTodoPath, "utf-8"));
467
478
  try {
468
479
  const todos = JSON.parse(content);
469
480
  if (todos.length > 0) return true;
470
481
  } catch {
471
482
  }
472
483
  }
473
- const allFiles = yield* Effect.tryPromise(() => fs4.readdir(todosDir));
484
+ const allFiles = yield* Effect.tryPromise(() => fs5.readdir(todosDir));
474
485
  const agentTodoPattern = new RegExp(`^${sessionId}-agent-([a-f0-9-]+)\\.json$`);
475
486
  const discoveredAgentIds = new Set(agentIds);
476
487
  for (const file of allFiles) {
@@ -481,12 +492,12 @@ var sessionHasTodos = (sessionId, agentIds = []) => Effect.gen(function* () {
481
492
  }
482
493
  for (const agentId of discoveredAgentIds) {
483
494
  const shortAgentId = agentId.replace("agent-", "");
484
- const agentTodoPath = path4.join(todosDir, `${sessionId}-agent-${shortAgentId}.json`);
495
+ const agentTodoPath = path5.join(todosDir, `${sessionId}-agent-${shortAgentId}.json`);
485
496
  const agentTodoExists = yield* Effect.tryPromise(
486
- () => fs4.access(agentTodoPath).then(() => true).catch(() => false)
497
+ () => fs5.access(agentTodoPath).then(() => true).catch(() => false)
487
498
  );
488
499
  if (agentTodoExists) {
489
- const content = yield* Effect.tryPromise(() => fs4.readFile(agentTodoPath, "utf-8"));
500
+ const content = yield* Effect.tryPromise(() => fs5.readFile(agentTodoPath, "utf-8"));
490
501
  try {
491
502
  const todos = JSON.parse(content);
492
503
  if (todos.length > 0) return true;
@@ -499,30 +510,30 @@ var sessionHasTodos = (sessionId, agentIds = []) => Effect.gen(function* () {
499
510
  var deleteLinkedTodos = (sessionId, agentIds) => Effect.gen(function* () {
500
511
  const todosDir = getTodosDir();
501
512
  const exists = yield* Effect.tryPromise(
502
- () => fs4.access(todosDir).then(() => true).catch(() => false)
513
+ () => fs5.access(todosDir).then(() => true).catch(() => false)
503
514
  );
504
515
  if (!exists) return { deletedCount: 0 };
505
- const backupDir = path4.join(todosDir, ".bak");
506
- yield* Effect.tryPromise(() => fs4.mkdir(backupDir, { recursive: true }));
516
+ const backupDir = path5.join(todosDir, ".bak");
517
+ yield* Effect.tryPromise(() => fs5.mkdir(backupDir, { recursive: true }));
507
518
  let deletedCount = 0;
508
- const sessionTodoPath = path4.join(todosDir, `${sessionId}.json`);
519
+ const sessionTodoPath = path5.join(todosDir, `${sessionId}.json`);
509
520
  const sessionTodoExists = yield* Effect.tryPromise(
510
- () => fs4.access(sessionTodoPath).then(() => true).catch(() => false)
521
+ () => fs5.access(sessionTodoPath).then(() => true).catch(() => false)
511
522
  );
512
523
  if (sessionTodoExists) {
513
- const backupPath = path4.join(backupDir, `${sessionId}.json`);
514
- yield* Effect.tryPromise(() => fs4.rename(sessionTodoPath, backupPath));
524
+ const backupPath = path5.join(backupDir, `${sessionId}.json`);
525
+ yield* Effect.tryPromise(() => fs5.rename(sessionTodoPath, backupPath));
515
526
  deletedCount++;
516
527
  }
517
528
  for (const agentId of agentIds) {
518
529
  const shortAgentId = agentId.replace("agent-", "");
519
- const agentTodoPath = path4.join(todosDir, `${sessionId}-agent-${shortAgentId}.json`);
530
+ const agentTodoPath = path5.join(todosDir, `${sessionId}-agent-${shortAgentId}.json`);
520
531
  const agentTodoExists = yield* Effect.tryPromise(
521
- () => fs4.access(agentTodoPath).then(() => true).catch(() => false)
532
+ () => fs5.access(agentTodoPath).then(() => true).catch(() => false)
522
533
  );
523
534
  if (agentTodoExists) {
524
- const backupPath = path4.join(backupDir, `${sessionId}-agent-${shortAgentId}.json`);
525
- yield* Effect.tryPromise(() => fs4.rename(agentTodoPath, backupPath));
535
+ const backupPath = path5.join(backupDir, `${sessionId}-agent-${shortAgentId}.json`);
536
+ yield* Effect.tryPromise(() => fs5.rename(agentTodoPath, backupPath));
526
537
  deletedCount++;
527
538
  }
528
539
  }
@@ -533,23 +544,23 @@ var findOrphanTodos = () => Effect.gen(function* () {
533
544
  const sessionsDir = getSessionsDir();
534
545
  const [todosExists, sessionsExists] = yield* Effect.all([
535
546
  Effect.tryPromise(
536
- () => fs4.access(todosDir).then(() => true).catch(() => false)
547
+ () => fs5.access(todosDir).then(() => true).catch(() => false)
537
548
  ),
538
549
  Effect.tryPromise(
539
- () => fs4.access(sessionsDir).then(() => true).catch(() => false)
550
+ () => fs5.access(sessionsDir).then(() => true).catch(() => false)
540
551
  )
541
552
  ]);
542
553
  if (!todosExists || !sessionsExists) return [];
543
- const todoFiles = yield* Effect.tryPromise(() => fs4.readdir(todosDir));
554
+ const todoFiles = yield* Effect.tryPromise(() => fs5.readdir(todosDir));
544
555
  const jsonFiles = todoFiles.filter((f) => f.endsWith(".json"));
545
556
  const validSessionIds = /* @__PURE__ */ new Set();
546
557
  const projectEntries = yield* Effect.tryPromise(
547
- () => fs4.readdir(sessionsDir, { withFileTypes: true })
558
+ () => fs5.readdir(sessionsDir, { withFileTypes: true })
548
559
  );
549
560
  for (const entry of projectEntries) {
550
561
  if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
551
- const projectPath = path4.join(sessionsDir, entry.name);
552
- const files = yield* Effect.tryPromise(() => fs4.readdir(projectPath));
562
+ const projectPath = path5.join(sessionsDir, entry.name);
563
+ const files = yield* Effect.tryPromise(() => fs5.readdir(projectPath));
553
564
  for (const f of files) {
554
565
  if (f.endsWith(".jsonl") && !f.startsWith("agent-")) {
555
566
  validSessionIds.add(f.replace(".jsonl", ""));
@@ -572,13 +583,13 @@ var deleteOrphanTodos = () => Effect.gen(function* () {
572
583
  const todosDir = getTodosDir();
573
584
  const orphans = yield* findOrphanTodos();
574
585
  if (orphans.length === 0) return { success: true, deletedCount: 0 };
575
- const backupDir = path4.join(todosDir, ".bak");
576
- yield* Effect.tryPromise(() => fs4.mkdir(backupDir, { recursive: true }));
586
+ const backupDir = path5.join(todosDir, ".bak");
587
+ yield* Effect.tryPromise(() => fs5.mkdir(backupDir, { recursive: true }));
577
588
  let deletedCount = 0;
578
589
  for (const orphan of orphans) {
579
- const filePath = path4.join(todosDir, orphan);
580
- const backupPath = path4.join(backupDir, orphan);
581
- yield* Effect.tryPromise(() => fs4.rename(filePath, backupPath));
590
+ const filePath = path5.join(todosDir, orphan);
591
+ const backupPath = path5.join(backupDir, orphan);
592
+ yield* Effect.tryPromise(() => fs5.rename(filePath, backupPath));
582
593
  deletedCount++;
583
594
  }
584
595
  return { success: true, deletedCount };
@@ -586,17 +597,17 @@ var deleteOrphanTodos = () => Effect.gen(function* () {
586
597
  var listProjects = Effect.gen(function* () {
587
598
  const sessionsDir = getSessionsDir();
588
599
  const exists = yield* Effect.tryPromise(
589
- () => fs4.access(sessionsDir).then(() => true).catch(() => false)
600
+ () => fs5.access(sessionsDir).then(() => true).catch(() => false)
590
601
  );
591
602
  if (!exists) {
592
603
  return [];
593
604
  }
594
- const entries = yield* Effect.tryPromise(() => fs4.readdir(sessionsDir, { withFileTypes: true }));
605
+ const entries = yield* Effect.tryPromise(() => fs5.readdir(sessionsDir, { withFileTypes: true }));
595
606
  const projects = yield* Effect.all(
596
607
  entries.filter((e) => e.isDirectory() && !e.name.startsWith(".")).map(
597
608
  (entry) => Effect.gen(function* () {
598
- const projectPath = path4.join(sessionsDir, entry.name);
599
- const files = yield* Effect.tryPromise(() => fs4.readdir(projectPath));
609
+ const projectPath = path5.join(sessionsDir, entry.name);
610
+ const files = yield* Effect.tryPromise(() => fs5.readdir(projectPath));
600
611
  const sessionFiles = files.filter((f) => f.endsWith(".jsonl") && !f.startsWith("agent-"));
601
612
  return {
602
613
  name: entry.name,
@@ -610,15 +621,82 @@ var listProjects = Effect.gen(function* () {
610
621
  );
611
622
  return projects;
612
623
  });
624
+ function deleteMessageWithChainRepair(messages, targetId, targetType) {
625
+ let targetIndex = -1;
626
+ {
627
+ targetIndex = messages.findIndex((m) => m.uuid === targetId);
628
+ if (targetIndex === -1) {
629
+ targetIndex = messages.findIndex(
630
+ (m) => m.leafUuid === targetId
631
+ );
632
+ }
633
+ if (targetIndex === -1) {
634
+ targetIndex = messages.findIndex(
635
+ (m) => m.type === "file-history-snapshot" && m.messageId === targetId
636
+ );
637
+ }
638
+ }
639
+ if (targetIndex === -1) {
640
+ return { deleted: null, alsoDeleted: [] };
641
+ }
642
+ const deletedMsg = messages[targetIndex];
643
+ const toolUseIds = [];
644
+ if (deletedMsg.type === "assistant") {
645
+ const content = deletedMsg.message?.content;
646
+ if (Array.isArray(content)) {
647
+ for (const item of content) {
648
+ if (item.type === "tool_use" && item.id) {
649
+ toolUseIds.push(item.id);
650
+ }
651
+ }
652
+ }
653
+ }
654
+ const toolResultIndices = [];
655
+ if (toolUseIds.length > 0) {
656
+ for (let i = 0; i < messages.length; i++) {
657
+ const msg = messages[i];
658
+ if (msg.type === "user") {
659
+ const content = msg.message?.content;
660
+ if (Array.isArray(content)) {
661
+ for (const item of content) {
662
+ if (item.type === "tool_result" && item.tool_use_id && toolUseIds.includes(item.tool_use_id)) {
663
+ toolResultIndices.push(i);
664
+ break;
665
+ }
666
+ }
667
+ }
668
+ }
669
+ }
670
+ }
671
+ const indicesToDelete = [targetIndex, ...toolResultIndices].sort((a, b) => b - a);
672
+ for (const idx of indicesToDelete) {
673
+ const msg = messages[idx];
674
+ const isInParentChain = msg.type !== "file-history-snapshot" && msg.uuid;
675
+ if (isInParentChain) {
676
+ const deletedUuid = msg.uuid;
677
+ const parentUuid = msg.parentUuid;
678
+ for (const m of messages) {
679
+ if (m.parentUuid === deletedUuid) {
680
+ m.parentUuid = parentUuid;
681
+ }
682
+ }
683
+ }
684
+ }
685
+ const alsoDeleted = toolResultIndices.map((i) => messages[i]);
686
+ for (const idx of indicesToDelete) {
687
+ messages.splice(idx, 1);
688
+ }
689
+ return { deleted: deletedMsg, alsoDeleted };
690
+ }
613
691
  var listSessions = (projectName) => Effect.gen(function* () {
614
- const projectPath = path4.join(getSessionsDir(), projectName);
615
- const files = yield* Effect.tryPromise(() => fs4.readdir(projectPath));
692
+ const projectPath = path5.join(getSessionsDir(), projectName);
693
+ const files = yield* Effect.tryPromise(() => fs5.readdir(projectPath));
616
694
  const sessionFiles = files.filter((f) => f.endsWith(".jsonl") && !f.startsWith("agent-"));
617
695
  const sessions = yield* Effect.all(
618
696
  sessionFiles.map(
619
697
  (file) => Effect.gen(function* () {
620
- const filePath = path4.join(projectPath, file);
621
- const content = yield* Effect.tryPromise(() => fs4.readFile(filePath, "utf-8"));
698
+ const filePath = path5.join(projectPath, file);
699
+ const content = yield* Effect.tryPromise(() => fs5.readFile(filePath, "utf-8"));
622
700
  const lines = content.trim().split("\n").filter(Boolean);
623
701
  const messages = lines.map((line) => JSON.parse(line));
624
702
  const sessionId = file.replace(".jsonl", "");
@@ -637,10 +715,25 @@ var listSessions = (projectName) => Effect.gen(function* () {
637
715
  }),
638
716
  Option.getOrElse(() => hasSummary ? "[Summary Only]" : `Session ${sessionId.slice(0, 8)}`)
639
717
  );
718
+ const currentSummary = pipe(
719
+ messages,
720
+ Array$1.findFirst((m) => m.type === "summary"),
721
+ Option.map((m) => m.summary),
722
+ Option.getOrUndefined
723
+ );
724
+ const customTitle = pipe(
725
+ messages,
726
+ Array$1.findFirst((m) => m.type === "custom-title"),
727
+ Option.map((m) => m.customTitle),
728
+ Option.flatMap(Option.fromNullable),
729
+ Option.getOrUndefined
730
+ );
640
731
  return {
641
732
  id: sessionId,
642
733
  projectName,
643
734
  title,
735
+ customTitle,
736
+ currentSummary,
644
737
  // If session has summary but no user/assistant messages, count as 1
645
738
  messageCount: userAssistantMessages.length > 0 ? userAssistantMessages.length : hasSummary ? 1 : 0,
646
739
  createdAt: firstMessage?.timestamp,
@@ -657,38 +750,27 @@ var listSessions = (projectName) => Effect.gen(function* () {
657
750
  });
658
751
  });
659
752
  var readSession = (projectName, sessionId) => Effect.gen(function* () {
660
- const filePath = path4.join(getSessionsDir(), projectName, `${sessionId}.jsonl`);
661
- const content = yield* Effect.tryPromise(() => fs4.readFile(filePath, "utf-8"));
753
+ const filePath = path5.join(getSessionsDir(), projectName, `${sessionId}.jsonl`);
754
+ const content = yield* Effect.tryPromise(() => fs5.readFile(filePath, "utf-8"));
662
755
  const lines = content.trim().split("\n").filter(Boolean);
663
756
  return lines.map((line) => JSON.parse(line));
664
757
  });
665
- var deleteMessage = (projectName, sessionId, messageUuid) => Effect.gen(function* () {
666
- const filePath = path4.join(getSessionsDir(), projectName, `${sessionId}.jsonl`);
667
- const content = yield* Effect.tryPromise(() => fs4.readFile(filePath, "utf-8"));
758
+ var deleteMessage = (projectName, sessionId, messageUuid, targetType) => Effect.gen(function* () {
759
+ const filePath = path5.join(getSessionsDir(), projectName, `${sessionId}.jsonl`);
760
+ const content = yield* Effect.tryPromise(() => fs5.readFile(filePath, "utf-8"));
668
761
  const lines = content.trim().split("\n").filter(Boolean);
669
762
  const messages = lines.map((line) => JSON.parse(line));
670
- const targetIndex = messages.findIndex(
671
- (m) => m.uuid === messageUuid || m.messageId === messageUuid || m.leafUuid === messageUuid
672
- );
673
- if (targetIndex === -1) {
763
+ const result = deleteMessageWithChainRepair(messages, messageUuid);
764
+ if (!result.deleted) {
674
765
  return { success: false, error: "Message not found" };
675
766
  }
676
- const deletedMsg = messages[targetIndex];
677
- const deletedUuid = deletedMsg?.uuid ?? deletedMsg?.messageId;
678
- const parentUuid = deletedMsg?.parentUuid;
679
- for (const msg of messages) {
680
- if (msg.parentUuid === deletedUuid) {
681
- msg.parentUuid = parentUuid;
682
- }
683
- }
684
- messages.splice(targetIndex, 1);
685
767
  const newContent = messages.map((m) => JSON.stringify(m)).join("\n") + "\n";
686
- yield* Effect.tryPromise(() => fs4.writeFile(filePath, newContent, "utf-8"));
687
- return { success: true, deletedMessage: deletedMsg };
768
+ yield* Effect.tryPromise(() => fs5.writeFile(filePath, newContent, "utf-8"));
769
+ return { success: true, deletedMessage: result.deleted };
688
770
  });
689
771
  var restoreMessage = (projectName, sessionId, message, index) => Effect.gen(function* () {
690
- const filePath = path4.join(getSessionsDir(), projectName, `${sessionId}.jsonl`);
691
- const content = yield* Effect.tryPromise(() => fs4.readFile(filePath, "utf-8"));
772
+ const filePath = path5.join(getSessionsDir(), projectName, `${sessionId}.jsonl`);
773
+ const content = yield* Effect.tryPromise(() => fs5.readFile(filePath, "utf-8"));
692
774
  const lines = content.trim().split("\n").filter(Boolean);
693
775
  const messages = lines.map((line) => JSON.parse(line));
694
776
  const msgUuid = message.uuid ?? message.messageId;
@@ -705,41 +787,41 @@ var restoreMessage = (projectName, sessionId, message, index) => Effect.gen(func
705
787
  const insertIndex = Math.min(index, messages.length);
706
788
  messages.splice(insertIndex, 0, message);
707
789
  const newContent = messages.map((m) => JSON.stringify(m)).join("\n") + "\n";
708
- yield* Effect.tryPromise(() => fs4.writeFile(filePath, newContent, "utf-8"));
790
+ yield* Effect.tryPromise(() => fs5.writeFile(filePath, newContent, "utf-8"));
709
791
  return { success: true };
710
792
  });
711
793
  var deleteSession = (projectName, sessionId) => Effect.gen(function* () {
712
794
  const sessionsDir = getSessionsDir();
713
- const projectPath = path4.join(sessionsDir, projectName);
714
- const filePath = path4.join(projectPath, `${sessionId}.jsonl`);
795
+ const projectPath = path5.join(sessionsDir, projectName);
796
+ const filePath = path5.join(projectPath, `${sessionId}.jsonl`);
715
797
  const linkedAgents = yield* findLinkedAgents(projectName, sessionId);
716
- const stat3 = yield* Effect.tryPromise(() => fs4.stat(filePath));
717
- if (stat3.size === 0) {
718
- yield* Effect.tryPromise(() => fs4.unlink(filePath));
719
- const agentBackupDir2 = path4.join(projectPath, ".bak");
720
- yield* Effect.tryPromise(() => fs4.mkdir(agentBackupDir2, { recursive: true }));
798
+ const stat4 = yield* Effect.tryPromise(() => fs5.stat(filePath));
799
+ if (stat4.size === 0) {
800
+ yield* Effect.tryPromise(() => fs5.unlink(filePath));
801
+ const agentBackupDir2 = path5.join(projectPath, ".bak");
802
+ yield* Effect.tryPromise(() => fs5.mkdir(agentBackupDir2, { recursive: true }));
721
803
  for (const agentId of linkedAgents) {
722
- const agentPath = path4.join(projectPath, `${agentId}.jsonl`);
723
- const agentBackupPath = path4.join(agentBackupDir2, `${agentId}.jsonl`);
724
- yield* Effect.tryPromise(() => fs4.rename(agentPath, agentBackupPath).catch(() => {
804
+ const agentPath = path5.join(projectPath, `${agentId}.jsonl`);
805
+ const agentBackupPath = path5.join(agentBackupDir2, `${agentId}.jsonl`);
806
+ yield* Effect.tryPromise(() => fs5.rename(agentPath, agentBackupPath).catch(() => {
725
807
  }));
726
808
  }
727
809
  yield* deleteLinkedTodos(sessionId, linkedAgents);
728
810
  return { success: true, deletedAgents: linkedAgents.length };
729
811
  }
730
- const backupDir = path4.join(sessionsDir, ".bak");
731
- yield* Effect.tryPromise(() => fs4.mkdir(backupDir, { recursive: true }));
732
- const agentBackupDir = path4.join(projectPath, ".bak");
733
- yield* Effect.tryPromise(() => fs4.mkdir(agentBackupDir, { recursive: true }));
812
+ const backupDir = path5.join(sessionsDir, ".bak");
813
+ yield* Effect.tryPromise(() => fs5.mkdir(backupDir, { recursive: true }));
814
+ const agentBackupDir = path5.join(projectPath, ".bak");
815
+ yield* Effect.tryPromise(() => fs5.mkdir(agentBackupDir, { recursive: true }));
734
816
  for (const agentId of linkedAgents) {
735
- const agentPath = path4.join(projectPath, `${agentId}.jsonl`);
736
- const agentBackupPath = path4.join(agentBackupDir, `${agentId}.jsonl`);
737
- yield* Effect.tryPromise(() => fs4.rename(agentPath, agentBackupPath).catch(() => {
817
+ const agentPath = path5.join(projectPath, `${agentId}.jsonl`);
818
+ const agentBackupPath = path5.join(agentBackupDir, `${agentId}.jsonl`);
819
+ yield* Effect.tryPromise(() => fs5.rename(agentPath, agentBackupPath).catch(() => {
738
820
  }));
739
821
  }
740
822
  const todosResult = yield* deleteLinkedTodos(sessionId, linkedAgents);
741
- const backupPath = path4.join(backupDir, `${projectName}_${sessionId}.jsonl`);
742
- yield* Effect.tryPromise(() => fs4.rename(filePath, backupPath));
823
+ const backupPath = path5.join(backupDir, `${projectName}_${sessionId}.jsonl`);
824
+ yield* Effect.tryPromise(() => fs5.rename(filePath, backupPath));
743
825
  return {
744
826
  success: true,
745
827
  backupPath,
@@ -748,9 +830,9 @@ var deleteSession = (projectName, sessionId) => Effect.gen(function* () {
748
830
  };
749
831
  });
750
832
  var renameSession = (projectName, sessionId, newTitle) => Effect.gen(function* () {
751
- const projectPath = path4.join(getSessionsDir(), projectName);
752
- const filePath = path4.join(projectPath, `${sessionId}.jsonl`);
753
- const content = yield* Effect.tryPromise(() => fs4.readFile(filePath, "utf-8"));
833
+ const projectPath = path5.join(getSessionsDir(), projectName);
834
+ const filePath = path5.join(projectPath, `${sessionId}.jsonl`);
835
+ const content = yield* Effect.tryPromise(() => fs5.readFile(filePath, "utf-8"));
754
836
  const lines = content.trim().split("\n").filter(Boolean);
755
837
  if (lines.length === 0) {
756
838
  return { success: false, error: "Empty session" };
@@ -774,14 +856,14 @@ var renameSession = (projectName, sessionId, newTitle) => Effect.gen(function* (
774
856
  messages.unshift(customTitleRecord);
775
857
  }
776
858
  const newContent = messages.map((m) => JSON.stringify(m)).join("\n") + "\n";
777
- yield* Effect.tryPromise(() => fs4.writeFile(filePath, newContent, "utf-8"));
778
- const projectFiles = yield* Effect.tryPromise(() => fs4.readdir(projectPath));
859
+ yield* Effect.tryPromise(() => fs5.writeFile(filePath, newContent, "utf-8"));
860
+ const projectFiles = yield* Effect.tryPromise(() => fs5.readdir(projectPath));
779
861
  const allJsonlFiles = projectFiles.filter((f) => f.endsWith(".jsonl"));
780
862
  const summariesTargetingThis = [];
781
863
  for (const file of allJsonlFiles) {
782
- const otherFilePath = path4.join(projectPath, file);
864
+ const otherFilePath = path5.join(projectPath, file);
783
865
  try {
784
- const otherContent = yield* Effect.tryPromise(() => fs4.readFile(otherFilePath, "utf-8"));
866
+ const otherContent = yield* Effect.tryPromise(() => fs5.readFile(otherFilePath, "utf-8"));
785
867
  const otherLines = otherContent.trim().split("\n").filter(Boolean);
786
868
  const otherMessages = otherLines.map((l) => JSON.parse(l));
787
869
  for (let i = 0; i < otherMessages.length; i++) {
@@ -801,8 +883,8 @@ var renameSession = (projectName, sessionId, newTitle) => Effect.gen(function* (
801
883
  if (summariesTargetingThis.length > 0) {
802
884
  summariesTargetingThis.sort((a, b) => (a.timestamp ?? "").localeCompare(b.timestamp ?? ""));
803
885
  const firstSummary = summariesTargetingThis[0];
804
- const summaryFilePath = path4.join(projectPath, firstSummary.file);
805
- const summaryContent = yield* Effect.tryPromise(() => fs4.readFile(summaryFilePath, "utf-8"));
886
+ const summaryFilePath = path5.join(projectPath, firstSummary.file);
887
+ const summaryContent = yield* Effect.tryPromise(() => fs5.readFile(summaryFilePath, "utf-8"));
806
888
  const summaryLines = summaryContent.trim().split("\n").filter(Boolean);
807
889
  const summaryMessages = summaryLines.map((l) => JSON.parse(l));
808
890
  summaryMessages[firstSummary.idx] = {
@@ -810,9 +892,9 @@ var renameSession = (projectName, sessionId, newTitle) => Effect.gen(function* (
810
892
  summary: newTitle
811
893
  };
812
894
  const newSummaryContent = summaryMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
813
- yield* Effect.tryPromise(() => fs4.writeFile(summaryFilePath, newSummaryContent, "utf-8"));
895
+ yield* Effect.tryPromise(() => fs5.writeFile(summaryFilePath, newSummaryContent, "utf-8"));
814
896
  } else {
815
- const currentContent = yield* Effect.tryPromise(() => fs4.readFile(filePath, "utf-8"));
897
+ const currentContent = yield* Effect.tryPromise(() => fs5.readFile(filePath, "utf-8"));
816
898
  const currentLines = currentContent.trim().split("\n").filter(Boolean);
817
899
  const currentMessages = currentLines.map((l) => JSON.parse(l));
818
900
  const firstUserIdx = currentMessages.findIndex((m) => m.type === "user");
@@ -831,102 +913,50 @@ var renameSession = (projectName, sessionId, newTitle) => Effect.gen(function* (
831
913
 
832
914
  ${cleanedText}`;
833
915
  const updatedContent = currentMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
834
- yield* Effect.tryPromise(() => fs4.writeFile(filePath, updatedContent, "utf-8"));
916
+ yield* Effect.tryPromise(() => fs5.writeFile(filePath, updatedContent, "utf-8"));
835
917
  }
836
918
  }
837
919
  }
838
920
  }
839
921
  return { success: true };
840
922
  });
841
- var getSessionFiles = (projectName, sessionId) => Effect.gen(function* () {
842
- const messages = yield* readSession(projectName, sessionId);
843
- const fileChanges = [];
844
- const seenFiles = /* @__PURE__ */ new Set();
845
- for (const msg of messages) {
846
- if (msg.type === "file-history-snapshot") {
847
- const snapshot = msg;
848
- const backups = snapshot.snapshot?.trackedFileBackups;
849
- if (backups && typeof backups === "object") {
850
- for (const filePath of Object.keys(backups)) {
851
- if (!seenFiles.has(filePath)) {
852
- seenFiles.add(filePath);
853
- fileChanges.push({
854
- path: filePath,
855
- action: "modified",
856
- timestamp: snapshot.snapshot?.timestamp,
857
- messageUuid: snapshot.messageId ?? msg.uuid
858
- });
859
- }
860
- }
861
- }
862
- }
863
- if (msg.type === "assistant" && msg.message?.content) {
864
- const content = msg.message.content;
865
- if (Array.isArray(content)) {
866
- for (const item of content) {
867
- if (item && typeof item === "object" && "type" in item && item.type === "tool_use") {
868
- const toolUse = item;
869
- if ((toolUse.name === "Write" || toolUse.name === "Edit") && toolUse.input?.file_path) {
870
- const filePath = toolUse.input.file_path;
871
- if (!seenFiles.has(filePath)) {
872
- seenFiles.add(filePath);
873
- fileChanges.push({
874
- path: filePath,
875
- action: toolUse.name === "Write" ? "created" : "modified",
876
- timestamp: msg.timestamp,
877
- messageUuid: msg.uuid
878
- });
879
- }
880
- }
881
- }
882
- }
883
- }
884
- }
885
- }
886
- return {
887
- sessionId,
888
- projectName,
889
- files: fileChanges,
890
- totalChanges: fileChanges.length
891
- };
892
- });
893
923
  var moveSession = (sourceProject, sessionId, targetProject) => Effect.gen(function* () {
894
924
  const sessionsDir = getSessionsDir();
895
- const sourcePath = path4.join(sessionsDir, sourceProject);
896
- const targetPath = path4.join(sessionsDir, targetProject);
897
- const sourceFile = path4.join(sourcePath, `${sessionId}.jsonl`);
898
- const targetFile = path4.join(targetPath, `${sessionId}.jsonl`);
925
+ const sourcePath = path5.join(sessionsDir, sourceProject);
926
+ const targetPath = path5.join(sessionsDir, targetProject);
927
+ const sourceFile = path5.join(sourcePath, `${sessionId}.jsonl`);
928
+ const targetFile = path5.join(targetPath, `${sessionId}.jsonl`);
899
929
  const sourceExists = yield* Effect.tryPromise(
900
- () => fs4.access(sourceFile).then(() => true).catch(() => false)
930
+ () => fs5.access(sourceFile).then(() => true).catch(() => false)
901
931
  );
902
932
  if (!sourceExists) {
903
933
  return { success: false, error: "Source session not found" };
904
934
  }
905
935
  const targetExists = yield* Effect.tryPromise(
906
- () => fs4.access(targetFile).then(() => true).catch(() => false)
936
+ () => fs5.access(targetFile).then(() => true).catch(() => false)
907
937
  );
908
938
  if (targetExists) {
909
939
  return { success: false, error: "Session already exists in target project" };
910
940
  }
911
- yield* Effect.tryPromise(() => fs4.mkdir(targetPath, { recursive: true }));
941
+ yield* Effect.tryPromise(() => fs5.mkdir(targetPath, { recursive: true }));
912
942
  const linkedAgents = yield* findLinkedAgents(sourceProject, sessionId);
913
- yield* Effect.tryPromise(() => fs4.rename(sourceFile, targetFile));
943
+ yield* Effect.tryPromise(() => fs5.rename(sourceFile, targetFile));
914
944
  for (const agentId of linkedAgents) {
915
- const sourceAgentFile = path4.join(sourcePath, `${agentId}.jsonl`);
916
- const targetAgentFile = path4.join(targetPath, `${agentId}.jsonl`);
945
+ const sourceAgentFile = path5.join(sourcePath, `${agentId}.jsonl`);
946
+ const targetAgentFile = path5.join(targetPath, `${agentId}.jsonl`);
917
947
  const agentExists = yield* Effect.tryPromise(
918
- () => fs4.access(sourceAgentFile).then(() => true).catch(() => false)
948
+ () => fs5.access(sourceAgentFile).then(() => true).catch(() => false)
919
949
  );
920
950
  if (agentExists) {
921
- yield* Effect.tryPromise(() => fs4.rename(sourceAgentFile, targetAgentFile));
951
+ yield* Effect.tryPromise(() => fs5.rename(sourceAgentFile, targetAgentFile));
922
952
  }
923
953
  }
924
954
  return { success: true };
925
955
  });
926
956
  var splitSession = (projectName, sessionId, splitAtMessageUuid) => Effect.gen(function* () {
927
- const projectPath = path4.join(getSessionsDir(), projectName);
928
- const filePath = path4.join(projectPath, `${sessionId}.jsonl`);
929
- const content = yield* Effect.tryPromise(() => fs4.readFile(filePath, "utf-8"));
957
+ const projectPath = path5.join(getSessionsDir(), projectName);
958
+ const filePath = path5.join(projectPath, `${sessionId}.jsonl`);
959
+ const content = yield* Effect.tryPromise(() => fs5.readFile(filePath, "utf-8"));
930
960
  const lines = content.trim().split("\n").filter(Boolean);
931
961
  const allMessages = lines.map((line) => JSON.parse(line));
932
962
  const splitIndex = allMessages.findIndex((m) => m.uuid === splitAtMessageUuid);
@@ -974,15 +1004,15 @@ var splitSession = (projectName, sessionId, splitAtMessageUuid) => Effect.gen(fu
974
1004
  updatedMovedMessages.unshift(clonedSummary);
975
1005
  }
976
1006
  const keptContent = keptMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
977
- yield* Effect.tryPromise(() => fs4.writeFile(filePath, keptContent, "utf-8"));
978
- const newFilePath = path4.join(projectPath, `${newSessionId}.jsonl`);
1007
+ yield* Effect.tryPromise(() => fs5.writeFile(filePath, keptContent, "utf-8"));
1008
+ const newFilePath = path5.join(projectPath, `${newSessionId}.jsonl`);
979
1009
  const newContent = updatedMovedMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
980
- yield* Effect.tryPromise(() => fs4.writeFile(newFilePath, newContent, "utf-8"));
981
- const agentFiles = yield* Effect.tryPromise(() => fs4.readdir(projectPath));
1010
+ yield* Effect.tryPromise(() => fs5.writeFile(newFilePath, newContent, "utf-8"));
1011
+ const agentFiles = yield* Effect.tryPromise(() => fs5.readdir(projectPath));
982
1012
  const agentJsonlFiles = agentFiles.filter((f) => f.startsWith("agent-") && f.endsWith(".jsonl"));
983
1013
  for (const agentFile of agentJsonlFiles) {
984
- const agentPath = path4.join(projectPath, agentFile);
985
- const agentContent = yield* Effect.tryPromise(() => fs4.readFile(agentPath, "utf-8"));
1014
+ const agentPath = path5.join(projectPath, agentFile);
1015
+ const agentContent = yield* Effect.tryPromise(() => fs5.readFile(agentPath, "utf-8"));
986
1016
  const agentLines = agentContent.trim().split("\n").filter(Boolean);
987
1017
  if (agentLines.length === 0) continue;
988
1018
  const firstAgentMsg = JSON.parse(agentLines[0]);
@@ -997,7 +1027,7 @@ var splitSession = (projectName, sessionId, splitAtMessageUuid) => Effect.gen(fu
997
1027
  return JSON.stringify({ ...msg, sessionId: newSessionId });
998
1028
  });
999
1029
  const updatedAgentContent = updatedAgentMessages.join("\n") + "\n";
1000
- yield* Effect.tryPromise(() => fs4.writeFile(agentPath, updatedAgentContent, "utf-8"));
1030
+ yield* Effect.tryPromise(() => fs5.writeFile(agentPath, updatedAgentContent, "utf-8"));
1001
1031
  }
1002
1032
  }
1003
1033
  }
@@ -1009,9 +1039,277 @@ var splitSession = (projectName, sessionId, splitAtMessageUuid) => Effect.gen(fu
1009
1039
  duplicatedSummary: shouldDuplicate
1010
1040
  };
1011
1041
  });
1042
+ var sortSessions = (sessions, sort) => {
1043
+ return sessions.sort((a, b) => {
1044
+ let comparison = 0;
1045
+ switch (sort.field) {
1046
+ case "summary": {
1047
+ comparison = a.sortTimestamp - b.sortTimestamp;
1048
+ break;
1049
+ }
1050
+ case "modified": {
1051
+ comparison = (a.fileMtime ?? 0) - (b.fileMtime ?? 0);
1052
+ break;
1053
+ }
1054
+ case "created": {
1055
+ const createdA = a.createdAt ? new Date(a.createdAt).getTime() : 0;
1056
+ const createdB = b.createdAt ? new Date(b.createdAt).getTime() : 0;
1057
+ comparison = createdA - createdB;
1058
+ break;
1059
+ }
1060
+ case "updated": {
1061
+ const updatedA = a.updatedAt ? new Date(a.updatedAt).getTime() : 0;
1062
+ const updatedB = b.updatedAt ? new Date(b.updatedAt).getTime() : 0;
1063
+ comparison = updatedA - updatedB;
1064
+ break;
1065
+ }
1066
+ case "messageCount": {
1067
+ comparison = a.messageCount - b.messageCount;
1068
+ break;
1069
+ }
1070
+ case "title": {
1071
+ const titleA = a.customTitle ?? a.currentSummary ?? a.title;
1072
+ const titleB = b.customTitle ?? b.currentSummary ?? b.title;
1073
+ comparison = titleA.localeCompare(titleB);
1074
+ break;
1075
+ }
1076
+ }
1077
+ return sort.order === "desc" ? -comparison : comparison;
1078
+ });
1079
+ };
1080
+ var loadSessionTreeDataInternal = (projectName, sessionId, summariesByTargetSession, fileMtime) => Effect.gen(function* () {
1081
+ const projectPath = path5.join(getSessionsDir(), projectName);
1082
+ const filePath = path5.join(projectPath, `${sessionId}.jsonl`);
1083
+ const content = yield* Effect.tryPromise(() => fs5.readFile(filePath, "utf-8"));
1084
+ const lines = content.trim().split("\n").filter(Boolean);
1085
+ const messages = lines.map((line) => JSON.parse(line));
1086
+ let summaries;
1087
+ if (summariesByTargetSession) {
1088
+ summaries = [...summariesByTargetSession.get(sessionId) ?? []].sort((a, b) => {
1089
+ const timestampCmp = (a.timestamp ?? "").localeCompare(b.timestamp ?? "");
1090
+ if (timestampCmp !== 0) return timestampCmp;
1091
+ return (b.sourceFile ?? "").localeCompare(a.sourceFile ?? "");
1092
+ });
1093
+ } else {
1094
+ summaries = [];
1095
+ const sessionUuids = /* @__PURE__ */ new Set();
1096
+ for (const msg of messages) {
1097
+ if (msg.uuid && typeof msg.uuid === "string") {
1098
+ sessionUuids.add(msg.uuid);
1099
+ }
1100
+ }
1101
+ const projectFiles = yield* Effect.tryPromise(() => fs5.readdir(projectPath));
1102
+ const allJsonlFiles = projectFiles.filter((f) => f.endsWith(".jsonl"));
1103
+ for (const file of allJsonlFiles) {
1104
+ try {
1105
+ const otherFilePath = path5.join(projectPath, file);
1106
+ const otherContent = yield* Effect.tryPromise(() => fs5.readFile(otherFilePath, "utf-8"));
1107
+ const otherLines = otherContent.trim().split("\n").filter(Boolean);
1108
+ for (const line of otherLines) {
1109
+ try {
1110
+ const msg = JSON.parse(line);
1111
+ if (msg.type === "summary" && typeof msg.summary === "string" && typeof msg.leafUuid === "string" && sessionUuids.has(msg.leafUuid)) {
1112
+ const targetMsg = messages.find((m) => m.uuid === msg.leafUuid);
1113
+ summaries.push({
1114
+ summary: msg.summary,
1115
+ leafUuid: msg.leafUuid,
1116
+ timestamp: targetMsg?.timestamp ?? msg.timestamp,
1117
+ sourceFile: file
1118
+ });
1119
+ }
1120
+ } catch {
1121
+ }
1122
+ }
1123
+ } catch {
1124
+ }
1125
+ }
1126
+ }
1127
+ summaries.sort((a, b) => {
1128
+ const timestampCmp = (a.timestamp ?? "").localeCompare(b.timestamp ?? "");
1129
+ if (timestampCmp !== 0) return timestampCmp;
1130
+ return (b.sourceFile ?? "").localeCompare(a.sourceFile ?? "");
1131
+ });
1132
+ let lastCompactBoundaryUuid;
1133
+ for (let i = messages.length - 1; i >= 0; i--) {
1134
+ const msg = messages[i];
1135
+ if (msg.type === "system" && msg.subtype === "compact_boundary") {
1136
+ lastCompactBoundaryUuid = msg.uuid;
1137
+ break;
1138
+ }
1139
+ }
1140
+ const firstUserMsg = messages.find((m) => m.type === "user");
1141
+ const customTitleMsg = messages.find((m) => m.type === "custom-title");
1142
+ const customTitle = customTitleMsg?.customTitle;
1143
+ const title = firstUserMsg ? extractTitle(extractTextContent(firstUserMsg.message)) : summaries.length > 0 ? "[Summary Only]" : `Session ${sessionId.slice(0, 8)}`;
1144
+ const userAssistantMessages = messages.filter(
1145
+ (m) => m.type === "user" || m.type === "assistant"
1146
+ );
1147
+ const firstMessage = userAssistantMessages[0];
1148
+ const lastMessage = userAssistantMessages[userAssistantMessages.length - 1];
1149
+ const linkedAgentIds = yield* findLinkedAgents(projectName, sessionId);
1150
+ const agents = [];
1151
+ for (const agentId of linkedAgentIds) {
1152
+ const agentPath = path5.join(projectPath, `${agentId}.jsonl`);
1153
+ try {
1154
+ const agentContent = yield* Effect.tryPromise(() => fs5.readFile(agentPath, "utf-8"));
1155
+ const agentLines = agentContent.trim().split("\n").filter(Boolean);
1156
+ const agentMsgs = agentLines.map((l) => JSON.parse(l));
1157
+ const agentUserAssistant = agentMsgs.filter(
1158
+ (m) => m.type === "user" || m.type === "assistant"
1159
+ );
1160
+ let agentName;
1161
+ const firstAgentMsg = agentMsgs.find((m) => m.type === "user");
1162
+ if (firstAgentMsg) {
1163
+ const text = extractTextContent(firstAgentMsg.message);
1164
+ if (text) {
1165
+ agentName = extractTitle(text);
1166
+ }
1167
+ }
1168
+ agents.push({
1169
+ id: agentId,
1170
+ name: agentName,
1171
+ messageCount: agentUserAssistant.length
1172
+ });
1173
+ } catch {
1174
+ agents.push({
1175
+ id: agentId,
1176
+ messageCount: 0
1177
+ });
1178
+ }
1179
+ }
1180
+ const todos = yield* findLinkedTodos(sessionId, linkedAgentIds);
1181
+ const createdAt = firstMessage?.timestamp ?? void 0;
1182
+ const sortTimestamp = getSessionSortTimestamp({ summaries, createdAt });
1183
+ return {
1184
+ id: sessionId,
1185
+ projectName,
1186
+ title,
1187
+ customTitle,
1188
+ currentSummary: summaries[0]?.summary,
1189
+ messageCount: userAssistantMessages.length > 0 ? userAssistantMessages.length : summaries.length > 0 ? 1 : 0,
1190
+ createdAt,
1191
+ updatedAt: lastMessage?.timestamp ?? void 0,
1192
+ fileMtime,
1193
+ sortTimestamp,
1194
+ summaries,
1195
+ agents,
1196
+ todos,
1197
+ lastCompactBoundaryUuid
1198
+ };
1199
+ });
1200
+ var loadSessionTreeData = (projectName, sessionId) => loadSessionTreeDataInternal(projectName, sessionId, void 0);
1201
+ var DEFAULT_SORT = { field: "summary", order: "desc" };
1202
+ var loadProjectTreeData = (projectName, sortOptions) => Effect.gen(function* () {
1203
+ const project = (yield* listProjects).find((p) => p.name === projectName);
1204
+ if (!project) {
1205
+ return null;
1206
+ }
1207
+ const sort = sortOptions ?? DEFAULT_SORT;
1208
+ const projectPath = path5.join(getSessionsDir(), projectName);
1209
+ const files = yield* Effect.tryPromise(() => fs5.readdir(projectPath));
1210
+ const sessionFiles = files.filter((f) => f.endsWith(".jsonl") && !f.startsWith("agent-"));
1211
+ const fileMtimes = /* @__PURE__ */ new Map();
1212
+ yield* Effect.all(
1213
+ sessionFiles.map(
1214
+ (file) => Effect.gen(function* () {
1215
+ const filePath = path5.join(projectPath, file);
1216
+ try {
1217
+ const stat4 = yield* Effect.tryPromise(() => fs5.stat(filePath));
1218
+ fileMtimes.set(file.replace(".jsonl", ""), stat4.mtimeMs);
1219
+ } catch {
1220
+ }
1221
+ })
1222
+ ),
1223
+ { concurrency: 20 }
1224
+ );
1225
+ const globalUuidMap = /* @__PURE__ */ new Map();
1226
+ const allSummaries = [];
1227
+ const allJsonlFiles = files.filter((f) => f.endsWith(".jsonl"));
1228
+ yield* Effect.all(
1229
+ allJsonlFiles.map(
1230
+ (file) => Effect.gen(function* () {
1231
+ const filePath = path5.join(projectPath, file);
1232
+ const fileSessionId = file.replace(".jsonl", "");
1233
+ try {
1234
+ const content = yield* Effect.tryPromise(() => fs5.readFile(filePath, "utf-8"));
1235
+ const lines = content.trim().split("\n").filter(Boolean);
1236
+ for (const line of lines) {
1237
+ try {
1238
+ const msg = JSON.parse(line);
1239
+ if (msg.uuid && typeof msg.uuid === "string") {
1240
+ globalUuidMap.set(msg.uuid, {
1241
+ sessionId: fileSessionId,
1242
+ timestamp: msg.timestamp
1243
+ });
1244
+ }
1245
+ if (msg.messageId && typeof msg.messageId === "string") {
1246
+ globalUuidMap.set(msg.messageId, {
1247
+ sessionId: fileSessionId,
1248
+ timestamp: msg.snapshot?.timestamp
1249
+ });
1250
+ }
1251
+ if (msg.type === "summary" && typeof msg.summary === "string") {
1252
+ allSummaries.push({
1253
+ summary: msg.summary,
1254
+ leafUuid: msg.leafUuid,
1255
+ timestamp: msg.timestamp,
1256
+ sourceFile: file
1257
+ });
1258
+ }
1259
+ } catch {
1260
+ }
1261
+ }
1262
+ } catch {
1263
+ }
1264
+ })
1265
+ ),
1266
+ { concurrency: 20 }
1267
+ );
1268
+ const summariesByTargetSession = /* @__PURE__ */ new Map();
1269
+ for (const summaryData of allSummaries) {
1270
+ if (summaryData.leafUuid) {
1271
+ const targetInfo = globalUuidMap.get(summaryData.leafUuid);
1272
+ if (targetInfo) {
1273
+ const targetSessionId = targetInfo.sessionId;
1274
+ if (!summariesByTargetSession.has(targetSessionId)) {
1275
+ summariesByTargetSession.set(targetSessionId, []);
1276
+ }
1277
+ summariesByTargetSession.get(targetSessionId).push({
1278
+ summary: summaryData.summary,
1279
+ leafUuid: summaryData.leafUuid,
1280
+ // Use summary's own timestamp for sorting, not the target message's timestamp
1281
+ timestamp: summaryData.timestamp ?? targetInfo.timestamp,
1282
+ sourceFile: summaryData.sourceFile
1283
+ });
1284
+ }
1285
+ }
1286
+ }
1287
+ const sessions = yield* Effect.all(
1288
+ sessionFiles.map((file) => {
1289
+ const sessionId = file.replace(".jsonl", "");
1290
+ const mtime = fileMtimes.get(sessionId);
1291
+ return loadSessionTreeDataInternal(projectName, sessionId, summariesByTargetSession, mtime);
1292
+ }),
1293
+ { concurrency: 10 }
1294
+ );
1295
+ const sortedSessions = sortSessions(sessions, sort);
1296
+ const filteredSessions = sortedSessions.filter((s) => {
1297
+ if (isErrorSessionTitle(s.title)) return false;
1298
+ if (isErrorSessionTitle(s.customTitle)) return false;
1299
+ if (isErrorSessionTitle(s.currentSummary)) return false;
1300
+ return true;
1301
+ });
1302
+ return {
1303
+ name: project.name,
1304
+ displayName: project.displayName,
1305
+ path: project.path,
1306
+ sessionCount: filteredSessions.length,
1307
+ sessions: filteredSessions
1308
+ };
1309
+ });
1012
1310
  var cleanInvalidMessages = (projectName, sessionId) => Effect.gen(function* () {
1013
- const filePath = path4.join(getSessionsDir(), projectName, `${sessionId}.jsonl`);
1014
- const content = yield* Effect.tryPromise(() => fs4.readFile(filePath, "utf-8"));
1311
+ const filePath = path5.join(getSessionsDir(), projectName, `${sessionId}.jsonl`);
1312
+ const content = yield* Effect.tryPromise(() => fs5.readFile(filePath, "utf-8"));
1015
1313
  const lines = content.trim().split("\n").filter(Boolean);
1016
1314
  if (lines.length === 0) return { removedCount: 0, remainingCount: 0 };
1017
1315
  const messages = lines.map((line) => JSON.parse(line));
@@ -1043,7 +1341,7 @@ var cleanInvalidMessages = (projectName, sessionId) => Effect.gen(function* () {
1043
1341
  lastValidUuid = msg.uuid;
1044
1342
  }
1045
1343
  const newContent = filtered.length > 0 ? filtered.map((m) => JSON.stringify(m)).join("\n") + "\n" : "";
1046
- yield* Effect.tryPromise(() => fs4.writeFile(filePath, newContent, "utf-8"));
1344
+ yield* Effect.tryPromise(() => fs5.writeFile(filePath, newContent, "utf-8"));
1047
1345
  const remainingUserAssistant = filtered.filter(
1048
1346
  (m) => m.type === "user" || m.type === "assistant"
1049
1347
  ).length;
@@ -1109,8 +1407,8 @@ var clearSessions = (options) => Effect.gen(function* () {
1109
1407
  const sessionsToDelete = [];
1110
1408
  if (clearInvalid) {
1111
1409
  for (const project of targetProjects) {
1112
- const projectPath = path4.join(getSessionsDir(), project.name);
1113
- const files = yield* Effect.tryPromise(() => fs4.readdir(projectPath));
1410
+ const projectPath = path5.join(getSessionsDir(), project.name);
1411
+ const files = yield* Effect.tryPromise(() => fs5.readdir(projectPath));
1114
1412
  const sessionFiles = files.filter((f) => f.endsWith(".jsonl") && !f.startsWith("agent-"));
1115
1413
  for (const file of sessionFiles) {
1116
1414
  const sessionId = file.replace(".jsonl", "");
@@ -1187,16 +1485,16 @@ var searchSessions = (query, options = {}) => Effect.gen(function* () {
1187
1485
  }
1188
1486
  if (searchContent) {
1189
1487
  for (const project of targetProjects) {
1190
- const projectPath = path4.join(getSessionsDir(), project.name);
1191
- const files = yield* Effect.tryPromise(() => fs4.readdir(projectPath));
1488
+ const projectPath = path5.join(getSessionsDir(), project.name);
1489
+ const files = yield* Effect.tryPromise(() => fs5.readdir(projectPath));
1192
1490
  const sessionFiles = files.filter((f) => f.endsWith(".jsonl") && !f.startsWith("agent-"));
1193
1491
  for (const file of sessionFiles) {
1194
1492
  const sessionId = file.replace(".jsonl", "");
1195
1493
  if (results.some((r) => r.sessionId === sessionId && r.projectName === project.name)) {
1196
1494
  continue;
1197
1495
  }
1198
- const filePath = path4.join(projectPath, file);
1199
- const content = yield* Effect.tryPromise(() => fs4.readFile(filePath, "utf-8"));
1496
+ const filePath = path5.join(projectPath, file);
1497
+ const content = yield* Effect.tryPromise(() => fs5.readFile(filePath, "utf-8"));
1200
1498
  const lines = content.trim().split("\n").filter(Boolean);
1201
1499
  for (const line of lines) {
1202
1500
  try {
@@ -1232,209 +1530,58 @@ var searchSessions = (query, options = {}) => Effect.gen(function* () {
1232
1530
  return dateB - dateA;
1233
1531
  });
1234
1532
  });
1235
- var loadSessionTreeDataInternal = (projectName, sessionId, summariesByTargetSession) => Effect.gen(function* () {
1236
- const projectPath = path4.join(getSessionsDir(), projectName);
1237
- const filePath = path4.join(projectPath, `${sessionId}.jsonl`);
1238
- const content = yield* Effect.tryPromise(() => fs4.readFile(filePath, "utf-8"));
1239
- const lines = content.trim().split("\n").filter(Boolean);
1240
- const messages = lines.map((line) => JSON.parse(line));
1241
- let summaries;
1242
- if (summariesByTargetSession) {
1243
- summaries = [...summariesByTargetSession.get(sessionId) ?? []].sort(
1244
- (a, b) => (a.timestamp ?? "").localeCompare(b.timestamp ?? "")
1245
- );
1246
- } else {
1247
- summaries = [];
1248
- const sessionUuids = /* @__PURE__ */ new Set();
1249
- for (const msg of messages) {
1250
- if (msg.uuid && typeof msg.uuid === "string") {
1251
- sessionUuids.add(msg.uuid);
1252
- }
1253
- }
1254
- const projectFiles = yield* Effect.tryPromise(() => fs4.readdir(projectPath));
1255
- const allJsonlFiles = projectFiles.filter((f) => f.endsWith(".jsonl"));
1256
- for (const file of allJsonlFiles) {
1257
- try {
1258
- const otherFilePath = path4.join(projectPath, file);
1259
- const otherContent = yield* Effect.tryPromise(() => fs4.readFile(otherFilePath, "utf-8"));
1260
- const otherLines = otherContent.trim().split("\n").filter(Boolean);
1261
- for (const line of otherLines) {
1262
- try {
1263
- const msg = JSON.parse(line);
1264
- if (msg.type === "summary" && typeof msg.summary === "string" && typeof msg.leafUuid === "string" && sessionUuids.has(msg.leafUuid)) {
1265
- const targetMsg = messages.find((m) => m.uuid === msg.leafUuid);
1266
- summaries.push({
1267
- summary: msg.summary,
1268
- leafUuid: msg.leafUuid,
1269
- timestamp: targetMsg?.timestamp ?? msg.timestamp
1270
- });
1271
- }
1272
- } catch {
1533
+ var getSessionFiles = (projectName, sessionId) => Effect.gen(function* () {
1534
+ const messages = yield* readSession(projectName, sessionId);
1535
+ const fileChanges = [];
1536
+ const seenFiles = /* @__PURE__ */ new Set();
1537
+ for (const msg of messages) {
1538
+ if (msg.type === "file-history-snapshot") {
1539
+ const snapshot = msg;
1540
+ const backups = snapshot.snapshot?.trackedFileBackups;
1541
+ if (backups && typeof backups === "object") {
1542
+ for (const filePath of Object.keys(backups)) {
1543
+ if (!seenFiles.has(filePath)) {
1544
+ seenFiles.add(filePath);
1545
+ fileChanges.push({
1546
+ path: filePath,
1547
+ action: "modified",
1548
+ timestamp: snapshot.snapshot?.timestamp,
1549
+ messageUuid: snapshot.messageId ?? msg.uuid
1550
+ });
1273
1551
  }
1274
1552
  }
1275
- } catch {
1276
- }
1277
- }
1278
- }
1279
- summaries.sort((a, b) => (a.timestamp ?? "").localeCompare(b.timestamp ?? ""));
1280
- let lastCompactBoundaryUuid;
1281
- for (let i = messages.length - 1; i >= 0; i--) {
1282
- const msg = messages[i];
1283
- if (msg.type === "system" && msg.subtype === "compact_boundary") {
1284
- lastCompactBoundaryUuid = msg.uuid;
1285
- break;
1286
- }
1287
- }
1288
- const firstUserMsg = messages.find((m) => m.type === "user");
1289
- const customTitleMsg = messages.find((m) => m.type === "custom-title");
1290
- const customTitle = customTitleMsg?.customTitle;
1291
- const title = firstUserMsg ? extractTitle(extractTextContent(firstUserMsg.message)) : summaries.length > 0 ? "[Summary Only]" : `Session ${sessionId.slice(0, 8)}`;
1292
- const userAssistantMessages = messages.filter(
1293
- (m) => m.type === "user" || m.type === "assistant"
1294
- );
1295
- const firstMessage = userAssistantMessages[0];
1296
- const lastMessage = userAssistantMessages[userAssistantMessages.length - 1];
1297
- const linkedAgentIds = yield* findLinkedAgents(projectName, sessionId);
1298
- const agents = [];
1299
- for (const agentId of linkedAgentIds) {
1300
- const agentPath = path4.join(projectPath, `${agentId}.jsonl`);
1301
- try {
1302
- const agentContent = yield* Effect.tryPromise(() => fs4.readFile(agentPath, "utf-8"));
1303
- const agentLines = agentContent.trim().split("\n").filter(Boolean);
1304
- const agentMsgs = agentLines.map((l) => JSON.parse(l));
1305
- const agentUserAssistant = agentMsgs.filter(
1306
- (m) => m.type === "user" || m.type === "assistant"
1307
- );
1308
- let agentName;
1309
- const firstAgentMsg = agentMsgs.find((m) => m.type === "user");
1310
- if (firstAgentMsg) {
1311
- const text = extractTextContent(firstAgentMsg.message);
1312
- if (text) {
1313
- agentName = extractTitle(text);
1314
- }
1315
1553
  }
1316
- agents.push({
1317
- id: agentId,
1318
- name: agentName,
1319
- messageCount: agentUserAssistant.length
1320
- });
1321
- } catch {
1322
- agents.push({
1323
- id: agentId,
1324
- messageCount: 0
1325
- });
1326
1554
  }
1327
- }
1328
- const todos = yield* findLinkedTodos(sessionId, linkedAgentIds);
1329
- return {
1330
- id: sessionId,
1331
- projectName,
1332
- title,
1333
- customTitle,
1334
- currentSummary: summaries[0]?.summary,
1335
- messageCount: userAssistantMessages.length > 0 ? userAssistantMessages.length : summaries.length > 0 ? 1 : 0,
1336
- createdAt: firstMessage?.timestamp ?? void 0,
1337
- updatedAt: lastMessage?.timestamp ?? void 0,
1338
- summaries,
1339
- agents,
1340
- todos,
1341
- lastCompactBoundaryUuid
1342
- };
1343
- });
1344
- var loadSessionTreeData = (projectName, sessionId) => loadSessionTreeDataInternal(projectName, sessionId, void 0);
1345
- var loadProjectTreeData = (projectName) => Effect.gen(function* () {
1346
- const project = (yield* listProjects).find((p) => p.name === projectName);
1347
- if (!project) {
1348
- return null;
1349
- }
1350
- const projectPath = path4.join(getSessionsDir(), projectName);
1351
- const files = yield* Effect.tryPromise(() => fs4.readdir(projectPath));
1352
- const sessionFiles = files.filter((f) => f.endsWith(".jsonl") && !f.startsWith("agent-"));
1353
- const globalUuidMap = /* @__PURE__ */ new Map();
1354
- const allSummaries = [];
1355
- const allJsonlFiles = files.filter((f) => f.endsWith(".jsonl"));
1356
- yield* Effect.all(
1357
- allJsonlFiles.map(
1358
- (file) => Effect.gen(function* () {
1359
- const filePath = path4.join(projectPath, file);
1360
- const fileSessionId = file.replace(".jsonl", "");
1361
- try {
1362
- const content = yield* Effect.tryPromise(() => fs4.readFile(filePath, "utf-8"));
1363
- const lines = content.trim().split("\n").filter(Boolean);
1364
- for (const line of lines) {
1365
- try {
1366
- const msg = JSON.parse(line);
1367
- if (msg.uuid && typeof msg.uuid === "string") {
1368
- globalUuidMap.set(msg.uuid, {
1369
- sessionId: fileSessionId,
1370
- timestamp: msg.timestamp
1371
- });
1372
- }
1373
- if (msg.messageId && typeof msg.messageId === "string") {
1374
- globalUuidMap.set(msg.messageId, {
1375
- sessionId: fileSessionId,
1376
- timestamp: msg.snapshot?.timestamp
1377
- });
1378
- }
1379
- if (msg.type === "summary" && typeof msg.summary === "string") {
1380
- allSummaries.push({
1381
- summary: msg.summary,
1382
- leafUuid: msg.leafUuid,
1383
- timestamp: msg.timestamp
1555
+ if (msg.type === "assistant" && msg.message?.content) {
1556
+ const content = msg.message.content;
1557
+ if (Array.isArray(content)) {
1558
+ for (const item of content) {
1559
+ if (item && typeof item === "object" && "type" in item && item.type === "tool_use") {
1560
+ const toolUse = item;
1561
+ if ((toolUse.name === "Write" || toolUse.name === "Edit") && toolUse.input?.file_path) {
1562
+ const filePath = toolUse.input.file_path;
1563
+ if (!seenFiles.has(filePath)) {
1564
+ seenFiles.add(filePath);
1565
+ fileChanges.push({
1566
+ path: filePath,
1567
+ action: toolUse.name === "Write" ? "created" : "modified",
1568
+ timestamp: msg.timestamp,
1569
+ messageUuid: msg.uuid
1384
1570
  });
1385
1571
  }
1386
- } catch {
1387
1572
  }
1388
1573
  }
1389
- } catch {
1390
1574
  }
1391
- })
1392
- ),
1393
- { concurrency: 20 }
1394
- );
1395
- const summariesByTargetSession = /* @__PURE__ */ new Map();
1396
- for (const summaryData of allSummaries) {
1397
- if (summaryData.leafUuid) {
1398
- const targetInfo = globalUuidMap.get(summaryData.leafUuid);
1399
- if (targetInfo) {
1400
- const targetSessionId = targetInfo.sessionId;
1401
- if (!summariesByTargetSession.has(targetSessionId)) {
1402
- summariesByTargetSession.set(targetSessionId, []);
1403
- }
1404
- summariesByTargetSession.get(targetSessionId).push({
1405
- summary: summaryData.summary,
1406
- leafUuid: summaryData.leafUuid,
1407
- timestamp: targetInfo.timestamp ?? summaryData.timestamp
1408
- });
1409
1575
  }
1410
1576
  }
1411
1577
  }
1412
- const sessions = yield* Effect.all(
1413
- sessionFiles.map((file) => {
1414
- const sessionId = file.replace(".jsonl", "");
1415
- return loadSessionTreeDataInternal(projectName, sessionId, summariesByTargetSession);
1416
- }),
1417
- { concurrency: 10 }
1418
- );
1419
- const sortedSessions = sessions.sort((a, b) => {
1420
- const dateA = a.updatedAt ? new Date(a.updatedAt).getTime() : 0;
1421
- const dateB = b.updatedAt ? new Date(b.updatedAt).getTime() : 0;
1422
- return dateB - dateA;
1423
- });
1424
- const filteredSessions = sortedSessions.filter((s) => {
1425
- if (isErrorSessionTitle(s.title)) return false;
1426
- if (isErrorSessionTitle(s.customTitle)) return false;
1427
- if (isErrorSessionTitle(s.currentSummary)) return false;
1428
- return true;
1429
- });
1430
1578
  return {
1431
- name: project.name,
1432
- displayName: project.displayName,
1433
- path: project.path,
1434
- sessionCount: filteredSessions.length,
1435
- sessions: filteredSessions
1579
+ sessionId,
1580
+ projectName,
1581
+ files: fileChanges,
1582
+ totalChanges: fileChanges.length
1436
1583
  };
1437
1584
  });
1438
1585
 
1439
- export { listProjects as a, loadProjectTreeData as b, clearSessions as c, deleteMessage as d, listSessions as e, deleteSession as f, getSessionsDir as g, readSession as h, getSessionFiles as i, renameSession as j, folderNameToPath as k, loadAgentMessages as l, moveSession as m, splitSession as n, loadSessionTreeData as o, previewCleanup as p, pathToFolderName as q, restoreMessage as r, searchSessions as s, sortProjects as t, getDisplayTitle as u, maskHomePath as v };
1440
- //# sourceMappingURL=index3-DkgTDgY2.js.map
1586
+ export { listProjects as a, loadProjectTreeData as b, clearSessions as c, deleteMessage as d, listSessions as e, deleteSession as f, getSessionsDir as g, readSession as h, getSessionFiles as i, renameSession as j, folderNameToPath as k, loadAgentMessages as l, moveSession as m, splitSession as n, loadSessionTreeData as o, previewCleanup as p, pathToFolderName as q, restoreMessage as r, searchSessions as s, sortProjects as t, getDisplayTitle as u, parseCommandMessage as v, maskHomePath as w };
1587
+ //# sourceMappingURL=index3-CcQtlmu9.js.map