spiracha 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/AGENTS.md +48 -5
  2. package/README.md +40 -5
  3. package/apps/ui/AGENTS.md +23 -4
  4. package/apps/ui/README.md +49 -2
  5. package/apps/ui/dist/client/assets/analytics-DOy1b6Sh.js +1 -0
  6. package/apps/ui/dist/client/assets/{antigravity-conversations._conversationId-DmD0sN8X.js → antigravity-conversations._conversationId-DqySVO2K.js} +2 -2
  7. package/apps/ui/dist/client/assets/antigravity-keychain-panel-B77qJz6f.js +1 -0
  8. package/apps/ui/dist/client/assets/antigravity._workspaceKey-B3NM6gRH.js +1 -0
  9. package/apps/ui/dist/client/assets/{antigravity.index-DEEkjlZa.js → antigravity.index-DP9JC2P9.js} +1 -1
  10. package/apps/ui/dist/client/assets/{badge-DfWvPfKF.js → badge-C3i4OKs8.js} +1 -1
  11. package/apps/ui/dist/client/assets/claude-code-sessions._sessionId-8pQ55ci2.js +1 -0
  12. package/apps/ui/dist/client/assets/claude-code-sessions._sessionId-DVz5UmtU.js +1 -0
  13. package/apps/ui/dist/client/assets/claude-code._workspaceKey-BBKskSum.js +1 -0
  14. package/apps/ui/dist/client/assets/claude-code._workspaceKey-OkikMUFs.js +1 -0
  15. package/apps/ui/dist/client/assets/claude-code.index-Cwu76dbb.js +1 -0
  16. package/apps/ui/dist/client/assets/claude-code.index-D6eMd08t.js +1 -0
  17. package/apps/ui/dist/client/assets/createServerFn-B-KkwmHU.js +3 -0
  18. package/apps/ui/dist/client/assets/cursor-threads._composerId-hBWlP1D-.js +1 -0
  19. package/apps/ui/dist/client/assets/cursor._workspaceKey-BFPkIRi-.js +1 -0
  20. package/apps/ui/dist/client/assets/cursor.index-8y4o20kb.js +2 -0
  21. package/apps/ui/dist/client/assets/delete-confirm-dialog-Bxs07u-j.js +7 -0
  22. package/apps/ui/dist/client/assets/dist-BrJhN2A0.js +5 -0
  23. package/apps/ui/dist/client/assets/{dist-BhZOxAPP.js → dist-Cmd3AIfD.js} +1 -1
  24. package/apps/ui/dist/client/assets/dropdown-menu-D5cvPaZt.js +1 -0
  25. package/apps/ui/dist/client/assets/{es2015-BkCWttyM.js → es2015-ad6040dw.js} +1 -1
  26. package/apps/ui/dist/client/assets/export-dialog-Dr8d2MqD.js +1 -0
  27. package/apps/ui/dist/client/assets/{formatters-BM9kB7ed.js → formatters-BtqyrX_c.js} +1 -1
  28. package/apps/ui/dist/client/assets/index-C-STgIH4.js +166 -0
  29. package/apps/ui/dist/client/assets/kiro-sessions._sessionId-CKgfJ7GR.js +1 -0
  30. package/apps/ui/dist/client/assets/kiro-sessions._sessionId-zvIJHtQF.js +1 -0
  31. package/apps/ui/dist/client/assets/kiro._workspaceKey-DhVuJuZB.js +1 -0
  32. package/apps/ui/dist/client/assets/kiro._workspaceKey-QArsjkTY.js +1 -0
  33. package/apps/ui/dist/client/assets/kiro.index-C-fr4m7i.js +1 -0
  34. package/apps/ui/dist/client/assets/kiro.index-OYgAdtZd.js +1 -0
  35. package/apps/ui/dist/client/assets/opencode-sessions._sessionId-DLjiTst-.js +1 -0
  36. package/apps/ui/dist/client/assets/opencode-sessions._sessionId-biBwrRbt.js +8 -0
  37. package/apps/ui/dist/client/assets/opencode._workspaceKey-C7OIzMOJ.js +1 -0
  38. package/apps/ui/dist/client/assets/opencode._workspaceKey-sBakX0oI.js +1 -0
  39. package/apps/ui/dist/client/assets/opencode.index-Bl_kNs9N.js +1 -0
  40. package/apps/ui/dist/client/assets/opencode.index-CN53bVmb.js +1 -0
  41. package/apps/ui/dist/client/assets/preload-helper-B8fFrdxC.js +1 -0
  42. package/apps/ui/dist/client/assets/projects._project-D8WloxQN.js +1 -0
  43. package/apps/ui/dist/client/assets/projects.index-5xRtuJdX.js +3 -0
  44. package/apps/ui/dist/client/assets/routes-DnzF_9CX.js +1 -0
  45. package/apps/ui/dist/client/assets/select-CYF6pF37.js +1 -0
  46. package/apps/ui/dist/client/assets/settings-Dx70jgP_.js +1 -0
  47. package/apps/ui/dist/client/assets/styles-B7Zi9EFA.css +1 -0
  48. package/apps/ui/dist/client/assets/tabs-CmuhkT-c.js +7 -0
  49. package/apps/ui/dist/client/assets/thread-transcript-stats-BUNz6u7F.js +1 -0
  50. package/apps/ui/dist/client/assets/threads._threadId-BMRSFow3.js +1 -0
  51. package/apps/ui/dist/client/assets/useMutation-BSFult2i.js +1 -0
  52. package/apps/ui/dist/client/assets/useQuery-CjINKZf1.js +1 -0
  53. package/apps/ui/dist/client/icon.svg +2 -1
  54. package/apps/ui/dist/server/assets/_tanstack-start-manifest_v-CQ8Jjs3B.js +387 -0
  55. package/apps/ui/dist/server/assets/{antigravity-conversations._conversationId-BtexWY-K.js → antigravity-conversations._conversationId-BKOyL2T6.js} +2 -2
  56. package/apps/ui/dist/server/assets/{antigravity-conversations._conversationId-zMrR6v6R.js → antigravity-conversations._conversationId-eS87Dx7g.js} +1 -1
  57. package/apps/ui/dist/server/assets/claude-code-db-Ik3VStKZ.js +361 -0
  58. package/apps/ui/dist/server/assets/claude-code-queries-Cgzi4K-e.js +37 -0
  59. package/apps/ui/dist/server/assets/claude-code-server-PfraClXS.js +72 -0
  60. package/apps/ui/dist/server/assets/claude-code-sessions._sessionId-C55oe6zj.js +18 -0
  61. package/apps/ui/dist/server/assets/claude-code-sessions._sessionId-D1RYYi3j.js +473 -0
  62. package/apps/ui/dist/server/assets/claude-code-sessions._sessionId-DSvPLEUL.js +11 -0
  63. package/apps/ui/dist/server/assets/claude-code-transcript-C-bxh3cS.js +139 -0
  64. package/apps/ui/dist/server/assets/claude-code-transcript-phase-DmUMc8VU.js +10 -0
  65. package/apps/ui/dist/server/assets/claude-code._workspaceKey-B5Xg_-tE.js +28 -0
  66. package/apps/ui/dist/server/assets/claude-code._workspaceKey-BPlzyXPa.js +11 -0
  67. package/apps/ui/dist/server/assets/claude-code._workspaceKey-DqDve2wl.js +191 -0
  68. package/apps/ui/dist/server/assets/claude-code.index-B7yYR7dD.js +92 -0
  69. package/apps/ui/dist/server/assets/claude-code.index-BUHThG1W.js +11 -0
  70. package/apps/ui/dist/server/assets/{codex-server-CNXSJuc2.js → codex-server-CGXU4H8-.js} +319 -29
  71. package/apps/ui/dist/server/assets/{cursor-db-cYZEU3WQ.js → cursor-db-CZnYy7aT.js} +3 -3
  72. package/apps/ui/dist/server/assets/{cursor-recovery-nq-kR62j.js → cursor-recovery-CXpO8KcD.js} +2 -2
  73. package/apps/ui/dist/server/assets/{cursor-server-C3q7hrp-.js → cursor-server-DNu52A3K.js} +13 -13
  74. package/apps/ui/dist/server/assets/{cursor-threads._composerId-BkMMTQ3v.js → cursor-threads._composerId-Ckn6ItHI.js} +3 -3
  75. package/apps/ui/dist/server/assets/{cursor-threads._composerId-BPJFWfJj.js → cursor-threads._composerId-p9-ARAzc.js} +1 -1
  76. package/apps/ui/dist/server/assets/{cursor-transcript-2iL3KFSK.js → cursor-transcript-B7tGnqtn.js} +1 -1
  77. package/apps/ui/dist/server/assets/{cursor._workspaceKey-C5PdTaKB.js → cursor._workspaceKey-CZuohIUL.js} +1 -1
  78. package/apps/ui/dist/server/assets/{cursor._workspaceKey-Ckj7apKI.js → cursor._workspaceKey-DPp5JSjy.js} +2 -2
  79. package/apps/ui/dist/server/assets/{export-dialog-BItjWgkZ.js → export-dialog-D88ze9Gy.js} +2 -2
  80. package/apps/ui/dist/server/assets/kiro-db--fXrED_-.js +552 -0
  81. package/apps/ui/dist/server/assets/kiro-queries-CzNlM2ok.js +37 -0
  82. package/apps/ui/dist/server/assets/kiro-server-9WRxg2Au.js +72 -0
  83. package/apps/ui/dist/server/assets/kiro-sessions._sessionId-CRY2c7YO.js +11 -0
  84. package/apps/ui/dist/server/assets/kiro-sessions._sessionId-F1UlwxmR.js +449 -0
  85. package/apps/ui/dist/server/assets/kiro-sessions._sessionId-bvTulT7C.js +18 -0
  86. package/apps/ui/dist/server/assets/kiro-transcript-DoekQBaH.js +112 -0
  87. package/apps/ui/dist/server/assets/kiro-transcript-phase-CJG40nQg.js +27 -0
  88. package/apps/ui/dist/server/assets/kiro._workspaceKey-BDe9sQwo.js +11 -0
  89. package/apps/ui/dist/server/assets/kiro._workspaceKey-CJsjgNwO.js +28 -0
  90. package/apps/ui/dist/server/assets/kiro._workspaceKey-D_-4Qb7y.js +193 -0
  91. package/apps/ui/dist/server/assets/kiro.index-C__-UROk.js +11 -0
  92. package/apps/ui/dist/server/assets/kiro.index-CmTbqeYj.js +93 -0
  93. package/apps/ui/dist/server/assets/opencode-db-BM7KjOzc.js +397 -0
  94. package/apps/ui/dist/server/assets/opencode-queries-BeNYXnQv.js +50 -0
  95. package/apps/ui/dist/server/assets/opencode-server-BpQ_kRze.js +72 -0
  96. package/apps/ui/dist/server/assets/opencode-sessions._sessionId-CGQ-t0vD.js +518 -0
  97. package/apps/ui/dist/server/assets/opencode-sessions._sessionId-D8Q7in_Z.js +18 -0
  98. package/apps/ui/dist/server/assets/opencode-sessions._sessionId-DKOvi0lV.js +11 -0
  99. package/apps/ui/dist/server/assets/opencode-think-tags-CAoD-EcZ.js +87 -0
  100. package/apps/ui/dist/server/assets/opencode-transcript-BNTcGNym.js +141 -0
  101. package/apps/ui/dist/server/assets/opencode-transcript-phase-OqLkiQD0.js +32 -0
  102. package/apps/ui/dist/server/assets/opencode._workspaceKey-BdqcWHw1.js +11 -0
  103. package/apps/ui/dist/server/assets/opencode._workspaceKey-CfH96HTT.js +28 -0
  104. package/apps/ui/dist/server/assets/opencode._workspaceKey-DdbHPDrO.js +207 -0
  105. package/apps/ui/dist/server/assets/opencode.index-BbVzkJXP.js +11 -0
  106. package/apps/ui/dist/server/assets/opencode.index-Vh_Gq_1L.js +93 -0
  107. package/apps/ui/dist/server/assets/{projects._project-Bpbc3C-L.js → projects._project-4io5LO0E.js} +1 -1
  108. package/apps/ui/dist/server/assets/{projects._project-CvZho6EQ.js → projects._project-D6ZoGhJ8.js} +2 -2
  109. package/apps/ui/dist/server/assets/{router-6m-ihwqA.js → router-Sac2DGk6.js} +157 -49
  110. package/apps/ui/dist/server/assets/{shared-CPRNYIql.js → shared-DyhChtHf.js} +4 -1
  111. package/apps/ui/dist/server/assets/source-session-export-server-DNutCawb.js +38 -0
  112. package/apps/ui/dist/server/assets/{start-CI_0bSiY.js → start-B_HFwkkk.js} +1 -1
  113. package/apps/ui/dist/server/assets/{tabs-CGA13IZM.js → tabs-DkaChNVg.js} +0 -1
  114. package/apps/ui/dist/server/assets/thread-transcript-stats-Dh34mt2u.js +45 -0
  115. package/apps/ui/dist/server/assets/{threads._threadId-D2GYkVn6.js → threads._threadId-BeXEc4Lo.js} +15 -6
  116. package/apps/ui/dist/server/assets/{threads._threadId-Bs0yuqO9.js → threads._threadId-Ci0S4mKU.js} +1 -1
  117. package/apps/ui/dist/server/server.js +72 -24
  118. package/package.json +21 -4
  119. package/src/lib/claude-code-db.ts +655 -0
  120. package/src/lib/claude-code-exporter-types.ts +110 -0
  121. package/src/lib/claude-code-transcript-phase.ts +25 -0
  122. package/src/lib/claude-code-transcript.ts +180 -0
  123. package/src/lib/codex-browser-db.ts +490 -31
  124. package/src/lib/codex-browser-export.ts +18 -2
  125. package/src/lib/codex-thread-cache.ts +17 -1
  126. package/src/lib/concurrency.ts +25 -0
  127. package/src/lib/kiro-db.ts +949 -0
  128. package/src/lib/kiro-exporter-types.ts +100 -0
  129. package/src/lib/kiro-transcript-phase.ts +41 -0
  130. package/src/lib/kiro-transcript.ts +115 -0
  131. package/src/lib/opencode-db.ts +610 -0
  132. package/src/lib/opencode-exporter-types.ts +129 -0
  133. package/src/lib/opencode-think-tags.ts +126 -0
  134. package/src/lib/opencode-transcript-phase.ts +50 -0
  135. package/src/lib/opencode-transcript.ts +194 -0
  136. package/src/lib/shared.ts +25 -0
  137. package/src/lib/ui-export-archive.ts +61 -0
  138. package/apps/ui/dist/client/assets/analytics-DK2jdvmI.js +0 -1
  139. package/apps/ui/dist/client/assets/antigravity-keychain-panel-BRHVjFAM.js +0 -1
  140. package/apps/ui/dist/client/assets/antigravity._workspaceKey-CGV7amas.js +0 -1
  141. package/apps/ui/dist/client/assets/createServerFn-CgRRVpBH.js +0 -3
  142. package/apps/ui/dist/client/assets/cursor-threads._composerId-Ti2gTm63.js +0 -1
  143. package/apps/ui/dist/client/assets/cursor._workspaceKey-DzD_c6j9.js +0 -1
  144. package/apps/ui/dist/client/assets/cursor.index-PkCFVcl4.js +0 -2
  145. package/apps/ui/dist/client/assets/delete-confirm-dialog-BHRmyLHr.js +0 -11
  146. package/apps/ui/dist/client/assets/dropdown-menu-Dy5cLzTy.js +0 -1
  147. package/apps/ui/dist/client/assets/export-dialog-C86SYHJn.js +0 -1
  148. package/apps/ui/dist/client/assets/index-CPvAP-jk.js +0 -149
  149. package/apps/ui/dist/client/assets/projects._project-Ckf6muWZ.js +0 -1
  150. package/apps/ui/dist/client/assets/projects.index-V5ibNZII.js +0 -3
  151. package/apps/ui/dist/client/assets/routes-Df2tgpyd.js +0 -1
  152. package/apps/ui/dist/client/assets/select-Bf2GwfPR.js +0 -1
  153. package/apps/ui/dist/client/assets/settings-5VQIzME0.js +0 -1
  154. package/apps/ui/dist/client/assets/styles-BhRkXgwB.css +0 -1
  155. package/apps/ui/dist/client/assets/tabs-OO4VU5KR.js +0 -7
  156. package/apps/ui/dist/client/assets/threads._threadId-BgDhFj2I.js +0 -1
  157. package/apps/ui/dist/client/assets/useMutation-CC_B7uy5.js +0 -1
  158. package/apps/ui/dist/client/assets/useQuery-C5By6WKU.js +0 -1
  159. package/apps/ui/dist/server/assets/_tanstack-start-manifest_v-CRW2kqj0.js +0 -232
@@ -0,0 +1,397 @@
1
+ import { i as asString, n as asNumber, r as asObject } from "./shared-DyhChtHf.js";
2
+ import { t as splitOpenCodeThinkTaggedText } from "./opencode-think-tags-CAoD-EcZ.js";
3
+ import { stat } from "node:fs/promises";
4
+ import os from "node:os";
5
+ import path from "node:path";
6
+ import { Database, constants } from "bun:sqlite";
7
+ import { pathToFileURL } from "node:url";
8
+ //#region ../../src/lib/opencode-exporter-types.ts
9
+ var getDefaultOpenCodeDataDir = (env = process.env, homeDir = os.homedir()) => {
10
+ return path.join(env.XDG_DATA_HOME || path.join(homeDir, ".local", "share"), "opencode");
11
+ };
12
+ var DEFAULT_OPENCODE_DATA_DIR = getDefaultOpenCodeDataDir();
13
+ var resolveOpenCodeDataDir = () => {
14
+ const configured = process.env.SPIRACHA_OPENCODE_DATA_DIR?.trim() || process.env.SPIRACHA_OPENCODE_DIR?.trim();
15
+ return configured ? configured : DEFAULT_OPENCODE_DATA_DIR;
16
+ };
17
+ var resolveOpenCodeDbPath = () => {
18
+ const configured = process.env.SPIRACHA_OPENCODE_DB?.trim();
19
+ return configured ? configured : path.join(resolveOpenCodeDataDir(), "opencode.db");
20
+ };
21
+ //#endregion
22
+ //#region ../../src/lib/opencode-db.ts
23
+ var OPENCODE_READONLY_DB_OPEN_FLAGS = constants.SQLITE_OPEN_READONLY | constants.SQLITE_OPEN_URI;
24
+ var MAIN_SESSION_FILTER = "s.parent_id IS NULL";
25
+ var pathExists = async (target) => {
26
+ return await stat(target).then(() => true).catch(() => false);
27
+ };
28
+ var getOpenCodeReadonlyDbUri = (dbPath) => {
29
+ const url = pathToFileURL(dbPath);
30
+ url.searchParams.set("mode", "ro");
31
+ return url.href;
32
+ };
33
+ var openOpenCodeReadonlyDb = (dbPath) => {
34
+ return new Database(getOpenCodeReadonlyDbUri(dbPath), OPENCODE_READONLY_DB_OPEN_FLAGS);
35
+ };
36
+ var parseJsonValue = (value) => {
37
+ if (!value) return null;
38
+ try {
39
+ return JSON.parse(value);
40
+ } catch {
41
+ return value;
42
+ }
43
+ };
44
+ var parseJsonObject = (value) => {
45
+ return asObject(parseJsonValue(value)) ?? {};
46
+ };
47
+ var cleanLabel = (value) => {
48
+ const cleaned = value?.replace(/\s+/g, " ").trim();
49
+ return cleaned ? cleaned : null;
50
+ };
51
+ var getWorkspaceLabel = (name, worktree) => {
52
+ const named = cleanLabel(name);
53
+ if (named) return named;
54
+ if (worktree === "/") return "(global)";
55
+ return path.basename(worktree.replace(/\/+$/u, "")) || worktree;
56
+ };
57
+ var getWorkspaceKey = (projectId) => `project:${projectId}`;
58
+ var getProjectIdFromWorkspaceKey = (workspaceKey) => {
59
+ return workspaceKey.startsWith("project:") ? workspaceKey.slice(8) : null;
60
+ };
61
+ var parseModelInfo = (value) => {
62
+ const parsed = parseJsonValue(value);
63
+ if (typeof parsed === "string") return {
64
+ id: parsed,
65
+ providerID: null,
66
+ raw: parsed,
67
+ variant: null
68
+ };
69
+ const model = asObject(parsed);
70
+ return {
71
+ id: asString(model?.id ?? null),
72
+ providerID: asString(model?.providerID ?? null),
73
+ raw: parsed,
74
+ variant: asString(model?.variant ?? null)
75
+ };
76
+ };
77
+ var formatModelLabel = (model) => {
78
+ if (typeof model.raw === "string") return cleanLabel(model.raw);
79
+ const id = cleanLabel(model.id);
80
+ const variant = cleanLabel(model.variant);
81
+ if (!id) return null;
82
+ return variant ? `${id} ${variant}` : id;
83
+ };
84
+ var toWorkspaceGroup = (row) => {
85
+ const label = getWorkspaceLabel(row.name, row.worktree);
86
+ return {
87
+ archivedSessionCount: row.archivedSessionCount,
88
+ key: getWorkspaceKey(row.projectId),
89
+ label,
90
+ lastActiveMs: row.lastActiveMs,
91
+ messageCount: row.messageCount,
92
+ partCount: row.partCount,
93
+ projectId: row.projectId,
94
+ sessionCount: row.sessionCount,
95
+ uri: pathToFileURL(row.worktree).href,
96
+ worktree: row.worktree
97
+ };
98
+ };
99
+ var toSessionSummary = (row) => {
100
+ const label = getWorkspaceLabel(row.projectName, row.worktree);
101
+ const model = parseModelInfo(row.model);
102
+ return {
103
+ agent: row.agent,
104
+ archivedAtMs: row.archivedAtMs,
105
+ cost: row.cost,
106
+ createdAtMs: row.createdAtMs,
107
+ directory: row.directory,
108
+ lastUpdatedAtMs: row.lastUpdatedAtMs,
109
+ messageCount: row.messageCount,
110
+ model,
111
+ modelLabel: formatModelLabel(model),
112
+ partCount: row.partCount,
113
+ path: row.path,
114
+ permission: row.permission,
115
+ projectId: row.projectId,
116
+ renderablePartCount: row.renderablePartCount,
117
+ sessionId: row.sessionId,
118
+ slug: row.slug,
119
+ summaryAdditions: row.summaryAdditions,
120
+ summaryDeletions: row.summaryDeletions,
121
+ summaryFiles: row.summaryFiles,
122
+ textPartCount: row.textPartCount,
123
+ title: cleanLabel(row.title) ?? row.sessionId,
124
+ tokensCacheRead: row.tokensCacheRead,
125
+ tokensCacheWrite: row.tokensCacheWrite,
126
+ tokensInput: row.tokensInput,
127
+ tokensOutput: row.tokensOutput,
128
+ tokensReasoning: row.tokensReasoning,
129
+ toolPartCount: row.toolPartCount,
130
+ totalTokens: row.tokensInput + row.tokensOutput + row.tokensReasoning + row.tokensCacheRead + row.tokensCacheWrite,
131
+ workspaceKey: getWorkspaceKey(row.projectId),
132
+ workspaceLabel: label,
133
+ worktree: row.worktree
134
+ };
135
+ };
136
+ var workspaceRowsQuery = `
137
+ SELECT
138
+ p.id AS projectId,
139
+ p.name AS name,
140
+ p.worktree AS worktree,
141
+ (
142
+ SELECT COUNT(*)
143
+ FROM session s
144
+ WHERE s.project_id = p.id AND ${MAIN_SESSION_FILTER}
145
+ ) AS sessionCount,
146
+ (
147
+ SELECT COUNT(*)
148
+ FROM session s
149
+ WHERE s.project_id = p.id AND ${MAIN_SESSION_FILTER} AND s.time_archived IS NOT NULL
150
+ ) AS archivedSessionCount,
151
+ (
152
+ SELECT COUNT(*)
153
+ FROM message m
154
+ JOIN session s ON s.id = m.session_id
155
+ WHERE s.project_id = p.id AND ${MAIN_SESSION_FILTER}
156
+ ) AS messageCount,
157
+ (
158
+ SELECT COUNT(*)
159
+ FROM part prt
160
+ JOIN session s ON s.id = prt.session_id
161
+ WHERE s.project_id = p.id AND ${MAIN_SESSION_FILTER}
162
+ ) AS partCount,
163
+ COALESCE((
164
+ SELECT MAX(s.time_updated)
165
+ FROM session s
166
+ WHERE s.project_id = p.id AND ${MAIN_SESSION_FILTER}
167
+ ), p.time_updated) AS lastActiveMs
168
+ FROM project p
169
+ `;
170
+ var sessionSelectQuery = `
171
+ SELECT
172
+ s.id AS sessionId,
173
+ s.project_id AS projectId,
174
+ p.name AS projectName,
175
+ p.worktree AS worktree,
176
+ s.slug AS slug,
177
+ s.directory AS directory,
178
+ s.title AS title,
179
+ s.permission AS permission,
180
+ s.time_created AS createdAtMs,
181
+ s.time_updated AS lastUpdatedAtMs,
182
+ s.time_archived AS archivedAtMs,
183
+ s.path AS path,
184
+ s.agent AS agent,
185
+ s.model AS model,
186
+ s.cost AS cost,
187
+ s.tokens_input AS tokensInput,
188
+ s.tokens_output AS tokensOutput,
189
+ s.tokens_reasoning AS tokensReasoning,
190
+ s.tokens_cache_read AS tokensCacheRead,
191
+ s.tokens_cache_write AS tokensCacheWrite,
192
+ s.summary_files AS summaryFiles,
193
+ s.summary_additions AS summaryAdditions,
194
+ s.summary_deletions AS summaryDeletions,
195
+ (
196
+ SELECT COUNT(*)
197
+ FROM message m
198
+ WHERE m.session_id = s.id
199
+ ) AS messageCount,
200
+ (
201
+ SELECT COUNT(*)
202
+ FROM part prt
203
+ WHERE prt.session_id = s.id
204
+ ) AS partCount,
205
+ (
206
+ SELECT COUNT(*)
207
+ FROM part prt
208
+ WHERE prt.session_id = s.id AND json_extract(prt.data, '$.type') = 'text'
209
+ ) AS textPartCount,
210
+ (
211
+ SELECT COUNT(*)
212
+ FROM part prt
213
+ WHERE prt.session_id = s.id AND json_extract(prt.data, '$.type') = 'tool'
214
+ ) AS toolPartCount,
215
+ (
216
+ SELECT COUNT(*)
217
+ FROM part prt
218
+ WHERE prt.session_id = s.id
219
+ AND (
220
+ (
221
+ json_extract(prt.data, '$.type') IN ('text', 'reasoning')
222
+ AND trim(COALESCE(json_extract(prt.data, '$.text'), '')) <> ''
223
+ )
224
+ OR json_extract(prt.data, '$.type') = 'tool'
225
+ )
226
+ ) AS renderablePartCount
227
+ FROM session s
228
+ JOIN project p ON p.id = s.project_id
229
+ `;
230
+ var listOpenCodeWorkspaceGroups = async (dbPath = resolveOpenCodeDbPath()) => {
231
+ if (!await pathExists(dbPath)) return [];
232
+ const db = openOpenCodeReadonlyDb(dbPath);
233
+ try {
234
+ return db.query(`${workspaceRowsQuery} ORDER BY lastActiveMs DESC, p.worktree ASC`).all().map(toWorkspaceGroup);
235
+ } finally {
236
+ db.close();
237
+ }
238
+ };
239
+ var readSessionSummaries = (db, whereSql, params) => {
240
+ return db.query(`${sessionSelectQuery} WHERE ${whereSql} ORDER BY s.time_updated DESC, s.title ASC`).all(...params).map(toSessionSummary);
241
+ };
242
+ var listOpenCodeSessionsForGroup = async (workspaceKey, dbPath = resolveOpenCodeDbPath()) => {
243
+ const projectId = getProjectIdFromWorkspaceKey(workspaceKey);
244
+ if (!projectId || !await pathExists(dbPath)) return [];
245
+ const db = openOpenCodeReadonlyDb(dbPath);
246
+ try {
247
+ return readSessionSummaries(db, `s.project_id = ? AND ${MAIN_SESSION_FILTER}`, [projectId]);
248
+ } finally {
249
+ db.close();
250
+ }
251
+ };
252
+ var readOpenCodeSessionSummary = (db, sessionId) => {
253
+ return readSessionSummaries(db, `s.id = ? AND ${MAIN_SESSION_FILTER}`, [sessionId])[0] ?? null;
254
+ };
255
+ var getMessageRole = (raw) => asString(raw.role ?? null) ?? "unknown";
256
+ var toPartType = (value) => {
257
+ switch (value) {
258
+ case "reasoning":
259
+ case "step-finish":
260
+ case "step-start":
261
+ case "text":
262
+ case "tool": return value;
263
+ default: return "unknown";
264
+ }
265
+ };
266
+ var formatJsonLike = (value) => {
267
+ if (value === void 0 || value === null) return null;
268
+ if (typeof value === "string") return value;
269
+ return JSON.stringify(value, null, 2);
270
+ };
271
+ var parseTimeMs = (raw, key) => {
272
+ return asNumber(asObject(raw.time ?? null)?.[key] ?? null);
273
+ };
274
+ var parseToolTimeMs = (raw, key) => {
275
+ return asNumber((asObject(asObject(raw.state ?? null)?.time ?? null) ?? asObject(raw.time ?? null))?.[key] ?? null);
276
+ };
277
+ var parseStepTokens = (value) => {
278
+ const tokens = asObject(value ?? null);
279
+ if (!tokens) return null;
280
+ const cache = asObject(tokens.cache ?? null);
281
+ return {
282
+ cacheRead: asNumber(cache?.read ?? null) ?? 0,
283
+ cacheWrite: asNumber(cache?.write ?? null) ?? 0,
284
+ input: asNumber(tokens.input ?? null) ?? 0,
285
+ output: asNumber(tokens.output ?? null) ?? 0,
286
+ reasoning: asNumber(tokens.reasoning ?? null) ?? 0,
287
+ total: asNumber(tokens.total ?? null) ?? 0
288
+ };
289
+ };
290
+ var parseTextOpenCodePart = (base) => ({
291
+ ...base,
292
+ endTimeMs: parseTimeMs(base.raw, "end"),
293
+ startTimeMs: parseTimeMs(base.raw, "start"),
294
+ text: asString(base.raw.text ?? null) ?? ""
295
+ });
296
+ var parseToolOpenCodePart = (base) => {
297
+ const state = asObject(base.raw.state ?? null);
298
+ return {
299
+ ...base,
300
+ argumentsText: formatJsonLike(state?.input),
301
+ callId: asString(base.raw.callID ?? null) ?? asString(base.raw.callId ?? null),
302
+ endTimeMs: parseToolTimeMs(base.raw, "end"),
303
+ outputText: formatJsonLike(state?.output),
304
+ startTimeMs: parseToolTimeMs(base.raw, "start"),
305
+ status: asString(state?.status ?? null),
306
+ title: asString(state?.title ?? null),
307
+ toolName: asString(base.raw.tool ?? null) ?? "unknown"
308
+ };
309
+ };
310
+ var parseStepFinishOpenCodePart = (base) => ({
311
+ ...base,
312
+ reason: asString(base.raw.reason ?? null),
313
+ snapshot: asString(base.raw.snapshot ?? null),
314
+ tokens: parseStepTokens(base.raw.tokens)
315
+ });
316
+ var parseStepStartOpenCodePart = (base) => ({
317
+ ...base,
318
+ snapshot: asString(base.raw.snapshot ?? null)
319
+ });
320
+ var parseOpenCodePartByType = (base) => {
321
+ switch (base.type) {
322
+ case "reasoning":
323
+ case "text": return parseTextOpenCodePart(base);
324
+ case "tool": return parseToolOpenCodePart(base);
325
+ case "step-finish": return parseStepFinishOpenCodePart(base);
326
+ case "step-start": return parseStepStartOpenCodePart(base);
327
+ case "unknown": return base;
328
+ }
329
+ };
330
+ var parseOpenCodePart = (row, role) => {
331
+ const raw = parseJsonObject(row.data);
332
+ return parseOpenCodePartByType({
333
+ createdAtMs: row.timeCreated,
334
+ messageId: row.messageId,
335
+ partId: row.partId,
336
+ raw,
337
+ role,
338
+ type: toPartType(raw.type),
339
+ updatedAtMs: row.timeUpdated
340
+ });
341
+ };
342
+ var isRenderablePart = (part) => {
343
+ if (part.type === "text" || part.type === "reasoning") {
344
+ const { reasoningBlocks, visibleText } = splitOpenCodeThinkTaggedText(part.text ?? "");
345
+ return Boolean(visibleText.trim() || reasoningBlocks.length > 0);
346
+ }
347
+ if (part.type === "tool") return Boolean(part.toolName || part.outputText?.trim() || part.argumentsText?.trim());
348
+ return false;
349
+ };
350
+ var readMessages = (db, sessionId) => {
351
+ const messageRows = db.query(`SELECT id AS messageId, time_created AS timeCreated, time_updated AS timeUpdated, data
352
+ FROM message
353
+ WHERE session_id = ?
354
+ ORDER BY time_created ASC, id ASC`).all(sessionId);
355
+ const partRows = db.query(`SELECT id AS partId, message_id AS messageId, time_created AS timeCreated, time_updated AS timeUpdated, data
356
+ FROM part
357
+ WHERE session_id = ?
358
+ ORDER BY time_created ASC, id ASC`).all(sessionId);
359
+ const partsByMessageId = /* @__PURE__ */ new Map();
360
+ for (const part of partRows) {
361
+ const parts = partsByMessageId.get(part.messageId) ?? [];
362
+ parts.push(part);
363
+ partsByMessageId.set(part.messageId, parts);
364
+ }
365
+ return messageRows.map((message) => {
366
+ const raw = parseJsonObject(message.data);
367
+ const role = getMessageRole(raw);
368
+ const parts = (partsByMessageId.get(message.messageId) ?? []).map((part) => parseOpenCodePart(part, role));
369
+ return {
370
+ createdAtMs: message.timeCreated,
371
+ messageId: message.messageId,
372
+ parts,
373
+ raw,
374
+ role,
375
+ updatedAtMs: message.timeUpdated
376
+ };
377
+ });
378
+ };
379
+ var readOpenCodeSessionTranscript = async (dbPath, sessionId) => {
380
+ if (!await pathExists(dbPath)) return null;
381
+ const db = openOpenCodeReadonlyDb(dbPath);
382
+ try {
383
+ const session = readOpenCodeSessionSummary(db, sessionId);
384
+ if (!session) return null;
385
+ const messages = readMessages(db, sessionId);
386
+ return {
387
+ messages,
388
+ partCount: messages.reduce((total, message) => total + message.parts.length, 0),
389
+ renderablePartCount: messages.reduce((total, message) => total + message.parts.filter(isRenderablePart).length, 0),
390
+ session
391
+ };
392
+ } finally {
393
+ db.close();
394
+ }
395
+ };
396
+ //#endregion
397
+ export { listOpenCodeSessionsForGroup, listOpenCodeWorkspaceGroups, readOpenCodeSessionTranscript, resolveOpenCodeDbPath };
@@ -0,0 +1,50 @@
1
+ import { t as createServerFn } from "../server.js";
2
+ import { t as isRetryableSqliteError } from "./sqlite-error-LZDrnxdd.js";
3
+ import { t as createSsrRpc } from "./createSsrRpc-C754NPki.js";
4
+ import { z } from "zod";
5
+ import { queryOptions } from "@tanstack/react-query";
6
+ //#region src/lib/opencode-server.ts
7
+ var workspaceSchema = z.object({ workspaceKey: z.string().min(1) });
8
+ var sessionSchema = z.object({ sessionId: z.string().min(1) });
9
+ var exportSessionSchema = z.object({
10
+ includeCommentary: z.boolean().default(true),
11
+ includeMetadata: z.boolean().default(true),
12
+ includeTools: z.boolean().default(true),
13
+ outputFormat: z.enum(["md", "txt"]).default("md"),
14
+ sessionId: z.string().min(1),
15
+ zipArchive: z.boolean().default(false)
16
+ });
17
+ var listOpenCodeWorkspacesFn = createServerFn({ method: "GET" }).handler(createSsrRpc("1579290293aa3c05864abeb16b20e7fbe85fe73b2518d8ba75dbc536dfc02b88"));
18
+ var listOpenCodeSessionsFn = createServerFn({ method: "GET" }).validator(workspaceSchema).handler(createSsrRpc("1d8e6aec1907ff012d654cbfaa89e559078a0c2d80a02f4b257d9a179a002e36"));
19
+ var getOpenCodeSessionDetailFn = createServerFn({ method: "GET" }).validator(sessionSchema).handler(createSsrRpc("0fdecc913045cc27ae7462cd3c143af926650dece043ca1a111e0e83a3cd327b"));
20
+ var exportOpenCodeSessionFn = createServerFn({ method: "POST" }).validator(exportSessionSchema).handler(createSsrRpc("c051a060ff7f4d39e308fd586d9f81f576b53e96f37bdc56dd80112679f01218"));
21
+ //#endregion
22
+ //#region src/lib/opencode-queries.ts
23
+ var retrySqliteQuery = (failureCount, error) => {
24
+ return failureCount < 3 && isRetryableSqliteError(error);
25
+ };
26
+ var retryDelay = (attemptIndex) => {
27
+ return [150, 400][attemptIndex] ?? 800;
28
+ };
29
+ var openCodeWorkspacesQueryOptions = () => queryOptions({
30
+ queryFn: () => listOpenCodeWorkspacesFn(),
31
+ queryKey: ["opencode-workspaces"],
32
+ retry: retrySqliteQuery,
33
+ retryDelay
34
+ });
35
+ var openCodeSessionsQueryOptions = (workspaceKey) => queryOptions({
36
+ enabled: workspaceKey !== null,
37
+ queryFn: () => listOpenCodeSessionsFn({ data: { workspaceKey: workspaceKey ?? "" } }),
38
+ queryKey: ["opencode-sessions", workspaceKey ?? "none"],
39
+ retry: retrySqliteQuery,
40
+ retryDelay
41
+ });
42
+ var openCodeSessionDetailQueryOptions = (sessionId) => queryOptions({
43
+ enabled: sessionId !== null,
44
+ queryFn: () => getOpenCodeSessionDetailFn({ data: { sessionId: sessionId ?? "" } }),
45
+ queryKey: ["opencode-session", sessionId ?? "none"],
46
+ retry: retrySqliteQuery,
47
+ retryDelay
48
+ });
49
+ //#endregion
50
+ export { exportOpenCodeSessionFn as i, openCodeSessionsQueryOptions as n, openCodeWorkspacesQueryOptions as r, openCodeSessionDetailQueryOptions as t };
@@ -0,0 +1,72 @@
1
+ import { t as createServerFn } from "../server.js";
2
+ import { t as createServerRpc } from "./createServerRpc-CF_DEwnm.js";
3
+ import { t as renderSourceSessionDownload } from "./source-session-export-server-DNutCawb.js";
4
+ import { z } from "zod";
5
+ //#region src/lib/opencode-server.ts?tss-serverfn-split
6
+ var workspaceSchema = z.object({ workspaceKey: z.string().min(1) });
7
+ var sessionSchema = z.object({ sessionId: z.string().min(1) });
8
+ var exportSessionSchema = z.object({
9
+ includeCommentary: z.boolean().default(true),
10
+ includeMetadata: z.boolean().default(true),
11
+ includeTools: z.boolean().default(true),
12
+ outputFormat: z.enum(["md", "txt"]).default("md"),
13
+ sessionId: z.string().min(1),
14
+ zipArchive: z.boolean().default(false)
15
+ });
16
+ var listOpenCodeWorkspacesFn_createServerFn_handler = createServerRpc({
17
+ id: "1579290293aa3c05864abeb16b20e7fbe85fe73b2518d8ba75dbc536dfc02b88",
18
+ name: "listOpenCodeWorkspacesFn",
19
+ filename: "src/lib/opencode-server.ts"
20
+ }, (opts) => listOpenCodeWorkspacesFn.__executeServer(opts));
21
+ var listOpenCodeWorkspacesFn = createServerFn({ method: "GET" }).handler(listOpenCodeWorkspacesFn_createServerFn_handler, async () => {
22
+ const { listOpenCodeWorkspaceGroups } = await import("./opencode-db-BM7KjOzc.js");
23
+ return listOpenCodeWorkspaceGroups();
24
+ });
25
+ var listOpenCodeSessionsFn_createServerFn_handler = createServerRpc({
26
+ id: "1d8e6aec1907ff012d654cbfaa89e559078a0c2d80a02f4b257d9a179a002e36",
27
+ name: "listOpenCodeSessionsFn",
28
+ filename: "src/lib/opencode-server.ts"
29
+ }, (opts) => listOpenCodeSessionsFn.__executeServer(opts));
30
+ var listOpenCodeSessionsFn = createServerFn({ method: "GET" }).validator(workspaceSchema).handler(listOpenCodeSessionsFn_createServerFn_handler, async ({ data }) => {
31
+ const { listOpenCodeSessionsForGroup } = await import("./opencode-db-BM7KjOzc.js");
32
+ return listOpenCodeSessionsForGroup(data.workspaceKey);
33
+ });
34
+ var loadOpenCodeSessionTranscript = async (sessionId) => {
35
+ const { readOpenCodeSessionTranscript, resolveOpenCodeDbPath } = await import("./opencode-db-BM7KjOzc.js");
36
+ const transcript = await readOpenCodeSessionTranscript(resolveOpenCodeDbPath(), sessionId);
37
+ if (!transcript) throw new Error(`OpenCode session not found: ${sessionId}`);
38
+ return transcript;
39
+ };
40
+ var getOpenCodeSessionDetailFn_createServerFn_handler = createServerRpc({
41
+ id: "0fdecc913045cc27ae7462cd3c143af926650dece043ca1a111e0e83a3cd327b",
42
+ name: "getOpenCodeSessionDetailFn",
43
+ filename: "src/lib/opencode-server.ts"
44
+ }, (opts) => getOpenCodeSessionDetailFn.__executeServer(opts));
45
+ var getOpenCodeSessionDetailFn = createServerFn({ method: "GET" }).validator(sessionSchema).handler(getOpenCodeSessionDetailFn_createServerFn_handler, async ({ data }) => {
46
+ return loadOpenCodeSessionTranscript(data.sessionId);
47
+ });
48
+ var exportOpenCodeSessionFn_createServerFn_handler = createServerRpc({
49
+ id: "c051a060ff7f4d39e308fd586d9f81f576b53e96f37bdc56dd80112679f01218",
50
+ name: "exportOpenCodeSessionFn",
51
+ filename: "src/lib/opencode-server.ts"
52
+ }, (opts) => exportOpenCodeSessionFn.__executeServer(opts));
53
+ var exportOpenCodeSessionFn = createServerFn({ method: "POST" }).validator(exportSessionSchema).handler(exportOpenCodeSessionFn_createServerFn_handler, async ({ data }) => {
54
+ const { renderOpenCodeTranscript } = await import("./opencode-transcript-BNTcGNym.js");
55
+ const transcript = await loadOpenCodeSessionTranscript(data.sessionId);
56
+ const content = renderOpenCodeTranscript(transcript, {
57
+ includeCommentary: data.includeCommentary,
58
+ includeMetadata: data.includeMetadata,
59
+ includeTools: data.includeTools,
60
+ outputFormat: data.outputFormat
61
+ });
62
+ if (!content) throw new Error(`OpenCode session has no exportable content: ${data.sessionId}`);
63
+ return renderSourceSessionDownload({
64
+ content,
65
+ fallbackBaseName: "opencode-session",
66
+ fileBaseName: transcript.session.title || transcript.session.slug || transcript.session.sessionId,
67
+ outputFormat: data.outputFormat,
68
+ zipArchive: data.zipArchive
69
+ });
70
+ });
71
+ //#endregion
72
+ export { exportOpenCodeSessionFn_createServerFn_handler, getOpenCodeSessionDetailFn_createServerFn_handler, listOpenCodeSessionsFn_createServerFn_handler, listOpenCodeWorkspacesFn_createServerFn_handler };