spiracha 1.1.2 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/AGENTS.md +57 -14
  2. package/README.md +122 -65
  3. package/apps/ui/AGENTS.md +18 -8
  4. package/apps/ui/README.md +30 -12
  5. package/apps/ui/dist/client/assets/{analytics-CqWZmyV6.js → analytics-B_hYz65v.js} +1 -1
  6. package/apps/ui/dist/client/assets/antigravity-conversations._conversationId-qiyygB7e.js +1 -0
  7. package/apps/ui/dist/client/assets/antigravity-conversations._conversationId-z1SQC2Kg.js +1 -0
  8. package/apps/ui/dist/client/assets/antigravity-keychain-panel-dYuRWtCf.js +1 -0
  9. package/apps/ui/dist/client/assets/antigravity._workspaceKey-CliqUr7o.js +1 -0
  10. package/apps/ui/dist/client/assets/antigravity._workspaceKey-CnoBzyX6.js +1 -0
  11. package/apps/ui/dist/client/assets/antigravity.index-CakfZz_E.js +1 -0
  12. package/apps/ui/dist/client/assets/antigravity.index-DY7M1KhG.js +1 -0
  13. package/apps/ui/dist/client/assets/badge-aHE9ETVe.js +1 -0
  14. package/apps/ui/dist/client/assets/checkbox-DN3XnJaA.js +1 -0
  15. package/apps/ui/dist/client/assets/cursor-threads._composerId-BMQyx8qG.js +1 -0
  16. package/apps/ui/dist/client/assets/cursor-threads._composerId-BTlaA-tV.js +1 -0
  17. package/apps/ui/dist/client/assets/cursor._workspaceKey-CrgrfevV.js +1 -0
  18. package/apps/ui/dist/client/assets/cursor._workspaceKey-bYS2syGL.js +1 -0
  19. package/apps/ui/dist/client/assets/cursor.index-CTqZMPYU.js +1 -0
  20. package/apps/ui/dist/client/assets/cursor.index-Clsz4E_e.js +2 -0
  21. package/apps/ui/dist/client/assets/{data-table-DnPYMPCD.js → data-table-Cj-v-uyB.js} +2 -2
  22. package/apps/ui/dist/client/assets/delete-confirm-dialog-DTpzBiNK.js +11 -0
  23. package/apps/ui/dist/client/assets/dist-BNAn99Pu.js +1 -0
  24. package/apps/ui/dist/client/assets/download-P3Rp23Ad.js +1 -0
  25. package/apps/ui/dist/client/assets/dropdown-menu-3qB5j9nt.js +1 -0
  26. package/apps/ui/dist/client/assets/es2015-Dwm_turD.js +41 -0
  27. package/apps/ui/dist/client/assets/export-dialog-CazdrASq.js +1 -0
  28. package/apps/ui/dist/client/assets/formatters-BdnWuM1z.js +1 -0
  29. package/apps/ui/dist/client/assets/index-BVFnfS78.js +22 -0
  30. package/apps/ui/dist/client/assets/json-panel-DLkS30sQ.js +1 -0
  31. package/apps/ui/dist/client/assets/metadata-section-jnIkB7dB.js +1 -0
  32. package/apps/ui/dist/client/assets/{metric-card-9jwBF7rG.js → metric-card-CBZuWLzQ.js} +1 -1
  33. package/apps/ui/dist/client/assets/page-header-CnD21cPn.js +1 -0
  34. package/apps/ui/dist/client/assets/projects._project-BLszwvYL.js +1 -0
  35. package/apps/ui/dist/client/assets/projects._project-DvLxYbvk.js +1 -0
  36. package/apps/ui/dist/client/assets/projects.index-COn8woBR.js +1 -0
  37. package/apps/ui/dist/client/assets/projects.index-DYs98skV.js +3 -0
  38. package/apps/ui/dist/client/assets/refresh-ccw-BDrYXjtD.js +1 -0
  39. package/apps/ui/dist/client/assets/reload-error-panel-DLAg0AW2.js +1 -0
  40. package/apps/ui/dist/client/assets/routes-BtF5-coe.js +1 -0
  41. package/apps/ui/dist/client/assets/scroll-text-CqaFm9by.js +1 -0
  42. package/apps/ui/dist/client/assets/select-DbnpwqL6.js +1 -0
  43. package/apps/ui/dist/client/assets/settings-CGX3VleN.js +1 -0
  44. package/apps/ui/dist/client/assets/styles-Ch0r3kMZ.css +1 -0
  45. package/apps/ui/dist/client/assets/text-document-panel-DPleOmmq.js +1 -0
  46. package/apps/ui/dist/client/assets/text-filter-7M6wRo-t.js +2 -0
  47. package/apps/ui/dist/client/assets/threads._threadId-D5w76IB-.js +7 -0
  48. package/apps/ui/dist/client/assets/{threads._threadId-DT75NiBa.js → threads._threadId-Dx85sI9P.js} +1 -1
  49. package/apps/ui/dist/client/assets/useMutation-MZ3Hr9h9.js +1 -0
  50. package/apps/ui/dist/client/assets/useQuery-Cb4V0AT0.js +1 -0
  51. package/apps/ui/dist/client/icon.svg +28 -0
  52. package/apps/ui/dist/client/manifest.json +6 -16
  53. package/apps/ui/dist/server/assets/_tanstack-start-manifest_v-CBbkUXw6.js +227 -0
  54. package/apps/ui/dist/server/assets/{analytics-BMxW_bZL.js → analytics-CBNOYZwJ.js} +2 -2
  55. package/apps/ui/dist/server/assets/antigravity-conversation-state-HgzS302O.js +16 -0
  56. package/apps/ui/dist/server/assets/antigravity-conversations._conversationId-B9Rm4EXh.js +212 -0
  57. package/apps/ui/dist/server/assets/antigravity-conversations._conversationId-BIdYNy68.js +20 -0
  58. package/apps/ui/dist/server/assets/antigravity-conversations._conversationId-D426O-64.js +11 -0
  59. package/apps/ui/dist/server/assets/antigravity-db-D9gW1D8G.js +576 -0
  60. package/apps/ui/dist/server/assets/antigravity-keychain-DOiuHDwK.js +126 -0
  61. package/apps/ui/dist/server/assets/antigravity-keychain-panel-DcLyBBwd.js +55 -0
  62. package/apps/ui/dist/server/assets/antigravity-queries-CgQhlQ7J.js +37 -0
  63. package/apps/ui/dist/server/assets/antigravity-server-DFUx4Khk.js +114 -0
  64. package/apps/ui/dist/server/assets/antigravity._workspaceKey-3m_MzNFA.js +11 -0
  65. package/apps/ui/dist/server/assets/antigravity._workspaceKey-D42ixtzp.js +210 -0
  66. package/apps/ui/dist/server/assets/antigravity._workspaceKey-DnSlSC-C.js +28 -0
  67. package/apps/ui/dist/server/assets/antigravity.index-DZVT-cac.js +104 -0
  68. package/apps/ui/dist/server/assets/antigravity.index-DudTB3Tq.js +11 -0
  69. package/apps/ui/dist/server/assets/badge-EvdhKK_Z.js +26 -0
  70. package/apps/ui/dist/server/assets/{codex-queries-CAF6HYiG.js → codex-queries-eOJGfHQj.js} +6 -18
  71. package/apps/ui/dist/server/assets/{codex-server-C01sv0JJ.js → codex-server-nrETIF--.js} +166 -226
  72. package/apps/ui/dist/server/assets/createServerRpc-BtXIw2iP.js +12 -0
  73. package/apps/ui/dist/server/assets/createSsrRpc-COf5Zuye.js +16 -0
  74. package/apps/ui/dist/server/assets/cursor-db-B7agkAvM.js +643 -0
  75. package/apps/ui/dist/server/assets/cursor-exporter-types-CI3goo-c.js +34 -0
  76. package/apps/ui/dist/server/assets/cursor-queries-BMhuJeUO.js +65 -0
  77. package/apps/ui/dist/server/assets/cursor-recovery-9bJLs7vG.js +361 -0
  78. package/apps/ui/dist/server/assets/cursor-server-BgylIFgn.js +184 -0
  79. package/apps/ui/dist/server/assets/cursor-threads._composerId-BB0Y_Mao.js +11 -0
  80. package/apps/ui/dist/server/assets/cursor-threads._composerId-BsxFKzoJ.js +218 -0
  81. package/apps/ui/dist/server/assets/cursor-threads._composerId-DXffY_CK.js +18 -0
  82. package/apps/ui/dist/server/assets/cursor-transcript-2iL3KFSK.js +125 -0
  83. package/apps/ui/dist/server/assets/cursor._workspaceKey-BP2J1x_x.js +28 -0
  84. package/apps/ui/dist/server/assets/cursor._workspaceKey-BQd0e-Pd.js +399 -0
  85. package/apps/ui/dist/server/assets/cursor._workspaceKey-nmg3YIOQ.js +11 -0
  86. package/apps/ui/dist/server/assets/cursor.index-CQVxtCm8.js +189 -0
  87. package/apps/ui/dist/server/assets/cursor.index-CcsX7DG0.js +11 -0
  88. package/apps/ui/dist/server/assets/{delete-confirm-dialog-CWqcTXTF.js → delete-confirm-dialog-PCD7S0_M.js} +5 -4
  89. package/apps/ui/dist/server/assets/download-DMmiy1xf.js +92 -0
  90. package/apps/ui/dist/server/assets/{input-B4tEzctc.js → dropdown-menu-Dy_9t6TN.js} +1 -11
  91. package/apps/ui/dist/server/assets/{download-C5rkk_Bo.js → export-dialog-DaPlOGFT.js} +8 -99
  92. package/apps/ui/dist/server/assets/json-panel-RYsxWFae.js +16 -0
  93. package/apps/ui/dist/server/assets/{loading-panel-DbLdvjtR.js → loading-panel-BGFnWseS.js} +1 -1
  94. package/apps/ui/dist/server/assets/metadata-section-D6Lbc7D6.js +54 -0
  95. package/apps/ui/dist/server/assets/page-header-VNSaM3xd.js +29 -0
  96. package/apps/ui/dist/server/assets/projects._project-Bshqk7JA.js +12 -0
  97. package/apps/ui/dist/server/assets/{projects._project-CJ7l0ynC.js → projects._project-DUN3iWfg.js} +4 -4
  98. package/apps/ui/dist/server/assets/{projects._project-CcJLp_A8.js → projects._project-Dim9Y0kD.js} +54 -26
  99. package/apps/ui/dist/server/assets/projects.index-BLXOx5eL.js +12 -0
  100. package/apps/ui/dist/server/assets/{projects.index-srtogpuF.js → projects.index-DjSQK5dm.js} +23 -27
  101. package/apps/ui/dist/server/assets/{projects.index-CaplpeMy.js → reload-error-panel-BJMxY3U1.js} +5 -6
  102. package/apps/ui/dist/server/assets/{router-C_w-haH6.js → router-DrDgc-LD.js} +131 -44
  103. package/apps/ui/dist/server/assets/{routes-CPe-ppmC.js → routes-B-GlEe2C.js} +54 -39
  104. package/apps/ui/dist/server/assets/{routes-BhbxvJE7.js → routes-CNHAUMwo.js} +2 -2
  105. package/apps/ui/dist/server/assets/{settings-MvWDgc1u.js → settings-OayxIYQQ.js} +1 -1
  106. package/apps/ui/dist/server/assets/shared-CPRNYIql.js +134 -0
  107. package/apps/ui/dist/server/assets/text-document-panel-D8JbQWAn.js +23 -0
  108. package/apps/ui/dist/server/assets/text-filter-CGKxMCKt.js +36 -0
  109. package/apps/ui/dist/server/assets/{threads._threadId-Ba7vv6-K.js → threads._threadId-CJzm4KrZ.js} +3 -3
  110. package/apps/ui/dist/server/assets/{threads._threadId-euyNckhj.js → threads._threadId-DODTYddm.js} +69 -76
  111. package/apps/ui/dist/server/server.js +83 -36
  112. package/bin/codex-chats-claude.js +5 -0
  113. package/bin/codex-chats.js +5 -0
  114. package/bin/spiracha.js +5 -0
  115. package/package.json +26 -13
  116. package/src/export-cursor.ts +244 -0
  117. package/src/lib/antigravity-db.ts +936 -0
  118. package/src/lib/antigravity-exporter-types.ts +70 -0
  119. package/src/lib/antigravity-keychain.ts +203 -0
  120. package/src/lib/codex-browser-db.ts +7 -1
  121. package/src/lib/codex-browser-export.ts +2 -2
  122. package/src/lib/codex-browser-types.ts +22 -1
  123. package/src/lib/codex-exporter-cli.ts +9 -9
  124. package/src/lib/codex-exporter-transcript.ts +16 -190
  125. package/src/lib/codex-exporter-types.ts +1 -1
  126. package/src/lib/codex-exporter.ts +0 -1
  127. package/src/lib/codex-thread-recovery.ts +202 -0
  128. package/src/lib/cursor-db.ts +1096 -0
  129. package/src/lib/cursor-exporter-types.ts +190 -0
  130. package/src/lib/cursor-exporter.ts +266 -0
  131. package/src/lib/cursor-recovery.ts +543 -0
  132. package/src/lib/cursor-transcript.ts +183 -0
  133. package/src/lib/interactive-cli.ts +2 -2
  134. package/src/mcp-server.ts +2 -2
  135. package/src/spiracha.ts +16 -3
  136. package/src/ui-cli.ts +2 -2
  137. package/apps/ui/dist/client/assets/checkbox-DXM4lkJq.js +0 -1
  138. package/apps/ui/dist/client/assets/delete-confirm-dialog-CcZaRX33.js +0 -11
  139. package/apps/ui/dist/client/assets/download-DOwxk-cG.js +0 -1
  140. package/apps/ui/dist/client/assets/es2015-Bm0kEzx2.js +0 -41
  141. package/apps/ui/dist/client/assets/formatters-C12LmYaa.js +0 -1
  142. package/apps/ui/dist/client/assets/index-DdJ7ahIt.js +0 -22
  143. package/apps/ui/dist/client/assets/input-CEsI7EpI.js +0 -1
  144. package/apps/ui/dist/client/assets/page-header-Dr_h1CVv.js +0 -1
  145. package/apps/ui/dist/client/assets/projects._project-uyNGnpjH.js +0 -1
  146. package/apps/ui/dist/client/assets/projects._project-zoM8d2nH.js +0 -1
  147. package/apps/ui/dist/client/assets/projects.index-D1CWVN-O.js +0 -1
  148. package/apps/ui/dist/client/assets/projects.index-DukMuny6.js +0 -1
  149. package/apps/ui/dist/client/assets/routes-Gr2Wwh83.js +0 -1
  150. package/apps/ui/dist/client/assets/select-CFim44gT.js +0 -1
  151. package/apps/ui/dist/client/assets/settings-DqhyDxo2.js +0 -1
  152. package/apps/ui/dist/client/assets/styles-CMrP9Jb4.css +0 -1
  153. package/apps/ui/dist/client/assets/threads._threadId-Df5VXIuZ.js +0 -7
  154. package/apps/ui/dist/client/favicon.ico +0 -0
  155. package/apps/ui/dist/client/logo192.png +0 -0
  156. package/apps/ui/dist/client/logo512.png +0 -0
  157. package/apps/ui/dist/server/assets/_tanstack-start-manifest_v-C0V305Nt.js +0 -99
  158. package/apps/ui/dist/server/assets/page-header-CxdZM86z.js +0 -25
  159. package/apps/ui/dist/server/assets/projects._project-CLSohrBp.js +0 -26
@@ -1,21 +1,8 @@
1
- import { n as TSS_SERVER_FUNCTION, r as getServerFnById, t as createServerFn } from "../server.js";
1
+ import { t as createServerFn } from "../server.js";
2
2
  import { t as isRetryableSqliteError } from "./sqlite-error-LZDrnxdd.js";
3
+ import { t as createSsrRpc } from "./createSsrRpc-COf5Zuye.js";
3
4
  import { queryOptions } from "@tanstack/react-query";
4
5
  import { z } from "zod";
5
- //#region ../../node_modules/.bun/@tanstack+start-server-core@1.169.3/node_modules/@tanstack/start-server-core/dist/esm/createSsrRpc.js
6
- var createSsrRpc = (functionId) => {
7
- const url = "/_serverFn/" + functionId;
8
- const serverFnMeta = { id: functionId };
9
- const fn = async (...args) => {
10
- return (await getServerFnById(functionId, { origin: "server" }))(...args);
11
- };
12
- return Object.assign(fn, {
13
- url,
14
- serverFnMeta,
15
- [TSS_SERVER_FUNCTION]: true
16
- });
17
- };
18
- //#endregion
19
6
  //#region src/lib/codex-server.ts
20
7
  var projectSchema = z.object({ project: z.string().min(1) });
21
8
  var deleteProjectSchema = z.object({
@@ -35,8 +22,8 @@ var analyticsSchema = z.object({ project: z.string().min(1).nullable() });
35
22
  var exportSchema = z.object({
36
23
  convertToProjectRoot: z.boolean(),
37
24
  includeCommentary: z.boolean(),
25
+ includeMetadata: z.boolean(),
38
26
  includeTools: z.boolean(),
39
- optimized: z.boolean(),
40
27
  outputFormat: z.enum(["md", "txt"]),
41
28
  redactUsername: z.boolean(),
42
29
  threadId: z.string().min(1)
@@ -44,8 +31,8 @@ var exportSchema = z.object({
44
31
  var exportThreadsSchema = z.object({
45
32
  convertToProjectRoot: z.boolean(),
46
33
  includeCommentary: z.boolean(),
34
+ includeMetadata: z.boolean(),
47
35
  includeTools: z.boolean(),
48
- optimized: z.boolean(),
49
36
  outputFormat: z.enum(["md", "txt"]),
50
37
  redactUsername: z.boolean(),
51
38
  threadIds: z.array(z.string().min(1)).min(1)
@@ -61,6 +48,7 @@ var exportThreadsFn = createServerFn({ method: "POST" }).inputValidator(exportTh
61
48
  var deleteThreadFn = createServerFn({ method: "POST" }).inputValidator(deleteThreadSchema).handler(createSsrRpc("29727b7ad5b8fe42e83817376653e064d9fe8888799f056b2e59296b3396568b"));
62
49
  var deleteThreadsFn = createServerFn({ method: "POST" }).inputValidator(deleteThreadsSchema).handler(createSsrRpc("96aa60bf7dd9b5bde415bcf3ad6f6955a975eecd9aa0516cf401cc39bebebe6c"));
63
50
  var deleteProjectFn = createServerFn({ method: "POST" }).inputValidator(deleteProjectSchema).handler(createSsrRpc("164ee82cdd565ed96591a64312f0f7bd961040baf066a89d9f5636330d11360b"));
51
+ var recoverProjectThreadsFn = createServerFn({ method: "POST" }).inputValidator(projectSchema).handler(createSsrRpc("412c05e00aef3ad43905593fdfd2f566561259da7e1f5d6f1c03428ff33c6867"));
64
52
  //#endregion
65
53
  //#region src/lib/codex-queries.ts
66
54
  var retrySqliteQuery = (failureCount, error) => {
@@ -106,4 +94,4 @@ var analyticsQueryOptions = (project) => queryOptions({
106
94
  retryDelay
107
95
  });
108
96
  //#endregion
109
- export { threadSnapshotQueryOptions as a, deleteThreadFn as c, exportThreadsFn as d, projectsQueryOptions as i, deleteThreadsFn as l, dashboardQueryOptions as n, threadTranscriptQueryOptions as o, projectThreadsQueryOptions as r, deleteProjectFn as s, analyticsQueryOptions as t, exportThreadFn as u };
97
+ export { threadSnapshotQueryOptions as a, deleteThreadFn as c, exportThreadsFn as d, recoverProjectThreadsFn as f, projectsQueryOptions as i, deleteThreadsFn as l, dashboardQueryOptions as n, threadTranscriptQueryOptions as o, projectThreadsQueryOptions as r, deleteProjectFn as s, analyticsQueryOptions as t, exportThreadFn as u };
@@ -1,154 +1,22 @@
1
- import { n as TSS_SERVER_FUNCTION, t as createServerFn } from "../server.js";
2
- import { t as formatModelLabel$1 } from "./model-label-B1NWGc65.js";
1
+ import { t as createServerFn } from "../server.js";
2
+ import { t as createServerRpc } from "./createServerRpc-BtXIw2iP.js";
3
3
  import { t as isRetryableSqliteError } from "./sqlite-error-LZDrnxdd.js";
4
+ import { a as cleanInlineTitle, c as formatInlineLiteral, d as readJsonlObjects, h as renderSection, i as cleanExtractedText, l as formatModelLabel, m as renderMetadataBlock, n as asObject, o as createExportWriteStream, p as renderDocumentTitle, r as asString, s as finalizeExportWriteStream, t as asNumber, u as getPortablePathBasename } from "./shared-CPRNYIql.js";
4
5
  import { t as applyPathTransforms } from "./path-transforms-DL2IwtYd.js";
5
6
  import { finished } from "node:stream/promises";
7
+ import { z } from "zod";
6
8
  import { Database } from "bun:sqlite";
7
- import { mkdir, mkdtemp, readdir, rename, rm, stat } from "node:fs/promises";
9
+ import { copyFile, mkdir, mkdtemp, readdir, rename, rm, stat, utimes } from "node:fs/promises";
8
10
  import os from "node:os";
9
11
  import path from "node:path";
10
- import { createReadStream, createWriteStream } from "node:fs";
11
- import { createInterface } from "node:readline";
12
+ import { createReadStream } from "node:fs";
12
13
  import { createHash, randomUUID } from "node:crypto";
13
- import { z } from "zod";
14
- //#region ../../node_modules/.bun/@tanstack+start-server-core@1.169.3/node_modules/@tanstack/start-server-core/dist/esm/createServerRpc.js
15
- var createServerRpc = (serverFnMeta, splitImportFn) => {
16
- const url = "/_serverFn/" + serverFnMeta.id;
17
- return Object.assign(splitImportFn, {
18
- url,
19
- serverFnMeta,
20
- [TSS_SERVER_FUNCTION]: true
21
- });
22
- };
23
- //#endregion
24
14
  //#region ../../src/lib/codex-exporter-types.ts
25
15
  var DEFAULT_CODEX_DIR = path.join(os.homedir(), ".codex");
26
16
  var DEFAULT_DB_PATH = path.join(DEFAULT_CODEX_DIR, "state_5.sqlite");
27
17
  path.join(DEFAULT_CODEX_DIR, "sessions");
28
18
  path.join(process.cwd(), "exports");
29
19
  //#endregion
30
- //#region ../../src/lib/shared.ts
31
- var getPortablePathBasename = (value) => {
32
- const trimmed = value.replace(/[\\/]+$/u, "");
33
- if (!trimmed) return "";
34
- return path.win32.basename(path.posix.basename(trimmed));
35
- };
36
- var cleanInlineTitle = (value) => {
37
- const compact = (value.split("\n").map((line) => line.trim()).find((line) => line.length > 0) ?? "").replace(/\s+/g, " ").trim();
38
- if (compact.length <= 160) return compact;
39
- return `${compact.slice(0, 157).trimEnd()}...`;
40
- };
41
- var cleanExtractedText = (text) => {
42
- return text.replace(/^\s*<\/?image>\s*$/gm, "").replace(/\n{3,}/g, "\n\n");
43
- };
44
- var formatModelLabel = formatModelLabel$1;
45
- var asObject = (value) => {
46
- if (!value || typeof value !== "object" || Array.isArray(value)) return null;
47
- return value;
48
- };
49
- var asString = (value) => {
50
- return typeof value === "string" ? value : null;
51
- };
52
- var asNumber = (value) => {
53
- return typeof value === "number" ? value : null;
54
- };
55
- var readJsonlObjects = (filePath) => {
56
- const stream = createReadStream(filePath, { encoding: "utf8" });
57
- const lines = createInterface({
58
- crlfDelay: Infinity,
59
- input: stream
60
- });
61
- const lineIterator = lines[Symbol.asyncIterator]();
62
- let closed = false;
63
- const close = () => {
64
- if (closed) return;
65
- closed = true;
66
- lines.close();
67
- stream.destroy();
68
- };
69
- const readNext = async () => {
70
- while (true) {
71
- const nextLine = await lineIterator.next();
72
- if (nextLine.done) {
73
- close();
74
- return {
75
- done: true,
76
- value: void 0
77
- };
78
- }
79
- const trimmed = nextLine.value.trim();
80
- if (!trimmed) continue;
81
- try {
82
- return {
83
- done: false,
84
- value: JSON.parse(trimmed)
85
- };
86
- } catch {}
87
- }
88
- };
89
- const iterator = {
90
- [Symbol.asyncIterator]: () => iterator,
91
- next: async () => readNext(),
92
- return: async () => {
93
- close();
94
- return {
95
- done: true,
96
- value: void 0
97
- };
98
- },
99
- throw: async (error) => {
100
- close();
101
- throw error;
102
- }
103
- };
104
- return iterator;
105
- };
106
- var renderDocumentTitle = (title, format) => {
107
- if (format === "md") return `# ${title}`;
108
- return [title, "=".repeat(Math.max(title.length, 3))].join("\n");
109
- };
110
- var renderMetadataBlock = (entries, format) => {
111
- const filteredEntries = entries.filter((entry) => entry.value !== null && entry.value !== void 0 && entry.value !== "");
112
- if (filteredEntries.length === 0) return "";
113
- if (format === "md") {
114
- const lines = ["---"];
115
- for (const entry of filteredEntries) lines.push(`${entry.key}: ${toMetadataValue(entry.value, "md")}`);
116
- lines.push("---");
117
- return `${lines.join("\n")}\n`;
118
- }
119
- const lines = ["Metadata", "--------"];
120
- for (const entry of filteredEntries) lines.push(`${entry.key}: ${toMetadataValue(entry.value, "txt")}`);
121
- return `${lines.join("\n")}\n`;
122
- };
123
- var renderSection = (title, body, format) => {
124
- const trimmedBody = body.trimEnd();
125
- if (!trimmedBody) return "";
126
- if (format === "md") return `## ${title}\n\n${trimmedBody}\n`;
127
- return `${title}\n${"-".repeat(Math.max(title.length, 3))}\n${trimmedBody}\n`;
128
- };
129
- var formatInlineLiteral = (value, format) => {
130
- return format === "md" ? inlineCode(value) : value;
131
- };
132
- var inlineCode = (value) => {
133
- const maxRunLength = (value.match(/`+/g) ?? []).reduce((max, run) => Math.max(max, run.length), 0);
134
- const fence = "`".repeat(maxRunLength + 1);
135
- return `${fence}${value.startsWith("`") || value.endsWith("`") ? ` ${value} ` : value}${fence}`;
136
- };
137
- var createExportWriteStream = async (outputPath) => {
138
- await mkdir(path.dirname(outputPath), { recursive: true });
139
- return createWriteStream(outputPath, { encoding: "utf8" });
140
- };
141
- var finalizeExportWriteStream = async (stream) => {
142
- stream.end();
143
- await finished(stream);
144
- };
145
- var toMetadataValue = (value, format) => {
146
- if (Array.isArray(value) || value && typeof value === "object") return JSON.stringify(value);
147
- if (typeof value === "string") return format === "md" ? JSON.stringify(value) : value;
148
- if (typeof value === "boolean" || typeof value === "number") return String(value);
149
- return format === "md" ? JSON.stringify(String(value)) : String(value);
150
- };
151
- //#endregion
152
20
  //#region ../../src/lib/codex-thread-parser.ts
153
21
  var createEmptyStats = () => {
154
22
  return {
@@ -890,7 +758,10 @@ var getCodexDashboardSummary = (dbPath) => {
890
758
  return {
891
759
  activeThreads: threads.filter((thread) => !thread.archived).length,
892
760
  archivedThreads: threads.filter((thread) => Boolean(thread.archived)).length,
893
- recentThreads: threads.slice(0, 5),
761
+ recentThreads: threads.slice(0, 5).filter((thread) => Boolean(getPortablePathBasename(thread.cwd))).map((thread) => ({
762
+ project: getPortablePathBasename(thread.cwd),
763
+ thread: compactThreadListRow(thread)
764
+ })),
894
765
  threadsWithRelations,
895
766
  topProjectsByThreadCount: [...projects].sort((left, right) => {
896
767
  if (left.threadCount !== right.threadCount) return right.threadCount - left.threadCount;
@@ -1067,13 +938,10 @@ var convertSessionFile = async (target, options) => {
1067
938
  }
1068
939
  if (!matchesFilters(target.thread?.cwd ?? transcriptState.sessionMeta.cwd ?? null, options)) return null;
1069
940
  if (transcriptState.sections.length === 0) return null;
1070
- if (options.optimized) return transcriptState.sections.join("\n\n").trimEnd() + "\n";
1071
- const title = getTitle(target, transcriptState.sessionMeta);
1072
- const metadata = buildMetadataEntries(target, transcriptState.sessionMeta, options);
1073
941
  return [
1074
- renderDocumentTitle(title, options.outputFormat),
942
+ renderDocumentTitle(getTitle(target, transcriptState.sessionMeta), options.outputFormat),
1075
943
  "",
1076
- renderMetadataBlock(metadata, options.outputFormat),
944
+ options.includeMetadata ? renderMetadataBlock(buildMetadataEntries(target, transcriptState.sessionMeta, options), options.outputFormat) : "",
1077
945
  ...transcriptState.sections
1078
946
  ].filter(Boolean).join("\n").trimEnd() + "\n";
1079
947
  };
@@ -1083,8 +951,7 @@ var writeSessionFileExport = async (target, options, outputPath, transform = (te
1083
951
  const state = {
1084
952
  assistantModel: target.thread?.model ?? null,
1085
953
  sections: [],
1086
- sessionMeta: {},
1087
- startedTranscript: false
954
+ sessionMeta: {}
1088
955
  };
1089
956
  let wroteSection = false;
1090
957
  try {
@@ -1093,7 +960,7 @@ var writeSessionFileExport = async (target, options, outputPath, transform = (te
1093
960
  captureSessionMeta(parsed, state.sessionMeta);
1094
961
  const block = renderCodexTranscriptRecord(parsed, options, state);
1095
962
  if (!block) continue;
1096
- transcriptStream.write(transform(wroteSection ? `${getSectionSeparator(options)}${block}` : block));
963
+ transcriptStream.write(transform(wroteSection ? `${getSectionSeparator()}${block}` : block));
1097
964
  wroteSection = true;
1098
965
  }
1099
966
  await finalizeExportWriteStream(transcriptStream);
@@ -1124,15 +991,12 @@ var collectCodexTranscript = async (sessionFile, options, assistantModel = null)
1124
991
  const state = {
1125
992
  assistantModel,
1126
993
  sections: [],
1127
- sessionMeta: {},
1128
- startedTranscript: false
994
+ sessionMeta: {}
1129
995
  };
1130
996
  for await (const parsed of readJsonlObjects(sessionFile)) processCodexTranscriptRecord(parsed, options, state);
1131
997
  return state;
1132
998
  };
1133
- var getSectionSeparator = (options) => {
1134
- return options.optimized ? "\n\n" : "\n";
1135
- };
999
+ var getSectionSeparator = () => "\n";
1136
1000
  var processCodexTranscriptRecord = (parsed, options, state) => {
1137
1001
  captureSessionMeta(parsed, state.sessionMeta);
1138
1002
  const block = renderCodexTranscriptRecord(parsed, options, state);
@@ -1144,37 +1008,19 @@ var renderCodexTranscriptRecord = (parsed, options, state) => {
1144
1008
  if (!options.includeTools) return "";
1145
1009
  const tool = extractToolRecord(parsed);
1146
1010
  if (!tool) return "";
1147
- return options.optimized ? renderCompactToolBlock(tool, options.outputFormat) : renderToolBlock(tool, options.outputFormat);
1011
+ return renderToolBlock(tool, options.outputFormat);
1148
1012
  };
1149
1013
  var processCodexMessageRecord = (message, options, state) => {
1150
- if (options.optimized) return processOptimizedCodexMessageRecord(message, options, state);
1151
1014
  return renderMessageBlock(message, options.outputFormat, state.assistantModel, options.includeCommentary);
1152
1015
  };
1153
- var processOptimizedCodexMessageRecord = (message, options, state) => {
1154
- if (message.role !== "user" && message.role !== "assistant") return "";
1155
- if (message.role === "assistant" && message.phase === "commentary" && !options.includeCommentary) return "";
1156
- const compact = compactMessageText(message, true);
1157
- if (!compact) return "";
1158
- if (!state.startedTranscript) {
1159
- if (shouldSkipOptimizedPrelude(message.role, compact)) return "";
1160
- state.startedTranscript = true;
1161
- }
1162
- return renderCompactBlock(message, compact, options.outputFormat, state.assistantModel);
1163
- };
1164
1016
  var buildStreamExportPrefix = (target, sessionMeta, options) => {
1165
- if (options.optimized) return "";
1166
- const title = getTitle(target, sessionMeta);
1167
- const metadata = buildMetadataEntries(target, sessionMeta, options);
1017
+ if (!options.includeMetadata) return "";
1168
1018
  return `${[
1169
- renderDocumentTitle(title, options.outputFormat),
1019
+ renderDocumentTitle(getTitle(target, sessionMeta), options.outputFormat),
1170
1020
  "",
1171
- renderMetadataBlock(metadata, options.outputFormat)
1021
+ renderMetadataBlock(buildMetadataEntries(target, sessionMeta, options), options.outputFormat)
1172
1022
  ].filter(Boolean).join("\n")}\n`;
1173
1023
  };
1174
- var compactMessageText = (message, optimized) => {
1175
- const cleaned = stripPreviewBlock(extractText(message.content));
1176
- return optimized ? optimizePlainText(optimizeRenderedText(cleaned)) : cleaned.trim();
1177
- };
1178
1024
  var formatToolOutputSummary = (outputText, outputFormat) => {
1179
1025
  if (!outputText) return "";
1180
1026
  const lines = outputText.split("\n").map((line) => line.trim()).filter(Boolean);
@@ -1214,10 +1060,6 @@ var getTitle = (target, sessionMeta) => {
1214
1060
  if (target.thread?.title) return cleanInlineTitle(target.thread.title);
1215
1061
  return sessionMeta.id ?? path.basename(target.sessionFile, ".jsonl");
1216
1062
  };
1217
- var shouldSkipOptimizedPrelude = (role, text) => {
1218
- if (role !== "user") return true;
1219
- return text.startsWith("AGENTS.md instructions for ") || text.startsWith("# AGENTS.md instructions for ") || text.startsWith("<permissions instructions>") || text.startsWith("<environment_context>") || text.startsWith("<app-context>") || text.startsWith("<collaboration_mode>") || text.startsWith("<skills_instructions>") || text.startsWith("You are Codex, a coding agent based on GPT-5.") || text.startsWith("Read this before making changes.") || text.includes("Filesystem sandboxing defines which files can be read or written.") || text.includes("approval_policy") || text.includes("base_instructions");
1220
- };
1221
1063
  var buildMetadataEntries = (target, sessionMeta, options) => {
1222
1064
  return [
1223
1065
  ...buildCodexExportIdentityMetadata(target, sessionMeta),
@@ -1495,7 +1337,7 @@ var extractToolRecord = (parsed) => {
1495
1337
  var renderMessageBlock = (message, outputFormat, assistantModel, includeCommentary) => {
1496
1338
  if (message.role !== "user" && message.role !== "assistant") return "";
1497
1339
  if (message.role === "assistant" && message.phase === "commentary" && !includeCommentary) return "";
1498
- const text = cleanExtractedText(extractText(message.content)).trim();
1340
+ const text = cleanExtractedText(stripPreviewBlock(extractText(message.content))).trim();
1499
1341
  if (!text || shouldSkipMessage(message.role, text)) return "";
1500
1342
  return renderSection(message.role === "user" ? "User" : formatModelLabel(message.model ?? assistantModel), message.phase ? `Phase: ${message.phase}\n\n${text}` : text, outputFormat);
1501
1343
  };
@@ -1507,20 +1349,6 @@ var renderToolBlock = (tool, outputFormat) => {
1507
1349
  const summary = formatToolOutputSummary(tool.outputText ?? "", outputFormat);
1508
1350
  return summary ? renderSection("Tool Output", summary, outputFormat) : "";
1509
1351
  };
1510
- var renderCompactBlock = (message, text, outputFormat, assistantModel) => {
1511
- const prefix = message.role === "user" ? "U:" : `${formatModelLabel(message.model ?? assistantModel)}:`;
1512
- const [firstLine, ...rest] = text.split("\n");
1513
- if (rest.length === 0) return `${prefix} ${normalizeCompactLiteral(firstLine, outputFormat)}`;
1514
- return [`${prefix} ${normalizeCompactLiteral(firstLine, outputFormat)}`, ...rest.map((line) => normalizeCompactLiteral(line, outputFormat))].join("\n");
1515
- };
1516
- var renderCompactToolBlock = (tool, outputFormat) => {
1517
- if (tool.kind === "call") {
1518
- const details = formatCompactToolCall(tool, outputFormat);
1519
- return details ? `T: ${details}` : "";
1520
- }
1521
- const summary = formatCompactToolOutput(tool.outputText ?? "");
1522
- return summary ? `R: ${summary}` : "";
1523
- };
1524
1352
  var stripPreviewBlock = (text) => {
1525
1353
  const parts = text.split(/\n{2,}/).map((part) => part.trim()).filter(Boolean);
1526
1354
  if (parts.length < 2) return text.trim();
@@ -1530,14 +1358,9 @@ var stripPreviewBlock = (text) => {
1530
1358
  if (!(!/^([UA]):/i.test(first) && !isTranscriptHeading(first) && /^([UA]):/i.test(second) === false && isTranscriptHeading(second))) return text.trim();
1531
1359
  return parts.slice(1).join("\n\n");
1532
1360
  };
1533
- var optimizeRenderedText = (text) => {
1534
- return text.replace(/^\*Phase:\s+`[^`]+`\*\s*\n*/gm, "").replace(/^\s*<image\b[^>]*>\s*$/gim, "").replace(/^\s*<\/image>\s*$/gim, "").replace(/^\s*\[Image attached\]\s*$/gim, "").replace(/^#{1,6}\s+/gm, "").replace(/^```[^\n]*\n?/gm, "").replace(/\n```$/gm, "").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/^##\s+User\s*$/gm, "User:").replace(/^##\s+Assistant\s*$/gm, "Assistant:").replace(/`([^`]+)`/g, "$1").replace(/\*\*([^*]+)\*\*/g, "$1").replace(/\*([^*\n]+)\*/g, "$1").replace(/\n{3,}/g, "\n\n").trim();
1535
- };
1536
- var optimizePlainText = (text) => {
1537
- return text.replace(/\r/g, "").replace(/^\s*<image\b[^>]*>\s*$/gim, "").replace(/^\s*<\/image>\s*$/gim, "").replace(/^\s*\[Image attached\]\s*$/gim, "").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/\*\*([^*]+)\*\*/g, "$1").replace(/\*([^*\n]+)\*/g, "$1").split("\n").map((line) => line.replace(/[ \t]+$/g, "")).join("\n").replace(/\n{3,}/g, "\n\n").trim();
1538
- };
1539
1361
  var shouldSkipMessage = (role, text) => {
1540
1362
  if (text.startsWith("<environment_context>")) return true;
1363
+ if (text.startsWith("AGENTS.md instructions for ")) return true;
1541
1364
  if (text.startsWith("# AGENTS.md instructions for ")) return true;
1542
1365
  if (role === "user" && text.includes("<environment_context>")) return true;
1543
1366
  return false;
@@ -1547,24 +1370,6 @@ var formatToolCallDetails = (tool, outputFormat) => {
1547
1370
  const details = parseExecCommandArguments(tool.argumentsText);
1548
1371
  return details.cmd ? `Command: ${formatInlineLiteral(details.cmd, outputFormat)}` : "";
1549
1372
  };
1550
- var formatCompactToolCall = (tool, outputFormat) => {
1551
- if (tool.name === "exec_command") {
1552
- const details = parseExecCommandArguments(tool.argumentsText);
1553
- if (!details.cmd) return "exec_command";
1554
- const command = formatInlineLiteral(details.cmd, outputFormat);
1555
- return details.workdir ? `exec_command ${command} @ ${details.workdir}` : `exec_command ${command}`;
1556
- }
1557
- return tool.callId ? `${tool.name} (${tool.callId})` : tool.name;
1558
- };
1559
- var formatCompactToolOutput = (outputText) => {
1560
- if (!outputText) return "";
1561
- const lines = outputText.split("\n").map((line) => line.trim()).filter(Boolean);
1562
- const exit = lines.find((line) => line.startsWith("Process exited with code "));
1563
- const wall = lines.find((line) => line.startsWith("Wall time: "));
1564
- if (exit && wall) return `${exit.replace("Process ", "")}; ${wall.toLowerCase()}`;
1565
- if (exit) return exit.replace("Process ", "");
1566
- return "";
1567
- };
1568
1373
  var extractText = (content) => {
1569
1374
  if (typeof content === "string") return content;
1570
1375
  if (Array.isArray(content)) return content.map((item) => extractContentPart(item)).filter((part) => part.length > 0).join("\n\n");
@@ -1583,9 +1388,6 @@ var extractContentPart = (value) => {
1583
1388
  if (type === "input_image") return "[Image attached]";
1584
1389
  return text ?? "";
1585
1390
  };
1586
- var normalizeCompactLiteral = (value, outputFormat) => {
1587
- return outputFormat === "md" ? value : value.replace(/`([^`]+)`/g, "$1");
1588
- };
1589
1391
  var UI_EXPORT_URL_PREFIX = "/__exports/";
1590
1392
  var DEFAULT_UI_EXPORT_DIR = path.join(os.tmpdir(), "spiracha-ui-exports");
1591
1393
  var DEFAULT_EXPORT_MAX_AGE_MS = 1440 * 60 * 1e3;
@@ -1646,9 +1448,9 @@ var toDownloadOptions = (input) => {
1646
1448
  dbPath: input.dbPath,
1647
1449
  flat: false,
1648
1450
  includeCommentary: input.includeCommentary,
1451
+ includeMetadata: input.includeMetadata,
1649
1452
  includeTools: input.includeTools,
1650
1453
  inputDir: "",
1651
- optimized: input.optimized,
1652
1454
  outputDir: "",
1653
1455
  outputFormat: input.outputFormat,
1654
1456
  projectFilter: null,
@@ -1908,6 +1710,136 @@ var renderCodexThreadsDownload = async (input) => {
1908
1710
  };
1909
1711
  };
1910
1712
  //#endregion
1713
+ //#region ../../src/lib/codex-thread-recovery.ts
1714
+ var backupFile = async (filePath, label) => {
1715
+ const backupPath = `${filePath}.bak-${label}-${(/* @__PURE__ */ new Date()).toISOString().replaceAll(":", "").replace(/\.\d{3}Z$/, "Z").replace("T", "-")}`;
1716
+ await copyFile(filePath, backupPath);
1717
+ return backupPath;
1718
+ };
1719
+ var resolveCodexDirFromDbPath = (dbPath) => {
1720
+ const dbDir = path.dirname(dbPath);
1721
+ return path.basename(dbDir) === "sqlite" ? path.dirname(dbDir) : dbDir;
1722
+ };
1723
+ var assertRequiredStatePath = async (filePath) => {
1724
+ if (!await Bun.file(filePath).exists()) throw new Error(`Required Codex state file not found: ${filePath}`);
1725
+ };
1726
+ var readGlobalState = async (globalStatePath) => {
1727
+ return await Bun.file(globalStatePath).json();
1728
+ };
1729
+ var writeGlobalState = async (globalStatePath, state) => {
1730
+ await Bun.write(globalStatePath, JSON.stringify(state));
1731
+ };
1732
+ var updateGlobalRoots = (state, projectCwds) => {
1733
+ const savedRoots = state["electron-saved-workspace-roots"] ?? [];
1734
+ const projectOrder = state["project-order"] ?? [];
1735
+ const missingSaved = projectCwds.filter((cwd) => !savedRoots.includes(cwd));
1736
+ const missingProjectOrder = projectCwds.filter((cwd) => !projectOrder.includes(cwd));
1737
+ if (missingSaved.length === 0 && missingProjectOrder.length === 0) return {
1738
+ projectRootsAdded: 0,
1739
+ savedRootsAdded: 0,
1740
+ state
1741
+ };
1742
+ state["electron-saved-workspace-roots"] = [...savedRoots, ...missingSaved];
1743
+ state["project-order"] = [...projectOrder, ...missingProjectOrder];
1744
+ return {
1745
+ projectRootsAdded: missingProjectOrder.length,
1746
+ savedRootsAdded: missingSaved.length,
1747
+ state
1748
+ };
1749
+ };
1750
+ var getProjectTopLevelThreads = (db, projectName) => {
1751
+ return db.query("SELECT id, cwd, rollout_path, thread_source FROM threads WHERE archived = 0").all().filter((thread) => {
1752
+ return getPortablePathBasename(thread.cwd) === projectName && thread.thread_source !== "subagent";
1753
+ });
1754
+ };
1755
+ var refreshThreadRows = (db, threadIds) => {
1756
+ if (threadIds.length === 0) return 0;
1757
+ const nowSeconds = Math.floor(Date.now() / 1e3);
1758
+ const nowMs = Date.now();
1759
+ const placeholders = threadIds.map(() => "?").join(", ");
1760
+ const result = db.prepare(`
1761
+ UPDATE threads
1762
+ SET updated_at = ?1,
1763
+ updated_at_ms = ?2,
1764
+ has_user_event = 1
1765
+ WHERE id IN (${placeholders})
1766
+ `).run(nowSeconds, nowMs, ...threadIds);
1767
+ return Number(result.changes);
1768
+ };
1769
+ var refreshSessionIndex = async (sessionIndexPath, threadIds) => {
1770
+ if (threadIds.length === 0) return 0;
1771
+ const now = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
1772
+ const threadIdSet = new Set(threadIds);
1773
+ const lines = (await Bun.file(sessionIndexPath).text()).split("\n");
1774
+ let updated = 0;
1775
+ const rewrittenLines = [];
1776
+ for (const line of lines) {
1777
+ if (!line.trim()) continue;
1778
+ const parsed = JSON.parse(line);
1779
+ if (parsed.id && threadIdSet.has(parsed.id)) {
1780
+ parsed.updated_at = now;
1781
+ updated += 1;
1782
+ }
1783
+ rewrittenLines.push(JSON.stringify(parsed));
1784
+ }
1785
+ await Bun.write(sessionIndexPath, `${rewrittenLines.join("\n")}\n`);
1786
+ return updated;
1787
+ };
1788
+ var touchRolloutFiles = async (codexDir, rolloutPaths) => {
1789
+ const now = /* @__PURE__ */ new Date();
1790
+ let touched = 0;
1791
+ for (const rolloutPath of rolloutPaths) {
1792
+ const absolutePath = path.isAbsolute(rolloutPath) ? rolloutPath : path.join(codexDir, rolloutPath);
1793
+ if (!await Bun.file(absolutePath).exists()) continue;
1794
+ await utimes(absolutePath, now, now);
1795
+ touched += 1;
1796
+ }
1797
+ return touched;
1798
+ };
1799
+ var recoverCodexProjectThreads = async (dbPath, projectName) => {
1800
+ const codexDir = resolveCodexDirFromDbPath(dbPath);
1801
+ const globalStatePath = path.join(codexDir, ".codex-global-state.json");
1802
+ const sessionIndexPath = path.join(codexDir, "session_index.jsonl");
1803
+ await assertRequiredStatePath(dbPath);
1804
+ await assertRequiredStatePath(globalStatePath);
1805
+ await assertRequiredStatePath(sessionIndexPath);
1806
+ const backups = {
1807
+ globalState: await backupFile(globalStatePath, "recover-project-roots"),
1808
+ sessionIndex: await backupFile(sessionIndexPath, "recover-project-session-index"),
1809
+ stateDb: await backupFile(dbPath, "recover-project-threads")
1810
+ };
1811
+ const globalState = await readGlobalState(globalStatePath);
1812
+ const db = runWithSqliteRetry({ action: () => {
1813
+ const opened = new Database(dbPath);
1814
+ opened.exec("PRAGMA busy_timeout = 5000");
1815
+ return opened;
1816
+ } });
1817
+ try {
1818
+ const topLevelThreads = getProjectTopLevelThreads(db, projectName);
1819
+ const projectCwds = [...new Set(topLevelThreads.map((thread) => thread.cwd))];
1820
+ const rootUpdateResult = updateGlobalRoots(globalState, projectCwds);
1821
+ await writeGlobalState(globalStatePath, rootUpdateResult.state);
1822
+ const threadIds = topLevelThreads.map((thread) => thread.id);
1823
+ const rolloutPaths = topLevelThreads.map((thread) => thread.rollout_path);
1824
+ const threadDbRowsUpdated = refreshThreadRows(db, threadIds);
1825
+ const sessionIndexRowsUpdated = await refreshSessionIndex(sessionIndexPath, threadIds);
1826
+ const rolloutFilesTouched = await touchRolloutFiles(codexDir, rolloutPaths);
1827
+ return {
1828
+ backups,
1829
+ projectName,
1830
+ projectRootsAdded: rootUpdateResult.projectRootsAdded,
1831
+ resolvedCwds: projectCwds,
1832
+ rolloutFilesTouched,
1833
+ savedRootsAdded: rootUpdateResult.savedRootsAdded,
1834
+ sessionIndexRowsUpdated,
1835
+ threadDbRowsUpdated,
1836
+ topLevelThreadsFound: threadIds.length
1837
+ };
1838
+ } finally {
1839
+ db.close();
1840
+ }
1841
+ };
1842
+ //#endregion
1911
1843
  //#region src/lib/codex-server.ts?tss-serverfn-split
1912
1844
  var projectSchema = z.object({ project: z.string().min(1) });
1913
1845
  var deleteProjectSchema = z.object({
@@ -1927,8 +1859,8 @@ var analyticsSchema = z.object({ project: z.string().min(1).nullable() });
1927
1859
  var exportSchema = z.object({
1928
1860
  convertToProjectRoot: z.boolean(),
1929
1861
  includeCommentary: z.boolean(),
1862
+ includeMetadata: z.boolean(),
1930
1863
  includeTools: z.boolean(),
1931
- optimized: z.boolean(),
1932
1864
  outputFormat: z.enum(["md", "txt"]),
1933
1865
  redactUsername: z.boolean(),
1934
1866
  threadId: z.string().min(1)
@@ -1936,8 +1868,8 @@ var exportSchema = z.object({
1936
1868
  var exportThreadsSchema = z.object({
1937
1869
  convertToProjectRoot: z.boolean(),
1938
1870
  includeCommentary: z.boolean(),
1871
+ includeMetadata: z.boolean(),
1939
1872
  includeTools: z.boolean(),
1940
- optimized: z.boolean(),
1941
1873
  outputFormat: z.enum(["md", "txt"]),
1942
1874
  redactUsername: z.boolean(),
1943
1875
  threadIds: z.array(z.string().min(1)).min(1)
@@ -2022,8 +1954,8 @@ var exportThreadFn = createServerFn({ method: "POST" }).inputValidator(exportSch
2022
1954
  return renderCodexThreadDownload({
2023
1955
  dbPath: getDbPath(),
2024
1956
  includeCommentary: data.includeCommentary,
1957
+ includeMetadata: data.includeMetadata,
2025
1958
  includeTools: data.includeTools,
2026
- optimized: data.optimized,
2027
1959
  outputFormat: data.outputFormat,
2028
1960
  pathDisplaySettings: {
2029
1961
  convertToProjectRoot: data.convertToProjectRoot,
@@ -2041,8 +1973,8 @@ var exportThreadsFn = createServerFn({ method: "POST" }).inputValidator(exportTh
2041
1973
  return renderCodexThreadsDownload({
2042
1974
  dbPath: getDbPath(),
2043
1975
  includeCommentary: data.includeCommentary,
1976
+ includeMetadata: data.includeMetadata,
2044
1977
  includeTools: data.includeTools,
2045
- optimized: data.optimized,
2046
1978
  outputFormat: data.outputFormat,
2047
1979
  pathDisplaySettings: {
2048
1980
  convertToProjectRoot: data.convertToProjectRoot,
@@ -2075,5 +2007,13 @@ var deleteProjectFn_createServerFn_handler = createServerRpc({
2075
2007
  var deleteProjectFn = createServerFn({ method: "POST" }).inputValidator(deleteProjectSchema).handler(deleteProjectFn_createServerFn_handler, async ({ data }) => {
2076
2008
  return deleteCodexProject(getDbPath(), data.project, { deleteSessionFiles: data.deleteSessionFiles });
2077
2009
  });
2010
+ var recoverProjectThreadsFn_createServerFn_handler = createServerRpc({
2011
+ id: "412c05e00aef3ad43905593fdfd2f566561259da7e1f5d6f1c03428ff33c6867",
2012
+ name: "recoverProjectThreadsFn",
2013
+ filename: "src/lib/codex-server.ts"
2014
+ }, (opts) => recoverProjectThreadsFn.__executeServer(opts));
2015
+ var recoverProjectThreadsFn = createServerFn({ method: "POST" }).inputValidator(projectSchema).handler(recoverProjectThreadsFn_createServerFn_handler, async ({ data }) => {
2016
+ return recoverCodexProjectThreads(getDbPath(), data.project);
2017
+ });
2078
2018
  //#endregion
2079
- export { deleteProjectFn_createServerFn_handler, deleteThreadFn_createServerFn_handler, deleteThreadsFn_createServerFn_handler, exportThreadFn_createServerFn_handler, exportThreadsFn_createServerFn_handler, getAnalyticsFn_createServerFn_handler, getDashboardSummaryFn_createServerFn_handler, getThreadSnapshotFn_createServerFn_handler, getThreadTranscriptFn_createServerFn_handler, listProjectThreadsFn_createServerFn_handler, listProjectsFn_createServerFn_handler };
2019
+ export { deleteProjectFn_createServerFn_handler, deleteThreadFn_createServerFn_handler, deleteThreadsFn_createServerFn_handler, exportThreadFn_createServerFn_handler, exportThreadsFn_createServerFn_handler, getAnalyticsFn_createServerFn_handler, getDashboardSummaryFn_createServerFn_handler, getThreadSnapshotFn_createServerFn_handler, getThreadTranscriptFn_createServerFn_handler, listProjectThreadsFn_createServerFn_handler, listProjectsFn_createServerFn_handler, recoverProjectThreadsFn_createServerFn_handler };
@@ -0,0 +1,12 @@
1
+ import { n as TSS_SERVER_FUNCTION } from "../server.js";
2
+ //#region ../../node_modules/.bun/@tanstack+start-server-core@1.169.3/node_modules/@tanstack/start-server-core/dist/esm/createServerRpc.js
3
+ var createServerRpc = (serverFnMeta, splitImportFn) => {
4
+ const url = "/_serverFn/" + serverFnMeta.id;
5
+ return Object.assign(splitImportFn, {
6
+ url,
7
+ serverFnMeta,
8
+ [TSS_SERVER_FUNCTION]: true
9
+ });
10
+ };
11
+ //#endregion
12
+ export { createServerRpc as t };
@@ -0,0 +1,16 @@
1
+ import { n as TSS_SERVER_FUNCTION, r as getServerFnById } from "../server.js";
2
+ //#region ../../node_modules/.bun/@tanstack+start-server-core@1.169.3/node_modules/@tanstack/start-server-core/dist/esm/createSsrRpc.js
3
+ var createSsrRpc = (functionId) => {
4
+ const url = "/_serverFn/" + functionId;
5
+ const serverFnMeta = { id: functionId };
6
+ const fn = async (...args) => {
7
+ return (await getServerFnById(functionId, { origin: "server" }))(...args);
8
+ };
9
+ return Object.assign(fn, {
10
+ url,
11
+ serverFnMeta,
12
+ [TSS_SERVER_FUNCTION]: true
13
+ });
14
+ };
15
+ //#endregion
16
+ export { createSsrRpc as t };