spiracha 1.4.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 (319) hide show
  1. package/AGENTS.md +116 -164
  2. package/README.md +92 -237
  3. package/apps/ui/AGENTS.md +36 -7
  4. package/apps/ui/README.md +79 -6
  5. package/apps/ui/components.json +21 -0
  6. package/apps/ui/package.json +65 -0
  7. package/apps/ui/{dist/client → public}/icon.svg +2 -1
  8. package/apps/ui/src/components/antigravity-conversations-table.tsx +206 -0
  9. package/apps/ui/src/components/antigravity-keychain-panel.tsx +76 -0
  10. package/apps/ui/src/components/antigravity-workspaces-table.tsx +63 -0
  11. package/apps/ui/src/components/app-shell.tsx +124 -0
  12. package/apps/ui/src/components/breadcrumbs.tsx +53 -0
  13. package/apps/ui/src/components/claude-code-sessions-table.tsx +114 -0
  14. package/apps/ui/src/components/claude-code-workspaces-table.tsx +55 -0
  15. package/apps/ui/src/components/cursor-threads-table.tsx +189 -0
  16. package/apps/ui/src/components/cursor-workspaces-table.tsx +140 -0
  17. package/apps/ui/src/components/data-table.tsx +241 -0
  18. package/apps/ui/src/components/delete-confirm-dialog.tsx +88 -0
  19. package/apps/ui/src/components/export-dialog.tsx +184 -0
  20. package/apps/ui/src/components/json-panel.tsx +17 -0
  21. package/apps/ui/src/components/kiro-sessions-table.tsx +112 -0
  22. package/apps/ui/src/components/kiro-workspaces-table.tsx +53 -0
  23. package/apps/ui/src/components/list-search-input.tsx +18 -0
  24. package/apps/ui/src/components/loading-panel.tsx +23 -0
  25. package/apps/ui/src/components/metadata-section.tsx +31 -0
  26. package/apps/ui/src/components/metric-card.tsx +19 -0
  27. package/apps/ui/src/components/opencode-sessions-table.tsx +128 -0
  28. package/apps/ui/src/components/opencode-workspaces-table.tsx +57 -0
  29. package/apps/ui/src/components/page-header.tsx +33 -0
  30. package/apps/ui/src/components/projects-loading-state.tsx +74 -0
  31. package/apps/ui/src/components/projects-table.tsx +108 -0
  32. package/apps/ui/src/components/qoder-sessions-table.tsx +112 -0
  33. package/apps/ui/src/components/qoder-workspaces-table.tsx +53 -0
  34. package/apps/ui/src/components/recent-threads-list.tsx +52 -0
  35. package/apps/ui/src/components/reload-error-panel.tsx +20 -0
  36. package/apps/ui/src/components/text-document-panel.tsx +19 -0
  37. package/apps/ui/src/components/theme-toggle.tsx +48 -0
  38. package/apps/ui/src/components/threads-table.tsx +202 -0
  39. package/apps/ui/src/components/transcript-view.tsx +552 -0
  40. package/apps/ui/src/components/ui/alert-dialog.tsx +160 -0
  41. package/apps/ui/src/components/ui/badge.tsx +45 -0
  42. package/apps/ui/src/components/ui/button.tsx +62 -0
  43. package/apps/ui/src/components/ui/checkbox.tsx +29 -0
  44. package/apps/ui/src/components/ui/dialog.tsx +137 -0
  45. package/apps/ui/src/components/ui/dropdown-menu.tsx +217 -0
  46. package/apps/ui/src/components/ui/input.tsx +21 -0
  47. package/apps/ui/src/components/ui/scroll-area.tsx +46 -0
  48. package/apps/ui/src/components/ui/select.tsx +163 -0
  49. package/apps/ui/src/components/ui/separator.tsx +28 -0
  50. package/apps/ui/src/components/ui/sheet.tsx +107 -0
  51. package/apps/ui/src/components/ui/skeleton.tsx +7 -0
  52. package/apps/ui/src/components/ui/table.tsx +76 -0
  53. package/apps/ui/src/components/ui/tabs.tsx +71 -0
  54. package/apps/ui/src/components/ui/tooltip.tsx +44 -0
  55. package/apps/ui/src/integrations/tanstack-query/devtools.tsx +6 -0
  56. package/apps/ui/src/integrations/tanstack-query/root-provider.tsx +10 -0
  57. package/apps/ui/src/lib/antigravity-conversation-state.ts +28 -0
  58. package/apps/ui/src/lib/antigravity-queries.ts +33 -0
  59. package/apps/ui/src/lib/antigravity-server.ts +128 -0
  60. package/apps/ui/src/lib/antigravity-transcript-events.ts +335 -0
  61. package/apps/ui/src/lib/claude-code-queries.ts +26 -0
  62. package/apps/ui/src/lib/claude-code-server.ts +75 -0
  63. package/apps/ui/src/lib/claude-code-transcript-events.ts +154 -0
  64. package/apps/ui/src/lib/codex-queries.ts +66 -0
  65. package/apps/ui/src/lib/codex-server.ts +209 -0
  66. package/apps/ui/src/lib/cursor-queries.ts +37 -0
  67. package/apps/ui/src/lib/cursor-server.ts +272 -0
  68. package/apps/ui/src/lib/cursor-transcript-events.ts +229 -0
  69. package/apps/ui/src/lib/download.ts +166 -0
  70. package/apps/ui/src/lib/formatters.ts +149 -0
  71. package/apps/ui/src/lib/kiro-queries.ts +22 -0
  72. package/apps/ui/src/lib/kiro-server.ts +73 -0
  73. package/apps/ui/src/lib/kiro-transcript-events.ts +113 -0
  74. package/apps/ui/src/lib/opencode-queries.ts +37 -0
  75. package/apps/ui/src/lib/opencode-server.ts +73 -0
  76. package/apps/ui/src/lib/opencode-transcript-events.ts +221 -0
  77. package/apps/ui/src/lib/package-metadata.ts +16 -0
  78. package/apps/ui/src/lib/path-utils.ts +13 -0
  79. package/apps/ui/src/lib/qoder-queries.ts +22 -0
  80. package/apps/ui/src/lib/qoder-server.ts +79 -0
  81. package/apps/ui/src/lib/qoder-transcript-events.ts +139 -0
  82. package/apps/ui/src/lib/route-search.ts +68 -0
  83. package/apps/ui/src/lib/settings-store.tsx +59 -0
  84. package/apps/ui/src/lib/source-session-export-server.ts +56 -0
  85. package/apps/ui/src/lib/text-filter.ts +22 -0
  86. package/apps/ui/src/lib/thread-id.ts +3 -0
  87. package/apps/ui/src/lib/thread-transcript-stats.ts +57 -0
  88. package/apps/ui/src/lib/utils.ts +7 -0
  89. package/apps/ui/src/routeTree.gen.ts +730 -0
  90. package/apps/ui/src/router.tsx +20 -0
  91. package/apps/ui/src/routes/$threadId.tsx +22 -0
  92. package/apps/ui/src/routes/__root.tsx +127 -0
  93. package/apps/ui/src/routes/analytics.tsx +143 -0
  94. package/apps/ui/src/routes/antigravity-conversations.$conversationId.tsx +438 -0
  95. package/apps/ui/src/routes/antigravity.$workspaceKey.tsx +127 -0
  96. package/apps/ui/src/routes/antigravity.index.tsx +51 -0
  97. package/apps/ui/src/routes/api.v1.conversation-query.ts +12 -0
  98. package/apps/ui/src/routes/api.v1.conversations.$source.$id.export.ts +12 -0
  99. package/apps/ui/src/routes/api.v1.conversations.$source.$id.ts +12 -0
  100. package/apps/ui/src/routes/api.v1.conversations.ts +12 -0
  101. package/apps/ui/src/routes/api.v1.resolve.ts +12 -0
  102. package/apps/ui/src/routes/api.v1.sources.ts +12 -0
  103. package/apps/ui/src/routes/claude-code-sessions.$sessionId.tsx +342 -0
  104. package/apps/ui/src/routes/claude-code.$workspaceKey.tsx +135 -0
  105. package/apps/ui/src/routes/claude-code.index.tsx +48 -0
  106. package/apps/ui/src/routes/codex.$project.tsx +390 -0
  107. package/apps/ui/src/routes/codex.index.tsx +116 -0
  108. package/apps/ui/src/routes/cursor-threads.$composerId.tsx +435 -0
  109. package/apps/ui/src/routes/cursor.$workspaceKey.tsx +416 -0
  110. package/apps/ui/src/routes/cursor.index.tsx +120 -0
  111. package/apps/ui/src/routes/index.tsx +124 -0
  112. package/apps/ui/src/routes/kiro-sessions.$sessionId.tsx +345 -0
  113. package/apps/ui/src/routes/kiro.$workspaceKey.tsx +136 -0
  114. package/apps/ui/src/routes/kiro.index.tsx +48 -0
  115. package/apps/ui/src/routes/opencode-sessions.$sessionId.tsx +334 -0
  116. package/apps/ui/src/routes/opencode.$workspaceKey.tsx +135 -0
  117. package/apps/ui/src/routes/opencode.index.tsx +48 -0
  118. package/apps/ui/src/routes/qoder-sessions.$sessionId.tsx +341 -0
  119. package/apps/ui/src/routes/qoder.$workspaceKey.tsx +139 -0
  120. package/apps/ui/src/routes/qoder.index.tsx +48 -0
  121. package/apps/ui/src/routes/settings.tsx +91 -0
  122. package/apps/ui/src/routes/threads.$threadId.tsx +619 -0
  123. package/apps/ui/src/styles.css +122 -0
  124. package/apps/ui/tsconfig.json +29 -0
  125. package/apps/ui/vite.config.ts +84 -0
  126. package/bin/spiracha.ts +32 -0
  127. package/package.json +50 -60
  128. package/src/client.ts +290 -0
  129. package/src/lib/antigravity-db.ts +213 -19
  130. package/src/lib/antigravity-exporter-types.ts +1 -0
  131. package/src/lib/claude-code-db.ts +655 -0
  132. package/src/lib/claude-code-exporter-types.ts +110 -0
  133. package/src/lib/claude-code-transcript-phase.ts +25 -0
  134. package/src/lib/claude-code-transcript.ts +180 -0
  135. package/src/lib/codex-analytics.ts +1 -1
  136. package/src/lib/codex-browser-db.ts +856 -61
  137. package/src/lib/codex-browser-export.ts +24 -16
  138. package/src/lib/codex-browser-types.ts +1 -1
  139. package/src/lib/codex-thread-cache.ts +17 -1
  140. package/src/lib/{codex-exporter-types.ts → codex-thread-types.ts} +2 -30
  141. package/src/lib/{codex-exporter-transcript.ts → codex-transcript-renderer.ts} +64 -28
  142. package/src/lib/concurrency.ts +25 -0
  143. package/src/lib/conversation-api.ts +792 -0
  144. package/src/lib/conversation-data/adapter-helpers.ts +110 -0
  145. package/src/lib/conversation-data/antigravity-adapter.ts +148 -0
  146. package/src/lib/conversation-data/claude-code-adapter.ts +175 -0
  147. package/src/lib/conversation-data/codex-adapter.ts +245 -0
  148. package/src/lib/conversation-data/cursor-adapter.ts +171 -0
  149. package/src/lib/conversation-data/index.ts +311 -0
  150. package/src/lib/conversation-data/kiro-adapter.ts +140 -0
  151. package/src/lib/conversation-data/message-selector.ts +37 -0
  152. package/src/lib/conversation-data/opencode-adapter.ts +180 -0
  153. package/src/lib/conversation-data/path-match.ts +79 -0
  154. package/src/lib/conversation-data/qoder-adapter.ts +230 -0
  155. package/src/lib/conversation-data/types.ts +116 -0
  156. package/src/lib/cursor-db.ts +67 -21
  157. package/src/lib/cursor-exporter-types.ts +0 -19
  158. package/src/lib/kiro-db.ts +949 -0
  159. package/src/lib/kiro-exporter-types.ts +100 -0
  160. package/src/lib/kiro-transcript-phase.ts +41 -0
  161. package/src/lib/kiro-transcript.ts +115 -0
  162. package/src/lib/opencode-db.ts +610 -0
  163. package/src/lib/opencode-exporter-types.ts +129 -0
  164. package/src/lib/opencode-think-tags.ts +126 -0
  165. package/src/lib/opencode-transcript-phase.ts +50 -0
  166. package/src/lib/opencode-transcript.ts +194 -0
  167. package/src/lib/qoder-acp-client.ts +268 -0
  168. package/src/lib/qoder-db.ts +1601 -0
  169. package/src/lib/qoder-exporter-types.ts +114 -0
  170. package/src/lib/qoder-transcript-phase.ts +41 -0
  171. package/src/lib/qoder-transcript.ts +112 -0
  172. package/src/lib/shared.ts +25 -0
  173. package/src/lib/ui-export-archive.ts +61 -0
  174. package/apps/ui/dist/client/assets/_threadId-CAIeH5mq.js +0 -1
  175. package/apps/ui/dist/client/assets/analytics-DK2jdvmI.js +0 -1
  176. package/apps/ui/dist/client/assets/antigravity-conversations._conversationId-DmD0sN8X.js +0 -7
  177. package/apps/ui/dist/client/assets/antigravity-conversations._conversationId-KAcXtNxI.js +0 -1
  178. package/apps/ui/dist/client/assets/antigravity-keychain-panel-BRHVjFAM.js +0 -1
  179. package/apps/ui/dist/client/assets/antigravity._workspaceKey-ByitGWki.js +0 -1
  180. package/apps/ui/dist/client/assets/antigravity._workspaceKey-CGV7amas.js +0 -1
  181. package/apps/ui/dist/client/assets/antigravity.index-DEEkjlZa.js +0 -1
  182. package/apps/ui/dist/client/assets/antigravity.index-DgW25FEV.js +0 -1
  183. package/apps/ui/dist/client/assets/badge-DfWvPfKF.js +0 -1
  184. package/apps/ui/dist/client/assets/checkbox-CdHitXWQ.js +0 -1
  185. package/apps/ui/dist/client/assets/createServerFn-CgRRVpBH.js +0 -3
  186. package/apps/ui/dist/client/assets/cursor-threads._composerId-CmBFclK8.js +0 -1
  187. package/apps/ui/dist/client/assets/cursor-threads._composerId-Ti2gTm63.js +0 -1
  188. package/apps/ui/dist/client/assets/cursor._workspaceKey-CaAZjGmm.js +0 -1
  189. package/apps/ui/dist/client/assets/cursor._workspaceKey-DzD_c6j9.js +0 -1
  190. package/apps/ui/dist/client/assets/cursor.index-CrnMwDCi.js +0 -1
  191. package/apps/ui/dist/client/assets/cursor.index-PkCFVcl4.js +0 -2
  192. package/apps/ui/dist/client/assets/data-table-Br78_dk3.js +0 -4
  193. package/apps/ui/dist/client/assets/delete-confirm-dialog-BHRmyLHr.js +0 -11
  194. package/apps/ui/dist/client/assets/dist-B9pyYCVU.js +0 -1
  195. package/apps/ui/dist/client/assets/dist-BhZOxAPP.js +0 -1
  196. package/apps/ui/dist/client/assets/dist-DvMS2965.js +0 -1
  197. package/apps/ui/dist/client/assets/download-Bf0QJKD3.js +0 -1
  198. package/apps/ui/dist/client/assets/dropdown-menu-Dy5cLzTy.js +0 -1
  199. package/apps/ui/dist/client/assets/es2015-BkCWttyM.js +0 -41
  200. package/apps/ui/dist/client/assets/export-dialog-C86SYHJn.js +0 -1
  201. package/apps/ui/dist/client/assets/formatters-BM9kB7ed.js +0 -1
  202. package/apps/ui/dist/client/assets/index-CPvAP-jk.js +0 -149
  203. package/apps/ui/dist/client/assets/jsx-runtime-DGeXAQPT.js +0 -1
  204. package/apps/ui/dist/client/assets/metric-card-Dplm0ZiM.js +0 -1
  205. package/apps/ui/dist/client/assets/page-header-Cwa3p6Tl.js +0 -1
  206. package/apps/ui/dist/client/assets/projects._project-Ckf6muWZ.js +0 -1
  207. package/apps/ui/dist/client/assets/projects._project-DSDwH4NF.js +0 -1
  208. package/apps/ui/dist/client/assets/projects.index-DEfhWqa8.js +0 -1
  209. package/apps/ui/dist/client/assets/projects.index-V5ibNZII.js +0 -3
  210. package/apps/ui/dist/client/assets/react-dom-DL96Jor4.js +0 -1
  211. package/apps/ui/dist/client/assets/refresh-ccw-BgKjOiA6.js +0 -1
  212. package/apps/ui/dist/client/assets/reload-error-panel-AHqu0akK.js +0 -1
  213. package/apps/ui/dist/client/assets/routes-Df2tgpyd.js +0 -1
  214. package/apps/ui/dist/client/assets/scroll-text-fM0sMOB3.js +0 -1
  215. package/apps/ui/dist/client/assets/select-Bf2GwfPR.js +0 -1
  216. package/apps/ui/dist/client/assets/settings-5VQIzME0.js +0 -1
  217. package/apps/ui/dist/client/assets/sqlite-error-B6uZjUe8.js +0 -1
  218. package/apps/ui/dist/client/assets/styles-BhRkXgwB.css +0 -1
  219. package/apps/ui/dist/client/assets/tabs-OO4VU5KR.js +0 -7
  220. package/apps/ui/dist/client/assets/text-filter-DVAZySUS.js +0 -2
  221. package/apps/ui/dist/client/assets/threads._threadId-BB9tTsV4.js +0 -1
  222. package/apps/ui/dist/client/assets/threads._threadId-BgDhFj2I.js +0 -1
  223. package/apps/ui/dist/client/assets/useMutation-CC_B7uy5.js +0 -1
  224. package/apps/ui/dist/client/assets/useQuery-C5By6WKU.js +0 -1
  225. package/apps/ui/dist/server/assets/_tanstack-start-manifest_v-CRW2kqj0.js +0 -232
  226. package/apps/ui/dist/server/assets/_threadId-B6SrBR9E.js +0 -6
  227. package/apps/ui/dist/server/assets/analytics-CYP_LT5Y.js +0 -16
  228. package/apps/ui/dist/server/assets/analytics-CtpOMVMO.js +0 -146
  229. package/apps/ui/dist/server/assets/antigravity-conversation-state-HgzS302O.js +0 -16
  230. package/apps/ui/dist/server/assets/antigravity-conversations._conversationId-BtexWY-K.js +0 -613
  231. package/apps/ui/dist/server/assets/antigravity-conversations._conversationId-D426O-64.js +0 -11
  232. package/apps/ui/dist/server/assets/antigravity-conversations._conversationId-zMrR6v6R.js +0 -20
  233. package/apps/ui/dist/server/assets/antigravity-db-Bh8_U9uw.js +0 -580
  234. package/apps/ui/dist/server/assets/antigravity-keychain-DOiuHDwK.js +0 -126
  235. package/apps/ui/dist/server/assets/antigravity-keychain-panel-CC7FLmAK.js +0 -55
  236. package/apps/ui/dist/server/assets/antigravity-queries-CGrJO9Vr.js +0 -37
  237. package/apps/ui/dist/server/assets/antigravity-server-CHRjVFqN.js +0 -114
  238. package/apps/ui/dist/server/assets/antigravity._workspaceKey-3m_MzNFA.js +0 -11
  239. package/apps/ui/dist/server/assets/antigravity._workspaceKey-B0QeYUOh.js +0 -28
  240. package/apps/ui/dist/server/assets/antigravity._workspaceKey-C3kP-qyN.js +0 -210
  241. package/apps/ui/dist/server/assets/antigravity.index-CPCYkqCi.js +0 -104
  242. package/apps/ui/dist/server/assets/antigravity.index-DudTB3Tq.js +0 -11
  243. package/apps/ui/dist/server/assets/badge-EvdhKK_Z.js +0 -26
  244. package/apps/ui/dist/server/assets/button-CmTDnzOn.js +0 -46
  245. package/apps/ui/dist/server/assets/checkbox-C0hovF41.js +0 -19
  246. package/apps/ui/dist/server/assets/codex-queries-CtgeZ7VL.js +0 -99
  247. package/apps/ui/dist/server/assets/codex-server-CNXSJuc2.js +0 -2004
  248. package/apps/ui/dist/server/assets/concurrency-VXtYvlGh.js +0 -18
  249. package/apps/ui/dist/server/assets/createServerRpc-CF_DEwnm.js +0 -12
  250. package/apps/ui/dist/server/assets/createSsrRpc-C754NPki.js +0 -16
  251. package/apps/ui/dist/server/assets/cursor-db-cYZEU3WQ.js +0 -830
  252. package/apps/ui/dist/server/assets/cursor-exporter-types-CI3goo-c.js +0 -34
  253. package/apps/ui/dist/server/assets/cursor-queries-NCIM0Nat.js +0 -67
  254. package/apps/ui/dist/server/assets/cursor-recovery-nq-kR62j.js +0 -361
  255. package/apps/ui/dist/server/assets/cursor-server-C3q7hrp-.js +0 -213
  256. package/apps/ui/dist/server/assets/cursor-threads._composerId-BB0Y_Mao.js +0 -11
  257. package/apps/ui/dist/server/assets/cursor-threads._composerId-BPJFWfJj.js +0 -18
  258. package/apps/ui/dist/server/assets/cursor-threads._composerId-BkMMTQ3v.js +0 -582
  259. package/apps/ui/dist/server/assets/cursor-transcript-2iL3KFSK.js +0 -125
  260. package/apps/ui/dist/server/assets/cursor._workspaceKey-C5PdTaKB.js +0 -28
  261. package/apps/ui/dist/server/assets/cursor._workspaceKey-Ckj7apKI.js +0 -401
  262. package/apps/ui/dist/server/assets/cursor._workspaceKey-nmg3YIOQ.js +0 -11
  263. package/apps/ui/dist/server/assets/cursor.index-CcsX7DG0.js +0 -11
  264. package/apps/ui/dist/server/assets/cursor.index-DkWT-mxw.js +0 -189
  265. package/apps/ui/dist/server/assets/data-table-Cdct823O.js +0 -189
  266. package/apps/ui/dist/server/assets/delete-confirm-dialog-BcBNCxWB.js +0 -144
  267. package/apps/ui/dist/server/assets/download-DMmiy1xf.js +0 -92
  268. package/apps/ui/dist/server/assets/dropdown-menu-Dy_9t6TN.js +0 -36
  269. package/apps/ui/dist/server/assets/empty-plugin-adapters-B3lHh1La.js +0 -5
  270. package/apps/ui/dist/server/assets/export-dialog-BItjWgkZ.js +0 -240
  271. package/apps/ui/dist/server/assets/formatters-FJaGZgJk.js +0 -91
  272. package/apps/ui/dist/server/assets/loading-panel-BGFnWseS.js +0 -27
  273. package/apps/ui/dist/server/assets/metric-card-ByEeLu0r.js +0 -23
  274. package/apps/ui/dist/server/assets/model-label-B1NWGc65.js +0 -13
  275. package/apps/ui/dist/server/assets/page-header-VNSaM3xd.js +0 -29
  276. package/apps/ui/dist/server/assets/path-transforms-DL2IwtYd.js +0 -31
  277. package/apps/ui/dist/server/assets/projects._project-Bpbc3C-L.js +0 -20
  278. package/apps/ui/dist/server/assets/projects._project-Bshqk7JA.js +0 -12
  279. package/apps/ui/dist/server/assets/projects._project-CvZho6EQ.js +0 -395
  280. package/apps/ui/dist/server/assets/projects.index-BLXOx5eL.js +0 -12
  281. package/apps/ui/dist/server/assets/projects.index-BkLiF2FF.js +0 -182
  282. package/apps/ui/dist/server/assets/projects.index-DesYXwfi.js +0 -14
  283. package/apps/ui/dist/server/assets/reload-error-panel-BJMxY3U1.js +0 -25
  284. package/apps/ui/dist/server/assets/route-search-ts4W9MJ9.js +0 -38
  285. package/apps/ui/dist/server/assets/router-6m-ihwqA.js +0 -410
  286. package/apps/ui/dist/server/assets/routes-Bsact1uB.js +0 -184
  287. package/apps/ui/dist/server/assets/routes-BzkJgq4W.js +0 -34
  288. package/apps/ui/dist/server/assets/select-GW76p-ld.js +0 -76
  289. package/apps/ui/dist/server/assets/settings-OayxIYQQ.js +0 -100
  290. package/apps/ui/dist/server/assets/settings-store-DpEJEQ7M.js +0 -52
  291. package/apps/ui/dist/server/assets/shared-CPRNYIql.js +0 -134
  292. package/apps/ui/dist/server/assets/sqlite-error-LZDrnxdd.js +0 -13
  293. package/apps/ui/dist/server/assets/start-CI_0bSiY.js +0 -4
  294. package/apps/ui/dist/server/assets/tabs-CGA13IZM.js +0 -502
  295. package/apps/ui/dist/server/assets/text-filter-CGKxMCKt.js +0 -36
  296. package/apps/ui/dist/server/assets/threads._threadId-BSSK4nkI.js +0 -26
  297. package/apps/ui/dist/server/assets/threads._threadId-Bs0yuqO9.js +0 -18
  298. package/apps/ui/dist/server/assets/threads._threadId-D2GYkVn6.js +0 -639
  299. package/apps/ui/dist/server/assets/ui-export-files-BHLX9bhN.js +0 -83
  300. package/apps/ui/dist/server/assets/utils-C_uf36nf.js +0 -8
  301. package/apps/ui/dist/server/server.js +0 -5847
  302. package/bin/codex-chats-claude.js +0 -5
  303. package/bin/codex-chats.js +0 -5
  304. package/bin/spiracha.js +0 -5
  305. package/src/export-chats.ts +0 -120
  306. package/src/export-claude.ts +0 -36
  307. package/src/export-cursor.ts +0 -244
  308. package/src/lib/claude-exporter.ts +0 -864
  309. package/src/lib/codex-exporter-cli.ts +0 -277
  310. package/src/lib/codex-exporter-db.ts +0 -319
  311. package/src/lib/codex-exporter.ts +0 -115
  312. package/src/lib/cursor-exporter.ts +0 -266
  313. package/src/lib/interactive-cli.ts +0 -433
  314. package/src/lib/native-open.ts +0 -54
  315. package/src/mcp-server.ts +0 -137
  316. package/src/spiracha.ts +0 -116
  317. package/src/ui-cli.ts +0 -310
  318. /package/apps/ui/{dist/client → public}/manifest.json +0 -0
  319. /package/apps/ui/{dist/client → public}/robots.txt +0 -0
@@ -0,0 +1,435 @@
1
+ import type { ThreadEvent, ThreadTranscriptStats } from '@spiracha/lib/codex-browser-types';
2
+ import { useMutation, useQueryClient, useSuspenseQuery } from '@tanstack/react-query';
3
+ import { createFileRoute, Link, useNavigate } from '@tanstack/react-router';
4
+ import { Download, Trash2 } from 'lucide-react';
5
+ import { useMemo, useState } from 'react';
6
+ import { Breadcrumbs } from '#/components/breadcrumbs';
7
+ import { DeleteConfirmDialog } from '#/components/delete-confirm-dialog';
8
+ import { ExportDialog } from '#/components/export-dialog';
9
+ import { JsonPanel } from '#/components/json-panel';
10
+ import { LoadingPanel } from '#/components/loading-panel';
11
+ import { MetadataSection } from '#/components/metadata-section';
12
+ import { MetricCard } from '#/components/metric-card';
13
+ import { PageHeader } from '#/components/page-header';
14
+ import { ReloadErrorPanel } from '#/components/reload-error-panel';
15
+ import { TranscriptView } from '#/components/transcript-view';
16
+ import { Button } from '#/components/ui/button';
17
+ import { Checkbox } from '#/components/ui/checkbox';
18
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from '#/components/ui/tabs';
19
+ import { cursorThreadDetailQueryOptions } from '#/lib/cursor-queries';
20
+ import { deleteCursorThreadsFn, exportCursorThreadFn, type getCursorThreadDetailFn } from '#/lib/cursor-server';
21
+ import { cursorTranscriptToThreadEvents, getCursorThreadTranscriptStats } from '#/lib/cursor-transcript-events';
22
+ import { downloadTextFile, downloadUrlFile } from '#/lib/download';
23
+ import { formatBytes, formatDateTime, formatList, formatNumber } from '#/lib/formatters';
24
+
25
+ type CursorThreadDetail = Awaited<ReturnType<typeof getCursorThreadDetailFn>>;
26
+
27
+ type ExportDialogOptions = {
28
+ includeCommentary: boolean;
29
+ includeMetadata: boolean;
30
+ includeTools: boolean;
31
+ outputFormat: 'md' | 'txt';
32
+ zipArchive: boolean;
33
+ };
34
+
35
+ type TranscriptControlsProps = {
36
+ rawJsonDisabled?: boolean;
37
+ showCommentary: boolean;
38
+ showExtraEvents: boolean;
39
+ showRawJson: boolean;
40
+ showToolCalls: boolean;
41
+ showUserMessages: boolean;
42
+ onShowCommentaryChange: (checked: boolean) => void;
43
+ onShowExtraEventsChange: (checked: boolean) => void;
44
+ onShowRawJsonChange: (checked: boolean) => void;
45
+ onShowToolCallsChange: (checked: boolean) => void;
46
+ onShowUserMessagesChange: (checked: boolean) => void;
47
+ };
48
+
49
+ const buildCursorThreadMetadata = (detail: CursorThreadDetail) => {
50
+ return [
51
+ { label: 'Composer ID', value: <span data-mono="true">{detail.thread.composerId}</span> },
52
+ {
53
+ label: 'Workspace',
54
+ value: (
55
+ <Link
56
+ className="text-[var(--accent)]"
57
+ params={{ workspaceKey: detail.thread.workspaceKey }}
58
+ to="/cursor/$workspaceKey"
59
+ >
60
+ {detail.thread.workspaceLabel}
61
+ </Link>
62
+ ),
63
+ },
64
+ { label: 'Workspace key', value: <span data-mono="true">{detail.thread.workspaceKey}</span> },
65
+ { label: 'Mode', value: detail.thread.mode ?? 'unknown' },
66
+ {
67
+ label: 'Created',
68
+ value: <span suppressHydrationWarning>{formatDateTime(detail.thread.createdAtMs)}</span>,
69
+ },
70
+ {
71
+ label: 'Updated',
72
+ value: <span suppressHydrationWarning>{formatDateTime(detail.thread.lastUpdatedAtMs)}</span>,
73
+ },
74
+ {
75
+ label: 'Transcript dirs',
76
+ value:
77
+ detail.thread.transcriptDirs.length > 0 ? (
78
+ <div className="space-y-1">
79
+ {detail.thread.transcriptDirs.map((directory) => (
80
+ <div data-mono="true" key={directory}>
81
+ {directory}
82
+ </div>
83
+ ))}
84
+ </div>
85
+ ) : (
86
+ 'n/a'
87
+ ),
88
+ },
89
+ ];
90
+ };
91
+
92
+ const buildCursorTranscriptStatsItems = (
93
+ detail: CursorThreadDetail,
94
+ events: ThreadEvent[],
95
+ stats: ThreadTranscriptStats,
96
+ ) => {
97
+ if (!detail.transcript) {
98
+ return [{ label: 'Transcript load', value: 'No renderable Cursor transcript content was found.' }];
99
+ }
100
+
101
+ return [
102
+ { label: 'Event kinds', value: formatList([...new Set(events.map((event) => event.kind))]) },
103
+ { label: 'Messages', value: formatNumber(stats.messageCount) },
104
+ { label: 'User messages', value: formatNumber(stats.userMessageCount) },
105
+ { label: 'Assistant messages', value: formatNumber(stats.assistantMessageCount) },
106
+ { label: 'Commentary updates', value: formatNumber(stats.commentaryCount) },
107
+ { label: 'Tool calls', value: formatNumber(stats.toolCallCount) },
108
+ { label: 'Tool outputs', value: formatNumber(stats.toolOutputCount) },
109
+ { label: 'Renderable bubbles', value: formatNumber(detail.transcript.renderableBubbleCount) },
110
+ { label: 'Omitted bubbles', value: formatNumber(detail.transcript.omittedBubbleCount) },
111
+ ];
112
+ };
113
+
114
+ const CursorTranscriptControls = ({
115
+ rawJsonDisabled = false,
116
+ showCommentary,
117
+ showExtraEvents,
118
+ showRawJson,
119
+ showToolCalls,
120
+ showUserMessages,
121
+ onShowCommentaryChange,
122
+ onShowExtraEventsChange,
123
+ onShowRawJsonChange,
124
+ onShowToolCallsChange,
125
+ onShowUserMessagesChange,
126
+ }: TranscriptControlsProps) => {
127
+ return (
128
+ <div className="flex flex-wrap gap-4 rounded-xl border border-[var(--border)] bg-[var(--panel)] px-4 py-3 shadow-[var(--panel-shadow)]">
129
+ <div className="flex items-center gap-2 text-sm">
130
+ <Checkbox
131
+ checked={showToolCalls}
132
+ id="cursor-transcript-show-tool-calls"
133
+ onCheckedChange={(checked) => onShowToolCallsChange(checked === true)}
134
+ />
135
+ <label htmlFor="cursor-transcript-show-tool-calls">Show tool calls</label>
136
+ </div>
137
+ <div className="flex items-center gap-2 text-sm">
138
+ <Checkbox
139
+ checked={showCommentary}
140
+ id="cursor-transcript-show-commentary"
141
+ onCheckedChange={(checked) => onShowCommentaryChange(checked === true)}
142
+ />
143
+ <label htmlFor="cursor-transcript-show-commentary">Show commentary</label>
144
+ </div>
145
+ <div className="flex items-center gap-2 text-sm">
146
+ <Checkbox
147
+ checked={showExtraEvents}
148
+ id="cursor-transcript-show-extra-events"
149
+ onCheckedChange={(checked) => onShowExtraEventsChange(checked === true)}
150
+ />
151
+ <label htmlFor="cursor-transcript-show-extra-events">Show extra events</label>
152
+ </div>
153
+ <div className="flex items-center gap-2 text-sm">
154
+ <Checkbox
155
+ checked={showRawJson}
156
+ disabled={rawJsonDisabled}
157
+ id="cursor-transcript-show-raw-json"
158
+ onCheckedChange={(checked) => onShowRawJsonChange(checked === true)}
159
+ />
160
+ <label htmlFor="cursor-transcript-show-raw-json">Raw JSON</label>
161
+ </div>
162
+ <div className="flex items-center gap-2 text-sm">
163
+ <Checkbox
164
+ checked={showUserMessages}
165
+ id="cursor-transcript-show-user-messages"
166
+ onCheckedChange={(checked) => onShowUserMessagesChange(checked === true)}
167
+ />
168
+ <label htmlFor="cursor-transcript-show-user-messages">User</label>
169
+ </div>
170
+ </div>
171
+ );
172
+ };
173
+
174
+ const CursorThreadMetadataPanels = ({
175
+ detail,
176
+ events,
177
+ stats,
178
+ }: {
179
+ detail: CursorThreadDetail;
180
+ events: ThreadEvent[];
181
+ stats: ThreadTranscriptStats;
182
+ }) => {
183
+ return (
184
+ <div className="grid gap-4 xl:grid-cols-[1.1fr_0.9fr]">
185
+ <MetadataSection items={buildCursorThreadMetadata(detail)} title="Thread metadata" />
186
+ <MetadataSection items={buildCursorTranscriptStatsItems(detail, events, stats)} title="Transcript stats" />
187
+ </div>
188
+ );
189
+ };
190
+
191
+ const CursorThreadRawPanels = ({ detail, events }: { detail: CursorThreadDetail; events: ThreadEvent[] }) => {
192
+ if (!detail.transcript) {
193
+ return (
194
+ <div className="rounded-xl border border-[var(--border)] bg-[var(--panel)] px-5 py-4 text-sm">
195
+ No Cursor transcript payload was found for this thread.
196
+ </div>
197
+ );
198
+ }
199
+
200
+ return (
201
+ <div className="space-y-4">
202
+ <JsonPanel title="Thread summary" value={detail.thread} />
203
+ <JsonPanel title="Transcript head" value={detail.transcript.head} />
204
+ <JsonPanel title="Cursor bubbles" value={detail.transcript.bubbles} />
205
+ <JsonPanel title="Transcript events" value={events} />
206
+ </div>
207
+ );
208
+ };
209
+
210
+ const CursorThreadDetailErrorComponent = ({ error }: { error: Error }) => {
211
+ return <ReloadErrorPanel description={error.message} title="Failed to load Cursor thread" />;
212
+ };
213
+
214
+ const CursorThreadDetailPage = () => {
215
+ const navigate = useNavigate();
216
+ const queryClient = useQueryClient();
217
+ const detail = useSuspenseQuery(cursorThreadDetailQueryOptions(Route.useParams().composerId)).data;
218
+ const [pendingDelete, setPendingDelete] = useState(false);
219
+ const [pendingExport, setPendingExport] = useState(false);
220
+ const [showToolCalls, setShowToolCalls] = useState(false);
221
+ const [showCommentary, setShowCommentary] = useState(false);
222
+ const [showExtraEvents, setShowExtraEvents] = useState(false);
223
+ const [showRawJson, setShowRawJson] = useState(false);
224
+ const [showUserMessages, setShowUserMessages] = useState(true);
225
+ const transcriptEvents = useMemo(
226
+ () => (detail.transcript ? cursorTranscriptToThreadEvents(detail.transcript) : []),
227
+ [detail.transcript],
228
+ );
229
+ const transcriptStats = useMemo(() => getCursorThreadTranscriptStats(transcriptEvents), [transcriptEvents]);
230
+
231
+ const deleteThreadMutation = useMutation({
232
+ mutationFn: () => deleteCursorThreadsFn({ data: { composerIds: [detail.thread.composerId] } }),
233
+ onSuccess: async () => {
234
+ await navigate({
235
+ params: { workspaceKey: detail.thread.workspaceKey },
236
+ to: '/cursor/$workspaceKey',
237
+ });
238
+ await Promise.all([
239
+ queryClient.invalidateQueries({ queryKey: ['cursor-thread', detail.thread.composerId] }),
240
+ queryClient.invalidateQueries({ queryKey: ['cursor-threads', detail.thread.workspaceKey] }),
241
+ queryClient.invalidateQueries({ queryKey: ['cursor-workspaces'] }),
242
+ ]);
243
+ },
244
+ });
245
+
246
+ const exportThreadMutation = useMutation({
247
+ mutationFn: async (options: ExportDialogOptions) => {
248
+ const download = await exportCursorThreadFn({
249
+ data: {
250
+ ...options,
251
+ composerId: detail.thread.composerId,
252
+ },
253
+ });
254
+
255
+ if (download.mode === 'download') {
256
+ downloadTextFile(download.fileName, download.content, download.mimeType);
257
+ return;
258
+ }
259
+
260
+ await downloadUrlFile(download.fileName, download.downloadUrl);
261
+ },
262
+ onSuccess: () => {
263
+ setPendingExport(false);
264
+ },
265
+ });
266
+
267
+ return (
268
+ <div className="space-y-6">
269
+ <PageHeader
270
+ actions={
271
+ <div className="flex flex-wrap gap-2">
272
+ <Button
273
+ className="rounded-full"
274
+ type="button"
275
+ variant="outline"
276
+ onClick={() => setPendingExport(true)}
277
+ >
278
+ <Download className="mr-2 size-4" />
279
+ Export
280
+ </Button>
281
+ <Button
282
+ className="rounded-full border-[var(--destructive)]/20 text-[var(--destructive)]"
283
+ type="button"
284
+ variant="outline"
285
+ onClick={() => setPendingDelete(true)}
286
+ >
287
+ <Trash2 className="mr-2 size-4" />
288
+ Delete
289
+ </Button>
290
+ </div>
291
+ }
292
+ breadcrumb={
293
+ <Breadcrumbs
294
+ items={[
295
+ { label: 'Cursor', to: '/cursor' },
296
+ {
297
+ label: detail.thread.workspaceLabel,
298
+ params: { workspaceKey: detail.thread.workspaceKey },
299
+ to: '/cursor/$workspaceKey',
300
+ },
301
+ { label: detail.thread.name },
302
+ ]}
303
+ />
304
+ }
305
+ eyebrow="Cursor thread"
306
+ subtitle="Thread detail for the selected Cursor workspace conversation."
307
+ title={detail.thread.name}
308
+ />
309
+
310
+ <div className="grid gap-3 md:grid-cols-2 xl:grid-cols-4">
311
+ <MetricCard label="Messages" value={formatNumber(detail.thread.bubbleCount)} />
312
+ <MetricCard label="Size" value={formatBytes(detail.thread.bubbleBytes)} />
313
+ <MetricCard label="Mode" value={detail.thread.mode ?? 'unknown'} />
314
+ <MetricCard
315
+ helper={`${formatNumber(detail.transcript?.renderableBubbleCount ?? 0)} renderable`}
316
+ label="Omitted"
317
+ value={formatNumber(detail.transcript?.omittedBubbleCount ?? 0)}
318
+ />
319
+ </div>
320
+
321
+ <Tabs className="space-y-4" defaultValue="transcript">
322
+ <TabsList className="grid w-fit min-w-[24rem] grid-cols-3 rounded-full border border-[var(--border)] bg-[var(--panel)] p-1">
323
+ <TabsTrigger className="rounded-full px-5 text-sm" value="transcript">
324
+ Transcript
325
+ </TabsTrigger>
326
+ <TabsTrigger className="rounded-full px-5 text-sm" value="metadata">
327
+ Metadata
328
+ </TabsTrigger>
329
+ <TabsTrigger className="rounded-full px-5 text-sm" value="raw">
330
+ Raw
331
+ </TabsTrigger>
332
+ </TabsList>
333
+
334
+ <TabsContent className="space-y-3" value="transcript">
335
+ <CursorTranscriptControls
336
+ rawJsonDisabled={!detail.transcript}
337
+ showCommentary={showCommentary}
338
+ showExtraEvents={showExtraEvents}
339
+ showRawJson={showRawJson}
340
+ showToolCalls={showToolCalls}
341
+ showUserMessages={showUserMessages}
342
+ onShowCommentaryChange={setShowCommentary}
343
+ onShowExtraEventsChange={setShowExtraEvents}
344
+ onShowRawJsonChange={setShowRawJson}
345
+ onShowToolCallsChange={setShowToolCalls}
346
+ onShowUserMessagesChange={setShowUserMessages}
347
+ />
348
+ {detail.transcript && transcriptEvents.length > 0 ? (
349
+ <TranscriptView
350
+ assistantModel={null}
351
+ events={transcriptEvents}
352
+ projectPath={null}
353
+ showCommentary={showCommentary}
354
+ showExtraEvents={showExtraEvents}
355
+ showRawJson={showRawJson}
356
+ showToolCalls={showToolCalls}
357
+ showUserMessages={showUserMessages}
358
+ />
359
+ ) : (
360
+ <section className="rounded-[1.6rem] border border-[var(--border)] bg-[var(--panel)] p-5 shadow-[var(--panel-shadow)]">
361
+ <h3 className="font-semibold text-[var(--muted-foreground)] text-sm uppercase tracking-[0.18em]">
362
+ Transcript
363
+ </h3>
364
+ <p className="mt-4 text-[var(--muted-foreground)] text-sm">
365
+ No renderable Cursor transcript content was found for this thread.
366
+ </p>
367
+ </section>
368
+ )}
369
+ </TabsContent>
370
+
371
+ <TabsContent value="metadata">
372
+ <CursorThreadMetadataPanels detail={detail} events={transcriptEvents} stats={transcriptStats} />
373
+ </TabsContent>
374
+
375
+ <TabsContent value="raw">
376
+ <CursorThreadRawPanels detail={detail} events={transcriptEvents} />
377
+ </TabsContent>
378
+ </Tabs>
379
+
380
+ <DeleteConfirmDialog
381
+ confirmLabel={deleteThreadMutation.isPending ? 'Deleting...' : 'Delete thread'}
382
+ description={`Permanently delete "${detail.thread.name}" from Cursor's database and remove any on-disk transcript directories. Quit Cursor first. This cannot be undone.`}
383
+ errorMessage={
384
+ deleteThreadMutation.isError
385
+ ? deleteThreadMutation.error instanceof Error
386
+ ? deleteThreadMutation.error.message
387
+ : 'Delete failed'
388
+ : null
389
+ }
390
+ open={pendingDelete}
391
+ title="Delete Cursor thread?"
392
+ onConfirm={() => deleteThreadMutation.mutate()}
393
+ onOpenChange={(nextOpen) => {
394
+ setPendingDelete(nextOpen);
395
+ if (!nextOpen) {
396
+ deleteThreadMutation.reset();
397
+ }
398
+ }}
399
+ />
400
+
401
+ <ExportDialog
402
+ errorMessage={
403
+ exportThreadMutation.isError
404
+ ? exportThreadMutation.error instanceof Error
405
+ ? exportThreadMutation.error.message
406
+ : 'Export failed'
407
+ : null
408
+ }
409
+ open={pendingExport}
410
+ pending={exportThreadMutation.isPending}
411
+ title={`Export ${detail.thread.name}`}
412
+ onExport={(options) => exportThreadMutation.mutate(options)}
413
+ onOpenChange={(nextOpen) => {
414
+ setPendingExport(nextOpen);
415
+ if (!nextOpen) {
416
+ exportThreadMutation.reset();
417
+ }
418
+ }}
419
+ />
420
+ </div>
421
+ );
422
+ };
423
+
424
+ export const Route = createFileRoute('/cursor-threads/$composerId')({
425
+ component: CursorThreadDetailPage,
426
+ errorComponent: CursorThreadDetailErrorComponent,
427
+ loader: ({ context, params }) =>
428
+ context.queryClient.ensureQueryData(cursorThreadDetailQueryOptions(params.composerId)),
429
+ pendingComponent: () => (
430
+ <LoadingPanel
431
+ description="Loading the Cursor transcript, thread metadata, and workspace context."
432
+ title="Loading thread"
433
+ />
434
+ ),
435
+ });