spiracha 1.2.0 → 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 (149) hide show
  1. package/AGENTS.md +49 -12
  2. package/README.md +117 -64
  3. package/apps/ui/AGENTS.md +16 -8
  4. package/apps/ui/README.md +28 -12
  5. package/apps/ui/dist/client/assets/{analytics-Cv0JMDN2.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-Bgnh7phF.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-BJX5rkHK.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-CUiCZSwo.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-2QpLKjlG.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-BH4Cb0v3.js → codex-queries-eOJGfHQj.js} +4 -16
  71. package/apps/ui/dist/server/assets/{codex-server-DqzruLmg.js → codex-server-nrETIF--.js} +149 -140
  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-Drctxary.js → export-dialog-DaPlOGFT.js} +1 -92
  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-gT01HBqH.js → projects._project-DUN3iWfg.js} +4 -4
  98. package/apps/ui/dist/server/assets/{projects._project-DreIU5b0.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-BYmgSGAj.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-Qj5Kn7bl.js → router-DrDgc-LD.js} +131 -44
  103. package/apps/ui/dist/server/assets/{routes-_LbCIjtJ.js → routes-B-GlEe2C.js} +54 -39
  104. package/apps/ui/dist/server/assets/{routes-BtcXuK0x.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-DcbAJkwf.js → threads._threadId-CJzm4KrZ.js} +3 -3
  110. package/apps/ui/dist/server/assets/{threads._threadId-D5m6ypGw.js → threads._threadId-DODTYddm.js} +69 -76
  111. package/apps/ui/dist/server/server.js +77 -13
  112. package/package.json +19 -9
  113. package/src/export-cursor.ts +244 -0
  114. package/src/lib/antigravity-db.ts +936 -0
  115. package/src/lib/antigravity-exporter-types.ts +70 -0
  116. package/src/lib/antigravity-keychain.ts +203 -0
  117. package/src/lib/codex-browser-db.ts +7 -1
  118. package/src/lib/codex-browser-types.ts +22 -1
  119. package/src/lib/codex-thread-recovery.ts +202 -0
  120. package/src/lib/cursor-db.ts +1096 -0
  121. package/src/lib/cursor-exporter-types.ts +190 -0
  122. package/src/lib/cursor-exporter.ts +266 -0
  123. package/src/lib/cursor-recovery.ts +543 -0
  124. package/src/lib/cursor-transcript.ts +183 -0
  125. package/src/spiracha.ts +16 -3
  126. package/src/ui-cli.ts +2 -2
  127. package/apps/ui/dist/client/assets/checkbox-DjHij7DJ.js +0 -1
  128. package/apps/ui/dist/client/assets/delete-confirm-dialog-CIZy_LXD.js +0 -11
  129. package/apps/ui/dist/client/assets/download-DQtfva4z.js +0 -1
  130. package/apps/ui/dist/client/assets/es2015-DsDKdYCE.js +0 -41
  131. package/apps/ui/dist/client/assets/formatters-CWFrMKSn.js +0 -1
  132. package/apps/ui/dist/client/assets/index-C_-e0lDI.js +0 -22
  133. package/apps/ui/dist/client/assets/input-BbgApiqZ.js +0 -1
  134. package/apps/ui/dist/client/assets/page-header-ODLuGLAB.js +0 -1
  135. package/apps/ui/dist/client/assets/projects._project-C2Pys_bB.js +0 -1
  136. package/apps/ui/dist/client/assets/projects._project-CHvAKvlu.js +0 -1
  137. package/apps/ui/dist/client/assets/projects.index-BmwtS1x-.js +0 -1
  138. package/apps/ui/dist/client/assets/projects.index-CuLw73mt.js +0 -1
  139. package/apps/ui/dist/client/assets/routes-CfnaTOlj.js +0 -1
  140. package/apps/ui/dist/client/assets/select-B1kH_5lx.js +0 -1
  141. package/apps/ui/dist/client/assets/settings-mYTB3sso.js +0 -1
  142. package/apps/ui/dist/client/assets/styles-CMrP9Jb4.css +0 -1
  143. package/apps/ui/dist/client/assets/threads._threadId-C_47okme.js +0 -7
  144. package/apps/ui/dist/client/favicon.ico +0 -0
  145. package/apps/ui/dist/client/logo192.png +0 -0
  146. package/apps/ui/dist/client/logo512.png +0 -0
  147. package/apps/ui/dist/server/assets/_tanstack-start-manifest_v-kj_QB_26.js +0 -99
  148. package/apps/ui/dist/server/assets/page-header-CxdZM86z.js +0 -25
  149. package/apps/ui/dist/server/assets/projects._project-CLSohrBp.js +0 -26
@@ -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;
@@ -1839,6 +1710,136 @@ var renderCodexThreadsDownload = async (input) => {
1839
1710
  };
1840
1711
  };
1841
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
1842
1843
  //#region src/lib/codex-server.ts?tss-serverfn-split
1843
1844
  var projectSchema = z.object({ project: z.string().min(1) });
1844
1845
  var deleteProjectSchema = z.object({
@@ -2006,5 +2007,13 @@ var deleteProjectFn_createServerFn_handler = createServerRpc({
2006
2007
  var deleteProjectFn = createServerFn({ method: "POST" }).inputValidator(deleteProjectSchema).handler(deleteProjectFn_createServerFn_handler, async ({ data }) => {
2007
2008
  return deleteCodexProject(getDbPath(), data.project, { deleteSessionFiles: data.deleteSessionFiles });
2008
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
+ });
2009
2018
  //#endregion
2010
- 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 };