spiracha 1.5.0 → 2.0.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 (365) hide show
  1. package/AGENTS.md +114 -205
  2. package/README.md +89 -269
  3. package/apps/ui/AGENTS.md +17 -7
  4. package/apps/ui/README.md +34 -8
  5. package/apps/ui/components.json +21 -0
  6. package/apps/ui/package.json +65 -0
  7. package/apps/ui/src/components/antigravity-conversations-table.tsx +206 -0
  8. package/apps/ui/src/components/antigravity-keychain-panel.tsx +76 -0
  9. package/apps/ui/src/components/antigravity-workspaces-table.tsx +63 -0
  10. package/apps/ui/src/components/app-shell.tsx +124 -0
  11. package/apps/ui/src/components/breadcrumbs.tsx +53 -0
  12. package/apps/ui/src/components/claude-code-sessions-table.tsx +114 -0
  13. package/apps/ui/src/components/claude-code-workspaces-table.tsx +55 -0
  14. package/apps/ui/src/components/cursor-threads-table.tsx +189 -0
  15. package/apps/ui/src/components/cursor-workspaces-table.tsx +140 -0
  16. package/apps/ui/src/components/data-table.tsx +241 -0
  17. package/apps/ui/src/components/delete-confirm-dialog.tsx +88 -0
  18. package/apps/ui/src/components/export-dialog.tsx +184 -0
  19. package/apps/ui/src/components/json-panel.tsx +17 -0
  20. package/apps/ui/src/components/kiro-sessions-table.tsx +112 -0
  21. package/apps/ui/src/components/kiro-workspaces-table.tsx +53 -0
  22. package/apps/ui/src/components/list-search-input.tsx +18 -0
  23. package/apps/ui/src/components/loading-panel.tsx +23 -0
  24. package/apps/ui/src/components/metadata-section.tsx +31 -0
  25. package/apps/ui/src/components/metric-card.tsx +19 -0
  26. package/apps/ui/src/components/opencode-sessions-table.tsx +128 -0
  27. package/apps/ui/src/components/opencode-workspaces-table.tsx +57 -0
  28. package/apps/ui/src/components/page-header.tsx +33 -0
  29. package/apps/ui/src/components/projects-loading-state.tsx +74 -0
  30. package/apps/ui/src/components/projects-table.tsx +108 -0
  31. package/apps/ui/src/components/qoder-sessions-table.tsx +112 -0
  32. package/apps/ui/src/components/qoder-workspaces-table.tsx +53 -0
  33. package/apps/ui/src/components/recent-threads-list.tsx +52 -0
  34. package/apps/ui/src/components/reload-error-panel.tsx +20 -0
  35. package/apps/ui/src/components/text-document-panel.tsx +19 -0
  36. package/apps/ui/src/components/theme-toggle.tsx +48 -0
  37. package/apps/ui/src/components/threads-table.tsx +202 -0
  38. package/apps/ui/src/components/transcript-view.tsx +552 -0
  39. package/apps/ui/src/components/ui/alert-dialog.tsx +160 -0
  40. package/apps/ui/src/components/ui/badge.tsx +45 -0
  41. package/apps/ui/src/components/ui/button.tsx +62 -0
  42. package/apps/ui/src/components/ui/checkbox.tsx +29 -0
  43. package/apps/ui/src/components/ui/dialog.tsx +137 -0
  44. package/apps/ui/src/components/ui/dropdown-menu.tsx +217 -0
  45. package/apps/ui/src/components/ui/input.tsx +21 -0
  46. package/apps/ui/src/components/ui/scroll-area.tsx +46 -0
  47. package/apps/ui/src/components/ui/select.tsx +163 -0
  48. package/apps/ui/src/components/ui/separator.tsx +28 -0
  49. package/apps/ui/src/components/ui/sheet.tsx +107 -0
  50. package/apps/ui/src/components/ui/skeleton.tsx +7 -0
  51. package/apps/ui/src/components/ui/table.tsx +76 -0
  52. package/apps/ui/src/components/ui/tabs.tsx +71 -0
  53. package/apps/ui/src/components/ui/tooltip.tsx +44 -0
  54. package/apps/ui/src/integrations/tanstack-query/devtools.tsx +6 -0
  55. package/apps/ui/src/integrations/tanstack-query/root-provider.tsx +10 -0
  56. package/apps/ui/src/lib/antigravity-conversation-state.ts +28 -0
  57. package/apps/ui/src/lib/antigravity-queries.ts +33 -0
  58. package/apps/ui/src/lib/antigravity-server.ts +128 -0
  59. package/apps/ui/src/lib/antigravity-transcript-events.ts +335 -0
  60. package/apps/ui/src/lib/claude-code-queries.ts +26 -0
  61. package/apps/ui/src/lib/claude-code-server.ts +75 -0
  62. package/apps/ui/src/lib/claude-code-transcript-events.ts +154 -0
  63. package/apps/ui/src/lib/codex-queries.ts +66 -0
  64. package/apps/ui/src/lib/codex-server.ts +209 -0
  65. package/apps/ui/src/lib/cursor-queries.ts +37 -0
  66. package/apps/ui/src/lib/cursor-server.ts +272 -0
  67. package/apps/ui/src/lib/cursor-transcript-events.ts +229 -0
  68. package/apps/ui/src/lib/download.ts +166 -0
  69. package/apps/ui/src/lib/formatters.ts +149 -0
  70. package/apps/ui/src/lib/kiro-queries.ts +22 -0
  71. package/apps/ui/src/lib/kiro-server.ts +73 -0
  72. package/apps/ui/src/lib/kiro-transcript-events.ts +113 -0
  73. package/apps/ui/src/lib/opencode-queries.ts +37 -0
  74. package/apps/ui/src/lib/opencode-server.ts +73 -0
  75. package/apps/ui/src/lib/opencode-transcript-events.ts +221 -0
  76. package/apps/ui/src/lib/package-metadata.ts +16 -0
  77. package/apps/ui/src/lib/path-utils.ts +13 -0
  78. package/apps/ui/src/lib/qoder-queries.ts +22 -0
  79. package/apps/ui/src/lib/qoder-server.ts +79 -0
  80. package/apps/ui/src/lib/qoder-transcript-events.ts +139 -0
  81. package/apps/ui/src/lib/route-search.ts +68 -0
  82. package/apps/ui/src/lib/settings-store.tsx +59 -0
  83. package/apps/ui/src/lib/source-session-export-server.ts +56 -0
  84. package/apps/ui/src/lib/text-filter.ts +22 -0
  85. package/apps/ui/src/lib/thread-id.ts +3 -0
  86. package/apps/ui/src/lib/thread-transcript-stats.ts +57 -0
  87. package/apps/ui/src/lib/utils.ts +7 -0
  88. package/apps/ui/src/routeTree.gen.ts +730 -0
  89. package/apps/ui/src/router.tsx +20 -0
  90. package/apps/ui/src/routes/$threadId.tsx +22 -0
  91. package/apps/ui/src/routes/__root.tsx +127 -0
  92. package/apps/ui/src/routes/analytics.tsx +143 -0
  93. package/apps/ui/src/routes/antigravity-conversations.$conversationId.tsx +438 -0
  94. package/apps/ui/src/routes/antigravity.$workspaceKey.tsx +127 -0
  95. package/apps/ui/src/routes/antigravity.index.tsx +51 -0
  96. package/apps/ui/src/routes/api.v1.conversation-query.ts +12 -0
  97. package/apps/ui/src/routes/api.v1.conversations.$source.$id.export.ts +12 -0
  98. package/apps/ui/src/routes/api.v1.conversations.$source.$id.ts +12 -0
  99. package/apps/ui/src/routes/api.v1.conversations.ts +12 -0
  100. package/apps/ui/src/routes/api.v1.resolve.ts +12 -0
  101. package/apps/ui/src/routes/api.v1.sources.ts +12 -0
  102. package/apps/ui/src/routes/claude-code-sessions.$sessionId.tsx +342 -0
  103. package/apps/ui/src/routes/claude-code.$workspaceKey.tsx +135 -0
  104. package/apps/ui/src/routes/claude-code.index.tsx +48 -0
  105. package/apps/ui/src/routes/codex.$project.tsx +390 -0
  106. package/apps/ui/src/routes/codex.index.tsx +116 -0
  107. package/apps/ui/src/routes/cursor-threads.$composerId.tsx +435 -0
  108. package/apps/ui/src/routes/cursor.$workspaceKey.tsx +416 -0
  109. package/apps/ui/src/routes/cursor.index.tsx +120 -0
  110. package/apps/ui/src/routes/index.tsx +124 -0
  111. package/apps/ui/src/routes/kiro-sessions.$sessionId.tsx +345 -0
  112. package/apps/ui/src/routes/kiro.$workspaceKey.tsx +136 -0
  113. package/apps/ui/src/routes/kiro.index.tsx +48 -0
  114. package/apps/ui/src/routes/opencode-sessions.$sessionId.tsx +334 -0
  115. package/apps/ui/src/routes/opencode.$workspaceKey.tsx +135 -0
  116. package/apps/ui/src/routes/opencode.index.tsx +48 -0
  117. package/apps/ui/src/routes/qoder-sessions.$sessionId.tsx +341 -0
  118. package/apps/ui/src/routes/qoder.$workspaceKey.tsx +139 -0
  119. package/apps/ui/src/routes/qoder.index.tsx +48 -0
  120. package/apps/ui/src/routes/settings.tsx +91 -0
  121. package/apps/ui/src/routes/threads.$threadId.tsx +619 -0
  122. package/apps/ui/src/styles.css +122 -0
  123. package/apps/ui/tsconfig.json +29 -0
  124. package/apps/ui/vite.config.ts +84 -0
  125. package/bin/spiracha.ts +32 -0
  126. package/package.json +46 -73
  127. package/src/client.ts +290 -0
  128. package/src/lib/antigravity-db.ts +213 -19
  129. package/src/lib/antigravity-exporter-types.ts +1 -0
  130. package/src/lib/codex-analytics.ts +1 -1
  131. package/src/lib/codex-browser-db.ts +410 -74
  132. package/src/lib/codex-browser-export.ts +6 -14
  133. package/src/lib/codex-browser-types.ts +1 -1
  134. package/src/lib/{codex-exporter-types.ts → codex-thread-types.ts} +2 -30
  135. package/src/lib/{codex-exporter-transcript.ts → codex-transcript-renderer.ts} +64 -28
  136. package/src/lib/conversation-api.ts +792 -0
  137. package/src/lib/conversation-data/adapter-helpers.ts +110 -0
  138. package/src/lib/conversation-data/antigravity-adapter.ts +148 -0
  139. package/src/lib/conversation-data/claude-code-adapter.ts +175 -0
  140. package/src/lib/conversation-data/codex-adapter.ts +245 -0
  141. package/src/lib/conversation-data/cursor-adapter.ts +171 -0
  142. package/src/lib/conversation-data/index.ts +311 -0
  143. package/src/lib/conversation-data/kiro-adapter.ts +140 -0
  144. package/src/lib/conversation-data/message-selector.ts +37 -0
  145. package/src/lib/conversation-data/opencode-adapter.ts +180 -0
  146. package/src/lib/conversation-data/path-match.ts +79 -0
  147. package/src/lib/conversation-data/qoder-adapter.ts +230 -0
  148. package/src/lib/conversation-data/types.ts +116 -0
  149. package/src/lib/cursor-db.ts +67 -21
  150. package/src/lib/cursor-exporter-types.ts +0 -19
  151. package/src/lib/qoder-acp-client.ts +268 -0
  152. package/src/lib/qoder-db.ts +1601 -0
  153. package/src/lib/qoder-exporter-types.ts +114 -0
  154. package/src/lib/qoder-transcript-phase.ts +41 -0
  155. package/src/lib/qoder-transcript.ts +112 -0
  156. package/apps/ui/dist/client/assets/_threadId-CAIeH5mq.js +0 -1
  157. package/apps/ui/dist/client/assets/analytics-DOy1b6Sh.js +0 -1
  158. package/apps/ui/dist/client/assets/antigravity-conversations._conversationId-DqySVO2K.js +0 -7
  159. package/apps/ui/dist/client/assets/antigravity-conversations._conversationId-KAcXtNxI.js +0 -1
  160. package/apps/ui/dist/client/assets/antigravity-keychain-panel-B77qJz6f.js +0 -1
  161. package/apps/ui/dist/client/assets/antigravity._workspaceKey-B3NM6gRH.js +0 -1
  162. package/apps/ui/dist/client/assets/antigravity._workspaceKey-ByitGWki.js +0 -1
  163. package/apps/ui/dist/client/assets/antigravity.index-DP9JC2P9.js +0 -1
  164. package/apps/ui/dist/client/assets/antigravity.index-DgW25FEV.js +0 -1
  165. package/apps/ui/dist/client/assets/badge-C3i4OKs8.js +0 -1
  166. package/apps/ui/dist/client/assets/checkbox-CdHitXWQ.js +0 -1
  167. package/apps/ui/dist/client/assets/claude-code-sessions._sessionId-8pQ55ci2.js +0 -1
  168. package/apps/ui/dist/client/assets/claude-code-sessions._sessionId-DVz5UmtU.js +0 -1
  169. package/apps/ui/dist/client/assets/claude-code._workspaceKey-BBKskSum.js +0 -1
  170. package/apps/ui/dist/client/assets/claude-code._workspaceKey-OkikMUFs.js +0 -1
  171. package/apps/ui/dist/client/assets/claude-code.index-Cwu76dbb.js +0 -1
  172. package/apps/ui/dist/client/assets/claude-code.index-D6eMd08t.js +0 -1
  173. package/apps/ui/dist/client/assets/createServerFn-B-KkwmHU.js +0 -3
  174. package/apps/ui/dist/client/assets/cursor-threads._composerId-CmBFclK8.js +0 -1
  175. package/apps/ui/dist/client/assets/cursor-threads._composerId-hBWlP1D-.js +0 -1
  176. package/apps/ui/dist/client/assets/cursor._workspaceKey-BFPkIRi-.js +0 -1
  177. package/apps/ui/dist/client/assets/cursor._workspaceKey-CaAZjGmm.js +0 -1
  178. package/apps/ui/dist/client/assets/cursor.index-8y4o20kb.js +0 -2
  179. package/apps/ui/dist/client/assets/cursor.index-CrnMwDCi.js +0 -1
  180. package/apps/ui/dist/client/assets/data-table-Br78_dk3.js +0 -4
  181. package/apps/ui/dist/client/assets/delete-confirm-dialog-Bxs07u-j.js +0 -7
  182. package/apps/ui/dist/client/assets/dist-B9pyYCVU.js +0 -1
  183. package/apps/ui/dist/client/assets/dist-BrJhN2A0.js +0 -5
  184. package/apps/ui/dist/client/assets/dist-Cmd3AIfD.js +0 -1
  185. package/apps/ui/dist/client/assets/dist-DvMS2965.js +0 -1
  186. package/apps/ui/dist/client/assets/download-Bf0QJKD3.js +0 -1
  187. package/apps/ui/dist/client/assets/dropdown-menu-D5cvPaZt.js +0 -1
  188. package/apps/ui/dist/client/assets/es2015-ad6040dw.js +0 -41
  189. package/apps/ui/dist/client/assets/export-dialog-Dr8d2MqD.js +0 -1
  190. package/apps/ui/dist/client/assets/formatters-BtqyrX_c.js +0 -1
  191. package/apps/ui/dist/client/assets/index-C-STgIH4.js +0 -166
  192. package/apps/ui/dist/client/assets/jsx-runtime-DGeXAQPT.js +0 -1
  193. package/apps/ui/dist/client/assets/kiro-sessions._sessionId-CKgfJ7GR.js +0 -1
  194. package/apps/ui/dist/client/assets/kiro-sessions._sessionId-zvIJHtQF.js +0 -1
  195. package/apps/ui/dist/client/assets/kiro._workspaceKey-DhVuJuZB.js +0 -1
  196. package/apps/ui/dist/client/assets/kiro._workspaceKey-QArsjkTY.js +0 -1
  197. package/apps/ui/dist/client/assets/kiro.index-C-fr4m7i.js +0 -1
  198. package/apps/ui/dist/client/assets/kiro.index-OYgAdtZd.js +0 -1
  199. package/apps/ui/dist/client/assets/metric-card-Dplm0ZiM.js +0 -1
  200. package/apps/ui/dist/client/assets/opencode-sessions._sessionId-DLjiTst-.js +0 -1
  201. package/apps/ui/dist/client/assets/opencode-sessions._sessionId-biBwrRbt.js +0 -8
  202. package/apps/ui/dist/client/assets/opencode._workspaceKey-C7OIzMOJ.js +0 -1
  203. package/apps/ui/dist/client/assets/opencode._workspaceKey-sBakX0oI.js +0 -1
  204. package/apps/ui/dist/client/assets/opencode.index-Bl_kNs9N.js +0 -1
  205. package/apps/ui/dist/client/assets/opencode.index-CN53bVmb.js +0 -1
  206. package/apps/ui/dist/client/assets/page-header-Cwa3p6Tl.js +0 -1
  207. package/apps/ui/dist/client/assets/preload-helper-B8fFrdxC.js +0 -1
  208. package/apps/ui/dist/client/assets/projects._project-D8WloxQN.js +0 -1
  209. package/apps/ui/dist/client/assets/projects._project-DSDwH4NF.js +0 -1
  210. package/apps/ui/dist/client/assets/projects.index-5xRtuJdX.js +0 -3
  211. package/apps/ui/dist/client/assets/projects.index-DEfhWqa8.js +0 -1
  212. package/apps/ui/dist/client/assets/react-dom-DL96Jor4.js +0 -1
  213. package/apps/ui/dist/client/assets/refresh-ccw-BgKjOiA6.js +0 -1
  214. package/apps/ui/dist/client/assets/reload-error-panel-AHqu0akK.js +0 -1
  215. package/apps/ui/dist/client/assets/routes-DnzF_9CX.js +0 -1
  216. package/apps/ui/dist/client/assets/scroll-text-fM0sMOB3.js +0 -1
  217. package/apps/ui/dist/client/assets/select-CYF6pF37.js +0 -1
  218. package/apps/ui/dist/client/assets/settings-Dx70jgP_.js +0 -1
  219. package/apps/ui/dist/client/assets/sqlite-error-B6uZjUe8.js +0 -1
  220. package/apps/ui/dist/client/assets/styles-B7Zi9EFA.css +0 -1
  221. package/apps/ui/dist/client/assets/tabs-CmuhkT-c.js +0 -7
  222. package/apps/ui/dist/client/assets/text-filter-DVAZySUS.js +0 -2
  223. package/apps/ui/dist/client/assets/thread-transcript-stats-BUNz6u7F.js +0 -1
  224. package/apps/ui/dist/client/assets/threads._threadId-BB9tTsV4.js +0 -1
  225. package/apps/ui/dist/client/assets/threads._threadId-BMRSFow3.js +0 -1
  226. package/apps/ui/dist/client/assets/useMutation-BSFult2i.js +0 -1
  227. package/apps/ui/dist/client/assets/useQuery-CjINKZf1.js +0 -1
  228. package/apps/ui/dist/server/assets/_tanstack-start-manifest_v-CQ8Jjs3B.js +0 -387
  229. package/apps/ui/dist/server/assets/_threadId-B6SrBR9E.js +0 -6
  230. package/apps/ui/dist/server/assets/analytics-CYP_LT5Y.js +0 -16
  231. package/apps/ui/dist/server/assets/analytics-CtpOMVMO.js +0 -146
  232. package/apps/ui/dist/server/assets/antigravity-conversation-state-HgzS302O.js +0 -16
  233. package/apps/ui/dist/server/assets/antigravity-conversations._conversationId-BKOyL2T6.js +0 -613
  234. package/apps/ui/dist/server/assets/antigravity-conversations._conversationId-D426O-64.js +0 -11
  235. package/apps/ui/dist/server/assets/antigravity-conversations._conversationId-eS87Dx7g.js +0 -20
  236. package/apps/ui/dist/server/assets/antigravity-db-Bh8_U9uw.js +0 -580
  237. package/apps/ui/dist/server/assets/antigravity-keychain-DOiuHDwK.js +0 -126
  238. package/apps/ui/dist/server/assets/antigravity-keychain-panel-CC7FLmAK.js +0 -55
  239. package/apps/ui/dist/server/assets/antigravity-queries-CGrJO9Vr.js +0 -37
  240. package/apps/ui/dist/server/assets/antigravity-server-CHRjVFqN.js +0 -114
  241. package/apps/ui/dist/server/assets/antigravity._workspaceKey-3m_MzNFA.js +0 -11
  242. package/apps/ui/dist/server/assets/antigravity._workspaceKey-B0QeYUOh.js +0 -28
  243. package/apps/ui/dist/server/assets/antigravity._workspaceKey-C3kP-qyN.js +0 -210
  244. package/apps/ui/dist/server/assets/antigravity.index-CPCYkqCi.js +0 -104
  245. package/apps/ui/dist/server/assets/antigravity.index-DudTB3Tq.js +0 -11
  246. package/apps/ui/dist/server/assets/badge-EvdhKK_Z.js +0 -26
  247. package/apps/ui/dist/server/assets/button-CmTDnzOn.js +0 -46
  248. package/apps/ui/dist/server/assets/checkbox-C0hovF41.js +0 -19
  249. package/apps/ui/dist/server/assets/claude-code-db-Ik3VStKZ.js +0 -361
  250. package/apps/ui/dist/server/assets/claude-code-queries-Cgzi4K-e.js +0 -37
  251. package/apps/ui/dist/server/assets/claude-code-server-PfraClXS.js +0 -72
  252. package/apps/ui/dist/server/assets/claude-code-sessions._sessionId-C55oe6zj.js +0 -18
  253. package/apps/ui/dist/server/assets/claude-code-sessions._sessionId-D1RYYi3j.js +0 -473
  254. package/apps/ui/dist/server/assets/claude-code-sessions._sessionId-DSvPLEUL.js +0 -11
  255. package/apps/ui/dist/server/assets/claude-code-transcript-C-bxh3cS.js +0 -139
  256. package/apps/ui/dist/server/assets/claude-code-transcript-phase-DmUMc8VU.js +0 -10
  257. package/apps/ui/dist/server/assets/claude-code._workspaceKey-B5Xg_-tE.js +0 -28
  258. package/apps/ui/dist/server/assets/claude-code._workspaceKey-BPlzyXPa.js +0 -11
  259. package/apps/ui/dist/server/assets/claude-code._workspaceKey-DqDve2wl.js +0 -191
  260. package/apps/ui/dist/server/assets/claude-code.index-B7yYR7dD.js +0 -92
  261. package/apps/ui/dist/server/assets/claude-code.index-BUHThG1W.js +0 -11
  262. package/apps/ui/dist/server/assets/codex-queries-CtgeZ7VL.js +0 -99
  263. package/apps/ui/dist/server/assets/codex-server-CGXU4H8-.js +0 -2294
  264. package/apps/ui/dist/server/assets/concurrency-VXtYvlGh.js +0 -18
  265. package/apps/ui/dist/server/assets/createServerRpc-CF_DEwnm.js +0 -12
  266. package/apps/ui/dist/server/assets/createSsrRpc-C754NPki.js +0 -16
  267. package/apps/ui/dist/server/assets/cursor-db-CZnYy7aT.js +0 -830
  268. package/apps/ui/dist/server/assets/cursor-exporter-types-CI3goo-c.js +0 -34
  269. package/apps/ui/dist/server/assets/cursor-queries-NCIM0Nat.js +0 -67
  270. package/apps/ui/dist/server/assets/cursor-recovery-CXpO8KcD.js +0 -361
  271. package/apps/ui/dist/server/assets/cursor-server-DNu52A3K.js +0 -213
  272. package/apps/ui/dist/server/assets/cursor-threads._composerId-BB0Y_Mao.js +0 -11
  273. package/apps/ui/dist/server/assets/cursor-threads._composerId-Ckn6ItHI.js +0 -582
  274. package/apps/ui/dist/server/assets/cursor-threads._composerId-p9-ARAzc.js +0 -18
  275. package/apps/ui/dist/server/assets/cursor-transcript-B7tGnqtn.js +0 -125
  276. package/apps/ui/dist/server/assets/cursor._workspaceKey-CZuohIUL.js +0 -28
  277. package/apps/ui/dist/server/assets/cursor._workspaceKey-DPp5JSjy.js +0 -401
  278. package/apps/ui/dist/server/assets/cursor._workspaceKey-nmg3YIOQ.js +0 -11
  279. package/apps/ui/dist/server/assets/cursor.index-CcsX7DG0.js +0 -11
  280. package/apps/ui/dist/server/assets/cursor.index-DkWT-mxw.js +0 -189
  281. package/apps/ui/dist/server/assets/data-table-Cdct823O.js +0 -189
  282. package/apps/ui/dist/server/assets/delete-confirm-dialog-BcBNCxWB.js +0 -144
  283. package/apps/ui/dist/server/assets/download-DMmiy1xf.js +0 -92
  284. package/apps/ui/dist/server/assets/dropdown-menu-Dy_9t6TN.js +0 -36
  285. package/apps/ui/dist/server/assets/empty-plugin-adapters-B3lHh1La.js +0 -5
  286. package/apps/ui/dist/server/assets/export-dialog-D88ze9Gy.js +0 -240
  287. package/apps/ui/dist/server/assets/formatters-FJaGZgJk.js +0 -91
  288. package/apps/ui/dist/server/assets/kiro-db--fXrED_-.js +0 -552
  289. package/apps/ui/dist/server/assets/kiro-queries-CzNlM2ok.js +0 -37
  290. package/apps/ui/dist/server/assets/kiro-server-9WRxg2Au.js +0 -72
  291. package/apps/ui/dist/server/assets/kiro-sessions._sessionId-CRY2c7YO.js +0 -11
  292. package/apps/ui/dist/server/assets/kiro-sessions._sessionId-F1UlwxmR.js +0 -449
  293. package/apps/ui/dist/server/assets/kiro-sessions._sessionId-bvTulT7C.js +0 -18
  294. package/apps/ui/dist/server/assets/kiro-transcript-DoekQBaH.js +0 -112
  295. package/apps/ui/dist/server/assets/kiro-transcript-phase-CJG40nQg.js +0 -27
  296. package/apps/ui/dist/server/assets/kiro._workspaceKey-BDe9sQwo.js +0 -11
  297. package/apps/ui/dist/server/assets/kiro._workspaceKey-CJsjgNwO.js +0 -28
  298. package/apps/ui/dist/server/assets/kiro._workspaceKey-D_-4Qb7y.js +0 -193
  299. package/apps/ui/dist/server/assets/kiro.index-C__-UROk.js +0 -11
  300. package/apps/ui/dist/server/assets/kiro.index-CmTbqeYj.js +0 -93
  301. package/apps/ui/dist/server/assets/loading-panel-BGFnWseS.js +0 -27
  302. package/apps/ui/dist/server/assets/metric-card-ByEeLu0r.js +0 -23
  303. package/apps/ui/dist/server/assets/model-label-B1NWGc65.js +0 -13
  304. package/apps/ui/dist/server/assets/opencode-db-BM7KjOzc.js +0 -397
  305. package/apps/ui/dist/server/assets/opencode-queries-BeNYXnQv.js +0 -50
  306. package/apps/ui/dist/server/assets/opencode-server-BpQ_kRze.js +0 -72
  307. package/apps/ui/dist/server/assets/opencode-sessions._sessionId-CGQ-t0vD.js +0 -518
  308. package/apps/ui/dist/server/assets/opencode-sessions._sessionId-D8Q7in_Z.js +0 -18
  309. package/apps/ui/dist/server/assets/opencode-sessions._sessionId-DKOvi0lV.js +0 -11
  310. package/apps/ui/dist/server/assets/opencode-think-tags-CAoD-EcZ.js +0 -87
  311. package/apps/ui/dist/server/assets/opencode-transcript-BNTcGNym.js +0 -141
  312. package/apps/ui/dist/server/assets/opencode-transcript-phase-OqLkiQD0.js +0 -32
  313. package/apps/ui/dist/server/assets/opencode._workspaceKey-BdqcWHw1.js +0 -11
  314. package/apps/ui/dist/server/assets/opencode._workspaceKey-CfH96HTT.js +0 -28
  315. package/apps/ui/dist/server/assets/opencode._workspaceKey-DdbHPDrO.js +0 -207
  316. package/apps/ui/dist/server/assets/opencode.index-BbVzkJXP.js +0 -11
  317. package/apps/ui/dist/server/assets/opencode.index-Vh_Gq_1L.js +0 -93
  318. package/apps/ui/dist/server/assets/page-header-VNSaM3xd.js +0 -29
  319. package/apps/ui/dist/server/assets/path-transforms-DL2IwtYd.js +0 -31
  320. package/apps/ui/dist/server/assets/projects._project-4io5LO0E.js +0 -20
  321. package/apps/ui/dist/server/assets/projects._project-Bshqk7JA.js +0 -12
  322. package/apps/ui/dist/server/assets/projects._project-D6ZoGhJ8.js +0 -395
  323. package/apps/ui/dist/server/assets/projects.index-BLXOx5eL.js +0 -12
  324. package/apps/ui/dist/server/assets/projects.index-BkLiF2FF.js +0 -182
  325. package/apps/ui/dist/server/assets/projects.index-DesYXwfi.js +0 -14
  326. package/apps/ui/dist/server/assets/reload-error-panel-BJMxY3U1.js +0 -25
  327. package/apps/ui/dist/server/assets/route-search-ts4W9MJ9.js +0 -38
  328. package/apps/ui/dist/server/assets/router-Sac2DGk6.js +0 -518
  329. package/apps/ui/dist/server/assets/routes-Bsact1uB.js +0 -184
  330. package/apps/ui/dist/server/assets/routes-BzkJgq4W.js +0 -34
  331. package/apps/ui/dist/server/assets/select-GW76p-ld.js +0 -76
  332. package/apps/ui/dist/server/assets/settings-OayxIYQQ.js +0 -100
  333. package/apps/ui/dist/server/assets/settings-store-DpEJEQ7M.js +0 -52
  334. package/apps/ui/dist/server/assets/shared-DyhChtHf.js +0 -137
  335. package/apps/ui/dist/server/assets/source-session-export-server-DNutCawb.js +0 -38
  336. package/apps/ui/dist/server/assets/sqlite-error-LZDrnxdd.js +0 -13
  337. package/apps/ui/dist/server/assets/start-B_HFwkkk.js +0 -4
  338. package/apps/ui/dist/server/assets/tabs-DkaChNVg.js +0 -501
  339. package/apps/ui/dist/server/assets/text-filter-CGKxMCKt.js +0 -36
  340. package/apps/ui/dist/server/assets/thread-transcript-stats-Dh34mt2u.js +0 -45
  341. package/apps/ui/dist/server/assets/threads._threadId-BSSK4nkI.js +0 -26
  342. package/apps/ui/dist/server/assets/threads._threadId-BeXEc4Lo.js +0 -648
  343. package/apps/ui/dist/server/assets/threads._threadId-Ci0S4mKU.js +0 -18
  344. package/apps/ui/dist/server/assets/ui-export-files-BHLX9bhN.js +0 -83
  345. package/apps/ui/dist/server/assets/utils-C_uf36nf.js +0 -8
  346. package/apps/ui/dist/server/server.js +0 -5895
  347. package/bin/codex-chats-claude.js +0 -5
  348. package/bin/codex-chats.js +0 -5
  349. package/bin/spiracha.js +0 -5
  350. package/src/export-chats.ts +0 -120
  351. package/src/export-claude.ts +0 -36
  352. package/src/export-cursor.ts +0 -244
  353. package/src/lib/claude-exporter.ts +0 -864
  354. package/src/lib/codex-exporter-cli.ts +0 -277
  355. package/src/lib/codex-exporter-db.ts +0 -319
  356. package/src/lib/codex-exporter.ts +0 -115
  357. package/src/lib/cursor-exporter.ts +0 -266
  358. package/src/lib/interactive-cli.ts +0 -433
  359. package/src/lib/native-open.ts +0 -54
  360. package/src/mcp-server.ts +0 -137
  361. package/src/spiracha.ts +0 -116
  362. package/src/ui-cli.ts +0 -310
  363. /package/apps/ui/{dist/client → public}/icon.svg +0 -0
  364. /package/apps/ui/{dist/client → public}/manifest.json +0 -0
  365. /package/apps/ui/{dist/client → public}/robots.txt +0 -0
@@ -1,34 +0,0 @@
1
- import os from "node:os";
2
- import path from "node:path";
3
- //#region ../../src/lib/cursor-exporter-types.ts
4
- var getDefaultCursorUserDir = (platform = process.platform, env = process.env, homeDir = os.homedir()) => {
5
- if (platform === "win32") return path.win32.join(env.APPDATA || path.win32.join(homeDir, "AppData", "Roaming"), "Cursor", "User");
6
- if (platform === "linux") return path.posix.join(env.XDG_DATA_HOME || path.posix.join(homeDir, ".local", "share"), "Cursor", "User");
7
- return path.posix.join(homeDir, "Library", "Application Support", "Cursor", "User");
8
- };
9
- var DEFAULT_CURSOR_USER_DIR = getDefaultCursorUserDir();
10
- var resolveCursorUserDir = () => {
11
- const configured = process.env.SPIRACHA_CURSOR_USER_DIR?.trim();
12
- return configured ? configured : DEFAULT_CURSOR_USER_DIR;
13
- };
14
- var getCursorWorkspaceStorageDir = (userDir = resolveCursorUserDir()) => path.join(userDir, "workspaceStorage");
15
- var getCursorGlobalDbPath = (userDir = resolveCursorUserDir()) => path.join(userDir, "globalStorage", "state.vscdb");
16
- var inferHomeDirFromCursorUserDir = (userDir) => {
17
- const normalized = userDir.replace(/\\/gu, "/");
18
- for (const suffix of [
19
- "/Library/Application Support/Cursor/User",
20
- "/AppData/Roaming/Cursor/User",
21
- "/.local/share/Cursor/User"
22
- ]) if (normalized.endsWith(suffix)) return userDir.slice(0, userDir.length - suffix.length);
23
- return null;
24
- };
25
- var getCursorProjectsDir = (userDir = resolveCursorUserDir()) => {
26
- const configured = process.env.SPIRACHA_CURSOR_PROJECTS_DIR?.trim();
27
- if (configured) return configured;
28
- const inferredHomeDir = inferHomeDirFromCursorUserDir(userDir);
29
- return inferredHomeDir ? path.join(inferredHomeDir, ".cursor", "projects") : path.join(userDir, "projects");
30
- };
31
- var COMPOSER_DATA_KEY = "composer.composerData";
32
- var COMPOSER_HEADERS_KEY = "composer.composerHeaders";
33
- //#endregion
34
- export { COMPOSER_DATA_KEY, COMPOSER_HEADERS_KEY, getCursorGlobalDbPath, getCursorProjectsDir, getCursorWorkspaceStorageDir, resolveCursorUserDir };
@@ -1,67 +0,0 @@
1
- import { t as createServerFn } from "../server.js";
2
- import { t as isRetryableSqliteError } from "./sqlite-error-LZDrnxdd.js";
3
- import { t as createSsrRpc } from "./createSsrRpc-C754NPki.js";
4
- import { z } from "zod";
5
- import { queryOptions } from "@tanstack/react-query";
6
- //#region src/lib/cursor-server.ts
7
- var workspaceSchema = z.object({ workspaceKey: z.string().min(1) });
8
- var threadSchema = z.object({ composerId: z.string().min(1) });
9
- var recoverSchema = z.object({
10
- apply: z.boolean().default(false),
11
- workspaceKey: z.string().min(1)
12
- });
13
- var exportSchema = z.object({
14
- composerId: z.string().min(1),
15
- includeCommentary: z.boolean().default(true),
16
- includeMetadata: z.boolean().default(true),
17
- includeTools: z.boolean().default(true),
18
- outputFormat: z.enum(["md", "txt"]).default("md"),
19
- zipArchive: z.boolean().default(false)
20
- });
21
- var exportThreadsSchema = z.object({
22
- composerIds: z.array(z.string().min(1)).min(1),
23
- includeCommentary: z.boolean().default(true),
24
- includeMetadata: z.boolean().default(true),
25
- includeTools: z.boolean().default(true),
26
- outputFormat: z.enum(["md", "txt"]).default("md"),
27
- zipArchive: z.boolean().default(true)
28
- });
29
- var deleteThreadsSchema = z.object({ composerIds: z.array(z.string().min(1)).min(1) });
30
- var listCursorWorkspacesFn = createServerFn({ method: "GET" }).handler(createSsrRpc("8fcf452a4587a4d4dc0c2f6439255e98123f23d863ca0e861403ae2a687272f2"));
31
- var listCursorThreadsFn = createServerFn({ method: "GET" }).validator(workspaceSchema).handler(createSsrRpc("23fb197bac88fb9e4950ef7608cd311d67c0867e424136c8373071dc54746806"));
32
- var getCursorThreadDetailFn = createServerFn({ method: "GET" }).validator(threadSchema).handler(createSsrRpc("6e893e740c05aad65a8eb32901b4c39277ebf718f0ba14b04d8df989bed2f32b"));
33
- var exportCursorThreadFn = createServerFn({ method: "POST" }).validator(exportSchema).handler(createSsrRpc("03050b86e5481024283bee890347a9da7b2493493044dcde6df989b3334d6b73"));
34
- var exportCursorThreadsFn = createServerFn({ method: "POST" }).validator(exportThreadsSchema).handler(createSsrRpc("e9609d5ab12ea0bc4dbd3289fad95417dd01a0a719c8ee588c0b8c8a9dc80c99"));
35
- var recoverCursorWorkspaceFn = createServerFn({ method: "POST" }).validator(recoverSchema).handler(createSsrRpc("a9bd5d510f2d1173d2ef610dda4d59a795af17e7c2a4affaba7e1f99822b2c40"));
36
- var deleteCursorThreadsFn = createServerFn({ method: "POST" }).validator(deleteThreadsSchema).handler(createSsrRpc("17afb84da4a3d5022132756ead0adaf0323660f50fc58d7f14830b01fdd59a13"));
37
- var deleteCursorWorkspaceFn = createServerFn({ method: "POST" }).validator(workspaceSchema).handler(createSsrRpc("fc72eb7835fc18130f6d7c20e15e560320521cd01c93e08667b340bfe6b90930"));
38
- //#endregion
39
- //#region src/lib/cursor-queries.ts
40
- var retrySqliteQuery = (failureCount, error) => {
41
- return failureCount < 3 && isRetryableSqliteError(error);
42
- };
43
- var retryDelay = (attemptIndex) => {
44
- return [150, 400][attemptIndex] ?? 800;
45
- };
46
- var cursorWorkspacesQueryOptions = () => queryOptions({
47
- queryFn: () => listCursorWorkspacesFn(),
48
- queryKey: ["cursor-workspaces"],
49
- retry: retrySqliteQuery,
50
- retryDelay
51
- });
52
- var cursorThreadsQueryOptions = (workspaceKey) => queryOptions({
53
- enabled: workspaceKey !== null,
54
- queryFn: () => listCursorThreadsFn({ data: { workspaceKey: workspaceKey ?? "" } }),
55
- queryKey: ["cursor-threads", workspaceKey ?? "none"],
56
- retry: retrySqliteQuery,
57
- retryDelay
58
- });
59
- var cursorThreadDetailQueryOptions = (composerId) => queryOptions({
60
- enabled: composerId !== null,
61
- queryFn: () => getCursorThreadDetailFn({ data: { composerId: composerId ?? "" } }),
62
- queryKey: ["cursor-thread", composerId ?? "none"],
63
- retry: retrySqliteQuery,
64
- retryDelay
65
- });
66
- //#endregion
67
- export { deleteCursorWorkspaceFn as a, recoverCursorWorkspaceFn as c, deleteCursorThreadsFn as i, cursorThreadsQueryOptions as n, exportCursorThreadFn as o, cursorWorkspacesQueryOptions as r, exportCursorThreadsFn as s, cursorThreadDetailQueryOptions as t };
@@ -1,361 +0,0 @@
1
- import { COMPOSER_DATA_KEY, COMPOSER_HEADERS_KEY, getCursorGlobalDbPath, resolveCursorUserDir } from "./cursor-exporter-types-CI3goo-c.js";
2
- import { findCursorTranscriptDirs, invalidateCursorDiscoveryCache, listCursorWorkspaceGroups, loadGlobalComposerHeaders, openCursorReadonlyDb } from "./cursor-db-CZnYy7aT.js";
3
- import { rm } from "node:fs/promises";
4
- import { Database } from "bun:sqlite";
5
- //#region ../../src/lib/cursor-recovery.ts
6
- var isCursorRunning = async () => {
7
- return await Bun.spawn([
8
- "pgrep",
9
- "-x",
10
- "Cursor"
11
- ], {
12
- stderr: "ignore",
13
- stdout: "ignore"
14
- }).exited === 0;
15
- };
16
- var backupStamp = () => (/* @__PURE__ */ new Date()).toISOString().replace(/[-:]/gu, "").replace(/\..+/u, "").replace("T", "-");
17
- var backupComposerHeaders = async (globalDbPath) => {
18
- const db = openCursorReadonlyDb(globalDbPath);
19
- let headers;
20
- try {
21
- headers = readJsonItem(db, "composer.composerHeaders") ?? { allComposers: [] };
22
- } finally {
23
- db.close();
24
- }
25
- const backupPath = `${globalDbPath}.composerHeaders.${backupStamp()}.json`;
26
- await Bun.write(backupPath, JSON.stringify(headers));
27
- return backupPath;
28
- };
29
- var backupPrunedThreads = async (globalDbPath, composerIds) => {
30
- const db = openCursorReadonlyDb(globalDbPath);
31
- try {
32
- const dump = composerIds.map((composerId) => ({
33
- bubbles: db.query("SELECT key, value FROM cursorDiskKV WHERE key LIKE ?").all(`bubbleId:${composerId}:%`),
34
- composerData: readJsonItemFromKv(db, `composerData:${composerId}`),
35
- composerId
36
- }));
37
- const backupPath = `${globalDbPath}.prunedThreads.${backupStamp()}.json`;
38
- await Bun.write(backupPath, JSON.stringify(dump));
39
- return backupPath;
40
- } finally {
41
- db.close();
42
- }
43
- };
44
- var readJsonItemFromKv = (db, key) => {
45
- const row = db.query("SELECT value FROM cursorDiskKV WHERE key = ?").get(key);
46
- if (!row?.value) return null;
47
- try {
48
- return JSON.parse(row.value);
49
- } catch {
50
- return null;
51
- }
52
- };
53
- var readJsonItem = (db, key) => {
54
- const row = db.query("SELECT value FROM ItemTable WHERE key = ?").get(key);
55
- if (!row?.value) return null;
56
- try {
57
- return JSON.parse(row.value);
58
- } catch {
59
- return null;
60
- }
61
- };
62
- var writeJsonItem = (db, key, value) => {
63
- db.run(`INSERT INTO ItemTable (key, value) VALUES (?, ?)
64
- ON CONFLICT(key) DO UPDATE SET value = excluded.value`, [key, JSON.stringify(value)]);
65
- };
66
- var scoreComposer = (entry) => Number(Boolean(entry.name)) + Number(entry.lastUpdatedAt ?? 0) + Number(entry.totalLinesAdded ?? 0);
67
- var mergeComposerEntries = (entries) => {
68
- const byId = /* @__PURE__ */ new Map();
69
- for (const entry of entries) {
70
- const id = entry.composerId;
71
- if (!id) continue;
72
- const current = byId.get(id);
73
- if (!current || scoreComposer(entry) >= scoreComposer(current)) byId.set(id, entry);
74
- }
75
- return [...byId.values()].sort((a, b) => Number(b.lastUpdatedAt ?? b.createdAt ?? 0) - Number(a.lastUpdatedAt ?? a.createdAt ?? 0));
76
- };
77
- var buildWorkspaceIdentifier = (bucket) => {
78
- if (bucket.kind === "folder" && bucket.folders[0]) {
79
- const folder = bucket.folders[0];
80
- return {
81
- id: bucket.bucketId,
82
- uri: {
83
- $mid: 1,
84
- external: `file://${folder}`,
85
- fsPath: folder,
86
- path: folder,
87
- scheme: "file"
88
- }
89
- };
90
- }
91
- return { id: bucket.bucketId };
92
- };
93
- var composersForBucket = (bucket, headers) => {
94
- let fromBucket = [];
95
- try {
96
- const db = openCursorReadonlyDb(bucket.dbPath);
97
- try {
98
- fromBucket = readJsonItem(db, "composer.composerData")?.allComposers ?? [];
99
- } finally {
100
- db.close();
101
- }
102
- } catch {
103
- fromBucket = [];
104
- }
105
- const linked = headers.filter((header) => header.workspaceIdentifier?.id === bucket.bucketId);
106
- return mergeComposerEntries([...fromBucket, ...linked]);
107
- };
108
- var chooseTargetBucket = (group) => {
109
- const [target, ...sources] = [...group.buckets].sort((a, b) => b.mtimeMs - a.mtimeMs || b.dbSizeBytes - a.dbSizeBytes);
110
- return {
111
- sources,
112
- target
113
- };
114
- };
115
- var relinkHeaders = (db, composers, sourceBucketIds, target) => {
116
- const headers = (readJsonItem(db, "composer.composerHeaders") ?? { allComposers: [] }).allComposers ?? [];
117
- const byId = new Map(headers.filter((header) => header.composerId).map((header) => [header.composerId, header]));
118
- const workspaceIdentifier = buildWorkspaceIdentifier(target);
119
- let relinked = 0;
120
- let added = 0;
121
- for (const composer of composers) {
122
- const id = composer.composerId;
123
- if (!id) continue;
124
- const existing = byId.get(id);
125
- if (existing) {
126
- const currentId = existing.workspaceIdentifier?.id;
127
- if (currentId !== target.bucketId && (currentId === void 0 || sourceBucketIds.has(currentId))) {
128
- existing.workspaceIdentifier = workspaceIdentifier;
129
- relinked += 1;
130
- }
131
- continue;
132
- }
133
- headers.push({
134
- ...composer,
135
- type: composer.type ?? "head",
136
- workspaceIdentifier
137
- });
138
- byId.set(id, headers[headers.length - 1]);
139
- added += 1;
140
- }
141
- if (relinked > 0 || added > 0) {
142
- headers.sort((a, b) => Number(b.lastUpdatedAt ?? b.createdAt ?? 0) - Number(a.lastUpdatedAt ?? a.createdAt ?? 0));
143
- writeJsonItem(db, COMPOSER_HEADERS_KEY, { allComposers: headers });
144
- }
145
- return {
146
- added,
147
- relinked
148
- };
149
- };
150
- var countBubbles = (db, composerId) => {
151
- return db.query("SELECT COUNT(*) AS count FROM cursorDiskKV WHERE key LIKE ?").get(`bubbleId:${composerId}:%`).count;
152
- };
153
- var recoverCursorWorkspaceGroup = async (group, apply, userDir = resolveCursorUserDir()) => {
154
- if (group.buckets.length === 0) throw new Error(`"${group.label}" has no on-disk Cursor storage bucket to recover into. Its threads can still be exported or deleted.`);
155
- const globalDbPath = getCursorGlobalDbPath(userDir);
156
- const headers = loadGlobalComposerHeaders(globalDbPath);
157
- const { target, sources } = chooseTargetBucket(group);
158
- const sourceBucketIds = new Set(sources.map((bucket) => bucket.bucketId));
159
- const merged = mergeComposerEntries([...composersForBucket(target, headers), ...sources.flatMap((bucket) => composersForBucket(bucket, headers))]);
160
- if (!apply) return buildRecoverResult(group, target, merged, globalDbPath, 0, merged.length);
161
- const currentBucketData = readTargetBucketComposerData(target);
162
- await backupComposerHeaders(globalDbPath);
163
- await backupTargetBucketComposerData(target, currentBucketData);
164
- const db = new Database(globalDbPath);
165
- let committed = false;
166
- let relinked = 0;
167
- let added = 0;
168
- try {
169
- db.exec("BEGIN IMMEDIATE");
170
- writeTargetBucketComposerData(target, buildTargetBucketComposerData(currentBucketData.data, merged));
171
- ({relinked, added} = relinkHeaders(db, merged, sourceBucketIds, target));
172
- db.exec("COMMIT");
173
- committed = true;
174
- } catch (error) {
175
- if (!committed) {
176
- try {
177
- db.exec("ROLLBACK");
178
- } catch {}
179
- try {
180
- writeTargetBucketComposerData(target, currentBucketData);
181
- } catch {}
182
- }
183
- throw error;
184
- } finally {
185
- db.close();
186
- invalidateCursorDiscoveryCache();
187
- }
188
- return buildRecoverResult(group, target, merged, globalDbPath, relinked, added);
189
- };
190
- var readTargetBucketComposerData = (target) => {
191
- const db = openCursorReadonlyDb(target.dbPath);
192
- try {
193
- const data = readJsonItem(db, COMPOSER_DATA_KEY);
194
- return {
195
- data: data ?? {},
196
- exists: data !== null
197
- };
198
- } finally {
199
- db.close();
200
- }
201
- };
202
- var backupTargetBucketComposerData = async (target, snapshot) => {
203
- const backupPath = `${target.dbPath}.composerData.${backupStamp()}.json`;
204
- await Bun.write(backupPath, JSON.stringify(snapshot));
205
- return backupPath;
206
- };
207
- var buildTargetBucketComposerData = (existing, merged) => {
208
- const selectedIds = merged.map((entry) => entry.composerId).filter((value) => Boolean(value));
209
- return {
210
- ...existing,
211
- allComposers: merged,
212
- hasMigratedComposerData: true,
213
- hasMigratedMultipleComposers: true,
214
- lastFocusedComposerIds: selectedIds.slice(0, 1),
215
- selectedComposerIds: selectedIds.slice(0, 5)
216
- };
217
- };
218
- var writeTargetBucketComposerData = (target, snapshot) => {
219
- const db = new Database(target.dbPath);
220
- try {
221
- if ("exists" in snapshot && !snapshot.exists) {
222
- db.run("DELETE FROM ItemTable WHERE key = ?", [COMPOSER_DATA_KEY]);
223
- return;
224
- }
225
- writeJsonItem(db, COMPOSER_DATA_KEY, "exists" in snapshot ? snapshot.data : snapshot);
226
- } finally {
227
- db.close();
228
- }
229
- };
230
- var buildRecoverResult = (group, target, merged, globalDbPath, relinked, added) => {
231
- const db = openCursorReadonlyDb(globalDbPath);
232
- try {
233
- return {
234
- activeBucketId: target.bucketId,
235
- addedHeaderCount: added,
236
- mergedThreadCount: merged.length,
237
- relinkedHeaderCount: relinked,
238
- threads: merged.filter((entry) => entry.composerId).map((entry) => ({
239
- bubbleCount: countBubbles(db, entry.composerId),
240
- composerId: entry.composerId,
241
- name: typeof entry.name === "string" && entry.name ? entry.name : "(untitled)"
242
- })),
243
- workspaceKey: group.key
244
- };
245
- } finally {
246
- db.close();
247
- }
248
- };
249
- var removeThreadFromBucket = (db, composerIds) => {
250
- const data = readJsonItem(db, COMPOSER_DATA_KEY);
251
- if (!data?.allComposers?.length) return false;
252
- const before = data.allComposers.length;
253
- data.allComposers = data.allComposers.filter((entry) => !composerIds.has(entry.composerId ?? ""));
254
- if (data.allComposers.length === before) return false;
255
- data.selectedComposerIds = (data.selectedComposerIds ?? []).filter((id) => !composerIds.has(id));
256
- data.lastFocusedComposerIds = (data.lastFocusedComposerIds ?? []).filter((id) => !composerIds.has(id));
257
- writeJsonItem(db, COMPOSER_DATA_KEY, data);
258
- return true;
259
- };
260
- var pruneGlobalThread = (db, composerId) => {
261
- const bubbleResult = db.run("DELETE FROM cursorDiskKV WHERE key LIKE ?", [`bubbleId:${composerId}:%`]);
262
- const headResult = db.run("DELETE FROM cursorDiskKV WHERE key = ?", [`composerData:${composerId}`]);
263
- return {
264
- bubbles: bubbleResult.changes ?? 0,
265
- composerData: headResult.changes ?? 0
266
- };
267
- };
268
- var removeThreadHeaders = (db, composerIds) => {
269
- const data = readJsonItem(db, COMPOSER_HEADERS_KEY);
270
- if (!data?.allComposers?.length) return 0;
271
- const before = data.allComposers.length;
272
- data.allComposers = data.allComposers.filter((entry) => !composerIds.has(entry.composerId ?? ""));
273
- const removed = before - data.allComposers.length;
274
- if (removed > 0) writeJsonItem(db, COMPOSER_HEADERS_KEY, data);
275
- return removed;
276
- };
277
- var pruneCursorThreads = async (threads, apply, userDir = resolveCursorUserDir()) => {
278
- const composerIds = new Set(threads.map((thread) => thread.composerId));
279
- const globalDbPath = getCursorGlobalDbPath(userDir);
280
- const result = {
281
- bubblesDeleted: 0,
282
- composerDataDeleted: 0,
283
- composerIds: [...composerIds],
284
- headersRemoved: 0,
285
- transcriptDirsRemoved: 0,
286
- workspaceBucketsUpdated: 0
287
- };
288
- if (composerIds.size === 0) return result;
289
- if (!apply) {
290
- result.bubblesDeleted = threads.reduce((sum, thread) => sum + thread.bubbleCount, 0);
291
- result.composerDataDeleted = threads.length;
292
- result.headersRemoved = threads.length;
293
- result.transcriptDirsRemoved = threads.reduce((sum, thread) => sum + thread.transcriptDirs.length, 0);
294
- return result;
295
- }
296
- await backupPrunedThreads(globalDbPath, [...composerIds]);
297
- await pruneGlobalThreads(globalDbPath, threads, composerIds, result);
298
- await pruneWorkspaceBuckets(threads, composerIds, result, userDir);
299
- await pruneTranscriptDirs(threads, result);
300
- invalidateCursorDiscoveryCache();
301
- return result;
302
- };
303
- var pruneGlobalThreads = async (globalDbPath, threads, composerIds, result) => {
304
- const db = new Database(globalDbPath);
305
- try {
306
- for (const thread of threads) {
307
- const deleted = pruneGlobalThread(db, thread.composerId);
308
- result.bubblesDeleted += deleted.bubbles;
309
- result.composerDataDeleted += deleted.composerData;
310
- }
311
- result.headersRemoved = removeThreadHeaders(db, composerIds);
312
- } finally {
313
- db.close();
314
- }
315
- };
316
- var pruneWorkspaceBuckets = async (_threads, composerIds, result, userDir) => {
317
- const groups = await listCursorWorkspaceGroups(userDir);
318
- const dbPaths = /* @__PURE__ */ new Set();
319
- for (const group of groups) for (const bucket of group.buckets) dbPaths.add(bucket.dbPath);
320
- for (const dbPath of dbPaths) {
321
- const db = new Database(dbPath);
322
- try {
323
- if (removeThreadFromBucket(db, composerIds)) result.workspaceBucketsUpdated += 1;
324
- } finally {
325
- db.close();
326
- }
327
- }
328
- };
329
- var pruneTranscriptDirs = async (threads, result) => {
330
- for (const thread of threads) for (const dir of thread.transcriptDirs) {
331
- await rm(dir, {
332
- force: true,
333
- recursive: true
334
- });
335
- result.transcriptDirsRemoved += 1;
336
- }
337
- };
338
- var collectCursorThreadsForDeletion = async (composerIds, userDir = resolveCursorUserDir()) => {
339
- const db = openCursorReadonlyDb(getCursorGlobalDbPath(userDir));
340
- const summaries = [];
341
- try {
342
- for (const composerId of composerIds) summaries.push({
343
- bubbleBytes: 0,
344
- bubbleCount: countBubbles(db, composerId),
345
- bucketId: null,
346
- composerId,
347
- createdAtMs: null,
348
- lastUpdatedAtMs: null,
349
- mode: null,
350
- name: "",
351
- transcriptDirs: await findCursorTranscriptDirs(composerId, userDir),
352
- workspaceKey: "",
353
- workspaceLabel: ""
354
- });
355
- } finally {
356
- db.close();
357
- }
358
- return summaries;
359
- };
360
- //#endregion
361
- export { collectCursorThreadsForDeletion, isCursorRunning, pruneCursorThreads, recoverCursorWorkspaceGroup };
@@ -1,213 +0,0 @@
1
- import { t as createServerFn } from "../server.js";
2
- import { t as createServerRpc } from "./createServerRpc-CF_DEwnm.js";
3
- import { a as sanitizeExportFileName, i as resolveUniqueExportFileBaseName, n as ensureUiExportDir, o as zipExportDirectory, r as getExportMimeType, t as buildUiExportDownloadUrl } from "./ui-export-files-BHLX9bhN.js";
4
- import { z } from "zod";
5
- import { randomUUID } from "node:crypto";
6
- import { mkdtemp, rm } from "node:fs/promises";
7
- import os from "node:os";
8
- import path from "node:path";
9
- //#region src/lib/cursor-server.ts?tss-serverfn-split
10
- var workspaceSchema = z.object({ workspaceKey: z.string().min(1) });
11
- var threadSchema = z.object({ composerId: z.string().min(1) });
12
- var recoverSchema = z.object({
13
- apply: z.boolean().default(false),
14
- workspaceKey: z.string().min(1)
15
- });
16
- var exportSchema = z.object({
17
- composerId: z.string().min(1),
18
- includeCommentary: z.boolean().default(true),
19
- includeMetadata: z.boolean().default(true),
20
- includeTools: z.boolean().default(true),
21
- outputFormat: z.enum(["md", "txt"]).default("md"),
22
- zipArchive: z.boolean().default(false)
23
- });
24
- var exportThreadsSchema = z.object({
25
- composerIds: z.array(z.string().min(1)).min(1),
26
- includeCommentary: z.boolean().default(true),
27
- includeMetadata: z.boolean().default(true),
28
- includeTools: z.boolean().default(true),
29
- outputFormat: z.enum(["md", "txt"]).default("md"),
30
- zipArchive: z.boolean().default(true)
31
- });
32
- var deleteThreadsSchema = z.object({ composerIds: z.array(z.string().min(1)).min(1) });
33
- var ensureCursorClosedForWrite = async () => {
34
- const { isCursorRunning } = await import("./cursor-recovery-CXpO8KcD.js");
35
- if (await isCursorRunning()) throw new Error("Quit Cursor before deleting. It rewrites chat history on exit, which can resurrect deleted threads.");
36
- };
37
- var findGroupByKey = async (workspaceKey) => {
38
- const { listCursorWorkspaceGroups } = await import("./cursor-db-CZnYy7aT.js");
39
- const group = (await listCursorWorkspaceGroups()).find((candidate) => candidate.key === workspaceKey);
40
- if (!group) throw new Error(`Cursor workspace not found: ${workspaceKey}`);
41
- return group;
42
- };
43
- var toSafeExportName = (value) => {
44
- return sanitizeExportFileName(value) || "cursor-thread";
45
- };
46
- var renderCursorZipDownload = async (rendered, outputFormat) => {
47
- const exportDir = await ensureUiExportDir();
48
- const exportBaseName = rendered.length === 1 ? `${toSafeExportName(rendered[0].composerId)}` : `cursor-threads-${rendered.length}`;
49
- const workspaceDir = await mkdtemp(path.join(os.tmpdir(), `${exportBaseName}-`));
50
- const zipPath = path.join(exportDir, `${exportBaseName}-${randomUUID()}.zip`);
51
- const usedBaseNames = /* @__PURE__ */ new Map();
52
- try {
53
- for (const entry of rendered) {
54
- const fileBaseName = resolveUniqueExportFileBaseName(toSafeExportName(entry.composerId), usedBaseNames);
55
- await Bun.write(path.join(workspaceDir, `${fileBaseName}.${outputFormat}`), entry.content);
56
- }
57
- await zipExportDirectory(workspaceDir, zipPath);
58
- } finally {
59
- await rm(workspaceDir, {
60
- force: true,
61
- recursive: true
62
- });
63
- }
64
- return {
65
- downloadUrl: buildUiExportDownloadUrl(zipPath),
66
- fileName: `${exportBaseName}.zip`,
67
- mimeType: "application/zip",
68
- mode: "download_url"
69
- };
70
- };
71
- var findCursorThreadByComposerId = async (composerId) => {
72
- const { listCursorThreadsForGroup, listCursorWorkspaceGroups } = await import("./cursor-db-CZnYy7aT.js");
73
- for (const group of await listCursorWorkspaceGroups()) {
74
- const thread = (await listCursorThreadsForGroup(group, void 0, { includeTranscriptDirs: false })).find((candidate) => candidate.composerId === composerId);
75
- if (thread) return thread;
76
- }
77
- return null;
78
- };
79
- var renderCursorDownload = async (input) => {
80
- const { readCursorThreadTranscriptWithAgentFiles } = await import("./cursor-db-CZnYy7aT.js");
81
- const { getCursorGlobalDbPath } = await import("./cursor-exporter-types-CI3goo-c.js");
82
- const { renderCursorTranscript } = await import("./cursor-transcript-B7tGnqtn.js");
83
- const globalDbPath = getCursorGlobalDbPath();
84
- const rendered = await Promise.all(input.composerIds.map(async (composerId) => {
85
- const transcript = await readCursorThreadTranscriptWithAgentFiles(globalDbPath, composerId);
86
- if (!transcript) throw new Error(`No transcript found for thread: ${composerId}`);
87
- const content = renderCursorTranscript(transcript, {
88
- includeCommentary: input.includeCommentary,
89
- includeMetadata: input.includeMetadata,
90
- includeTools: input.includeTools,
91
- outputFormat: input.outputFormat
92
- });
93
- if (!content) throw new Error(`Thread has no exportable content: ${composerId}`);
94
- return {
95
- composerId,
96
- content
97
- };
98
- }));
99
- if (input.zipArchive || rendered.length > 1) return renderCursorZipDownload(rendered, input.outputFormat);
100
- if (rendered.length === 1) return {
101
- content: rendered[0].content,
102
- fileName: `${toSafeExportName(rendered[0].composerId)}.${input.outputFormat}`,
103
- mimeType: getExportMimeType(input.outputFormat),
104
- mode: "download"
105
- };
106
- throw new Error("No Cursor threads selected for export");
107
- };
108
- var listCursorWorkspacesFn_createServerFn_handler = createServerRpc({
109
- id: "8fcf452a4587a4d4dc0c2f6439255e98123f23d863ca0e861403ae2a687272f2",
110
- name: "listCursorWorkspacesFn",
111
- filename: "src/lib/cursor-server.ts"
112
- }, (opts) => listCursorWorkspacesFn.__executeServer(opts));
113
- var listCursorWorkspacesFn = createServerFn({ method: "GET" }).handler(listCursorWorkspacesFn_createServerFn_handler, async () => {
114
- const { listCursorWorkspaceGroups } = await import("./cursor-db-CZnYy7aT.js");
115
- return listCursorWorkspaceGroups();
116
- });
117
- var listCursorThreadsFn_createServerFn_handler = createServerRpc({
118
- id: "23fb197bac88fb9e4950ef7608cd311d67c0867e424136c8373071dc54746806",
119
- name: "listCursorThreadsFn",
120
- filename: "src/lib/cursor-server.ts"
121
- }, (opts) => listCursorThreadsFn.__executeServer(opts));
122
- var listCursorThreadsFn = createServerFn({ method: "GET" }).validator(workspaceSchema).handler(listCursorThreadsFn_createServerFn_handler, async ({ data }) => {
123
- const { listCursorThreadsForGroup } = await import("./cursor-db-CZnYy7aT.js");
124
- return listCursorThreadsForGroup(await findGroupByKey(data.workspaceKey), void 0, { includeTranscriptDirs: false });
125
- });
126
- var getCursorThreadDetailFn_createServerFn_handler = createServerRpc({
127
- id: "6e893e740c05aad65a8eb32901b4c39277ebf718f0ba14b04d8df989bed2f32b",
128
- name: "getCursorThreadDetailFn",
129
- filename: "src/lib/cursor-server.ts"
130
- }, (opts) => getCursorThreadDetailFn.__executeServer(opts));
131
- var getCursorThreadDetailFn = createServerFn({ method: "GET" }).validator(threadSchema).handler(getCursorThreadDetailFn_createServerFn_handler, async ({ data }) => {
132
- const { readCursorThreadTranscriptWithAgentFiles } = await import("./cursor-db-CZnYy7aT.js");
133
- const { getCursorGlobalDbPath } = await import("./cursor-exporter-types-CI3goo-c.js");
134
- const thread = await findCursorThreadByComposerId(data.composerId);
135
- if (!thread) throw new Error(`Cursor thread not found: ${data.composerId}`);
136
- return {
137
- thread,
138
- transcript: await readCursorThreadTranscriptWithAgentFiles(getCursorGlobalDbPath(), data.composerId)
139
- };
140
- });
141
- var exportCursorThreadFn_createServerFn_handler = createServerRpc({
142
- id: "03050b86e5481024283bee890347a9da7b2493493044dcde6df989b3334d6b73",
143
- name: "exportCursorThreadFn",
144
- filename: "src/lib/cursor-server.ts"
145
- }, (opts) => exportCursorThreadFn.__executeServer(opts));
146
- var exportCursorThreadFn = createServerFn({ method: "POST" }).validator(exportSchema).handler(exportCursorThreadFn_createServerFn_handler, async ({ data }) => {
147
- return await renderCursorDownload({
148
- composerIds: [data.composerId],
149
- includeCommentary: data.includeCommentary,
150
- includeMetadata: data.includeMetadata,
151
- includeTools: data.includeTools,
152
- outputFormat: data.outputFormat,
153
- zipArchive: data.zipArchive
154
- });
155
- });
156
- var exportCursorThreadsFn_createServerFn_handler = createServerRpc({
157
- id: "e9609d5ab12ea0bc4dbd3289fad95417dd01a0a719c8ee588c0b8c8a9dc80c99",
158
- name: "exportCursorThreadsFn",
159
- filename: "src/lib/cursor-server.ts"
160
- }, (opts) => exportCursorThreadsFn.__executeServer(opts));
161
- var exportCursorThreadsFn = createServerFn({ method: "POST" }).validator(exportThreadsSchema).handler(exportCursorThreadsFn_createServerFn_handler, async ({ data }) => {
162
- return await renderCursorDownload({
163
- composerIds: data.composerIds,
164
- includeCommentary: data.includeCommentary,
165
- includeMetadata: data.includeMetadata,
166
- includeTools: data.includeTools,
167
- outputFormat: data.outputFormat,
168
- zipArchive: data.zipArchive
169
- });
170
- });
171
- var recoverCursorWorkspaceFn_createServerFn_handler = createServerRpc({
172
- id: "a9bd5d510f2d1173d2ef610dda4d59a795af17e7c2a4affaba7e1f99822b2c40",
173
- name: "recoverCursorWorkspaceFn",
174
- filename: "src/lib/cursor-server.ts"
175
- }, (opts) => recoverCursorWorkspaceFn.__executeServer(opts));
176
- var recoverCursorWorkspaceFn = createServerFn({ method: "POST" }).validator(recoverSchema).handler(recoverCursorWorkspaceFn_createServerFn_handler, async ({ data }) => {
177
- const { isCursorRunning, recoverCursorWorkspaceGroup } = await import("./cursor-recovery-CXpO8KcD.js");
178
- const group = await findGroupByKey(data.workspaceKey);
179
- if (data.apply && await isCursorRunning()) throw new Error("Quit Cursor before recovering. It overwrites chat history on exit, undoing the recovery.");
180
- return recoverCursorWorkspaceGroup(group, data.apply);
181
- });
182
- var deleteCursorThreadsFn_createServerFn_handler = createServerRpc({
183
- id: "17afb84da4a3d5022132756ead0adaf0323660f50fc58d7f14830b01fdd59a13",
184
- name: "deleteCursorThreadsFn",
185
- filename: "src/lib/cursor-server.ts"
186
- }, (opts) => deleteCursorThreadsFn.__executeServer(opts));
187
- var deleteCursorThreadsFn = createServerFn({ method: "POST" }).validator(deleteThreadsSchema).handler(deleteCursorThreadsFn_createServerFn_handler, async ({ data }) => {
188
- const { collectCursorThreadsForDeletion, pruneCursorThreads } = await import("./cursor-recovery-CXpO8KcD.js");
189
- await ensureCursorClosedForWrite();
190
- return pruneCursorThreads(await collectCursorThreadsForDeletion(data.composerIds), true);
191
- });
192
- var deleteCursorWorkspaceFn_createServerFn_handler = createServerRpc({
193
- id: "fc72eb7835fc18130f6d7c20e15e560320521cd01c93e08667b340bfe6b90930",
194
- name: "deleteCursorWorkspaceFn",
195
- filename: "src/lib/cursor-server.ts"
196
- }, (opts) => deleteCursorWorkspaceFn.__executeServer(opts));
197
- var deleteCursorWorkspaceFn = createServerFn({ method: "POST" }).validator(workspaceSchema).handler(deleteCursorWorkspaceFn_createServerFn_handler, async ({ data }) => {
198
- const { listCursorThreadsForGroup } = await import("./cursor-db-CZnYy7aT.js");
199
- const { collectCursorThreadsForDeletion, pruneCursorThreads } = await import("./cursor-recovery-CXpO8KcD.js");
200
- await ensureCursorClosedForWrite();
201
- const composerIds = (await listCursorThreadsForGroup(await findGroupByKey(data.workspaceKey), void 0, { includeTranscriptDirs: false })).map((thread) => thread.composerId);
202
- if (composerIds.length === 0) return {
203
- bubblesDeleted: 0,
204
- composerDataDeleted: 0,
205
- composerIds: [],
206
- headersRemoved: 0,
207
- transcriptDirsRemoved: 0,
208
- workspaceBucketsUpdated: 0
209
- };
210
- return pruneCursorThreads(await collectCursorThreadsForDeletion(composerIds), true);
211
- });
212
- //#endregion
213
- export { deleteCursorThreadsFn_createServerFn_handler, deleteCursorWorkspaceFn_createServerFn_handler, exportCursorThreadFn_createServerFn_handler, exportCursorThreadsFn_createServerFn_handler, getCursorThreadDetailFn_createServerFn_handler, listCursorThreadsFn_createServerFn_handler, listCursorWorkspacesFn_createServerFn_handler, recoverCursorWorkspaceFn_createServerFn_handler };