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
@@ -0,0 +1,438 @@
1
+ import { useMutation, useSuspenseQuery } from '@tanstack/react-query';
2
+ import { createFileRoute, Link } from '@tanstack/react-router';
3
+ import { Download, ScrollText } from 'lucide-react';
4
+ import { useMemo, useState } from 'react';
5
+ import { AntigravityKeychainPanel } from '#/components/antigravity-keychain-panel';
6
+ import { Breadcrumbs } from '#/components/breadcrumbs';
7
+ import { JsonPanel } from '#/components/json-panel';
8
+ import { LoadingPanel } from '#/components/loading-panel';
9
+ import { MetadataSection } from '#/components/metadata-section';
10
+ import { MetricCard } from '#/components/metric-card';
11
+ import { PageHeader } from '#/components/page-header';
12
+ import { ReloadErrorPanel } from '#/components/reload-error-panel';
13
+ import { TextDocumentPanel } from '#/components/text-document-panel';
14
+ import { TranscriptView } from '#/components/transcript-view';
15
+ import { Button } from '#/components/ui/button';
16
+ import { Checkbox } from '#/components/ui/checkbox';
17
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from '#/components/ui/tabs';
18
+ import { canExportAntigravityConversation } from '#/lib/antigravity-conversation-state';
19
+ import {
20
+ antigravityConversationDetailQueryOptions,
21
+ antigravityDecryptionQueryOptions,
22
+ } from '#/lib/antigravity-queries';
23
+ import {
24
+ exportAntigravityArtifactsFn,
25
+ exportAntigravityConversationFn,
26
+ type getAntigravityConversationDetailFn,
27
+ } from '#/lib/antigravity-server';
28
+ import {
29
+ antigravityMarkdownToThreadEvents,
30
+ getAntigravityThreadTranscriptStats,
31
+ } from '#/lib/antigravity-transcript-events';
32
+ import { downloadTextFile } from '#/lib/download';
33
+ import { formatBytes, formatDateTime, formatNumber } from '#/lib/formatters';
34
+
35
+ type AntigravityConversationDetail = Awaited<ReturnType<typeof getAntigravityConversationDetailFn>>;
36
+
37
+ type TranscriptControlsProps = {
38
+ rawJsonDisabled?: boolean;
39
+ showCommentary: boolean;
40
+ showExtraEvents: boolean;
41
+ showRawJson: boolean;
42
+ showToolCalls: boolean;
43
+ showUserMessages: boolean;
44
+ onShowCommentaryChange: (checked: boolean) => void;
45
+ onShowExtraEventsChange: (checked: boolean) => void;
46
+ onShowRawJsonChange: (checked: boolean) => void;
47
+ onShowToolCallsChange: (checked: boolean) => void;
48
+ onShowUserMessagesChange: (checked: boolean) => void;
49
+ };
50
+
51
+ const buildConversationMetadata = (detail: AntigravityConversationDetail) => {
52
+ return [
53
+ { label: 'Conversation ID', value: <span data-mono="true">{detail.conversation.conversationId}</span> },
54
+ {
55
+ label: 'Workspace',
56
+ value: (
57
+ <Link
58
+ className="text-[var(--accent)]"
59
+ params={{ workspaceKey: detail.conversation.workspaceKey }}
60
+ to="/antigravity/$workspaceKey"
61
+ >
62
+ {detail.conversation.workspaceLabel}
63
+ </Link>
64
+ ),
65
+ },
66
+ {
67
+ label: 'Created',
68
+ value: <span suppressHydrationWarning>{formatDateTime(detail.conversation.createdAtMs)}</span>,
69
+ },
70
+ {
71
+ label: 'Updated',
72
+ value: <span suppressHydrationWarning>{formatDateTime(detail.conversation.lastUpdatedAtMs)}</span>,
73
+ },
74
+ { label: 'Transcript source', value: detail.conversation.transcriptSource ?? 'n/a' },
75
+ { label: 'Conversation path', value: detail.conversation.conversationPath ?? 'n/a' },
76
+ { label: 'Transcript path', value: detail.conversation.transcriptPath ?? 'n/a' },
77
+ { label: 'Summary path', value: detail.conversation.summaryPath ?? 'n/a' },
78
+ { label: 'Source root', value: detail.conversation.sourceRoot ?? 'n/a' },
79
+ ];
80
+ };
81
+
82
+ const buildTranscriptStatsItems = (
83
+ detail: AntigravityConversationDetail,
84
+ events: ReturnType<typeof antigravityMarkdownToThreadEvents>,
85
+ ) => {
86
+ if (detail.transcriptLocked) {
87
+ return [
88
+ { label: 'Transcript load', value: 'Transcript is locked until Antigravity Keychain access is enabled.' },
89
+ ];
90
+ }
91
+
92
+ if (!detail.conversationMarkdown) {
93
+ return [{ label: 'Transcript load', value: 'No renderable transcript content was found.' }];
94
+ }
95
+
96
+ const stats = getAntigravityThreadTranscriptStats(events);
97
+ return [
98
+ { label: 'Event kinds', value: [...new Set(events.map((event) => event.kind))].join(', ') || 'n/a' },
99
+ { label: 'Messages', value: formatNumber(stats.messageCount) },
100
+ { label: 'User messages', value: formatNumber(stats.userMessageCount) },
101
+ { label: 'Assistant messages', value: formatNumber(stats.assistantMessageCount) },
102
+ { label: 'Commentary updates', value: formatNumber(stats.commentaryCount) },
103
+ { label: 'Final answers', value: formatNumber(stats.finalAnswerCount) },
104
+ { label: 'Tool calls', value: formatNumber(stats.toolCallCount) },
105
+ { label: 'Tool outputs', value: formatNumber(stats.toolOutputCount) },
106
+ ];
107
+ };
108
+
109
+ export const Route = createFileRoute('/antigravity-conversations/$conversationId')({
110
+ component: AntigravityConversationDetailPage,
111
+ errorComponent: AntigravityConversationDetailErrorComponent,
112
+ loader: async ({ context, params }) => {
113
+ await Promise.all([
114
+ context.queryClient.ensureQueryData(antigravityDecryptionQueryOptions()),
115
+ context.queryClient.ensureQueryData(antigravityConversationDetailQueryOptions(params.conversationId)),
116
+ ]);
117
+ },
118
+ pendingComponent: () => (
119
+ <LoadingPanel
120
+ description="Loading the Antigravity conversation transcript, artifact data, and workspace context."
121
+ title="Loading conversation"
122
+ />
123
+ ),
124
+ });
125
+
126
+ function AntigravityConversationDetailErrorComponent({ error }: { error: Error }) {
127
+ return <ReloadErrorPanel description={error.message} title="Failed to load Antigravity conversation" />;
128
+ }
129
+
130
+ function AntigravityConversationHeaderActions({
131
+ canExportArtifacts,
132
+ canExportConversation,
133
+ exportArtifactsPending,
134
+ exportConversationPending,
135
+ showConversationExport,
136
+ onExportArtifacts,
137
+ onExportConversation,
138
+ }: {
139
+ canExportArtifacts: boolean;
140
+ canExportConversation: boolean;
141
+ exportArtifactsPending: boolean;
142
+ exportConversationPending: boolean;
143
+ showConversationExport: boolean;
144
+ onExportArtifacts: () => void;
145
+ onExportConversation: () => void;
146
+ }) {
147
+ return (
148
+ <div className="flex flex-wrap gap-2">
149
+ {showConversationExport ? (
150
+ <Button
151
+ className="rounded-full"
152
+ disabled={!canExportConversation || exportConversationPending}
153
+ type="button"
154
+ variant="outline"
155
+ onClick={onExportConversation}
156
+ >
157
+ <Download className="mr-2 size-4" />
158
+ Export conversation
159
+ </Button>
160
+ ) : null}
161
+ {canExportArtifacts ? (
162
+ <Button
163
+ className="rounded-full"
164
+ disabled={exportArtifactsPending}
165
+ type="button"
166
+ variant="outline"
167
+ onClick={onExportArtifacts}
168
+ >
169
+ <ScrollText className="mr-2 size-4" />
170
+ Export artifacts
171
+ </Button>
172
+ ) : null}
173
+ </div>
174
+ );
175
+ }
176
+
177
+ const AntigravityTranscriptControls = ({
178
+ rawJsonDisabled = false,
179
+ showCommentary,
180
+ showExtraEvents,
181
+ showRawJson,
182
+ showToolCalls,
183
+ showUserMessages,
184
+ onShowCommentaryChange,
185
+ onShowExtraEventsChange,
186
+ onShowRawJsonChange,
187
+ onShowToolCallsChange,
188
+ onShowUserMessagesChange,
189
+ }: TranscriptControlsProps) => {
190
+ return (
191
+ <div className="flex flex-wrap gap-4 rounded-xl border border-[var(--border)] bg-[var(--panel)] px-4 py-3 shadow-[var(--panel-shadow)]">
192
+ <div className="flex items-center gap-2 text-sm">
193
+ <Checkbox
194
+ checked={showToolCalls}
195
+ id="antigravity-transcript-show-tool-calls"
196
+ onCheckedChange={(checked) => onShowToolCallsChange(checked === true)}
197
+ />
198
+ <label htmlFor="antigravity-transcript-show-tool-calls">Show tool calls</label>
199
+ </div>
200
+ <div className="flex items-center gap-2 text-sm">
201
+ <Checkbox
202
+ checked={showCommentary}
203
+ id="antigravity-transcript-show-commentary"
204
+ onCheckedChange={(checked) => onShowCommentaryChange(checked === true)}
205
+ />
206
+ <label htmlFor="antigravity-transcript-show-commentary">Show commentary</label>
207
+ </div>
208
+ <div className="flex items-center gap-2 text-sm">
209
+ <Checkbox
210
+ checked={showExtraEvents}
211
+ id="antigravity-transcript-show-extra-events"
212
+ onCheckedChange={(checked) => onShowExtraEventsChange(checked === true)}
213
+ />
214
+ <label htmlFor="antigravity-transcript-show-extra-events">Show extra events</label>
215
+ </div>
216
+ <div className="flex items-center gap-2 text-sm">
217
+ <Checkbox
218
+ checked={showRawJson}
219
+ disabled={rawJsonDisabled}
220
+ id="antigravity-transcript-show-raw-json"
221
+ onCheckedChange={(checked) => onShowRawJsonChange(checked === true)}
222
+ />
223
+ <label htmlFor="antigravity-transcript-show-raw-json">Raw JSON</label>
224
+ </div>
225
+ <div className="flex items-center gap-2 text-sm">
226
+ <Checkbox
227
+ checked={showUserMessages}
228
+ id="antigravity-transcript-show-user-messages"
229
+ onCheckedChange={(checked) => onShowUserMessagesChange(checked === true)}
230
+ />
231
+ <label htmlFor="antigravity-transcript-show-user-messages">User</label>
232
+ </div>
233
+ </div>
234
+ );
235
+ };
236
+
237
+ function EmptyAntigravityTranscript({ detail }: { detail: AntigravityConversationDetail }) {
238
+ return (
239
+ <section className="rounded-[1.6rem] border border-[var(--border)] bg-[var(--panel)] p-5 shadow-[var(--panel-shadow)]">
240
+ <h3 className="font-semibold text-[var(--muted-foreground)] text-sm uppercase tracking-[0.18em]">
241
+ Transcript
242
+ </h3>
243
+ <p className="mt-4 text-[var(--muted-foreground)] text-sm">
244
+ {detail.transcriptLocked
245
+ ? 'Unlock Antigravity transcript export to inspect the rendered conversation content here.'
246
+ : detail.artifactsMarkdown
247
+ ? 'No transcript preview is available for this conversation. Generated artifacts are available in the Raw tab.'
248
+ : 'No transcript preview is available for this conversation.'}
249
+ </p>
250
+ </section>
251
+ );
252
+ }
253
+
254
+ function AntigravityRawPanels({
255
+ detail,
256
+ events,
257
+ }: {
258
+ detail: AntigravityConversationDetail;
259
+ events: ReturnType<typeof antigravityMarkdownToThreadEvents>;
260
+ }) {
261
+ return (
262
+ <div className="space-y-4">
263
+ <JsonPanel title="Conversation summary" value={detail.conversation} />
264
+ <JsonPanel title="Transcript events" value={events} />
265
+ {detail.conversationMarkdown ? (
266
+ <TextDocumentPanel
267
+ content={detail.conversationMarkdown}
268
+ description="Rendered transcript Markdown used for export."
269
+ title="Transcript Markdown"
270
+ />
271
+ ) : null}
272
+ {detail.artifactsMarkdown ? (
273
+ <TextDocumentPanel
274
+ content={detail.artifactsMarkdown}
275
+ description="Generated artifacts."
276
+ title="Artifacts"
277
+ />
278
+ ) : null}
279
+ </div>
280
+ );
281
+ }
282
+
283
+ function AntigravityConversationDetailPage() {
284
+ const decryptionState = useSuspenseQuery(antigravityDecryptionQueryOptions()).data;
285
+ const detail = useSuspenseQuery(antigravityConversationDetailQueryOptions(Route.useParams().conversationId)).data;
286
+ const [showToolCalls, setShowToolCalls] = useState(false);
287
+ const [showCommentary, setShowCommentary] = useState(false);
288
+ const [showExtraEvents, setShowExtraEvents] = useState(false);
289
+ const [showRawJson, setShowRawJson] = useState(false);
290
+ const [showUserMessages, setShowUserMessages] = useState(true);
291
+ const transcriptEvents = useMemo(
292
+ () => antigravityMarkdownToThreadEvents(detail.conversationMarkdown),
293
+ [detail.conversationMarkdown],
294
+ );
295
+ const canExportConversation = canExportAntigravityConversation(
296
+ detail.conversation,
297
+ Boolean(decryptionState?.isUnlocked),
298
+ );
299
+ const canExportArtifacts = detail.artifactsMarkdown !== null;
300
+ const showConversationExport = canExportConversation || detail.transcriptLocked;
301
+
302
+ const exportConversationMutation = useMutation({
303
+ mutationFn: () =>
304
+ exportAntigravityConversationFn({ data: { conversationId: detail.conversation.conversationId } }),
305
+ onSuccess: (result) => {
306
+ downloadTextFile(result.filename, result.content, 'text/markdown; charset=utf-8');
307
+ },
308
+ });
309
+
310
+ const exportArtifactsMutation = useMutation({
311
+ mutationFn: () =>
312
+ exportAntigravityArtifactsFn({ data: { conversationId: detail.conversation.conversationId } }),
313
+ onSuccess: (result) => {
314
+ downloadTextFile(result.filename, result.content, 'text/markdown; charset=utf-8');
315
+ },
316
+ });
317
+
318
+ return (
319
+ <div className="space-y-6">
320
+ <PageHeader
321
+ actions={
322
+ <AntigravityConversationHeaderActions
323
+ canExportArtifacts={canExportArtifacts}
324
+ canExportConversation={canExportConversation}
325
+ exportArtifactsPending={exportArtifactsMutation.isPending}
326
+ exportConversationPending={exportConversationMutation.isPending}
327
+ showConversationExport={showConversationExport}
328
+ onExportArtifacts={() => exportArtifactsMutation.mutate()}
329
+ onExportConversation={() => exportConversationMutation.mutate()}
330
+ />
331
+ }
332
+ breadcrumb={
333
+ <Breadcrumbs
334
+ items={[
335
+ { label: 'Antigravity', to: '/antigravity' },
336
+ {
337
+ label: detail.conversation.workspaceLabel,
338
+ params: { workspaceKey: detail.conversation.workspaceKey },
339
+ to: '/antigravity/$workspaceKey',
340
+ },
341
+ { label: detail.conversation.title },
342
+ ]}
343
+ />
344
+ }
345
+ eyebrow="Antigravity conversation"
346
+ subtitle="Conversation detail for the selected Antigravity workspace session."
347
+ title={detail.conversation.title}
348
+ />
349
+
350
+ <AntigravityKeychainPanel />
351
+
352
+ <div className="grid gap-3 md:grid-cols-2 xl:grid-cols-4">
353
+ <MetricCard label="Transcript entries" value={formatNumber(detail.conversation.transcriptEntryCount)} />
354
+ <MetricCard label="Artifacts" value={formatNumber(detail.conversation.artifactCount)} />
355
+ <MetricCard label="Size" value={formatBytes(detail.conversation.conversationBytes)} />
356
+ <MetricCard
357
+ helper={detail.conversation.transcriptSource ?? 'summary'}
358
+ label="Indexed items"
359
+ value={formatNumber(detail.conversation.indexedItemCount ?? 0)}
360
+ />
361
+ </div>
362
+
363
+ <Tabs className="space-y-4" defaultValue="transcript">
364
+ <TabsList className="grid w-fit min-w-[24rem] grid-cols-3 rounded-full border border-[var(--border)] bg-[var(--panel)] p-1">
365
+ <TabsTrigger className="rounded-full px-5 text-sm" value="transcript">
366
+ Transcript
367
+ </TabsTrigger>
368
+ <TabsTrigger className="rounded-full px-5 text-sm" value="metadata">
369
+ Metadata
370
+ </TabsTrigger>
371
+ <TabsTrigger className="rounded-full px-5 text-sm" value="raw">
372
+ Raw
373
+ </TabsTrigger>
374
+ </TabsList>
375
+
376
+ <TabsContent className="space-y-3" value="transcript">
377
+ <AntigravityTranscriptControls
378
+ rawJsonDisabled={transcriptEvents.length === 0}
379
+ showCommentary={showCommentary}
380
+ showExtraEvents={showExtraEvents}
381
+ showRawJson={showRawJson}
382
+ showToolCalls={showToolCalls}
383
+ showUserMessages={showUserMessages}
384
+ onShowCommentaryChange={setShowCommentary}
385
+ onShowExtraEventsChange={setShowExtraEvents}
386
+ onShowRawJsonChange={setShowRawJson}
387
+ onShowToolCallsChange={setShowToolCalls}
388
+ onShowUserMessagesChange={setShowUserMessages}
389
+ />
390
+ {transcriptEvents.length > 0 ? (
391
+ <TranscriptView
392
+ assistantModel={null}
393
+ events={transcriptEvents}
394
+ projectPath={detail.conversation.workspaceFolder}
395
+ showCommentary={showCommentary}
396
+ showExtraEvents={showExtraEvents}
397
+ showRawJson={showRawJson}
398
+ showToolCalls={showToolCalls}
399
+ showUserMessages={showUserMessages}
400
+ />
401
+ ) : (
402
+ <EmptyAntigravityTranscript detail={detail} />
403
+ )}
404
+ </TabsContent>
405
+
406
+ <TabsContent value="metadata">
407
+ <div className="grid gap-4 xl:grid-cols-[0.95fr_1.05fr]">
408
+ <MetadataSection items={buildConversationMetadata(detail)} title="Conversation metadata" />
409
+ <MetadataSection
410
+ items={buildTranscriptStatsItems(detail, transcriptEvents)}
411
+ title="Transcript stats"
412
+ />
413
+ </div>
414
+ </TabsContent>
415
+
416
+ <TabsContent value="raw">
417
+ <AntigravityRawPanels detail={detail} events={transcriptEvents} />
418
+ </TabsContent>
419
+ </Tabs>
420
+
421
+ {exportConversationMutation.isError ? (
422
+ <p className="text-[var(--destructive)] text-sm">
423
+ {exportConversationMutation.error instanceof Error
424
+ ? exportConversationMutation.error.message
425
+ : 'Conversation export failed'}
426
+ </p>
427
+ ) : null}
428
+
429
+ {exportArtifactsMutation.isError ? (
430
+ <p className="text-[var(--destructive)] text-sm">
431
+ {exportArtifactsMutation.error instanceof Error
432
+ ? exportArtifactsMutation.error.message
433
+ : 'Artifact export failed'}
434
+ </p>
435
+ ) : null}
436
+ </div>
437
+ );
438
+ }
@@ -0,0 +1,127 @@
1
+ import type { AntigravityConversation, AntigravityWorkspaceGroup } from '@spiracha/lib/antigravity-exporter-types';
2
+ import { useMutation, useSuspenseQuery } from '@tanstack/react-query';
3
+ import { createFileRoute } from '@tanstack/react-router';
4
+ import { useDeferredValue, useState } from 'react';
5
+ import { AntigravityConversationsTable } from '#/components/antigravity-conversations-table';
6
+ import { AntigravityKeychainPanel } from '#/components/antigravity-keychain-panel';
7
+ import { ListSearchInput } from '#/components/list-search-input';
8
+ import { LoadingPanel } from '#/components/loading-panel';
9
+ import { PageHeader } from '#/components/page-header';
10
+ import { ReloadErrorPanel } from '#/components/reload-error-panel';
11
+ import {
12
+ antigravityConversationsQueryOptions,
13
+ antigravityDecryptionQueryOptions,
14
+ antigravityWorkspacesQueryOptions,
15
+ } from '#/lib/antigravity-queries';
16
+ import { exportAntigravityArtifactsFn, exportAntigravityConversationFn } from '#/lib/antigravity-server';
17
+ import { downloadTextFile } from '#/lib/download';
18
+ import { matchesTextQuery } from '#/lib/text-filter';
19
+
20
+ const findWorkspaceOrThrow = (workspaces: AntigravityWorkspaceGroup[], workspaceKey: string) => {
21
+ const workspace = workspaces.find((candidate) => candidate.key === workspaceKey);
22
+ if (!workspace) {
23
+ throw new Error(`Antigravity workspace not found: ${workspaceKey}`);
24
+ }
25
+
26
+ return workspace;
27
+ };
28
+
29
+ export const Route = createFileRoute('/antigravity/$workspaceKey')({
30
+ component: AntigravityWorkspacePage,
31
+ errorComponent: AntigravityWorkspaceErrorComponent,
32
+ loader: async ({ context, params }) => {
33
+ const workspaces = await context.queryClient.ensureQueryData(antigravityWorkspacesQueryOptions());
34
+ findWorkspaceOrThrow(workspaces, params.workspaceKey);
35
+ await Promise.all([
36
+ context.queryClient.ensureQueryData(antigravityDecryptionQueryOptions()),
37
+ context.queryClient.ensureQueryData(antigravityConversationsQueryOptions(params.workspaceKey)),
38
+ ]);
39
+ },
40
+ pendingComponent: () => (
41
+ <LoadingPanel
42
+ description="Loading Antigravity conversations, artifacts, and transcript availability."
43
+ title="Loading workspace"
44
+ />
45
+ ),
46
+ });
47
+
48
+ function AntigravityWorkspaceErrorComponent({ error }: { error: Error }) {
49
+ return <ReloadErrorPanel description={error.message} title="Failed to load Antigravity workspace" />;
50
+ }
51
+
52
+ function AntigravityWorkspacePage() {
53
+ const params = Route.useParams();
54
+ const workspaces = useSuspenseQuery(antigravityWorkspacesQueryOptions()).data;
55
+ const workspace = findWorkspaceOrThrow(workspaces, params.workspaceKey);
56
+ const conversations = useSuspenseQuery(antigravityConversationsQueryOptions(workspace.key)).data;
57
+ const decryptionState = useSuspenseQuery(antigravityDecryptionQueryOptions()).data ?? null;
58
+ const [searchInput, setSearchInput] = useState('');
59
+ const deferredSearch = useDeferredValue(searchInput);
60
+
61
+ const exportConversationMutation = useMutation({
62
+ mutationFn: (conversation: AntigravityConversation) =>
63
+ exportAntigravityConversationFn({ data: { conversationId: conversation.conversationId } }),
64
+ onSuccess: (result) => {
65
+ downloadTextFile(result.filename, result.content, 'text/markdown; charset=utf-8');
66
+ },
67
+ });
68
+
69
+ const exportArtifactsMutation = useMutation({
70
+ mutationFn: (conversation: AntigravityConversation) =>
71
+ exportAntigravityArtifactsFn({ data: { conversationId: conversation.conversationId } }),
72
+ onSuccess: (result) => {
73
+ downloadTextFile(result.filename, result.content, 'text/markdown; charset=utf-8');
74
+ },
75
+ });
76
+
77
+ const visibleConversations = conversations.filter((conversation) =>
78
+ matchesTextQuery(deferredSearch, [
79
+ conversation.title,
80
+ conversation.conversationId,
81
+ conversation.transcriptSource,
82
+ conversation.workspaceLabel,
83
+ ]),
84
+ );
85
+
86
+ return (
87
+ <div className="space-y-6">
88
+ <PageHeader
89
+ actions={
90
+ <ListSearchInput
91
+ placeholder="Search title, id, or transcript source"
92
+ value={searchInput}
93
+ onValueChange={setSearchInput}
94
+ />
95
+ }
96
+ eyebrow="Antigravity workspace"
97
+ subtitle="Inspect conversation coverage across Antigravity transcripts, raw payloads, and generated artifacts."
98
+ title={workspace.label}
99
+ />
100
+
101
+ <AntigravityKeychainPanel />
102
+
103
+ <AntigravityConversationsTable
104
+ conversations={visibleConversations}
105
+ decryptionState={decryptionState}
106
+ onExportArtifacts={(conversation) => exportArtifactsMutation.mutate(conversation)}
107
+ onExportConversation={(conversation) => exportConversationMutation.mutate(conversation)}
108
+ />
109
+
110
+ {exportConversationMutation.isError ? (
111
+ <p className="text-[var(--destructive)] text-sm">
112
+ {exportConversationMutation.error instanceof Error
113
+ ? exportConversationMutation.error.message
114
+ : 'Conversation export failed'}
115
+ </p>
116
+ ) : null}
117
+
118
+ {exportArtifactsMutation.isError ? (
119
+ <p className="text-[var(--destructive)] text-sm">
120
+ {exportArtifactsMutation.error instanceof Error
121
+ ? exportArtifactsMutation.error.message
122
+ : 'Artifact export failed'}
123
+ </p>
124
+ ) : null}
125
+ </div>
126
+ );
127
+ }
@@ -0,0 +1,51 @@
1
+ import { useSuspenseQuery } from '@tanstack/react-query';
2
+ import { createFileRoute } from '@tanstack/react-router';
3
+ import { useDeferredValue, useState } from 'react';
4
+ import { AntigravityKeychainPanel } from '#/components/antigravity-keychain-panel';
5
+ import { AntigravityWorkspacesTable } from '#/components/antigravity-workspaces-table';
6
+ import { ListSearchInput } from '#/components/list-search-input';
7
+ import { PageHeader } from '#/components/page-header';
8
+ import { ReloadErrorPanel } from '#/components/reload-error-panel';
9
+ import { antigravityWorkspacesQueryOptions } from '#/lib/antigravity-queries';
10
+ import { matchesTextQuery } from '#/lib/text-filter';
11
+
12
+ export const Route = createFileRoute('/antigravity/')({
13
+ component: AntigravityPage,
14
+ errorComponent: AntigravityErrorComponent,
15
+ loader: ({ context }) => context.queryClient.ensureQueryData(antigravityWorkspacesQueryOptions()),
16
+ });
17
+
18
+ function AntigravityErrorComponent({ error }: { error: Error }) {
19
+ return <ReloadErrorPanel description={error.message} title="Failed to load Antigravity workspaces" />;
20
+ }
21
+
22
+ function AntigravityPage() {
23
+ const workspaces = useSuspenseQuery(antigravityWorkspacesQueryOptions()).data;
24
+ const [searchInput, setSearchInput] = useState('');
25
+ const deferredSearch = useDeferredValue(searchInput);
26
+
27
+ const visibleWorkspaces = workspaces.filter((workspace) =>
28
+ matchesTextQuery(deferredSearch, [workspace.label, workspace.uri, workspace.key]),
29
+ );
30
+
31
+ return (
32
+ <div className="space-y-6">
33
+ <PageHeader
34
+ actions={
35
+ <ListSearchInput
36
+ placeholder="Search workspace name or path"
37
+ value={searchInput}
38
+ onValueChange={setSearchInput}
39
+ />
40
+ }
41
+ eyebrow="Inventory"
42
+ subtitle="Workspace groups are derived from Antigravity summary indexes, raw conversation files, local logs, and brain artifacts."
43
+ title="Antigravity"
44
+ />
45
+
46
+ <AntigravityKeychainPanel />
47
+
48
+ <AntigravityWorkspacesTable workspaces={visibleWorkspaces} />
49
+ </div>
50
+ );
51
+ }
@@ -0,0 +1,12 @@
1
+ import { createFileRoute } from '@tanstack/react-router';
2
+
3
+ export const Route = createFileRoute('/api/v1/conversation-query')({
4
+ server: {
5
+ handlers: {
6
+ POST: async ({ request }) => {
7
+ const { handleConversationApiRequest } = await import('@spiracha/lib/conversation-api');
8
+ return handleConversationApiRequest(request);
9
+ },
10
+ },
11
+ },
12
+ });
@@ -0,0 +1,12 @@
1
+ import { createFileRoute } from '@tanstack/react-router';
2
+
3
+ export const Route = createFileRoute('/api/v1/conversations/$source/$id/export')({
4
+ server: {
5
+ handlers: {
6
+ GET: async ({ request }) => {
7
+ const { handleConversationApiRequest } = await import('@spiracha/lib/conversation-api');
8
+ return handleConversationApiRequest(request);
9
+ },
10
+ },
11
+ },
12
+ });
@@ -0,0 +1,12 @@
1
+ import { createFileRoute } from '@tanstack/react-router';
2
+
3
+ export const Route = createFileRoute('/api/v1/conversations/$source/$id')({
4
+ server: {
5
+ handlers: {
6
+ GET: async ({ request }) => {
7
+ const { handleConversationApiRequest } = await import('@spiracha/lib/conversation-api');
8
+ return handleConversationApiRequest(request);
9
+ },
10
+ },
11
+ },
12
+ });
@@ -0,0 +1,12 @@
1
+ import { createFileRoute } from '@tanstack/react-router';
2
+
3
+ export const Route = createFileRoute('/api/v1/conversations')({
4
+ server: {
5
+ handlers: {
6
+ GET: async ({ request }) => {
7
+ const { handleConversationApiRequest } = await import('@spiracha/lib/conversation-api');
8
+ return handleConversationApiRequest(request);
9
+ },
10
+ },
11
+ },
12
+ });