spiracha 1.3.3 → 1.4.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 (158) hide show
  1. package/AGENTS.md +7 -1
  2. package/README.md +6 -0
  3. package/apps/ui/AGENTS.md +8 -0
  4. package/apps/ui/README.md +10 -3
  5. package/apps/ui/dist/client/assets/analytics-DK2jdvmI.js +1 -0
  6. package/apps/ui/dist/client/assets/antigravity-conversations._conversationId-DmD0sN8X.js +7 -0
  7. package/apps/ui/dist/client/assets/antigravity-conversations._conversationId-KAcXtNxI.js +1 -0
  8. package/apps/ui/dist/client/assets/antigravity-keychain-panel-BRHVjFAM.js +1 -0
  9. package/apps/ui/dist/client/assets/antigravity._workspaceKey-ByitGWki.js +1 -0
  10. package/apps/ui/dist/client/assets/antigravity._workspaceKey-CGV7amas.js +1 -0
  11. package/apps/ui/dist/client/assets/antigravity.index-DEEkjlZa.js +1 -0
  12. package/apps/ui/dist/client/assets/antigravity.index-DgW25FEV.js +1 -0
  13. package/apps/ui/dist/client/assets/badge-DfWvPfKF.js +1 -0
  14. package/apps/ui/dist/client/assets/checkbox-CdHitXWQ.js +1 -0
  15. package/apps/ui/dist/client/assets/createServerFn-CgRRVpBH.js +3 -0
  16. package/apps/ui/dist/client/assets/cursor-threads._composerId-CmBFclK8.js +1 -0
  17. package/apps/ui/dist/client/assets/cursor-threads._composerId-Ti2gTm63.js +1 -0
  18. package/apps/ui/dist/client/assets/cursor._workspaceKey-CaAZjGmm.js +1 -0
  19. package/apps/ui/dist/client/assets/cursor._workspaceKey-DzD_c6j9.js +1 -0
  20. package/apps/ui/dist/client/assets/cursor.index-CrnMwDCi.js +1 -0
  21. package/apps/ui/dist/client/assets/cursor.index-PkCFVcl4.js +2 -0
  22. package/apps/ui/dist/client/assets/{data-table-DeQq8xdt.js → data-table-Br78_dk3.js} +2 -2
  23. package/apps/ui/dist/client/assets/delete-confirm-dialog-BHRmyLHr.js +11 -0
  24. package/apps/ui/dist/client/assets/dist-B9pyYCVU.js +1 -0
  25. package/apps/ui/dist/client/assets/dist-BhZOxAPP.js +1 -0
  26. package/apps/ui/dist/client/assets/dist-DvMS2965.js +1 -0
  27. package/apps/ui/dist/client/assets/download-Bf0QJKD3.js +1 -0
  28. package/apps/ui/dist/client/assets/dropdown-menu-Dy5cLzTy.js +1 -0
  29. package/apps/ui/dist/client/assets/es2015-BkCWttyM.js +41 -0
  30. package/apps/ui/dist/client/assets/export-dialog-C86SYHJn.js +1 -0
  31. package/apps/ui/dist/client/assets/formatters-BM9kB7ed.js +1 -0
  32. package/apps/ui/dist/client/assets/index-CPvAP-jk.js +149 -0
  33. package/apps/ui/dist/client/assets/jsx-runtime-DGeXAQPT.js +1 -0
  34. package/apps/ui/dist/client/assets/metric-card-Dplm0ZiM.js +1 -0
  35. package/apps/ui/dist/client/assets/page-header-Cwa3p6Tl.js +1 -0
  36. package/apps/ui/dist/client/assets/projects._project-Ckf6muWZ.js +1 -0
  37. package/apps/ui/dist/client/assets/projects._project-DSDwH4NF.js +1 -0
  38. package/apps/ui/dist/client/assets/projects.index-DEfhWqa8.js +1 -0
  39. package/apps/ui/dist/client/assets/projects.index-V5ibNZII.js +3 -0
  40. package/apps/ui/dist/client/assets/react-dom-DL96Jor4.js +1 -0
  41. package/apps/ui/dist/client/assets/refresh-ccw-BgKjOiA6.js +1 -0
  42. package/apps/ui/dist/client/assets/reload-error-panel-AHqu0akK.js +1 -0
  43. package/apps/ui/dist/client/assets/routes-Df2tgpyd.js +1 -0
  44. package/apps/ui/dist/client/assets/scroll-text-fM0sMOB3.js +1 -0
  45. package/apps/ui/dist/client/assets/select-Bf2GwfPR.js +1 -0
  46. package/apps/ui/dist/client/assets/settings-5VQIzME0.js +1 -0
  47. package/apps/ui/dist/client/assets/sqlite-error-B6uZjUe8.js +1 -0
  48. package/apps/ui/dist/client/assets/styles-BhRkXgwB.css +1 -0
  49. package/apps/ui/dist/client/assets/tabs-OO4VU5KR.js +7 -0
  50. package/apps/ui/dist/client/assets/text-filter-DVAZySUS.js +2 -0
  51. package/apps/ui/dist/client/assets/threads._threadId-BB9tTsV4.js +1 -0
  52. package/apps/ui/dist/client/assets/threads._threadId-BgDhFj2I.js +1 -0
  53. package/apps/ui/dist/client/assets/useMutation-CC_B7uy5.js +1 -0
  54. package/apps/ui/dist/client/assets/useQuery-C5By6WKU.js +1 -0
  55. package/apps/ui/dist/server/assets/_tanstack-start-manifest_v-CRW2kqj0.js +232 -0
  56. package/apps/ui/dist/server/assets/analytics-CYP_LT5Y.js +16 -0
  57. package/apps/ui/dist/server/assets/{analytics-Dc_QDZZC.js → analytics-CtpOMVMO.js} +13 -6
  58. package/apps/ui/dist/server/assets/antigravity-conversations._conversationId-BtexWY-K.js +613 -0
  59. package/apps/ui/dist/server/assets/{antigravity-conversations._conversationId-C9z4AeN-.js → antigravity-conversations._conversationId-zMrR6v6R.js} +2 -2
  60. package/apps/ui/dist/server/assets/{antigravity-db-D9gW1D8G.js → antigravity-db-Bh8_U9uw.js} +11 -7
  61. package/apps/ui/dist/server/assets/{antigravity-keychain-panel-bpPoxhyp.js → antigravity-keychain-panel-CC7FLmAK.js} +1 -1
  62. package/apps/ui/dist/server/assets/{antigravity-queries-DVIKyOXi.js → antigravity-queries-CGrJO9Vr.js} +5 -5
  63. package/apps/ui/dist/server/assets/{antigravity-server-Cp1lc8fp.js → antigravity-server-CHRjVFqN.js} +11 -11
  64. package/apps/ui/dist/server/assets/{antigravity._workspaceKey-Dl8o1ptg.js → antigravity._workspaceKey-B0QeYUOh.js} +2 -2
  65. package/apps/ui/dist/server/assets/{antigravity._workspaceKey-BAoa4izU.js → antigravity._workspaceKey-C3kP-qyN.js} +4 -4
  66. package/apps/ui/dist/server/assets/{antigravity.index-BOlrJasZ.js → antigravity.index-CPCYkqCi.js} +2 -2
  67. package/apps/ui/dist/server/assets/{codex-queries-ev_mRUzr.js → codex-queries-CtgeZ7VL.js} +15 -13
  68. package/apps/ui/dist/server/assets/{codex-server-DIYFLozB.js → codex-server-CNXSJuc2.js} +104 -119
  69. package/apps/ui/dist/server/assets/concurrency-VXtYvlGh.js +18 -0
  70. package/apps/ui/dist/server/assets/{createServerRpc-Cg-Zr1rq.js → createServerRpc-CF_DEwnm.js} +1 -1
  71. package/apps/ui/dist/server/assets/{createSsrRpc-DVnVQhGx.js → createSsrRpc-C754NPki.js} +1 -1
  72. package/apps/ui/dist/server/assets/{cursor-db-B7agkAvM.js → cursor-db-cYZEU3WQ.js} +194 -7
  73. package/apps/ui/dist/server/assets/{cursor-queries-f7DjBKSD.js → cursor-queries-NCIM0Nat.js} +12 -10
  74. package/apps/ui/dist/server/assets/{cursor-recovery-9bJLs7vG.js → cursor-recovery-nq-kR62j.js} +1 -1
  75. package/apps/ui/dist/server/assets/{cursor-server-nPzojHN3.js → cursor-server-C3q7hrp-.js} +70 -41
  76. package/apps/ui/dist/server/assets/{cursor-threads._composerId-B3qcsh9C.js → cursor-threads._composerId-BPJFWfJj.js} +2 -2
  77. package/apps/ui/dist/server/assets/cursor-threads._composerId-BkMMTQ3v.js +582 -0
  78. package/apps/ui/dist/server/assets/{cursor._workspaceKey-BL_CQyHQ.js → cursor._workspaceKey-C5PdTaKB.js} +2 -2
  79. package/apps/ui/dist/server/assets/{cursor._workspaceKey-BhQeepXB.js → cursor._workspaceKey-Ckj7apKI.js} +11 -9
  80. package/apps/ui/dist/server/assets/{cursor.index-CsrdckZD.js → cursor.index-DkWT-mxw.js} +2 -2
  81. package/apps/ui/dist/server/assets/{delete-confirm-dialog-PCD7S0_M.js → delete-confirm-dialog-BcBNCxWB.js} +5 -1
  82. package/apps/ui/dist/server/assets/{empty-plugin-adapters-D3qLMPfC.js → empty-plugin-adapters-B3lHh1La.js} +1 -1
  83. package/apps/ui/dist/server/assets/{export-dialog-DaPlOGFT.js → export-dialog-BItjWgkZ.js} +53 -11
  84. package/apps/ui/dist/server/assets/{projects._project-CqqUFr4l.js → projects._project-Bpbc3C-L.js} +5 -3
  85. package/apps/ui/dist/server/assets/{projects._project-DahGqNYS.js → projects._project-CvZho6EQ.js} +42 -12
  86. package/apps/ui/dist/server/assets/{projects.index-CkTeFWNU.js → projects.index-BkLiF2FF.js} +21 -7
  87. package/apps/ui/dist/server/assets/projects.index-DesYXwfi.js +14 -0
  88. package/apps/ui/dist/server/assets/route-search-ts4W9MJ9.js +38 -0
  89. package/apps/ui/dist/server/assets/{router-K0m7dK4T.js → router-6m-ihwqA.js} +78 -62
  90. package/apps/ui/dist/server/assets/{routes-Xix3ZeSo.js → routes-Bsact1uB.js} +2 -2
  91. package/apps/ui/dist/server/assets/{routes-0x1U0IHq.js → routes-BzkJgq4W.js} +2 -2
  92. package/apps/ui/dist/server/assets/start-CI_0bSiY.js +4 -0
  93. package/apps/ui/dist/server/assets/tabs-CGA13IZM.js +502 -0
  94. package/apps/ui/dist/server/assets/{threads._threadId-BLCkGW--.js → threads._threadId-Bs0yuqO9.js} +2 -2
  95. package/apps/ui/dist/server/assets/threads._threadId-D2GYkVn6.js +639 -0
  96. package/apps/ui/dist/server/assets/ui-export-files-BHLX9bhN.js +83 -0
  97. package/apps/ui/dist/server/server.js +93 -83
  98. package/package.json +9 -9
  99. package/src/lib/antigravity-db.ts +20 -13
  100. package/src/lib/codex-analytics.ts +118 -18
  101. package/src/lib/codex-browser-db.ts +1 -25
  102. package/src/lib/codex-browser-export.ts +9 -69
  103. package/src/lib/cursor-db.ts +318 -7
  104. package/src/lib/cursor-exporter.ts +2 -2
  105. package/src/lib/ui-cache.ts +14 -1
  106. package/apps/ui/dist/client/assets/analytics-C83LcWNb.js +0 -1
  107. package/apps/ui/dist/client/assets/antigravity-conversations._conversationId-DkY8EEpK.js +0 -1
  108. package/apps/ui/dist/client/assets/antigravity-conversations._conversationId-OraHuz8j.js +0 -1
  109. package/apps/ui/dist/client/assets/antigravity-keychain-panel-DnDcq1ge.js +0 -1
  110. package/apps/ui/dist/client/assets/antigravity._workspaceKey-CQaZscA5.js +0 -1
  111. package/apps/ui/dist/client/assets/antigravity._workspaceKey-DTs99obU.js +0 -1
  112. package/apps/ui/dist/client/assets/antigravity.index-DbJa715k.js +0 -1
  113. package/apps/ui/dist/client/assets/antigravity.index-P-rs6w5X.js +0 -1
  114. package/apps/ui/dist/client/assets/badge-wgTVp-aq.js +0 -1
  115. package/apps/ui/dist/client/assets/checkbox-BUx0Gkuf.js +0 -1
  116. package/apps/ui/dist/client/assets/cursor-threads._composerId-D0DFXt8t.js +0 -1
  117. package/apps/ui/dist/client/assets/cursor-threads._composerId-tFa6Cf6A.js +0 -1
  118. package/apps/ui/dist/client/assets/cursor._workspaceKey-Df4PfA2k.js +0 -1
  119. package/apps/ui/dist/client/assets/cursor._workspaceKey-DwrzEtnV.js +0 -1
  120. package/apps/ui/dist/client/assets/cursor.index-CNBf4ZiR.js +0 -1
  121. package/apps/ui/dist/client/assets/cursor.index-DP9Hy8X6.js +0 -2
  122. package/apps/ui/dist/client/assets/delete-confirm-dialog-CPlNsLhM.js +0 -11
  123. package/apps/ui/dist/client/assets/dist-Ds3kS91l.js +0 -1
  124. package/apps/ui/dist/client/assets/download-DLuPnxpV.js +0 -1
  125. package/apps/ui/dist/client/assets/dropdown-menu-lFk6zjoL.js +0 -1
  126. package/apps/ui/dist/client/assets/es2015-D-H_iZF6.js +0 -41
  127. package/apps/ui/dist/client/assets/export-dialog-CyqyvwiP.js +0 -1
  128. package/apps/ui/dist/client/assets/formatters-DbCKP02D.js +0 -1
  129. package/apps/ui/dist/client/assets/index-C-ZPpKJ0.js +0 -22
  130. package/apps/ui/dist/client/assets/json-panel-BsngvucB.js +0 -1
  131. package/apps/ui/dist/client/assets/metadata-section-Dtl8dNag.js +0 -1
  132. package/apps/ui/dist/client/assets/metric-card-DNzR1Rne.js +0 -1
  133. package/apps/ui/dist/client/assets/page-header-dha_O7ZL.js +0 -1
  134. package/apps/ui/dist/client/assets/projects._project-B7HBhbXv.js +0 -1
  135. package/apps/ui/dist/client/assets/projects._project-DHVvuT7A.js +0 -1
  136. package/apps/ui/dist/client/assets/projects.index-BUUtx2AZ.js +0 -1
  137. package/apps/ui/dist/client/assets/projects.index-BojAe1Y4.js +0 -3
  138. package/apps/ui/dist/client/assets/refresh-ccw-B-ASKHtx.js +0 -1
  139. package/apps/ui/dist/client/assets/reload-error-panel-DD8M1BIY.js +0 -1
  140. package/apps/ui/dist/client/assets/routes-q7bzFp35.js +0 -1
  141. package/apps/ui/dist/client/assets/scroll-text-TvHyiJ_N.js +0 -1
  142. package/apps/ui/dist/client/assets/select-BFv1HMiT.js +0 -1
  143. package/apps/ui/dist/client/assets/settings-CvegTo4F.js +0 -1
  144. package/apps/ui/dist/client/assets/styles-Ch0r3kMZ.css +0 -1
  145. package/apps/ui/dist/client/assets/text-document-panel-D7Rws41o.js +0 -1
  146. package/apps/ui/dist/client/assets/text-filter-2q5pEoZh.js +0 -2
  147. package/apps/ui/dist/client/assets/threads._threadId-LpZVUlPq.js +0 -7
  148. package/apps/ui/dist/client/assets/threads._threadId-MSmNIBkq.js +0 -1
  149. package/apps/ui/dist/client/assets/useMutation-BOPJU9e0.js +0 -1
  150. package/apps/ui/dist/client/assets/useQuery-CbxZiVGF.js +0 -1
  151. package/apps/ui/dist/server/assets/_tanstack-start-manifest_v-zvGzK-Yx.js +0 -229
  152. package/apps/ui/dist/server/assets/antigravity-conversations._conversationId-JEhx-f2R.js +0 -212
  153. package/apps/ui/dist/server/assets/cursor-threads._composerId-BK3iW-3e.js +0 -218
  154. package/apps/ui/dist/server/assets/json-panel-RYsxWFae.js +0 -16
  155. package/apps/ui/dist/server/assets/metadata-section-D6Lbc7D6.js +0 -54
  156. package/apps/ui/dist/server/assets/start-bX7bXjzw.js +0 -4
  157. package/apps/ui/dist/server/assets/text-document-panel-D8JbQWAn.js +0 -23
  158. package/apps/ui/dist/server/assets/threads._threadId-LjgsGUh-.js +0 -1052
@@ -3,6 +3,7 @@ import { getCursorGlobalDbPath, getCursorProjectsDir, getCursorWorkspaceStorageD
3
3
  import { Database, constants } from "bun:sqlite";
4
4
  import { readdir, stat } from "node:fs/promises";
5
5
  import path from "node:path";
6
+ import { createHash } from "node:crypto";
6
7
  //#region ../../src/lib/cursor-db.ts
7
8
  var CURSOR_READONLY_DB_OPEN_FLAGS = constants.SQLITE_OPEN_READONLY | constants.SQLITE_OPEN_URI;
8
9
  var getCursorReadonlyDbUri = (dbPath) => {
@@ -52,10 +53,23 @@ var normalizeCursorPath = (value) => {
52
53
  if (!decoded) return "";
53
54
  return decoded.replace(/\/+$/u, "") || decoded;
54
55
  };
56
+ var warnCursorDataIssue = (event, details) => {
57
+ console.warn(`[spiracha:cursor] ${event}`, details);
58
+ };
59
+ var stripJsonComments = (value) => {
60
+ return value.replace(/\/\*[\s\S]*?\*\//gu, "").replace(/(^|\s)\/\/.*$/gmu, "$1");
61
+ };
62
+ var parseCodeWorkspaceJson = (text) => {
63
+ try {
64
+ return JSON.parse(text);
65
+ } catch {
66
+ return JSON.parse(stripJsonComments(text));
67
+ }
68
+ };
55
69
  var parseCodeWorkspaceFolders = async (workspaceFilePath) => {
56
70
  if (!workspaceFilePath.endsWith(".code-workspace")) return [];
57
71
  try {
58
- const data = await Bun.file(workspaceFilePath).json();
72
+ const data = parseCodeWorkspaceJson(await Bun.file(workspaceFilePath).text());
59
73
  const folders = [];
60
74
  for (const entry of data.folders ?? []) {
61
75
  const folderPath = entry.path;
@@ -63,16 +77,28 @@ var parseCodeWorkspaceFolders = async (workspaceFilePath) => {
63
77
  folders.push(folderPath.startsWith("/") ? normalizeCursorPath(folderPath) : normalizeCursorPath(path.join(path.dirname(workspaceFilePath), folderPath)));
64
78
  }
65
79
  return folders;
66
- } catch {
80
+ } catch (error) {
81
+ warnCursorDataIssue("invalid_code_workspace_json", {
82
+ error: error instanceof Error ? error.message : String(error),
83
+ workspaceFilePath
84
+ });
67
85
  return [];
68
86
  }
69
87
  };
70
88
  var loadGlobalComposerHeaders = (globalDbPath) => {
71
- const db = openCursorReadonlyDb(globalDbPath);
72
89
  try {
73
- return readItemValue(db, "composer.composerHeaders")?.allComposers ?? [];
74
- } finally {
75
- db.close();
90
+ const db = openCursorReadonlyDb(globalDbPath);
91
+ try {
92
+ return readItemValue(db, "composer.composerHeaders")?.allComposers ?? [];
93
+ } finally {
94
+ db.close();
95
+ }
96
+ } catch (error) {
97
+ warnCursorDataIssue("global_composer_headers_unavailable", {
98
+ error: error instanceof Error ? error.message : String(error),
99
+ globalDbPath
100
+ });
101
+ return [];
76
102
  }
77
103
  };
78
104
  var readBucketWorkspaceJson = async (workspaceJsonPath) => {
@@ -613,6 +639,162 @@ var readBubble = (db, composerId, bubbleId) => {
613
639
  var isRenderableBubble = (bubble) => {
614
640
  return Boolean(bubble.text.trim() || bubble.thinking?.trim() || bubble.toolCall);
615
641
  };
642
+ var normalizeBubbleText = (value) => {
643
+ return (value ?? "").replace(/\s+/gu, " ").trim();
644
+ };
645
+ var hashText = (value) => createHash("sha1").update(value).digest("hex").slice(0, 12);
646
+ var stableStringifyJson = (value) => {
647
+ if (Array.isArray(value)) return `[${value.map(stableStringifyJson).join(",")}]`;
648
+ if (value && typeof value === "object") return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${stableStringifyJson(value[key])}`).join(",")}}`;
649
+ return JSON.stringify(value);
650
+ };
651
+ var normalizeToolArgumentsText = (value) => {
652
+ if (!value?.trim()) return "";
653
+ try {
654
+ return stableStringifyJson(JSON.parse(value));
655
+ } catch {
656
+ return normalizeBubbleText(value);
657
+ }
658
+ };
659
+ var hasRenderableTextSuperset = (left, right) => {
660
+ const normalizedLeft = normalizeBubbleText(left);
661
+ const normalizedRight = normalizeBubbleText(right);
662
+ if (!normalizedLeft && !normalizedRight) return true;
663
+ return normalizedLeft === normalizedRight || normalizedLeft.startsWith(normalizedRight) || normalizedRight.startsWith(normalizedLeft);
664
+ };
665
+ var haveSameToolIdentity = (left, right) => {
666
+ if (!left && !right) return true;
667
+ if (!left || !right) return false;
668
+ return left.name === right.name && normalizeToolArgumentsText(left.argumentsText) === normalizeToolArgumentsText(right.argumentsText);
669
+ };
670
+ var areEquivalentBubbles = (left, right) => {
671
+ return left.kind === right.kind && hasRenderableTextSuperset(left.text, right.text) && Boolean(normalizeBubbleText(left.thinking)) === Boolean(normalizeBubbleText(right.thinking)) && haveSameToolIdentity(left.toolCall, right.toolCall);
672
+ };
673
+ var findAgentTailStartIndex = (existingBubbles, agentBubbles) => {
674
+ const maxOverlap = Math.min(existingBubbles.length, agentBubbles.length);
675
+ for (let overlapLength = maxOverlap; overlapLength > 0; overlapLength -= 1) {
676
+ const existingStart = existingBubbles.length - overlapLength;
677
+ if (agentBubbles.slice(0, overlapLength).every((bubble, index) => areEquivalentBubbles(existingBubbles[existingStart + index], bubble))) return overlapLength;
678
+ }
679
+ return 0;
680
+ };
681
+ var hasEquivalentBubble = (bubbles, candidate) => {
682
+ return bubbles.some((bubble) => areEquivalentBubbles(bubble, candidate));
683
+ };
684
+ var getAgentTranscriptContentParts = (entry) => {
685
+ const content = asObject(entry.message ?? null)?.content ?? entry.content ?? null;
686
+ if (Array.isArray(content)) return content.map((part) => asObject(part)).filter((part) => Boolean(part));
687
+ if (typeof content === "string") return [{
688
+ text: content,
689
+ type: "text"
690
+ }];
691
+ return [];
692
+ };
693
+ var parseAgentTranscriptToolCall = (parts) => {
694
+ const toolUse = parts.find((part) => asString(part.type ?? null) === "tool_use");
695
+ if (!toolUse) return null;
696
+ const name = asString(toolUse.name ?? null);
697
+ if (!name) return null;
698
+ return {
699
+ argumentsText: toolUse.input === void 0 ? null : JSON.stringify(toolUse.input),
700
+ callId: asString(toolUse.id ?? null),
701
+ name,
702
+ resultText: null,
703
+ status: null
704
+ };
705
+ };
706
+ var parseAgentTranscriptBubble = (filePath, lineNumber, raw) => {
707
+ const message = asObject(raw.message ?? null);
708
+ const role = asString(raw.role ?? message?.role ?? null);
709
+ const kind = role === "user" || role === "assistant" ? role : "unknown";
710
+ const parts = getAgentTranscriptContentParts(raw);
711
+ const text = parts.filter((part) => asString(part.type ?? null) === "text").map((part) => asString(part.text ?? null)).filter((value) => Boolean(value?.trim())).join("\n\n");
712
+ const toolCall = parseAgentTranscriptToolCall(parts);
713
+ const bubble = {
714
+ bubbleId: `agent-transcript:${hashText(path.resolve(filePath))}:${path.basename(filePath)}:${lineNumber}`,
715
+ createdAtMs: null,
716
+ kind,
717
+ text,
718
+ thinking: null,
719
+ toolCall
720
+ };
721
+ return isRenderableBubble(bubble) ? bubble : null;
722
+ };
723
+ var readCursorAgentTranscriptFile = async (filePath) => {
724
+ let text = "";
725
+ try {
726
+ text = await Bun.file(filePath).text();
727
+ } catch (error) {
728
+ warnCursorDataIssue("agent_transcript_unreadable", {
729
+ error: error instanceof Error ? error.message : String(error),
730
+ filePath
731
+ });
732
+ return [];
733
+ }
734
+ const bubbles = [];
735
+ for (const [index, line] of text.split(/\n/u).entries()) {
736
+ if (!line.trim()) continue;
737
+ let raw;
738
+ try {
739
+ raw = JSON.parse(line);
740
+ } catch (error) {
741
+ warnCursorDataIssue("invalid_agent_transcript_jsonl", {
742
+ error: error instanceof Error ? error.message : String(error),
743
+ filePath,
744
+ lineNumber: index + 1
745
+ });
746
+ continue;
747
+ }
748
+ const entry = asObject(raw);
749
+ if (!entry) continue;
750
+ const bubble = parseAgentTranscriptBubble(filePath, index + 1, entry);
751
+ if (bubble) bubbles.push(bubble);
752
+ }
753
+ return bubbles;
754
+ };
755
+ var listCursorAgentTranscriptFiles = async (transcriptDir, composerId) => {
756
+ const preferred = path.join(transcriptDir, `${composerId}.jsonl`);
757
+ const files = /* @__PURE__ */ new Set();
758
+ if (await pathExists(preferred)) files.add(preferred);
759
+ let entries = [];
760
+ try {
761
+ entries = await readdir(transcriptDir);
762
+ } catch {
763
+ return [...files];
764
+ }
765
+ for (const entry of entries) if (entry.endsWith(".jsonl")) files.add(path.join(transcriptDir, entry));
766
+ return [...files].sort();
767
+ };
768
+ var readCursorAgentTranscriptBubbles = async (composerId, userDir) => {
769
+ const transcriptDirs = await findCursorTranscriptDirs(composerId, userDir);
770
+ const bubbles = [];
771
+ for (const transcriptDir of transcriptDirs.sort()) {
772
+ const files = await listCursorAgentTranscriptFiles(transcriptDir, composerId);
773
+ for (const file of files) bubbles.push(...await readCursorAgentTranscriptFile(file));
774
+ }
775
+ return bubbles;
776
+ };
777
+ var mergeAgentTranscriptTail = (transcript, agentBubbles) => {
778
+ const tailStartIndex = findAgentTailStartIndex(transcript.bubbles, agentBubbles);
779
+ const seen = [...transcript.bubbles];
780
+ const appended = [];
781
+ const candidates = agentBubbles.slice(tailStartIndex);
782
+ for (const bubble of candidates) {
783
+ if (hasEquivalentBubble(seen, bubble)) continue;
784
+ seen.push(bubble);
785
+ appended.push(bubble);
786
+ }
787
+ if (appended.length === 0) return transcript;
788
+ return {
789
+ ...transcript,
790
+ bubbles: [...transcript.bubbles, ...appended],
791
+ renderableBubbleCount: transcript.renderableBubbleCount + appended.length
792
+ };
793
+ };
794
+ var inferCursorUserDirFromGlobalDbPath = (globalDbPath) => {
795
+ const globalStorageDir = path.dirname(globalDbPath);
796
+ return path.basename(globalStorageDir) === "globalStorage" ? path.dirname(globalStorageDir) : resolveCursorUserDir();
797
+ };
616
798
  var readCursorThreadTranscript = (globalDbPath, composerId) => {
617
799
  const head = readCursorThreadHead(globalDbPath, composerId);
618
800
  if (!head) return null;
@@ -635,9 +817,14 @@ var readCursorThreadTranscript = (globalDbPath, composerId) => {
635
817
  db.close();
636
818
  }
637
819
  };
820
+ var readCursorThreadTranscriptWithAgentFiles = async (globalDbPath, composerId, userDir = inferCursorUserDirFromGlobalDbPath(globalDbPath)) => {
821
+ const transcript = readCursorThreadTranscript(globalDbPath, composerId);
822
+ if (!transcript) return null;
823
+ return mergeAgentTranscriptTail(transcript, await readCursorAgentTranscriptBubbles(composerId, userDir));
824
+ };
638
825
  var readAllBubbleIds = (db, composerId) => {
639
826
  const prefix = `bubbleId:${composerId}:`;
640
827
  return db.query("SELECT key FROM cursorDiskKV WHERE key LIKE ? ORDER BY key ASC").all(`${prefix}%`).map((row) => row.key.slice(prefix.length));
641
828
  };
642
829
  //#endregion
643
- export { findCursorTranscriptDirs, invalidateCursorDiscoveryCache, listCursorThreadsForGroup, listCursorWorkspaceGroups, loadGlobalComposerHeaders, openCursorReadonlyDb, readCursorThreadTranscript };
830
+ export { findCursorTranscriptDirs, invalidateCursorDiscoveryCache, listCursorThreadsForGroup, listCursorWorkspaceGroups, loadGlobalComposerHeaders, openCursorReadonlyDb, readCursorThreadTranscriptWithAgentFiles };
@@ -1,6 +1,6 @@
1
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-DVnVQhGx.js";
3
+ import { t as createSsrRpc } from "./createSsrRpc-C754NPki.js";
4
4
  import { z } from "zod";
5
5
  import { queryOptions } from "@tanstack/react-query";
6
6
  //#region src/lib/cursor-server.ts
@@ -15,24 +15,26 @@ var exportSchema = z.object({
15
15
  includeCommentary: z.boolean().default(true),
16
16
  includeMetadata: z.boolean().default(true),
17
17
  includeTools: z.boolean().default(true),
18
- outputFormat: z.enum(["md", "txt"]).default("md")
18
+ outputFormat: z.enum(["md", "txt"]).default("md"),
19
+ zipArchive: z.boolean().default(false)
19
20
  });
20
21
  var exportThreadsSchema = z.object({
21
22
  composerIds: z.array(z.string().min(1)).min(1),
22
23
  includeCommentary: z.boolean().default(true),
23
24
  includeMetadata: z.boolean().default(true),
24
25
  includeTools: z.boolean().default(true),
25
- outputFormat: z.enum(["md", "txt"]).default("md")
26
+ outputFormat: z.enum(["md", "txt"]).default("md"),
27
+ zipArchive: z.boolean().default(true)
26
28
  });
27
29
  var deleteThreadsSchema = z.object({ composerIds: z.array(z.string().min(1)).min(1) });
28
30
  var listCursorWorkspacesFn = createServerFn({ method: "GET" }).handler(createSsrRpc("8fcf452a4587a4d4dc0c2f6439255e98123f23d863ca0e861403ae2a687272f2"));
29
- var listCursorThreadsFn = createServerFn({ method: "GET" }).inputValidator(workspaceSchema).handler(createSsrRpc("23fb197bac88fb9e4950ef7608cd311d67c0867e424136c8373071dc54746806"));
30
- var getCursorThreadDetailFn = createServerFn({ method: "GET" }).inputValidator(threadSchema).handler(createSsrRpc("6e893e740c05aad65a8eb32901b4c39277ebf718f0ba14b04d8df989bed2f32b"));
31
- var exportCursorThreadFn = createServerFn({ method: "POST" }).inputValidator(exportSchema).handler(createSsrRpc("03050b86e5481024283bee890347a9da7b2493493044dcde6df989b3334d6b73"));
32
- var exportCursorThreadsFn = createServerFn({ method: "POST" }).inputValidator(exportThreadsSchema).handler(createSsrRpc("e9609d5ab12ea0bc4dbd3289fad95417dd01a0a719c8ee588c0b8c8a9dc80c99"));
33
- var recoverCursorWorkspaceFn = createServerFn({ method: "POST" }).inputValidator(recoverSchema).handler(createSsrRpc("a9bd5d510f2d1173d2ef610dda4d59a795af17e7c2a4affaba7e1f99822b2c40"));
34
- var deleteCursorThreadsFn = createServerFn({ method: "POST" }).inputValidator(deleteThreadsSchema).handler(createSsrRpc("17afb84da4a3d5022132756ead0adaf0323660f50fc58d7f14830b01fdd59a13"));
35
- var deleteCursorWorkspaceFn = createServerFn({ method: "POST" }).inputValidator(workspaceSchema).handler(createSsrRpc("fc72eb7835fc18130f6d7c20e15e560320521cd01c93e08667b340bfe6b90930"));
31
+ var listCursorThreadsFn = createServerFn({ method: "GET" }).validator(workspaceSchema).handler(createSsrRpc("23fb197bac88fb9e4950ef7608cd311d67c0867e424136c8373071dc54746806"));
32
+ var getCursorThreadDetailFn = createServerFn({ method: "GET" }).validator(threadSchema).handler(createSsrRpc("6e893e740c05aad65a8eb32901b4c39277ebf718f0ba14b04d8df989bed2f32b"));
33
+ var exportCursorThreadFn = createServerFn({ method: "POST" }).validator(exportSchema).handler(createSsrRpc("03050b86e5481024283bee890347a9da7b2493493044dcde6df989b3334d6b73"));
34
+ var exportCursorThreadsFn = createServerFn({ method: "POST" }).validator(exportThreadsSchema).handler(createSsrRpc("e9609d5ab12ea0bc4dbd3289fad95417dd01a0a719c8ee588c0b8c8a9dc80c99"));
35
+ var recoverCursorWorkspaceFn = createServerFn({ method: "POST" }).validator(recoverSchema).handler(createSsrRpc("a9bd5d510f2d1173d2ef610dda4d59a795af17e7c2a4affaba7e1f99822b2c40"));
36
+ var deleteCursorThreadsFn = createServerFn({ method: "POST" }).validator(deleteThreadsSchema).handler(createSsrRpc("17afb84da4a3d5022132756ead0adaf0323660f50fc58d7f14830b01fdd59a13"));
37
+ var deleteCursorWorkspaceFn = createServerFn({ method: "POST" }).validator(workspaceSchema).handler(createSsrRpc("fc72eb7835fc18130f6d7c20e15e560320521cd01c93e08667b340bfe6b90930"));
36
38
  //#endregion
37
39
  //#region src/lib/cursor-queries.ts
38
40
  var retrySqliteQuery = (failureCount, error) => {
@@ -1,5 +1,5 @@
1
1
  import { COMPOSER_DATA_KEY, COMPOSER_HEADERS_KEY, getCursorGlobalDbPath, resolveCursorUserDir } from "./cursor-exporter-types-CI3goo-c.js";
2
- import { findCursorTranscriptDirs, invalidateCursorDiscoveryCache, listCursorWorkspaceGroups, loadGlobalComposerHeaders, openCursorReadonlyDb } from "./cursor-db-B7agkAvM.js";
2
+ import { findCursorTranscriptDirs, invalidateCursorDiscoveryCache, listCursorWorkspaceGroups, loadGlobalComposerHeaders, openCursorReadonlyDb } from "./cursor-db-cYZEU3WQ.js";
3
3
  import { Database } from "bun:sqlite";
4
4
  import { rm } from "node:fs/promises";
5
5
  //#region ../../src/lib/cursor-recovery.ts
@@ -1,6 +1,11 @@
1
1
  import { t as createServerFn } from "../server.js";
2
- import { t as createServerRpc } from "./createServerRpc-Cg-Zr1rq.js";
2
+ import { t as createServerRpc } from "./createServerRpc-CF_DEwnm.js";
3
+ import { a as sanitizeExportFileName, i as resolveUniqueExportFileBaseName, n as ensureUiExportDir, o as zipExportDirectory, r as getExportMimeType, t as buildUiExportDownloadUrl } from "./ui-export-files-BHLX9bhN.js";
3
4
  import { z } from "zod";
5
+ import { mkdtemp, rm } from "node:fs/promises";
6
+ import os from "node:os";
7
+ import path from "node:path";
8
+ import { randomUUID } from "node:crypto";
4
9
  //#region src/lib/cursor-server.ts?tss-serverfn-split
5
10
  var workspaceSchema = z.object({ workspaceKey: z.string().min(1) });
6
11
  var threadSchema = z.object({ composerId: z.string().min(1) });
@@ -13,28 +18,58 @@ var exportSchema = z.object({
13
18
  includeCommentary: z.boolean().default(true),
14
19
  includeMetadata: z.boolean().default(true),
15
20
  includeTools: z.boolean().default(true),
16
- outputFormat: z.enum(["md", "txt"]).default("md")
21
+ outputFormat: z.enum(["md", "txt"]).default("md"),
22
+ zipArchive: z.boolean().default(false)
17
23
  });
18
24
  var exportThreadsSchema = z.object({
19
25
  composerIds: z.array(z.string().min(1)).min(1),
20
26
  includeCommentary: z.boolean().default(true),
21
27
  includeMetadata: z.boolean().default(true),
22
28
  includeTools: z.boolean().default(true),
23
- outputFormat: z.enum(["md", "txt"]).default("md")
29
+ outputFormat: z.enum(["md", "txt"]).default("md"),
30
+ zipArchive: z.boolean().default(true)
24
31
  });
25
32
  var deleteThreadsSchema = z.object({ composerIds: z.array(z.string().min(1)).min(1) });
26
33
  var ensureCursorClosedForWrite = async () => {
27
- const { isCursorRunning } = await import("./cursor-recovery-9bJLs7vG.js");
34
+ const { isCursorRunning } = await import("./cursor-recovery-nq-kR62j.js");
28
35
  if (await isCursorRunning()) throw new Error("Quit Cursor before deleting. It rewrites chat history on exit, which can resurrect deleted threads.");
29
36
  };
30
37
  var findGroupByKey = async (workspaceKey) => {
31
- const { listCursorWorkspaceGroups } = await import("./cursor-db-B7agkAvM.js");
38
+ const { listCursorWorkspaceGroups } = await import("./cursor-db-cYZEU3WQ.js");
32
39
  const group = (await listCursorWorkspaceGroups()).find((candidate) => candidate.key === workspaceKey);
33
40
  if (!group) throw new Error(`Cursor workspace not found: ${workspaceKey}`);
34
41
  return group;
35
42
  };
43
+ var toSafeExportName = (value) => {
44
+ return sanitizeExportFileName(value) || "cursor-thread";
45
+ };
46
+ var renderCursorZipDownload = async (rendered, outputFormat) => {
47
+ const exportDir = await ensureUiExportDir();
48
+ const exportBaseName = rendered.length === 1 ? `${toSafeExportName(rendered[0].composerId)}` : `cursor-threads-${rendered.length}`;
49
+ const workspaceDir = await mkdtemp(path.join(os.tmpdir(), `${exportBaseName}-`));
50
+ const zipPath = path.join(exportDir, `${exportBaseName}-${randomUUID()}.zip`);
51
+ const usedBaseNames = /* @__PURE__ */ new Map();
52
+ try {
53
+ for (const entry of rendered) {
54
+ const fileBaseName = resolveUniqueExportFileBaseName(toSafeExportName(entry.composerId), usedBaseNames);
55
+ await Bun.write(path.join(workspaceDir, `${fileBaseName}.${outputFormat}`), entry.content);
56
+ }
57
+ await zipExportDirectory(workspaceDir, zipPath);
58
+ } finally {
59
+ await rm(workspaceDir, {
60
+ force: true,
61
+ recursive: true
62
+ });
63
+ }
64
+ return {
65
+ downloadUrl: buildUiExportDownloadUrl(zipPath),
66
+ fileName: `${exportBaseName}.zip`,
67
+ mimeType: "application/zip",
68
+ mode: "download_url"
69
+ };
70
+ };
36
71
  var findCursorThreadByComposerId = async (composerId) => {
37
- const { listCursorThreadsForGroup, listCursorWorkspaceGroups } = await import("./cursor-db-B7agkAvM.js");
72
+ const { listCursorThreadsForGroup, listCursorWorkspaceGroups } = await import("./cursor-db-cYZEU3WQ.js");
38
73
  for (const group of await listCursorWorkspaceGroups()) {
39
74
  const thread = (await listCursorThreadsForGroup(group, void 0, { includeTranscriptDirs: false })).find((candidate) => candidate.composerId === composerId);
40
75
  if (thread) return thread;
@@ -42,11 +77,12 @@ var findCursorThreadByComposerId = async (composerId) => {
42
77
  return null;
43
78
  };
44
79
  var renderCursorDownload = async (input) => {
45
- const { readCursorThreadTranscript } = await import("./cursor-db-B7agkAvM.js");
80
+ const { readCursorThreadTranscriptWithAgentFiles } = await import("./cursor-db-cYZEU3WQ.js");
46
81
  const { getCursorGlobalDbPath } = await import("./cursor-exporter-types-CI3goo-c.js");
47
82
  const { renderCursorTranscript } = await import("./cursor-transcript-2iL3KFSK.js");
48
- const rendered = input.composerIds.map((composerId) => {
49
- const transcript = readCursorThreadTranscript(getCursorGlobalDbPath(), composerId);
83
+ const globalDbPath = getCursorGlobalDbPath();
84
+ const rendered = await Promise.all(input.composerIds.map(async (composerId) => {
85
+ const transcript = await readCursorThreadTranscriptWithAgentFiles(globalDbPath, composerId);
50
86
  if (!transcript) throw new Error(`No transcript found for thread: ${composerId}`);
51
87
  const content = renderCursorTranscript(transcript, {
52
88
  includeCommentary: input.includeCommentary,
@@ -59,16 +95,15 @@ var renderCursorDownload = async (input) => {
59
95
  composerId,
60
96
  content
61
97
  };
62
- });
98
+ }));
99
+ if (input.zipArchive || rendered.length > 1) return renderCursorZipDownload(rendered, input.outputFormat);
63
100
  if (rendered.length === 1) return {
64
101
  content: rendered[0].content,
65
- filename: `${rendered[0].composerId}.${input.outputFormat}`
66
- };
67
- const separator = input.outputFormat === "md" ? "\n\n---\n\n" : "\n\n================================================================\n\n";
68
- return {
69
- content: rendered.map((entry) => entry.content.trimEnd()).join(separator).concat("\n"),
70
- filename: `cursor-threads-${rendered.length}.${input.outputFormat}`
102
+ fileName: `${toSafeExportName(rendered[0].composerId)}.${input.outputFormat}`,
103
+ mimeType: getExportMimeType(input.outputFormat),
104
+ mode: "download"
71
105
  };
106
+ throw new Error("No Cursor threads selected for export");
72
107
  };
73
108
  var listCursorWorkspacesFn_createServerFn_handler = createServerRpc({
74
109
  id: "8fcf452a4587a4d4dc0c2f6439255e98123f23d863ca0e861403ae2a687272f2",
@@ -76,7 +111,7 @@ var listCursorWorkspacesFn_createServerFn_handler = createServerRpc({
76
111
  filename: "src/lib/cursor-server.ts"
77
112
  }, (opts) => listCursorWorkspacesFn.__executeServer(opts));
78
113
  var listCursorWorkspacesFn = createServerFn({ method: "GET" }).handler(listCursorWorkspacesFn_createServerFn_handler, async () => {
79
- const { listCursorWorkspaceGroups } = await import("./cursor-db-B7agkAvM.js");
114
+ const { listCursorWorkspaceGroups } = await import("./cursor-db-cYZEU3WQ.js");
80
115
  return listCursorWorkspaceGroups();
81
116
  });
82
117
  var listCursorThreadsFn_createServerFn_handler = createServerRpc({
@@ -84,8 +119,8 @@ var listCursorThreadsFn_createServerFn_handler = createServerRpc({
84
119
  name: "listCursorThreadsFn",
85
120
  filename: "src/lib/cursor-server.ts"
86
121
  }, (opts) => listCursorThreadsFn.__executeServer(opts));
87
- var listCursorThreadsFn = createServerFn({ method: "GET" }).inputValidator(workspaceSchema).handler(listCursorThreadsFn_createServerFn_handler, async ({ data }) => {
88
- const { listCursorThreadsForGroup } = await import("./cursor-db-B7agkAvM.js");
122
+ var listCursorThreadsFn = createServerFn({ method: "GET" }).validator(workspaceSchema).handler(listCursorThreadsFn_createServerFn_handler, async ({ data }) => {
123
+ const { listCursorThreadsForGroup } = await import("./cursor-db-cYZEU3WQ.js");
89
124
  return listCursorThreadsForGroup(await findGroupByKey(data.workspaceKey), void 0, { includeTranscriptDirs: false });
90
125
  });
91
126
  var getCursorThreadDetailFn_createServerFn_handler = createServerRpc({
@@ -93,22 +128,14 @@ var getCursorThreadDetailFn_createServerFn_handler = createServerRpc({
93
128
  name: "getCursorThreadDetailFn",
94
129
  filename: "src/lib/cursor-server.ts"
95
130
  }, (opts) => getCursorThreadDetailFn.__executeServer(opts));
96
- var getCursorThreadDetailFn = createServerFn({ method: "GET" }).inputValidator(threadSchema).handler(getCursorThreadDetailFn_createServerFn_handler, async ({ data }) => {
97
- const { readCursorThreadTranscript } = await import("./cursor-db-B7agkAvM.js");
131
+ var getCursorThreadDetailFn = createServerFn({ method: "GET" }).validator(threadSchema).handler(getCursorThreadDetailFn_createServerFn_handler, async ({ data }) => {
132
+ const { readCursorThreadTranscriptWithAgentFiles } = await import("./cursor-db-cYZEU3WQ.js");
98
133
  const { getCursorGlobalDbPath } = await import("./cursor-exporter-types-CI3goo-c.js");
99
- const { renderCursorTranscript } = await import("./cursor-transcript-2iL3KFSK.js");
100
134
  const thread = await findCursorThreadByComposerId(data.composerId);
101
135
  if (!thread) throw new Error(`Cursor thread not found: ${data.composerId}`);
102
- const transcript = readCursorThreadTranscript(getCursorGlobalDbPath(), data.composerId);
103
136
  return {
104
- renderedTranscript: transcript ? renderCursorTranscript(transcript, {
105
- includeCommentary: true,
106
- includeMetadata: false,
107
- includeTools: true,
108
- outputFormat: "md"
109
- }) : null,
110
137
  thread,
111
- transcript
138
+ transcript: await readCursorThreadTranscriptWithAgentFiles(getCursorGlobalDbPath(), data.composerId)
112
139
  };
113
140
  });
114
141
  var exportCursorThreadFn_createServerFn_handler = createServerRpc({
@@ -116,13 +143,14 @@ var exportCursorThreadFn_createServerFn_handler = createServerRpc({
116
143
  name: "exportCursorThreadFn",
117
144
  filename: "src/lib/cursor-server.ts"
118
145
  }, (opts) => exportCursorThreadFn.__executeServer(opts));
119
- var exportCursorThreadFn = createServerFn({ method: "POST" }).inputValidator(exportSchema).handler(exportCursorThreadFn_createServerFn_handler, async ({ data }) => {
146
+ var exportCursorThreadFn = createServerFn({ method: "POST" }).validator(exportSchema).handler(exportCursorThreadFn_createServerFn_handler, async ({ data }) => {
120
147
  return await renderCursorDownload({
121
148
  composerIds: [data.composerId],
122
149
  includeCommentary: data.includeCommentary,
123
150
  includeMetadata: data.includeMetadata,
124
151
  includeTools: data.includeTools,
125
- outputFormat: data.outputFormat
152
+ outputFormat: data.outputFormat,
153
+ zipArchive: data.zipArchive
126
154
  });
127
155
  });
128
156
  var exportCursorThreadsFn_createServerFn_handler = createServerRpc({
@@ -130,13 +158,14 @@ var exportCursorThreadsFn_createServerFn_handler = createServerRpc({
130
158
  name: "exportCursorThreadsFn",
131
159
  filename: "src/lib/cursor-server.ts"
132
160
  }, (opts) => exportCursorThreadsFn.__executeServer(opts));
133
- var exportCursorThreadsFn = createServerFn({ method: "POST" }).inputValidator(exportThreadsSchema).handler(exportCursorThreadsFn_createServerFn_handler, async ({ data }) => {
161
+ var exportCursorThreadsFn = createServerFn({ method: "POST" }).validator(exportThreadsSchema).handler(exportCursorThreadsFn_createServerFn_handler, async ({ data }) => {
134
162
  return await renderCursorDownload({
135
163
  composerIds: data.composerIds,
136
164
  includeCommentary: data.includeCommentary,
137
165
  includeMetadata: data.includeMetadata,
138
166
  includeTools: data.includeTools,
139
- outputFormat: data.outputFormat
167
+ outputFormat: data.outputFormat,
168
+ zipArchive: data.zipArchive
140
169
  });
141
170
  });
142
171
  var recoverCursorWorkspaceFn_createServerFn_handler = createServerRpc({
@@ -144,8 +173,8 @@ var recoverCursorWorkspaceFn_createServerFn_handler = createServerRpc({
144
173
  name: "recoverCursorWorkspaceFn",
145
174
  filename: "src/lib/cursor-server.ts"
146
175
  }, (opts) => recoverCursorWorkspaceFn.__executeServer(opts));
147
- var recoverCursorWorkspaceFn = createServerFn({ method: "POST" }).inputValidator(recoverSchema).handler(recoverCursorWorkspaceFn_createServerFn_handler, async ({ data }) => {
148
- const { isCursorRunning, recoverCursorWorkspaceGroup } = await import("./cursor-recovery-9bJLs7vG.js");
176
+ var recoverCursorWorkspaceFn = createServerFn({ method: "POST" }).validator(recoverSchema).handler(recoverCursorWorkspaceFn_createServerFn_handler, async ({ data }) => {
177
+ const { isCursorRunning, recoverCursorWorkspaceGroup } = await import("./cursor-recovery-nq-kR62j.js");
149
178
  const group = await findGroupByKey(data.workspaceKey);
150
179
  if (data.apply && await isCursorRunning()) throw new Error("Quit Cursor before recovering. It overwrites chat history on exit, undoing the recovery.");
151
180
  return recoverCursorWorkspaceGroup(group, data.apply);
@@ -155,8 +184,8 @@ var deleteCursorThreadsFn_createServerFn_handler = createServerRpc({
155
184
  name: "deleteCursorThreadsFn",
156
185
  filename: "src/lib/cursor-server.ts"
157
186
  }, (opts) => deleteCursorThreadsFn.__executeServer(opts));
158
- var deleteCursorThreadsFn = createServerFn({ method: "POST" }).inputValidator(deleteThreadsSchema).handler(deleteCursorThreadsFn_createServerFn_handler, async ({ data }) => {
159
- const { collectCursorThreadsForDeletion, pruneCursorThreads } = await import("./cursor-recovery-9bJLs7vG.js");
187
+ var deleteCursorThreadsFn = createServerFn({ method: "POST" }).validator(deleteThreadsSchema).handler(deleteCursorThreadsFn_createServerFn_handler, async ({ data }) => {
188
+ const { collectCursorThreadsForDeletion, pruneCursorThreads } = await import("./cursor-recovery-nq-kR62j.js");
160
189
  await ensureCursorClosedForWrite();
161
190
  return pruneCursorThreads(await collectCursorThreadsForDeletion(data.composerIds), true);
162
191
  });
@@ -165,9 +194,9 @@ var deleteCursorWorkspaceFn_createServerFn_handler = createServerRpc({
165
194
  name: "deleteCursorWorkspaceFn",
166
195
  filename: "src/lib/cursor-server.ts"
167
196
  }, (opts) => deleteCursorWorkspaceFn.__executeServer(opts));
168
- var deleteCursorWorkspaceFn = createServerFn({ method: "POST" }).inputValidator(workspaceSchema).handler(deleteCursorWorkspaceFn_createServerFn_handler, async ({ data }) => {
169
- const { listCursorThreadsForGroup } = await import("./cursor-db-B7agkAvM.js");
170
- const { collectCursorThreadsForDeletion, pruneCursorThreads } = await import("./cursor-recovery-9bJLs7vG.js");
197
+ var deleteCursorWorkspaceFn = createServerFn({ method: "POST" }).validator(workspaceSchema).handler(deleteCursorWorkspaceFn_createServerFn_handler, async ({ data }) => {
198
+ const { listCursorThreadsForGroup } = await import("./cursor-db-cYZEU3WQ.js");
199
+ const { collectCursorThreadsForDeletion, pruneCursorThreads } = await import("./cursor-recovery-nq-kR62j.js");
171
200
  await ensureCursorClosedForWrite();
172
201
  const composerIds = (await listCursorThreadsForGroup(await findGroupByKey(data.workspaceKey), void 0, { includeTranscriptDirs: false })).map((thread) => thread.composerId);
173
202
  if (composerIds.length === 0) return {
@@ -1,10 +1,10 @@
1
- import { t as cursorThreadDetailQueryOptions } from "./cursor-queries-f7DjBKSD.js";
1
+ import { t as cursorThreadDetailQueryOptions } from "./cursor-queries-NCIM0Nat.js";
2
2
  import { t as LoadingPanel } from "./loading-panel-BGFnWseS.js";
3
3
  import { createFileRoute, lazyRouteComponent } from "@tanstack/react-router";
4
4
  import { jsx } from "react/jsx-runtime";
5
5
  //#region src/routes/cursor-threads.$composerId.tsx
6
6
  var $$splitErrorComponentImporter = () => import("./cursor-threads._composerId-BB0Y_Mao.js");
7
- var $$splitComponentImporter = () => import("./cursor-threads._composerId-BK3iW-3e.js");
7
+ var $$splitComponentImporter = () => import("./cursor-threads._composerId-BkMMTQ3v.js");
8
8
  var Route = createFileRoute("/cursor-threads/$composerId")({
9
9
  component: lazyRouteComponent($$splitComponentImporter, "component"),
10
10
  errorComponent: lazyRouteComponent($$splitErrorComponentImporter, "errorComponent"),