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.
- package/AGENTS.md +55 -6
- package/README.md +46 -5
- package/apps/ui/AGENTS.md +31 -4
- package/apps/ui/README.md +59 -5
- package/apps/ui/dist/client/assets/analytics-DOy1b6Sh.js +1 -0
- package/apps/ui/dist/client/assets/antigravity-conversations._conversationId-DqySVO2K.js +7 -0
- package/apps/ui/dist/client/assets/antigravity-conversations._conversationId-KAcXtNxI.js +1 -0
- package/apps/ui/dist/client/assets/antigravity-keychain-panel-B77qJz6f.js +1 -0
- package/apps/ui/dist/client/assets/antigravity._workspaceKey-B3NM6gRH.js +1 -0
- package/apps/ui/dist/client/assets/antigravity._workspaceKey-ByitGWki.js +1 -0
- package/apps/ui/dist/client/assets/antigravity.index-DP9JC2P9.js +1 -0
- package/apps/ui/dist/client/assets/antigravity.index-DgW25FEV.js +1 -0
- package/apps/ui/dist/client/assets/badge-C3i4OKs8.js +1 -0
- package/apps/ui/dist/client/assets/checkbox-CdHitXWQ.js +1 -0
- package/apps/ui/dist/client/assets/claude-code-sessions._sessionId-8pQ55ci2.js +1 -0
- package/apps/ui/dist/client/assets/claude-code-sessions._sessionId-DVz5UmtU.js +1 -0
- package/apps/ui/dist/client/assets/claude-code._workspaceKey-BBKskSum.js +1 -0
- package/apps/ui/dist/client/assets/claude-code._workspaceKey-OkikMUFs.js +1 -0
- package/apps/ui/dist/client/assets/claude-code.index-Cwu76dbb.js +1 -0
- package/apps/ui/dist/client/assets/claude-code.index-D6eMd08t.js +1 -0
- package/apps/ui/dist/client/assets/createServerFn-B-KkwmHU.js +3 -0
- package/apps/ui/dist/client/assets/cursor-threads._composerId-CmBFclK8.js +1 -0
- package/apps/ui/dist/client/assets/cursor-threads._composerId-hBWlP1D-.js +1 -0
- package/apps/ui/dist/client/assets/cursor._workspaceKey-BFPkIRi-.js +1 -0
- package/apps/ui/dist/client/assets/cursor._workspaceKey-CaAZjGmm.js +1 -0
- package/apps/ui/dist/client/assets/cursor.index-8y4o20kb.js +2 -0
- package/apps/ui/dist/client/assets/cursor.index-CrnMwDCi.js +1 -0
- package/apps/ui/dist/client/assets/{data-table-DeQq8xdt.js → data-table-Br78_dk3.js} +2 -2
- package/apps/ui/dist/client/assets/delete-confirm-dialog-Bxs07u-j.js +7 -0
- package/apps/ui/dist/client/assets/dist-B9pyYCVU.js +1 -0
- package/apps/ui/dist/client/assets/dist-BrJhN2A0.js +5 -0
- package/apps/ui/dist/client/assets/dist-Cmd3AIfD.js +1 -0
- package/apps/ui/dist/client/assets/dist-DvMS2965.js +1 -0
- package/apps/ui/dist/client/assets/download-Bf0QJKD3.js +1 -0
- package/apps/ui/dist/client/assets/dropdown-menu-D5cvPaZt.js +1 -0
- package/apps/ui/dist/client/assets/es2015-ad6040dw.js +41 -0
- package/apps/ui/dist/client/assets/export-dialog-Dr8d2MqD.js +1 -0
- package/apps/ui/dist/client/assets/formatters-BtqyrX_c.js +1 -0
- package/apps/ui/dist/client/assets/index-C-STgIH4.js +166 -0
- package/apps/ui/dist/client/assets/jsx-runtime-DGeXAQPT.js +1 -0
- package/apps/ui/dist/client/assets/kiro-sessions._sessionId-CKgfJ7GR.js +1 -0
- package/apps/ui/dist/client/assets/kiro-sessions._sessionId-zvIJHtQF.js +1 -0
- package/apps/ui/dist/client/assets/kiro._workspaceKey-DhVuJuZB.js +1 -0
- package/apps/ui/dist/client/assets/kiro._workspaceKey-QArsjkTY.js +1 -0
- package/apps/ui/dist/client/assets/kiro.index-C-fr4m7i.js +1 -0
- package/apps/ui/dist/client/assets/kiro.index-OYgAdtZd.js +1 -0
- package/apps/ui/dist/client/assets/metric-card-Dplm0ZiM.js +1 -0
- package/apps/ui/dist/client/assets/opencode-sessions._sessionId-DLjiTst-.js +1 -0
- package/apps/ui/dist/client/assets/opencode-sessions._sessionId-biBwrRbt.js +8 -0
- package/apps/ui/dist/client/assets/opencode._workspaceKey-C7OIzMOJ.js +1 -0
- package/apps/ui/dist/client/assets/opencode._workspaceKey-sBakX0oI.js +1 -0
- package/apps/ui/dist/client/assets/opencode.index-Bl_kNs9N.js +1 -0
- package/apps/ui/dist/client/assets/opencode.index-CN53bVmb.js +1 -0
- package/apps/ui/dist/client/assets/page-header-Cwa3p6Tl.js +1 -0
- package/apps/ui/dist/client/assets/preload-helper-B8fFrdxC.js +1 -0
- package/apps/ui/dist/client/assets/projects._project-D8WloxQN.js +1 -0
- package/apps/ui/dist/client/assets/projects._project-DSDwH4NF.js +1 -0
- package/apps/ui/dist/client/assets/projects.index-5xRtuJdX.js +3 -0
- package/apps/ui/dist/client/assets/projects.index-DEfhWqa8.js +1 -0
- package/apps/ui/dist/client/assets/react-dom-DL96Jor4.js +1 -0
- package/apps/ui/dist/client/assets/refresh-ccw-BgKjOiA6.js +1 -0
- package/apps/ui/dist/client/assets/reload-error-panel-AHqu0akK.js +1 -0
- package/apps/ui/dist/client/assets/routes-DnzF_9CX.js +1 -0
- package/apps/ui/dist/client/assets/scroll-text-fM0sMOB3.js +1 -0
- package/apps/ui/dist/client/assets/select-CYF6pF37.js +1 -0
- package/apps/ui/dist/client/assets/settings-Dx70jgP_.js +1 -0
- package/apps/ui/dist/client/assets/sqlite-error-B6uZjUe8.js +1 -0
- package/apps/ui/dist/client/assets/styles-B7Zi9EFA.css +1 -0
- package/apps/ui/dist/client/assets/tabs-CmuhkT-c.js +7 -0
- package/apps/ui/dist/client/assets/text-filter-DVAZySUS.js +2 -0
- package/apps/ui/dist/client/assets/thread-transcript-stats-BUNz6u7F.js +1 -0
- package/apps/ui/dist/client/assets/threads._threadId-BB9tTsV4.js +1 -0
- package/apps/ui/dist/client/assets/threads._threadId-BMRSFow3.js +1 -0
- package/apps/ui/dist/client/assets/useMutation-BSFult2i.js +1 -0
- package/apps/ui/dist/client/assets/useQuery-CjINKZf1.js +1 -0
- package/apps/ui/dist/client/icon.svg +2 -1
- package/apps/ui/dist/server/assets/_tanstack-start-manifest_v-CQ8Jjs3B.js +387 -0
- package/apps/ui/dist/server/assets/analytics-CYP_LT5Y.js +16 -0
- package/apps/ui/dist/server/assets/{analytics-Dc_QDZZC.js → analytics-CtpOMVMO.js} +13 -6
- package/apps/ui/dist/server/assets/antigravity-conversations._conversationId-BKOyL2T6.js +613 -0
- package/apps/ui/dist/server/assets/{antigravity-conversations._conversationId-C9z4AeN-.js → antigravity-conversations._conversationId-eS87Dx7g.js} +2 -2
- package/apps/ui/dist/server/assets/{antigravity-db-D9gW1D8G.js → antigravity-db-Bh8_U9uw.js} +11 -7
- package/apps/ui/dist/server/assets/{antigravity-keychain-panel-bpPoxhyp.js → antigravity-keychain-panel-CC7FLmAK.js} +1 -1
- package/apps/ui/dist/server/assets/{antigravity-queries-DVIKyOXi.js → antigravity-queries-CGrJO9Vr.js} +5 -5
- package/apps/ui/dist/server/assets/{antigravity-server-Cp1lc8fp.js → antigravity-server-CHRjVFqN.js} +11 -11
- package/apps/ui/dist/server/assets/{antigravity._workspaceKey-Dl8o1ptg.js → antigravity._workspaceKey-B0QeYUOh.js} +2 -2
- package/apps/ui/dist/server/assets/{antigravity._workspaceKey-BAoa4izU.js → antigravity._workspaceKey-C3kP-qyN.js} +4 -4
- package/apps/ui/dist/server/assets/{antigravity.index-BOlrJasZ.js → antigravity.index-CPCYkqCi.js} +2 -2
- package/apps/ui/dist/server/assets/claude-code-db-Ik3VStKZ.js +361 -0
- package/apps/ui/dist/server/assets/claude-code-queries-Cgzi4K-e.js +37 -0
- package/apps/ui/dist/server/assets/claude-code-server-PfraClXS.js +72 -0
- package/apps/ui/dist/server/assets/claude-code-sessions._sessionId-C55oe6zj.js +18 -0
- package/apps/ui/dist/server/assets/claude-code-sessions._sessionId-D1RYYi3j.js +473 -0
- package/apps/ui/dist/server/assets/claude-code-sessions._sessionId-DSvPLEUL.js +11 -0
- package/apps/ui/dist/server/assets/claude-code-transcript-C-bxh3cS.js +139 -0
- package/apps/ui/dist/server/assets/claude-code-transcript-phase-DmUMc8VU.js +10 -0
- package/apps/ui/dist/server/assets/claude-code._workspaceKey-B5Xg_-tE.js +28 -0
- package/apps/ui/dist/server/assets/claude-code._workspaceKey-BPlzyXPa.js +11 -0
- package/apps/ui/dist/server/assets/claude-code._workspaceKey-DqDve2wl.js +191 -0
- package/apps/ui/dist/server/assets/claude-code.index-B7yYR7dD.js +92 -0
- package/apps/ui/dist/server/assets/claude-code.index-BUHThG1W.js +11 -0
- package/apps/ui/dist/server/assets/{codex-queries-ev_mRUzr.js → codex-queries-CtgeZ7VL.js} +15 -13
- package/apps/ui/dist/server/assets/{codex-server-DIYFLozB.js → codex-server-CGXU4H8-.js} +421 -146
- package/apps/ui/dist/server/assets/concurrency-VXtYvlGh.js +18 -0
- package/apps/ui/dist/server/assets/{createServerRpc-Cg-Zr1rq.js → createServerRpc-CF_DEwnm.js} +1 -1
- package/apps/ui/dist/server/assets/{createSsrRpc-DVnVQhGx.js → createSsrRpc-C754NPki.js} +1 -1
- package/apps/ui/dist/server/assets/{cursor-db-B7agkAvM.js → cursor-db-CZnYy7aT.js} +196 -9
- package/apps/ui/dist/server/assets/{cursor-queries-f7DjBKSD.js → cursor-queries-NCIM0Nat.js} +12 -10
- package/apps/ui/dist/server/assets/{cursor-recovery-9bJLs7vG.js → cursor-recovery-CXpO8KcD.js} +2 -2
- package/apps/ui/dist/server/assets/{cursor-server-nPzojHN3.js → cursor-server-DNu52A3K.js} +71 -42
- package/apps/ui/dist/server/assets/cursor-threads._composerId-Ckn6ItHI.js +582 -0
- package/apps/ui/dist/server/assets/{cursor-threads._composerId-B3qcsh9C.js → cursor-threads._composerId-p9-ARAzc.js} +2 -2
- package/apps/ui/dist/server/assets/{cursor-transcript-2iL3KFSK.js → cursor-transcript-B7tGnqtn.js} +1 -1
- package/apps/ui/dist/server/assets/{cursor._workspaceKey-BL_CQyHQ.js → cursor._workspaceKey-CZuohIUL.js} +2 -2
- package/apps/ui/dist/server/assets/{cursor._workspaceKey-BhQeepXB.js → cursor._workspaceKey-DPp5JSjy.js} +11 -9
- package/apps/ui/dist/server/assets/{cursor.index-CsrdckZD.js → cursor.index-DkWT-mxw.js} +2 -2
- package/apps/ui/dist/server/assets/{delete-confirm-dialog-PCD7S0_M.js → delete-confirm-dialog-BcBNCxWB.js} +5 -1
- package/apps/ui/dist/server/assets/{empty-plugin-adapters-D3qLMPfC.js → empty-plugin-adapters-B3lHh1La.js} +1 -1
- package/apps/ui/dist/server/assets/{export-dialog-DaPlOGFT.js → export-dialog-D88ze9Gy.js} +54 -12
- package/apps/ui/dist/server/assets/kiro-db--fXrED_-.js +552 -0
- package/apps/ui/dist/server/assets/kiro-queries-CzNlM2ok.js +37 -0
- package/apps/ui/dist/server/assets/kiro-server-9WRxg2Au.js +72 -0
- package/apps/ui/dist/server/assets/kiro-sessions._sessionId-CRY2c7YO.js +11 -0
- package/apps/ui/dist/server/assets/kiro-sessions._sessionId-F1UlwxmR.js +449 -0
- package/apps/ui/dist/server/assets/kiro-sessions._sessionId-bvTulT7C.js +18 -0
- package/apps/ui/dist/server/assets/kiro-transcript-DoekQBaH.js +112 -0
- package/apps/ui/dist/server/assets/kiro-transcript-phase-CJG40nQg.js +27 -0
- package/apps/ui/dist/server/assets/kiro._workspaceKey-BDe9sQwo.js +11 -0
- package/apps/ui/dist/server/assets/kiro._workspaceKey-CJsjgNwO.js +28 -0
- package/apps/ui/dist/server/assets/kiro._workspaceKey-D_-4Qb7y.js +193 -0
- package/apps/ui/dist/server/assets/kiro.index-C__-UROk.js +11 -0
- package/apps/ui/dist/server/assets/kiro.index-CmTbqeYj.js +93 -0
- package/apps/ui/dist/server/assets/opencode-db-BM7KjOzc.js +397 -0
- package/apps/ui/dist/server/assets/opencode-queries-BeNYXnQv.js +50 -0
- package/apps/ui/dist/server/assets/opencode-server-BpQ_kRze.js +72 -0
- package/apps/ui/dist/server/assets/opencode-sessions._sessionId-CGQ-t0vD.js +518 -0
- package/apps/ui/dist/server/assets/opencode-sessions._sessionId-D8Q7in_Z.js +18 -0
- package/apps/ui/dist/server/assets/opencode-sessions._sessionId-DKOvi0lV.js +11 -0
- package/apps/ui/dist/server/assets/opencode-think-tags-CAoD-EcZ.js +87 -0
- package/apps/ui/dist/server/assets/opencode-transcript-BNTcGNym.js +141 -0
- package/apps/ui/dist/server/assets/opencode-transcript-phase-OqLkiQD0.js +32 -0
- package/apps/ui/dist/server/assets/opencode._workspaceKey-BdqcWHw1.js +11 -0
- package/apps/ui/dist/server/assets/opencode._workspaceKey-CfH96HTT.js +28 -0
- package/apps/ui/dist/server/assets/opencode._workspaceKey-DdbHPDrO.js +207 -0
- package/apps/ui/dist/server/assets/opencode.index-BbVzkJXP.js +11 -0
- package/apps/ui/dist/server/assets/opencode.index-Vh_Gq_1L.js +93 -0
- package/apps/ui/dist/server/assets/{projects._project-CqqUFr4l.js → projects._project-4io5LO0E.js} +5 -3
- package/apps/ui/dist/server/assets/{projects._project-DahGqNYS.js → projects._project-D6ZoGhJ8.js} +42 -12
- package/apps/ui/dist/server/assets/{projects.index-CkTeFWNU.js → projects.index-BkLiF2FF.js} +21 -7
- package/apps/ui/dist/server/assets/projects.index-DesYXwfi.js +14 -0
- package/apps/ui/dist/server/assets/route-search-ts4W9MJ9.js +38 -0
- package/apps/ui/dist/server/assets/router-Sac2DGk6.js +518 -0
- package/apps/ui/dist/server/assets/{routes-Xix3ZeSo.js → routes-Bsact1uB.js} +2 -2
- package/apps/ui/dist/server/assets/{routes-0x1U0IHq.js → routes-BzkJgq4W.js} +2 -2
- package/apps/ui/dist/server/assets/{shared-CPRNYIql.js → shared-DyhChtHf.js} +4 -1
- package/apps/ui/dist/server/assets/source-session-export-server-DNutCawb.js +38 -0
- package/apps/ui/dist/server/assets/start-B_HFwkkk.js +4 -0
- package/apps/ui/dist/server/assets/tabs-DkaChNVg.js +501 -0
- package/apps/ui/dist/server/assets/thread-transcript-stats-Dh34mt2u.js +45 -0
- package/apps/ui/dist/server/assets/threads._threadId-BeXEc4Lo.js +648 -0
- package/apps/ui/dist/server/assets/{threads._threadId-BLCkGW--.js → threads._threadId-Ci0S4mKU.js} +2 -2
- package/apps/ui/dist/server/assets/ui-export-files-BHLX9bhN.js +83 -0
- package/apps/ui/dist/server/server.js +141 -83
- package/package.json +28 -11
- package/src/lib/antigravity-db.ts +20 -13
- package/src/lib/claude-code-db.ts +655 -0
- package/src/lib/claude-code-exporter-types.ts +110 -0
- package/src/lib/claude-code-transcript-phase.ts +25 -0
- package/src/lib/claude-code-transcript.ts +180 -0
- package/src/lib/codex-analytics.ts +118 -18
- package/src/lib/codex-browser-db.ts +491 -56
- package/src/lib/codex-browser-export.ts +27 -71
- package/src/lib/codex-thread-cache.ts +17 -1
- package/src/lib/concurrency.ts +25 -0
- package/src/lib/cursor-db.ts +318 -7
- package/src/lib/cursor-exporter.ts +2 -2
- package/src/lib/kiro-db.ts +949 -0
- package/src/lib/kiro-exporter-types.ts +100 -0
- package/src/lib/kiro-transcript-phase.ts +41 -0
- package/src/lib/kiro-transcript.ts +115 -0
- package/src/lib/opencode-db.ts +610 -0
- package/src/lib/opencode-exporter-types.ts +129 -0
- package/src/lib/opencode-think-tags.ts +126 -0
- package/src/lib/opencode-transcript-phase.ts +50 -0
- package/src/lib/opencode-transcript.ts +194 -0
- package/src/lib/shared.ts +25 -0
- package/src/lib/ui-cache.ts +14 -1
- package/src/lib/ui-export-archive.ts +61 -0
- package/apps/ui/dist/client/assets/analytics-C83LcWNb.js +0 -1
- package/apps/ui/dist/client/assets/antigravity-conversations._conversationId-DkY8EEpK.js +0 -1
- package/apps/ui/dist/client/assets/antigravity-conversations._conversationId-OraHuz8j.js +0 -1
- package/apps/ui/dist/client/assets/antigravity-keychain-panel-DnDcq1ge.js +0 -1
- package/apps/ui/dist/client/assets/antigravity._workspaceKey-CQaZscA5.js +0 -1
- package/apps/ui/dist/client/assets/antigravity._workspaceKey-DTs99obU.js +0 -1
- package/apps/ui/dist/client/assets/antigravity.index-DbJa715k.js +0 -1
- package/apps/ui/dist/client/assets/antigravity.index-P-rs6w5X.js +0 -1
- package/apps/ui/dist/client/assets/badge-wgTVp-aq.js +0 -1
- package/apps/ui/dist/client/assets/checkbox-BUx0Gkuf.js +0 -1
- package/apps/ui/dist/client/assets/cursor-threads._composerId-D0DFXt8t.js +0 -1
- package/apps/ui/dist/client/assets/cursor-threads._composerId-tFa6Cf6A.js +0 -1
- package/apps/ui/dist/client/assets/cursor._workspaceKey-Df4PfA2k.js +0 -1
- package/apps/ui/dist/client/assets/cursor._workspaceKey-DwrzEtnV.js +0 -1
- package/apps/ui/dist/client/assets/cursor.index-CNBf4ZiR.js +0 -1
- package/apps/ui/dist/client/assets/cursor.index-DP9Hy8X6.js +0 -2
- package/apps/ui/dist/client/assets/delete-confirm-dialog-CPlNsLhM.js +0 -11
- package/apps/ui/dist/client/assets/dist-Ds3kS91l.js +0 -1
- package/apps/ui/dist/client/assets/download-DLuPnxpV.js +0 -1
- package/apps/ui/dist/client/assets/dropdown-menu-lFk6zjoL.js +0 -1
- package/apps/ui/dist/client/assets/es2015-D-H_iZF6.js +0 -41
- package/apps/ui/dist/client/assets/export-dialog-CyqyvwiP.js +0 -1
- package/apps/ui/dist/client/assets/formatters-DbCKP02D.js +0 -1
- package/apps/ui/dist/client/assets/index-C-ZPpKJ0.js +0 -22
- package/apps/ui/dist/client/assets/json-panel-BsngvucB.js +0 -1
- package/apps/ui/dist/client/assets/metadata-section-Dtl8dNag.js +0 -1
- package/apps/ui/dist/client/assets/metric-card-DNzR1Rne.js +0 -1
- package/apps/ui/dist/client/assets/page-header-dha_O7ZL.js +0 -1
- package/apps/ui/dist/client/assets/projects._project-B7HBhbXv.js +0 -1
- package/apps/ui/dist/client/assets/projects._project-DHVvuT7A.js +0 -1
- package/apps/ui/dist/client/assets/projects.index-BUUtx2AZ.js +0 -1
- package/apps/ui/dist/client/assets/projects.index-BojAe1Y4.js +0 -3
- package/apps/ui/dist/client/assets/refresh-ccw-B-ASKHtx.js +0 -1
- package/apps/ui/dist/client/assets/reload-error-panel-DD8M1BIY.js +0 -1
- package/apps/ui/dist/client/assets/routes-q7bzFp35.js +0 -1
- package/apps/ui/dist/client/assets/scroll-text-TvHyiJ_N.js +0 -1
- package/apps/ui/dist/client/assets/select-BFv1HMiT.js +0 -1
- package/apps/ui/dist/client/assets/settings-CvegTo4F.js +0 -1
- package/apps/ui/dist/client/assets/styles-Ch0r3kMZ.css +0 -1
- package/apps/ui/dist/client/assets/text-document-panel-D7Rws41o.js +0 -1
- package/apps/ui/dist/client/assets/text-filter-2q5pEoZh.js +0 -2
- package/apps/ui/dist/client/assets/threads._threadId-LpZVUlPq.js +0 -7
- package/apps/ui/dist/client/assets/threads._threadId-MSmNIBkq.js +0 -1
- package/apps/ui/dist/client/assets/useMutation-BOPJU9e0.js +0 -1
- package/apps/ui/dist/client/assets/useQuery-CbxZiVGF.js +0 -1
- package/apps/ui/dist/server/assets/_tanstack-start-manifest_v-zvGzK-Yx.js +0 -229
- package/apps/ui/dist/server/assets/antigravity-conversations._conversationId-JEhx-f2R.js +0 -212
- package/apps/ui/dist/server/assets/cursor-threads._composerId-BK3iW-3e.js +0 -218
- package/apps/ui/dist/server/assets/json-panel-RYsxWFae.js +0 -16
- package/apps/ui/dist/server/assets/metadata-section-D6Lbc7D6.js +0 -54
- package/apps/ui/dist/server/assets/router-K0m7dK4T.js +0 -394
- package/apps/ui/dist/server/assets/start-bX7bXjzw.js +0 -4
- package/apps/ui/dist/server/assets/text-document-panel-D8JbQWAn.js +0 -23
- package/apps/ui/dist/server/assets/threads._threadId-LjgsGUh-.js +0 -1052
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import { t as createServerFn } from "../server.js";
|
|
2
|
-
import { t as createServerRpc } from "./createServerRpc-
|
|
3
|
-
import { a as
|
|
2
|
+
import { t as createServerRpc } from "./createServerRpc-CF_DEwnm.js";
|
|
3
|
+
import { a as sanitizeExportFileName, n as ensureUiExportDir, o as zipExportDirectory, r as getExportMimeType, s as zipExportFile, t as buildUiExportDownloadUrl } from "./ui-export-files-BHLX9bhN.js";
|
|
4
|
+
import { a as cleanExtractedText, c as finalizeExportWriteStream, d as getPortablePathBasename, f as readJsonlObjects$1, g as renderSection, h as renderMetadataBlock, i as asString, l as formatInlineLiteral, m as renderDocumentTitle, n as asNumber, o as cleanInlineTitle, r as asObject, s as createExportWriteStream, u as formatModelLabel } from "./shared-DyhChtHf.js";
|
|
5
|
+
import { t as mapWithConcurrency } from "./concurrency-VXtYvlGh.js";
|
|
4
6
|
import { t as isRetryableSqliteError } from "./sqlite-error-LZDrnxdd.js";
|
|
5
7
|
import { t as applyPathTransforms } from "./path-transforms-DL2IwtYd.js";
|
|
6
8
|
import { finished } from "node:stream/promises";
|
|
7
9
|
import { z } from "zod";
|
|
8
|
-
import {
|
|
10
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
9
11
|
import { copyFile, mkdir, mkdtemp, readdir, rename, rm, stat, utimes } from "node:fs/promises";
|
|
10
12
|
import os from "node:os";
|
|
11
13
|
import path from "node:path";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
+
import { Database, constants } from "bun:sqlite";
|
|
15
|
+
import { closeSync, createReadStream, openSync, readSync, readdirSync, statSync } from "node:fs";
|
|
16
|
+
import { StringDecoder } from "node:string_decoder";
|
|
17
|
+
import { pathToFileURL } from "node:url";
|
|
14
18
|
//#region ../../src/lib/codex-exporter-types.ts
|
|
15
19
|
var DEFAULT_CODEX_DIR = path.join(os.homedir(), ".codex");
|
|
16
20
|
var DEFAULT_DB_PATH = path.join(DEFAULT_CODEX_DIR, "state_5.sqlite");
|
|
@@ -55,7 +59,7 @@ var parseCodexTranscriptFile = async (sessionFile, options = {}) => {
|
|
|
55
59
|
const maxEvents = options.maxEvents ?? Number.POSITIVE_INFINITY;
|
|
56
60
|
const maxTurnContexts = options.maxTurnContexts ?? Number.POSITIVE_INFINITY;
|
|
57
61
|
let sequence = 0;
|
|
58
|
-
for await (const parsed of readJsonlObjects(sessionFile)) {
|
|
62
|
+
for await (const parsed of readJsonlObjects$1(sessionFile)) {
|
|
59
63
|
captureSessionMeta$1(parsed, sessionMeta);
|
|
60
64
|
if (asString(parsed.type) === "turn_context") {
|
|
61
65
|
if (turnContexts.length < maxTurnContexts) captureTurnContext(parsed, turnContexts);
|
|
@@ -373,6 +377,16 @@ var toCachePath = (key) => {
|
|
|
373
377
|
var hashCacheKeyParts = (...parts) => {
|
|
374
378
|
return createHash("sha1").update(parts.join("|")).digest("hex");
|
|
375
379
|
};
|
|
380
|
+
var hashCacheKeyPartsIterable = (parts) => {
|
|
381
|
+
const hash = createHash("sha1");
|
|
382
|
+
for (const part of parts) {
|
|
383
|
+
hash.update(String(part.length));
|
|
384
|
+
hash.update(":");
|
|
385
|
+
hash.update(part);
|
|
386
|
+
hash.update(";");
|
|
387
|
+
}
|
|
388
|
+
return hash.digest("hex");
|
|
389
|
+
};
|
|
376
390
|
var getFileFingerprint = async (filePath) => {
|
|
377
391
|
const metadata = await stat(filePath);
|
|
378
392
|
return `${filePath}:${metadata.size}:${metadata.mtimeMs}`;
|
|
@@ -390,7 +404,8 @@ var getCachedJson = async (key) => {
|
|
|
390
404
|
return null;
|
|
391
405
|
}
|
|
392
406
|
if (parsed && typeof parsed === "object" && "version" in parsed && parsed.version === CACHE_ENVELOPE_VERSION && "value" in parsed) return parsed.value;
|
|
393
|
-
|
|
407
|
+
await rm(filePath, { force: true });
|
|
408
|
+
return null;
|
|
394
409
|
};
|
|
395
410
|
var setCachedJson = async (key, value) => {
|
|
396
411
|
await ensureCacheDir();
|
|
@@ -420,12 +435,24 @@ var invalidateCacheByPrefix = async (...prefixes) => {
|
|
|
420
435
|
//#endregion
|
|
421
436
|
//#region ../../src/lib/codex-thread-cache.ts
|
|
422
437
|
var LARGE_THREAD_SIZE_BYTES = 100 * 1024 * 1024;
|
|
438
|
+
var isMissingFileError$2 = (error) => {
|
|
439
|
+
return error instanceof Error && "code" in error && error.code === "ENOENT";
|
|
440
|
+
};
|
|
423
441
|
var getCachedParsedCodexTranscript = async (sessionFile) => {
|
|
424
442
|
const fingerprint = await getFileFingerprint(sessionFile);
|
|
425
443
|
return withCachedJson(`thread-${hashCacheKeyParts(path.basename(sessionFile), fingerprint)}`, async () => parseCodexTranscriptFile(sessionFile));
|
|
426
444
|
};
|
|
427
445
|
var getThreadRolloutLoadState = async (sessionFile, largeTranscriptThresholdBytes = LARGE_THREAD_SIZE_BYTES) => {
|
|
428
|
-
|
|
446
|
+
let metadata;
|
|
447
|
+
try {
|
|
448
|
+
metadata = await stat(sessionFile);
|
|
449
|
+
} catch (error) {
|
|
450
|
+
if (isMissingFileError$2(error)) return {
|
|
451
|
+
fileSizeBytes: null,
|
|
452
|
+
shouldDeferTranscriptLoad: false
|
|
453
|
+
};
|
|
454
|
+
throw error;
|
|
455
|
+
}
|
|
429
456
|
return {
|
|
430
457
|
fileSizeBytes: metadata.size,
|
|
431
458
|
shouldDeferTranscriptLoad: metadata.size > largeTranscriptThresholdBytes
|
|
@@ -483,6 +510,13 @@ var runWithSqliteRetry = ({ action, delaysMs = DEFAULT_RETRY_DELAYS_MS, sleep =
|
|
|
483
510
|
var SQLITE_DELETE_BATCH_SIZE = 400;
|
|
484
511
|
var SESSION_FILE_DELETE_CONCURRENCY = 16;
|
|
485
512
|
var THREAD_LIST_IO_CONCURRENCY = 8;
|
|
513
|
+
var CODEX_READONLY_DB_OPEN_FLAGS = constants.SQLITE_OPEN_READONLY | constants.SQLITE_OPEN_URI;
|
|
514
|
+
var JSONL_READ_CHUNK_BYTES = 64 * 1024;
|
|
515
|
+
var SESSION_META_READ_LIMIT_BYTES = 4 * 1024 * 1024;
|
|
516
|
+
var THREAD_ID_PATTERN = /([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/iu;
|
|
517
|
+
var isSqliteCantOpenError = (error) => {
|
|
518
|
+
return error.code === "SQLITE_CANTOPEN";
|
|
519
|
+
};
|
|
486
520
|
var chunkValues = (values, chunkSize) => {
|
|
487
521
|
const chunks = [];
|
|
488
522
|
for (let index = 0; index < values.length; index += chunkSize) chunks.push(values.slice(index, index + chunkSize));
|
|
@@ -492,29 +526,16 @@ var isPromiseLike = (value) => {
|
|
|
492
526
|
if (typeof value !== "object" && typeof value !== "function" || value === null) return false;
|
|
493
527
|
return "then" in value && typeof value.then === "function";
|
|
494
528
|
};
|
|
495
|
-
var
|
|
496
|
-
const results = new Array(values.length);
|
|
497
|
-
let nextIndex = 0;
|
|
498
|
-
const worker = async () => {
|
|
499
|
-
while (true) {
|
|
500
|
-
const currentIndex = nextIndex;
|
|
501
|
-
nextIndex += 1;
|
|
502
|
-
if (currentIndex >= values.length) return;
|
|
503
|
-
results[currentIndex] = await mapper(values[currentIndex], currentIndex);
|
|
504
|
-
}
|
|
505
|
-
};
|
|
506
|
-
await Promise.all(Array.from({ length: Math.min(limit, values.length) }, () => worker()));
|
|
507
|
-
return results;
|
|
508
|
-
};
|
|
509
|
-
var openReadonlyDb = (dbPath, busyTimeoutMs) => {
|
|
529
|
+
var openReadonlyDb = (dbPath) => {
|
|
510
530
|
const db = new Database(dbPath, { readonly: true });
|
|
511
531
|
try {
|
|
512
|
-
db.
|
|
532
|
+
db.query("SELECT name FROM sqlite_master LIMIT 1").get();
|
|
513
533
|
return db;
|
|
514
534
|
} catch (error) {
|
|
515
535
|
db.close();
|
|
516
|
-
throw error;
|
|
536
|
+
if (!isSqliteCantOpenError(error)) throw error;
|
|
517
537
|
}
|
|
538
|
+
return new Database(`${pathToFileURL(dbPath).href}?immutable=1`, CODEX_READONLY_DB_OPEN_FLAGS);
|
|
518
539
|
};
|
|
519
540
|
var openWritableDb = (dbPath, busyTimeoutMs) => {
|
|
520
541
|
const db = new Database(dbPath);
|
|
@@ -550,7 +571,7 @@ var parseJsonSafely$1 = (value) => {
|
|
|
550
571
|
};
|
|
551
572
|
var withReadonlyDb = (dbPath, callback) => {
|
|
552
573
|
return runWithSqliteRetry({ action: () => {
|
|
553
|
-
const db = openReadonlyDb(dbPath
|
|
574
|
+
const db = openReadonlyDb(dbPath);
|
|
554
575
|
try {
|
|
555
576
|
const result = callback(db);
|
|
556
577
|
if (isPromiseLike(result)) throw new Error("Database callbacks must be synchronous");
|
|
@@ -581,9 +602,7 @@ var resolveCodexThreadDbPath = () => {
|
|
|
581
602
|
path.join(os.homedir(), ".codex", "state_5.sqlite")
|
|
582
603
|
];
|
|
583
604
|
for (const candidate of candidates) try {
|
|
584
|
-
|
|
585
|
-
return openReadonlyDb(candidate, 1500);
|
|
586
|
-
} }).close();
|
|
605
|
+
if (!statSync(candidate).isFile()) continue;
|
|
587
606
|
return candidate;
|
|
588
607
|
} catch {}
|
|
589
608
|
throw new Error(`Unable to open Codex thread database. Tried: ${candidates.join(", ")}`);
|
|
@@ -593,6 +612,256 @@ var readAllThreads = (dbPath) => {
|
|
|
593
612
|
return db.query("SELECT * FROM threads ORDER BY COALESCE(updated_at_ms, updated_at * 1000) DESC, id DESC").all();
|
|
594
613
|
});
|
|
595
614
|
};
|
|
615
|
+
var resolveCodexDirFromDbPath$1 = (dbPath) => {
|
|
616
|
+
const dbDir = path.dirname(dbPath);
|
|
617
|
+
return path.basename(dbDir) === "sqlite" ? path.dirname(dbDir) : dbDir;
|
|
618
|
+
};
|
|
619
|
+
var parseJsonlObject = (line) => {
|
|
620
|
+
try {
|
|
621
|
+
return JSON.parse(line);
|
|
622
|
+
} catch {
|
|
623
|
+
return null;
|
|
624
|
+
}
|
|
625
|
+
};
|
|
626
|
+
var emitJsonlLine = (line, onRecord) => {
|
|
627
|
+
const trimmed = line.trim();
|
|
628
|
+
const parsed = trimmed ? parseJsonlObject(trimmed) : null;
|
|
629
|
+
if (parsed) onRecord(parsed);
|
|
630
|
+
};
|
|
631
|
+
var emitCompleteJsonlLines = (text, onRecord) => {
|
|
632
|
+
const lines = text.split(/\r?\n/u);
|
|
633
|
+
const pending = lines.pop() ?? "";
|
|
634
|
+
for (const line of lines) emitJsonlLine(line, onRecord);
|
|
635
|
+
return pending;
|
|
636
|
+
};
|
|
637
|
+
var readJsonlObjects = (filePath, onRecord) => {
|
|
638
|
+
let descriptor = null;
|
|
639
|
+
try {
|
|
640
|
+
if (!statSync(filePath).isFile()) return;
|
|
641
|
+
descriptor = openSync(filePath, "r");
|
|
642
|
+
const buffer = Buffer.alloc(JSONL_READ_CHUNK_BYTES);
|
|
643
|
+
const decoder = new StringDecoder("utf8");
|
|
644
|
+
let position = 0;
|
|
645
|
+
let pending = "";
|
|
646
|
+
while (true) {
|
|
647
|
+
const bytesRead = readSync(descriptor, buffer, 0, buffer.length, position);
|
|
648
|
+
if (bytesRead === 0) break;
|
|
649
|
+
position += bytesRead;
|
|
650
|
+
pending += decoder.write(buffer.subarray(0, bytesRead));
|
|
651
|
+
pending = emitCompleteJsonlLines(pending, onRecord);
|
|
652
|
+
}
|
|
653
|
+
emitJsonlLine(pending + decoder.end(), onRecord);
|
|
654
|
+
} catch {
|
|
655
|
+
return;
|
|
656
|
+
} finally {
|
|
657
|
+
if (descriptor !== null) closeSync(descriptor);
|
|
658
|
+
}
|
|
659
|
+
};
|
|
660
|
+
var collectJsonlObjects = (filePath) => {
|
|
661
|
+
const records = [];
|
|
662
|
+
readJsonlObjects(filePath, (record) => {
|
|
663
|
+
records.push(record);
|
|
664
|
+
});
|
|
665
|
+
return records;
|
|
666
|
+
};
|
|
667
|
+
var readSessionIndexEntries = (codexDir) => {
|
|
668
|
+
return collectJsonlObjects(path.join(codexDir, "session_index.jsonl")).filter((entry) => typeof entry.id === "string" && entry.id.length > 0);
|
|
669
|
+
};
|
|
670
|
+
var collectSessionFilesByThreadId = (sessionsDir) => {
|
|
671
|
+
const sessionFiles = /* @__PURE__ */ new Map();
|
|
672
|
+
const visit = (directory) => {
|
|
673
|
+
const entries = (() => {
|
|
674
|
+
try {
|
|
675
|
+
return readdirSync(directory, { withFileTypes: true });
|
|
676
|
+
} catch {
|
|
677
|
+
return null;
|
|
678
|
+
}
|
|
679
|
+
})();
|
|
680
|
+
if (!entries) return;
|
|
681
|
+
for (const entry of entries) {
|
|
682
|
+
const entryPath = path.join(directory, entry.name);
|
|
683
|
+
if (entry.isDirectory()) {
|
|
684
|
+
visit(entryPath);
|
|
685
|
+
continue;
|
|
686
|
+
}
|
|
687
|
+
if (!entry.isFile()) continue;
|
|
688
|
+
const threadId = THREAD_ID_PATTERN.exec(entry.name)?.[1];
|
|
689
|
+
if (threadId && !sessionFiles.has(threadId)) sessionFiles.set(threadId, entryPath);
|
|
690
|
+
}
|
|
691
|
+
};
|
|
692
|
+
visit(sessionsDir);
|
|
693
|
+
return sessionFiles;
|
|
694
|
+
};
|
|
695
|
+
var readSessionMetaLine = (sessionFile) => {
|
|
696
|
+
let descriptor = null;
|
|
697
|
+
try {
|
|
698
|
+
descriptor = openSync(sessionFile, "r");
|
|
699
|
+
const chunks = [];
|
|
700
|
+
let totalBytes = 0;
|
|
701
|
+
while (totalBytes < SESSION_META_READ_LIMIT_BYTES) {
|
|
702
|
+
const buffer = Buffer.alloc(Math.min(64 * 1024, SESSION_META_READ_LIMIT_BYTES - totalBytes));
|
|
703
|
+
const bytesRead = readSync(descriptor, buffer, 0, buffer.length, totalBytes);
|
|
704
|
+
if (bytesRead === 0) break;
|
|
705
|
+
chunks.push(buffer.subarray(0, bytesRead));
|
|
706
|
+
totalBytes += bytesRead;
|
|
707
|
+
if (buffer.subarray(0, bytesRead).includes(10)) break;
|
|
708
|
+
}
|
|
709
|
+
return Buffer.concat(chunks).toString("utf8").split(/\r?\n/u)[0]?.trim() || null;
|
|
710
|
+
} catch {
|
|
711
|
+
return null;
|
|
712
|
+
} finally {
|
|
713
|
+
if (descriptor !== null) closeSync(descriptor);
|
|
714
|
+
}
|
|
715
|
+
};
|
|
716
|
+
var readFallbackSessionMeta = (sessionFile) => {
|
|
717
|
+
const line = readSessionMetaLine(sessionFile);
|
|
718
|
+
if (!line) return null;
|
|
719
|
+
try {
|
|
720
|
+
const record = JSON.parse(line);
|
|
721
|
+
return record.type === "session_meta" && record.payload ? record.payload : null;
|
|
722
|
+
} catch {
|
|
723
|
+
return null;
|
|
724
|
+
}
|
|
725
|
+
};
|
|
726
|
+
var parseIsoMs = (value, fallback) => {
|
|
727
|
+
if (!value) return fallback;
|
|
728
|
+
const parsed = Date.parse(value);
|
|
729
|
+
return Number.isFinite(parsed) ? parsed : fallback;
|
|
730
|
+
};
|
|
731
|
+
var stringOrNull = (value) => typeof value === "string" && value.length > 0 ? value : null;
|
|
732
|
+
var numberOrNull = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
733
|
+
var objectOrNull = (value) => {
|
|
734
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
735
|
+
};
|
|
736
|
+
var isFallbackSubagent = (sessionMeta) => {
|
|
737
|
+
return Boolean(sessionMeta.thread_source === "subagent" || stringOrNull(sessionMeta.parent_thread_id) || stringOrNull(sessionMeta.forked_from_id));
|
|
738
|
+
};
|
|
739
|
+
var readFallbackRolloutStats = (sessionFile) => {
|
|
740
|
+
let model = null;
|
|
741
|
+
let tokensUsed = 0;
|
|
742
|
+
readJsonlObjects(sessionFile, (record) => {
|
|
743
|
+
const payload = objectOrNull(record.payload);
|
|
744
|
+
if (!payload) return;
|
|
745
|
+
if (record.type === "turn_context") {
|
|
746
|
+
model = stringOrNull(payload.model) ?? model;
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
const payloadType = stringOrNull(payload.type);
|
|
750
|
+
if (payloadType === "message" || payloadType === "agent_message") {
|
|
751
|
+
model = stringOrNull(payload.model) ?? model;
|
|
752
|
+
return;
|
|
753
|
+
}
|
|
754
|
+
if (payloadType !== "token_count") return;
|
|
755
|
+
tokensUsed = numberOrNull(objectOrNull(objectOrNull(payload.info)?.total_token_usage)?.total_tokens) ?? tokensUsed;
|
|
756
|
+
});
|
|
757
|
+
return {
|
|
758
|
+
model,
|
|
759
|
+
tokensUsed
|
|
760
|
+
};
|
|
761
|
+
};
|
|
762
|
+
var buildFallbackThreadRow = (entry, sessionFile, sessionMeta, rolloutStats) => {
|
|
763
|
+
const cwd = stringOrNull(sessionMeta.cwd);
|
|
764
|
+
if (!cwd) return null;
|
|
765
|
+
let mtimeMs = Date.now();
|
|
766
|
+
try {
|
|
767
|
+
mtimeMs = statSync(sessionFile).mtimeMs;
|
|
768
|
+
} catch {}
|
|
769
|
+
const updatedAtMs = parseIsoMs(entry.updated_at, mtimeMs);
|
|
770
|
+
const createdAtMs = parseIsoMs(sessionMeta.timestamp, updatedAtMs);
|
|
771
|
+
const title = entry.thread_name?.trim() || path.basename(sessionFile, ".jsonl");
|
|
772
|
+
const source = stringOrNull(sessionMeta.source) ?? "session_file";
|
|
773
|
+
return {
|
|
774
|
+
agent_nickname: sessionMeta.agent_nickname ?? null,
|
|
775
|
+
agent_path: sessionMeta.agent_path ?? null,
|
|
776
|
+
agent_role: sessionMeta.agent_role ?? null,
|
|
777
|
+
approval_mode: "unknown",
|
|
778
|
+
archived: 0,
|
|
779
|
+
archived_at: null,
|
|
780
|
+
cli_version: sessionMeta.cli_version ?? "",
|
|
781
|
+
created_at: Math.floor(createdAtMs / 1e3),
|
|
782
|
+
created_at_ms: Math.floor(createdAtMs),
|
|
783
|
+
cwd,
|
|
784
|
+
first_user_message: title,
|
|
785
|
+
git_branch: null,
|
|
786
|
+
git_origin_url: null,
|
|
787
|
+
git_sha: null,
|
|
788
|
+
has_user_event: sessionMeta.thread_source === "user" ? 1 : 0,
|
|
789
|
+
id: entry.id,
|
|
790
|
+
memory_mode: "enabled",
|
|
791
|
+
model: rolloutStats.model,
|
|
792
|
+
model_provider: sessionMeta.model_provider ?? "unknown",
|
|
793
|
+
preview: title,
|
|
794
|
+
reasoning_effort: null,
|
|
795
|
+
rollout_path: sessionFile,
|
|
796
|
+
sandbox_policy: "{}",
|
|
797
|
+
source,
|
|
798
|
+
thread_source: sessionMeta.thread_source ?? null,
|
|
799
|
+
title,
|
|
800
|
+
tokens_used: rolloutStats.tokensUsed,
|
|
801
|
+
updated_at: Math.floor(updatedAtMs / 1e3),
|
|
802
|
+
updated_at_ms: Math.floor(updatedAtMs)
|
|
803
|
+
};
|
|
804
|
+
};
|
|
805
|
+
var readFallbackThreadRows = (dbPath, existingThreadIds, projectName = null, options = {}) => {
|
|
806
|
+
const codexDir = resolveCodexDirFromDbPath$1(dbPath);
|
|
807
|
+
const sessionFilesByThreadId = collectSessionFilesByThreadId(path.join(codexDir, "sessions"));
|
|
808
|
+
const fallbackThreads = [];
|
|
809
|
+
for (const entry of readSessionIndexEntries(codexDir)) {
|
|
810
|
+
if (existingThreadIds.has(entry.id)) continue;
|
|
811
|
+
const sessionFile = sessionFilesByThreadId.get(entry.id);
|
|
812
|
+
if (!sessionFile) continue;
|
|
813
|
+
const sessionMeta = readFallbackSessionMeta(sessionFile);
|
|
814
|
+
if (!sessionMeta) continue;
|
|
815
|
+
if (!options.includeSubagents && isFallbackSubagent(sessionMeta)) continue;
|
|
816
|
+
const fallbackThread = buildFallbackThreadRow(entry, sessionFile, sessionMeta, readFallbackRolloutStats(sessionFile));
|
|
817
|
+
if (!fallbackThread || projectName && getPortablePathBasename(fallbackThread.cwd) !== projectName) continue;
|
|
818
|
+
fallbackThreads.push(fallbackThread);
|
|
819
|
+
}
|
|
820
|
+
return fallbackThreads;
|
|
821
|
+
};
|
|
822
|
+
var mergeFallbackThreadRows = (dbPath, threads, projectName = null) => {
|
|
823
|
+
const threadIds = new Set(threads.map((thread) => thread.id));
|
|
824
|
+
return [...threads, ...readFallbackThreadRows(dbPath, threadIds, projectName)].sort((left, right) => {
|
|
825
|
+
const updatedDifference = toTimestampMs(right) - toTimestampMs(left);
|
|
826
|
+
if (updatedDifference !== 0) return updatedDifference;
|
|
827
|
+
return right.id.localeCompare(left.id);
|
|
828
|
+
});
|
|
829
|
+
};
|
|
830
|
+
var applyRolloutActivityTimestamps = (threads) => {
|
|
831
|
+
return threads.map((thread) => {
|
|
832
|
+
let rolloutUpdatedAtMs = toTimestampMs(thread);
|
|
833
|
+
try {
|
|
834
|
+
rolloutUpdatedAtMs = Math.max(rolloutUpdatedAtMs, statSync(thread.rollout_path).mtimeMs);
|
|
835
|
+
} catch {}
|
|
836
|
+
if (rolloutUpdatedAtMs <= toTimestampMs(thread)) return thread;
|
|
837
|
+
return {
|
|
838
|
+
...thread,
|
|
839
|
+
updated_at: Math.floor(rolloutUpdatedAtMs / 1e3),
|
|
840
|
+
updated_at_ms: Math.floor(rolloutUpdatedAtMs)
|
|
841
|
+
};
|
|
842
|
+
}).sort((left, right) => {
|
|
843
|
+
const updatedDifference = toTimestampMs(right) - toTimestampMs(left);
|
|
844
|
+
if (updatedDifference !== 0) return updatedDifference;
|
|
845
|
+
return right.id.localeCompare(left.id);
|
|
846
|
+
});
|
|
847
|
+
};
|
|
848
|
+
var buildDashboardRecentThreads = (threads) => {
|
|
849
|
+
const bestThreadByProject = /* @__PURE__ */ new Map();
|
|
850
|
+
for (const thread of threads) {
|
|
851
|
+
const project = getPortablePathBasename(thread.cwd);
|
|
852
|
+
if (!project) continue;
|
|
853
|
+
const current = bestThreadByProject.get(project);
|
|
854
|
+
if (!current || toTimestampMs(thread) > toTimestampMs(current)) bestThreadByProject.set(project, thread);
|
|
855
|
+
}
|
|
856
|
+
return [...bestThreadByProject.values()].sort((left, right) => {
|
|
857
|
+
const updatedDifference = toTimestampMs(right) - toTimestampMs(left);
|
|
858
|
+
if (updatedDifference !== 0) return updatedDifference;
|
|
859
|
+
return right.id.localeCompare(left.id);
|
|
860
|
+
}).slice(0, 5).map((thread) => ({
|
|
861
|
+
project: getPortablePathBasename(thread.cwd),
|
|
862
|
+
thread: compactThreadListRow(thread)
|
|
863
|
+
}));
|
|
864
|
+
};
|
|
596
865
|
var filterThreadsByProject = (threads, projectName) => {
|
|
597
866
|
if (!projectName) return threads;
|
|
598
867
|
return threads.filter((thread) => getPortablePathBasename(thread.cwd) === projectName);
|
|
@@ -697,7 +966,7 @@ var deleteThreadSessionFiles = async (sessionFiles) => {
|
|
|
697
966
|
return uniqueSessionFiles;
|
|
698
967
|
};
|
|
699
968
|
var listCodexProjects = (dbPath) => {
|
|
700
|
-
return mapProjectSummaries(buildProjectSummaryMap(readAllThreads(dbPath)));
|
|
969
|
+
return mapProjectSummaries(buildProjectSummaryMap(applyRolloutActivityTimestamps(mergeFallbackThreadRows(dbPath, readAllThreads(dbPath)))));
|
|
701
970
|
};
|
|
702
971
|
var compactThreadListRow = (thread) => {
|
|
703
972
|
return {
|
|
@@ -707,8 +976,19 @@ var compactThreadListRow = (thread) => {
|
|
|
707
976
|
};
|
|
708
977
|
};
|
|
709
978
|
var listProjectThreads = async (dbPath, projectName, options = {}) => {
|
|
710
|
-
return (await mapWithConcurrency(filterThreadsByProject(readAllThreads(dbPath), projectName), THREAD_LIST_IO_CONCURRENCY, async (thread) => {
|
|
979
|
+
return (await mapWithConcurrency(applyRolloutActivityTimestamps(mergeFallbackThreadRows(dbPath, filterThreadsByProject(readAllThreads(dbPath), projectName), projectName)), THREAD_LIST_IO_CONCURRENCY, async (thread) => {
|
|
711
980
|
const rollout = await getThreadRolloutLoadState(thread.rollout_path, options.largeTranscriptThresholdBytes);
|
|
981
|
+
if (rollout.fileSizeBytes === null) return {
|
|
982
|
+
project: projectName,
|
|
983
|
+
rolloutSizeBytes: null,
|
|
984
|
+
stats: {
|
|
985
|
+
deferred: false,
|
|
986
|
+
execCommandCount: 0,
|
|
987
|
+
toolCallCount: 0,
|
|
988
|
+
webSearchEventCount: 0
|
|
989
|
+
},
|
|
990
|
+
thread: compactThreadListRow(thread)
|
|
991
|
+
};
|
|
712
992
|
if (rollout.shouldDeferTranscriptLoad) return {
|
|
713
993
|
project: projectName,
|
|
714
994
|
rolloutSizeBytes: rollout.fileSizeBytes,
|
|
@@ -737,10 +1017,11 @@ var listProjectThreads = async (dbPath, projectName, options = {}) => {
|
|
|
737
1017
|
var getThreadBrowseData = (dbPath, threadId) => {
|
|
738
1018
|
return withReadonlyDb(dbPath, (db) => {
|
|
739
1019
|
const existingTableNames = getExistingTableNames(db);
|
|
740
|
-
const
|
|
1020
|
+
const dbThread = db.query("SELECT * FROM threads WHERE id = ? LIMIT 1").get(threadId);
|
|
1021
|
+
const thread = dbThread ?? readFallbackThreadRows(dbPath, /* @__PURE__ */ new Set(), null, { includeSubagents: true }).find((fallbackThread) => fallbackThread.id === threadId) ?? null;
|
|
741
1022
|
if (!thread) throw new Error(`Thread not found: ${threadId}`);
|
|
742
1023
|
return {
|
|
743
|
-
dynamicTools: (existingTableNames.has("thread_dynamic_tools") ? db.query("SELECT thread_id, position, name, description, input_schema, defer_loading, namespace FROM thread_dynamic_tools WHERE thread_id = ? ORDER BY position ASC").all(threadId) : []).map((row) => parseDynamicToolRow(row)),
|
|
1024
|
+
dynamicTools: (dbThread && existingTableNames.has("thread_dynamic_tools") ? db.query("SELECT thread_id, position, name, description, input_schema, defer_loading, namespace FROM thread_dynamic_tools WHERE thread_id = ? ORDER BY position ASC").all(threadId) : []).map((row) => parseDynamicToolRow(row)),
|
|
744
1025
|
project: getPortablePathBasename(thread.cwd),
|
|
745
1026
|
relations: getRelationsForThread(db, threadId, existingTableNames),
|
|
746
1027
|
thread
|
|
@@ -748,7 +1029,7 @@ var getThreadBrowseData = (dbPath, threadId) => {
|
|
|
748
1029
|
});
|
|
749
1030
|
};
|
|
750
1031
|
var getCodexDashboardSummary = (dbPath) => {
|
|
751
|
-
const threads = readAllThreads(dbPath);
|
|
1032
|
+
const threads = applyRolloutActivityTimestamps(mergeFallbackThreadRows(dbPath, readAllThreads(dbPath)));
|
|
752
1033
|
const projects = mapProjectSummaries(buildProjectSummaryMap(threads));
|
|
753
1034
|
const threadsWithRelations = withReadonlyDb(dbPath, (db) => {
|
|
754
1035
|
if (!getExistingTableNames(db).has("thread_spawn_edges")) return 0;
|
|
@@ -758,10 +1039,7 @@ var getCodexDashboardSummary = (dbPath) => {
|
|
|
758
1039
|
return {
|
|
759
1040
|
activeThreads: threads.filter((thread) => !thread.archived).length,
|
|
760
1041
|
archivedThreads: threads.filter((thread) => Boolean(thread.archived)).length,
|
|
761
|
-
recentThreads: threads
|
|
762
|
-
project: getPortablePathBasename(thread.cwd),
|
|
763
|
-
thread: compactThreadListRow(thread)
|
|
764
|
-
})),
|
|
1042
|
+
recentThreads: buildDashboardRecentThreads(threads),
|
|
765
1043
|
threadsWithRelations,
|
|
766
1044
|
topProjectsByThreadCount: [...projects].sort((left, right) => {
|
|
767
1045
|
if (left.threadCount !== right.threadCount) return right.threadCount - left.threadCount;
|
|
@@ -828,13 +1106,16 @@ var deleteCodexProject = async (dbPath, projectName, options = {}) => {
|
|
|
828
1106
|
}
|
|
829
1107
|
};
|
|
830
1108
|
var listScopedThreads = (dbPath, projectName) => {
|
|
831
|
-
return filterThreadsByProject(readAllThreads(dbPath), projectName);
|
|
1109
|
+
return mergeFallbackThreadRows(dbPath, filterThreadsByProject(readAllThreads(dbPath), projectName), projectName);
|
|
832
1110
|
};
|
|
833
1111
|
var invalidateCodexUiCaches = async () => {
|
|
834
1112
|
await invalidateCacheByPrefix("analytics-", "thread-");
|
|
835
1113
|
};
|
|
836
|
-
|
|
837
|
-
|
|
1114
|
+
var resolveAnalyticsTranscriptConcurrency = (configuredValue = process.env.SPIRACHA_ANALYTICS_TRANSCRIPT_CONCURRENCY) => {
|
|
1115
|
+
const parsed = Number(configuredValue);
|
|
1116
|
+
if (!Number.isInteger(parsed) || parsed < 1) return 8;
|
|
1117
|
+
return parsed;
|
|
1118
|
+
};
|
|
838
1119
|
var roundToTwoDecimals = (value) => {
|
|
839
1120
|
return Number(value.toFixed(2));
|
|
840
1121
|
};
|
|
@@ -870,20 +1151,68 @@ var buildModelsByTokens = (threads) => {
|
|
|
870
1151
|
return left.model.localeCompare(right.model);
|
|
871
1152
|
});
|
|
872
1153
|
};
|
|
873
|
-
var
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
1154
|
+
var timestampSignature = (thread) => {
|
|
1155
|
+
return String(thread.updated_at_ms ?? thread.updated_at * 1e3);
|
|
1156
|
+
};
|
|
1157
|
+
var threadMetadataCacheKeyParts = (thread) => [
|
|
1158
|
+
thread.id,
|
|
1159
|
+
thread.rollout_path,
|
|
1160
|
+
timestampSignature(thread),
|
|
1161
|
+
String(thread.created_at_ms ?? thread.created_at * 1e3),
|
|
1162
|
+
String(thread.tokens_used),
|
|
1163
|
+
String(thread.archived),
|
|
1164
|
+
String(thread.archived_at ?? ""),
|
|
1165
|
+
thread.cwd,
|
|
1166
|
+
thread.model ?? "",
|
|
1167
|
+
thread.model_provider,
|
|
1168
|
+
thread.cli_version,
|
|
1169
|
+
thread.title,
|
|
1170
|
+
thread.preview
|
|
1171
|
+
];
|
|
1172
|
+
var buildCodexAnalyticsCacheKey = (dbPath, threads, project) => {
|
|
1173
|
+
return `analytics-${hashCacheKeyPartsIterable((function* () {
|
|
1174
|
+
yield "v2";
|
|
1175
|
+
yield dbPath;
|
|
1176
|
+
yield project ?? "all";
|
|
1177
|
+
yield String(threads.length);
|
|
1178
|
+
for (const thread of threads) yield* threadMetadataCacheKeyParts(thread);
|
|
1179
|
+
})())}`;
|
|
1180
|
+
};
|
|
1181
|
+
var buildThreadAnalyticsCacheKey = (thread) => {
|
|
1182
|
+
return `thread-analytics-${hashCacheKeyParts("v1", ...threadMetadataCacheKeyParts(thread))}`;
|
|
1183
|
+
};
|
|
1184
|
+
var parseThreadAnalyticsFile = async (sessionFile) => {
|
|
1185
|
+
const toolNames = [];
|
|
1186
|
+
let hasWebSearch = false;
|
|
1187
|
+
for await (const parsed of readJsonlObjects$1(sessionFile)) {
|
|
1188
|
+
if (parsed.type !== "response_item") continue;
|
|
1189
|
+
const payload = asObject(parsed.payload);
|
|
1190
|
+
if (!payload) continue;
|
|
1191
|
+
const payloadType = asString(payload.type);
|
|
1192
|
+
if (payloadType === "function_call") {
|
|
1193
|
+
toolNames.push(asString(payload.name) ?? "unknown");
|
|
1194
|
+
continue;
|
|
1195
|
+
}
|
|
1196
|
+
if (payloadType === "web_search_call" || payloadType === "web_search_end") hasWebSearch = true;
|
|
1197
|
+
}
|
|
1198
|
+
return {
|
|
1199
|
+
hasWebSearch,
|
|
1200
|
+
toolNames
|
|
1201
|
+
};
|
|
1202
|
+
};
|
|
1203
|
+
var getCachedThreadAnalytics = async (thread) => {
|
|
1204
|
+
return withCachedJson(buildThreadAnalyticsCacheKey(thread), () => parseThreadAnalyticsFile(thread.rollout_path));
|
|
877
1205
|
};
|
|
878
|
-
var
|
|
1206
|
+
var computeCodexAnalyticsFromThreads = async (threads, options = {}) => {
|
|
879
1207
|
const totalTokens = threads.reduce((sum, thread) => sum + thread.tokens_used, 0);
|
|
880
1208
|
const projectNames = new Set(threads.map((thread) => getPortablePathBasename(thread.cwd)).filter(Boolean));
|
|
881
1209
|
const toolUsage = /* @__PURE__ */ new Map();
|
|
882
|
-
const transcripts = await Promise.all(threads.map((thread) => getCachedParsedCodexTranscript(thread.rollout_path)));
|
|
883
1210
|
let threadsWithWebSearch = 0;
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
1211
|
+
const loadThreadAnalytics = options.loadThreadAnalytics ?? getCachedThreadAnalytics;
|
|
1212
|
+
const threadAnalytics = await mapWithConcurrency(threads, options.transcriptConcurrency ?? resolveAnalyticsTranscriptConcurrency(), (thread) => loadThreadAnalytics(thread));
|
|
1213
|
+
for (const analytics of threadAnalytics) {
|
|
1214
|
+
if (analytics.hasWebSearch) threadsWithWebSearch += 1;
|
|
1215
|
+
for (const toolName of analytics.toolNames) incrementCount(toolUsage, toolName);
|
|
887
1216
|
}
|
|
888
1217
|
return {
|
|
889
1218
|
modelsByTokens: buildModelsByTokens(threads),
|
|
@@ -904,7 +1233,7 @@ var computeCodexAnalytics = async (threads) => {
|
|
|
904
1233
|
};
|
|
905
1234
|
var getCodexAnalytics = async (input) => {
|
|
906
1235
|
const threads = listScopedThreads(input.dbPath, input.project);
|
|
907
|
-
return withCachedJson(
|
|
1236
|
+
return withCachedJson(buildCodexAnalyticsCacheKey(input.dbPath, threads, input.project), async () => computeCodexAnalyticsFromThreads(threads, { transcriptConcurrency: input.transcriptConcurrency }));
|
|
908
1237
|
};
|
|
909
1238
|
//#endregion
|
|
910
1239
|
//#region ../../src/lib/codex-exporter-db.ts
|
|
@@ -956,7 +1285,7 @@ var writeSessionFileExport = async (target, options, outputPath, transform = (te
|
|
|
956
1285
|
let wroteSection = false;
|
|
957
1286
|
try {
|
|
958
1287
|
transcriptStream = await createExportWriteStream(transcriptOutputPath);
|
|
959
|
-
for await (const parsed of readJsonlObjects(target.sessionFile)) {
|
|
1288
|
+
for await (const parsed of readJsonlObjects$1(target.sessionFile)) {
|
|
960
1289
|
captureSessionMeta(parsed, state.sessionMeta);
|
|
961
1290
|
const block = renderCodexTranscriptRecord(parsed, options, state);
|
|
962
1291
|
if (!block) continue;
|
|
@@ -993,7 +1322,7 @@ var collectCodexTranscript = async (sessionFile, options, assistantModel = null)
|
|
|
993
1322
|
sections: [],
|
|
994
1323
|
sessionMeta: {}
|
|
995
1324
|
};
|
|
996
|
-
for await (const parsed of readJsonlObjects(sessionFile)) processCodexTranscriptRecord(parsed, options, state);
|
|
1325
|
+
for await (const parsed of readJsonlObjects$1(sessionFile)) processCodexTranscriptRecord(parsed, options, state);
|
|
997
1326
|
return state;
|
|
998
1327
|
};
|
|
999
1328
|
var getSectionSeparator = () => "\n";
|
|
@@ -1388,47 +1717,20 @@ var extractContentPart = (value) => {
|
|
|
1388
1717
|
if (type === "input_image") return "[Image attached]";
|
|
1389
1718
|
return text ?? "";
|
|
1390
1719
|
};
|
|
1391
|
-
var UI_EXPORT_URL_PREFIX = "/__exports/";
|
|
1392
|
-
var DEFAULT_UI_EXPORT_DIR = path.join(os.tmpdir(), "spiracha-ui-exports");
|
|
1393
|
-
var DEFAULT_EXPORT_MAX_AGE_MS = 1440 * 60 * 1e3;
|
|
1394
|
-
var getUiExportDir = () => {
|
|
1395
|
-
return process.env["SPIRACHA_UI_EXPORT_DIR"]?.trim() || DEFAULT_UI_EXPORT_DIR;
|
|
1396
|
-
};
|
|
1397
|
-
var ensureUiExportDir = async () => {
|
|
1398
|
-
const exportDir = getUiExportDir();
|
|
1399
|
-
await mkdir(exportDir, { recursive: true });
|
|
1400
|
-
await purgeStaleUiExports(exportDir);
|
|
1401
|
-
return exportDir;
|
|
1402
|
-
};
|
|
1403
|
-
var buildUiExportDownloadUrl = (filePath) => {
|
|
1404
|
-
return `${UI_EXPORT_URL_PREFIX}${encodeURIComponent(path.basename(filePath))}`;
|
|
1405
|
-
};
|
|
1406
|
-
var purgeStaleUiExports = async (exportDir = getUiExportDir(), maxAgeMs = DEFAULT_EXPORT_MAX_AGE_MS) => {
|
|
1407
|
-
const entries = await readdir(exportDir, { withFileTypes: true });
|
|
1408
|
-
const cutoff = Date.now() - maxAgeMs;
|
|
1409
|
-
await Promise.all(entries.filter((entry) => entry.isFile()).map(async (entry) => {
|
|
1410
|
-
const filePath = path.join(exportDir, entry.name);
|
|
1411
|
-
if ((await stat(filePath)).mtimeMs >= cutoff) return;
|
|
1412
|
-
await rm(filePath, { force: true });
|
|
1413
|
-
}));
|
|
1414
|
-
};
|
|
1415
1720
|
//#endregion
|
|
1416
1721
|
//#region ../../src/lib/codex-browser-export.ts
|
|
1417
1722
|
var LARGE_BROWSER_EXPORT_THRESHOLD_BYTES = 128 * 1024 * 1024;
|
|
1418
|
-
var toSanitizedFileName = (value) => {
|
|
1419
|
-
return value.replace(/[<>:"/\\|?*\u0000-\u001f]/gu, " ").replace(/\.\.+/gu, " ").replace(/\s+/gu, " ").trim();
|
|
1420
|
-
};
|
|
1421
1723
|
var formatReadableExportDate = (value) => {
|
|
1422
1724
|
const date = new Date(value);
|
|
1423
1725
|
return `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, "0")}-${String(date.getUTCDate()).padStart(2, "0")}-${String(date.getUTCHours()).padStart(2, "0")}${String(date.getUTCMinutes()).padStart(2, "0")}`;
|
|
1424
1726
|
};
|
|
1425
1727
|
var buildExportBaseName = (thread) => {
|
|
1426
|
-
return `${
|
|
1728
|
+
return `${sanitizeExportFileName(getPortablePathBasename(thread.cwd) || "thread") || "thread"}-${formatReadableExportDate(thread.updated_at_ms ?? thread.updated_at * 1e3)}-${thread.id.slice(0, 8)}`;
|
|
1427
1729
|
};
|
|
1428
1730
|
var buildBatchExportBaseName = (threads) => {
|
|
1429
1731
|
const firstThread = threads[0];
|
|
1430
1732
|
if (!firstThread) throw new Error("No threads selected for export");
|
|
1431
|
-
return `${
|
|
1733
|
+
return `${sanitizeExportFileName(getPortablePathBasename(firstThread.cwd) || "threads") || "threads"}-${formatReadableExportDate(Math.max(...threads.map((thread) => thread.updated_at_ms ?? thread.updated_at * 1e3)))}-threads-${threads.length}`;
|
|
1432
1734
|
};
|
|
1433
1735
|
var buildUniqueArchivePath = (exportDir, exportBaseName) => {
|
|
1434
1736
|
return path.join(exportDir, `${exportBaseName}-${randomUUID()}.zip`);
|
|
@@ -1457,9 +1759,6 @@ var toDownloadOptions = (input) => {
|
|
|
1457
1759
|
threadIds: [input.threadId]
|
|
1458
1760
|
};
|
|
1459
1761
|
};
|
|
1460
|
-
var getMimeType = (outputFormat) => {
|
|
1461
|
-
return outputFormat === "md" ? "text/markdown; charset=utf-8" : "text/plain; charset=utf-8";
|
|
1462
|
-
};
|
|
1463
1762
|
var resolvePublicExportDir = async (publicExportDir) => {
|
|
1464
1763
|
if (publicExportDir) {
|
|
1465
1764
|
await ensureDirectory(publicExportDir);
|
|
@@ -1480,17 +1779,27 @@ var getRolloutSnapshot = async (rolloutPath) => {
|
|
|
1480
1779
|
sizeBytes: metadata.size
|
|
1481
1780
|
};
|
|
1482
1781
|
};
|
|
1782
|
+
var isMissingFileError$1 = (error) => {
|
|
1783
|
+
return error instanceof Error && "code" in error && error.code === "ENOENT";
|
|
1784
|
+
};
|
|
1785
|
+
var getExistingRolloutSnapshot = async (threadId, rolloutPath) => {
|
|
1786
|
+
try {
|
|
1787
|
+
return await getRolloutSnapshot(rolloutPath);
|
|
1788
|
+
} catch (error) {
|
|
1789
|
+
if (isMissingFileError$1(error)) throw new Error(`Thread ${threadId} rollout file is missing: ${rolloutPath}`, { cause: error });
|
|
1790
|
+
throw error;
|
|
1791
|
+
}
|
|
1792
|
+
};
|
|
1483
1793
|
var logExportEvent = (level, event, details) => {
|
|
1484
1794
|
console[level](`[spiracha:export] ${event}`, details);
|
|
1485
1795
|
};
|
|
1486
|
-
var logRolloutChangeIfDetected = (threadId,
|
|
1796
|
+
var logRolloutChangeIfDetected = (threadId, beforeSnapshot, afterSnapshot) => {
|
|
1487
1797
|
if (beforeSnapshot.mtimeMs === afterSnapshot.mtimeMs && beforeSnapshot.sizeBytes === afterSnapshot.sizeBytes) return;
|
|
1488
1798
|
logExportEvent("warn", "rollout_changed_during_export", {
|
|
1489
1799
|
afterMtimeMs: afterSnapshot.mtimeMs,
|
|
1490
1800
|
afterSizeBytes: afterSnapshot.sizeBytes,
|
|
1491
1801
|
beforeMtimeMs: beforeSnapshot.mtimeMs,
|
|
1492
1802
|
beforeSizeBytes: beforeSnapshot.sizeBytes,
|
|
1493
|
-
rolloutPath,
|
|
1494
1803
|
threadId
|
|
1495
1804
|
});
|
|
1496
1805
|
};
|
|
@@ -1507,63 +1816,25 @@ var cleanupExportWorkspace = async (workspacePath) => {
|
|
|
1507
1816
|
});
|
|
1508
1817
|
}
|
|
1509
1818
|
};
|
|
1510
|
-
var zipExportFile = async (sourcePath, zipPath) => {
|
|
1511
|
-
const proc = Bun.spawn([
|
|
1512
|
-
"zip",
|
|
1513
|
-
"-9",
|
|
1514
|
-
"-j",
|
|
1515
|
-
zipPath,
|
|
1516
|
-
sourcePath
|
|
1517
|
-
], {
|
|
1518
|
-
stderr: "pipe",
|
|
1519
|
-
stdout: "pipe"
|
|
1520
|
-
});
|
|
1521
|
-
const [stdoutText, stderrText, exitCode] = await Promise.all([
|
|
1522
|
-
new Response(proc.stdout).text(),
|
|
1523
|
-
new Response(proc.stderr).text(),
|
|
1524
|
-
proc.exited
|
|
1525
|
-
]);
|
|
1526
|
-
if (exitCode !== 0) throw new Error(`zip failed (${exitCode}): ${(stderrText || stdoutText).trim()}`);
|
|
1527
|
-
};
|
|
1528
|
-
var zipExportDirectory = async (sourceDirectory, zipPath) => {
|
|
1529
|
-
const proc = Bun.spawn([
|
|
1530
|
-
"zip",
|
|
1531
|
-
"-9",
|
|
1532
|
-
"-r",
|
|
1533
|
-
zipPath,
|
|
1534
|
-
"."
|
|
1535
|
-
], {
|
|
1536
|
-
cwd: sourceDirectory,
|
|
1537
|
-
stderr: "pipe",
|
|
1538
|
-
stdout: "pipe"
|
|
1539
|
-
});
|
|
1540
|
-
const [stdoutText, stderrText, exitCode] = await Promise.all([
|
|
1541
|
-
new Response(proc.stdout).text(),
|
|
1542
|
-
new Response(proc.stderr).text(),
|
|
1543
|
-
proc.exited
|
|
1544
|
-
]);
|
|
1545
|
-
if (exitCode !== 0) throw new Error(`zip failed (${exitCode}): ${(stderrText || stdoutText).trim()}`);
|
|
1546
|
-
};
|
|
1547
1819
|
var renderCodexThreadDownload = async (input) => {
|
|
1548
1820
|
const startedAt = Date.now();
|
|
1549
1821
|
const browseData = getThreadBrowseData(input.dbPath, input.threadId);
|
|
1550
1822
|
const extension = input.outputFormat === "md" ? "md" : "txt";
|
|
1551
1823
|
const fileBaseName = buildExportBaseName(browseData.thread);
|
|
1552
1824
|
const fileName = `${fileBaseName}.${extension}`;
|
|
1553
|
-
const mimeType =
|
|
1825
|
+
const mimeType = getExportMimeType(input.outputFormat);
|
|
1554
1826
|
const transform = (text) => input.pathDisplaySettings ? applyPathTransforms(text, {
|
|
1555
1827
|
...input.pathDisplaySettings,
|
|
1556
1828
|
projectPath: browseData.thread.cwd
|
|
1557
1829
|
}) : text;
|
|
1558
|
-
const rolloutSnapshotBefore = await
|
|
1830
|
+
const rolloutSnapshotBefore = await getExistingRolloutSnapshot(input.threadId, browseData.thread.rollout_path);
|
|
1559
1831
|
logExportEvent("info", "single_start", {
|
|
1560
1832
|
fileName,
|
|
1561
|
-
rolloutPath: browseData.thread.rollout_path,
|
|
1562
1833
|
sizeBytes: rolloutSnapshotBefore.sizeBytes,
|
|
1563
1834
|
threadId: input.threadId
|
|
1564
1835
|
});
|
|
1565
1836
|
try {
|
|
1566
|
-
if (rolloutSnapshotBefore.sizeBytes > (input.largeExportThresholdBytes ?? LARGE_BROWSER_EXPORT_THRESHOLD_BYTES)) {
|
|
1837
|
+
if (input.zipArchive || rolloutSnapshotBefore.sizeBytes > (input.largeExportThresholdBytes ?? LARGE_BROWSER_EXPORT_THRESHOLD_BYTES)) {
|
|
1567
1838
|
const exportBaseName = fileBaseName;
|
|
1568
1839
|
const exportDir = await resolvePublicExportDir(input.publicExportDir);
|
|
1569
1840
|
const workspaceDir = await createExportWorkspace(exportDir, exportBaseName);
|
|
@@ -1582,7 +1853,7 @@ var renderCodexThreadDownload = async (input) => {
|
|
|
1582
1853
|
await cleanupExportWorkspace(workspaceDir);
|
|
1583
1854
|
}
|
|
1584
1855
|
const rolloutSnapshotAfter = await getRolloutSnapshot(browseData.thread.rollout_path);
|
|
1585
|
-
logRolloutChangeIfDetected(input.threadId,
|
|
1856
|
+
logRolloutChangeIfDetected(input.threadId, rolloutSnapshotBefore, rolloutSnapshotAfter);
|
|
1586
1857
|
const zipStat = await Bun.file(zipPath).stat();
|
|
1587
1858
|
logExportEvent("info", "single_zip_ready", {
|
|
1588
1859
|
downloadUrl: buildUiExportDownloadUrl(zipPath),
|
|
@@ -1608,7 +1879,7 @@ var renderCodexThreadDownload = async (input) => {
|
|
|
1608
1879
|
}, toDownloadOptions(input));
|
|
1609
1880
|
if (!content) throw new Error(`Thread ${input.threadId} produced no exportable content`);
|
|
1610
1881
|
const rolloutSnapshotAfter = await getRolloutSnapshot(browseData.thread.rollout_path);
|
|
1611
|
-
logRolloutChangeIfDetected(input.threadId,
|
|
1882
|
+
logRolloutChangeIfDetected(input.threadId, rolloutSnapshotBefore, rolloutSnapshotAfter);
|
|
1612
1883
|
logExportEvent("info", "single_inline_ready", {
|
|
1613
1884
|
durationMs: Date.now() - startedAt,
|
|
1614
1885
|
fileName,
|
|
@@ -1649,7 +1920,7 @@ var renderCodexThreadsDownload = async (input) => {
|
|
|
1649
1920
|
});
|
|
1650
1921
|
try {
|
|
1651
1922
|
for (const entry of browseEntries) {
|
|
1652
|
-
const rolloutSnapshotBefore = await
|
|
1923
|
+
const rolloutSnapshotBefore = await getExistingRolloutSnapshot(entry.thread.id, entry.thread.rollout_path);
|
|
1653
1924
|
const singleBaseName = buildExportBaseName(entry.thread);
|
|
1654
1925
|
const uniqueBaseName = buildUniqueBatchEntryBaseName(singleBaseName, entry.thread.id, usedBatchEntryBaseNames);
|
|
1655
1926
|
const relativeFileName = `${uniqueBaseName}.${input.outputFormat === "md" ? "md" : "txt"}`;
|
|
@@ -1677,7 +1948,7 @@ var renderCodexThreadsDownload = async (input) => {
|
|
|
1677
1948
|
threadIds: [entry.thread.id]
|
|
1678
1949
|
}, savedPath, transform)) throw new Error(`Thread ${entry.thread.id} produced no exportable content`);
|
|
1679
1950
|
const rolloutSnapshotAfter = await getRolloutSnapshot(entry.thread.rollout_path);
|
|
1680
|
-
logRolloutChangeIfDetected(entry.thread.id,
|
|
1951
|
+
logRolloutChangeIfDetected(entry.thread.id, rolloutSnapshotBefore, rolloutSnapshotAfter);
|
|
1681
1952
|
}
|
|
1682
1953
|
await zipExportDirectory(bundleDirectory, zipPath);
|
|
1683
1954
|
} catch (error) {
|
|
@@ -1863,7 +2134,8 @@ var exportSchema = z.object({
|
|
|
1863
2134
|
includeTools: z.boolean(),
|
|
1864
2135
|
outputFormat: z.enum(["md", "txt"]),
|
|
1865
2136
|
redactUsername: z.boolean(),
|
|
1866
|
-
threadId: z.string().min(1)
|
|
2137
|
+
threadId: z.string().min(1),
|
|
2138
|
+
zipArchive: z.boolean().default(false)
|
|
1867
2139
|
});
|
|
1868
2140
|
var exportThreadsSchema = z.object({
|
|
1869
2141
|
convertToProjectRoot: z.boolean(),
|
|
@@ -1872,7 +2144,8 @@ var exportThreadsSchema = z.object({
|
|
|
1872
2144
|
includeTools: z.boolean(),
|
|
1873
2145
|
outputFormat: z.enum(["md", "txt"]),
|
|
1874
2146
|
redactUsername: z.boolean(),
|
|
1875
|
-
threadIds: z.array(z.string().min(1)).min(1)
|
|
2147
|
+
threadIds: z.array(z.string().min(1)).min(1),
|
|
2148
|
+
zipArchive: z.boolean().default(true)
|
|
1876
2149
|
});
|
|
1877
2150
|
var getDbPath = () => process.env.SPIRACHA_CODEX_DB?.trim() || resolveCodexThreadDbPath();
|
|
1878
2151
|
var isMissingFileError = (error) => {
|
|
@@ -1899,7 +2172,7 @@ var listProjectThreadsFn_createServerFn_handler = createServerRpc({
|
|
|
1899
2172
|
name: "listProjectThreadsFn",
|
|
1900
2173
|
filename: "src/lib/codex-server.ts"
|
|
1901
2174
|
}, (opts) => listProjectThreadsFn.__executeServer(opts));
|
|
1902
|
-
var listProjectThreadsFn = createServerFn({ method: "GET" }).
|
|
2175
|
+
var listProjectThreadsFn = createServerFn({ method: "GET" }).validator(projectSchema).handler(listProjectThreadsFn_createServerFn_handler, async ({ data }) => {
|
|
1903
2176
|
return listProjectThreads(getDbPath(), data.project);
|
|
1904
2177
|
});
|
|
1905
2178
|
var getThreadSnapshotFn_createServerFn_handler = createServerRpc({
|
|
@@ -1907,7 +2180,7 @@ var getThreadSnapshotFn_createServerFn_handler = createServerRpc({
|
|
|
1907
2180
|
name: "getThreadSnapshotFn",
|
|
1908
2181
|
filename: "src/lib/codex-server.ts"
|
|
1909
2182
|
}, (opts) => getThreadSnapshotFn.__executeServer(opts));
|
|
1910
|
-
var getThreadSnapshotFn = createServerFn({ method: "GET" }).
|
|
2183
|
+
var getThreadSnapshotFn = createServerFn({ method: "GET" }).validator(threadSchema).handler(getThreadSnapshotFn_createServerFn_handler, async ({ data }) => {
|
|
1911
2184
|
const browseData = getThreadBrowseData(getDbPath(), data.threadId);
|
|
1912
2185
|
const rollout = await getThreadRolloutLoadState(browseData.thread.rollout_path);
|
|
1913
2186
|
let transcript = null;
|
|
@@ -1931,7 +2204,7 @@ var getThreadTranscriptFn_createServerFn_handler = createServerRpc({
|
|
|
1931
2204
|
name: "getThreadTranscriptFn",
|
|
1932
2205
|
filename: "src/lib/codex-server.ts"
|
|
1933
2206
|
}, (opts) => getThreadTranscriptFn.__executeServer(opts));
|
|
1934
|
-
var getThreadTranscriptFn = createServerFn({ method: "GET" }).
|
|
2207
|
+
var getThreadTranscriptFn = createServerFn({ method: "GET" }).validator(threadSchema).handler(getThreadTranscriptFn_createServerFn_handler, async ({ data }) => {
|
|
1935
2208
|
return getCachedThreadTranscriptPreview(getThreadBrowseData(getDbPath(), data.threadId).thread.rollout_path);
|
|
1936
2209
|
});
|
|
1937
2210
|
var getAnalyticsFn_createServerFn_handler = createServerRpc({
|
|
@@ -1939,7 +2212,7 @@ var getAnalyticsFn_createServerFn_handler = createServerRpc({
|
|
|
1939
2212
|
name: "getAnalyticsFn",
|
|
1940
2213
|
filename: "src/lib/codex-server.ts"
|
|
1941
2214
|
}, (opts) => getAnalyticsFn.__executeServer(opts));
|
|
1942
|
-
var getAnalyticsFn = createServerFn({ method: "GET" }).
|
|
2215
|
+
var getAnalyticsFn = createServerFn({ method: "GET" }).validator(analyticsSchema).handler(getAnalyticsFn_createServerFn_handler, async ({ data }) => {
|
|
1943
2216
|
return getCodexAnalytics({
|
|
1944
2217
|
dbPath: getDbPath(),
|
|
1945
2218
|
project: data.project
|
|
@@ -1950,7 +2223,7 @@ var exportThreadFn_createServerFn_handler = createServerRpc({
|
|
|
1950
2223
|
name: "exportThreadFn",
|
|
1951
2224
|
filename: "src/lib/codex-server.ts"
|
|
1952
2225
|
}, (opts) => exportThreadFn.__executeServer(opts));
|
|
1953
|
-
var exportThreadFn = createServerFn({ method: "POST" }).
|
|
2226
|
+
var exportThreadFn = createServerFn({ method: "POST" }).validator(exportSchema).handler(exportThreadFn_createServerFn_handler, async ({ data }) => {
|
|
1954
2227
|
return renderCodexThreadDownload({
|
|
1955
2228
|
dbPath: getDbPath(),
|
|
1956
2229
|
includeCommentary: data.includeCommentary,
|
|
@@ -1961,7 +2234,8 @@ var exportThreadFn = createServerFn({ method: "POST" }).inputValidator(exportSch
|
|
|
1961
2234
|
convertToProjectRoot: data.convertToProjectRoot,
|
|
1962
2235
|
redactUsername: data.redactUsername
|
|
1963
2236
|
},
|
|
1964
|
-
threadId: data.threadId
|
|
2237
|
+
threadId: data.threadId,
|
|
2238
|
+
zipArchive: data.zipArchive
|
|
1965
2239
|
});
|
|
1966
2240
|
});
|
|
1967
2241
|
var exportThreadsFn_createServerFn_handler = createServerRpc({
|
|
@@ -1969,7 +2243,7 @@ var exportThreadsFn_createServerFn_handler = createServerRpc({
|
|
|
1969
2243
|
name: "exportThreadsFn",
|
|
1970
2244
|
filename: "src/lib/codex-server.ts"
|
|
1971
2245
|
}, (opts) => exportThreadsFn.__executeServer(opts));
|
|
1972
|
-
var exportThreadsFn = createServerFn({ method: "POST" }).
|
|
2246
|
+
var exportThreadsFn = createServerFn({ method: "POST" }).validator(exportThreadsSchema).handler(exportThreadsFn_createServerFn_handler, async ({ data }) => {
|
|
1973
2247
|
return renderCodexThreadsDownload({
|
|
1974
2248
|
dbPath: getDbPath(),
|
|
1975
2249
|
includeCommentary: data.includeCommentary,
|
|
@@ -1980,7 +2254,8 @@ var exportThreadsFn = createServerFn({ method: "POST" }).inputValidator(exportTh
|
|
|
1980
2254
|
convertToProjectRoot: data.convertToProjectRoot,
|
|
1981
2255
|
redactUsername: data.redactUsername
|
|
1982
2256
|
},
|
|
1983
|
-
threadIds: data.threadIds
|
|
2257
|
+
threadIds: data.threadIds,
|
|
2258
|
+
zipArchive: data.zipArchive
|
|
1984
2259
|
});
|
|
1985
2260
|
});
|
|
1986
2261
|
var deleteThreadFn_createServerFn_handler = createServerRpc({
|
|
@@ -1988,7 +2263,7 @@ var deleteThreadFn_createServerFn_handler = createServerRpc({
|
|
|
1988
2263
|
name: "deleteThreadFn",
|
|
1989
2264
|
filename: "src/lib/codex-server.ts"
|
|
1990
2265
|
}, (opts) => deleteThreadFn.__executeServer(opts));
|
|
1991
|
-
var deleteThreadFn = createServerFn({ method: "POST" }).
|
|
2266
|
+
var deleteThreadFn = createServerFn({ method: "POST" }).validator(deleteThreadSchema).handler(deleteThreadFn_createServerFn_handler, async ({ data }) => {
|
|
1992
2267
|
return deleteCodexThread(getDbPath(), data.threadId, { deleteSessionFiles: data.deleteSessionFiles });
|
|
1993
2268
|
});
|
|
1994
2269
|
var deleteThreadsFn_createServerFn_handler = createServerRpc({
|
|
@@ -1996,7 +2271,7 @@ var deleteThreadsFn_createServerFn_handler = createServerRpc({
|
|
|
1996
2271
|
name: "deleteThreadsFn",
|
|
1997
2272
|
filename: "src/lib/codex-server.ts"
|
|
1998
2273
|
}, (opts) => deleteThreadsFn.__executeServer(opts));
|
|
1999
|
-
var deleteThreadsFn = createServerFn({ method: "POST" }).
|
|
2274
|
+
var deleteThreadsFn = createServerFn({ method: "POST" }).validator(deleteThreadsSchema).handler(deleteThreadsFn_createServerFn_handler, async ({ data }) => {
|
|
2000
2275
|
return deleteCodexThreads(getDbPath(), data.threadIds, { deleteSessionFiles: data.deleteSessionFiles });
|
|
2001
2276
|
});
|
|
2002
2277
|
var deleteProjectFn_createServerFn_handler = createServerRpc({
|
|
@@ -2004,7 +2279,7 @@ var deleteProjectFn_createServerFn_handler = createServerRpc({
|
|
|
2004
2279
|
name: "deleteProjectFn",
|
|
2005
2280
|
filename: "src/lib/codex-server.ts"
|
|
2006
2281
|
}, (opts) => deleteProjectFn.__executeServer(opts));
|
|
2007
|
-
var deleteProjectFn = createServerFn({ method: "POST" }).
|
|
2282
|
+
var deleteProjectFn = createServerFn({ method: "POST" }).validator(deleteProjectSchema).handler(deleteProjectFn_createServerFn_handler, async ({ data }) => {
|
|
2008
2283
|
return deleteCodexProject(getDbPath(), data.project, { deleteSessionFiles: data.deleteSessionFiles });
|
|
2009
2284
|
});
|
|
2010
2285
|
var recoverProjectThreadsFn_createServerFn_handler = createServerRpc({
|
|
@@ -2012,7 +2287,7 @@ var recoverProjectThreadsFn_createServerFn_handler = createServerRpc({
|
|
|
2012
2287
|
name: "recoverProjectThreadsFn",
|
|
2013
2288
|
filename: "src/lib/codex-server.ts"
|
|
2014
2289
|
}, (opts) => recoverProjectThreadsFn.__executeServer(opts));
|
|
2015
|
-
var recoverProjectThreadsFn = createServerFn({ method: "POST" }).
|
|
2290
|
+
var recoverProjectThreadsFn = createServerFn({ method: "POST" }).validator(projectSchema).handler(recoverProjectThreadsFn_createServerFn_handler, async ({ data }) => {
|
|
2016
2291
|
return recoverCodexProjectThreads(getDbPath(), data.project);
|
|
2017
2292
|
});
|
|
2018
2293
|
//#endregion
|