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,473 @@
1
+ import { t as Button } from "./button-CmTDnzOn.js";
2
+ import { i as exportClaudeCodeSessionFn, t as claudeCodeSessionDetailQueryOptions } from "./claude-code-queries-Cgzi4K-e.js";
3
+ import { t as Route } from "./claude-code-sessions._sessionId-C55oe6zj.js";
4
+ import { t as Checkbox } from "./checkbox-C0hovF41.js";
5
+ import { t as MetricCard } from "./metric-card-ByEeLu0r.js";
6
+ import { t as PageHeader } from "./page-header-VNSaM3xd.js";
7
+ import { i as formatList, o as formatNumber, r as formatDateTime, s as formatTokens } from "./formatters-FJaGZgJk.js";
8
+ import { a as TranscriptView, c as Breadcrumbs, i as TabsTrigger, n as TabsContent, o as MetadataSection, r as TabsList, s as JsonPanel, t as Tabs } from "./tabs-DkaChNVg.js";
9
+ import { n as downloadUrlFile, t as downloadTextFile } from "./download-DMmiy1xf.js";
10
+ import { t as ExportDialog } from "./export-dialog-D88ze9Gy.js";
11
+ import { t as getClaudeCodeAssistantMessagePhase } from "./claude-code-transcript-phase-DmUMc8VU.js";
12
+ import { t as getThreadTranscriptStats } from "./thread-transcript-stats-Dh34mt2u.js";
13
+ import { useMemo, useState } from "react";
14
+ import { Link } from "@tanstack/react-router";
15
+ import { jsx, jsxs } from "react/jsx-runtime";
16
+ import { useMutation, useSuspenseQuery } from "@tanstack/react-query";
17
+ import { Download } from "lucide-react";
18
+ //#region src/lib/claude-code-transcript-events.ts
19
+ var buildRaw = (entry, part, eventType) => ({
20
+ entryId: entry.entryId,
21
+ eventType,
22
+ role: entry.role,
23
+ source: "claude_code_local_jsonl",
24
+ type: part.type,
25
+ ...part.raw
26
+ });
27
+ var buildMessageEvent = (entry, part, sequence, text) => ({
28
+ isHiddenByDefault: entry.role !== "assistant" && entry.role !== "user",
29
+ kind: "message",
30
+ memoryCitation: null,
31
+ model: entry.model ?? null,
32
+ phase: getClaudeCodeAssistantMessagePhase(entry),
33
+ raw: buildRaw(entry, part, "message"),
34
+ role: entry.role,
35
+ sequence,
36
+ text,
37
+ timestamp: entry.timestamp,
38
+ variant: entry.role === "user" ? "user_message" : entry.role === "assistant" ? "agent_message" : "message"
39
+ });
40
+ var buildReasoningEvent = (entry, part, sequence) => {
41
+ const text = part.text?.trim();
42
+ if (!text) return null;
43
+ return {
44
+ content: text,
45
+ hasEncryptedContent: false,
46
+ kind: "reasoning",
47
+ raw: buildRaw(entry, part, "reasoning"),
48
+ sequence,
49
+ summary: [text],
50
+ timestamp: entry.timestamp
51
+ };
52
+ };
53
+ var buildToolCallCommand = (part) => {
54
+ const toolName = part.toolName ?? "unknown";
55
+ if (!part.argumentsText?.trim()) return toolName;
56
+ return `${toolName}\n${part.argumentsText}`;
57
+ };
58
+ var buildToolCallEvent = (entry, part, sequence) => ({
59
+ argumentsParseFailed: false,
60
+ argumentsText: part.argumentsText ?? null,
61
+ callId: part.toolUseId ?? null,
62
+ command: buildToolCallCommand(part),
63
+ kind: "tool_call",
64
+ name: part.toolName ?? "unknown",
65
+ raw: buildRaw(entry, part, "tool_call"),
66
+ sequence,
67
+ timestamp: entry.timestamp,
68
+ workdir: entry.cwd
69
+ });
70
+ var buildToolOutputEvent = (entry, part, sequence) => {
71
+ const outputText = part.outputText?.trim();
72
+ if (!outputText) return null;
73
+ return {
74
+ callId: part.toolUseId ?? null,
75
+ exitCode: part.isError ? 1 : null,
76
+ kind: "tool_output",
77
+ outputText,
78
+ raw: buildRaw(entry, part, "tool_output"),
79
+ sequence,
80
+ summary: outputText,
81
+ timestamp: entry.timestamp,
82
+ wallTime: null
83
+ };
84
+ };
85
+ var partToEvents = (entry, part, sequence) => {
86
+ if (part.type === "text" || part.type === "attachment") {
87
+ const text = part.text?.trim();
88
+ return text ? [buildMessageEvent(entry, part, sequence, text)] : [];
89
+ }
90
+ if (part.type === "thinking") {
91
+ const event = buildReasoningEvent(entry, part, sequence);
92
+ return event ? [event] : [];
93
+ }
94
+ if (part.type === "tool_use") return [buildToolCallEvent(entry, part, sequence)];
95
+ if (part.type === "tool_result") {
96
+ const event = buildToolOutputEvent(entry, part, sequence);
97
+ return event ? [event] : [];
98
+ }
99
+ return [];
100
+ };
101
+ var claudeCodeTranscriptToThreadEvents = (transcript) => {
102
+ const events = [];
103
+ let sequence = 0;
104
+ for (const entry of transcript.entries) for (const part of entry.parts) {
105
+ events.push(...partToEvents(entry, part, sequence));
106
+ sequence += 1;
107
+ }
108
+ return events;
109
+ };
110
+ var getClaudeCodeThreadTranscriptStats = (events) => {
111
+ return getThreadTranscriptStats(events);
112
+ };
113
+ //#endregion
114
+ //#region src/routes/claude-code-sessions.$sessionId.tsx?tsr-split=component
115
+ var buildSessionMetadata = (detail) => [
116
+ {
117
+ label: "Session ID",
118
+ value: /* @__PURE__ */ jsx("span", {
119
+ "data-mono": "true",
120
+ children: detail.session.sessionId
121
+ })
122
+ },
123
+ {
124
+ label: "Workspace",
125
+ value: /* @__PURE__ */ jsx(Link, {
126
+ className: "text-[var(--accent)]",
127
+ params: { workspaceKey: detail.session.workspaceKey },
128
+ to: "/claude-code/$workspaceKey",
129
+ children: detail.session.workspaceLabel
130
+ })
131
+ },
132
+ {
133
+ label: "Worktree",
134
+ value: detail.session.worktree
135
+ },
136
+ {
137
+ label: "CWD",
138
+ value: detail.session.cwd
139
+ },
140
+ {
141
+ label: "Model",
142
+ value: detail.session.model ?? "unknown"
143
+ },
144
+ {
145
+ label: "Version",
146
+ value: detail.session.version ?? "unknown"
147
+ },
148
+ {
149
+ label: "Git branch",
150
+ value: detail.session.gitBranch ?? "unknown"
151
+ },
152
+ {
153
+ label: "Created",
154
+ value: /* @__PURE__ */ jsx("span", {
155
+ suppressHydrationWarning: true,
156
+ children: formatDateTime(detail.session.createdAtMs)
157
+ })
158
+ },
159
+ {
160
+ label: "Last active",
161
+ value: /* @__PURE__ */ jsx("span", {
162
+ suppressHydrationWarning: true,
163
+ children: formatDateTime(detail.session.lastActiveAtMs)
164
+ })
165
+ },
166
+ {
167
+ label: "Source file",
168
+ value: detail.session.filePath
169
+ }
170
+ ];
171
+ var buildTranscriptStatsItems = (detail, events, stats) => [
172
+ {
173
+ label: "Event kinds",
174
+ value: formatList([...new Set(events.map((event) => event.kind))])
175
+ },
176
+ {
177
+ label: "Messages",
178
+ value: formatNumber(stats.messageCount)
179
+ },
180
+ {
181
+ label: "User messages",
182
+ value: formatNumber(stats.userMessageCount)
183
+ },
184
+ {
185
+ label: "Assistant messages",
186
+ value: formatNumber(stats.assistantMessageCount)
187
+ },
188
+ {
189
+ label: "Reasoning events",
190
+ value: formatNumber(events.filter((event) => event.kind === "reasoning").length)
191
+ },
192
+ {
193
+ label: "Final answers",
194
+ value: formatNumber(stats.finalAnswerCount)
195
+ },
196
+ {
197
+ label: "Tool calls",
198
+ value: formatNumber(stats.toolCallCount)
199
+ },
200
+ {
201
+ label: "Tool outputs",
202
+ value: formatNumber(stats.toolOutputCount)
203
+ },
204
+ {
205
+ label: "Attachments",
206
+ value: formatNumber(detail.session.attachmentCount)
207
+ },
208
+ {
209
+ label: "Renderable parts",
210
+ value: formatNumber(detail.renderablePartCount)
211
+ }
212
+ ];
213
+ var ClaudeCodeTranscriptControls = ({ rawJsonDisabled = false, showCommentary, showExtraEvents, showRawJson, showToolCalls, showUserMessages, onShowCommentaryChange, onShowExtraEventsChange, onShowRawJsonChange, onShowToolCallsChange, onShowUserMessagesChange }) => {
214
+ return /* @__PURE__ */ jsxs("div", {
215
+ className: "flex flex-wrap gap-4 rounded-xl border border-[var(--border)] bg-[var(--panel)] px-4 py-3 shadow-[var(--panel-shadow)]",
216
+ children: [
217
+ /* @__PURE__ */ jsxs("div", {
218
+ className: "flex items-center gap-2 text-sm",
219
+ children: [/* @__PURE__ */ jsx(Checkbox, {
220
+ checked: showToolCalls,
221
+ id: "claude-code-transcript-show-tool-calls",
222
+ onCheckedChange: (checked) => onShowToolCallsChange(checked === true)
223
+ }), /* @__PURE__ */ jsx("label", {
224
+ htmlFor: "claude-code-transcript-show-tool-calls",
225
+ children: "Show tool calls"
226
+ })]
227
+ }),
228
+ /* @__PURE__ */ jsxs("div", {
229
+ className: "flex items-center gap-2 text-sm",
230
+ children: [/* @__PURE__ */ jsx(Checkbox, {
231
+ checked: showCommentary,
232
+ id: "claude-code-transcript-show-commentary",
233
+ onCheckedChange: (checked) => onShowCommentaryChange(checked === true)
234
+ }), /* @__PURE__ */ jsx("label", {
235
+ htmlFor: "claude-code-transcript-show-commentary",
236
+ children: "Show commentary"
237
+ })]
238
+ }),
239
+ /* @__PURE__ */ jsxs("div", {
240
+ className: "flex items-center gap-2 text-sm",
241
+ children: [/* @__PURE__ */ jsx(Checkbox, {
242
+ checked: showExtraEvents,
243
+ id: "claude-code-transcript-show-extra-events",
244
+ onCheckedChange: (checked) => onShowExtraEventsChange(checked === true)
245
+ }), /* @__PURE__ */ jsx("label", {
246
+ htmlFor: "claude-code-transcript-show-extra-events",
247
+ children: "Show extra events"
248
+ })]
249
+ }),
250
+ /* @__PURE__ */ jsxs("div", {
251
+ className: "flex items-center gap-2 text-sm",
252
+ children: [/* @__PURE__ */ jsx(Checkbox, {
253
+ checked: showRawJson,
254
+ disabled: rawJsonDisabled,
255
+ id: "claude-code-transcript-show-raw-json",
256
+ onCheckedChange: (checked) => onShowRawJsonChange(checked === true)
257
+ }), /* @__PURE__ */ jsx("label", {
258
+ htmlFor: "claude-code-transcript-show-raw-json",
259
+ children: "Raw JSON"
260
+ })]
261
+ }),
262
+ /* @__PURE__ */ jsxs("div", {
263
+ className: "flex items-center gap-2 text-sm",
264
+ children: [/* @__PURE__ */ jsx(Checkbox, {
265
+ checked: showUserMessages,
266
+ id: "claude-code-transcript-show-user-messages",
267
+ onCheckedChange: (checked) => onShowUserMessagesChange(checked === true)
268
+ }), /* @__PURE__ */ jsx("label", {
269
+ htmlFor: "claude-code-transcript-show-user-messages",
270
+ children: "User"
271
+ })]
272
+ })
273
+ ]
274
+ });
275
+ };
276
+ function ClaudeCodeRawPanels({ detail, events }) {
277
+ return /* @__PURE__ */ jsxs("div", {
278
+ className: "space-y-4",
279
+ children: [
280
+ /* @__PURE__ */ jsx(JsonPanel, {
281
+ title: "Session summary",
282
+ value: detail.session
283
+ }),
284
+ /* @__PURE__ */ jsx(JsonPanel, {
285
+ title: "Claude Code entries",
286
+ value: detail.entries
287
+ }),
288
+ /* @__PURE__ */ jsx(JsonPanel, {
289
+ title: "Raw JSONL events",
290
+ value: detail.rawEvents
291
+ }),
292
+ /* @__PURE__ */ jsx(JsonPanel, {
293
+ title: "Transcript events",
294
+ value: events
295
+ })
296
+ ]
297
+ });
298
+ }
299
+ function ClaudeCodeSessionDetailPage() {
300
+ const detail = useSuspenseQuery(claudeCodeSessionDetailQueryOptions(Route.useParams().sessionId)).data;
301
+ const [pendingExport, setPendingExport] = useState(false);
302
+ const [showToolCalls, setShowToolCalls] = useState(false);
303
+ const [showCommentary, setShowCommentary] = useState(false);
304
+ const [showExtraEvents, setShowExtraEvents] = useState(false);
305
+ const [showRawJson, setShowRawJson] = useState(false);
306
+ const [showUserMessages, setShowUserMessages] = useState(true);
307
+ const transcriptEvents = useMemo(() => claudeCodeTranscriptToThreadEvents(detail), [detail]);
308
+ const transcriptStats = useMemo(() => getClaudeCodeThreadTranscriptStats(transcriptEvents), [transcriptEvents]);
309
+ const exportSessionMutation = useMutation({
310
+ mutationFn: async (options) => {
311
+ const download = await exportClaudeCodeSessionFn({ data: {
312
+ includeCommentary: options.includeCommentary,
313
+ includeMetadata: options.includeMetadata,
314
+ includeTools: options.includeTools,
315
+ outputFormat: options.outputFormat,
316
+ sessionId: detail.session.sessionId,
317
+ zipArchive: options.zipArchive
318
+ } });
319
+ if (download.mode === "download") {
320
+ downloadTextFile(download.fileName, download.content, download.mimeType);
321
+ return;
322
+ }
323
+ await downloadUrlFile(download.fileName, download.downloadUrl);
324
+ },
325
+ onSuccess: () => {
326
+ setPendingExport(false);
327
+ }
328
+ });
329
+ return /* @__PURE__ */ jsxs("div", {
330
+ className: "space-y-6",
331
+ children: [
332
+ /* @__PURE__ */ jsx(PageHeader, {
333
+ actions: /* @__PURE__ */ jsxs(Button, {
334
+ className: "rounded-full",
335
+ type: "button",
336
+ variant: "outline",
337
+ onClick: () => setPendingExport(true),
338
+ children: [/* @__PURE__ */ jsx(Download, { className: "mr-2 size-4" }), "Export"]
339
+ }),
340
+ breadcrumb: /* @__PURE__ */ jsx(Breadcrumbs, { items: [
341
+ {
342
+ label: "Claude Code",
343
+ to: "/claude-code"
344
+ },
345
+ {
346
+ label: detail.session.workspaceLabel,
347
+ params: { workspaceKey: detail.session.workspaceKey },
348
+ to: "/claude-code/$workspaceKey"
349
+ },
350
+ { label: detail.session.title }
351
+ ] }),
352
+ eyebrow: "Claude Code session",
353
+ subtitle: "Session detail for the selected Claude Code project conversation.",
354
+ title: detail.session.title
355
+ }),
356
+ /* @__PURE__ */ jsxs("div", {
357
+ className: "grid gap-3 md:grid-cols-2 xl:grid-cols-4",
358
+ children: [
359
+ /* @__PURE__ */ jsx(MetricCard, {
360
+ label: "Messages",
361
+ value: formatNumber(detail.session.messageCount)
362
+ }),
363
+ /* @__PURE__ */ jsx(MetricCard, {
364
+ label: "Tool calls",
365
+ value: formatNumber(detail.session.toolCallCount)
366
+ }),
367
+ /* @__PURE__ */ jsx(MetricCard, {
368
+ label: "Tool outputs",
369
+ value: formatNumber(detail.session.toolResultCount)
370
+ }),
371
+ /* @__PURE__ */ jsx(MetricCard, {
372
+ label: "Tokens",
373
+ value: formatTokens(detail.session.totalTokens)
374
+ })
375
+ ]
376
+ }),
377
+ /* @__PURE__ */ jsxs(Tabs, {
378
+ className: "space-y-4",
379
+ defaultValue: "transcript",
380
+ children: [
381
+ /* @__PURE__ */ jsxs(TabsList, {
382
+ className: "grid w-fit min-w-[24rem] grid-cols-3 rounded-full border border-[var(--border)] bg-[var(--panel)] p-1",
383
+ children: [
384
+ /* @__PURE__ */ jsx(TabsTrigger, {
385
+ className: "rounded-full px-5 text-sm",
386
+ value: "transcript",
387
+ children: "Transcript"
388
+ }),
389
+ /* @__PURE__ */ jsx(TabsTrigger, {
390
+ className: "rounded-full px-5 text-sm",
391
+ value: "metadata",
392
+ children: "Metadata"
393
+ }),
394
+ /* @__PURE__ */ jsx(TabsTrigger, {
395
+ className: "rounded-full px-5 text-sm",
396
+ value: "raw",
397
+ children: "Raw"
398
+ })
399
+ ]
400
+ }),
401
+ /* @__PURE__ */ jsxs(TabsContent, {
402
+ className: "space-y-3",
403
+ value: "transcript",
404
+ children: [/* @__PURE__ */ jsx(ClaudeCodeTranscriptControls, {
405
+ rawJsonDisabled: transcriptEvents.length === 0,
406
+ showCommentary,
407
+ showExtraEvents,
408
+ showRawJson,
409
+ showToolCalls,
410
+ showUserMessages,
411
+ onShowCommentaryChange: setShowCommentary,
412
+ onShowExtraEventsChange: setShowExtraEvents,
413
+ onShowRawJsonChange: setShowRawJson,
414
+ onShowToolCallsChange: setShowToolCalls,
415
+ onShowUserMessagesChange: setShowUserMessages
416
+ }), transcriptEvents.length > 0 ? /* @__PURE__ */ jsx(TranscriptView, {
417
+ assistantModel: detail.session.model,
418
+ events: transcriptEvents,
419
+ projectPath: detail.session.worktree,
420
+ showCommentary,
421
+ showExtraEvents,
422
+ showRawJson,
423
+ showToolCalls,
424
+ showUserMessages
425
+ }) : /* @__PURE__ */ jsxs("section", {
426
+ className: "rounded-[1.6rem] border border-[var(--border)] bg-[var(--panel)] p-5 shadow-[var(--panel-shadow)]",
427
+ children: [/* @__PURE__ */ jsx("h3", {
428
+ className: "font-semibold text-[var(--muted-foreground)] text-sm uppercase tracking-[0.18em]",
429
+ children: "Transcript"
430
+ }), /* @__PURE__ */ jsx("p", {
431
+ className: "mt-4 text-[var(--muted-foreground)] text-sm",
432
+ children: "No renderable Claude Code transcript content was found for this session."
433
+ })]
434
+ })]
435
+ }),
436
+ /* @__PURE__ */ jsx(TabsContent, {
437
+ value: "metadata",
438
+ children: /* @__PURE__ */ jsxs("div", {
439
+ className: "grid gap-4 xl:grid-cols-[0.95fr_1.05fr]",
440
+ children: [/* @__PURE__ */ jsx(MetadataSection, {
441
+ items: buildSessionMetadata(detail),
442
+ title: "Session metadata"
443
+ }), /* @__PURE__ */ jsx(MetadataSection, {
444
+ items: buildTranscriptStatsItems(detail, transcriptEvents, transcriptStats),
445
+ title: "Transcript stats"
446
+ })]
447
+ })
448
+ }),
449
+ /* @__PURE__ */ jsx(TabsContent, {
450
+ value: "raw",
451
+ children: /* @__PURE__ */ jsx(ClaudeCodeRawPanels, {
452
+ detail,
453
+ events: transcriptEvents
454
+ })
455
+ })
456
+ ]
457
+ }),
458
+ /* @__PURE__ */ jsx(ExportDialog, {
459
+ errorMessage: exportSessionMutation.isError ? exportSessionMutation.error instanceof Error ? exportSessionMutation.error.message : "Export failed" : null,
460
+ open: pendingExport,
461
+ pending: exportSessionMutation.isPending,
462
+ title: `Export ${detail.session.title}`,
463
+ onExport: (options) => exportSessionMutation.mutate(options),
464
+ onOpenChange: (open) => {
465
+ setPendingExport(open);
466
+ if (!open) exportSessionMutation.reset();
467
+ }
468
+ })
469
+ ]
470
+ });
471
+ }
472
+ //#endregion
473
+ export { ClaudeCodeSessionDetailPage as component };
@@ -0,0 +1,11 @@
1
+ import { t as ReloadErrorPanel } from "./reload-error-panel-BJMxY3U1.js";
2
+ import { jsx } from "react/jsx-runtime";
3
+ //#region src/routes/claude-code-sessions.$sessionId.tsx?tsr-split=errorComponent
4
+ function ClaudeCodeSessionDetailErrorComponent({ error }) {
5
+ return /* @__PURE__ */ jsx(ReloadErrorPanel, {
6
+ description: error.message,
7
+ title: "Failed to load Claude Code session"
8
+ });
9
+ }
10
+ //#endregion
11
+ export { ClaudeCodeSessionDetailErrorComponent as errorComponent };
@@ -0,0 +1,139 @@
1
+ import { a as cleanExtractedText, g as renderSection, h as renderMetadataBlock, l as formatInlineLiteral, m as renderDocumentTitle, o as cleanInlineTitle, p as renderCodeBlock } from "./shared-DyhChtHf.js";
2
+ import { t as getClaudeCodeAssistantMessagePhase } from "./claude-code-transcript-phase-DmUMc8VU.js";
3
+ //#region ../../src/lib/claude-code-transcript.ts
4
+ var TOOL_OUTPUT_PREVIEW_LIMIT = 4e3;
5
+ var getSessionTitle = (session) => {
6
+ return cleanInlineTitle(session.title || session.sessionId);
7
+ };
8
+ var buildMetadataEntries = (session) => [
9
+ {
10
+ key: "exported_from",
11
+ value: "claude_code_local_jsonl"
12
+ },
13
+ {
14
+ key: "session_id",
15
+ value: session.sessionId
16
+ },
17
+ {
18
+ key: "title",
19
+ value: session.title
20
+ },
21
+ {
22
+ key: "source_transcript_path",
23
+ value: session.filePath
24
+ },
25
+ {
26
+ key: "workspace_key",
27
+ value: session.workspaceKey
28
+ },
29
+ {
30
+ key: "worktree",
31
+ value: session.worktree
32
+ },
33
+ {
34
+ key: "cwd",
35
+ value: session.cwd
36
+ },
37
+ {
38
+ key: "model",
39
+ value: session.model
40
+ },
41
+ {
42
+ key: "version",
43
+ value: session.version
44
+ },
45
+ {
46
+ key: "git_branch",
47
+ value: session.gitBranch
48
+ },
49
+ {
50
+ key: "created_at_iso",
51
+ value: session.createdAtIso
52
+ },
53
+ {
54
+ key: "last_active_at_iso",
55
+ value: session.lastActiveAtIso
56
+ },
57
+ {
58
+ key: "message_count",
59
+ value: session.messageCount
60
+ },
61
+ {
62
+ key: "tool_call_count",
63
+ value: session.toolCallCount
64
+ },
65
+ {
66
+ key: "tool_result_count",
67
+ value: session.toolResultCount
68
+ },
69
+ {
70
+ key: "total_tokens",
71
+ value: session.totalTokens
72
+ }
73
+ ];
74
+ var roleTitle = (role) => {
75
+ if (role === "assistant") return "Assistant";
76
+ if (role === "user") return "User";
77
+ if (role === "system") return "System";
78
+ return role ? cleanInlineTitle(role) : "Message";
79
+ };
80
+ var truncateOutput = (text) => {
81
+ if (text.length <= TOOL_OUTPUT_PREVIEW_LIMIT) return text;
82
+ return `${text.slice(0, TOOL_OUTPUT_PREVIEW_LIMIT)}\n... (truncated)`;
83
+ };
84
+ var renderTextPart = (part, role, options) => {
85
+ const text = cleanExtractedText(part.text ?? "").trim();
86
+ return text ? renderSection(roleTitle(role), text, options.outputFormat) : "";
87
+ };
88
+ var renderThinkingPart = (part, options) => {
89
+ if (!options.includeCommentary) return "";
90
+ const text = cleanExtractedText(part.text ?? "").trim();
91
+ return text ? renderSection("Reasoning", text, options.outputFormat) : "";
92
+ };
93
+ var renderToolUsePart = (part, options) => {
94
+ if (!options.includeTools) return "";
95
+ const lines = [`Tool: ${formatInlineLiteral(part.toolName ?? "unknown", options.outputFormat)}`];
96
+ if (part.toolUseId) lines.push(`Call ID: ${part.toolUseId}`);
97
+ if (part.argumentsText?.trim()) lines.push("", "Input:", "", renderCodeBlock(part.argumentsText.trim(), options.outputFormat));
98
+ return renderSection("Tool Call", lines.join("\n"), options.outputFormat);
99
+ };
100
+ var renderToolResultPart = (part, options) => {
101
+ if (!options.includeTools) return "";
102
+ const outputText = part.outputText?.trim();
103
+ if (!outputText) return "";
104
+ const lines = [];
105
+ if (part.isError) lines.push("Error: true", "");
106
+ if (part.toolUseId) lines.push(`Call ID: ${part.toolUseId}`, "");
107
+ lines.push(renderCodeBlock(truncateOutput(outputText), options.outputFormat));
108
+ return renderSection("Tool Output", lines.join("\n"), options.outputFormat);
109
+ };
110
+ var renderAttachmentPart = (part, options) => {
111
+ if (!options.includeCommentary) return "";
112
+ const text = cleanExtractedText(part.text ?? "").trim();
113
+ if (!text) return "";
114
+ return renderSection(part.attachmentType ? `Attachment: ${part.attachmentType}` : "Attachment", text, options.outputFormat);
115
+ };
116
+ var renderPart = (entry, part, options) => {
117
+ switch (part.type) {
118
+ case "text":
119
+ if (getClaudeCodeAssistantMessagePhase(entry) === "commentary" && !options.includeCommentary) return "";
120
+ return renderTextPart(part, entry.role, options);
121
+ case "thinking": return renderThinkingPart(part, options);
122
+ case "tool_use": return renderToolUsePart(part, options);
123
+ case "tool_result": return renderToolResultPart(part, options);
124
+ case "attachment": return renderAttachmentPart(part, options);
125
+ case "unknown": return "";
126
+ }
127
+ };
128
+ var renderClaudeCodeTranscript = (transcript, options) => {
129
+ const sections = transcript.entries.flatMap((entry) => entry.parts.map((part) => renderPart(entry, part, options)).filter(Boolean));
130
+ if (sections.length === 0) return null;
131
+ return `${[
132
+ renderDocumentTitle(getSessionTitle(transcript.session), options.outputFormat),
133
+ "",
134
+ options.includeMetadata ? renderMetadataBlock(buildMetadataEntries(transcript.session), options.outputFormat) : "",
135
+ ...sections
136
+ ].filter(Boolean).join("\n").trimEnd()}\n`;
137
+ };
138
+ //#endregion
139
+ export { renderClaudeCodeTranscript };
@@ -0,0 +1,10 @@
1
+ //#region ../../src/lib/claude-code-transcript-phase.ts
2
+ var asMessageObject = (value) => {
3
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
4
+ };
5
+ var getClaudeCodeAssistantMessagePhase = (entry) => {
6
+ if (entry.role !== "assistant") return null;
7
+ return asMessageObject(entry.raw.message)?.stop_reason === "tool_use" ? "commentary" : "final_answer";
8
+ };
9
+ //#endregion
10
+ export { getClaudeCodeAssistantMessagePhase as t };
@@ -0,0 +1,28 @@
1
+ import { n as claudeCodeSessionsQueryOptions, r as claudeCodeWorkspacesQueryOptions } from "./claude-code-queries-Cgzi4K-e.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/claude-code.$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(`Claude Code workspace not found: ${workspaceKey}`);
9
+ return workspace;
10
+ };
11
+ //#endregion
12
+ //#region src/routes/claude-code.$workspaceKey.tsx
13
+ var $$splitErrorComponentImporter = () => import("./claude-code._workspaceKey-BPlzyXPa.js");
14
+ var $$splitComponentImporter = () => import("./claude-code._workspaceKey-DqDve2wl.js");
15
+ var Route = createFileRoute("/claude-code/$workspaceKey")({
16
+ component: lazyRouteComponent($$splitComponentImporter, "component"),
17
+ errorComponent: lazyRouteComponent($$splitErrorComponentImporter, "errorComponent"),
18
+ loader: async ({ context, params }) => {
19
+ findWorkspaceOrThrow(await context.queryClient.ensureQueryData(claudeCodeWorkspacesQueryOptions()), params.workspaceKey);
20
+ await context.queryClient.ensureQueryData(claudeCodeSessionsQueryOptions(params.workspaceKey));
21
+ },
22
+ pendingComponent: () => /* @__PURE__ */ jsx(LoadingPanel, {
23
+ description: "Loading Claude Code sessions and transcript metadata.",
24
+ title: "Loading workspace"
25
+ })
26
+ });
27
+ //#endregion
28
+ export { findWorkspaceOrThrow as n, Route as t };
@@ -0,0 +1,11 @@
1
+ import { t as ReloadErrorPanel } from "./reload-error-panel-BJMxY3U1.js";
2
+ import { jsx } from "react/jsx-runtime";
3
+ //#region src/routes/claude-code.$workspaceKey.tsx?tsr-split=errorComponent
4
+ function ClaudeCodeWorkspaceErrorComponent({ error }) {
5
+ return /* @__PURE__ */ jsx(ReloadErrorPanel, {
6
+ description: error.message,
7
+ title: "Failed to load Claude Code workspace"
8
+ });
9
+ }
10
+ //#endregion
11
+ export { ClaudeCodeWorkspaceErrorComponent as errorComponent };