spiracha 1.3.3 → 1.5.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 (242) hide show
  1. package/AGENTS.md +55 -6
  2. package/README.md +46 -5
  3. package/apps/ui/AGENTS.md +31 -4
  4. package/apps/ui/README.md +59 -5
  5. package/apps/ui/dist/client/assets/analytics-DOy1b6Sh.js +1 -0
  6. package/apps/ui/dist/client/assets/antigravity-conversations._conversationId-DqySVO2K.js +7 -0
  7. package/apps/ui/dist/client/assets/antigravity-conversations._conversationId-KAcXtNxI.js +1 -0
  8. package/apps/ui/dist/client/assets/antigravity-keychain-panel-B77qJz6f.js +1 -0
  9. package/apps/ui/dist/client/assets/antigravity._workspaceKey-B3NM6gRH.js +1 -0
  10. package/apps/ui/dist/client/assets/antigravity._workspaceKey-ByitGWki.js +1 -0
  11. package/apps/ui/dist/client/assets/antigravity.index-DP9JC2P9.js +1 -0
  12. package/apps/ui/dist/client/assets/antigravity.index-DgW25FEV.js +1 -0
  13. package/apps/ui/dist/client/assets/badge-C3i4OKs8.js +1 -0
  14. package/apps/ui/dist/client/assets/checkbox-CdHitXWQ.js +1 -0
  15. package/apps/ui/dist/client/assets/claude-code-sessions._sessionId-8pQ55ci2.js +1 -0
  16. package/apps/ui/dist/client/assets/claude-code-sessions._sessionId-DVz5UmtU.js +1 -0
  17. package/apps/ui/dist/client/assets/claude-code._workspaceKey-BBKskSum.js +1 -0
  18. package/apps/ui/dist/client/assets/claude-code._workspaceKey-OkikMUFs.js +1 -0
  19. package/apps/ui/dist/client/assets/claude-code.index-Cwu76dbb.js +1 -0
  20. package/apps/ui/dist/client/assets/claude-code.index-D6eMd08t.js +1 -0
  21. package/apps/ui/dist/client/assets/createServerFn-B-KkwmHU.js +3 -0
  22. package/apps/ui/dist/client/assets/cursor-threads._composerId-CmBFclK8.js +1 -0
  23. package/apps/ui/dist/client/assets/cursor-threads._composerId-hBWlP1D-.js +1 -0
  24. package/apps/ui/dist/client/assets/cursor._workspaceKey-BFPkIRi-.js +1 -0
  25. package/apps/ui/dist/client/assets/cursor._workspaceKey-CaAZjGmm.js +1 -0
  26. package/apps/ui/dist/client/assets/cursor.index-8y4o20kb.js +2 -0
  27. package/apps/ui/dist/client/assets/cursor.index-CrnMwDCi.js +1 -0
  28. package/apps/ui/dist/client/assets/{data-table-DeQq8xdt.js → data-table-Br78_dk3.js} +2 -2
  29. package/apps/ui/dist/client/assets/delete-confirm-dialog-Bxs07u-j.js +7 -0
  30. package/apps/ui/dist/client/assets/dist-B9pyYCVU.js +1 -0
  31. package/apps/ui/dist/client/assets/dist-BrJhN2A0.js +5 -0
  32. package/apps/ui/dist/client/assets/dist-Cmd3AIfD.js +1 -0
  33. package/apps/ui/dist/client/assets/dist-DvMS2965.js +1 -0
  34. package/apps/ui/dist/client/assets/download-Bf0QJKD3.js +1 -0
  35. package/apps/ui/dist/client/assets/dropdown-menu-D5cvPaZt.js +1 -0
  36. package/apps/ui/dist/client/assets/es2015-ad6040dw.js +41 -0
  37. package/apps/ui/dist/client/assets/export-dialog-Dr8d2MqD.js +1 -0
  38. package/apps/ui/dist/client/assets/formatters-BtqyrX_c.js +1 -0
  39. package/apps/ui/dist/client/assets/index-C-STgIH4.js +166 -0
  40. package/apps/ui/dist/client/assets/jsx-runtime-DGeXAQPT.js +1 -0
  41. package/apps/ui/dist/client/assets/kiro-sessions._sessionId-CKgfJ7GR.js +1 -0
  42. package/apps/ui/dist/client/assets/kiro-sessions._sessionId-zvIJHtQF.js +1 -0
  43. package/apps/ui/dist/client/assets/kiro._workspaceKey-DhVuJuZB.js +1 -0
  44. package/apps/ui/dist/client/assets/kiro._workspaceKey-QArsjkTY.js +1 -0
  45. package/apps/ui/dist/client/assets/kiro.index-C-fr4m7i.js +1 -0
  46. package/apps/ui/dist/client/assets/kiro.index-OYgAdtZd.js +1 -0
  47. package/apps/ui/dist/client/assets/metric-card-Dplm0ZiM.js +1 -0
  48. package/apps/ui/dist/client/assets/opencode-sessions._sessionId-DLjiTst-.js +1 -0
  49. package/apps/ui/dist/client/assets/opencode-sessions._sessionId-biBwrRbt.js +8 -0
  50. package/apps/ui/dist/client/assets/opencode._workspaceKey-C7OIzMOJ.js +1 -0
  51. package/apps/ui/dist/client/assets/opencode._workspaceKey-sBakX0oI.js +1 -0
  52. package/apps/ui/dist/client/assets/opencode.index-Bl_kNs9N.js +1 -0
  53. package/apps/ui/dist/client/assets/opencode.index-CN53bVmb.js +1 -0
  54. package/apps/ui/dist/client/assets/page-header-Cwa3p6Tl.js +1 -0
  55. package/apps/ui/dist/client/assets/preload-helper-B8fFrdxC.js +1 -0
  56. package/apps/ui/dist/client/assets/projects._project-D8WloxQN.js +1 -0
  57. package/apps/ui/dist/client/assets/projects._project-DSDwH4NF.js +1 -0
  58. package/apps/ui/dist/client/assets/projects.index-5xRtuJdX.js +3 -0
  59. package/apps/ui/dist/client/assets/projects.index-DEfhWqa8.js +1 -0
  60. package/apps/ui/dist/client/assets/react-dom-DL96Jor4.js +1 -0
  61. package/apps/ui/dist/client/assets/refresh-ccw-BgKjOiA6.js +1 -0
  62. package/apps/ui/dist/client/assets/reload-error-panel-AHqu0akK.js +1 -0
  63. package/apps/ui/dist/client/assets/routes-DnzF_9CX.js +1 -0
  64. package/apps/ui/dist/client/assets/scroll-text-fM0sMOB3.js +1 -0
  65. package/apps/ui/dist/client/assets/select-CYF6pF37.js +1 -0
  66. package/apps/ui/dist/client/assets/settings-Dx70jgP_.js +1 -0
  67. package/apps/ui/dist/client/assets/sqlite-error-B6uZjUe8.js +1 -0
  68. package/apps/ui/dist/client/assets/styles-B7Zi9EFA.css +1 -0
  69. package/apps/ui/dist/client/assets/tabs-CmuhkT-c.js +7 -0
  70. package/apps/ui/dist/client/assets/text-filter-DVAZySUS.js +2 -0
  71. package/apps/ui/dist/client/assets/thread-transcript-stats-BUNz6u7F.js +1 -0
  72. package/apps/ui/dist/client/assets/threads._threadId-BB9tTsV4.js +1 -0
  73. package/apps/ui/dist/client/assets/threads._threadId-BMRSFow3.js +1 -0
  74. package/apps/ui/dist/client/assets/useMutation-BSFult2i.js +1 -0
  75. package/apps/ui/dist/client/assets/useQuery-CjINKZf1.js +1 -0
  76. package/apps/ui/dist/client/icon.svg +2 -1
  77. package/apps/ui/dist/server/assets/_tanstack-start-manifest_v-CQ8Jjs3B.js +387 -0
  78. package/apps/ui/dist/server/assets/analytics-CYP_LT5Y.js +16 -0
  79. package/apps/ui/dist/server/assets/{analytics-Dc_QDZZC.js → analytics-CtpOMVMO.js} +13 -6
  80. package/apps/ui/dist/server/assets/antigravity-conversations._conversationId-BKOyL2T6.js +613 -0
  81. package/apps/ui/dist/server/assets/{antigravity-conversations._conversationId-C9z4AeN-.js → antigravity-conversations._conversationId-eS87Dx7g.js} +2 -2
  82. package/apps/ui/dist/server/assets/{antigravity-db-D9gW1D8G.js → antigravity-db-Bh8_U9uw.js} +11 -7
  83. package/apps/ui/dist/server/assets/{antigravity-keychain-panel-bpPoxhyp.js → antigravity-keychain-panel-CC7FLmAK.js} +1 -1
  84. package/apps/ui/dist/server/assets/{antigravity-queries-DVIKyOXi.js → antigravity-queries-CGrJO9Vr.js} +5 -5
  85. package/apps/ui/dist/server/assets/{antigravity-server-Cp1lc8fp.js → antigravity-server-CHRjVFqN.js} +11 -11
  86. package/apps/ui/dist/server/assets/{antigravity._workspaceKey-Dl8o1ptg.js → antigravity._workspaceKey-B0QeYUOh.js} +2 -2
  87. package/apps/ui/dist/server/assets/{antigravity._workspaceKey-BAoa4izU.js → antigravity._workspaceKey-C3kP-qyN.js} +4 -4
  88. package/apps/ui/dist/server/assets/{antigravity.index-BOlrJasZ.js → antigravity.index-CPCYkqCi.js} +2 -2
  89. package/apps/ui/dist/server/assets/claude-code-db-Ik3VStKZ.js +361 -0
  90. package/apps/ui/dist/server/assets/claude-code-queries-Cgzi4K-e.js +37 -0
  91. package/apps/ui/dist/server/assets/claude-code-server-PfraClXS.js +72 -0
  92. package/apps/ui/dist/server/assets/claude-code-sessions._sessionId-C55oe6zj.js +18 -0
  93. package/apps/ui/dist/server/assets/claude-code-sessions._sessionId-D1RYYi3j.js +473 -0
  94. package/apps/ui/dist/server/assets/claude-code-sessions._sessionId-DSvPLEUL.js +11 -0
  95. package/apps/ui/dist/server/assets/claude-code-transcript-C-bxh3cS.js +139 -0
  96. package/apps/ui/dist/server/assets/claude-code-transcript-phase-DmUMc8VU.js +10 -0
  97. package/apps/ui/dist/server/assets/claude-code._workspaceKey-B5Xg_-tE.js +28 -0
  98. package/apps/ui/dist/server/assets/claude-code._workspaceKey-BPlzyXPa.js +11 -0
  99. package/apps/ui/dist/server/assets/claude-code._workspaceKey-DqDve2wl.js +191 -0
  100. package/apps/ui/dist/server/assets/claude-code.index-B7yYR7dD.js +92 -0
  101. package/apps/ui/dist/server/assets/claude-code.index-BUHThG1W.js +11 -0
  102. package/apps/ui/dist/server/assets/{codex-queries-ev_mRUzr.js → codex-queries-CtgeZ7VL.js} +15 -13
  103. package/apps/ui/dist/server/assets/{codex-server-DIYFLozB.js → codex-server-CGXU4H8-.js} +421 -146
  104. package/apps/ui/dist/server/assets/concurrency-VXtYvlGh.js +18 -0
  105. package/apps/ui/dist/server/assets/{createServerRpc-Cg-Zr1rq.js → createServerRpc-CF_DEwnm.js} +1 -1
  106. package/apps/ui/dist/server/assets/{createSsrRpc-DVnVQhGx.js → createSsrRpc-C754NPki.js} +1 -1
  107. package/apps/ui/dist/server/assets/{cursor-db-B7agkAvM.js → cursor-db-CZnYy7aT.js} +196 -9
  108. package/apps/ui/dist/server/assets/{cursor-queries-f7DjBKSD.js → cursor-queries-NCIM0Nat.js} +12 -10
  109. package/apps/ui/dist/server/assets/{cursor-recovery-9bJLs7vG.js → cursor-recovery-CXpO8KcD.js} +2 -2
  110. package/apps/ui/dist/server/assets/{cursor-server-nPzojHN3.js → cursor-server-DNu52A3K.js} +71 -42
  111. package/apps/ui/dist/server/assets/cursor-threads._composerId-Ckn6ItHI.js +582 -0
  112. package/apps/ui/dist/server/assets/{cursor-threads._composerId-B3qcsh9C.js → cursor-threads._composerId-p9-ARAzc.js} +2 -2
  113. package/apps/ui/dist/server/assets/{cursor-transcript-2iL3KFSK.js → cursor-transcript-B7tGnqtn.js} +1 -1
  114. package/apps/ui/dist/server/assets/{cursor._workspaceKey-BL_CQyHQ.js → cursor._workspaceKey-CZuohIUL.js} +2 -2
  115. package/apps/ui/dist/server/assets/{cursor._workspaceKey-BhQeepXB.js → cursor._workspaceKey-DPp5JSjy.js} +11 -9
  116. package/apps/ui/dist/server/assets/{cursor.index-CsrdckZD.js → cursor.index-DkWT-mxw.js} +2 -2
  117. package/apps/ui/dist/server/assets/{delete-confirm-dialog-PCD7S0_M.js → delete-confirm-dialog-BcBNCxWB.js} +5 -1
  118. package/apps/ui/dist/server/assets/{empty-plugin-adapters-D3qLMPfC.js → empty-plugin-adapters-B3lHh1La.js} +1 -1
  119. package/apps/ui/dist/server/assets/{export-dialog-DaPlOGFT.js → export-dialog-D88ze9Gy.js} +54 -12
  120. package/apps/ui/dist/server/assets/kiro-db--fXrED_-.js +552 -0
  121. package/apps/ui/dist/server/assets/kiro-queries-CzNlM2ok.js +37 -0
  122. package/apps/ui/dist/server/assets/kiro-server-9WRxg2Au.js +72 -0
  123. package/apps/ui/dist/server/assets/kiro-sessions._sessionId-CRY2c7YO.js +11 -0
  124. package/apps/ui/dist/server/assets/kiro-sessions._sessionId-F1UlwxmR.js +449 -0
  125. package/apps/ui/dist/server/assets/kiro-sessions._sessionId-bvTulT7C.js +18 -0
  126. package/apps/ui/dist/server/assets/kiro-transcript-DoekQBaH.js +112 -0
  127. package/apps/ui/dist/server/assets/kiro-transcript-phase-CJG40nQg.js +27 -0
  128. package/apps/ui/dist/server/assets/kiro._workspaceKey-BDe9sQwo.js +11 -0
  129. package/apps/ui/dist/server/assets/kiro._workspaceKey-CJsjgNwO.js +28 -0
  130. package/apps/ui/dist/server/assets/kiro._workspaceKey-D_-4Qb7y.js +193 -0
  131. package/apps/ui/dist/server/assets/kiro.index-C__-UROk.js +11 -0
  132. package/apps/ui/dist/server/assets/kiro.index-CmTbqeYj.js +93 -0
  133. package/apps/ui/dist/server/assets/opencode-db-BM7KjOzc.js +397 -0
  134. package/apps/ui/dist/server/assets/opencode-queries-BeNYXnQv.js +50 -0
  135. package/apps/ui/dist/server/assets/opencode-server-BpQ_kRze.js +72 -0
  136. package/apps/ui/dist/server/assets/opencode-sessions._sessionId-CGQ-t0vD.js +518 -0
  137. package/apps/ui/dist/server/assets/opencode-sessions._sessionId-D8Q7in_Z.js +18 -0
  138. package/apps/ui/dist/server/assets/opencode-sessions._sessionId-DKOvi0lV.js +11 -0
  139. package/apps/ui/dist/server/assets/opencode-think-tags-CAoD-EcZ.js +87 -0
  140. package/apps/ui/dist/server/assets/opencode-transcript-BNTcGNym.js +141 -0
  141. package/apps/ui/dist/server/assets/opencode-transcript-phase-OqLkiQD0.js +32 -0
  142. package/apps/ui/dist/server/assets/opencode._workspaceKey-BdqcWHw1.js +11 -0
  143. package/apps/ui/dist/server/assets/opencode._workspaceKey-CfH96HTT.js +28 -0
  144. package/apps/ui/dist/server/assets/opencode._workspaceKey-DdbHPDrO.js +207 -0
  145. package/apps/ui/dist/server/assets/opencode.index-BbVzkJXP.js +11 -0
  146. package/apps/ui/dist/server/assets/opencode.index-Vh_Gq_1L.js +93 -0
  147. package/apps/ui/dist/server/assets/{projects._project-CqqUFr4l.js → projects._project-4io5LO0E.js} +5 -3
  148. package/apps/ui/dist/server/assets/{projects._project-DahGqNYS.js → projects._project-D6ZoGhJ8.js} +42 -12
  149. package/apps/ui/dist/server/assets/{projects.index-CkTeFWNU.js → projects.index-BkLiF2FF.js} +21 -7
  150. package/apps/ui/dist/server/assets/projects.index-DesYXwfi.js +14 -0
  151. package/apps/ui/dist/server/assets/route-search-ts4W9MJ9.js +38 -0
  152. package/apps/ui/dist/server/assets/router-Sac2DGk6.js +518 -0
  153. package/apps/ui/dist/server/assets/{routes-Xix3ZeSo.js → routes-Bsact1uB.js} +2 -2
  154. package/apps/ui/dist/server/assets/{routes-0x1U0IHq.js → routes-BzkJgq4W.js} +2 -2
  155. package/apps/ui/dist/server/assets/{shared-CPRNYIql.js → shared-DyhChtHf.js} +4 -1
  156. package/apps/ui/dist/server/assets/source-session-export-server-DNutCawb.js +38 -0
  157. package/apps/ui/dist/server/assets/start-B_HFwkkk.js +4 -0
  158. package/apps/ui/dist/server/assets/tabs-DkaChNVg.js +501 -0
  159. package/apps/ui/dist/server/assets/thread-transcript-stats-Dh34mt2u.js +45 -0
  160. package/apps/ui/dist/server/assets/threads._threadId-BeXEc4Lo.js +648 -0
  161. package/apps/ui/dist/server/assets/{threads._threadId-BLCkGW--.js → threads._threadId-Ci0S4mKU.js} +2 -2
  162. package/apps/ui/dist/server/assets/ui-export-files-BHLX9bhN.js +83 -0
  163. package/apps/ui/dist/server/server.js +141 -83
  164. package/package.json +28 -11
  165. package/src/lib/antigravity-db.ts +20 -13
  166. package/src/lib/claude-code-db.ts +655 -0
  167. package/src/lib/claude-code-exporter-types.ts +110 -0
  168. package/src/lib/claude-code-transcript-phase.ts +25 -0
  169. package/src/lib/claude-code-transcript.ts +180 -0
  170. package/src/lib/codex-analytics.ts +118 -18
  171. package/src/lib/codex-browser-db.ts +491 -56
  172. package/src/lib/codex-browser-export.ts +27 -71
  173. package/src/lib/codex-thread-cache.ts +17 -1
  174. package/src/lib/concurrency.ts +25 -0
  175. package/src/lib/cursor-db.ts +318 -7
  176. package/src/lib/cursor-exporter.ts +2 -2
  177. package/src/lib/kiro-db.ts +949 -0
  178. package/src/lib/kiro-exporter-types.ts +100 -0
  179. package/src/lib/kiro-transcript-phase.ts +41 -0
  180. package/src/lib/kiro-transcript.ts +115 -0
  181. package/src/lib/opencode-db.ts +610 -0
  182. package/src/lib/opencode-exporter-types.ts +129 -0
  183. package/src/lib/opencode-think-tags.ts +126 -0
  184. package/src/lib/opencode-transcript-phase.ts +50 -0
  185. package/src/lib/opencode-transcript.ts +194 -0
  186. package/src/lib/shared.ts +25 -0
  187. package/src/lib/ui-cache.ts +14 -1
  188. package/src/lib/ui-export-archive.ts +61 -0
  189. package/apps/ui/dist/client/assets/analytics-C83LcWNb.js +0 -1
  190. package/apps/ui/dist/client/assets/antigravity-conversations._conversationId-DkY8EEpK.js +0 -1
  191. package/apps/ui/dist/client/assets/antigravity-conversations._conversationId-OraHuz8j.js +0 -1
  192. package/apps/ui/dist/client/assets/antigravity-keychain-panel-DnDcq1ge.js +0 -1
  193. package/apps/ui/dist/client/assets/antigravity._workspaceKey-CQaZscA5.js +0 -1
  194. package/apps/ui/dist/client/assets/antigravity._workspaceKey-DTs99obU.js +0 -1
  195. package/apps/ui/dist/client/assets/antigravity.index-DbJa715k.js +0 -1
  196. package/apps/ui/dist/client/assets/antigravity.index-P-rs6w5X.js +0 -1
  197. package/apps/ui/dist/client/assets/badge-wgTVp-aq.js +0 -1
  198. package/apps/ui/dist/client/assets/checkbox-BUx0Gkuf.js +0 -1
  199. package/apps/ui/dist/client/assets/cursor-threads._composerId-D0DFXt8t.js +0 -1
  200. package/apps/ui/dist/client/assets/cursor-threads._composerId-tFa6Cf6A.js +0 -1
  201. package/apps/ui/dist/client/assets/cursor._workspaceKey-Df4PfA2k.js +0 -1
  202. package/apps/ui/dist/client/assets/cursor._workspaceKey-DwrzEtnV.js +0 -1
  203. package/apps/ui/dist/client/assets/cursor.index-CNBf4ZiR.js +0 -1
  204. package/apps/ui/dist/client/assets/cursor.index-DP9Hy8X6.js +0 -2
  205. package/apps/ui/dist/client/assets/delete-confirm-dialog-CPlNsLhM.js +0 -11
  206. package/apps/ui/dist/client/assets/dist-Ds3kS91l.js +0 -1
  207. package/apps/ui/dist/client/assets/download-DLuPnxpV.js +0 -1
  208. package/apps/ui/dist/client/assets/dropdown-menu-lFk6zjoL.js +0 -1
  209. package/apps/ui/dist/client/assets/es2015-D-H_iZF6.js +0 -41
  210. package/apps/ui/dist/client/assets/export-dialog-CyqyvwiP.js +0 -1
  211. package/apps/ui/dist/client/assets/formatters-DbCKP02D.js +0 -1
  212. package/apps/ui/dist/client/assets/index-C-ZPpKJ0.js +0 -22
  213. package/apps/ui/dist/client/assets/json-panel-BsngvucB.js +0 -1
  214. package/apps/ui/dist/client/assets/metadata-section-Dtl8dNag.js +0 -1
  215. package/apps/ui/dist/client/assets/metric-card-DNzR1Rne.js +0 -1
  216. package/apps/ui/dist/client/assets/page-header-dha_O7ZL.js +0 -1
  217. package/apps/ui/dist/client/assets/projects._project-B7HBhbXv.js +0 -1
  218. package/apps/ui/dist/client/assets/projects._project-DHVvuT7A.js +0 -1
  219. package/apps/ui/dist/client/assets/projects.index-BUUtx2AZ.js +0 -1
  220. package/apps/ui/dist/client/assets/projects.index-BojAe1Y4.js +0 -3
  221. package/apps/ui/dist/client/assets/refresh-ccw-B-ASKHtx.js +0 -1
  222. package/apps/ui/dist/client/assets/reload-error-panel-DD8M1BIY.js +0 -1
  223. package/apps/ui/dist/client/assets/routes-q7bzFp35.js +0 -1
  224. package/apps/ui/dist/client/assets/scroll-text-TvHyiJ_N.js +0 -1
  225. package/apps/ui/dist/client/assets/select-BFv1HMiT.js +0 -1
  226. package/apps/ui/dist/client/assets/settings-CvegTo4F.js +0 -1
  227. package/apps/ui/dist/client/assets/styles-Ch0r3kMZ.css +0 -1
  228. package/apps/ui/dist/client/assets/text-document-panel-D7Rws41o.js +0 -1
  229. package/apps/ui/dist/client/assets/text-filter-2q5pEoZh.js +0 -2
  230. package/apps/ui/dist/client/assets/threads._threadId-LpZVUlPq.js +0 -7
  231. package/apps/ui/dist/client/assets/threads._threadId-MSmNIBkq.js +0 -1
  232. package/apps/ui/dist/client/assets/useMutation-BOPJU9e0.js +0 -1
  233. package/apps/ui/dist/client/assets/useQuery-CbxZiVGF.js +0 -1
  234. package/apps/ui/dist/server/assets/_tanstack-start-manifest_v-zvGzK-Yx.js +0 -229
  235. package/apps/ui/dist/server/assets/antigravity-conversations._conversationId-JEhx-f2R.js +0 -212
  236. package/apps/ui/dist/server/assets/cursor-threads._composerId-BK3iW-3e.js +0 -218
  237. package/apps/ui/dist/server/assets/json-panel-RYsxWFae.js +0 -16
  238. package/apps/ui/dist/server/assets/metadata-section-D6Lbc7D6.js +0 -54
  239. package/apps/ui/dist/server/assets/router-K0m7dK4T.js +0 -394
  240. package/apps/ui/dist/server/assets/start-bX7bXjzw.js +0 -4
  241. package/apps/ui/dist/server/assets/text-document-panel-D8JbQWAn.js +0 -23
  242. package/apps/ui/dist/server/assets/threads._threadId-LjgsGUh-.js +0 -1052
@@ -0,0 +1,129 @@
1
+ import os from 'node:os';
2
+ import path from 'node:path';
3
+ import type { ExportFormat, JsonValue } from './shared';
4
+
5
+ export const getDefaultOpenCodeDataDir = (env: NodeJS.ProcessEnv = process.env, homeDir = os.homedir()): string => {
6
+ return path.join(env.XDG_DATA_HOME || path.join(homeDir, '.local', 'share'), 'opencode');
7
+ };
8
+
9
+ export const DEFAULT_OPENCODE_DATA_DIR = getDefaultOpenCodeDataDir();
10
+
11
+ export const resolveOpenCodeDataDir = (): string => {
12
+ const configured = process.env.SPIRACHA_OPENCODE_DATA_DIR?.trim() || process.env.SPIRACHA_OPENCODE_DIR?.trim();
13
+ return configured ? configured : DEFAULT_OPENCODE_DATA_DIR;
14
+ };
15
+
16
+ export const resolveOpenCodeDbPath = (): string => {
17
+ const configured = process.env.SPIRACHA_OPENCODE_DB?.trim();
18
+ return configured ? configured : path.join(resolveOpenCodeDataDir(), 'opencode.db');
19
+ };
20
+
21
+ export type OpenCodeWorkspaceGroup = {
22
+ archivedSessionCount: number;
23
+ key: string;
24
+ label: string;
25
+ lastActiveMs: number;
26
+ messageCount: number;
27
+ partCount: number;
28
+ projectId: string;
29
+ sessionCount: number;
30
+ uri: string;
31
+ worktree: string;
32
+ };
33
+
34
+ export type OpenCodeModelInfo = {
35
+ id: string | null;
36
+ providerID: string | null;
37
+ raw: JsonValue | string | null;
38
+ variant: string | null;
39
+ };
40
+
41
+ export type OpenCodeSessionSummary = {
42
+ agent: string | null;
43
+ archivedAtMs: number | null;
44
+ cost: number;
45
+ createdAtMs: number;
46
+ directory: string;
47
+ lastUpdatedAtMs: number;
48
+ messageCount: number;
49
+ model: OpenCodeModelInfo;
50
+ modelLabel: string | null;
51
+ partCount: number;
52
+ path: string | null;
53
+ permission: string | null;
54
+ projectId: string;
55
+ renderablePartCount: number;
56
+ sessionId: string;
57
+ slug: string;
58
+ summaryAdditions: number | null;
59
+ summaryDeletions: number | null;
60
+ summaryFiles: number | null;
61
+ textPartCount: number;
62
+ title: string;
63
+ tokensCacheRead: number;
64
+ tokensCacheWrite: number;
65
+ tokensInput: number;
66
+ tokensOutput: number;
67
+ tokensReasoning: number;
68
+ toolPartCount: number;
69
+ totalTokens: number;
70
+ worktree: string;
71
+ workspaceKey: string;
72
+ workspaceLabel: string;
73
+ };
74
+
75
+ export type OpenCodePartType = 'reasoning' | 'step-finish' | 'step-start' | 'text' | 'tool' | 'unknown';
76
+
77
+ export type OpenCodeStepTokens = {
78
+ cacheRead: number;
79
+ cacheWrite: number;
80
+ input: number;
81
+ output: number;
82
+ reasoning: number;
83
+ total: number;
84
+ };
85
+
86
+ export type OpenCodeTranscriptPart = {
87
+ argumentsText?: string | null;
88
+ callId?: string | null;
89
+ createdAtMs: number;
90
+ endTimeMs?: number | null;
91
+ messageId: string;
92
+ outputText?: string | null;
93
+ partId: string;
94
+ raw: Record<string, JsonValue>;
95
+ reason?: string | null;
96
+ role: string;
97
+ snapshot?: string | null;
98
+ startTimeMs?: number | null;
99
+ status?: string | null;
100
+ text?: string;
101
+ title?: string | null;
102
+ tokens?: OpenCodeStepTokens | null;
103
+ toolName?: string | null;
104
+ type: OpenCodePartType;
105
+ updatedAtMs: number;
106
+ };
107
+
108
+ export type OpenCodeTranscriptMessage = {
109
+ createdAtMs: number;
110
+ messageId: string;
111
+ parts: OpenCodeTranscriptPart[];
112
+ raw: Record<string, JsonValue>;
113
+ role: string;
114
+ updatedAtMs: number;
115
+ };
116
+
117
+ export type OpenCodeSessionTranscript = {
118
+ messages: OpenCodeTranscriptMessage[];
119
+ partCount: number;
120
+ renderablePartCount: number;
121
+ session: OpenCodeSessionSummary;
122
+ };
123
+
124
+ export type OpenCodeExportOptions = {
125
+ includeCommentary: boolean;
126
+ includeMetadata: boolean;
127
+ includeTools: boolean;
128
+ outputFormat: ExportFormat;
129
+ };
@@ -0,0 +1,126 @@
1
+ export type OpenCodeThinkTagText = {
2
+ reasoningBlocks: string[];
3
+ visibleText: string;
4
+ };
5
+
6
+ const THINK_OPEN_PATTERN = /<think\b[^>]*>/iy;
7
+ const THINK_CLOSE_PATTERN = /<\/think>/gi;
8
+ const THINK_CLOSE_TAG_LENGTH = '</think>'.length;
9
+
10
+ const normalizeExtractedText = (text: string): string => {
11
+ return text.replace(/\n{3,}/g, '\n\n').trim();
12
+ };
13
+
14
+ const getBacktickRunLength = (text: string, start: number): number => {
15
+ let end = start;
16
+ while (text[end] === '`') {
17
+ end += 1;
18
+ }
19
+
20
+ return end - start;
21
+ };
22
+
23
+ const findClosingBackticks = (text: string, start: number, runLength: number): number => {
24
+ const marker = '`'.repeat(runLength);
25
+ const index = text.indexOf(marker, start + runLength);
26
+ return index === -1 ? text.length : index + runLength;
27
+ };
28
+
29
+ const findThinkCloseIndex = (text: string, start: number): number => {
30
+ THINK_CLOSE_PATTERN.lastIndex = start;
31
+ const match = THINK_CLOSE_PATTERN.exec(text);
32
+ return match ? match.index : -1;
33
+ };
34
+
35
+ const getLastVisibleChar = (parts: string[]): string => {
36
+ for (let index = parts.length - 1; index >= 0; index -= 1) {
37
+ const part = parts[index];
38
+ if (part) {
39
+ return part.at(-1) ?? '';
40
+ }
41
+ }
42
+
43
+ return '';
44
+ };
45
+
46
+ const getThinkReplacement = (previous: string, next: string): string => {
47
+ if (previous === '\n' || next === '\n') {
48
+ return '\n';
49
+ }
50
+ if ((previous && /\s/u.test(previous)) || (next && /\s/u.test(next))) {
51
+ return '';
52
+ }
53
+
54
+ return ' ';
55
+ };
56
+
57
+ const shouldSkipFollowingSpace = (replacement: string, previous: string, next: string): boolean => {
58
+ return (replacement === ' ' || Boolean(previous && /[^\S\n]/u.test(previous))) && /[^\S\n]/u.test(next);
59
+ };
60
+
61
+ const readThinkBlock = (
62
+ text: string,
63
+ cursor: number,
64
+ visibleParts: string[],
65
+ ): { nextCursor: number; reasoning: string | null; replacement: string } | null => {
66
+ THINK_OPEN_PATTERN.lastIndex = cursor;
67
+ const openMatch = THINK_OPEN_PATTERN.exec(text);
68
+ if (openMatch?.index !== cursor) {
69
+ return null;
70
+ }
71
+
72
+ const reasoningStart = THINK_OPEN_PATTERN.lastIndex;
73
+ const closeIndex = findThinkCloseIndex(text, reasoningStart);
74
+ const reasoningEnd = closeIndex === -1 ? text.length : closeIndex;
75
+ const normalizedReasoning = normalizeExtractedText(text.slice(reasoningStart, reasoningEnd));
76
+ let nextCursor = closeIndex === -1 ? text.length : closeIndex + THINK_CLOSE_TAG_LENGTH;
77
+ const previous = getLastVisibleChar(visibleParts);
78
+ const replacement = getThinkReplacement(previous, text[nextCursor] ?? '');
79
+ if (shouldSkipFollowingSpace(replacement, previous, text[nextCursor] ?? '')) {
80
+ nextCursor += 1;
81
+ }
82
+
83
+ return {
84
+ nextCursor,
85
+ reasoning: normalizedReasoning || null,
86
+ replacement,
87
+ };
88
+ };
89
+
90
+ /**
91
+ * OpenCode can store MiniMax reasoning inline as <think> blocks. Preserve literal
92
+ * examples in Markdown code while extracting model-emitted tags as commentary.
93
+ */
94
+ export const splitOpenCodeThinkTaggedText = (text: string): OpenCodeThinkTagText => {
95
+ const reasoningBlocks: string[] = [];
96
+ const visibleParts: string[] = [];
97
+ let cursor = 0;
98
+
99
+ while (cursor < text.length) {
100
+ if (text[cursor] === '`') {
101
+ const runLength = getBacktickRunLength(text, cursor);
102
+ const end = findClosingBackticks(text, cursor, runLength);
103
+ visibleParts.push(text.slice(cursor, end));
104
+ cursor = end;
105
+ continue;
106
+ }
107
+
108
+ const thinkBlock = readThinkBlock(text, cursor, visibleParts);
109
+ if (thinkBlock) {
110
+ if (thinkBlock.reasoning) {
111
+ reasoningBlocks.push(thinkBlock.reasoning);
112
+ }
113
+ visibleParts.push(thinkBlock.replacement);
114
+ cursor = thinkBlock.nextCursor;
115
+ continue;
116
+ }
117
+
118
+ visibleParts.push(text[cursor]!);
119
+ cursor += 1;
120
+ }
121
+
122
+ return {
123
+ reasoningBlocks,
124
+ visibleText: normalizeExtractedText(visibleParts.join('')),
125
+ };
126
+ };
@@ -0,0 +1,50 @@
1
+ import type { OpenCodeTranscriptPart } from './opencode-exporter-types';
2
+ import { splitOpenCodeThinkTaggedText } from './opencode-think-tags';
3
+
4
+ export type OpenCodeMessagePhase = 'commentary' | 'final_answer' | null;
5
+
6
+ export const getFinalOpenCodeAssistantTextPartIds = (parts: OpenCodeTranscriptPart[]): Set<string> => {
7
+ const finalPartIds = new Set<string>();
8
+ let latestAssistantTextPartId: string | null = null;
9
+
10
+ const flushAssistantRun = () => {
11
+ if (latestAssistantTextPartId) {
12
+ finalPartIds.add(latestAssistantTextPartId);
13
+ latestAssistantTextPartId = null;
14
+ }
15
+ };
16
+
17
+ for (const part of parts) {
18
+ if (part.role === 'user') {
19
+ flushAssistantRun();
20
+ continue;
21
+ }
22
+
23
+ if (part.role !== 'assistant') {
24
+ continue;
25
+ }
26
+
27
+ if (part.type === 'tool') {
28
+ latestAssistantTextPartId = null;
29
+ continue;
30
+ }
31
+
32
+ if (part.type === 'text' && splitOpenCodeThinkTaggedText(part.text ?? '').visibleText.trim()) {
33
+ latestAssistantTextPartId = part.partId;
34
+ }
35
+ }
36
+
37
+ flushAssistantRun();
38
+ return finalPartIds;
39
+ };
40
+
41
+ export const getOpenCodeTextPartPhase = (
42
+ part: OpenCodeTranscriptPart,
43
+ finalAssistantTextPartIds: Set<string>,
44
+ ): OpenCodeMessagePhase => {
45
+ if (part.role !== 'assistant') {
46
+ return null;
47
+ }
48
+
49
+ return finalAssistantTextPartIds.has(part.partId) ? 'final_answer' : 'commentary';
50
+ };
@@ -0,0 +1,194 @@
1
+ import type {
2
+ OpenCodeExportOptions,
3
+ OpenCodeSessionSummary,
4
+ OpenCodeSessionTranscript,
5
+ OpenCodeTranscriptPart,
6
+ } from './opencode-exporter-types';
7
+ import { splitOpenCodeThinkTaggedText } from './opencode-think-tags';
8
+ import { getFinalOpenCodeAssistantTextPartIds, getOpenCodeTextPartPhase } from './opencode-transcript-phase';
9
+ import {
10
+ cleanExtractedText,
11
+ cleanInlineTitle,
12
+ formatInlineLiteral,
13
+ type MetadataEntry,
14
+ renderCodeBlock,
15
+ renderDocumentTitle,
16
+ renderMetadataBlock,
17
+ renderSection,
18
+ } from './shared';
19
+
20
+ const TOOL_OUTPUT_PREVIEW_LIMIT = 4000;
21
+ const MIN_DATE_MS = -8_640_000_000_000_000;
22
+ const MAX_DATE_MS = 8_640_000_000_000_000;
23
+
24
+ const formatUnixMillis = (value: number | null): string | null => {
25
+ if (
26
+ value === null ||
27
+ value === undefined ||
28
+ !Number.isFinite(value) ||
29
+ value < MIN_DATE_MS ||
30
+ value > MAX_DATE_MS
31
+ ) {
32
+ return null;
33
+ }
34
+
35
+ return new Date(value).toISOString();
36
+ };
37
+
38
+ const getSessionTitle = (session: OpenCodeSessionSummary): string => {
39
+ return cleanInlineTitle(session.title || session.sessionId);
40
+ };
41
+
42
+ const buildMetadataEntries = (session: OpenCodeSessionSummary): MetadataEntry[] => [
43
+ { key: 'exported_from', value: 'opencode_sqlite' },
44
+ { key: 'session_id', value: session.sessionId },
45
+ { key: 'title', value: session.title },
46
+ { key: 'slug', value: session.slug },
47
+ { key: 'project_id', value: session.projectId },
48
+ { key: 'worktree', value: session.worktree },
49
+ { key: 'directory', value: session.directory },
50
+ { key: 'agent', value: session.agent },
51
+ { key: 'model', value: session.modelLabel },
52
+ { key: 'created_at_unix_ms', value: session.createdAtMs },
53
+ { key: 'created_at_iso', value: formatUnixMillis(session.createdAtMs) },
54
+ { key: 'last_updated_at_unix_ms', value: session.lastUpdatedAtMs },
55
+ { key: 'last_updated_at_iso', value: formatUnixMillis(session.lastUpdatedAtMs) },
56
+ { key: 'message_count', value: session.messageCount },
57
+ { key: 'part_count', value: session.partCount },
58
+ { key: 'total_tokens', value: session.totalTokens },
59
+ { key: 'cost', value: session.cost },
60
+ ];
61
+
62
+ const roleTitle = (role: string): string => {
63
+ if (role === 'assistant') {
64
+ return 'Assistant';
65
+ }
66
+
67
+ if (role === 'user') {
68
+ return 'User';
69
+ }
70
+
71
+ if (role === 'system') {
72
+ return 'System';
73
+ }
74
+
75
+ return role ? cleanInlineTitle(role) : 'Message';
76
+ };
77
+
78
+ const truncateOutput = (text: string): string => {
79
+ if (text.length <= TOOL_OUTPUT_PREVIEW_LIMIT) {
80
+ return text;
81
+ }
82
+
83
+ return `${text.slice(0, TOOL_OUTPUT_PREVIEW_LIMIT)}\n... (truncated)`;
84
+ };
85
+
86
+ const renderTextPart = (
87
+ part: OpenCodeTranscriptPart,
88
+ options: OpenCodeExportOptions,
89
+ finalAssistantTextPartIds: Set<string>,
90
+ ): string => {
91
+ const { reasoningBlocks, visibleText } =
92
+ part.role === 'assistant'
93
+ ? splitOpenCodeThinkTaggedText(part.text ?? '')
94
+ : { reasoningBlocks: [], visibleText: part.text ?? '' };
95
+ const sections: string[] = [];
96
+
97
+ if (options.includeCommentary) {
98
+ sections.push(
99
+ ...reasoningBlocks
100
+ .map((block) => cleanExtractedText(block).trim())
101
+ .filter(Boolean)
102
+ .map((block) => renderSection('Reasoning', block, options.outputFormat)),
103
+ );
104
+ }
105
+
106
+ const text = cleanExtractedText(visibleText).trim();
107
+ if (
108
+ text &&
109
+ (getOpenCodeTextPartPhase(part, finalAssistantTextPartIds) !== 'commentary' || options.includeCommentary)
110
+ ) {
111
+ sections.push(renderSection(roleTitle(part.role), text, options.outputFormat));
112
+ }
113
+
114
+ return sections.join('\n\n');
115
+ };
116
+
117
+ const renderReasoningPart = (part: OpenCodeTranscriptPart, options: OpenCodeExportOptions): string => {
118
+ if (!options.includeCommentary) {
119
+ return '';
120
+ }
121
+
122
+ const { reasoningBlocks, visibleText } = splitOpenCodeThinkTaggedText(part.text ?? '');
123
+ const text = cleanExtractedText([...reasoningBlocks, visibleText].filter(Boolean).join('\n\n')).trim();
124
+ return text ? renderSection('Reasoning', text, options.outputFormat) : '';
125
+ };
126
+
127
+ const renderToolPart = (part: OpenCodeTranscriptPart, options: OpenCodeExportOptions): string => {
128
+ if (!options.includeTools) {
129
+ return '';
130
+ }
131
+
132
+ const toolName = part.toolName ?? 'unknown';
133
+ const lines = [`Tool: ${formatInlineLiteral(toolName, options.outputFormat)}`];
134
+ if (part.status) {
135
+ lines.push(`Status: ${part.status}`);
136
+ }
137
+ if (part.callId) {
138
+ lines.push(`Call ID: ${part.callId}`);
139
+ }
140
+ if (part.title) {
141
+ lines.push(`Title: ${part.title}`);
142
+ }
143
+ if (part.argumentsText?.trim()) {
144
+ lines.push('', 'Input:', '', renderCodeBlock(part.argumentsText.trim(), options.outputFormat));
145
+ }
146
+ if (part.outputText?.trim()) {
147
+ lines.push('', 'Output:', '', renderCodeBlock(truncateOutput(part.outputText.trim()), options.outputFormat));
148
+ }
149
+
150
+ return renderSection('Tool Call', lines.join('\n'), options.outputFormat);
151
+ };
152
+
153
+ const renderPart = (
154
+ part: OpenCodeTranscriptPart,
155
+ options: OpenCodeExportOptions,
156
+ finalAssistantTextPartIds: Set<string>,
157
+ ): string => {
158
+ if (part.type === 'text') {
159
+ return renderTextPart(part, options, finalAssistantTextPartIds);
160
+ }
161
+
162
+ if (part.type === 'reasoning') {
163
+ return renderReasoningPart(part, options);
164
+ }
165
+
166
+ if (part.type === 'tool') {
167
+ return renderToolPart(part, options);
168
+ }
169
+
170
+ return '';
171
+ };
172
+
173
+ export const renderOpenCodeTranscript = (
174
+ transcript: OpenCodeSessionTranscript,
175
+ options: OpenCodeExportOptions,
176
+ ): string | null => {
177
+ const partsList = transcript.messages.flatMap((message) => message.parts);
178
+ const finalAssistantTextPartIds = getFinalOpenCodeAssistantTextPartIds(partsList);
179
+ const sections = partsList.map((part) => renderPart(part, options, finalAssistantTextPartIds)).filter(Boolean);
180
+ if (sections.length === 0) {
181
+ return null;
182
+ }
183
+
184
+ const parts = [
185
+ renderDocumentTitle(getSessionTitle(transcript.session), options.outputFormat),
186
+ '',
187
+ options.includeMetadata
188
+ ? renderMetadataBlock(buildMetadataEntries(transcript.session), options.outputFormat)
189
+ : '',
190
+ ...sections,
191
+ ].filter(Boolean);
192
+
193
+ return `${parts.join('\n').trimEnd()}\n`;
194
+ };
package/src/lib/shared.ts CHANGED
@@ -42,6 +42,31 @@ export const getPortablePathBasename = (value: string): string => {
42
42
  return path.win32.basename(path.posix.basename(trimmed));
43
43
  };
44
44
 
45
+ export const isWorkspacePathQuery = (value: string): boolean => {
46
+ const raw = value.trim();
47
+ return raw.startsWith('/') || raw.startsWith('~') || raw.includes('/') || raw.includes('\\');
48
+ };
49
+
50
+ export const normalizeWorkspacePathQuery = (value: string): string => {
51
+ return expandHome(value.trim())
52
+ .replace(/[\\/]+$/u, '')
53
+ .replace(/\\/gu, '/');
54
+ };
55
+
56
+ export const workspacePathMatchesQuery = (worktree: string, query: string): boolean => {
57
+ const normalizedQuery = normalizeWorkspacePathQuery(query);
58
+ const normalizedWorktree = normalizeWorkspacePathQuery(worktree);
59
+ if (!normalizedQuery) {
60
+ return false;
61
+ }
62
+ if (normalizedWorktree === normalizedQuery) {
63
+ return true;
64
+ }
65
+
66
+ const suffix = normalizedQuery.replace(/^\/+/u, '');
67
+ return Boolean(suffix) && normalizedWorktree.endsWith(`/${suffix}`);
68
+ };
69
+
45
70
  export const cleanInlineTitle = (value: string): string => {
46
71
  const firstLine =
47
72
  value
@@ -24,6 +24,18 @@ export const hashCacheKeyParts = (...parts: string[]) => {
24
24
  return createHash('sha1').update(parts.join('|')).digest('hex');
25
25
  };
26
26
 
27
+ export const hashCacheKeyPartsIterable = (parts: Iterable<string>) => {
28
+ const hash = createHash('sha1');
29
+ for (const part of parts) {
30
+ hash.update(String(part.length));
31
+ hash.update(':');
32
+ hash.update(part);
33
+ hash.update(';');
34
+ }
35
+
36
+ return hash.digest('hex');
37
+ };
38
+
27
39
  export const getFileFingerprint = async (filePath: string) => {
28
40
  const metadata = await stat(filePath);
29
41
  return `${filePath}:${metadata.size}:${metadata.mtimeMs}`;
@@ -55,7 +67,8 @@ export const getCachedJson = async <T>(key: string): Promise<T | null> => {
55
67
  return (parsed as CacheEnvelope<T>).value;
56
68
  }
57
69
 
58
- return parsed as T;
70
+ await rm(filePath, { force: true });
71
+ return null;
59
72
  };
60
73
 
61
74
  export const setCachedJson = async <T>(key: string, value: T) => {
@@ -0,0 +1,61 @@
1
+ import type { ExportFormat } from './shared';
2
+
3
+ export const sanitizeExportFileName = (value: string) => {
4
+ return value
5
+ .replace(/[<>:"/\\|?*\u0000-\u001f]/gu, ' ')
6
+ .replace(/\.\.+/gu, ' ')
7
+ .replace(/\s+/gu, ' ')
8
+ .trim();
9
+ };
10
+
11
+ export const getExportMimeType = (outputFormat: ExportFormat) => {
12
+ return outputFormat === 'md' ? 'text/markdown; charset=utf-8' : 'text/plain; charset=utf-8';
13
+ };
14
+
15
+ export const resolveUniqueExportFileBaseName = (baseName: string, usedCounts: Map<string, number>) => {
16
+ const count = (usedCounts.get(baseName) ?? 0) + 1;
17
+ usedCounts.set(baseName, count);
18
+ return count === 1 ? baseName : `${baseName}-${count}`;
19
+ };
20
+
21
+ const readPipeText = async (pipe: ReadableStream<Uint8Array> | number | undefined) => {
22
+ return pipe && typeof pipe !== 'number' ? new Response(pipe).text() : '';
23
+ };
24
+
25
+ const runZip = async (args: string[], options: { cwd?: string } = {}) => {
26
+ let proc: ReturnType<typeof Bun.spawn>;
27
+ try {
28
+ proc = Bun.spawn(['zip', '-9', ...args], {
29
+ cwd: options.cwd,
30
+ stderr: 'pipe',
31
+ stdout: 'pipe',
32
+ });
33
+ } catch (error) {
34
+ throw new Error(
35
+ `zip command failed to start. Install the "zip" executable or choose a non-zip export. ${error instanceof Error ? error.message : String(error)}`,
36
+ );
37
+ }
38
+
39
+ const [stdoutText, stderrText, exitCode] = await Promise.all([
40
+ readPipeText(proc.stdout),
41
+ readPipeText(proc.stderr),
42
+ proc.exited,
43
+ ]);
44
+
45
+ if (exitCode !== 0) {
46
+ const output = (stderrText || stdoutText).trim();
47
+ throw new Error(
48
+ output
49
+ ? `zip command failed (${exitCode}): ${output}`
50
+ : `zip command failed (${exitCode}). Install the "zip" executable or choose a non-zip export.`,
51
+ );
52
+ }
53
+ };
54
+
55
+ export const zipExportFile = async (sourcePath: string, zipPath: string) => {
56
+ await runZip(['-j', zipPath, sourcePath]);
57
+ };
58
+
59
+ export const zipExportDirectory = async (sourceDirectory: string, zipPath: string) => {
60
+ await runZip(['-r', zipPath, '.'], { cwd: sourceDirectory });
61
+ };
@@ -1 +0,0 @@
1
- import{c as e,o as t,s as n}from"./formatters-DbCKP02D.js";import{n as r,t as i}from"./data-table-DeQq8xdt.js";import{a,i as o,n as s,r as c,t as l}from"./select-BFv1HMiT.js";import{Bt as u,Lt as d,M as f,k as p,zt as m}from"./index-C-ZPpKJ0.js";import{t as h}from"./metric-card-DNzR1Rne.js";import{t as g}from"./page-header-dha_O7ZL.js";var _=u(m()),v=d(),y=r(),b=[y.accessor(`name`,{cell:e=>(0,v.jsx)(`span`,{className:`font-mono text-sm`,children:e.getValue()}),header:`Tool`}),y.accessor(`count`,{cell:e=>(0,v.jsx)(`span`,{className:`font-mono text-sm`,children:t(e.getValue())}),header:`Calls`})],x=r(),S=[x.accessor(`model`,{cell:e=>(0,v.jsx)(`span`,{className:`font-mono text-sm`,children:e.getValue()}),header:`Model`}),x.accessor(`threadCount`,{cell:e=>(0,v.jsx)(`span`,{className:`font-mono text-sm`,children:t(e.getValue())}),header:`Threads`}),x.accessor(`totalTokens`,{cell:e=>(0,v.jsx)(`span`,{className:`font-mono text-sm`,children:n(e.getValue())}),header:`Tokens`})];function C(){let r=e(f()).data,[u,d]=(0,_.useState)(null),m=e(p(u)).data;return(0,v.jsxs)(`div`,{className:`space-y-6`,children:[(0,v.jsx)(g,{actions:(0,v.jsxs)(l,{value:u??`__all__`,onValueChange:e=>{(0,_.startTransition)(()=>{d(e===`__all__`?null:e)})},children:[(0,v.jsx)(o,{className:`h-10 w-full rounded-full border-[var(--border)] bg-[var(--panel)] sm:w-[15rem]`,children:(0,v.jsx)(a,{placeholder:`Filter by project`})}),(0,v.jsxs)(s,{children:[(0,v.jsx)(c,{value:`__all__`,children:`All projects`}),r.map(e=>(0,v.jsx)(c,{value:e.name,children:e.name},e.name))]})]}),eyebrow:`Analytics`,subtitle:`Inspect token load, tool-call distribution, and project-scoped usage patterns to understand where Codex is spending effort.`,title:`Analytics`}),(0,v.jsxs)(`div`,{className:`grid gap-4 md:grid-cols-2 xl:grid-cols-5`,children:[(0,v.jsx)(h,{label:`Threads`,value:t(m.summary.totalThreads)}),(0,v.jsx)(h,{label:`Projects`,value:t(m.summary.totalProjects)}),(0,v.jsx)(h,{label:`Tokens`,value:n(m.summary.totalTokens)}),(0,v.jsx)(h,{label:`Average per thread`,value:n(Math.round(m.summary.averageTokensPerThread))}),(0,v.jsx)(h,{label:`Web search threads`,value:t(m.summary.threadsWithWebSearch)})]}),(0,v.jsxs)(`div`,{className:`grid gap-4 xl:grid-cols-2`,children:[(0,v.jsxs)(`section`,{className:`space-y-4`,children:[(0,v.jsxs)(`div`,{children:[(0,v.jsx)(`h3`,{className:`font-semibold text-sm`,children:`Most frequent tool calls`}),(0,v.jsx)(`p`,{className:`mt-1 text-[var(--muted-foreground)] text-sm`,children:`Useful for future prompt and tool optimization work.`})]}),(0,v.jsx)(i,{columns:b,data:m.toolUsage,emptyMessage:`No tool calls recorded.`})]}),(0,v.jsxs)(`section`,{className:`space-y-4`,children:[(0,v.jsxs)(`div`,{children:[(0,v.jsx)(`h3`,{className:`font-semibold text-sm`,children:`Model token breakdown`}),(0,v.jsx)(`p`,{className:`mt-1 text-[var(--muted-foreground)] text-sm`,children:`Compare model usage and token concentration within the current project scope.`})]}),(0,v.jsx)(i,{columns:S,data:m.modelsByTokens,emptyMessage:`No model usage recorded.`})]})]})]})}export{C as component};
@@ -1 +0,0 @@
1
- import{Lt as e}from"./index-C-ZPpKJ0.js";import{t}from"./reload-error-panel-DD8M1BIY.js";var n=e();function r({error:e}){return(0,n.jsx)(t,{description:e.message,title:`Failed to load Antigravity conversation`})}export{r as errorComponent};
@@ -1 +0,0 @@
1
- import{c as e,n as t,o as n,r}from"./formatters-DbCKP02D.js";import{t as i}from"./useMutation-BOPJU9e0.js";import{n as a,t as o}from"./metadata-section-Dtl8dNag.js";import{r as s,t as c}from"./download-DLuPnxpV.js";import{t as l}from"./antigravity-keychain-panel-DnDcq1ge.js";import{t as u}from"./scroll-text-TvHyiJ_N.js";import{Ft as d,H as f,Lt as p,d as m,g as h,l as g,m as _,p as v,t as y}from"./index-C-ZPpKJ0.js";import{t as b}from"./metric-card-DNzR1Rne.js";import{t as x}from"./page-header-dha_O7ZL.js";import{t as S}from"./text-document-panel-D7Rws41o.js";var C=p(),w=e=>[{label:`Conversation ID`,value:(0,C.jsx)(`span`,{"data-mono":`true`,children:e.conversation.conversationId})},{label:`Workspace`,value:(0,C.jsx)(d,{className:`text-[var(--accent)]`,params:{workspaceKey:e.conversation.workspaceKey},to:`/antigravity/$workspaceKey`,children:e.conversation.workspaceLabel})},{label:`Created`,value:(0,C.jsx)(`span`,{suppressHydrationWarning:!0,children:r(e.conversation.createdAtMs)})},{label:`Updated`,value:(0,C.jsx)(`span`,{suppressHydrationWarning:!0,children:r(e.conversation.lastUpdatedAtMs)})},{label:`Transcript source`,value:e.conversation.transcriptSource??`n/a`},{label:`Conversation path`,value:e.conversation.conversationPath??`n/a`},{label:`Transcript path`,value:e.conversation.transcriptPath??`n/a`},{label:`Summary path`,value:e.conversation.summaryPath??`n/a`},{label:`Source root`,value:e.conversation.sourceRoot??`n/a`}];function T({canExportArtifacts:e,canExportConversation:t,exportArtifactsPending:n,exportConversationPending:r,showConversationExport:i,onExportArtifacts:a,onExportConversation:o}){return(0,C.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[i?(0,C.jsxs)(f,{className:`rounded-full`,disabled:!t||r,type:`button`,variant:`outline`,onClick:o,children:[(0,C.jsx)(s,{className:`mr-2 size-4`}),`Export conversation`]}):null,e?(0,C.jsxs)(f,{className:`rounded-full`,disabled:n,type:`button`,variant:`outline`,onClick:a,children:[(0,C.jsx)(u,{className:`mr-2 size-4`}),`Export artifacts`]}):null]})}function E({detail:e}){return(0,C.jsxs)(`div`,{className:`space-y-4`,children:[e.transcriptLocked?(0,C.jsxs)(`section`,{className:`rounded-[1.6rem] border border-[var(--border)] bg-[var(--panel)] p-5 shadow-[var(--panel-shadow)]`,children:[(0,C.jsx)(`h3`,{className:`font-semibold text-[var(--muted-foreground)] text-sm uppercase tracking-[0.18em]`,children:`Transcript`}),(0,C.jsx)(`p`,{className:`mt-4 text-[var(--muted-foreground)] text-sm`,children:`Unlock Antigravity transcript export to inspect the rendered conversation content here.`})]}):e.conversationMarkdown?(0,C.jsx)(S,{content:e.conversationMarkdown,description:`Rendered from the available Antigravity transcript or decrypted safe-storage payload.`,title:`Conversation transcript`}):(0,C.jsxs)(`section`,{className:`rounded-[1.6rem] border border-[var(--border)] bg-[var(--panel)] p-5 shadow-[var(--panel-shadow)]`,children:[(0,C.jsx)(`h3`,{className:`font-semibold text-[var(--muted-foreground)] text-sm uppercase tracking-[0.18em]`,children:`Transcript`}),(0,C.jsx)(`p`,{className:`mt-4 text-[var(--muted-foreground)] text-sm`,children:e.artifactsMarkdown?`No transcript preview is available for this conversation. Generated artifacts are available below.`:`No transcript preview is available for this conversation.`})]}),e.artifactsMarkdown?(0,C.jsx)(S,{content:e.artifactsMarkdown,description:`Markdown artifacts generated for this conversation.`,title:`Artifacts`}):null]})}function D(){let r=e(m()).data,s=e(g(y.useParams().conversationId)).data,u=h(s.conversation,!!r?.isUnlocked),d=s.artifactsMarkdown!==null,f=u||s.transcriptLocked,p=i({mutationFn:()=>_({data:{conversationId:s.conversation.conversationId}}),onSuccess:e=>{c(e.filename,e.content,`text/markdown; charset=utf-8`)}}),S=i({mutationFn:()=>v({data:{conversationId:s.conversation.conversationId}}),onSuccess:e=>{c(e.filename,e.content,`text/markdown; charset=utf-8`)}});return(0,C.jsxs)(`div`,{className:`space-y-6`,children:[(0,C.jsx)(x,{actions:(0,C.jsx)(T,{canExportArtifacts:d,canExportConversation:u,exportArtifactsPending:S.isPending,exportConversationPending:p.isPending,showConversationExport:f,onExportArtifacts:()=>S.mutate(),onExportConversation:()=>p.mutate()}),breadcrumb:(0,C.jsx)(a,{items:[{label:`Antigravity`,to:`/antigravity`},{label:s.conversation.workspaceLabel,params:{workspaceKey:s.conversation.workspaceKey},to:`/antigravity/$workspaceKey`},{label:s.conversation.title}]}),eyebrow:`Antigravity conversation`,subtitle:`Conversation detail for the selected Antigravity workspace session.`,title:s.conversation.title}),(0,C.jsx)(l,{}),(0,C.jsxs)(`div`,{className:`grid gap-3 md:grid-cols-2 xl:grid-cols-4`,children:[(0,C.jsx)(b,{label:`Transcript entries`,value:n(s.conversation.transcriptEntryCount)}),(0,C.jsx)(b,{label:`Artifacts`,value:n(s.conversation.artifactCount)}),(0,C.jsx)(b,{label:`Size`,value:t(s.conversation.conversationBytes)}),(0,C.jsx)(b,{helper:s.conversation.transcriptSource??`summary`,label:`Indexed items`,value:n(s.conversation.indexedItemCount??0)})]}),(0,C.jsxs)(`div`,{className:`grid gap-4 xl:grid-cols-[0.95fr_1.05fr]`,children:[(0,C.jsx)(o,{items:w(s),title:`Conversation metadata`}),(0,C.jsx)(E,{detail:s})]}),p.isError?(0,C.jsx)(`p`,{className:`text-[var(--destructive)] text-sm`,children:p.error instanceof Error?p.error.message:`Conversation export failed`}):null,S.isError?(0,C.jsx)(`p`,{className:`text-[var(--destructive)] text-sm`,children:S.error instanceof Error?S.error.message:`Artifact export failed`}):null]})}export{D as component};
@@ -1 +0,0 @@
1
- import{t as e}from"./useMutation-BOPJU9e0.js";import{t}from"./useQuery-CbxZiVGF.js";import{H as n,Lt as r,_t as i,d as a,gt as o,h as s,mt as c}from"./index-C-ZPpKJ0.js";var l=o(`key-round`,[[`path`,{d:`M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z`,key:`1s6t7t`}],[`circle`,{cx:`16.5`,cy:`7.5`,r:`.5`,fill:`currentColor`,key:`w0ekpg`}]]),u=o(`lock-keyhole`,[[`circle`,{cx:`12`,cy:`16`,r:`1`,key:`1au0dj`}],[`rect`,{x:`3`,y:`10`,width:`18`,height:`12`,rx:`2`,key:`6s8ecr`}],[`path`,{d:`M7 10V7a5 5 0 0 1 10 0v3`,key:`1pqi11`}]]),d=o(`shield-check`,[[`path`,{d:`M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z`,key:`oel41y`}],[`path`,{d:`m9 12 2 2 4-4`,key:`dzmm74`}]]),f=o(`triangle-alert`,[[`path`,{d:`m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3`,key:`wmoenq`}],[`path`,{d:`M12 9v4`,key:`juzpu7`}],[`path`,{d:`M12 17h.01`,key:`p32p05`}]]),p=r();function m(){let r=i(),o=t(a()).data??null,m=e({mutationFn:()=>s(),onSuccess:e=>{r.setQueryData(a().queryKey,e),Promise.all([r.invalidateQueries({queryKey:a().queryKey}),r.invalidateQueries({queryKey:[`antigravity-conversation`]})])}});if(!o||o.status===`unsupported`)return null;let h=o.isUnlocked,g=m.error?.message??o.error;return(0,p.jsxs)(`div`,{className:c(`flex flex-col gap-3 rounded-xl border px-4 py-3 sm:flex-row sm:items-center sm:justify-between`,h?`border-emerald-500/30 bg-emerald-500/10`:`border-[var(--border)] bg-[var(--panel)]`),children:[(0,p.jsxs)(`div`,{className:`flex min-w-0 items-start gap-3`,children:[(0,p.jsx)(`div`,{className:c(`mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-md`,h?`bg-emerald-500/15 text-emerald-600`:`bg-[var(--panel-secondary)]`),children:h?(0,p.jsx)(d,{className:`size-4`}):(0,p.jsx)(u,{className:`size-4`})}),(0,p.jsxs)(`div`,{className:`min-w-0`,children:[(0,p.jsx)(`p`,{className:`font-medium text-sm`,children:h?`Keychain access enabled`:`Unlock Antigravity transcript export`}),(0,p.jsx)(`p`,{className:`mt-1 text-[var(--muted-foreground)] text-xs`,children:h?`The Antigravity key is cached in this server process only. Transcript exports are available for local logs and safe-storage payloads.`:`Spiracha needs one-time access to ${o.keychainService} to decrypt Antigravity transcript data. macOS will ask for approval after you click unlock.`}),g?(0,p.jsxs)(`p`,{className:`mt-2 flex items-center gap-1 text-[var(--destructive)] text-xs`,children:[(0,p.jsx)(f,{className:`size-3`}),g]}):null]})]}),h?null:(0,p.jsxs)(n,{className:`shrink-0`,disabled:!o.canRequestAccess||m.isPending,type:`button`,onClick:()=>m.mutate(),children:[(0,p.jsx)(l,{className:`size-4`}),m.isPending?`Waiting...`:`Unlock`]})]})}export{u as n,m as t};
@@ -1 +0,0 @@
1
- import{c as e,n as t,o as n,r}from"./formatters-DbCKP02D.js";import{t as i}from"./useMutation-BOPJU9e0.js";import{n as a,t as o}from"./data-table-DeQq8xdt.js";import{r as s,t as c}from"./download-DLuPnxpV.js";import{a as l,i as u,n as d,r as f,t as p}from"./dropdown-menu-lFk6zjoL.js";import{n as m,t as h}from"./antigravity-keychain-panel-DnDcq1ge.js";import{t as g}from"./scroll-text-TvHyiJ_N.js";import{Bt as _,Ft as v,H as y,Lt as b,_ as x,d as S,f as C,g as w,m as T,n as E,p as D,r as O,u as k,v as A,y as j,zt as M}from"./index-C-ZPpKJ0.js";import{t as N}from"./page-header-dha_O7ZL.js";import{t as P}from"./badge-wgTVp-aq.js";import{n as F,t as I}from"./text-filter-2q5pEoZh.js";var L=_(M(),1),R=b(),z=a(),B=(e,t)=>{let n=e.artifactCount>0,r=!!t?.isUnlocked,i=A(e)||x(e),a=w(e,r),o=j(e,r),s=a||o;return{canExportConversation:a,hasArtifacts:n,hasTranscript:i,lockedTranscript:o,showActions:s||n,showConversationAction:s}},V=(e,t)=>t.hasTranscript?`${e.transcriptSource?e.transcriptSource.replace(/-/gu,` `):`transcript`} · ${t.lockedTranscript?`locked`:`available`}`:`Summary only`,H=(e,i,a)=>[z.accessor(`title`,{cell:t=>{let n=B(t.row.original,e);return(0,R.jsxs)(v,{className:`block w-[16rem] max-w-[22rem] space-y-1 rounded-md outline-none transition hover:opacity-80 focus-visible:ring-2 focus-visible:ring-[var(--accent)] lg:w-auto`,params:{conversationId:t.row.original.conversationId},to:`/antigravity-conversations/$conversationId`,children:[(0,R.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,R.jsx)(`p`,{className:`truncate font-medium underline-offset-2 hover:underline`,children:t.getValue()}),n.hasTranscript?(0,R.jsx)(P,{variant:`secondary`,children:`transcript`}):null,n.hasArtifacts?(0,R.jsx)(P,{variant:`outline`,children:`artifact`}):null]}),(0,R.jsx)(`p`,{className:`truncate text-[var(--muted-foreground)] text-xs`,children:t.row.original.conversationId})]})},header:`Conversation`}),z.accessor(`lastUpdatedAtMs`,{cell:e=>(0,R.jsx)(`span`,{className:`whitespace-nowrap text-sm`,suppressHydrationWarning:!0,children:r(e.getValue())}),header:`Updated`}),z.display({cell:t=>{let r=B(t.row.original,e);return(0,R.jsxs)(`span`,{className:`text-sm`,children:[V(t.row.original,r),t.row.original.transcriptEntryCount>0?` · ${n(t.row.original.transcriptEntryCount)} entries`:``]})},header:`Transcript`,id:`transcript`}),z.accessor(`artifactCount`,{cell:e=>(0,R.jsx)(`span`,{className:`font-mono text-sm`,children:n(e.getValue())}),header:`Artifacts`}),z.accessor(`conversationBytes`,{cell:e=>(0,R.jsx)(`span`,{className:`font-mono text-sm`,children:t(e.getValue())}),header:`Size`}),z.display({cell:t=>{let n=B(t.row.original,e);return n.showActions?(0,R.jsxs)(p,{children:[(0,R.jsx)(u,{asChild:!0,children:(0,R.jsx)(y,{className:`rounded-full`,size:`icon`,type:`button`,variant:`ghost`,onClick:e=>e.stopPropagation(),children:(0,R.jsx)(l,{className:`size-4`})})}),(0,R.jsxs)(d,{align:`end`,children:[n.showConversationAction?(0,R.jsxs)(f,{disabled:!n.canExportConversation,onClick:()=>i(t.row.original),children:[n.lockedTranscript?(0,R.jsx)(m,{className:`mr-2 size-4`}):(0,R.jsx)(s,{className:`mr-2 size-4`}),n.lockedTranscript?`Unlock conversation export first`:`Export conversation`]}):null,n.hasArtifacts?(0,R.jsxs)(f,{onClick:()=>a(t.row.original),children:[(0,R.jsx)(g,{className:`mr-2 size-4`}),`Export artifacts`]}):null]})]}):(0,R.jsx)(`span`,{className:`text-[var(--muted-foreground)] text-sm`,children:`No export`})},header:``,id:`actions`})];function U({conversations:e,decryptionState:t,onExportArtifacts:n,onExportConversation:r}){return(0,R.jsx)(o,{columns:(0,L.useMemo)(()=>H(t,r,n),[t,n,r]),data:e,emptyMessage:`No Antigravity conversations match the current workspace filter.`})}function W(){let t=E.useParams(),n=e(C()).data,r=O(n,t.workspaceKey),a=e(k(r.key)).data,o=e(S()).data??null,[s,l]=(0,L.useState)(``),u=(0,L.useDeferredValue)(s),d=i({mutationFn:e=>T({data:{conversationId:e.conversationId}}),onSuccess:e=>{c(e.filename,e.content,`text/markdown; charset=utf-8`)}}),f=i({mutationFn:e=>D({data:{conversationId:e.conversationId}}),onSuccess:e=>{c(e.filename,e.content,`text/markdown; charset=utf-8`)}}),p=a.filter(e=>I(u,[e.title,e.conversationId,e.transcriptSource,e.workspaceLabel]));return(0,R.jsxs)(`div`,{className:`space-y-6`,children:[(0,R.jsx)(N,{actions:(0,R.jsx)(F,{placeholder:`Search title, id, or transcript source`,value:s,onValueChange:l}),eyebrow:`Antigravity workspace`,subtitle:`Inspect conversation coverage across Antigravity transcripts, raw payloads, and generated artifacts.`,title:r.label}),(0,R.jsx)(h,{}),(0,R.jsx)(U,{conversations:p,decryptionState:o,onExportArtifacts:e=>f.mutate(e),onExportConversation:e=>d.mutate(e)}),d.isError?(0,R.jsx)(`p`,{className:`text-[var(--destructive)] text-sm`,children:d.error instanceof Error?d.error.message:`Conversation export failed`}):null,f.isError?(0,R.jsx)(`p`,{className:`text-[var(--destructive)] text-sm`,children:f.error instanceof Error?f.error.message:`Artifact export failed`}):null]})}export{W as component};
@@ -1 +0,0 @@
1
- import{Lt as e}from"./index-C-ZPpKJ0.js";import{t}from"./reload-error-panel-DD8M1BIY.js";var n=e();function r({error:e}){return(0,n.jsx)(t,{description:e.message,title:`Failed to load Antigravity workspace`})}export{r as errorComponent};
@@ -1 +0,0 @@
1
- import{Lt as e}from"./index-C-ZPpKJ0.js";import{t}from"./reload-error-panel-DD8M1BIY.js";var n=e();function r({error:e}){return(0,n.jsx)(t,{description:e.message,title:`Failed to load Antigravity workspaces`})}export{r as errorComponent};