spiracha 1.5.0 → 2.1.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.
- package/AGENTS.md +114 -205
- package/README.md +94 -269
- package/apps/ui/AGENTS.md +17 -7
- package/apps/ui/README.md +52 -8
- package/apps/ui/components.json +21 -0
- package/apps/ui/package.json +65 -0
- package/apps/ui/src/components/antigravity-conversations-table.tsx +245 -0
- package/apps/ui/src/components/antigravity-keychain-panel.tsx +76 -0
- package/apps/ui/src/components/antigravity-workspaces-table.tsx +63 -0
- package/apps/ui/src/components/app-shell.tsx +125 -0
- package/apps/ui/src/components/breadcrumbs.tsx +71 -0
- package/apps/ui/src/components/claude-code-sessions-table.tsx +150 -0
- package/apps/ui/src/components/claude-code-workspaces-table.tsx +57 -0
- package/apps/ui/src/components/cursor-threads-table.tsx +152 -0
- package/apps/ui/src/components/cursor-workspaces-table.tsx +140 -0
- package/apps/ui/src/components/data-table.tsx +243 -0
- package/apps/ui/src/components/delete-confirm-dialog.tsx +88 -0
- package/apps/ui/src/components/export-dialog.tsx +174 -0
- package/apps/ui/src/components/grok-sessions-table.tsx +146 -0
- package/apps/ui/src/components/grok-workspaces-table.tsx +53 -0
- package/apps/ui/src/components/json-panel.tsx +17 -0
- package/apps/ui/src/components/kiro-sessions-table.tsx +148 -0
- package/apps/ui/src/components/kiro-workspaces-table.tsx +53 -0
- package/apps/ui/src/components/list-search-input.tsx +18 -0
- package/apps/ui/src/components/loading-panel.tsx +23 -0
- package/apps/ui/src/components/metadata-section.tsx +31 -0
- package/apps/ui/src/components/metric-card.tsx +19 -0
- package/apps/ui/src/components/opencode-sessions-table.tsx +164 -0
- package/apps/ui/src/components/opencode-workspaces-table.tsx +57 -0
- package/apps/ui/src/components/page-header.tsx +39 -0
- package/apps/ui/src/components/projects-loading-state.tsx +74 -0
- package/apps/ui/src/components/projects-table.tsx +108 -0
- package/apps/ui/src/components/qoder-sessions-table.tsx +133 -0
- package/apps/ui/src/components/qoder-workspaces-table.tsx +57 -0
- package/apps/ui/src/components/recent-threads-list.tsx +52 -0
- package/apps/ui/src/components/reload-error-panel.tsx +20 -0
- package/apps/ui/src/components/selection-actions-toolbar.tsx +80 -0
- package/apps/ui/src/components/text-document-panel.tsx +19 -0
- package/apps/ui/src/components/theme-toggle.tsx +48 -0
- package/apps/ui/src/components/threads-table.tsx +165 -0
- package/apps/ui/src/components/transcript-view.tsx +648 -0
- package/apps/ui/src/components/ui/alert-dialog.tsx +160 -0
- package/apps/ui/src/components/ui/badge.tsx +45 -0
- package/apps/ui/src/components/ui/button.tsx +62 -0
- package/apps/ui/src/components/ui/checkbox.tsx +29 -0
- package/apps/ui/src/components/ui/dialog.tsx +137 -0
- package/apps/ui/src/components/ui/dropdown-menu.tsx +217 -0
- package/apps/ui/src/components/ui/input.tsx +21 -0
- package/apps/ui/src/components/ui/scroll-area.tsx +46 -0
- package/apps/ui/src/components/ui/select.tsx +163 -0
- package/apps/ui/src/components/ui/separator.tsx +28 -0
- package/apps/ui/src/components/ui/sheet.tsx +107 -0
- package/apps/ui/src/components/ui/skeleton.tsx +7 -0
- package/apps/ui/src/components/ui/table.tsx +76 -0
- package/apps/ui/src/components/ui/tabs.tsx +71 -0
- package/apps/ui/src/components/ui/tooltip.tsx +44 -0
- package/apps/ui/src/integrations/tanstack-query/devtools.tsx +6 -0
- package/apps/ui/src/integrations/tanstack-query/root-provider.tsx +10 -0
- package/apps/ui/src/lib/antigravity-conversation-state.ts +41 -0
- package/apps/ui/src/lib/antigravity-queries.ts +33 -0
- package/apps/ui/src/lib/antigravity-server.ts +273 -0
- package/apps/ui/src/lib/antigravity-transcript-events.ts +343 -0
- package/apps/ui/src/lib/claude-code-queries.ts +34 -0
- package/apps/ui/src/lib/claude-code-server.ts +243 -0
- package/apps/ui/src/lib/claude-code-transcript-events.ts +161 -0
- package/apps/ui/src/lib/codex-queries.ts +82 -0
- package/apps/ui/src/lib/codex-server.ts +291 -0
- package/apps/ui/src/lib/cursor-queries.ts +37 -0
- package/apps/ui/src/lib/cursor-server.ts +315 -0
- package/apps/ui/src/lib/cursor-transcript-events.ts +229 -0
- package/apps/ui/src/lib/download.ts +166 -0
- package/apps/ui/src/lib/formatters.ts +147 -0
- package/apps/ui/src/lib/grok-queries.ts +22 -0
- package/apps/ui/src/lib/grok-server.ts +169 -0
- package/apps/ui/src/lib/grok-transcript-events.ts +149 -0
- package/apps/ui/src/lib/kiro-queries.ts +22 -0
- package/apps/ui/src/lib/kiro-server.ts +151 -0
- package/apps/ui/src/lib/kiro-transcript-events.ts +113 -0
- package/apps/ui/src/lib/opencode-queries.ts +37 -0
- package/apps/ui/src/lib/opencode-server.ts +151 -0
- package/apps/ui/src/lib/opencode-transcript-events.ts +221 -0
- package/apps/ui/src/lib/package-metadata.ts +16 -0
- package/apps/ui/src/lib/path-utils.ts +13 -0
- package/apps/ui/src/lib/qoder-queries.ts +22 -0
- package/apps/ui/src/lib/qoder-server.ts +135 -0
- package/apps/ui/src/lib/qoder-transcript-events.ts +139 -0
- package/apps/ui/src/lib/route-search.ts +182 -0
- package/apps/ui/src/lib/settings-store.tsx +59 -0
- package/apps/ui/src/lib/source-session-export-server.ts +139 -0
- package/apps/ui/src/lib/text-filter.ts +22 -0
- package/apps/ui/src/lib/thread-id.ts +3 -0
- package/apps/ui/src/lib/thread-transcript-load.ts +15 -0
- package/apps/ui/src/lib/thread-transcript-stats.ts +57 -0
- package/apps/ui/src/lib/utils.ts +7 -0
- package/apps/ui/src/lib/workspace-delete-navigation.ts +12 -0
- package/apps/ui/src/routeTree.gen.ts +837 -0
- package/apps/ui/src/router.tsx +20 -0
- package/apps/ui/src/routes/$threadId.tsx +22 -0
- package/apps/ui/src/routes/__root.tsx +127 -0
- package/apps/ui/src/routes/analytics.tsx +143 -0
- package/apps/ui/src/routes/antigravity-conversations.$conversationId.tsx +504 -0
- package/apps/ui/src/routes/antigravity.$workspaceKey.tsx +365 -0
- package/apps/ui/src/routes/antigravity.index.tsx +51 -0
- package/apps/ui/src/routes/api.v1.conversation-query.ts +12 -0
- package/apps/ui/src/routes/api.v1.conversations.$source.$id.export.ts +12 -0
- package/apps/ui/src/routes/api.v1.conversations.$source.$id.ts +16 -0
- package/apps/ui/src/routes/api.v1.conversations.delete.ts +12 -0
- package/apps/ui/src/routes/api.v1.conversations.export.ts +12 -0
- package/apps/ui/src/routes/api.v1.conversations.ts +12 -0
- package/apps/ui/src/routes/api.v1.resolve.ts +12 -0
- package/apps/ui/src/routes/api.v1.sources.ts +12 -0
- package/apps/ui/src/routes/claude-code-sessions.$sessionId.tsx +468 -0
- package/apps/ui/src/routes/claude-code.$workspaceKey.tsx +274 -0
- package/apps/ui/src/routes/claude-code.index.tsx +48 -0
- package/apps/ui/src/routes/codex.$project.tsx +390 -0
- package/apps/ui/src/routes/codex.index.tsx +116 -0
- package/apps/ui/src/routes/cursor-threads.$composerId.tsx +435 -0
- package/apps/ui/src/routes/cursor.$workspaceKey.tsx +426 -0
- package/apps/ui/src/routes/cursor.index.tsx +120 -0
- package/apps/ui/src/routes/grok-sessions.$sessionId.tsx +388 -0
- package/apps/ui/src/routes/grok.$workspaceKey.tsx +301 -0
- package/apps/ui/src/routes/grok.index.tsx +48 -0
- package/apps/ui/src/routes/index.tsx +124 -0
- package/apps/ui/src/routes/kiro-sessions.$sessionId.tsx +396 -0
- package/apps/ui/src/routes/kiro.$workspaceKey.tsx +303 -0
- package/apps/ui/src/routes/kiro.index.tsx +48 -0
- package/apps/ui/src/routes/opencode-sessions.$sessionId.tsx +420 -0
- package/apps/ui/src/routes/opencode.$workspaceKey.tsx +327 -0
- package/apps/ui/src/routes/opencode.index.tsx +61 -0
- package/apps/ui/src/routes/qoder-sessions.$sessionId.tsx +344 -0
- package/apps/ui/src/routes/qoder.$workspaceKey.tsx +186 -0
- package/apps/ui/src/routes/qoder.index.tsx +48 -0
- package/apps/ui/src/routes/settings.tsx +91 -0
- package/apps/ui/src/routes/threads.$threadId.tsx +1103 -0
- package/apps/ui/src/styles.css +122 -0
- package/apps/ui/tsconfig.json +29 -0
- package/apps/ui/vite.config.ts +84 -0
- package/bin/spiracha.ts +32 -0
- package/package.json +54 -80
- package/src/client.ts +423 -0
- package/src/lib/antigravity-db.ts +414 -44
- package/src/lib/antigravity-exporter-types.ts +4 -0
- package/src/lib/antigravity-projects.ts +201 -0
- package/src/lib/claude-code-db.ts +498 -32
- package/src/lib/claude-code-exporter-types.ts +5 -0
- package/src/lib/claude-code-transcript-phase.ts +60 -1
- package/src/lib/claude-code-transcript.ts +8 -5
- package/src/lib/codex-analytics.ts +1 -1
- package/src/lib/codex-browser-db.ts +410 -74
- package/src/lib/codex-browser-export.ts +29 -41
- package/src/lib/codex-browser-types.ts +1 -1
- package/src/lib/codex-thread-cache.ts +41 -13
- package/src/lib/codex-thread-parser.ts +86 -35
- package/src/lib/{codex-exporter-types.ts → codex-thread-types.ts} +2 -30
- package/src/lib/codex-transcript-filter.ts +31 -0
- package/src/lib/{codex-exporter-transcript.ts → codex-transcript-renderer.ts} +104 -48
- package/src/lib/concurrency.ts +41 -0
- package/src/lib/conversation-api.ts +1172 -0
- package/src/lib/conversation-data/adapter-helpers.ts +110 -0
- package/src/lib/conversation-data/antigravity-adapter.ts +167 -0
- package/src/lib/conversation-data/claude-code-adapter.ts +206 -0
- package/src/lib/conversation-data/codex-adapter.ts +269 -0
- package/src/lib/conversation-data/cursor-adapter.ts +205 -0
- package/src/lib/conversation-data/grok-adapter.ts +210 -0
- package/src/lib/conversation-data/index.ts +386 -0
- package/src/lib/conversation-data/kiro-adapter.ts +174 -0
- package/src/lib/conversation-data/message-selector.ts +37 -0
- package/src/lib/conversation-data/opencode-adapter.ts +202 -0
- package/src/lib/conversation-data/path-match.ts +79 -0
- package/src/lib/conversation-data/qoder-adapter.ts +255 -0
- package/src/lib/conversation-data/types.ts +159 -0
- package/src/lib/conversation-zip-export.ts +57 -0
- package/src/lib/cursor-db.ts +100 -25
- package/src/lib/cursor-exporter-types.ts +0 -19
- package/src/lib/grok-db.ts +1026 -0
- package/src/lib/grok-exporter-types.ts +110 -0
- package/src/lib/grok-transcript-phase.ts +52 -0
- package/src/lib/grok-transcript.ts +154 -0
- package/src/lib/kiro-db.ts +52 -1
- package/src/lib/model-label.ts +11 -3
- package/src/lib/opencode-db.ts +598 -55
- package/src/lib/opencode-transcript.ts +8 -5
- package/src/lib/qoder-acp-client.ts +268 -0
- package/src/lib/qoder-db.ts +1601 -0
- package/src/lib/qoder-exporter-types.ts +114 -0
- package/src/lib/qoder-transcript-phase.ts +41 -0
- package/src/lib/qoder-transcript.ts +112 -0
- package/src/lib/shared.ts +12 -0
- package/src/lib/transcript-load-limiter.ts +82 -0
- package/src/lib/ui-cache.ts +43 -17
- package/src/lib/ui-export-archive.ts +60 -0
- package/apps/ui/dist/client/assets/_threadId-CAIeH5mq.js +0 -1
- package/apps/ui/dist/client/assets/analytics-DOy1b6Sh.js +0 -1
- package/apps/ui/dist/client/assets/antigravity-conversations._conversationId-DqySVO2K.js +0 -7
- package/apps/ui/dist/client/assets/antigravity-conversations._conversationId-KAcXtNxI.js +0 -1
- package/apps/ui/dist/client/assets/antigravity-keychain-panel-B77qJz6f.js +0 -1
- package/apps/ui/dist/client/assets/antigravity._workspaceKey-B3NM6gRH.js +0 -1
- package/apps/ui/dist/client/assets/antigravity._workspaceKey-ByitGWki.js +0 -1
- package/apps/ui/dist/client/assets/antigravity.index-DP9JC2P9.js +0 -1
- package/apps/ui/dist/client/assets/antigravity.index-DgW25FEV.js +0 -1
- package/apps/ui/dist/client/assets/badge-C3i4OKs8.js +0 -1
- package/apps/ui/dist/client/assets/checkbox-CdHitXWQ.js +0 -1
- package/apps/ui/dist/client/assets/claude-code-sessions._sessionId-8pQ55ci2.js +0 -1
- package/apps/ui/dist/client/assets/claude-code-sessions._sessionId-DVz5UmtU.js +0 -1
- package/apps/ui/dist/client/assets/claude-code._workspaceKey-BBKskSum.js +0 -1
- package/apps/ui/dist/client/assets/claude-code._workspaceKey-OkikMUFs.js +0 -1
- package/apps/ui/dist/client/assets/claude-code.index-Cwu76dbb.js +0 -1
- package/apps/ui/dist/client/assets/claude-code.index-D6eMd08t.js +0 -1
- package/apps/ui/dist/client/assets/createServerFn-B-KkwmHU.js +0 -3
- package/apps/ui/dist/client/assets/cursor-threads._composerId-CmBFclK8.js +0 -1
- package/apps/ui/dist/client/assets/cursor-threads._composerId-hBWlP1D-.js +0 -1
- package/apps/ui/dist/client/assets/cursor._workspaceKey-BFPkIRi-.js +0 -1
- package/apps/ui/dist/client/assets/cursor._workspaceKey-CaAZjGmm.js +0 -1
- package/apps/ui/dist/client/assets/cursor.index-8y4o20kb.js +0 -2
- package/apps/ui/dist/client/assets/cursor.index-CrnMwDCi.js +0 -1
- package/apps/ui/dist/client/assets/data-table-Br78_dk3.js +0 -4
- package/apps/ui/dist/client/assets/delete-confirm-dialog-Bxs07u-j.js +0 -7
- package/apps/ui/dist/client/assets/dist-B9pyYCVU.js +0 -1
- package/apps/ui/dist/client/assets/dist-BrJhN2A0.js +0 -5
- package/apps/ui/dist/client/assets/dist-Cmd3AIfD.js +0 -1
- package/apps/ui/dist/client/assets/dist-DvMS2965.js +0 -1
- package/apps/ui/dist/client/assets/download-Bf0QJKD3.js +0 -1
- package/apps/ui/dist/client/assets/dropdown-menu-D5cvPaZt.js +0 -1
- package/apps/ui/dist/client/assets/es2015-ad6040dw.js +0 -41
- package/apps/ui/dist/client/assets/export-dialog-Dr8d2MqD.js +0 -1
- package/apps/ui/dist/client/assets/formatters-BtqyrX_c.js +0 -1
- package/apps/ui/dist/client/assets/index-C-STgIH4.js +0 -166
- package/apps/ui/dist/client/assets/jsx-runtime-DGeXAQPT.js +0 -1
- package/apps/ui/dist/client/assets/kiro-sessions._sessionId-CKgfJ7GR.js +0 -1
- package/apps/ui/dist/client/assets/kiro-sessions._sessionId-zvIJHtQF.js +0 -1
- package/apps/ui/dist/client/assets/kiro._workspaceKey-DhVuJuZB.js +0 -1
- package/apps/ui/dist/client/assets/kiro._workspaceKey-QArsjkTY.js +0 -1
- package/apps/ui/dist/client/assets/kiro.index-C-fr4m7i.js +0 -1
- package/apps/ui/dist/client/assets/kiro.index-OYgAdtZd.js +0 -1
- package/apps/ui/dist/client/assets/metric-card-Dplm0ZiM.js +0 -1
- package/apps/ui/dist/client/assets/opencode-sessions._sessionId-DLjiTst-.js +0 -1
- package/apps/ui/dist/client/assets/opencode-sessions._sessionId-biBwrRbt.js +0 -8
- package/apps/ui/dist/client/assets/opencode._workspaceKey-C7OIzMOJ.js +0 -1
- package/apps/ui/dist/client/assets/opencode._workspaceKey-sBakX0oI.js +0 -1
- package/apps/ui/dist/client/assets/opencode.index-Bl_kNs9N.js +0 -1
- package/apps/ui/dist/client/assets/opencode.index-CN53bVmb.js +0 -1
- package/apps/ui/dist/client/assets/page-header-Cwa3p6Tl.js +0 -1
- package/apps/ui/dist/client/assets/preload-helper-B8fFrdxC.js +0 -1
- package/apps/ui/dist/client/assets/projects._project-D8WloxQN.js +0 -1
- package/apps/ui/dist/client/assets/projects._project-DSDwH4NF.js +0 -1
- package/apps/ui/dist/client/assets/projects.index-5xRtuJdX.js +0 -3
- package/apps/ui/dist/client/assets/projects.index-DEfhWqa8.js +0 -1
- package/apps/ui/dist/client/assets/react-dom-DL96Jor4.js +0 -1
- package/apps/ui/dist/client/assets/refresh-ccw-BgKjOiA6.js +0 -1
- package/apps/ui/dist/client/assets/reload-error-panel-AHqu0akK.js +0 -1
- package/apps/ui/dist/client/assets/routes-DnzF_9CX.js +0 -1
- package/apps/ui/dist/client/assets/scroll-text-fM0sMOB3.js +0 -1
- package/apps/ui/dist/client/assets/select-CYF6pF37.js +0 -1
- package/apps/ui/dist/client/assets/settings-Dx70jgP_.js +0 -1
- package/apps/ui/dist/client/assets/sqlite-error-B6uZjUe8.js +0 -1
- package/apps/ui/dist/client/assets/styles-B7Zi9EFA.css +0 -1
- package/apps/ui/dist/client/assets/tabs-CmuhkT-c.js +0 -7
- package/apps/ui/dist/client/assets/text-filter-DVAZySUS.js +0 -2
- package/apps/ui/dist/client/assets/thread-transcript-stats-BUNz6u7F.js +0 -1
- package/apps/ui/dist/client/assets/threads._threadId-BB9tTsV4.js +0 -1
- package/apps/ui/dist/client/assets/threads._threadId-BMRSFow3.js +0 -1
- package/apps/ui/dist/client/assets/useMutation-BSFult2i.js +0 -1
- package/apps/ui/dist/client/assets/useQuery-CjINKZf1.js +0 -1
- package/apps/ui/dist/server/assets/_tanstack-start-manifest_v-CQ8Jjs3B.js +0 -387
- package/apps/ui/dist/server/assets/_threadId-B6SrBR9E.js +0 -6
- package/apps/ui/dist/server/assets/analytics-CYP_LT5Y.js +0 -16
- package/apps/ui/dist/server/assets/analytics-CtpOMVMO.js +0 -146
- package/apps/ui/dist/server/assets/antigravity-conversation-state-HgzS302O.js +0 -16
- package/apps/ui/dist/server/assets/antigravity-conversations._conversationId-BKOyL2T6.js +0 -613
- package/apps/ui/dist/server/assets/antigravity-conversations._conversationId-D426O-64.js +0 -11
- package/apps/ui/dist/server/assets/antigravity-conversations._conversationId-eS87Dx7g.js +0 -20
- package/apps/ui/dist/server/assets/antigravity-db-Bh8_U9uw.js +0 -580
- package/apps/ui/dist/server/assets/antigravity-keychain-DOiuHDwK.js +0 -126
- package/apps/ui/dist/server/assets/antigravity-keychain-panel-CC7FLmAK.js +0 -55
- package/apps/ui/dist/server/assets/antigravity-queries-CGrJO9Vr.js +0 -37
- package/apps/ui/dist/server/assets/antigravity-server-CHRjVFqN.js +0 -114
- package/apps/ui/dist/server/assets/antigravity._workspaceKey-3m_MzNFA.js +0 -11
- package/apps/ui/dist/server/assets/antigravity._workspaceKey-B0QeYUOh.js +0 -28
- package/apps/ui/dist/server/assets/antigravity._workspaceKey-C3kP-qyN.js +0 -210
- package/apps/ui/dist/server/assets/antigravity.index-CPCYkqCi.js +0 -104
- package/apps/ui/dist/server/assets/antigravity.index-DudTB3Tq.js +0 -11
- package/apps/ui/dist/server/assets/badge-EvdhKK_Z.js +0 -26
- package/apps/ui/dist/server/assets/button-CmTDnzOn.js +0 -46
- package/apps/ui/dist/server/assets/checkbox-C0hovF41.js +0 -19
- package/apps/ui/dist/server/assets/claude-code-db-Ik3VStKZ.js +0 -361
- package/apps/ui/dist/server/assets/claude-code-queries-Cgzi4K-e.js +0 -37
- package/apps/ui/dist/server/assets/claude-code-server-PfraClXS.js +0 -72
- package/apps/ui/dist/server/assets/claude-code-sessions._sessionId-C55oe6zj.js +0 -18
- package/apps/ui/dist/server/assets/claude-code-sessions._sessionId-D1RYYi3j.js +0 -473
- package/apps/ui/dist/server/assets/claude-code-sessions._sessionId-DSvPLEUL.js +0 -11
- package/apps/ui/dist/server/assets/claude-code-transcript-C-bxh3cS.js +0 -139
- package/apps/ui/dist/server/assets/claude-code-transcript-phase-DmUMc8VU.js +0 -10
- package/apps/ui/dist/server/assets/claude-code._workspaceKey-B5Xg_-tE.js +0 -28
- package/apps/ui/dist/server/assets/claude-code._workspaceKey-BPlzyXPa.js +0 -11
- package/apps/ui/dist/server/assets/claude-code._workspaceKey-DqDve2wl.js +0 -191
- package/apps/ui/dist/server/assets/claude-code.index-B7yYR7dD.js +0 -92
- package/apps/ui/dist/server/assets/claude-code.index-BUHThG1W.js +0 -11
- package/apps/ui/dist/server/assets/codex-queries-CtgeZ7VL.js +0 -99
- package/apps/ui/dist/server/assets/codex-server-CGXU4H8-.js +0 -2294
- package/apps/ui/dist/server/assets/concurrency-VXtYvlGh.js +0 -18
- package/apps/ui/dist/server/assets/createServerRpc-CF_DEwnm.js +0 -12
- package/apps/ui/dist/server/assets/createSsrRpc-C754NPki.js +0 -16
- package/apps/ui/dist/server/assets/cursor-db-CZnYy7aT.js +0 -830
- package/apps/ui/dist/server/assets/cursor-exporter-types-CI3goo-c.js +0 -34
- package/apps/ui/dist/server/assets/cursor-queries-NCIM0Nat.js +0 -67
- package/apps/ui/dist/server/assets/cursor-recovery-CXpO8KcD.js +0 -361
- package/apps/ui/dist/server/assets/cursor-server-DNu52A3K.js +0 -213
- package/apps/ui/dist/server/assets/cursor-threads._composerId-BB0Y_Mao.js +0 -11
- package/apps/ui/dist/server/assets/cursor-threads._composerId-Ckn6ItHI.js +0 -582
- package/apps/ui/dist/server/assets/cursor-threads._composerId-p9-ARAzc.js +0 -18
- package/apps/ui/dist/server/assets/cursor-transcript-B7tGnqtn.js +0 -125
- package/apps/ui/dist/server/assets/cursor._workspaceKey-CZuohIUL.js +0 -28
- package/apps/ui/dist/server/assets/cursor._workspaceKey-DPp5JSjy.js +0 -401
- package/apps/ui/dist/server/assets/cursor._workspaceKey-nmg3YIOQ.js +0 -11
- package/apps/ui/dist/server/assets/cursor.index-CcsX7DG0.js +0 -11
- package/apps/ui/dist/server/assets/cursor.index-DkWT-mxw.js +0 -189
- package/apps/ui/dist/server/assets/data-table-Cdct823O.js +0 -189
- package/apps/ui/dist/server/assets/delete-confirm-dialog-BcBNCxWB.js +0 -144
- package/apps/ui/dist/server/assets/download-DMmiy1xf.js +0 -92
- package/apps/ui/dist/server/assets/dropdown-menu-Dy_9t6TN.js +0 -36
- package/apps/ui/dist/server/assets/empty-plugin-adapters-B3lHh1La.js +0 -5
- package/apps/ui/dist/server/assets/export-dialog-D88ze9Gy.js +0 -240
- package/apps/ui/dist/server/assets/formatters-FJaGZgJk.js +0 -91
- package/apps/ui/dist/server/assets/kiro-db--fXrED_-.js +0 -552
- package/apps/ui/dist/server/assets/kiro-queries-CzNlM2ok.js +0 -37
- package/apps/ui/dist/server/assets/kiro-server-9WRxg2Au.js +0 -72
- package/apps/ui/dist/server/assets/kiro-sessions._sessionId-CRY2c7YO.js +0 -11
- package/apps/ui/dist/server/assets/kiro-sessions._sessionId-F1UlwxmR.js +0 -449
- package/apps/ui/dist/server/assets/kiro-sessions._sessionId-bvTulT7C.js +0 -18
- package/apps/ui/dist/server/assets/kiro-transcript-DoekQBaH.js +0 -112
- package/apps/ui/dist/server/assets/kiro-transcript-phase-CJG40nQg.js +0 -27
- package/apps/ui/dist/server/assets/kiro._workspaceKey-BDe9sQwo.js +0 -11
- package/apps/ui/dist/server/assets/kiro._workspaceKey-CJsjgNwO.js +0 -28
- package/apps/ui/dist/server/assets/kiro._workspaceKey-D_-4Qb7y.js +0 -193
- package/apps/ui/dist/server/assets/kiro.index-C__-UROk.js +0 -11
- package/apps/ui/dist/server/assets/kiro.index-CmTbqeYj.js +0 -93
- package/apps/ui/dist/server/assets/loading-panel-BGFnWseS.js +0 -27
- package/apps/ui/dist/server/assets/metric-card-ByEeLu0r.js +0 -23
- package/apps/ui/dist/server/assets/model-label-B1NWGc65.js +0 -13
- package/apps/ui/dist/server/assets/opencode-db-BM7KjOzc.js +0 -397
- package/apps/ui/dist/server/assets/opencode-queries-BeNYXnQv.js +0 -50
- package/apps/ui/dist/server/assets/opencode-server-BpQ_kRze.js +0 -72
- package/apps/ui/dist/server/assets/opencode-sessions._sessionId-CGQ-t0vD.js +0 -518
- package/apps/ui/dist/server/assets/opencode-sessions._sessionId-D8Q7in_Z.js +0 -18
- package/apps/ui/dist/server/assets/opencode-sessions._sessionId-DKOvi0lV.js +0 -11
- package/apps/ui/dist/server/assets/opencode-think-tags-CAoD-EcZ.js +0 -87
- package/apps/ui/dist/server/assets/opencode-transcript-BNTcGNym.js +0 -141
- package/apps/ui/dist/server/assets/opencode-transcript-phase-OqLkiQD0.js +0 -32
- package/apps/ui/dist/server/assets/opencode._workspaceKey-BdqcWHw1.js +0 -11
- package/apps/ui/dist/server/assets/opencode._workspaceKey-CfH96HTT.js +0 -28
- package/apps/ui/dist/server/assets/opencode._workspaceKey-DdbHPDrO.js +0 -207
- package/apps/ui/dist/server/assets/opencode.index-BbVzkJXP.js +0 -11
- package/apps/ui/dist/server/assets/opencode.index-Vh_Gq_1L.js +0 -93
- package/apps/ui/dist/server/assets/page-header-VNSaM3xd.js +0 -29
- package/apps/ui/dist/server/assets/path-transforms-DL2IwtYd.js +0 -31
- package/apps/ui/dist/server/assets/projects._project-4io5LO0E.js +0 -20
- package/apps/ui/dist/server/assets/projects._project-Bshqk7JA.js +0 -12
- package/apps/ui/dist/server/assets/projects._project-D6ZoGhJ8.js +0 -395
- package/apps/ui/dist/server/assets/projects.index-BLXOx5eL.js +0 -12
- package/apps/ui/dist/server/assets/projects.index-BkLiF2FF.js +0 -182
- package/apps/ui/dist/server/assets/projects.index-DesYXwfi.js +0 -14
- package/apps/ui/dist/server/assets/reload-error-panel-BJMxY3U1.js +0 -25
- package/apps/ui/dist/server/assets/route-search-ts4W9MJ9.js +0 -38
- package/apps/ui/dist/server/assets/router-Sac2DGk6.js +0 -518
- package/apps/ui/dist/server/assets/routes-Bsact1uB.js +0 -184
- package/apps/ui/dist/server/assets/routes-BzkJgq4W.js +0 -34
- package/apps/ui/dist/server/assets/select-GW76p-ld.js +0 -76
- package/apps/ui/dist/server/assets/settings-OayxIYQQ.js +0 -100
- package/apps/ui/dist/server/assets/settings-store-DpEJEQ7M.js +0 -52
- package/apps/ui/dist/server/assets/shared-DyhChtHf.js +0 -137
- package/apps/ui/dist/server/assets/source-session-export-server-DNutCawb.js +0 -38
- package/apps/ui/dist/server/assets/sqlite-error-LZDrnxdd.js +0 -13
- package/apps/ui/dist/server/assets/start-B_HFwkkk.js +0 -4
- package/apps/ui/dist/server/assets/tabs-DkaChNVg.js +0 -501
- package/apps/ui/dist/server/assets/text-filter-CGKxMCKt.js +0 -36
- package/apps/ui/dist/server/assets/thread-transcript-stats-Dh34mt2u.js +0 -45
- package/apps/ui/dist/server/assets/threads._threadId-BSSK4nkI.js +0 -26
- package/apps/ui/dist/server/assets/threads._threadId-BeXEc4Lo.js +0 -648
- package/apps/ui/dist/server/assets/threads._threadId-Ci0S4mKU.js +0 -18
- package/apps/ui/dist/server/assets/ui-export-files-BHLX9bhN.js +0 -83
- package/apps/ui/dist/server/assets/utils-C_uf36nf.js +0 -8
- package/apps/ui/dist/server/server.js +0 -5895
- package/bin/codex-chats-claude.js +0 -5
- package/bin/codex-chats.js +0 -5
- package/bin/spiracha.js +0 -5
- package/src/export-chats.ts +0 -120
- package/src/export-claude.ts +0 -36
- package/src/export-cursor.ts +0 -244
- package/src/lib/claude-exporter.ts +0 -864
- package/src/lib/codex-exporter-cli.ts +0 -277
- package/src/lib/codex-exporter-db.ts +0 -319
- package/src/lib/codex-exporter.ts +0 -115
- package/src/lib/cursor-exporter.ts +0 -266
- package/src/lib/interactive-cli.ts +0 -433
- package/src/lib/native-open.ts +0 -54
- package/src/mcp-server.ts +0 -137
- package/src/spiracha.ts +0 -116
- package/src/ui-cli.ts +0 -310
- /package/apps/ui/{dist/client → public}/icon.svg +0 -0
- /package/apps/ui/{dist/client → public}/manifest.json +0 -0
- /package/apps/ui/{dist/client → public}/robots.txt +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readdir, stat } from 'node:fs/promises';
|
|
1
|
+
import { readdir, rm, stat } from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import {
|
|
4
4
|
type AntigravityArtifact,
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
resolveAntigravityRoots,
|
|
12
12
|
} from './antigravity-exporter-types';
|
|
13
13
|
import { decryptAntigravitySafeStoragePayload } from './antigravity-keychain';
|
|
14
|
+
import { resolveAntigravityProjectNames } from './antigravity-projects';
|
|
14
15
|
import { mapWithConcurrency } from './concurrency';
|
|
15
16
|
|
|
16
17
|
type ProtoField = {
|
|
@@ -25,6 +26,7 @@ type SummaryEntry = {
|
|
|
25
26
|
createdAtMs: number | null;
|
|
26
27
|
indexedItemCount: number | null;
|
|
27
28
|
lastUpdatedAtMs: number | null;
|
|
29
|
+
projectId: string | null;
|
|
28
30
|
summaryPath: string;
|
|
29
31
|
title: string;
|
|
30
32
|
workspaceFolder: string | null;
|
|
@@ -33,6 +35,11 @@ type SummaryEntry = {
|
|
|
33
35
|
workspaceUri: string | null;
|
|
34
36
|
};
|
|
35
37
|
|
|
38
|
+
export type DeleteAntigravityConversationResult = {
|
|
39
|
+
deletedConversationIds: string[];
|
|
40
|
+
deletedPaths: string[];
|
|
41
|
+
};
|
|
42
|
+
|
|
36
43
|
type ConversationFile = {
|
|
37
44
|
bytes: number;
|
|
38
45
|
mtimeMs: number;
|
|
@@ -49,11 +56,21 @@ type TranscriptFile = {
|
|
|
49
56
|
bytes: number;
|
|
50
57
|
entryCount: number;
|
|
51
58
|
mtimeMs: number;
|
|
59
|
+
model: string | null;
|
|
52
60
|
path: string;
|
|
53
61
|
root: string;
|
|
54
62
|
source: Exclude<AntigravityTranscriptSource, 'safe-storage'>;
|
|
55
63
|
};
|
|
56
64
|
|
|
65
|
+
export type AntigravityConversationMessage = {
|
|
66
|
+
createdAtMs: number | null;
|
|
67
|
+
metadata: Record<string, unknown>;
|
|
68
|
+
order: number;
|
|
69
|
+
phase: 'final_answer' | 'reasoning' | 'tool_call' | 'tool_output' | 'unknown';
|
|
70
|
+
role: 'assistant' | 'system' | 'tool' | 'unknown' | 'user';
|
|
71
|
+
text: string;
|
|
72
|
+
};
|
|
73
|
+
|
|
57
74
|
type WorkspaceInfo = Pick<SummaryEntry, 'workspaceFolder' | 'workspaceKey' | 'workspaceLabel' | 'workspaceUri'>;
|
|
58
75
|
|
|
59
76
|
const UNKNOWN_WORKSPACE: WorkspaceInfo = {
|
|
@@ -260,8 +277,8 @@ const parseContextWorkspaceInfo = (field: ProtoField | null): WorkspaceInfo | nu
|
|
|
260
277
|
// Antigravity summary parsing is reverse-engineered from agyhub_summaries_proto.pb:
|
|
261
278
|
// entry field 1 = conversation id, entry field 2 = summary message. Inside that summary,
|
|
262
279
|
// field 1 = title, 2 = indexed item count, 3 = last-updated timestamp, 7 = created timestamp,
|
|
263
|
-
// 9 = workspace info, and 17 = context
|
|
264
|
-
//
|
|
280
|
+
// 9 = workspace info, and 17 = context metadata. Context field 18 is the Antigravity
|
|
281
|
+
// project id; workspace parsing uses context field 7 or nested workspace field 1.
|
|
265
282
|
const parseSummaryEntry = (entryField: ProtoField, summaryPath: string): SummaryEntry | null => {
|
|
266
283
|
try {
|
|
267
284
|
const entryFields = nestedFields(entryField);
|
|
@@ -272,6 +289,7 @@ const parseSummaryEntry = (entryField: ProtoField, summaryPath: string): Summary
|
|
|
272
289
|
}
|
|
273
290
|
|
|
274
291
|
const summaryFields = nestedFields(summaryBytes);
|
|
292
|
+
const contextFields = nestedFields(firstField(summaryFields, 17));
|
|
275
293
|
const workspace =
|
|
276
294
|
parseWorkspaceInfo(firstField(summaryFields, 9)) ??
|
|
277
295
|
parseContextWorkspaceInfo(firstField(summaryFields, 17)) ??
|
|
@@ -283,6 +301,7 @@ const parseSummaryEntry = (entryField: ProtoField, summaryPath: string): Summary
|
|
|
283
301
|
createdAtMs: parseTimestampMs(firstField(summaryFields, 7)),
|
|
284
302
|
indexedItemCount: fieldNumberValue(summaryFields, 2),
|
|
285
303
|
lastUpdatedAtMs: parseTimestampMs(firstField(summaryFields, 3)),
|
|
304
|
+
projectId: fieldString(contextFields, 18),
|
|
286
305
|
summaryPath,
|
|
287
306
|
title: cleanTitle(fieldString(summaryFields, 1), conversationId),
|
|
288
307
|
};
|
|
@@ -307,6 +326,84 @@ export const readAntigravitySummaryIndex = async (summaryPath: string): Promise<
|
|
|
307
326
|
}
|
|
308
327
|
};
|
|
309
328
|
|
|
329
|
+
const getFieldBounds = (
|
|
330
|
+
buffer: Uint8Array,
|
|
331
|
+
start: number,
|
|
332
|
+
): {
|
|
333
|
+
end: number;
|
|
334
|
+
fieldNumber: number;
|
|
335
|
+
payloadEnd: number;
|
|
336
|
+
payloadStart: number;
|
|
337
|
+
wireType: number;
|
|
338
|
+
} => {
|
|
339
|
+
const key = readVarint(buffer, start, buffer.length);
|
|
340
|
+
const fieldNumber = key.value >> 3;
|
|
341
|
+
const wireType = key.value & 7;
|
|
342
|
+
let index = key.next;
|
|
343
|
+
|
|
344
|
+
if (wireType === 0) {
|
|
345
|
+
const value = readVarint(buffer, index, buffer.length);
|
|
346
|
+
return { end: value.next, fieldNumber, payloadEnd: value.next, payloadStart: index, wireType };
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
if (wireType === 1) {
|
|
350
|
+
return { end: index + 8, fieldNumber, payloadEnd: index + 8, payloadStart: index, wireType };
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
if (wireType === 2) {
|
|
354
|
+
const length = readVarint(buffer, index, buffer.length);
|
|
355
|
+
index = length.next;
|
|
356
|
+
return {
|
|
357
|
+
end: index + length.value,
|
|
358
|
+
fieldNumber,
|
|
359
|
+
payloadEnd: index + length.value,
|
|
360
|
+
payloadStart: index,
|
|
361
|
+
wireType,
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if (wireType === 5) {
|
|
366
|
+
return { end: index + 4, fieldNumber, payloadEnd: index + 4, payloadStart: index, wireType };
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
throw new Error(`Unsupported protobuf wire type: ${wireType}`);
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
const removeConversationFromSummaryIndex = async (summaryPath: string, conversationId: string): Promise<boolean> => {
|
|
373
|
+
if (!(await pathExists(summaryPath))) {
|
|
374
|
+
return false;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
const buffer = new Uint8Array(await Bun.file(summaryPath).arrayBuffer());
|
|
378
|
+
const retained: Uint8Array[] = [];
|
|
379
|
+
let removed = false;
|
|
380
|
+
let index = 0;
|
|
381
|
+
|
|
382
|
+
while (index < buffer.length) {
|
|
383
|
+
const bounds = getFieldBounds(buffer, index);
|
|
384
|
+
const fieldBytes = buffer.slice(index, bounds.end);
|
|
385
|
+
const shouldRemove =
|
|
386
|
+
bounds.fieldNumber === 1 &&
|
|
387
|
+
bounds.wireType === 2 &&
|
|
388
|
+
fieldString(parseProtoFields(buffer, bounds.payloadStart, bounds.payloadEnd), 1) === conversationId;
|
|
389
|
+
|
|
390
|
+
if (shouldRemove) {
|
|
391
|
+
removed = true;
|
|
392
|
+
} else {
|
|
393
|
+
retained.push(fieldBytes);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
index = bounds.end;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
if (!removed) {
|
|
400
|
+
return false;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
await Bun.write(summaryPath, Buffer.concat(retained));
|
|
404
|
+
return true;
|
|
405
|
+
};
|
|
406
|
+
|
|
310
407
|
const preferConversationFile = (
|
|
311
408
|
current: ConversationFile | undefined,
|
|
312
409
|
candidate: ConversationFile,
|
|
@@ -489,20 +586,91 @@ const countJsonlEntries = async (filePath: string): Promise<number> => {
|
|
|
489
586
|
}
|
|
490
587
|
};
|
|
491
588
|
|
|
589
|
+
const stripModelQualifier = (value: string): string => value.replace(/\s*\([^)]*\)\s*$/u, '').trim();
|
|
590
|
+
|
|
591
|
+
const extractModelSelection = (content: string): string | null => {
|
|
592
|
+
const marker = '`Model Selection`';
|
|
593
|
+
const markerIndex = content.indexOf(marker);
|
|
594
|
+
if (markerIndex < 0) {
|
|
595
|
+
return null;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
const toIndex = content.indexOf(' to ', markerIndex + marker.length);
|
|
599
|
+
if (toIndex < 0) {
|
|
600
|
+
return null;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
const candidate = content.slice(toIndex + ' to '.length);
|
|
604
|
+
const endMarkers = ['. No need', '. If reporting', '</USER_SETTINGS_CHANGE>', '\n'];
|
|
605
|
+
const endIndex = endMarkers.reduce<number | null>((earliest, endMarker) => {
|
|
606
|
+
const index = candidate.indexOf(endMarker);
|
|
607
|
+
return index < 0 || (earliest !== null && index >= earliest) ? earliest : index;
|
|
608
|
+
}, null);
|
|
609
|
+
const rawModel = (endIndex === null ? candidate : candidate.slice(0, endIndex)).trim();
|
|
610
|
+
return rawModel ? stripModelQualifier(rawModel) : null;
|
|
611
|
+
};
|
|
612
|
+
|
|
613
|
+
const extractTranscriptModel = async (filePath: string): Promise<string | null> => {
|
|
614
|
+
const text = await Bun.file(filePath)
|
|
615
|
+
.text()
|
|
616
|
+
.catch(() => '');
|
|
617
|
+
for (const entry of parseLogEntries(text)) {
|
|
618
|
+
const model = extractModelSelection(getString(entry.content) ?? '');
|
|
619
|
+
if (model) {
|
|
620
|
+
return model;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
return null;
|
|
625
|
+
};
|
|
626
|
+
|
|
492
627
|
const preferTranscriptFile = (current: TranscriptFile | undefined, candidate: TranscriptFile): TranscriptFile => {
|
|
493
628
|
if (!current) {
|
|
494
629
|
return candidate;
|
|
495
630
|
}
|
|
496
631
|
|
|
632
|
+
const sourceRank = (source: TranscriptFile['source']) => (source === 'transcript' ? 2 : 1);
|
|
633
|
+
const candidateRank = sourceRank(candidate.source);
|
|
634
|
+
const currentRank = sourceRank(current.source);
|
|
635
|
+
if (candidateRank !== currentRank) {
|
|
636
|
+
return candidateRank > currentRank ? candidate : current;
|
|
637
|
+
}
|
|
638
|
+
|
|
497
639
|
if (candidate.mtimeMs !== current.mtimeMs) {
|
|
498
640
|
return candidate.mtimeMs > current.mtimeMs ? candidate : current;
|
|
499
641
|
}
|
|
500
642
|
|
|
501
|
-
if (candidate.
|
|
502
|
-
return candidate.
|
|
643
|
+
if (candidate.entryCount !== current.entryCount) {
|
|
644
|
+
return candidate.entryCount > current.entryCount ? candidate : current;
|
|
503
645
|
}
|
|
504
646
|
|
|
505
|
-
return candidate.
|
|
647
|
+
return candidate.bytes > current.bytes ? candidate : current;
|
|
648
|
+
};
|
|
649
|
+
|
|
650
|
+
const readTranscriptFileCandidate = async (
|
|
651
|
+
root: string,
|
|
652
|
+
logsDir: string,
|
|
653
|
+
candidate: { name: string; source: TranscriptFile['source'] },
|
|
654
|
+
): Promise<TranscriptFile | null> => {
|
|
655
|
+
const transcriptPath = path.join(logsDir, candidate.name);
|
|
656
|
+
try {
|
|
657
|
+
const info = await stat(transcriptPath);
|
|
658
|
+
if (!info.isFile()) {
|
|
659
|
+
return null;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
return {
|
|
663
|
+
bytes: info.size,
|
|
664
|
+
entryCount: await countJsonlEntries(transcriptPath),
|
|
665
|
+
model: await extractTranscriptModel(transcriptPath),
|
|
666
|
+
mtimeMs: info.mtimeMs,
|
|
667
|
+
path: transcriptPath,
|
|
668
|
+
root,
|
|
669
|
+
source: candidate.source,
|
|
670
|
+
};
|
|
671
|
+
} catch {
|
|
672
|
+
return null;
|
|
673
|
+
}
|
|
506
674
|
};
|
|
507
675
|
|
|
508
676
|
const readTranscriptFilesForRoot = async (root: string): Promise<Map<string, TranscriptFile>> => {
|
|
@@ -522,28 +690,14 @@ const readTranscriptFilesForRoot = async (root: string): Promise<Map<string, Tra
|
|
|
522
690
|
|
|
523
691
|
const logsDir = path.join(brainDir, entry.name, '.system_generated', 'logs');
|
|
524
692
|
for (const candidate of [
|
|
525
|
-
{ name: '
|
|
693
|
+
{ name: 'transcript_full.jsonl', source: 'transcript' as const },
|
|
526
694
|
{ name: 'transcript.jsonl', source: 'transcript' as const },
|
|
695
|
+
{ name: 'overview.txt', source: 'overview' as const },
|
|
527
696
|
]) {
|
|
528
|
-
const
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
continue;
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
transcripts.set(
|
|
536
|
-
entry.name,
|
|
537
|
-
preferTranscriptFile(transcripts.get(entry.name), {
|
|
538
|
-
bytes: info.size,
|
|
539
|
-
entryCount: await countJsonlEntries(transcriptPath),
|
|
540
|
-
mtimeMs: info.mtimeMs,
|
|
541
|
-
path: transcriptPath,
|
|
542
|
-
root,
|
|
543
|
-
source: candidate.source,
|
|
544
|
-
}),
|
|
545
|
-
);
|
|
546
|
-
} catch {}
|
|
697
|
+
const transcript = await readTranscriptFileCandidate(root, logsDir, candidate);
|
|
698
|
+
if (transcript) {
|
|
699
|
+
transcripts.set(entry.name, preferTranscriptFile(transcripts.get(entry.name), transcript));
|
|
700
|
+
}
|
|
547
701
|
}
|
|
548
702
|
}
|
|
549
703
|
|
|
@@ -625,6 +779,8 @@ const toConversation = (
|
|
|
625
779
|
): AntigravityConversation => {
|
|
626
780
|
const fallbackTitle = artifacts[0]?.summary ?? conversationId;
|
|
627
781
|
const artifactBytes = artifacts.reduce((total, artifact) => total + artifact.bytes, 0);
|
|
782
|
+
const conversationBytes = file?.bytes ?? 0;
|
|
783
|
+
const transcriptBytes = transcript?.bytes ?? 0;
|
|
628
784
|
const workspace = resolveConversationWorkspace(summary, file, transcript, artifacts);
|
|
629
785
|
const lastUpdatedAtMs = resolveConversationLastUpdatedAt(artifacts, file, summary, transcript);
|
|
630
786
|
const sourceRoot = resolveConversationSourceRoot(file, transcript, artifacts);
|
|
@@ -633,17 +789,20 @@ const toConversation = (
|
|
|
633
789
|
artifactBytes,
|
|
634
790
|
artifactCount: artifacts.length,
|
|
635
791
|
artifacts,
|
|
636
|
-
conversationBytes
|
|
792
|
+
conversationBytes,
|
|
637
793
|
conversationId,
|
|
638
794
|
conversationMtimeMs: file?.mtimeMs ?? null,
|
|
639
795
|
conversationPath: file?.path ?? null,
|
|
640
796
|
createdAtMs: summary?.createdAtMs ?? null,
|
|
641
797
|
indexedItemCount: summary?.indexedItemCount ?? null,
|
|
642
798
|
lastUpdatedAtMs,
|
|
799
|
+
model: transcript?.model ?? null,
|
|
800
|
+
projectId: summary?.projectId ?? null,
|
|
643
801
|
sourceRoot,
|
|
644
802
|
summaryPath: summary?.summaryPath ?? null,
|
|
645
803
|
title: summary?.title ?? cleanTitle(fallbackTitle, conversationId),
|
|
646
|
-
|
|
804
|
+
totalBytes: conversationBytes + transcriptBytes + artifactBytes,
|
|
805
|
+
transcriptBytes,
|
|
647
806
|
transcriptEntryCount: transcript?.entryCount ?? 0,
|
|
648
807
|
transcriptPath: transcript?.path ?? null,
|
|
649
808
|
transcriptSource: resolveConversationTranscriptSource(file, transcript),
|
|
@@ -685,25 +844,30 @@ export const listAntigravityConversations = async (
|
|
|
685
844
|
|
|
686
845
|
export const groupAntigravityConversations = (
|
|
687
846
|
conversations: AntigravityConversation[],
|
|
847
|
+
projectNames: ReadonlyMap<string, string> = new Map(),
|
|
688
848
|
): AntigravityWorkspaceGroup[] => {
|
|
689
849
|
const groups = new Map<string, AntigravityWorkspaceGroup>();
|
|
690
850
|
for (const conversation of conversations) {
|
|
691
|
-
const
|
|
851
|
+
const projectName = conversation.projectId ? projectNames.get(conversation.projectId) : null;
|
|
852
|
+
const groupKey = conversation.projectId ? `project:${conversation.projectId}` : conversation.workspaceKey;
|
|
853
|
+
const current = groups.get(groupKey) ?? {
|
|
692
854
|
artifactCount: 0,
|
|
693
855
|
conversationBytes: 0,
|
|
694
856
|
conversationCount: 0,
|
|
695
|
-
key:
|
|
696
|
-
label: conversation.workspaceLabel,
|
|
857
|
+
key: groupKey,
|
|
858
|
+
label: projectName ?? conversation.workspaceLabel,
|
|
697
859
|
lastActiveMs: 0,
|
|
860
|
+
totalBytes: 0,
|
|
698
861
|
transcriptCount: 0,
|
|
699
|
-
uri: conversation.workspaceUri,
|
|
862
|
+
uri: conversation.projectId ? null : conversation.workspaceUri,
|
|
700
863
|
};
|
|
701
864
|
current.artifactCount += conversation.artifactCount;
|
|
702
865
|
current.conversationBytes += conversation.conversationBytes;
|
|
703
866
|
current.conversationCount += 1;
|
|
704
867
|
current.lastActiveMs = Math.max(current.lastActiveMs, conversation.lastUpdatedAtMs ?? 0);
|
|
705
868
|
current.transcriptCount += conversation.transcriptEntryCount > 0 ? 1 : 0;
|
|
706
|
-
|
|
869
|
+
current.totalBytes += conversation.totalBytes;
|
|
870
|
+
groups.set(groupKey, current);
|
|
707
871
|
}
|
|
708
872
|
|
|
709
873
|
return [...groups.values()].sort((a, b) => b.lastActiveMs - a.lastActiveMs || a.label.localeCompare(b.label));
|
|
@@ -712,16 +876,67 @@ export const groupAntigravityConversations = (
|
|
|
712
876
|
export const listAntigravityWorkspaceGroups = async (
|
|
713
877
|
roots = resolveAntigravityRoots(),
|
|
714
878
|
): Promise<AntigravityWorkspaceGroup[]> => {
|
|
715
|
-
|
|
879
|
+
const conversations = await listAntigravityConversations(roots);
|
|
880
|
+
const projectNames = await resolveAntigravityProjectNames(
|
|
881
|
+
conversations.flatMap((conversation) => (conversation.projectId ? [conversation.projectId] : [])),
|
|
882
|
+
);
|
|
883
|
+
return groupAntigravityConversations(conversations, projectNames);
|
|
716
884
|
};
|
|
717
885
|
|
|
718
886
|
export const listAntigravityConversationsForGroup = async (
|
|
719
887
|
workspaceKey: string,
|
|
720
888
|
roots = resolveAntigravityRoots(),
|
|
721
889
|
): Promise<AntigravityConversation[]> => {
|
|
722
|
-
return (await listAntigravityConversations(roots)).filter(
|
|
723
|
-
|
|
724
|
-
|
|
890
|
+
return (await listAntigravityConversations(roots)).filter((conversation) => {
|
|
891
|
+
const conversationGroupKey = conversation.projectId
|
|
892
|
+
? `project:${conversation.projectId}`
|
|
893
|
+
: conversation.workspaceKey;
|
|
894
|
+
return conversationGroupKey === workspaceKey;
|
|
895
|
+
});
|
|
896
|
+
};
|
|
897
|
+
|
|
898
|
+
const existingAntigravityDeletePaths = async (root: string, conversationId: string): Promise<string[]> => {
|
|
899
|
+
const conversationPath = path.join(getAntigravityConversationDir(root), `${conversationId}.pb`);
|
|
900
|
+
const artifactDir = path.join(getAntigravityBrainDir(root), conversationId);
|
|
901
|
+
const logsDir = path.join(artifactDir, '.system_generated', 'logs');
|
|
902
|
+
const candidates = [
|
|
903
|
+
conversationPath,
|
|
904
|
+
path.join(logsDir, 'overview.txt'),
|
|
905
|
+
path.join(logsDir, 'transcript.jsonl'),
|
|
906
|
+
path.join(logsDir, 'transcript_full.jsonl'),
|
|
907
|
+
artifactDir,
|
|
908
|
+
];
|
|
909
|
+
const exists = await Promise.all(candidates.map(pathExists));
|
|
910
|
+
return candidates.filter((_, index) => exists[index]);
|
|
911
|
+
};
|
|
912
|
+
|
|
913
|
+
export const deleteAntigravityConversation = async (
|
|
914
|
+
roots: string[],
|
|
915
|
+
conversationId: string,
|
|
916
|
+
): Promise<DeleteAntigravityConversationResult> => {
|
|
917
|
+
if (!isSafeConversationId(conversationId)) {
|
|
918
|
+
return { deletedConversationIds: [], deletedPaths: [] };
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
const deletedPaths: string[] = [];
|
|
922
|
+
let deletedSummary = false;
|
|
923
|
+
|
|
924
|
+
for (const root of roots) {
|
|
925
|
+
deletedSummary =
|
|
926
|
+
(await removeConversationFromSummaryIndex(getAntigravitySummaryIndexPath(root), conversationId)) ||
|
|
927
|
+
deletedSummary;
|
|
928
|
+
|
|
929
|
+
const rootPaths = await existingAntigravityDeletePaths(root, conversationId);
|
|
930
|
+
deletedPaths.push(...rootPaths);
|
|
931
|
+
|
|
932
|
+
await rm(path.join(getAntigravityConversationDir(root), `${conversationId}.pb`), { force: true });
|
|
933
|
+
await rm(path.join(getAntigravityBrainDir(root), conversationId), { force: true, recursive: true });
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
return {
|
|
937
|
+
deletedConversationIds: deletedSummary || deletedPaths.length > 0 ? [conversationId] : [],
|
|
938
|
+
deletedPaths: [...new Set(deletedPaths)],
|
|
939
|
+
};
|
|
725
940
|
};
|
|
726
941
|
|
|
727
942
|
export const renderAntigravityArtifactsMarkdown = async (
|
|
@@ -853,7 +1068,7 @@ const renderLogEntry = (entry: AntigravityLogEntry): string[] => {
|
|
|
853
1068
|
const heading = logEntryHeading(entry);
|
|
854
1069
|
const timestamp = getString(entry.created_at);
|
|
855
1070
|
const content = cleanLogContent(entry);
|
|
856
|
-
const thinking = getString(entry.thinking);
|
|
1071
|
+
const thinking = getString(entry.thinking) ?? '';
|
|
857
1072
|
const parts = [`## ${heading}`, ''];
|
|
858
1073
|
|
|
859
1074
|
if (timestamp) {
|
|
@@ -872,6 +1087,135 @@ const renderLogEntry = (entry: AntigravityLogEntry): string[] => {
|
|
|
872
1087
|
return parts;
|
|
873
1088
|
};
|
|
874
1089
|
|
|
1090
|
+
const logEntryCreatedAtMs = (entry: AntigravityLogEntry): number | null => {
|
|
1091
|
+
const timestamp = getString(entry.created_at);
|
|
1092
|
+
if (!timestamp) {
|
|
1093
|
+
return null;
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
const parsed = Date.parse(timestamp);
|
|
1097
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
1098
|
+
};
|
|
1099
|
+
|
|
1100
|
+
const logEntryOrder = (entry: AntigravityLogEntry, fallback: number): number => {
|
|
1101
|
+
return typeof entry.step_index === 'number' && Number.isFinite(entry.step_index) ? entry.step_index : fallback;
|
|
1102
|
+
};
|
|
1103
|
+
|
|
1104
|
+
const isAssistantLogEntry = (entry: AntigravityLogEntry): boolean => {
|
|
1105
|
+
return getString(entry.source) === 'MODEL' && getString(entry.type) === 'PLANNER_RESPONSE';
|
|
1106
|
+
};
|
|
1107
|
+
|
|
1108
|
+
const logEntryRole = (entry: AntigravityLogEntry): AntigravityConversationMessage['role'] => {
|
|
1109
|
+
const source = getString(entry.source);
|
|
1110
|
+
if (source?.startsWith('USER')) {
|
|
1111
|
+
return 'user';
|
|
1112
|
+
}
|
|
1113
|
+
if (isAssistantLogEntry(entry)) {
|
|
1114
|
+
return 'assistant';
|
|
1115
|
+
}
|
|
1116
|
+
if (source === 'SYSTEM') {
|
|
1117
|
+
return 'system';
|
|
1118
|
+
}
|
|
1119
|
+
if (source === 'MODEL') {
|
|
1120
|
+
return 'tool';
|
|
1121
|
+
}
|
|
1122
|
+
return 'unknown';
|
|
1123
|
+
};
|
|
1124
|
+
|
|
1125
|
+
const logEntryPhase = (entry: AntigravityLogEntry): AntigravityConversationMessage['phase'] => {
|
|
1126
|
+
const role = logEntryRole(entry);
|
|
1127
|
+
if (role === 'assistant') {
|
|
1128
|
+
return 'final_answer';
|
|
1129
|
+
}
|
|
1130
|
+
if (role === 'tool') {
|
|
1131
|
+
return 'tool_output';
|
|
1132
|
+
}
|
|
1133
|
+
return 'unknown';
|
|
1134
|
+
};
|
|
1135
|
+
|
|
1136
|
+
const logEntryMetadata = (entry: AntigravityLogEntry): Record<string, unknown> => ({
|
|
1137
|
+
source: getString(entry.source),
|
|
1138
|
+
status: getString(entry.status),
|
|
1139
|
+
type: getString(entry.type),
|
|
1140
|
+
});
|
|
1141
|
+
|
|
1142
|
+
const toolCallsText = (toolCalls: unknown): string => {
|
|
1143
|
+
if (!Array.isArray(toolCalls)) {
|
|
1144
|
+
return '';
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
return toolCalls
|
|
1148
|
+
.flatMap((call) => {
|
|
1149
|
+
if (!call || typeof call !== 'object') {
|
|
1150
|
+
return [];
|
|
1151
|
+
}
|
|
1152
|
+
const { args, name } = call as { args?: unknown; name?: unknown };
|
|
1153
|
+
return [JSON.stringify({ args, name: typeof name === 'string' ? name : 'unknown' })];
|
|
1154
|
+
})
|
|
1155
|
+
.join('\n');
|
|
1156
|
+
};
|
|
1157
|
+
|
|
1158
|
+
const logEntryToMessages = (entry: AntigravityLogEntry, index: number): AntigravityConversationMessage[] => {
|
|
1159
|
+
const order = logEntryOrder(entry, index);
|
|
1160
|
+
const createdAtMs = logEntryCreatedAtMs(entry);
|
|
1161
|
+
const role = logEntryRole(entry);
|
|
1162
|
+
const phase = logEntryPhase(entry);
|
|
1163
|
+
const metadata = logEntryMetadata(entry);
|
|
1164
|
+
const messages: AntigravityConversationMessage[] = [];
|
|
1165
|
+
const thinking = getString(entry.thinking)?.trim();
|
|
1166
|
+
if (thinking && role === 'assistant') {
|
|
1167
|
+
messages.push({
|
|
1168
|
+
createdAtMs,
|
|
1169
|
+
metadata,
|
|
1170
|
+
order,
|
|
1171
|
+
phase: 'reasoning',
|
|
1172
|
+
role: 'assistant',
|
|
1173
|
+
text: thinking,
|
|
1174
|
+
});
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
const content = cleanLogContent(entry);
|
|
1178
|
+
if (content) {
|
|
1179
|
+
messages.push({
|
|
1180
|
+
createdAtMs,
|
|
1181
|
+
metadata,
|
|
1182
|
+
order,
|
|
1183
|
+
phase,
|
|
1184
|
+
role,
|
|
1185
|
+
text: content,
|
|
1186
|
+
});
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
const calls = toolCallsText(entry.tool_calls);
|
|
1190
|
+
if (calls) {
|
|
1191
|
+
messages.push({
|
|
1192
|
+
createdAtMs,
|
|
1193
|
+
metadata,
|
|
1194
|
+
order,
|
|
1195
|
+
phase: 'tool_call',
|
|
1196
|
+
role: 'tool',
|
|
1197
|
+
text: calls,
|
|
1198
|
+
});
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
return messages;
|
|
1202
|
+
};
|
|
1203
|
+
|
|
1204
|
+
export const readAntigravityConversationMessages = async (
|
|
1205
|
+
conversation: AntigravityConversation,
|
|
1206
|
+
): Promise<AntigravityConversationMessage[]> => {
|
|
1207
|
+
if (!conversation.transcriptPath || !conversation.transcriptSource) {
|
|
1208
|
+
return [];
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
try {
|
|
1212
|
+
const entries = parseLogEntries(await Bun.file(conversation.transcriptPath).text());
|
|
1213
|
+
return entries.flatMap(logEntryToMessages);
|
|
1214
|
+
} catch {
|
|
1215
|
+
return [];
|
|
1216
|
+
}
|
|
1217
|
+
};
|
|
1218
|
+
|
|
875
1219
|
const renderAntigravityTranscriptMarkdown = async (conversation: AntigravityConversation): Promise<string | null> => {
|
|
876
1220
|
if (!conversation.transcriptPath || !conversation.transcriptSource) {
|
|
877
1221
|
return null;
|
|
@@ -886,6 +1230,7 @@ const renderAntigravityTranscriptMarkdown = async (conversation: AntigravityConv
|
|
|
886
1230
|
conversation.transcriptSource === 'overview'
|
|
887
1231
|
? 'antigravity_overview_transcript'
|
|
888
1232
|
: 'antigravity_jsonl_transcript';
|
|
1233
|
+
const sections = entries.flatMap((entry) => renderLogEntry(entry));
|
|
889
1234
|
const parts = [
|
|
890
1235
|
`# ${conversation.title}`,
|
|
891
1236
|
'',
|
|
@@ -893,12 +1238,9 @@ const renderAntigravityTranscriptMarkdown = async (conversation: AntigravityConv
|
|
|
893
1238
|
`- conversation_id: \`${conversation.conversationId}\``,
|
|
894
1239
|
conversation.workspaceUri ? `- workspace: \`${conversation.workspaceUri}\`` : '',
|
|
895
1240
|
'',
|
|
1241
|
+
...sections,
|
|
896
1242
|
].filter(Boolean);
|
|
897
1243
|
|
|
898
|
-
for (const entry of entries) {
|
|
899
|
-
parts.push(...renderLogEntry(entry));
|
|
900
|
-
}
|
|
901
|
-
|
|
902
1244
|
return `${parts.join('\n').trimEnd()}\n`;
|
|
903
1245
|
};
|
|
904
1246
|
|
|
@@ -922,9 +1264,37 @@ const renderDecryptedSafeStorageMarkdown = (conversation: AntigravityConversatio
|
|
|
922
1264
|
.join('\n');
|
|
923
1265
|
};
|
|
924
1266
|
|
|
1267
|
+
const renderAntigravitySummaryMarkdown = (conversation: AntigravityConversation): string | null => {
|
|
1268
|
+
if (conversation.artifactCount > 0) {
|
|
1269
|
+
return null;
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
if (!conversation.summaryPath && conversation.indexedItemCount === null) {
|
|
1273
|
+
return null;
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
return [
|
|
1277
|
+
`# ${conversation.title}`,
|
|
1278
|
+
'',
|
|
1279
|
+
'- exported_from: `antigravity_summary_index`',
|
|
1280
|
+
`- conversation_id: \`${conversation.conversationId}\``,
|
|
1281
|
+
conversation.workspaceUri ? `- workspace: \`${conversation.workspaceUri}\`` : '',
|
|
1282
|
+
conversation.indexedItemCount !== null ? `- indexed_items: \`${conversation.indexedItemCount}\`` : '',
|
|
1283
|
+
conversation.createdAtMs ? `- created_at: \`${new Date(conversation.createdAtMs).toISOString()}\`` : '',
|
|
1284
|
+
conversation.lastUpdatedAtMs ? `- updated_at: \`${new Date(conversation.lastUpdatedAtMs).toISOString()}\`` : '',
|
|
1285
|
+
'',
|
|
1286
|
+
'No local transcript log was found for this Antigravity conversation. The export contains the summary index metadata that Antigravity retained.',
|
|
1287
|
+
'',
|
|
1288
|
+
]
|
|
1289
|
+
.filter(Boolean)
|
|
1290
|
+
.join('\n');
|
|
1291
|
+
};
|
|
1292
|
+
|
|
925
1293
|
export const renderAntigravityConversationMarkdown = async (
|
|
926
1294
|
conversation: AntigravityConversation,
|
|
927
|
-
options: {
|
|
1295
|
+
options: {
|
|
1296
|
+
keychainSecret?: string | null;
|
|
1297
|
+
} = {},
|
|
928
1298
|
): Promise<string | null> => {
|
|
929
1299
|
const transcript = await renderAntigravityTranscriptMarkdown(conversation);
|
|
930
1300
|
if (transcript) {
|
|
@@ -939,5 +1309,5 @@ export const renderAntigravityConversationMarkdown = async (
|
|
|
939
1309
|
}
|
|
940
1310
|
}
|
|
941
1311
|
|
|
942
|
-
return
|
|
1312
|
+
return renderAntigravitySummaryMarkdown(conversation);
|
|
943
1313
|
};
|
|
@@ -45,9 +45,12 @@ export type AntigravityConversation = {
|
|
|
45
45
|
createdAtMs: number | null;
|
|
46
46
|
indexedItemCount: number | null;
|
|
47
47
|
lastUpdatedAtMs: number | null;
|
|
48
|
+
model: string | null;
|
|
49
|
+
projectId: string | null;
|
|
48
50
|
sourceRoot: string | null;
|
|
49
51
|
summaryPath: string | null;
|
|
50
52
|
title: string;
|
|
53
|
+
totalBytes: number;
|
|
51
54
|
transcriptBytes: number;
|
|
52
55
|
transcriptEntryCount: number;
|
|
53
56
|
transcriptPath: string | null;
|
|
@@ -66,5 +69,6 @@ export type AntigravityWorkspaceGroup = {
|
|
|
66
69
|
label: string;
|
|
67
70
|
lastActiveMs: number;
|
|
68
71
|
transcriptCount: number;
|
|
72
|
+
totalBytes: number;
|
|
69
73
|
uri: string | null;
|
|
70
74
|
};
|