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
@@ -0,0 +1,218 @@
1
+ import { t as Button } from "./button-CmTDnzOn.js";
2
+ import { i as deleteCursorThreadsFn, o as exportCursorThreadFn, t as cursorThreadDetailQueryOptions } from "./cursor-queries-BMhuJeUO.js";
3
+ import { t as Route } from "./cursor-threads._composerId-DXffY_CK.js";
4
+ import { t as MetricCard } from "./metric-card-ByEeLu0r.js";
5
+ import { t as PageHeader } from "./page-header-VNSaM3xd.js";
6
+ import { n as formatBytes, o as formatNumber, r as formatDateTime } from "./formatters-FJaGZgJk.js";
7
+ import { n as Breadcrumbs, t as MetadataSection } from "./metadata-section-D6Lbc7D6.js";
8
+ import { t as TextDocumentPanel } from "./text-document-panel-D8JbQWAn.js";
9
+ import { t as downloadTextFile } from "./download-DMmiy1xf.js";
10
+ import { t as DeleteConfirmDialog } from "./delete-confirm-dialog-PCD7S0_M.js";
11
+ import { t as ExportDialog } from "./export-dialog-DaPlOGFT.js";
12
+ import { t as JsonPanel } from "./json-panel-RYsxWFae.js";
13
+ import { useState } from "react";
14
+ import { Link, useNavigate } from "@tanstack/react-router";
15
+ import { jsx, jsxs } from "react/jsx-runtime";
16
+ import { useMutation, useQueryClient, useSuspenseQuery } from "@tanstack/react-query";
17
+ import { Download, Trash2 } from "lucide-react";
18
+ //#region src/routes/cursor-threads.$composerId.tsx?tsr-split=component
19
+ var buildCursorThreadMetadata = (detail) => {
20
+ return [
21
+ {
22
+ label: "Composer ID",
23
+ value: /* @__PURE__ */ jsx("span", {
24
+ "data-mono": "true",
25
+ children: detail.thread.composerId
26
+ })
27
+ },
28
+ {
29
+ label: "Workspace",
30
+ value: /* @__PURE__ */ jsx(Link, {
31
+ className: "text-[var(--accent)]",
32
+ params: { workspaceKey: detail.thread.workspaceKey },
33
+ to: "/cursor/$workspaceKey",
34
+ children: detail.thread.workspaceLabel
35
+ })
36
+ },
37
+ {
38
+ label: "Workspace key",
39
+ value: /* @__PURE__ */ jsx("span", {
40
+ "data-mono": "true",
41
+ children: detail.thread.workspaceKey
42
+ })
43
+ },
44
+ {
45
+ label: "Mode",
46
+ value: detail.thread.mode ?? "unknown"
47
+ },
48
+ {
49
+ label: "Created",
50
+ value: /* @__PURE__ */ jsx("span", {
51
+ suppressHydrationWarning: true,
52
+ children: formatDateTime(detail.thread.createdAtMs)
53
+ })
54
+ },
55
+ {
56
+ label: "Updated",
57
+ value: /* @__PURE__ */ jsx("span", {
58
+ suppressHydrationWarning: true,
59
+ children: formatDateTime(detail.thread.lastUpdatedAtMs)
60
+ })
61
+ },
62
+ {
63
+ label: "Transcript dirs",
64
+ value: detail.thread.transcriptDirs.length > 0 ? /* @__PURE__ */ jsx("div", {
65
+ className: "space-y-1",
66
+ children: detail.thread.transcriptDirs.map((directory) => /* @__PURE__ */ jsx("div", {
67
+ "data-mono": "true",
68
+ children: directory
69
+ }, directory))
70
+ }) : "n/a"
71
+ }
72
+ ];
73
+ };
74
+ var getCursorExportMimeType = (outputFormat) => {
75
+ return outputFormat === "md" ? "text/markdown; charset=utf-8" : "text/plain; charset=utf-8";
76
+ };
77
+ var CursorThreadDetailPage = () => {
78
+ const navigate = useNavigate();
79
+ const queryClient = useQueryClient();
80
+ const detail = useSuspenseQuery(cursorThreadDetailQueryOptions(Route.useParams().composerId)).data;
81
+ const [pendingDelete, setPendingDelete] = useState(false);
82
+ const [pendingExport, setPendingExport] = useState(false);
83
+ const deleteThreadMutation = useMutation({
84
+ mutationFn: () => deleteCursorThreadsFn({ data: { composerIds: [detail.thread.composerId] } }),
85
+ onSuccess: async () => {
86
+ await navigate({
87
+ params: { workspaceKey: detail.thread.workspaceKey },
88
+ to: "/cursor/$workspaceKey"
89
+ });
90
+ await Promise.all([
91
+ queryClient.invalidateQueries({ queryKey: ["cursor-thread", detail.thread.composerId] }),
92
+ queryClient.invalidateQueries({ queryKey: ["cursor-threads", detail.thread.workspaceKey] }),
93
+ queryClient.invalidateQueries({ queryKey: ["cursor-workspaces"] })
94
+ ]);
95
+ }
96
+ });
97
+ const exportThreadMutation = useMutation({
98
+ mutationFn: async (options) => {
99
+ const download = await exportCursorThreadFn({ data: {
100
+ ...options,
101
+ composerId: detail.thread.composerId
102
+ } });
103
+ downloadTextFile(download.filename, download.content, getCursorExportMimeType(options.outputFormat));
104
+ },
105
+ onSuccess: () => {
106
+ setPendingExport(false);
107
+ }
108
+ });
109
+ return /* @__PURE__ */ jsxs("div", {
110
+ className: "space-y-6",
111
+ children: [
112
+ /* @__PURE__ */ jsx(PageHeader, {
113
+ actions: /* @__PURE__ */ jsxs("div", {
114
+ className: "flex flex-wrap gap-2",
115
+ children: [/* @__PURE__ */ jsxs(Button, {
116
+ className: "rounded-full",
117
+ type: "button",
118
+ variant: "outline",
119
+ onClick: () => setPendingExport(true),
120
+ children: [/* @__PURE__ */ jsx(Download, { className: "mr-2 size-4" }), "Export"]
121
+ }), /* @__PURE__ */ jsxs(Button, {
122
+ className: "rounded-full border-[var(--destructive)]/20 text-[var(--destructive)]",
123
+ type: "button",
124
+ variant: "outline",
125
+ onClick: () => setPendingDelete(true),
126
+ children: [/* @__PURE__ */ jsx(Trash2, { className: "mr-2 size-4" }), "Delete"]
127
+ })]
128
+ }),
129
+ breadcrumb: /* @__PURE__ */ jsx(Breadcrumbs, { items: [
130
+ {
131
+ label: "Cursor",
132
+ to: "/cursor"
133
+ },
134
+ {
135
+ label: detail.thread.workspaceLabel,
136
+ params: { workspaceKey: detail.thread.workspaceKey },
137
+ to: "/cursor/$workspaceKey"
138
+ },
139
+ { label: detail.thread.name }
140
+ ] }),
141
+ eyebrow: "Cursor thread",
142
+ subtitle: "Thread detail for the selected Cursor workspace conversation.",
143
+ title: detail.thread.name
144
+ }),
145
+ /* @__PURE__ */ jsxs("div", {
146
+ className: "grid gap-3 md:grid-cols-2 xl:grid-cols-4",
147
+ children: [
148
+ /* @__PURE__ */ jsx(MetricCard, {
149
+ label: "Messages",
150
+ value: formatNumber(detail.thread.bubbleCount)
151
+ }),
152
+ /* @__PURE__ */ jsx(MetricCard, {
153
+ label: "Size",
154
+ value: formatBytes(detail.thread.bubbleBytes)
155
+ }),
156
+ /* @__PURE__ */ jsx(MetricCard, {
157
+ label: "Mode",
158
+ value: detail.thread.mode ?? "unknown"
159
+ }),
160
+ /* @__PURE__ */ jsx(MetricCard, {
161
+ helper: `${formatNumber(detail.transcript?.renderableBubbleCount ?? 0)} renderable`,
162
+ label: "Omitted",
163
+ value: formatNumber(detail.transcript?.omittedBubbleCount ?? 0)
164
+ })
165
+ ]
166
+ }),
167
+ /* @__PURE__ */ jsxs("div", {
168
+ className: "grid gap-4 xl:grid-cols-[0.95fr_1.05fr]",
169
+ children: [/* @__PURE__ */ jsx(MetadataSection, {
170
+ items: buildCursorThreadMetadata(detail),
171
+ title: "Thread metadata"
172
+ }), detail.renderedTranscript ? /* @__PURE__ */ jsx(TextDocumentPanel, {
173
+ content: detail.renderedTranscript,
174
+ description: "Rendered with commentary and tool calls enabled.",
175
+ title: "Transcript"
176
+ }) : /* @__PURE__ */ jsxs("section", {
177
+ className: "rounded-[1.6rem] border border-[var(--border)] bg-[var(--panel)] p-5 shadow-[var(--panel-shadow)]",
178
+ children: [/* @__PURE__ */ jsx("h3", {
179
+ className: "font-semibold text-[var(--muted-foreground)] text-sm uppercase tracking-[0.18em]",
180
+ children: "Transcript"
181
+ }), /* @__PURE__ */ jsx("p", {
182
+ className: "mt-4 text-[var(--muted-foreground)] text-sm",
183
+ children: "No renderable Cursor transcript content was found for this thread."
184
+ })]
185
+ })]
186
+ }),
187
+ detail.transcript ? /* @__PURE__ */ jsx(JsonPanel, {
188
+ title: "Raw transcript",
189
+ value: detail.transcript
190
+ }) : null,
191
+ deleteThreadMutation.isError ? /* @__PURE__ */ jsx("p", {
192
+ className: "text-[var(--destructive)] text-sm",
193
+ children: deleteThreadMutation.error instanceof Error ? deleteThreadMutation.error.message : "Delete failed"
194
+ }) : null,
195
+ exportThreadMutation.isError ? /* @__PURE__ */ jsx("p", {
196
+ className: "text-[var(--destructive)] text-sm",
197
+ children: exportThreadMutation.error instanceof Error ? exportThreadMutation.error.message : "Export failed"
198
+ }) : null,
199
+ /* @__PURE__ */ jsx(DeleteConfirmDialog, {
200
+ confirmLabel: deleteThreadMutation.isPending ? "Deleting..." : "Delete thread",
201
+ description: `Permanently delete "${detail.thread.name}" from Cursor's database and remove any on-disk transcript directories. Quit Cursor first. This cannot be undone.`,
202
+ open: pendingDelete,
203
+ title: "Delete Cursor thread?",
204
+ onConfirm: () => deleteThreadMutation.mutate(),
205
+ onOpenChange: setPendingDelete
206
+ }),
207
+ /* @__PURE__ */ jsx(ExportDialog, {
208
+ open: pendingExport,
209
+ pending: exportThreadMutation.isPending,
210
+ title: `Export ${detail.thread.name}`,
211
+ onExport: (options) => exportThreadMutation.mutate(options),
212
+ onOpenChange: setPendingExport
213
+ })
214
+ ]
215
+ });
216
+ };
217
+ //#endregion
218
+ export { CursorThreadDetailPage as component };
@@ -0,0 +1,18 @@
1
+ import { t as cursorThreadDetailQueryOptions } from "./cursor-queries-BMhuJeUO.js";
2
+ import { t as LoadingPanel } from "./loading-panel-BGFnWseS.js";
3
+ import { createFileRoute, lazyRouteComponent } from "@tanstack/react-router";
4
+ import { jsx } from "react/jsx-runtime";
5
+ //#region src/routes/cursor-threads.$composerId.tsx
6
+ var $$splitErrorComponentImporter = () => import("./cursor-threads._composerId-BB0Y_Mao.js");
7
+ var $$splitComponentImporter = () => import("./cursor-threads._composerId-BsxFKzoJ.js");
8
+ var Route = createFileRoute("/cursor-threads/$composerId")({
9
+ component: lazyRouteComponent($$splitComponentImporter, "component"),
10
+ errorComponent: lazyRouteComponent($$splitErrorComponentImporter, "errorComponent"),
11
+ loader: ({ context, params }) => context.queryClient.ensureQueryData(cursorThreadDetailQueryOptions(params.composerId)),
12
+ pendingComponent: () => /* @__PURE__ */ jsx(LoadingPanel, {
13
+ description: "Loading the Cursor transcript, thread metadata, and workspace context.",
14
+ title: "Loading thread"
15
+ })
16
+ });
17
+ //#endregion
18
+ export { Route as t };
@@ -0,0 +1,125 @@
1
+ import { a as cleanInlineTitle, c as formatInlineLiteral, f as renderCodeBlock, h as renderSection, i as cleanExtractedText, m as renderMetadataBlock, p as renderDocumentTitle } from "./shared-CPRNYIql.js";
2
+ //#region ../../src/lib/cursor-transcript.ts
3
+ var TOOL_RESULT_PREVIEW_LIMIT = 4e3;
4
+ var MIN_DATE_MS = -864e13;
5
+ var MAX_DATE_MS = 864e13;
6
+ var formatUnixMillis = (value) => {
7
+ if (value === null || value === void 0 || !Number.isFinite(value) || value < MIN_DATE_MS || value > MAX_DATE_MS) return null;
8
+ return new Date(value).toISOString();
9
+ };
10
+ var prettyToolArguments = (argumentsText) => {
11
+ if (!argumentsText) return null;
12
+ try {
13
+ return JSON.stringify(JSON.parse(argumentsText), null, 2);
14
+ } catch {
15
+ return argumentsText;
16
+ }
17
+ };
18
+ var truncateResult = (resultText) => {
19
+ if (resultText.length <= TOOL_RESULT_PREVIEW_LIMIT) return resultText;
20
+ return `${resultText.slice(0, TOOL_RESULT_PREVIEW_LIMIT)}\n... (truncated)`;
21
+ };
22
+ var renderCursorToolCall = (toolCall, outputFormat) => {
23
+ const lines = [`Tool: ${formatInlineLiteral(toolCall.name, outputFormat)}`];
24
+ if (toolCall.status) lines.push(`Status: ${toolCall.status}`);
25
+ const args = prettyToolArguments(toolCall.argumentsText);
26
+ if (args) lines.push("", "Arguments:", "", renderCodeBlock(args, outputFormat));
27
+ const result = toolCall.resultText?.trim();
28
+ if (result) lines.push("", "Result:", "", renderCodeBlock(truncateResult(result), outputFormat));
29
+ return renderSection("Tool Call", lines.join("\n"), outputFormat);
30
+ };
31
+ var renderUserBubble = (bubble, outputFormat) => {
32
+ const text = cleanExtractedText(bubble.text).trim();
33
+ return text ? renderSection("User", text, outputFormat) : "";
34
+ };
35
+ var renderAssistantBubble = (bubble, options) => {
36
+ const blocks = [];
37
+ if (options.includeCommentary && bubble.thinking?.trim()) {
38
+ const reasoning = cleanExtractedText(bubble.thinking).trim();
39
+ if (reasoning) blocks.push(renderSection("Reasoning", reasoning, options.outputFormat));
40
+ }
41
+ const text = cleanExtractedText(bubble.text).trim();
42
+ if (text) blocks.push(renderSection("Assistant", text, options.outputFormat));
43
+ if (options.includeTools && bubble.toolCall) blocks.push(renderCursorToolCall(bubble.toolCall, options.outputFormat));
44
+ return blocks;
45
+ };
46
+ var renderCursorBubble = (bubble, options) => {
47
+ if (bubble.kind === "user") {
48
+ const block = renderUserBubble(bubble, options.outputFormat);
49
+ return block ? [block] : [];
50
+ }
51
+ if (bubble.kind === "assistant") return renderAssistantBubble(bubble, options);
52
+ return [];
53
+ };
54
+ var getThreadTitle = (head) => {
55
+ if (head.name) return cleanInlineTitle(head.name);
56
+ return head.composerId;
57
+ };
58
+ var buildMetadataEntries = (transcript) => {
59
+ const { head } = transcript;
60
+ return [
61
+ {
62
+ key: "exported_from",
63
+ value: "cursor_global_storage_bubbles"
64
+ },
65
+ {
66
+ key: "composer_id",
67
+ value: head.composerId
68
+ },
69
+ {
70
+ key: "title",
71
+ value: head.name
72
+ },
73
+ {
74
+ key: "mode",
75
+ value: head.mode
76
+ },
77
+ {
78
+ key: "created_at_unix_ms",
79
+ value: head.createdAtMs
80
+ },
81
+ {
82
+ key: "created_at_iso",
83
+ value: formatUnixMillis(head.createdAtMs)
84
+ },
85
+ {
86
+ key: "last_updated_at_unix_ms",
87
+ value: head.lastUpdatedAtMs
88
+ },
89
+ {
90
+ key: "last_updated_at_iso",
91
+ value: formatUnixMillis(head.lastUpdatedAtMs)
92
+ },
93
+ {
94
+ key: "rendered_message_count",
95
+ value: transcript.renderableBubbleCount
96
+ },
97
+ {
98
+ key: "omitted_message_count",
99
+ value: transcript.omittedBubbleCount > 0 ? transcript.omittedBubbleCount : null
100
+ }
101
+ ];
102
+ };
103
+ var buildTruncationNotice = (transcript, outputFormat) => {
104
+ if (transcript.omittedBubbleCount <= 0) return "";
105
+ const orderedCount = transcript.head.orderedBubbleIds.length;
106
+ return renderSection("Note", [
107
+ `Cursor indexed only the most recent ${orderedCount} of`,
108
+ `${orderedCount + transcript.omittedBubbleCount} stored messages for this thread,`,
109
+ "so earlier messages are not part of its conversation index and are not included here."
110
+ ].join(" "), outputFormat);
111
+ };
112
+ var renderCursorTranscript = (transcript, options) => {
113
+ const sections = [];
114
+ for (const bubble of transcript.bubbles) sections.push(...renderCursorBubble(bubble, options));
115
+ if (sections.length === 0) return null;
116
+ return `${[
117
+ renderDocumentTitle(getThreadTitle(transcript.head), options.outputFormat),
118
+ "",
119
+ options.includeMetadata ? renderMetadataBlock(buildMetadataEntries(transcript), options.outputFormat) : "",
120
+ buildTruncationNotice(transcript, options.outputFormat),
121
+ ...sections
122
+ ].filter(Boolean).join("\n").trimEnd()}\n`;
123
+ };
124
+ //#endregion
125
+ export { renderCursorTranscript };
@@ -0,0 +1,28 @@
1
+ import { n as cursorThreadsQueryOptions, r as cursorWorkspacesQueryOptions } from "./cursor-queries-BMhuJeUO.js";
2
+ import { t as LoadingPanel } from "./loading-panel-BGFnWseS.js";
3
+ import { createFileRoute, lazyRouteComponent } from "@tanstack/react-router";
4
+ import { jsx } from "react/jsx-runtime";
5
+ //#region src/routes/cursor.$workspaceKey.tsx?tsr-shared=1
6
+ var findWorkspaceOrThrow = (workspaces, workspaceKey) => {
7
+ const workspace = workspaces.find((candidate) => candidate.key === workspaceKey);
8
+ if (!workspace) throw new Error(`Cursor workspace not found: ${workspaceKey}`);
9
+ return workspace;
10
+ };
11
+ //#endregion
12
+ //#region src/routes/cursor.$workspaceKey.tsx
13
+ var $$splitErrorComponentImporter = () => import("./cursor._workspaceKey-nmg3YIOQ.js");
14
+ var $$splitComponentImporter = () => import("./cursor._workspaceKey-BQd0e-Pd.js");
15
+ var Route = createFileRoute("/cursor/$workspaceKey")({
16
+ component: lazyRouteComponent($$splitComponentImporter, "component"),
17
+ errorComponent: lazyRouteComponent($$splitErrorComponentImporter, "errorComponent"),
18
+ loader: async ({ context, params }) => {
19
+ findWorkspaceOrThrow(await context.queryClient.ensureQueryData(cursorWorkspacesQueryOptions()), params.workspaceKey);
20
+ await context.queryClient.ensureQueryData(cursorThreadsQueryOptions(params.workspaceKey));
21
+ },
22
+ pendingComponent: () => /* @__PURE__ */ jsx(LoadingPanel, {
23
+ description: "Loading Cursor threads and workspace metadata. Larger workspaces can take a moment.",
24
+ title: "Loading workspace"
25
+ })
26
+ });
27
+ //#endregion
28
+ export { findWorkspaceOrThrow as n, Route as t };