@opengeni/react 0.29.0 → 0.32.1

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 (207) hide show
  1. package/dist/approvals.d.ts +14 -0
  2. package/dist/{chunk-M7X4JZOD.js → chunk-4QOQ2DSR.js} +8 -1
  3. package/dist/chunk-4QOQ2DSR.js.map +1 -0
  4. package/dist/{chunk-HQFPO7VX.js → chunk-7CJOAW3V.js} +24 -3
  5. package/dist/{chunk-HQFPO7VX.js.map → chunk-7CJOAW3V.js.map} +1 -1
  6. package/dist/{chunk-CSJBF3QJ.js → chunk-A2WITZTI.js} +377 -113
  7. package/dist/chunk-A2WITZTI.js.map +1 -0
  8. package/dist/{chunk-BC6RKIHS.js → chunk-GZ4KR67U.js} +11 -11
  9. package/dist/{chunk-AVLMIWYO.js → chunk-KZRUYCL4.js} +12 -6
  10. package/dist/chunk-KZRUYCL4.js.map +1 -0
  11. package/dist/{chunk-OKXCECLG.js → chunk-TCCE5ZU5.js} +171 -22
  12. package/dist/chunk-TCCE5ZU5.js.map +1 -0
  13. package/dist/chunk-U255M5EZ.js +178 -0
  14. package/dist/chunk-U255M5EZ.js.map +1 -0
  15. package/dist/{chunk-IPVOVOW6.js → chunk-WY2QN2CX.js} +2539 -2174
  16. package/dist/chunk-WY2QN2CX.js.map +1 -0
  17. package/dist/chunk-ZNNE2VES.js +6413 -0
  18. package/dist/chunk-ZNNE2VES.js.map +1 -0
  19. package/dist/client.d.ts +33 -0
  20. package/dist/commands/index.d.ts +3 -0
  21. package/dist/commands/registry.d.ts +41 -0
  22. package/dist/commands/types.d.ts +85 -0
  23. package/dist/components/approval-surface.d.ts +28 -0
  24. package/dist/components/chat-composer.d.ts +51 -0
  25. package/dist/components/code-editor.d.ts +43 -0
  26. package/dist/components/command-palette.d.ts +25 -0
  27. package/dist/components/composer-transcription-control.d.ts +36 -0
  28. package/dist/components/composer.d.ts +277 -0
  29. package/dist/components/copy-button.d.ts +26 -0
  30. package/dist/components/desktop-viewer.d.ts +85 -0
  31. package/dist/components/diff-view.d.ts +38 -0
  32. package/dist/components/enrollment-consent.d.ts +33 -0
  33. package/dist/components/enrollment-device-flow.d.ts +27 -0
  34. package/dist/components/file-browser.d.ts +47 -0
  35. package/dist/components/fleet-tile.d.ts +18 -0
  36. package/dist/components/human-input-form.d.ts +47 -0
  37. package/dist/components/machine-card.d.ts +21 -0
  38. package/dist/components/machine-dock-bar.d.ts +31 -0
  39. package/dist/components/machine-health-pill.d.ts +9 -0
  40. package/dist/components/machine-metrics.d.ts +15 -0
  41. package/dist/components/machine-status-pill.d.ts +54 -0
  42. package/dist/components/machines/health.d.ts +25 -0
  43. package/dist/components/machines/machine-detail.d.ts +14 -0
  44. package/dist/components/machines/metric-history-chart.d.ts +24 -0
  45. package/dist/components/machines/metric-sparkline.d.ts +9 -0
  46. package/dist/components/machines/series.d.ts +24 -0
  47. package/dist/components/machines-dashboard.d.ts +30 -0
  48. package/dist/components/markdown.d.ts +31 -0
  49. package/dist/components/message-timeline.d.ts +98 -0
  50. package/dist/components/model-picker.d.ts +19 -0
  51. package/dist/components/pierre-diff.d.ts +34 -0
  52. package/dist/components/pierre-file.d.ts +27 -0
  53. package/dist/components/queue-draft-policy.d.ts +7 -0
  54. package/dist/components/queue-surface-implementation.d.ts +20 -0
  55. package/dist/components/queue-surface-state.d.ts +12 -0
  56. package/dist/components/queue-surface.d.ts +12 -0
  57. package/dist/components/sandbox-files.d.ts +49 -0
  58. package/dist/components/sandbox-terminal.d.ts +123 -0
  59. package/dist/components/sandbox-workspace.d.ts +128 -0
  60. package/dist/components/session-chrome.d.ts +70 -0
  61. package/dist/components/session-status.d.ts +25 -0
  62. package/dist/components/soften-streaming-markdown.d.ts +13 -0
  63. package/dist/components/stream-reveal.d.ts +37 -0
  64. package/dist/components/tip-follow.d.ts +139 -0
  65. package/dist/components/tooltip.d.ts +16 -0
  66. package/dist/components/workbench-changes.d.ts +34 -0
  67. package/dist/components/workspace-dock.d.ts +35 -0
  68. package/dist/composer.d.ts +11 -7
  69. package/dist/composer.js +9 -6
  70. package/dist/hooks/internal.d.ts +46 -0
  71. package/dist/hooks/use-available-models.d.ts +37 -0
  72. package/dist/hooks/use-billing-usage.d.ts +26 -0
  73. package/dist/hooks/use-codex-accounts.d.ts +69 -0
  74. package/dist/{use-composer-ClHy1rkL.d.ts → hooks/use-composer.d.ts} +16 -24
  75. package/dist/hooks/use-desktop-stream.d.ts +43 -0
  76. package/dist/hooks/use-environments.d.ts +35 -0
  77. package/dist/{use-file-attachments-BmT8WtqO.d.ts → hooks/use-file-attachments.d.ts} +6 -9
  78. package/dist/hooks/use-goal.d.ts +46 -0
  79. package/dist/hooks/use-human-input.d.ts +26 -0
  80. package/dist/hooks/use-last-started-turn-policy.d.ts +27 -0
  81. package/dist/hooks/use-machine-chip.d.ts +54 -0
  82. package/dist/hooks/use-machines.d.ts +81 -0
  83. package/dist/hooks/use-packs.d.ts +27 -0
  84. package/dist/hooks/use-relay-frame-stream.d.ts +53 -0
  85. package/dist/hooks/use-rigs.d.ts +87 -0
  86. package/dist/hooks/use-sandbox-files.d.ts +108 -0
  87. package/dist/hooks/use-sandbox-git.d.ts +58 -0
  88. package/dist/hooks/use-sandbox-terminal.d.ts +62 -0
  89. package/dist/hooks/use-scheduled-tasks.d.ts +15 -0
  90. package/dist/hooks/use-session-capabilities.d.ts +83 -0
  91. package/dist/hooks/use-session-control.d.ts +22 -0
  92. package/dist/hooks/use-session-events.d.ts +92 -0
  93. package/dist/hooks/use-session-lineage.d.ts +17 -0
  94. package/dist/hooks/use-session-mcp-approval-policy.d.ts +23 -0
  95. package/dist/hooks/use-session.d.ts +23 -0
  96. package/dist/hooks/use-slash-commands.d.ts +66 -0
  97. package/dist/hooks/use-terminal-stream.d.ts +46 -0
  98. package/dist/hooks/use-transcription.d.ts +73 -0
  99. package/dist/hooks/use-turn-queue.d.ts +44 -0
  100. package/dist/hooks/use-voice-input.d.ts +25 -0
  101. package/dist/hooks/use-windowed-sections.d.ts +42 -0
  102. package/dist/hooks/use-workspace-capture.d.ts +49 -0
  103. package/dist/hooks/use-workspace-edit.d.ts +73 -0
  104. package/dist/hooks/use-workspace-sessions.d.ts +30 -0
  105. package/dist/hooks/use-workspaces.d.ts +22 -0
  106. package/dist/human-input.d.ts +18 -0
  107. package/dist/index.d.ts +144 -2119
  108. package/dist/index.js +421 -324
  109. package/dist/index.js.map +1 -1
  110. package/dist/lib/clipboard.d.ts +7 -0
  111. package/dist/lib/cn.d.ts +3 -0
  112. package/dist/lib/format.d.ts +48 -0
  113. package/dist/lib/git-patch.d.ts +8 -0
  114. package/dist/lib/motion-inspect.d.ts +5 -0
  115. package/dist/lib/motion.d.ts +14 -0
  116. package/dist/lib/noto-sans-arabic-loader.d.ts +1 -0
  117. package/dist/lib/noto-sans-jp-loader.generated.d.ts +1 -0
  118. package/dist/lib/relay-wire.d.ts +30 -0
  119. package/dist/lib/use-portal-token-style.d.ts +9 -0
  120. package/dist/lib/use-theme-type.d.ts +5 -0
  121. package/dist/lib/use-unicode-fonts.d.ts +12 -0
  122. package/dist/lib/xterm-renderer.d.ts +19 -0
  123. package/dist/lib/xterm-theme.d.ts +75 -0
  124. package/dist/machines.d.ts +30 -413
  125. package/dist/machines.js +3 -3
  126. package/dist/model-policy.d.ts +32 -0
  127. package/dist/model-policy.js +33 -0
  128. package/dist/model-policy.js.map +1 -0
  129. package/dist/provider.d.ts +16 -0
  130. package/dist/{queue-surface-implementation-UQ535OKQ.js → queue-surface-implementation-THPAKGMD.js} +2 -2
  131. package/dist/{queue-surface-implementation-UQ535OKQ.js.map → queue-surface-implementation-THPAKGMD.js.map} +1 -1
  132. package/dist/session-context.d.ts +82 -0
  133. package/dist/session-ui.d.ts +10 -7
  134. package/dist/session-ui.js +9 -5
  135. package/dist/session.d.ts +28 -6
  136. package/dist/session.js +11 -11
  137. package/dist/timeline/activity-rail.d.ts +19 -0
  138. package/dist/timeline/disclosure-context.d.ts +14 -0
  139. package/dist/timeline/entrance.d.ts +14 -0
  140. package/dist/timeline/fleet-decision-projection.d.ts +9 -0
  141. package/dist/timeline/fleet-decision-row.d.ts +11 -0
  142. package/dist/timeline/fold-memory.d.ts +15 -0
  143. package/dist/timeline/index.d.ts +18 -0
  144. package/dist/timeline/parsers.d.ts +96 -0
  145. package/dist/timeline/projection.d.ts +38 -0
  146. package/dist/timeline/registry.d.ts +40 -0
  147. package/dist/timeline/screenshot-lightbox.d.ts +26 -0
  148. package/dist/timeline/seen-activity-ids.d.ts +2 -0
  149. package/dist/timeline/shared.d.ts +125 -0
  150. package/dist/timeline/tool-diff.d.ts +8 -0
  151. package/dist/timeline/tool-display-name.d.ts +10 -0
  152. package/dist/timeline/tool-renderers.d.ts +5 -0
  153. package/dist/timeline/turn-summary.d.ts +116 -0
  154. package/dist/{use-turn-queue-D_1a8W_l.d.ts → timeline/types.d.ts} +41 -69
  155. package/dist/types/machines.d.ts +11 -0
  156. package/package.json +8 -4
  157. package/src/client.ts +1 -0
  158. package/src/components/composer-transcription-control.tsx +278 -130
  159. package/src/components/composer.tsx +20 -15
  160. package/src/components/copy-button.tsx +127 -0
  161. package/src/components/markdown.tsx +231 -32
  162. package/src/components/message-timeline.tsx +1304 -378
  163. package/src/components/model-picker.tsx +83 -43
  164. package/src/components/queue-surface-implementation.tsx +1 -1
  165. package/src/components/session-chrome.tsx +942 -0
  166. package/src/components/soften-streaming-markdown.ts +205 -0
  167. package/src/components/stream-reveal.ts +195 -0
  168. package/src/components/tip-follow.ts +459 -0
  169. package/src/components/tooltip.tsx +103 -0
  170. package/src/composer.ts +6 -0
  171. package/src/hooks/internal.ts +30 -4
  172. package/src/hooks/use-available-models.ts +51 -4
  173. package/src/hooks/use-composer.ts +23 -3
  174. package/src/hooks/use-last-started-turn-policy.ts +95 -0
  175. package/src/hooks/use-session-events.ts +359 -5
  176. package/src/hooks/use-voice-input.ts +232 -0
  177. package/src/index.ts +47 -1
  178. package/src/lib/clipboard.ts +58 -0
  179. package/src/lib/format.ts +18 -0
  180. package/src/lib/motion-inspect.ts +5 -0
  181. package/src/lib/motion.ts +80 -0
  182. package/src/model-policy.ts +210 -0
  183. package/src/session-ui.ts +7 -0
  184. package/src/timeline/activity-rail.tsx +46 -7
  185. package/src/timeline/entrance.tsx +10 -0
  186. package/src/timeline/fold-memory.ts +52 -0
  187. package/src/timeline/index.ts +9 -1
  188. package/src/timeline/projection.ts +226 -41
  189. package/src/timeline/seen-activity-ids.ts +19 -0
  190. package/src/timeline/shared.tsx +1 -1
  191. package/src/timeline/tool-renderers.tsx +75 -6
  192. package/src/timeline/turn-summary.tsx +387 -97
  193. package/src/timeline/types.ts +21 -0
  194. package/styles/index.css +99 -7
  195. package/styles/tokens.css +44 -3
  196. package/dist/chunk-AVLMIWYO.js.map +0 -1
  197. package/dist/chunk-CSJBF3QJ.js.map +0 -1
  198. package/dist/chunk-IPVOVOW6.js.map +0 -1
  199. package/dist/chunk-M7X4JZOD.js.map +0 -1
  200. package/dist/chunk-OKXCECLG.js.map +0 -1
  201. package/dist/chunk-ZMNPFZWL.js +0 -3918
  202. package/dist/chunk-ZMNPFZWL.js.map +0 -1
  203. package/dist/composer-BMzimGTO.d.ts +0 -528
  204. package/dist/session-DaONt-dY.d.ts +0 -264
  205. package/dist/session-context-CAjlaeZb.d.ts +0 -84
  206. package/dist/session-ui-B5_roA95.d.ts +0 -259
  207. /package/dist/{chunk-BC6RKIHS.js.map → chunk-GZ4KR67U.js.map} +0 -0
@@ -1,3918 +0,0 @@
1
- import {
2
- cn
3
- } from "./chunk-TK7G6XLT.js";
4
- import {
5
- buildTimeline,
6
- groupTimeline
7
- } from "./chunk-OKXCECLG.js";
8
- import {
9
- formatRelativeTime,
10
- stringifyPayload,
11
- truncate,
12
- tryParseJson
13
- } from "./chunk-M7X4JZOD.js";
14
- import {
15
- EmptyQueueStateSurface
16
- } from "./chunk-YDNWMKXO.js";
17
-
18
- // src/components/queue-surface.tsx
19
- import { Loader2Icon } from "lucide-react";
20
- import { lazy, Suspense } from "react";
21
- import { jsx, jsxs } from "react/jsx-runtime";
22
- var loadQueueSurface = () => import("./queue-surface-implementation-UQ535OKQ.js");
23
- var QueueSurface = createQueueSurface(loadQueueSurface);
24
- function createQueueSurface(loadImplementation) {
25
- const LazyQueueSurface = lazy(async () => ({
26
- default: (await loadImplementation()).QueueSurface
27
- }));
28
- return function QueueSurfaceBoundary(props) {
29
- const { queue } = props;
30
- if (queue.queue.length + queue.pendingInputs.length === 0) {
31
- if (!queue.stoppingPreviousAttempt && !queue.error && !queue.mutationError) return null;
32
- return /* @__PURE__ */ jsx(EmptyQueueStateSurface, { queue });
33
- }
34
- return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(QueueSurfaceFallback, {}), children: /* @__PURE__ */ jsx(LazyQueueSurface, { ...props }) });
35
- };
36
- }
37
- function QueueSurfaceFallback() {
38
- return /* @__PURE__ */ jsx(
39
- "div",
40
- {
41
- "aria-live": "polite",
42
- className: "mx-auto mb-2 w-full max-w-3xl shrink-0 px-4 sm:px-6",
43
- "data-testid": "queue-surface-loading",
44
- role: "status",
45
- children: /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-lg border border-border bg-surface/80 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-3 py-2 text-xs text-fg-muted pointer-coarse:min-h-[44px]", children: [
46
- /* @__PURE__ */ jsx(
47
- Loader2Icon,
48
- {
49
- "aria-hidden": "true",
50
- className: "size-3.5 shrink-0 animate-spin motion-reduce:animate-none"
51
- }
52
- ),
53
- "Loading inputs\u2026"
54
- ] }) })
55
- }
56
- );
57
- }
58
-
59
- // src/components/human-input-form.tsx
60
- import { useEffect, useId, useRef, useState } from "react";
61
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
62
- var defaultHumanInputFormMessages = {
63
- title: "Your input is needed",
64
- description: "The agent is paused until you answer these questions.",
65
- submit: "Continue",
66
- skip: "Skip",
67
- submitting: "Submitting\u2026",
68
- other: "Other",
69
- deadlineLabel: "Respond before",
70
- formatDeadline,
71
- required: "This question is required.",
72
- minLength: (count) => `Enter at least ${count} characters.`,
73
- maxLength: (count) => `Enter no more than ${count} characters.`,
74
- otherRequired: "Enter a value for Other.",
75
- minSelections: (count) => `Choose at least ${count} option${count === 1 ? "" : "s"}.`,
76
- maxSelections: (count) => `Choose no more than ${count} option${count === 1 ? "" : "s"}.`
77
- };
78
- function HumanInputForm({
79
- request,
80
- onSubmit,
81
- submitting = false,
82
- error,
83
- title,
84
- description,
85
- submitLabel,
86
- skipLabel,
87
- messages: messageOverrides,
88
- autoFocus = true,
89
- className
90
- }) {
91
- const messages = { ...defaultHumanInputFormMessages, ...messageOverrides };
92
- const resolvedTitle = title === void 0 ? messages.title : title;
93
- const resolvedDescription = description === void 0 ? messages.description : description;
94
- const resolvedSubmitLabel = submitLabel ?? messages.submit;
95
- const resolvedSkipLabel = skipLabel ?? messages.skip;
96
- const formId = useId();
97
- const [drafts, setDrafts] = useState(
98
- () => initialDrafts(request.questions)
99
- );
100
- const [validationErrors, setValidationErrors] = useState({});
101
- const [submissionError, setSubmissionError] = useState(null);
102
- const [submittingInternally, setSubmittingInternally] = useState(false);
103
- const submissionInFlight = useRef(false);
104
- const submissionGeneration = useRef(0);
105
- const busy = submitting || submittingInternally;
106
- useEffect(() => {
107
- submissionGeneration.current += 1;
108
- submissionInFlight.current = false;
109
- setDrafts(initialDrafts(request.questions));
110
- setValidationErrors({});
111
- setSubmissionError(null);
112
- setSubmittingInternally(false);
113
- }, [request.id, request.questions]);
114
- const update = (questionId, apply) => {
115
- setDrafts((current) => ({
116
- ...current,
117
- [questionId]: apply(current[questionId] ?? emptyDraft())
118
- }));
119
- setValidationErrors((current) => {
120
- if (!(questionId in current)) return current;
121
- const next = { ...current };
122
- delete next[questionId];
123
- return next;
124
- });
125
- };
126
- const submitResponse = async (response) => {
127
- if (busy || submissionInFlight.current) return;
128
- const generation = submissionGeneration.current;
129
- submissionInFlight.current = true;
130
- setSubmissionError(null);
131
- setSubmittingInternally(true);
132
- try {
133
- await onSubmit(response);
134
- } catch (cause) {
135
- if (generation === submissionGeneration.current) {
136
- setSubmissionError(cause instanceof Error ? cause.message : String(cause));
137
- }
138
- } finally {
139
- if (generation === submissionGeneration.current) {
140
- submissionInFlight.current = false;
141
- setSubmittingInternally(false);
142
- }
143
- }
144
- };
145
- const submit = async (event) => {
146
- event.preventDefault();
147
- const result = answersFromDrafts(request.questions, drafts, messages);
148
- if (Object.keys(result.errors).length > 0) {
149
- setValidationErrors(result.errors);
150
- return;
151
- }
152
- await submitResponse({ outcome: "answered", answers: result.answers });
153
- };
154
- return /* @__PURE__ */ jsxs2(
155
- "form",
156
- {
157
- "data-human-input-request": request.id,
158
- onSubmit: (event) => void submit(event),
159
- className: cn(
160
- "og-root flex w-full flex-col gap-5 rounded-og-lg border border-og-border bg-og-surface-1 p-5 shadow-og-sm",
161
- className
162
- ),
163
- children: [
164
- /* @__PURE__ */ jsxs2("header", { children: [
165
- /* @__PURE__ */ jsx2("h2", { className: "text-og-md font-semibold text-og-fg", children: resolvedTitle }),
166
- resolvedDescription ? /* @__PURE__ */ jsx2("div", { className: "mt-1 text-og-sm text-og-fg-muted", children: resolvedDescription }) : null,
167
- request.expiresAt ? /* @__PURE__ */ jsxs2("p", { className: "mt-1 text-og-xs text-og-fg-subtle", children: [
168
- messages.deadlineLabel,
169
- " ",
170
- /* @__PURE__ */ jsx2("time", { dateTime: request.expiresAt, children: messages.formatDeadline(request.expiresAt) })
171
- ] }) : null
172
- ] }),
173
- /* @__PURE__ */ jsx2("fieldset", { disabled: busy, className: "contents", children: request.questions.map((question, index) => {
174
- const draft = drafts[question.id] ?? emptyDraft();
175
- const fieldId = `${formId}-${index}`;
176
- const errorId = `${fieldId}-error`;
177
- const helpId = `${fieldId}-help`;
178
- const describedBy = [question.helpText ? helpId : null, validationErrors[question.id] ? errorId : null].filter(Boolean).join(" ") || void 0;
179
- return /* @__PURE__ */ jsxs2("div", { className: "flex flex-col gap-2", children: [
180
- /* @__PURE__ */ jsxs2(
181
- "label",
182
- {
183
- htmlFor: question.kind === "text" ? fieldId : void 0,
184
- className: "text-og-base font-medium text-og-fg",
185
- children: [
186
- question.label ?? question.prompt,
187
- question.required ? /* @__PURE__ */ jsx2("span", { "aria-hidden": true, className: "ml-1 text-og-status-failed", children: "*" }) : null
188
- ]
189
- }
190
- ),
191
- question.label ? /* @__PURE__ */ jsx2("p", { className: "text-og-sm text-og-fg-muted", children: question.prompt }) : null,
192
- question.helpText ? /* @__PURE__ */ jsx2("p", { id: helpId, className: "text-og-xs text-og-fg-subtle", children: question.helpText }) : null,
193
- question.kind === "text" ? /* @__PURE__ */ jsx2(
194
- "textarea",
195
- {
196
- id: fieldId,
197
- value: draft.values[0] ?? "",
198
- onChange: (event) => update(question.id, (current) => ({
199
- ...current,
200
- values: event.target.value ? [event.target.value] : []
201
- })),
202
- "aria-invalid": Boolean(validationErrors[question.id]),
203
- "aria-describedby": describedBy,
204
- autoFocus: autoFocus && index === 0,
205
- rows: 3,
206
- className: "min-h-20 w-full resize-y rounded-og-md border border-og-border bg-og-surface-2 px-3 py-2 text-og-base text-og-fg outline-none placeholder:text-og-fg-subtle focus:border-og-accent"
207
- }
208
- ) : /* @__PURE__ */ jsxs2(
209
- "div",
210
- {
211
- role: question.kind === "single_select" ? "radiogroup" : "group",
212
- "aria-describedby": describedBy,
213
- className: "flex flex-col gap-2",
214
- children: [
215
- question.options.map((option, optionIndex) => {
216
- const checked = draft.values.includes(option.id);
217
- return /* @__PURE__ */ jsxs2(
218
- "label",
219
- {
220
- className: "flex cursor-pointer items-start gap-2 rounded-og-md border border-og-border px-3 py-2 hover:bg-og-surface-2",
221
- children: [
222
- /* @__PURE__ */ jsx2(
223
- "input",
224
- {
225
- type: question.kind === "single_select" ? "radio" : "checkbox",
226
- name: question.kind === "single_select" ? fieldId : void 0,
227
- autoFocus: autoFocus && index === 0 && optionIndex === 0,
228
- checked,
229
- onChange: (event) => update(question.id, (current) => ({
230
- ...current,
231
- values: question.kind === "single_select" ? event.target.checked ? [option.id] : [] : event.target.checked ? [...current.values, option.id] : current.values.filter((value) => value !== option.id),
232
- ...question.kind === "single_select" && event.target.checked ? { otherSelected: false } : {}
233
- })),
234
- className: "mt-0.5 accent-og-accent"
235
- }
236
- ),
237
- /* @__PURE__ */ jsxs2("span", { className: "min-w-0", children: [
238
- /* @__PURE__ */ jsx2("span", { className: "block text-og-sm font-medium text-og-fg", children: option.label }),
239
- option.description ? /* @__PURE__ */ jsx2("span", { className: "block text-og-xs text-og-fg-muted", children: option.description }) : null
240
- ] })
241
- ]
242
- },
243
- option.id
244
- );
245
- }),
246
- question.allowOther ? /* @__PURE__ */ jsxs2("label", { className: "flex items-start gap-2 rounded-og-md border border-og-border px-3 py-2", children: [
247
- /* @__PURE__ */ jsx2(
248
- "input",
249
- {
250
- type: question.kind === "single_select" ? "radio" : "checkbox",
251
- name: question.kind === "single_select" ? fieldId : void 0,
252
- checked: draft.otherSelected,
253
- autoFocus: autoFocus && index === 0 && question.options.length === 0,
254
- onChange: (event) => update(question.id, (current) => ({
255
- ...current,
256
- otherSelected: event.target.checked,
257
- ...question.kind === "single_select" && event.target.checked ? { values: [] } : {}
258
- })),
259
- className: "mt-2 accent-og-accent"
260
- }
261
- ),
262
- /* @__PURE__ */ jsxs2("span", { className: "min-w-0 flex-1", children: [
263
- /* @__PURE__ */ jsx2("span", { className: "block text-og-sm font-medium text-og-fg", children: messages.other }),
264
- /* @__PURE__ */ jsx2(
265
- "input",
266
- {
267
- type: "text",
268
- value: draft.other,
269
- disabled: !draft.otherSelected || busy,
270
- onChange: (event) => update(question.id, (current) => ({
271
- ...current,
272
- other: event.target.value
273
- })),
274
- className: "mt-1 w-full rounded-og-sm border border-og-border bg-og-surface-2 px-2 py-1.5 text-og-sm text-og-fg outline-none focus:border-og-accent disabled:opacity-50"
275
- }
276
- )
277
- ] })
278
- ] }) : null
279
- ]
280
- }
281
- ),
282
- validationErrors[question.id] ? /* @__PURE__ */ jsx2("p", { id: errorId, role: "alert", className: "text-og-xs text-og-status-failed", children: validationErrors[question.id] }) : null
283
- ] }, question.id);
284
- }) }),
285
- error ?? submissionError ? /* @__PURE__ */ jsx2("p", { role: "alert", className: "text-og-sm text-og-status-failed", children: error ?? submissionError }) : null,
286
- /* @__PURE__ */ jsxs2("footer", { className: "flex items-center justify-end gap-2", children: [
287
- request.allowSkip ? /* @__PURE__ */ jsx2(
288
- "button",
289
- {
290
- type: "button",
291
- disabled: busy,
292
- onClick: () => void submitResponse({ outcome: "skipped" }),
293
- className: "rounded-og-md border border-og-border px-3 py-2 text-og-sm font-medium text-og-fg-muted hover:bg-og-surface-2 disabled:opacity-50",
294
- children: resolvedSkipLabel
295
- }
296
- ) : null,
297
- /* @__PURE__ */ jsx2(
298
- "button",
299
- {
300
- type: "submit",
301
- disabled: busy,
302
- className: "rounded-og-md bg-og-accent px-3 py-2 text-og-sm font-medium text-og-accent-fg hover:bg-og-accent-strong disabled:opacity-50",
303
- children: busy ? messages.submitting : resolvedSubmitLabel
304
- }
305
- )
306
- ] })
307
- ]
308
- }
309
- );
310
- }
311
- function answersFromDrafts(questions, drafts, messageOverrides = {}) {
312
- const messages = { ...defaultHumanInputFormMessages, ...messageOverrides };
313
- const answers = [];
314
- const errors = {};
315
- for (const question of questions) {
316
- const draft = drafts[question.id] ?? emptyDraft();
317
- const values = question.kind === "text" ? draft.values.filter(Boolean) : draft.values;
318
- const other = draft.otherSelected ? draft.other.trim() : "";
319
- const supplied = values.length + (other ? 1 : 0);
320
- if (question.required && supplied === 0) {
321
- errors[question.id] = messages.required;
322
- continue;
323
- }
324
- if (question.kind === "text") {
325
- const value = values[0] ?? "";
326
- if (value && question.validation?.minLength != null && value.length < question.validation.minLength) {
327
- errors[question.id] = messages.minLength(question.validation.minLength);
328
- continue;
329
- }
330
- if (question.validation?.maxLength != null && value.length > question.validation.maxLength) {
331
- errors[question.id] = messages.maxLength(question.validation.maxLength);
332
- continue;
333
- }
334
- } else {
335
- if (draft.otherSelected && !other) {
336
- errors[question.id] = messages.otherRequired;
337
- continue;
338
- }
339
- const min = question.validation?.minSelections;
340
- const max = question.kind === "single_select" ? 1 : question.validation?.maxSelections;
341
- if (min != null && supplied < min) {
342
- errors[question.id] = messages.minSelections(min);
343
- continue;
344
- }
345
- if (max != null && supplied > max) {
346
- errors[question.id] = messages.maxSelections(max);
347
- continue;
348
- }
349
- }
350
- if (supplied > 0) {
351
- answers.push({
352
- questionId: question.id,
353
- values,
354
- ...other ? { other } : {}
355
- });
356
- }
357
- }
358
- return { answers, errors };
359
- }
360
- function initialDrafts(questions) {
361
- return Object.fromEntries(questions.map((question) => [question.id, emptyDraft()]));
362
- }
363
- function emptyDraft() {
364
- return { values: [], other: "", otherSelected: false };
365
- }
366
- function formatDeadline(value) {
367
- const date = new Date(value);
368
- return Number.isNaN(date.getTime()) ? value : date.toLocaleString();
369
- }
370
-
371
- // src/timeline/registry.ts
372
- function rawTypeOf(item) {
373
- const raw = item.raw;
374
- if (raw && typeof raw === "object" && typeof raw.type === "string") {
375
- return raw.type;
376
- }
377
- return null;
378
- }
379
- function createToolRegistry(baseEntries, baseFallback, options = {}) {
380
- const entries = [...options.entries ?? [], ...baseEntries];
381
- const fallback = options.fallback ?? baseFallback;
382
- const byRawType = /* @__PURE__ */ new Map();
383
- const byName = /* @__PURE__ */ new Map();
384
- for (const entry of entries) {
385
- if (entry.match === "rawType") {
386
- if (!byRawType.has(entry.type)) {
387
- byRawType.set(entry.type, entry.render);
388
- }
389
- } else if (!byName.has(entry.name)) {
390
- byName.set(entry.name, entry.render);
391
- }
392
- }
393
- const resolve = (item) => {
394
- const rawType = rawTypeOf(item);
395
- if (rawType) {
396
- const byType = byRawType.get(rawType);
397
- if (byType) {
398
- return byType;
399
- }
400
- }
401
- return byName.get(item.name) ?? fallback;
402
- };
403
- return { resolve, fallback };
404
- }
405
-
406
- // src/timeline/parsers.ts
407
- import { normalizeMcpOutput } from "@opengeni/sdk";
408
- function sandboxCommandExitCode(out) {
409
- const match = String(out ?? "").match(/Process exited with code (-?\d+)/);
410
- return match ? Number(match[1]) : null;
411
- }
412
- function parseExecBannerSessionId(out) {
413
- const text = String(out ?? "");
414
- const outputIdx = text.indexOf("\nOutput:\n");
415
- const banner = outputIdx >= 0 ? text.slice(0, outputIdx) : text.startsWith("Output:\n") ? "" : text;
416
- const match = banner.match(/Process running with session ID (\d+)/);
417
- if (!match) {
418
- return null;
419
- }
420
- const n = Number.parseInt(match[1], 10);
421
- return Number.isFinite(n) ? n : null;
422
- }
423
- function stripExecBanner(out) {
424
- const text = String(out ?? "");
425
- const marker = text.indexOf("\nOutput:\n");
426
- if (marker >= 0) {
427
- return text.slice(marker + "\nOutput:\n".length);
428
- }
429
- if (text.startsWith("Output:\n")) {
430
- return text.slice("Output:\n".length);
431
- }
432
- return text;
433
- }
434
- function execTruncated(out) {
435
- return /Total output lines:|\.{3}\d+ tokens truncated\.{3}|\[\.{3}\d+ characters truncated/.test(
436
- String(out ?? "")
437
- );
438
- }
439
- function isExecSessionLostBanner(out) {
440
- return /write_stdin failed: session not found: \d+/.test(String(out ?? ""));
441
- }
442
- function looksBinary(text) {
443
- return text.includes("\0") || text.startsWith("\x7FELF");
444
- }
445
- function controlCaret(printable) {
446
- return String(printable).replace(
447
- /[\u0000-\u001f]/g,
448
- (c) => `^${String.fromCharCode(c.charCodeAt(0) + 64)}`
449
- );
450
- }
451
- function v4aToGitFileDiff(op) {
452
- const status = op.type === "create_file" ? "added" : op.type === "delete_file" ? "deleted" : op.moveTo ? "renamed" : "modified";
453
- const oldPath = op.moveTo ? op.path : null;
454
- const path = op.moveTo || op.path;
455
- const hunks = [];
456
- let additions = 0;
457
- let deletions = 0;
458
- let sawHunkAnchor = false;
459
- if (op.type !== "delete_file") {
460
- const lines = (op.diff ?? "").split("\n");
461
- let cur = null;
462
- let oldNo = 1;
463
- let newNo = 1;
464
- for (const raw of lines) {
465
- if (raw.startsWith("@@")) {
466
- sawHunkAnchor = true;
467
- const match = raw.match(/-(\d+)(?:,\d+)?\s+\+(\d+)/);
468
- oldNo = match ? Number(match[1]) : 1;
469
- newNo = match ? Number(match[2]) : 1;
470
- cur = {
471
- oldStart: oldNo,
472
- oldLines: 0,
473
- newStart: newNo,
474
- newLines: 0,
475
- header: raw,
476
- lines: [{ type: "meta", oldNo: null, newNo: null, text: raw }]
477
- };
478
- hunks.push(cur);
479
- } else if (cur || op.type === "create_file") {
480
- if (!cur) {
481
- cur = {
482
- oldStart: 0,
483
- oldLines: 0,
484
- newStart: 1,
485
- newLines: 0,
486
- header: "",
487
- lines: []
488
- };
489
- hunks.push(cur);
490
- oldNo = 0;
491
- newNo = 1;
492
- }
493
- if (raw.startsWith("+")) {
494
- cur.lines.push({
495
- type: "add",
496
- oldNo: null,
497
- newNo: newNo++,
498
- text: raw.slice(1)
499
- });
500
- cur.newLines += 1;
501
- additions += 1;
502
- } else if (raw.startsWith("-")) {
503
- cur.lines.push({
504
- type: "del",
505
- oldNo: oldNo++,
506
- newNo: null,
507
- text: raw.slice(1)
508
- });
509
- cur.oldLines += 1;
510
- deletions += 1;
511
- } else {
512
- cur.lines.push({
513
- type: "context",
514
- oldNo: oldNo++,
515
- newNo: newNo++,
516
- text: raw.replace(/^ /, "")
517
- });
518
- cur.oldLines += 1;
519
- cur.newLines += 1;
520
- }
521
- }
522
- }
523
- if (op.type === "update_file" && !sawHunkAnchor && lines.some((l) => l.trim().length > 0)) {
524
- throw new Error("malformed V4A: no @@ hunk anchor");
525
- }
526
- }
527
- return {
528
- path,
529
- oldPath,
530
- status,
531
- isBinary: false,
532
- isImage: false,
533
- additions,
534
- deletions,
535
- hunks,
536
- truncated: false
537
- };
538
- }
539
- function applyPatchOps(raw) {
540
- const r = raw ?? {};
541
- if (Array.isArray(r.operations)) {
542
- return r.operations;
543
- }
544
- return r.operation ? [r.operation] : [];
545
- }
546
- function isApplyPatch(item) {
547
- const type = item.raw && typeof item.raw === "object" ? item.raw.type : void 0;
548
- return type === "apply_patch_call" || item.name === "apply_patch_call";
549
- }
550
- var SECRET_KEY = /^(value|secret|token|password|api[_-]?key|signing[_-]?key)$/i;
551
- function redactSecrets(value) {
552
- if (Array.isArray(value)) {
553
- return value.map(redactSecrets);
554
- }
555
- if (value && typeof value === "object") {
556
- const out = {};
557
- for (const [k, v] of Object.entries(value)) {
558
- out[k] = SECRET_KEY.test(k) ? "\u2022\u2022\u2022\u2022" : redactSecrets(v);
559
- }
560
- return out;
561
- }
562
- return value;
563
- }
564
- function parseToolArgs(args) {
565
- if (args == null) {
566
- return {};
567
- }
568
- if (typeof args === "string") {
569
- const parsed = tryParseJson(args);
570
- return parsed && typeof parsed === "object" ? parsed : {};
571
- }
572
- return typeof args === "object" ? args : {};
573
- }
574
- function tailPeek(text) {
575
- const trimmed = text.trim();
576
- if (!trimmed) {
577
- return "";
578
- }
579
- const lines = trimmed.split("\n");
580
- return lines[lines.length - 1] ?? "";
581
- }
582
- function unwrapMcpOutput(output) {
583
- const normalized = normalizeMcpOutput(output);
584
- return { text: normalized.text, isError: normalized.isError };
585
- }
586
- function screenshotDataUrl(out) {
587
- if (typeof out === "string") {
588
- if (out.startsWith("data:image")) {
589
- return out;
590
- }
591
- if (out.startsWith("{") || out.startsWith("[")) {
592
- const parsed = tryParseJson(out);
593
- if (parsed !== void 0 && parsed !== out) {
594
- return screenshotDataUrl(parsed);
595
- }
596
- }
597
- return null;
598
- }
599
- if (Array.isArray(out)) {
600
- for (const entry of out) {
601
- const url = screenshotDataUrl(entry);
602
- if (url) {
603
- return url;
604
- }
605
- }
606
- return null;
607
- }
608
- if (out === null || typeof out !== "object") {
609
- return null;
610
- }
611
- const record = out;
612
- const imageUrl = record.image_url ?? record.imageUrl;
613
- if (typeof imageUrl === "string" && imageUrl.startsWith("data:image")) {
614
- return imageUrl;
615
- }
616
- if (imageUrl && typeof imageUrl === "object") {
617
- const url = imageUrl.url;
618
- if (typeof url === "string" && url.startsWith("data:image")) {
619
- return url;
620
- }
621
- }
622
- const image = record.image;
623
- if (image && typeof image === "object") {
624
- const mediaType = typeof image.mediaType === "string" ? image.mediaType : "image/png";
625
- const base64 = bytesToBase64(image.data);
626
- if (base64) {
627
- return `data:${mediaType};base64,${base64}`;
628
- }
629
- if (typeof image.data === "string" && image.data.length > 0) {
630
- return `data:${mediaType};base64,${image.data}`;
631
- }
632
- }
633
- return null;
634
- }
635
- function mediaPreviewFact(out) {
636
- if (typeof out === "string" && (out.startsWith("{") || out.startsWith("["))) {
637
- const parsed = tryParseJson(out);
638
- if (parsed !== void 0 && parsed !== out) return mediaPreviewFact(parsed);
639
- }
640
- if (Array.isArray(out)) {
641
- for (const entry of out) {
642
- const preview = mediaPreviewFact(entry);
643
- if (preview) return preview;
644
- }
645
- return null;
646
- }
647
- if (!out || typeof out !== "object") return null;
648
- const record = out;
649
- if (record.type !== "media_preview" || typeof record.mediaType !== "string" || record.fullOutputAvailable !== false || typeof record.preview !== "string" || record.inlineBytes !== null && typeof record.inlineBytes !== "number") {
650
- return null;
651
- }
652
- return record;
653
- }
654
- function bytesToBase64(data) {
655
- const isByte = (n) => typeof n === "number" && Number.isInteger(n) && n >= 0 && n <= 255;
656
- let bytes = null;
657
- if (Array.isArray(data) && data.every(isByte)) {
658
- bytes = data;
659
- } else if (data && typeof data === "object") {
660
- const record = data;
661
- if (record.type === "Buffer" && Array.isArray(record.data) && record.data.every(isByte)) {
662
- bytes = record.data;
663
- } else {
664
- const keys = Object.keys(record);
665
- if (keys.length > 0 && keys.every((key) => /^\d+$/.test(key))) {
666
- const values = keys.sort((a, b) => Number(a) - Number(b)).map((key) => record[key]);
667
- if (values.every(isByte)) {
668
- bytes = values;
669
- }
670
- }
671
- }
672
- }
673
- if (!bytes || bytes.length === 0) {
674
- return null;
675
- }
676
- try {
677
- let binary = "";
678
- const CHUNK = 32768;
679
- for (let i = 0; i < bytes.length; i += CHUNK) {
680
- binary += String.fromCharCode(...bytes.slice(i, i + CHUNK));
681
- }
682
- return typeof btoa === "function" ? btoa(binary) : Buffer.from(binary, "binary").toString("base64");
683
- } catch {
684
- return null;
685
- }
686
- }
687
-
688
- // src/timeline/disclosure-context.tsx
689
- import { createContext, useContext } from "react";
690
- import { jsx as jsx3 } from "react/jsx-runtime";
691
- var DisclosureDefaultsContext = createContext(void 0);
692
- function DisclosureDefaultsProvider({
693
- defaultOpen,
694
- children
695
- }) {
696
- return /* @__PURE__ */ jsx3(DisclosureDefaultsContext.Provider, { value: defaultOpen, children });
697
- }
698
- function useForcedDefaultOpen() {
699
- return useContext(DisclosureDefaultsContext);
700
- }
701
-
702
- // src/timeline/screenshot-lightbox.tsx
703
- import { XIcon } from "lucide-react";
704
- import { AnimatePresence, motion } from "motion/react";
705
- import { createContext as createContext2, useCallback, useContext as useContext2, useMemo, useState as useState2 } from "react";
706
- import { Dialog } from "radix-ui";
707
- import { Fragment, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
708
- var LightboxContext = createContext2(null);
709
- function useLightbox() {
710
- return useContext2(LightboxContext) ?? NOOP;
711
- }
712
- function useLightboxOptional() {
713
- return useContext2(LightboxContext);
714
- }
715
- var NOOP = { open: () => {
716
- } };
717
- function LightboxProvider({ children }) {
718
- const ancestor = useContext2(LightboxContext);
719
- if (ancestor) {
720
- return /* @__PURE__ */ jsx4(Fragment, { children });
721
- }
722
- return /* @__PURE__ */ jsx4(LightboxRoot, { children });
723
- }
724
- function LightboxRoot({ children }) {
725
- const [state, setState] = useState2(null);
726
- const open = useCallback((src, caption) => {
727
- setState(caption ? { src, caption } : { src });
728
- }, []);
729
- const controller = useMemo(() => ({ open }), [open]);
730
- return /* @__PURE__ */ jsxs3(LightboxContext.Provider, { value: controller, children: [
731
- children,
732
- /* @__PURE__ */ jsx4(Dialog.Root, { open: state !== null, onOpenChange: (next) => !next && setState(null), children: /* @__PURE__ */ jsx4(AnimatePresence, { children: state !== null ? /* @__PURE__ */ jsxs3(Dialog.Portal, { forceMount: true, children: [
733
- /* @__PURE__ */ jsx4(Dialog.Overlay, { asChild: true, forceMount: true, children: /* @__PURE__ */ jsx4(
734
- motion.div,
735
- {
736
- initial: { opacity: 0 },
737
- animate: { opacity: 1 },
738
- exit: { opacity: 0 },
739
- transition: { duration: 0.15 },
740
- className: "og-root fixed inset-0 z-50 bg-black/90 backdrop-blur-md"
741
- }
742
- ) }),
743
- /* @__PURE__ */ jsx4(
744
- Dialog.Content,
745
- {
746
- asChild: true,
747
- forceMount: true,
748
- "aria-label": "Screenshot",
749
- onOpenAutoFocus: (event) => event.preventDefault(),
750
- children: /* @__PURE__ */ jsxs3(
751
- motion.div,
752
- {
753
- initial: { opacity: 0, scale: 0.98 },
754
- animate: { opacity: 1, scale: 1 },
755
- exit: { opacity: 0, scale: 0.98 },
756
- transition: { duration: 0.18, ease: [0.16, 1, 0.3, 1] },
757
- onClick: (event) => {
758
- if (event.target === event.currentTarget) {
759
- setState(null);
760
- }
761
- },
762
- className: "og-root fixed inset-0 z-50 flex items-center justify-center p-6 sm:p-12",
763
- children: [
764
- /* @__PURE__ */ jsx4(Dialog.Title, { className: "sr-only", children: "Screenshot" }),
765
- /* @__PURE__ */ jsxs3("figure", { className: "m-0 flex max-h-full max-w-5xl flex-col items-center gap-3", children: [
766
- /* @__PURE__ */ jsxs3("div", { className: "relative flex min-h-0 w-fit max-w-full", children: [
767
- /* @__PURE__ */ jsx4(
768
- "img",
769
- {
770
- src: state.src,
771
- alt: state.caption ?? "Screenshot",
772
- className: "min-h-0 max-h-[82vh] w-auto max-w-full rounded-og-md border border-white/10 object-contain shadow-og-lg"
773
- }
774
- ),
775
- /* @__PURE__ */ jsx4(
776
- Dialog.Close,
777
- {
778
- className: cn(
779
- "absolute -right-3 -top-3 inline-flex size-9 items-center justify-center rounded-full",
780
- "border border-white/15 bg-black/60 text-white/70 backdrop-blur",
781
- "transition-colors hover:border-white/30 hover:text-white"
782
- ),
783
- "aria-label": "Close",
784
- children: /* @__PURE__ */ jsx4(XIcon, { className: "size-4" })
785
- }
786
- )
787
- ] }),
788
- state.caption ? /* @__PURE__ */ jsx4("figcaption", { className: "max-w-2xl text-center font-og-mono text-og-xs text-white/55", children: state.caption }) : /* @__PURE__ */ jsx4("figcaption", { className: "font-og-mono text-og-xs uppercase tracking-[0.1em] text-white/35", children: "Esc or click outside to close" })
789
- ] })
790
- ]
791
- }
792
- )
793
- }
794
- )
795
- ] }) : null }) })
796
- ] });
797
- }
798
-
799
- // src/timeline/shared.tsx
800
- import { CameraIcon, CameraOffIcon, ChevronRightIcon } from "lucide-react";
801
- import { useState as useState3 } from "react";
802
- import { Collapsible } from "radix-ui";
803
- import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
804
- var ICON_TONE = {
805
- accent: "text-og-accent",
806
- failed: "text-og-status-failed",
807
- running: "text-og-status-running",
808
- muted: "text-og-fg-subtle"
809
- };
810
- function ActivityDisclosure({
811
- icon,
812
- iconTone: iconToneProp = "muted",
813
- title,
814
- titleMono,
815
- running,
816
- preview,
817
- media,
818
- chip: chipProp,
819
- failed,
820
- cancelled,
821
- expandable = true,
822
- children
823
- }) {
824
- const iconTone = failed && iconToneProp === "muted" ? "failed" : iconToneProp;
825
- const chip = chipProp ?? (failed ? { tone: "bad", text: "failed" } : cancelled ? { tone: "interrupted", text: "interrupted" } : void 0);
826
- const forcedDefaultOpen = useForcedDefaultOpen();
827
- const [open, setOpen] = useState3(forcedDefaultOpen ?? false);
828
- const hasBody = expandable && children != null;
829
- const previewVisible = preview != null && !open;
830
- const rowClass = cn(
831
- "group/disclosure flex w-full min-w-0 items-center gap-2 rounded-og-sm px-1.5 py-1.5 text-left text-og-base",
832
- "text-og-fg-muted transition-colors duration-150",
833
- // A tool row is a touch target on coarse pointers: grow its padding so the
834
- // hit area clears the 40px minimum without loosening the dense desktop rail.
835
- "pointer-coarse:py-2.5"
836
- );
837
- const inner = /* @__PURE__ */ jsxs4(Fragment2, { children: [
838
- hasBody ? /* @__PURE__ */ jsx5(ChevronRightIcon, { className: "size-3.5 shrink-0 text-og-fg-subtle transition-transform duration-150 ease-og-in-out group-data-[state=open]/disclosure:rotate-90" }) : /* @__PURE__ */ jsx5("span", { className: "size-3.5 shrink-0" }),
839
- /* @__PURE__ */ jsx5("span", { className: cn("shrink-0", ICON_TONE[iconTone]), children: icon }),
840
- /* @__PURE__ */ jsx5(
841
- "span",
842
- {
843
- className: cn(
844
- "min-w-0 shrink truncate text-og-base font-medium",
845
- titleMono && "font-og-mono text-og-sm font-normal",
846
- running && "og-shimmer-text"
847
- ),
848
- children: title
849
- }
850
- ),
851
- previewVisible && !media ? /* @__PURE__ */ jsx5("span", { className: "min-w-0 flex-1 truncate text-og-sm text-og-fg-subtle", children: preview }) : /* @__PURE__ */ jsx5("span", { className: "flex-1" }),
852
- media ? /* @__PURE__ */ jsx5("span", { className: "ml-auto flex shrink-0 items-center gap-2 pl-2", children: media }) : chip && !open ? /* @__PURE__ */ jsx5("span", { className: "ml-auto shrink-0 pl-2", children: /* @__PURE__ */ jsx5(Chip, { chip }) }) : null
853
- ] });
854
- const dataStatus = cancelled ? "cancelled" : failed ? "failed" : void 0;
855
- if (!hasBody) {
856
- return /* @__PURE__ */ jsx5("div", { className: cn(rowClass, "cursor-default"), "data-status": dataStatus, children: inner });
857
- }
858
- return /* @__PURE__ */ jsxs4(Collapsible.Root, { open, onOpenChange: setOpen, children: [
859
- /* @__PURE__ */ jsx5(Collapsible.Trigger, { asChild: true, children: /* @__PURE__ */ jsx5(
860
- "div",
861
- {
862
- role: "button",
863
- tabIndex: 0,
864
- onKeyDown: (event) => {
865
- if (event.key === "Enter" || event.key === " ") {
866
- event.preventDefault();
867
- setOpen((prev) => !prev);
868
- }
869
- },
870
- "data-status": dataStatus,
871
- className: cn(
872
- rowClass,
873
- "cursor-pointer outline-none hover:bg-og-surface-1 hover:text-og-fg",
874
- "focus-visible:ring-2 focus-visible:ring-og-accent focus-visible:ring-offset-0"
875
- ),
876
- children: inner
877
- }
878
- ) }),
879
- /* @__PURE__ */ jsx5(Collapsible.Content, { className: "overflow-hidden data-[state=closed]:animate-og-collapse data-[state=open]:animate-og-expand", children: /* @__PURE__ */ jsx5("div", { className: "mb-2 ml-7 mt-1.5 flex flex-col gap-2", children }) })
880
- ] });
881
- }
882
- function Chip({ chip }) {
883
- const base = "inline-flex items-center font-og-mono text-og-xs leading-none";
884
- const withText = chip.text ? "gap-1.5" : "gap-0";
885
- if (chip.tone === "bad") {
886
- return /* @__PURE__ */ jsxs4("span", { className: cn(base, withText, "text-og-status-failed"), children: [
887
- /* @__PURE__ */ jsx5("span", { className: "size-1.5 rounded-full bg-og-status-failed" }),
888
- chip.text
889
- ] });
890
- }
891
- if (chip.tone === "interrupted") {
892
- return /* @__PURE__ */ jsx5("span", { className: cn(base, "text-og-fg-subtle og-cancelled-chip"), children: chip.text });
893
- }
894
- return /* @__PURE__ */ jsx5("span", { className: cn(base, "text-og-fg-subtle"), children: chip.text });
895
- }
896
- function TermBlock({
897
- command,
898
- workdir,
899
- output,
900
- live,
901
- tailLines = 12,
902
- failed
903
- }) {
904
- const [full, setFull] = useState3(false);
905
- const empty = output.trim() === "";
906
- const lines = output.split("\n");
907
- const big = lines.length > tailLines + 4;
908
- const shown = full || !big ? output : lines.slice(-tailLines).join("\n");
909
- const showMore = big && !full;
910
- const showHeader = command != null || workdir != null;
911
- return /* @__PURE__ */ jsxs4(
912
- "div",
913
- {
914
- className: cn(
915
- "min-w-0 border-l-2 pl-3",
916
- failed ? "border-og-status-failed/50" : live ? "border-og-status-running/50" : "border-og-border"
917
- ),
918
- children: [
919
- showHeader ? /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2 pb-1", children: [
920
- /* @__PURE__ */ jsx5("span", { className: "select-none text-og-status-idle", children: "$" }),
921
- command != null ? /* @__PURE__ */ jsx5("span", { className: "min-w-0 flex-1 truncate font-og-mono text-og-sm text-og-fg-muted", children: command }) : /* @__PURE__ */ jsx5("span", { className: "flex-1" }),
922
- workdir ? /* @__PURE__ */ jsx5("span", { className: "shrink-0 font-og-mono text-og-xs text-og-fg-subtle", children: workdir }) : null
923
- ] }) : null,
924
- empty ? /* @__PURE__ */ jsx5("p", { className: "font-og-mono text-og-xs italic text-og-fg-subtle", children: "(no output)" }) : /* @__PURE__ */ jsxs4("pre", { className: "max-h-72 overflow-auto whitespace-pre-wrap break-all font-og-mono text-og-xs leading-5 text-og-fg-muted", children: [
925
- shown,
926
- live ? /* @__PURE__ */ jsx5("span", { className: "ml-px inline-block h-[1em] w-[2px] translate-y-[2px] animate-og-blink bg-og-accent align-middle" }) : null
927
- ] }),
928
- showMore ? /* @__PURE__ */ jsxs4(
929
- "button",
930
- {
931
- type: "button",
932
- onClick: () => setFull(true),
933
- className: "mt-1 text-left text-og-xs text-og-fg-subtle transition-colors hover:text-og-fg",
934
- children: [
935
- "show full output (",
936
- lines.length,
937
- " lines)"
938
- ]
939
- }
940
- ) : null
941
- ]
942
- }
943
- );
944
- }
945
- function PayloadBlock({
946
- label,
947
- value,
948
- failed
949
- }) {
950
- const text = typeof value === "string" ? value : stringifyPayload(value);
951
- if (!text || text.trim() === "") {
952
- return null;
953
- }
954
- return /* @__PURE__ */ jsxs4(
955
- "div",
956
- {
957
- className: cn(
958
- "min-w-0 border-l-2 pl-3",
959
- failed ? "border-og-status-failed/50" : "border-og-border"
960
- ),
961
- children: [
962
- /* @__PURE__ */ jsx5("p", { className: "mb-1 text-og-xs font-medium uppercase tracking-[0.08em] text-og-fg-subtle", children: label }),
963
- /* @__PURE__ */ jsx5(
964
- "pre",
965
- {
966
- className: cn(
967
- "max-h-64 overflow-auto whitespace-pre-wrap break-all font-og-mono text-og-xs leading-5",
968
- failed ? "text-og-status-failed" : "text-og-fg-muted"
969
- ),
970
- children: text
971
- }
972
- )
973
- ]
974
- }
975
- );
976
- }
977
- function BodyNote({
978
- children,
979
- tone
980
- }) {
981
- if (tone === "error") {
982
- return /* @__PURE__ */ jsx5("div", { className: "border-l-2 border-og-status-failed/50 pl-3 font-og-mono text-og-xs leading-5 text-og-status-failed", children });
983
- }
984
- return /* @__PURE__ */ jsx5("p", { className: "px-0.5 text-og-sm italic leading-5 text-og-fg-subtle", children });
985
- }
986
- var MEDIA_BOX = "h-7 w-[52px] shrink-0 rounded-og-xs border border-og-border";
987
- function MediaSkeleton() {
988
- return /* @__PURE__ */ jsxs4(
989
- "span",
990
- {
991
- className: cn(
992
- MEDIA_BOX,
993
- "relative inline-flex items-center justify-center overflow-hidden bg-og-surface-2"
994
- ),
995
- children: [
996
- /* @__PURE__ */ jsx5("span", { className: "absolute inset-0 animate-og-pulse bg-og-surface-3/50" }),
997
- /* @__PURE__ */ jsx5(CameraIcon, { className: "relative size-3.5 text-og-fg-subtle" })
998
- ]
999
- }
1000
- );
1001
- }
1002
- function MediaEmpty() {
1003
- return /* @__PURE__ */ jsx5("span", { className: cn(MEDIA_BOX, "inline-flex items-center justify-center bg-og-bg"), children: /* @__PURE__ */ jsx5(CameraOffIcon, { className: "size-3.5 text-og-fg-subtle" }) });
1004
- }
1005
- function Thumbnail({
1006
- src,
1007
- caption,
1008
- alt = "screenshot"
1009
- }) {
1010
- const lightbox = useLightboxOptional();
1011
- const [failed, setFailed] = useState3(false);
1012
- if (failed) {
1013
- return /* @__PURE__ */ jsx5(MediaEmpty, {});
1014
- }
1015
- const img = /* @__PURE__ */ jsx5(
1016
- "img",
1017
- {
1018
- src,
1019
- alt,
1020
- onError: () => setFailed(true),
1021
- className: "h-full w-full object-cover transition-opacity group-hover/thumb:opacity-80"
1022
- }
1023
- );
1024
- if (!lightbox) {
1025
- return /* @__PURE__ */ jsx5("span", { className: cn(MEDIA_BOX, "inline-flex overflow-hidden bg-og-bg"), children: img });
1026
- }
1027
- return /* @__PURE__ */ jsx5(
1028
- "button",
1029
- {
1030
- type: "button",
1031
- onClick: (event) => {
1032
- event.stopPropagation();
1033
- lightbox.open(src, caption);
1034
- },
1035
- onKeyDown: (event) => {
1036
- if (event.key === "Enter" || event.key === " ") {
1037
- event.stopPropagation();
1038
- }
1039
- },
1040
- className: cn(
1041
- MEDIA_BOX,
1042
- "group/thumb relative inline-flex overflow-hidden bg-og-bg outline-none",
1043
- "focus-visible:ring-2 focus-visible:ring-og-accent"
1044
- ),
1045
- "aria-label": "Expand screenshot",
1046
- children: img
1047
- }
1048
- );
1049
- }
1050
- function ScreenshotFigure({
1051
- src,
1052
- caption,
1053
- alt = "screenshot"
1054
- }) {
1055
- const lightbox = useLightboxOptional();
1056
- const [failed, setFailed] = useState3(false);
1057
- const surface = "block w-full overflow-hidden rounded-og-md border border-og-border bg-og-bg";
1058
- const img = /* @__PURE__ */ jsx5(
1059
- "img",
1060
- {
1061
- src,
1062
- alt,
1063
- onError: () => setFailed(true),
1064
- className: "max-h-80 w-full object-contain"
1065
- }
1066
- );
1067
- return /* @__PURE__ */ jsxs4("figure", { className: "m-0 min-w-0", children: [
1068
- failed ? /* @__PURE__ */ jsx5("div", { className: "rounded-og-md border border-og-border bg-og-bg px-3 py-6 text-center font-og-mono text-og-xs text-og-fg-subtle", children: "image unavailable" }) : lightbox ? /* @__PURE__ */ jsx5(
1069
- "button",
1070
- {
1071
- type: "button",
1072
- onClick: () => lightbox.open(src, caption),
1073
- className: surface,
1074
- "aria-label": "Expand screenshot",
1075
- children: img
1076
- }
1077
- ) : /* @__PURE__ */ jsx5("div", { className: surface, children: img }),
1078
- caption ? /* @__PURE__ */ jsx5("figcaption", { className: "mt-1.5 font-og-mono text-og-xs text-og-fg-subtle", children: caption }) : null
1079
- ] });
1080
- }
1081
-
1082
- // src/lib/git-patch.ts
1083
- function gitFileDiffToPatch(file) {
1084
- const oldPath = file.oldPath ?? file.path;
1085
- const newPath = file.path;
1086
- const lines = [];
1087
- lines.push(`diff --git a/${oldPath} b/${newPath}`);
1088
- if (file.status === "deleted") {
1089
- lines.push(`--- a/${oldPath}`);
1090
- lines.push(`+++ /dev/null`);
1091
- } else if (file.status === "added" || file.status === "untracked") {
1092
- lines.push(`--- /dev/null`);
1093
- lines.push(`+++ b/${newPath}`);
1094
- } else {
1095
- lines.push(`--- a/${oldPath}`);
1096
- lines.push(`+++ b/${newPath}`);
1097
- }
1098
- for (const hunk of file.hunks) {
1099
- const headerIsValid = /^@@ -\d+(?:,\d+)? \+\d+(?:,\d+)? @@/.test(hunk.header ?? "");
1100
- const header = headerIsValid ? hunk.header : `@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`;
1101
- lines.push(header);
1102
- for (const line of hunk.lines) {
1103
- if (line.type === "meta") continue;
1104
- const prefix = line.type === "add" ? "+" : line.type === "del" ? "-" : " ";
1105
- lines.push(`${prefix}${line.text}`);
1106
- }
1107
- }
1108
- return lines.join("\n") + "\n";
1109
- }
1110
-
1111
- // src/components/pierre-diff.tsx
1112
- import {
1113
- lazy as lazy2,
1114
- Suspense as Suspense2,
1115
- useEffect as useEffect2,
1116
- useState as useState4
1117
- } from "react";
1118
- import { jsx as jsx6 } from "react/jsx-runtime";
1119
- var LazyPatchDiff = lazy2(async () => {
1120
- const mod = await import("@pierre/diffs/react");
1121
- return { default: mod.PatchDiff };
1122
- });
1123
- function PierreDiff({
1124
- diff,
1125
- layout = "unified",
1126
- themeType,
1127
- theme,
1128
- disableWorkerPool,
1129
- loading,
1130
- fallback,
1131
- plain,
1132
- overflow = "wrap",
1133
- className
1134
- }) {
1135
- const [failed, setFailed] = useState4(false);
1136
- const [forcedColors, setForcedColors] = useState4(false);
1137
- useEffect2(() => {
1138
- if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
1139
- const query = window.matchMedia("(forced-colors: active)");
1140
- const update = () => setForcedColors(query.matches);
1141
- update();
1142
- query.addEventListener?.("change", update);
1143
- return () => query.removeEventListener?.("change", update);
1144
- }, []);
1145
- useEffect2(() => {
1146
- if (plain) return;
1147
- let cancelled = false;
1148
- void import("@pierre/diffs/react").catch(() => {
1149
- if (!cancelled) setFailed(true);
1150
- });
1151
- return () => {
1152
- cancelled = true;
1153
- };
1154
- }, [plain]);
1155
- if (plain || failed || forcedColors) {
1156
- return /* @__PURE__ */ jsx6(
1157
- "div",
1158
- {
1159
- className,
1160
- "data-opengeni-plain-diff": forcedColors ? "forced-colors" : "fallback",
1161
- children: fallback ?? /* @__PURE__ */ jsx6(PlainPatch, { diff })
1162
- }
1163
- );
1164
- }
1165
- const options = {
1166
- diffStyle: layout,
1167
- overflow,
1168
- stickyHeader: true,
1169
- ...theme ? { theme } : {
1170
- theme: {
1171
- dark: "github-dark-high-contrast",
1172
- light: "github-light-high-contrast"
1173
- }
1174
- },
1175
- themeType: themeType ?? "dark"
1176
- };
1177
- const pierreVars = {
1178
- "--diffs-dark-bg": "var(--og-color-bg)",
1179
- "--diffs-light-bg": "var(--og-color-bg)",
1180
- "--diffs-bg-buffer-override": "var(--og-color-surface-1)",
1181
- "--diffs-bg-separator-override": "var(--og-color-surface-1)",
1182
- "--diffs-addition-color-override": "var(--og-color-status-idle)",
1183
- "--diffs-deletion-color-override": "var(--og-color-status-failed)",
1184
- "--diffs-fg-number-addition-override": "var(--og-color-status-idle)",
1185
- "--diffs-fg-number-deletion-override": "var(--og-color-status-failed)",
1186
- "--diffs-bg-addition-override": "color-mix(in oklab, var(--og-color-status-idle) 12%, var(--og-color-bg))",
1187
- "--diffs-bg-deletion-override": "color-mix(in oklab, var(--og-color-status-failed) 12%, var(--og-color-bg))",
1188
- "--diffs-bg-addition-emphasis-override": "color-mix(in oklab, var(--og-color-status-idle) 22%, var(--og-color-bg))",
1189
- "--diffs-bg-deletion-emphasis-override": "color-mix(in oklab, var(--og-color-status-failed) 22%, var(--og-color-bg))",
1190
- "--diffs-header-font-family": "var(--og-font-sans)",
1191
- "--diffs-font-family": "var(--og-font-mono)",
1192
- "--diffs-font-size": "var(--og-code-font-size)",
1193
- "--diffs-line-height": "var(--og-code-line-height)"
1194
- };
1195
- return /* @__PURE__ */ jsx6("div", { className: cn("min-w-0", className), "data-opengeni-pierre-diff": true, style: pierreVars, children: /* @__PURE__ */ jsx6(Suspense2, { fallback: loading ?? /* @__PURE__ */ jsx6(DiffSkeleton, {}), children: diff.map((file) => /* @__PURE__ */ jsx6("div", { className: "mb-2", children: /* @__PURE__ */ jsx6(
1196
- LazyPatchDiff,
1197
- {
1198
- patch: gitFileDiffToPatch(file),
1199
- options,
1200
- ...disableWorkerPool !== void 0 ? { disableWorkerPool } : {}
1201
- }
1202
- ) }, file.path)) }) });
1203
- }
1204
- function DiffSkeleton() {
1205
- return /* @__PURE__ */ jsx6("div", { className: "p-3 text-og-sm text-og-fg-subtle", children: "Loading diff\u2026" });
1206
- }
1207
- function PlainPatch({ diff }) {
1208
- if (diff.length === 0) {
1209
- return /* @__PURE__ */ jsx6("div", { className: "p-3 text-og-sm text-og-fg-subtle", children: "No changes" });
1210
- }
1211
- return /* @__PURE__ */ jsx6("div", { className: "min-w-0", children: diff.map((file) => /* @__PURE__ */ jsx6(
1212
- "pre",
1213
- {
1214
- "aria-label": `Diff for ${file.path}`,
1215
- className: "mb-2 overflow-auto whitespace-pre rounded-og-sm border border-og-border bg-og-bg/60 p-2.5 font-og-mono text-og-xs leading-5",
1216
- role: "region",
1217
- tabIndex: 0,
1218
- children: gitFileDiffToPatch(file).split("\n").map((line, index) => /* @__PURE__ */ jsx6(
1219
- "span",
1220
- {
1221
- className: cn(
1222
- "block",
1223
- line.startsWith("@@") ? "text-og-accent" : line.startsWith("+") ? "text-og-status-idle" : line.startsWith("-") ? "text-og-status-failed" : "text-og-fg-muted"
1224
- ),
1225
- children: line || " "
1226
- },
1227
- index
1228
- ))
1229
- },
1230
- file.path
1231
- )) });
1232
- }
1233
-
1234
- // src/timeline/tool-renderers.tsx
1235
- import {
1236
- CameraIcon as CameraIcon2,
1237
- CameraOffIcon as CameraOffIcon2,
1238
- FileDiffIcon,
1239
- GlobeIcon,
1240
- ImageIcon,
1241
- KeyboardIcon,
1242
- KeyRoundIcon,
1243
- LockIcon,
1244
- MousePointer2Icon,
1245
- PlugIcon,
1246
- SearchIcon,
1247
- TerminalIcon,
1248
- WrenchIcon
1249
- } from "lucide-react";
1250
-
1251
- // src/timeline/tool-diff.tsx
1252
- import { useState as useState6 } from "react";
1253
-
1254
- // src/lib/use-theme-type.ts
1255
- import { useEffect as useEffect3, useState as useState5 } from "react";
1256
- function useThemeType(forced) {
1257
- const [detected, setDetected] = useState5("dark");
1258
- useEffect3(() => {
1259
- if (forced || typeof document === "undefined") return;
1260
- const read = () => {
1261
- const el = document.querySelector("[data-og-theme]");
1262
- const value = el?.getAttribute("data-og-theme");
1263
- setDetected(value === "light" ? "light" : "dark");
1264
- };
1265
- read();
1266
- const observer = new MutationObserver(read);
1267
- observer.observe(document.documentElement, {
1268
- attributes: true,
1269
- attributeFilter: ["data-og-theme"],
1270
- subtree: true
1271
- });
1272
- return () => observer.disconnect();
1273
- }, [forced]);
1274
- return forced ?? detected;
1275
- }
1276
-
1277
- // src/timeline/tool-diff.tsx
1278
- import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
1279
- function ToolDiff({ files }) {
1280
- const [layout, setLayout] = useState6("unified");
1281
- const themeType = useThemeType(void 0);
1282
- return /* @__PURE__ */ jsxs5("div", { className: "min-w-0", children: [
1283
- /* @__PURE__ */ jsx7("div", { className: "mb-1.5 flex justify-end", children: /* @__PURE__ */ jsx7(LayoutToggle, { layout, onChange: setLayout }) }),
1284
- /* @__PURE__ */ jsx7(PierreDiff, { diff: files, layout, themeType })
1285
- ] });
1286
- }
1287
- function LayoutToggle({
1288
- layout,
1289
- onChange
1290
- }) {
1291
- return /* @__PURE__ */ jsx7("div", { className: "inline-flex items-center gap-px rounded-og-xs border border-og-border p-px", children: ["unified", "split"].map((value) => /* @__PURE__ */ jsx7(
1292
- "button",
1293
- {
1294
- type: "button",
1295
- onClick: () => onChange(value),
1296
- className: cn(
1297
- "rounded-og-xs px-2 py-[3px] text-og-xs font-medium capitalize transition-colors",
1298
- layout === value ? "bg-og-surface-2 text-og-fg" : "text-og-fg-subtle hover:text-og-fg-muted"
1299
- ),
1300
- children: value
1301
- },
1302
- value
1303
- )) });
1304
- }
1305
- function RawPatch({ diff }) {
1306
- const occurrences = /* @__PURE__ */ new Map();
1307
- const lines = diff.split("\n").map((line) => {
1308
- const occurrence = (occurrences.get(line) ?? 0) + 1;
1309
- occurrences.set(line, occurrence);
1310
- return { key: `${line}\0${occurrence}`, line };
1311
- });
1312
- return /* @__PURE__ */ jsxs5("div", { className: "min-w-0", children: [
1313
- /* @__PURE__ */ jsx7("p", { className: "mb-1 text-og-xs font-medium uppercase tracking-[0.08em] text-og-fg-subtle", children: "raw patch (could not parse hunks)" }),
1314
- /* @__PURE__ */ jsx7("pre", { className: "max-h-72 overflow-auto border-l-2 border-og-border pl-3 font-og-mono text-og-xs leading-5", children: lines.map(({ key, line }) => /* @__PURE__ */ jsx7(
1315
- "span",
1316
- {
1317
- className: cn(
1318
- "block",
1319
- line.startsWith("@@") ? "text-og-accent" : line.startsWith("+") ? "text-og-status-idle" : line.startsWith("-") ? "text-og-status-failed" : "text-og-fg-muted"
1320
- ),
1321
- children: line || " "
1322
- },
1323
- key
1324
- )) })
1325
- ] });
1326
- }
1327
-
1328
- // src/timeline/tool-display-name.ts
1329
- function toolDisplayName(name) {
1330
- const boundary = name.indexOf("__");
1331
- const toolPart = boundary >= 0 ? name.slice(boundary + 2) : name;
1332
- return toolPart.replace(/[_-]+/g, " ").trim();
1333
- }
1334
-
1335
- // src/timeline/tool-renderers.tsx
1336
- import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
1337
- var ICON_SIZE = "size-3.5";
1338
- function RunningPreview({ children }) {
1339
- return /* @__PURE__ */ jsxs6("span", { className: "inline-flex items-center gap-1.5", children: [
1340
- /* @__PURE__ */ jsx8("span", { className: "size-1.5 shrink-0 animate-og-pulse rounded-full bg-og-status-running" }),
1341
- /* @__PURE__ */ jsx8("span", { className: "min-w-0 truncate", children })
1342
- ] });
1343
- }
1344
- function ExecRenderer({ item }) {
1345
- const args = parseToolArgs(item.arguments);
1346
- const cmd = typeof args.cmd === "string" ? args.cmd : "";
1347
- const workdir = typeof args.workdir === "string" ? args.workdir : null;
1348
- const running = item.status === "running";
1349
- const out = item.output;
1350
- const title = `$ ${cmd}`;
1351
- if (item.status === "failed" && out === void 0) {
1352
- return /* @__PURE__ */ jsx8(
1353
- ActivityDisclosure,
1354
- {
1355
- icon: /* @__PURE__ */ jsx8(TerminalIcon, { className: ICON_SIZE }),
1356
- iconTone: "failed",
1357
- title,
1358
- titleMono: true,
1359
- chip: { tone: "bad", text: "failed" },
1360
- preview: "output lost \u2014 NUL byte could not be stored",
1361
- children: /* @__PURE__ */ jsx8(BodyNote, { tone: "error", children: "output contained a NUL byte and could not be stored; the turn failed on this tool's output insert \u2014 no output event ever arrived." })
1362
- }
1363
- );
1364
- }
1365
- if (item.status === "failed" && (out == null || out === "")) {
1366
- return /* @__PURE__ */ jsx8(
1367
- ActivityDisclosure,
1368
- {
1369
- icon: /* @__PURE__ */ jsx8(TerminalIcon, { className: ICON_SIZE }),
1370
- iconTone: "failed",
1371
- title,
1372
- titleMono: true,
1373
- chip: { tone: "bad", text: "failed" },
1374
- preview: "tool call failed",
1375
- children: /* @__PURE__ */ jsx8(BodyNote, { tone: "error", children: "the tool call failed with no output." })
1376
- }
1377
- );
1378
- }
1379
- if (running) {
1380
- const streamed = typeof out === "string" ? stripExecBanner(out) : "";
1381
- return /* @__PURE__ */ jsx8(
1382
- ActivityDisclosure,
1383
- {
1384
- icon: /* @__PURE__ */ jsx8(TerminalIcon, { className: ICON_SIZE }),
1385
- iconTone: "running",
1386
- title,
1387
- titleMono: true,
1388
- running: true,
1389
- preview: /* @__PURE__ */ jsx8(RunningPreview, { children: streamed ? `${streamed.split("\n").length} lines` : "running\u2026" }),
1390
- children: /* @__PURE__ */ jsx8(TermBlock, { command: null, workdir, output: streamed, live: true })
1391
- }
1392
- );
1393
- }
1394
- const text = typeof out === "string" ? out : stringifyPayload(out);
1395
- const stripped = stripExecBanner(text);
1396
- const bgSession = parseExecBannerSessionId(text);
1397
- const exitCode = sandboxCommandExitCode(text);
1398
- const binary = looksBinary(stripped);
1399
- let chip;
1400
- let iconTone = "muted";
1401
- if (bgSession != null) {
1402
- chip = { tone: "muted", text: `session ${bgSession}` };
1403
- } else if (exitCode != null && exitCode !== 0) {
1404
- chip = { tone: "bad", text: `exit ${exitCode}` };
1405
- iconTone = "failed";
1406
- }
1407
- const preview = binary ? "binary output" : tailPeek(stripped) || "(no output)";
1408
- const truncated = execTruncated(text);
1409
- const body = binary ? "(binary output suppressed)" : stripped;
1410
- return /* @__PURE__ */ jsxs6(
1411
- ActivityDisclosure,
1412
- {
1413
- icon: /* @__PURE__ */ jsx8(TerminalIcon, { className: ICON_SIZE }),
1414
- iconTone,
1415
- title,
1416
- titleMono: true,
1417
- ...chip ? { chip } : {},
1418
- failed: item.status === "failed",
1419
- cancelled: item.status === "cancelled",
1420
- preview: truncated ? `\u22EF truncated \xB7 ${preview}` : preview,
1421
- children: [
1422
- /* @__PURE__ */ jsx8(
1423
- TermBlock,
1424
- {
1425
- command: null,
1426
- workdir,
1427
- output: body,
1428
- failed: item.status === "failed" || exitCode != null && exitCode !== 0
1429
- }
1430
- ),
1431
- bgSession != null ? /* @__PURE__ */ jsxs6(BodyNote, { children: [
1432
- "\u21B3 session ",
1433
- bgSession,
1434
- " \u2014 a later write_stdin can target this PTY."
1435
- ] }) : null
1436
- ]
1437
- }
1438
- );
1439
- }
1440
- function WriteStdinRenderer({ item }) {
1441
- const args = parseToolArgs(item.arguments);
1442
- const sessionId = typeof args.session_id === "string" || typeof args.session_id === "number" ? args.session_id : void 0;
1443
- const running = item.status === "running";
1444
- const text = typeof item.output === "string" ? item.output : stringifyPayload(item.output);
1445
- const lost = isExecSessionLostBanner(text);
1446
- const keys = controlCaret(typeof args.chars === "string" ? args.chars : "");
1447
- const exitCode = sandboxCommandExitCode(text);
1448
- const stripped = stripExecBanner(text);
1449
- if (running) {
1450
- return /* @__PURE__ */ jsx8(
1451
- ActivityDisclosure,
1452
- {
1453
- icon: /* @__PURE__ */ jsx8(KeyboardIcon, { className: ICON_SIZE }),
1454
- iconTone: "running",
1455
- title: `session ${sessionId} \u2190 ${keys || "\u2205"}`,
1456
- titleMono: true,
1457
- running: true,
1458
- preview: /* @__PURE__ */ jsx8(RunningPreview, { children: "sending\u2026" }),
1459
- children: /* @__PURE__ */ jsxs6(BodyNote, { children: [
1460
- "sending input to session ",
1461
- sessionId,
1462
- "\u2026"
1463
- ] })
1464
- }
1465
- );
1466
- }
1467
- let chip;
1468
- if (lost) {
1469
- chip = { tone: "bad", text: "lost" };
1470
- } else if (exitCode != null && exitCode !== 0) {
1471
- chip = { tone: "bad", text: `exit ${exitCode}` };
1472
- }
1473
- return /* @__PURE__ */ jsx8(
1474
- ActivityDisclosure,
1475
- {
1476
- icon: /* @__PURE__ */ jsx8(KeyboardIcon, { className: ICON_SIZE }),
1477
- iconTone: lost ? "failed" : "muted",
1478
- title: `session ${sessionId} \u2190 ${keys || "\u2205"}`,
1479
- titleMono: true,
1480
- ...chip ? { chip } : {},
1481
- failed: item.status === "failed",
1482
- cancelled: item.status === "cancelled",
1483
- preview: lost ? `session ${sessionId} PTY vanished` : tailPeek(stripped) || "sent",
1484
- children: lost ? /* @__PURE__ */ jsx8(BodyNote, { tone: "error", children: stripped || text }) : /* @__PURE__ */ jsx8(TermBlock, { command: `write_stdin \u2192 session ${sessionId}`, output: stripped })
1485
- }
1486
- );
1487
- }
1488
- function verbForOp(op) {
1489
- if (!op) {
1490
- return "Edited";
1491
- }
1492
- return op.type === "create_file" ? "Created" : op.type === "delete_file" ? "Deleted" : op.moveTo ? "Renamed" : "Edited";
1493
- }
1494
- function basename(path) {
1495
- const parts = path.split("/").filter(Boolean);
1496
- return parts.length ? parts[parts.length - 1] : path;
1497
- }
1498
- function dirname(path) {
1499
- const idx = path.lastIndexOf("/");
1500
- return idx >= 0 ? path.slice(0, idx + 1) : "";
1501
- }
1502
- function PathPreview({
1503
- path,
1504
- add,
1505
- del
1506
- }) {
1507
- return /* @__PURE__ */ jsxs6("span", { className: "inline-flex items-center gap-2 truncate font-og-mono", children: [
1508
- /* @__PURE__ */ jsxs6("span", { className: "truncate", children: [
1509
- /* @__PURE__ */ jsx8("span", { className: "text-og-fg-subtle", children: dirname(path) }),
1510
- /* @__PURE__ */ jsx8("span", { className: "text-og-fg-muted", children: basename(path) })
1511
- ] }),
1512
- add != null || del != null ? /* @__PURE__ */ jsxs6("span", { className: "shrink-0 text-og-fg-subtle", children: [
1513
- add != null ? `+${add}` : "",
1514
- add != null && del != null ? " " : "",
1515
- del != null ? `\u2212${del}` : ""
1516
- ] }) : null
1517
- ] });
1518
- }
1519
- function ApplyPatchRenderer({ item }) {
1520
- const ops = applyPatchOps(item.raw);
1521
- const failed = item.status === "failed";
1522
- const cancelled = item.status === "cancelled";
1523
- const running = item.status === "running";
1524
- const firstOp = ops[0];
1525
- if (running) {
1526
- const fileCount = ops.length;
1527
- const titleVerb = firstOp ? `Applying ${basename(firstOp.path)}` : "Applying patch";
1528
- return /* @__PURE__ */ jsx8(
1529
- ActivityDisclosure,
1530
- {
1531
- icon: /* @__PURE__ */ jsx8(FileDiffIcon, { className: ICON_SIZE }),
1532
- iconTone: "running",
1533
- title: fileCount > 1 ? `Applying ${fileCount} files` : titleVerb,
1534
- running: true,
1535
- preview: /* @__PURE__ */ jsx8(RunningPreview, { children: fileCount > 1 ? `${fileCount} files` : firstOp ? firstOp.path : "applying\u2026" }),
1536
- children: ops.map((op) => {
1537
- const file2 = safeParseOp(op);
1538
- return file2 ? /* @__PURE__ */ jsx8(ToolDiff, { files: [file2] }, op.path) : /* @__PURE__ */ jsxs6("div", { children: [
1539
- /* @__PURE__ */ jsx8("p", { className: "mb-1 font-og-mono text-og-xs text-og-fg-muted", children: op.path }),
1540
- /* @__PURE__ */ jsx8(RawPatch, { diff: op.diff ?? "" })
1541
- ] }, op.path);
1542
- })
1543
- }
1544
- );
1545
- }
1546
- if (failed) {
1547
- return /* @__PURE__ */ jsx8(
1548
- ActivityDisclosure,
1549
- {
1550
- icon: /* @__PURE__ */ jsx8(FileDiffIcon, { className: ICON_SIZE }),
1551
- iconTone: "failed",
1552
- title: firstOp ? `${verbForOp(firstOp)} ${basename(firstOp.path)}` : "apply_patch",
1553
- chip: { tone: "bad", text: "failed" },
1554
- preview: typeof item.output === "string" ? item.output : "patch failed",
1555
- children: /* @__PURE__ */ jsx8(PayloadBlock, { label: "Error", value: item.output, failed: true })
1556
- }
1557
- );
1558
- }
1559
- if (ops.length > 1) {
1560
- const parsed = ops.map((op) => safeParseOp(op));
1561
- const goodFiles = parsed.filter((f) => f !== null);
1562
- const add = goodFiles.reduce((n, f) => n + f.additions, 0);
1563
- const del = goodFiles.reduce((n, f) => n + f.deletions, 0);
1564
- return /* @__PURE__ */ jsx8(
1565
- ActivityDisclosure,
1566
- {
1567
- icon: /* @__PURE__ */ jsx8(FileDiffIcon, { className: ICON_SIZE }),
1568
- iconTone: "accent",
1569
- title: `Edited ${ops.length} files`,
1570
- cancelled,
1571
- preview: /* @__PURE__ */ jsxs6("span", { className: "inline-flex items-center gap-2 font-og-mono", children: [
1572
- /* @__PURE__ */ jsxs6("span", { className: "text-og-fg-muted", children: [
1573
- ops.length,
1574
- " files"
1575
- ] }),
1576
- /* @__PURE__ */ jsxs6("span", { className: "text-og-fg-subtle", children: [
1577
- "+",
1578
- add,
1579
- " \u2212",
1580
- del
1581
- ] })
1582
- ] }),
1583
- children: ops.map((op, index) => {
1584
- const file2 = parsed[index];
1585
- return file2 ? /* @__PURE__ */ jsx8(ToolDiff, { files: [file2] }, op.path) : /* @__PURE__ */ jsxs6("div", { children: [
1586
- /* @__PURE__ */ jsx8("p", { className: "mb-1 font-og-mono text-og-xs text-og-fg-muted", children: op.path }),
1587
- /* @__PURE__ */ jsx8(RawPatch, { diff: op.diff ?? "" })
1588
- ] }, op.path);
1589
- })
1590
- }
1591
- );
1592
- }
1593
- if (!firstOp) {
1594
- return /* @__PURE__ */ jsx8(GenericRenderer, { item });
1595
- }
1596
- if (firstOp.type === "delete_file") {
1597
- return /* @__PURE__ */ jsx8(
1598
- ActivityDisclosure,
1599
- {
1600
- icon: /* @__PURE__ */ jsx8(FileDiffIcon, { className: ICON_SIZE }),
1601
- iconTone: "failed",
1602
- title: `Deleted ${basename(firstOp.path)}`,
1603
- cancelled,
1604
- preview: /* @__PURE__ */ jsx8(PathPreview, { path: firstOp.path }),
1605
- children: /* @__PURE__ */ jsx8(BodyNote, { children: "File deleted \u2014 no diff to show." })
1606
- }
1607
- );
1608
- }
1609
- const file = safeParseOp(firstOp);
1610
- if (!file) {
1611
- return /* @__PURE__ */ jsx8(
1612
- ActivityDisclosure,
1613
- {
1614
- icon: /* @__PURE__ */ jsx8(FileDiffIcon, { className: ICON_SIZE }),
1615
- iconTone: "accent",
1616
- title: `${verbForOp(firstOp)} ${basename(firstOp.path)}`,
1617
- cancelled,
1618
- preview: /* @__PURE__ */ jsxs6("span", { className: "inline-flex items-center gap-2 font-og-mono", children: [
1619
- /* @__PURE__ */ jsx8("span", { className: "text-og-fg-muted", children: basename(firstOp.path) }),
1620
- /* @__PURE__ */ jsx8("span", { className: "text-og-fg-subtle", children: "malformed V4A" })
1621
- ] }),
1622
- children: /* @__PURE__ */ jsx8(RawPatch, { diff: firstOp.diff ?? "" })
1623
- }
1624
- );
1625
- }
1626
- return /* @__PURE__ */ jsx8(
1627
- ActivityDisclosure,
1628
- {
1629
- icon: /* @__PURE__ */ jsx8(FileDiffIcon, { className: ICON_SIZE }),
1630
- iconTone: "accent",
1631
- title: `${verbForOp(firstOp)} ${basename(file.path)}`,
1632
- cancelled,
1633
- preview: /* @__PURE__ */ jsx8(PathPreview, { path: file.path, add: file.additions, del: file.deletions }),
1634
- children: /* @__PURE__ */ jsx8(ToolDiff, { files: [file] })
1635
- }
1636
- );
1637
- }
1638
- function safeParseOp(op) {
1639
- try {
1640
- return v4aToGitFileDiff(op);
1641
- } catch {
1642
- return null;
1643
- }
1644
- }
1645
- function computerVerb(action) {
1646
- if (!action || !action.type) {
1647
- return "Acted";
1648
- }
1649
- switch (action.type) {
1650
- case "screenshot":
1651
- return "Screenshot";
1652
- case "click":
1653
- return `Clicked (${action.x}, ${action.y})`;
1654
- case "double_click":
1655
- return `Double-clicked (${action.x}, ${action.y})`;
1656
- case "move":
1657
- return `Moved (${action.x}, ${action.y})`;
1658
- case "scroll":
1659
- return "Scrolled";
1660
- case "type": {
1661
- const t = action.text ?? "";
1662
- return `Typed \u201C${t.slice(0, 28)}${t.length > 28 ? "\u2026" : ""}\u201D`;
1663
- }
1664
- case "keypress":
1665
- return `Pressed ${(action.keys ?? []).join("+")}`;
1666
- case "drag":
1667
- return "Dragged";
1668
- case "wait":
1669
- return "Waited";
1670
- default:
1671
- return action.type;
1672
- }
1673
- }
1674
- function asComputerArgs(args) {
1675
- if (!args) {
1676
- return {};
1677
- }
1678
- const parsed = typeof args === "string" ? tryParseJson(args) : args;
1679
- if (!parsed || typeof parsed !== "object") {
1680
- return {};
1681
- }
1682
- const record = parsed;
1683
- return {
1684
- ...typeof record.x === "number" ? { x: record.x } : {},
1685
- ...typeof record.y === "number" ? { y: record.y } : {},
1686
- ...typeof record.text === "string" ? { text: record.text } : {},
1687
- ...Array.isArray(record.keys) ? { keys: record.keys } : {},
1688
- ...typeof record.button === "string" ? { button: record.button } : {}
1689
- };
1690
- }
1691
- function ComputerCallRenderer({ item }) {
1692
- const raw = item.raw ?? {};
1693
- const functionAction = !raw.action && item.name.startsWith("computer_") && item.name !== "computer_call" ? { type: item.name.slice("computer_".length), ...asComputerArgs(item.arguments) } : void 0;
1694
- const action = raw.action ?? functionAction;
1695
- const actions = raw.actions ?? (action ? [action] : []);
1696
- const verb = computerVerb(action);
1697
- const out = item.output;
1698
- const running = item.status === "running";
1699
- const rejected = raw.providerData?.approvalStatus === "rejected";
1700
- const readOnly = typeof out === "string" && out.includes("read-only");
1701
- const shotUrl = screenshotDataUrl(out);
1702
- const omittedMedia = mediaPreviewFact(out);
1703
- const empty = out === "" || out == null;
1704
- const batched = actions.length > 1 ? actions.map((a) => computerVerb(a)).join(" \xB7 ") : null;
1705
- const countSuffix = actions.length > 1 ? ` \xB7${actions.length}` : "";
1706
- const isShot = action?.type === "screenshot";
1707
- if (running) {
1708
- return /* @__PURE__ */ jsx8(
1709
- ActivityDisclosure,
1710
- {
1711
- icon: isShot ? /* @__PURE__ */ jsx8(CameraIcon2, { className: ICON_SIZE }) : /* @__PURE__ */ jsx8(MousePointer2Icon, { className: ICON_SIZE }),
1712
- iconTone: "running",
1713
- title: verb,
1714
- running: true,
1715
- media: /* @__PURE__ */ jsx8(MediaSkeleton, {}),
1716
- children: /* @__PURE__ */ jsx8(BodyNote, { children: "capturing frame\u2026" })
1717
- }
1718
- );
1719
- }
1720
- if (readOnly) {
1721
- return /* @__PURE__ */ jsx8(
1722
- ActivityDisclosure,
1723
- {
1724
- icon: /* @__PURE__ */ jsx8(MousePointer2Icon, { className: ICON_SIZE }),
1725
- iconTone: "failed",
1726
- title: verb,
1727
- chip: { tone: "bad", text: "read-only" },
1728
- preview: "write actions disabled",
1729
- children: /* @__PURE__ */ jsx8(BodyNote, { tone: "error", children: "computer-use is read-only \u2014 write actions are disabled." })
1730
- }
1731
- );
1732
- }
1733
- if (rejected) {
1734
- return /* @__PURE__ */ jsx8(
1735
- ActivityDisclosure,
1736
- {
1737
- icon: /* @__PURE__ */ jsx8(LockIcon, { className: ICON_SIZE }),
1738
- iconTone: "muted",
1739
- title: verb,
1740
- preview: "approval rejected \u2014 this action did not run",
1741
- children: /* @__PURE__ */ jsx8(BodyNote, { children: "approval rejected \u2014 this action did not run." })
1742
- }
1743
- );
1744
- }
1745
- const isFailed = item.status === "failed";
1746
- const isCancelled = item.status === "cancelled";
1747
- if (shotUrl) {
1748
- const caption = `${verb}${actions.length > 1 ? ` (+${actions.length - 1} more)` : ""}`;
1749
- return /* @__PURE__ */ jsxs6(
1750
- ActivityDisclosure,
1751
- {
1752
- icon: isShot ? /* @__PURE__ */ jsx8(CameraIcon2, { className: ICON_SIZE }) : /* @__PURE__ */ jsx8(MousePointer2Icon, { className: ICON_SIZE }),
1753
- iconTone: isFailed ? "failed" : "accent",
1754
- title: `${verb}${countSuffix}`,
1755
- failed: isFailed,
1756
- cancelled: isCancelled,
1757
- media: /* @__PURE__ */ jsx8(Thumbnail, { src: shotUrl, caption }),
1758
- children: [
1759
- /* @__PURE__ */ jsx8(ScreenshotFigure, { src: shotUrl, caption }),
1760
- batched ? /* @__PURE__ */ jsxs6(BodyNote, { children: [
1761
- "batched: ",
1762
- batched
1763
- ] }) : null
1764
- ]
1765
- }
1766
- );
1767
- }
1768
- if (omittedMedia) {
1769
- return /* @__PURE__ */ jsxs6(
1770
- ActivityDisclosure,
1771
- {
1772
- icon: /* @__PURE__ */ jsx8(CameraOffIcon2, { className: ICON_SIZE }),
1773
- iconTone: isFailed ? "failed" : "muted",
1774
- title: `${verb}${countSuffix} \xB7 image omitted \xB7 not retained`,
1775
- failed: isFailed,
1776
- cancelled: isCancelled,
1777
- preview: "inline image omitted \xB7 not retained",
1778
- media: /* @__PURE__ */ jsx8(MediaEmpty, {}),
1779
- children: [
1780
- /* @__PURE__ */ jsxs6(BodyNote, { children: [
1781
- "The inline ",
1782
- omittedMedia.mediaType,
1783
- " output was omitted from the audit timeline and its source bytes were not retained."
1784
- ] }),
1785
- batched ? /* @__PURE__ */ jsxs6(BodyNote, { children: [
1786
- "batched: ",
1787
- batched
1788
- ] }) : null
1789
- ]
1790
- }
1791
- );
1792
- }
1793
- if (empty) {
1794
- return /* @__PURE__ */ jsx8(
1795
- ActivityDisclosure,
1796
- {
1797
- icon: /* @__PURE__ */ jsx8(CameraOffIcon2, { className: ICON_SIZE }),
1798
- iconTone: isFailed ? "failed" : "muted",
1799
- title: verb,
1800
- failed: isFailed,
1801
- cancelled: isCancelled,
1802
- media: /* @__PURE__ */ jsx8(MediaEmpty, {}),
1803
- children: /* @__PURE__ */ jsx8(BodyNote, { children: isFailed ? "computer_call failed \u2014 no image returned." : isCancelled ? "computer_call interrupted \u2014 no image returned." : "(no image) \u2014 the session returned an empty screenshot." })
1804
- }
1805
- );
1806
- }
1807
- return /* @__PURE__ */ jsx8(
1808
- ActivityDisclosure,
1809
- {
1810
- icon: /* @__PURE__ */ jsx8(MousePointer2Icon, { className: ICON_SIZE }),
1811
- iconTone: isFailed ? "failed" : "accent",
1812
- title: verb,
1813
- failed: isFailed,
1814
- cancelled: isCancelled,
1815
- preview: batched ?? void 0,
1816
- expandable: batched != null,
1817
- children: batched ? /* @__PURE__ */ jsx8(BodyNote, { children: batched }) : null
1818
- }
1819
- );
1820
- }
1821
- function WebSearchRenderer({ item }) {
1822
- const raw = item.raw ?? {};
1823
- const action = raw.providerData?.action ?? {};
1824
- const query = action.query ?? "(query unavailable)";
1825
- const queries = action.queries ?? [];
1826
- const variants = queries.length > 1 ? ` +${queries.length - 1} variants` : "";
1827
- const running = item.status === "running";
1828
- const rawResults = item.output?.results;
1829
- const results = Array.isArray(rawResults) ? rawResults.filter((r) => !!r && typeof r === "object") : void 0;
1830
- const resultOccurrences = /* @__PURE__ */ new Map();
1831
- const keyedResults = results?.map((result) => {
1832
- const contentKey = `${result.domain}\0${result.title}\0${result.snippet}`;
1833
- const occurrence = (resultOccurrences.get(contentKey) ?? 0) + 1;
1834
- resultOccurrences.set(contentKey, occurrence);
1835
- return { key: `${contentKey}\0${occurrence}`, result };
1836
- });
1837
- if (running) {
1838
- return /* @__PURE__ */ jsx8(
1839
- ActivityDisclosure,
1840
- {
1841
- icon: /* @__PURE__ */ jsx8(SearchIcon, { className: ICON_SIZE }),
1842
- iconTone: "running",
1843
- title: "Searching the web",
1844
- running: true,
1845
- preview: /* @__PURE__ */ jsx8(RunningPreview, { children: `${query}${variants}` }),
1846
- children: /* @__PURE__ */ jsx8(BodyNote, { children: "searching\u2026 results fold into the model context (no output event)." })
1847
- }
1848
- );
1849
- }
1850
- return /* @__PURE__ */ jsx8(
1851
- ActivityDisclosure,
1852
- {
1853
- icon: /* @__PURE__ */ jsx8(SearchIcon, { className: ICON_SIZE }),
1854
- iconTone: "muted",
1855
- title: "Searched the web",
1856
- preview: `${query}${variants}`,
1857
- failed: item.status === "failed",
1858
- cancelled: item.status === "cancelled",
1859
- children: keyedResults && keyedResults.length ? /* @__PURE__ */ jsx8("ul", { className: "flex flex-col gap-2", children: keyedResults.map(({ key, result }) => /* @__PURE__ */ jsxs6("li", { className: "flex gap-2.5", children: [
1860
- /* @__PURE__ */ jsx8(GlobeIcon, { className: "mt-0.5 size-3.5 shrink-0 text-og-fg-subtle" }),
1861
- /* @__PURE__ */ jsxs6("div", { className: "min-w-0", children: [
1862
- /* @__PURE__ */ jsxs6("p", { className: "truncate text-og-base text-og-fg", children: [
1863
- result.title,
1864
- " ",
1865
- /* @__PURE__ */ jsx8("span", { className: "text-og-fg-subtle", children: result.domain })
1866
- ] }),
1867
- /* @__PURE__ */ jsx8("p", { className: "text-og-sm leading-5 text-og-fg-muted", children: result.snippet })
1868
- ] })
1869
- ] }, key)) }) : /* @__PURE__ */ jsx8(BodyNote, { children: "results folded into model context \u2014 no list available." })
1870
- }
1871
- );
1872
- }
1873
- var VIEW_IMAGE_ERRORS = [
1874
- "was not found",
1875
- "is not a file",
1876
- "exceeded the allowed size",
1877
- "is not a supported image",
1878
- "unable to read image"
1879
- ];
1880
- function ViewImageRenderer({ item }) {
1881
- const args = parseToolArgs(item.arguments);
1882
- const path = typeof args.path === "string" ? args.path : "";
1883
- const out = item.output;
1884
- const text = typeof out === "string" ? out : "";
1885
- const omittedMedia = mediaPreviewFact(out);
1886
- if (item.status === "running") {
1887
- return /* @__PURE__ */ jsx8(
1888
- ActivityDisclosure,
1889
- {
1890
- icon: /* @__PURE__ */ jsx8(ImageIcon, { className: ICON_SIZE }),
1891
- iconTone: "running",
1892
- title: `View ${basename(path)}`,
1893
- running: true,
1894
- preview: /* @__PURE__ */ jsx8(RunningPreview, { children: "reading\u2026" }),
1895
- media: /* @__PURE__ */ jsx8(MediaSkeleton, {}),
1896
- children: /* @__PURE__ */ jsx8(BodyNote, { children: "reading image\u2026" })
1897
- }
1898
- );
1899
- }
1900
- const viewFailed = item.status === "failed";
1901
- const viewCancelled = item.status === "cancelled";
1902
- const errMatch = VIEW_IMAGE_ERRORS.find((p) => text.includes(p));
1903
- if (errMatch) {
1904
- const tooBig = text.includes("exceeded the allowed size");
1905
- return /* @__PURE__ */ jsx8(
1906
- ActivityDisclosure,
1907
- {
1908
- icon: /* @__PURE__ */ jsx8(ImageIcon, { className: ICON_SIZE }),
1909
- iconTone: "failed",
1910
- title: `View ${basename(path)}`,
1911
- chip: { tone: "bad", text: tooBig ? "too large" : "error" },
1912
- preview: text,
1913
- children: /* @__PURE__ */ jsx8(BodyNote, { tone: "error", children: text })
1914
- }
1915
- );
1916
- }
1917
- if (text.startsWith("OpenAI file reference:")) {
1918
- return /* @__PURE__ */ jsx8(
1919
- ActivityDisclosure,
1920
- {
1921
- icon: /* @__PURE__ */ jsx8(ImageIcon, { className: ICON_SIZE }),
1922
- iconTone: viewFailed ? "failed" : "muted",
1923
- title: `Viewed ${basename(path)}`,
1924
- failed: viewFailed,
1925
- cancelled: viewCancelled,
1926
- preview: path,
1927
- children: /* @__PURE__ */ jsx8(BodyNote, { children: text })
1928
- }
1929
- );
1930
- }
1931
- if (omittedMedia) {
1932
- return /* @__PURE__ */ jsx8(
1933
- ActivityDisclosure,
1934
- {
1935
- icon: /* @__PURE__ */ jsx8(ImageIcon, { className: ICON_SIZE }),
1936
- iconTone: viewFailed ? "failed" : "muted",
1937
- title: `Viewed ${basename(path)} \xB7 image omitted \xB7 not retained`,
1938
- failed: viewFailed,
1939
- cancelled: viewCancelled,
1940
- preview: "inline image omitted \xB7 not retained",
1941
- media: /* @__PURE__ */ jsx8(MediaEmpty, {}),
1942
- children: /* @__PURE__ */ jsxs6(BodyNote, { children: [
1943
- "The inline ",
1944
- omittedMedia.mediaType,
1945
- " output was omitted from the audit timeline and its source bytes were not retained."
1946
- ] })
1947
- }
1948
- );
1949
- }
1950
- if (text.includes("No image data")) {
1951
- return /* @__PURE__ */ jsx8(
1952
- ActivityDisclosure,
1953
- {
1954
- icon: /* @__PURE__ */ jsx8(ImageIcon, { className: ICON_SIZE }),
1955
- iconTone: viewFailed ? "failed" : "muted",
1956
- title: `Viewed ${basename(path)}`,
1957
- failed: viewFailed,
1958
- cancelled: viewCancelled,
1959
- preview: "(no image)",
1960
- children: /* @__PURE__ */ jsx8(BodyNote, { children: viewFailed ? "view_image failed \u2014 no image data returned." : viewCancelled ? "view_image interrupted." : "(no image) \u2014 the sandbox session returned no image data." })
1961
- }
1962
- );
1963
- }
1964
- if (text.startsWith("data:")) {
1965
- return /* @__PURE__ */ jsx8(
1966
- ActivityDisclosure,
1967
- {
1968
- icon: /* @__PURE__ */ jsx8(ImageIcon, { className: ICON_SIZE }),
1969
- iconTone: viewFailed ? "failed" : "accent",
1970
- title: `Viewed ${basename(path)}`,
1971
- failed: viewFailed,
1972
- cancelled: viewCancelled,
1973
- media: /* @__PURE__ */ jsx8(Thumbnail, { src: text, caption: path, alt: path }),
1974
- children: /* @__PURE__ */ jsx8(ScreenshotFigure, { src: text, caption: path, alt: path })
1975
- }
1976
- );
1977
- }
1978
- return /* @__PURE__ */ jsx8(GenericRenderer, { item });
1979
- }
1980
- function SecretSetRenderer({ item }) {
1981
- const args = parseToolArgs(item.arguments);
1982
- const name = typeof args.name === "string" ? args.name : "variable";
1983
- if (item.status === "running") {
1984
- return /* @__PURE__ */ jsx8(
1985
- ActivityDisclosure,
1986
- {
1987
- icon: /* @__PURE__ */ jsx8(KeyRoundIcon, { className: ICON_SIZE }),
1988
- iconTone: "running",
1989
- title: `Set ${name}`,
1990
- running: true,
1991
- preview: /* @__PURE__ */ jsx8(RunningPreview, { children: "setting\u2026" }),
1992
- children: /* @__PURE__ */ jsx8(PayloadBlock, { label: "Arguments", value: redactSecrets(args) })
1993
- }
1994
- );
1995
- }
1996
- if (item.status === "failed") {
1997
- const errorText = typeof item.output === "string" ? item.output : null;
1998
- return /* @__PURE__ */ jsxs6(
1999
- ActivityDisclosure,
2000
- {
2001
- icon: /* @__PURE__ */ jsx8(KeyRoundIcon, { className: ICON_SIZE }),
2002
- iconTone: "failed",
2003
- title: `Set ${name}`,
2004
- failed: true,
2005
- preview: errorText ?? "variable write failed",
2006
- children: [
2007
- /* @__PURE__ */ jsx8(PayloadBlock, { label: "Arguments", value: redactSecrets(args) }),
2008
- errorText ? /* @__PURE__ */ jsx8(PayloadBlock, { label: "Error", value: errorText, failed: true }) : /* @__PURE__ */ jsx8(BodyNote, { tone: "error", children: "the tool call failed with no output." })
2009
- ]
2010
- }
2011
- );
2012
- }
2013
- return /* @__PURE__ */ jsxs6(
2014
- ActivityDisclosure,
2015
- {
2016
- icon: /* @__PURE__ */ jsx8(KeyRoundIcon, { className: ICON_SIZE }),
2017
- iconTone: "muted",
2018
- title: `Set ${name}`,
2019
- cancelled: item.status === "cancelled",
2020
- preview: "value write-only \xB7 never returned",
2021
- children: [
2022
- /* @__PURE__ */ jsx8(PayloadBlock, { label: "Arguments", value: redactSecrets(args) }),
2023
- /* @__PURE__ */ jsx8(BodyNote, { children: "the value is a secret \u2014 redacted in every view; the API never returns it." })
2024
- ]
2025
- }
2026
- );
2027
- }
2028
- function GenericRenderer({ item }) {
2029
- const running = item.status === "running";
2030
- const args = redactSecrets(parseToolArgs(item.arguments));
2031
- const display = toolDisplayName(item.name);
2032
- if (running) {
2033
- return /* @__PURE__ */ jsx8(
2034
- ActivityDisclosure,
2035
- {
2036
- icon: /* @__PURE__ */ jsx8(PlugIcon, { className: ICON_SIZE }),
2037
- iconTone: "running",
2038
- title: display,
2039
- running: true,
2040
- preview: /* @__PURE__ */ jsx8(RunningPreview, { children: compactArgs(args) || "running\u2026" }),
2041
- children: /* @__PURE__ */ jsx8(PayloadBlock, { label: "Arguments", value: args })
2042
- }
2043
- );
2044
- }
2045
- const { text: outText, isError } = unwrapMcpOutput(item.output);
2046
- if ((isError || item.status === "failed") && item.status !== "cancelled") {
2047
- return /* @__PURE__ */ jsxs6(
2048
- ActivityDisclosure,
2049
- {
2050
- icon: /* @__PURE__ */ jsx8(WrenchIcon, { className: ICON_SIZE }),
2051
- iconTone: "failed",
2052
- title: display,
2053
- chip: { tone: "bad", text: "error" },
2054
- preview: outText.slice(0, 80),
2055
- children: [
2056
- /* @__PURE__ */ jsx8(PayloadBlock, { label: "Arguments", value: args }),
2057
- /* @__PURE__ */ jsx8(PayloadBlock, { label: "Error", value: outText, failed: true })
2058
- ]
2059
- }
2060
- );
2061
- }
2062
- return /* @__PURE__ */ jsxs6(
2063
- ActivityDisclosure,
2064
- {
2065
- icon: /* @__PURE__ */ jsx8(WrenchIcon, { className: ICON_SIZE }),
2066
- iconTone: "muted",
2067
- title: display,
2068
- cancelled: item.status === "cancelled",
2069
- preview: compactArgs(args),
2070
- children: [
2071
- /* @__PURE__ */ jsx8(PayloadBlock, { label: "Arguments", value: args }),
2072
- /* @__PURE__ */ jsx8(PayloadBlock, { label: "Result", value: outText })
2073
- ]
2074
- }
2075
- );
2076
- }
2077
- function compactArgs(args) {
2078
- const text = stringifyPayload(args).replace(/\s+/g, " ").trim();
2079
- return text === "{}" ? "" : text.length > 90 ? `${text.slice(0, 89)}\u2026` : text;
2080
- }
2081
- var BASE_ENTRIES = [
2082
- // Provider-native items carry `raw.type` on the wire — this is their source of
2083
- // truth and is consulted first by the registry.
2084
- { match: "rawType", type: "apply_patch_call", render: ApplyPatchRenderer },
2085
- { match: "rawType", type: "computer_call", render: ComputerCallRenderer },
2086
- { match: "rawType", type: "hosted_tool_call", render: WebSearchRenderer },
2087
- // First-party sandbox + MCP tools resolve by name. `apply_patch_call` /
2088
- // `computer_call` are intentionally repeated by name as a fallback only for
2089
- // first-party replays that omit `raw` (the rawType entries above win whenever
2090
- // `raw.type` is present, which is the live-wire case).
2091
- { match: "name", name: "exec_command", render: ExecRenderer },
2092
- { match: "name", name: "write_stdin", render: WriteStdinRenderer },
2093
- { match: "name", name: "apply_patch_call", render: ApplyPatchRenderer },
2094
- { match: "name", name: "computer_call", render: ComputerCallRenderer },
2095
- // Function-mode computer tools (codex / chat-wire transports).
2096
- { match: "name", name: "computer_screenshot", render: ComputerCallRenderer },
2097
- { match: "name", name: "computer_click", render: ComputerCallRenderer },
2098
- { match: "name", name: "computer_double_click", render: ComputerCallRenderer },
2099
- { match: "name", name: "computer_move", render: ComputerCallRenderer },
2100
- { match: "name", name: "computer_scroll", render: ComputerCallRenderer },
2101
- { match: "name", name: "computer_type", render: ComputerCallRenderer },
2102
- { match: "name", name: "computer_keypress", render: ComputerCallRenderer },
2103
- { match: "name", name: "computer_drag", render: ComputerCallRenderer },
2104
- { match: "name", name: "web_search_call", render: WebSearchRenderer },
2105
- { match: "name", name: "view_image", render: ViewImageRenderer },
2106
- { match: "name", name: "environment_set_variable", render: SecretSetRenderer }
2107
- ];
2108
- var defaultToolRegistry = createToolRegistry(BASE_ENTRIES, GenericRenderer);
2109
- function createDefaultToolRegistry(options = {}) {
2110
- return createToolRegistry(BASE_ENTRIES, GenericRenderer, options);
2111
- }
2112
-
2113
- // src/timeline/activity-rail.tsx
2114
- import {
2115
- ArrowRightIcon,
2116
- BotIcon,
2117
- BrainCircuitIcon,
2118
- BrainIcon,
2119
- SquareTerminalIcon
2120
- } from "lucide-react";
2121
- import { lazy as lazy3, Suspense as Suspense3 } from "react";
2122
- import { jsx as rowJsx, jsxs as rowJsxs } from "react/jsx-runtime";
2123
-
2124
- // src/timeline/entrance.tsx
2125
- import { createContext as createContext3, useContext as useContext3, useRef as useRef2 } from "react";
2126
- var EntranceAnimationContext = createContext3(true);
2127
- var EntranceAnimationProvider = EntranceAnimationContext.Provider;
2128
- function useEntranceAnimation() {
2129
- const enabled = useContext3(EntranceAnimationContext);
2130
- const captured = useRef2(enabled);
2131
- return captured.current;
2132
- }
2133
-
2134
- // src/timeline/activity-rail.tsx
2135
- import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
2136
- var LazyFleetDecisionRow = lazy3(() => import("./fleet-decision-row-GGCAT4E4.js"));
2137
- function familyOf(item) {
2138
- if (item.kind === "tool-call") {
2139
- return item.name === "exec_command" || item.name === "write_stdin" ? "terminal" : item.name;
2140
- }
2141
- return item.kind;
2142
- }
2143
- function ActivityRail({
2144
- items,
2145
- toolRegistry = defaultToolRegistry,
2146
- onOpenSession,
2147
- onMemoryClick,
2148
- bare,
2149
- className
2150
- }) {
2151
- const enter = useEntranceAnimation();
2152
- return /* @__PURE__ */ jsx9(
2153
- "div",
2154
- {
2155
- className: cn(
2156
- // Rows sit TIGHT by default (gap-0.5) so a same-family run reads as one
2157
- // calm cluster; a family change opens real breathing room (mt-3) below,
2158
- // so a long rail reads as a few clusters, not a metronome of rows.
2159
- "flex flex-col gap-0.5",
2160
- !bare && "border-l-2 border-og-border pl-3 sm:pl-4",
2161
- !bare && enter && "animate-og-enter",
2162
- className
2163
- ),
2164
- children: items.map((item, index) => {
2165
- const newFamily = index > 0 && familyOf(item) !== familyOf(items[index - 1]);
2166
- const row = renderActivity(item, toolRegistry, onOpenSession, onMemoryClick);
2167
- return /* @__PURE__ */ jsx9("div", { "data-og-timeline-row-anchor": "", className: cn(newFamily && "mt-3"), children: row }, item.id);
2168
- })
2169
- }
2170
- );
2171
- }
2172
- function assertNever(item) {
2173
- throw new Error(`ActivityRail: unhandled activity item ${JSON.stringify(item)}`);
2174
- }
2175
- function renderActivity(item, toolRegistry, onOpenSession, onMemoryClick) {
2176
- switch (item.kind) {
2177
- case "reasoning":
2178
- return /* @__PURE__ */ jsx9(ReasoningRow, { item });
2179
- case "tool-call": {
2180
- const Renderer = toolRegistry.resolve(item);
2181
- return /* @__PURE__ */ jsx9(Renderer, { item });
2182
- }
2183
- case "worker":
2184
- return /* @__PURE__ */ jsx9(WorkerRow, { item, onOpenSession });
2185
- case "sandbox":
2186
- return /* @__PURE__ */ jsx9(SandboxRow, { item });
2187
- case "memory":
2188
- return /* @__PURE__ */ jsx9(MemoryRow, { item, onMemoryClick });
2189
- case "fleet-decision":
2190
- return /* @__PURE__ */ jsx9(Suspense3, { fallback: null, children: /* @__PURE__ */ jsx9(
2191
- LazyFleetDecisionRow,
2192
- {
2193
- item,
2194
- d: ActivityDisclosure,
2195
- b: BodyNote,
2196
- j: rowJsx,
2197
- s: rowJsxs
2198
- }
2199
- ) });
2200
- default:
2201
- return assertNever(item);
2202
- }
2203
- }
2204
- function ReasoningRow({ item }) {
2205
- return /* @__PURE__ */ jsx9(
2206
- ActivityDisclosure,
2207
- {
2208
- icon: /* @__PURE__ */ jsx9(BrainIcon, { className: "size-3.5" }),
2209
- iconTone: "muted",
2210
- title: item.streaming ? "Thinking" : /* @__PURE__ */ jsx9("span", { className: "font-normal italic text-og-fg-subtle", children: "Thought" }),
2211
- running: item.streaming,
2212
- preview: truncate(item.text, 110),
2213
- children: /* @__PURE__ */ jsx9("p", { className: "whitespace-pre-wrap text-og-base leading-6 text-og-fg-muted", children: item.text })
2214
- }
2215
- );
2216
- }
2217
- var MEMORY_KIND_LABEL = {
2218
- preference: "Preference",
2219
- semantic: "Fact",
2220
- procedural: "Procedure",
2221
- decision: "Decision",
2222
- episodic: "History"
2223
- };
2224
- function MemoryRow({
2225
- item,
2226
- onMemoryClick
2227
- }) {
2228
- const corrected = item.variant === "corrected";
2229
- const kindLabel = MEMORY_KIND_LABEL[item.memoryKind];
2230
- const superseded = corrected && Boolean(item.replacementPreview);
2231
- const targetId = corrected ? item.replacementMemoryId ?? item.memoryId : item.memoryId;
2232
- const deepLink = Boolean(onMemoryClick);
2233
- return /* @__PURE__ */ jsxs7(
2234
- ActivityDisclosure,
2235
- {
2236
- icon: /* @__PURE__ */ jsx9(BrainCircuitIcon, { className: "size-3.5" }),
2237
- iconTone: "muted",
2238
- title: /* @__PURE__ */ jsxs7("span", { className: "inline-flex min-w-0 items-center gap-2", children: [
2239
- /* @__PURE__ */ jsx9("span", { className: "shrink-0", children: corrected ? "Updated memory" : "Saved to memory" }),
2240
- kindLabel ? /* @__PURE__ */ jsx9("span", { className: "shrink-0 rounded-og-xs bg-og-surface-2 px-1.5 py-px text-og-xs font-normal leading-tight text-og-fg-subtle", children: kindLabel }) : null
2241
- ] }),
2242
- preview: superseded ? item.replacementPreview : item.preview,
2243
- children: [
2244
- superseded ? (
2245
- // The correction as a before → after: the old memory struck through and
2246
- // dimmed, the new text in the ordinary body weight below it.
2247
- /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-1.5", children: [
2248
- /* @__PURE__ */ jsx9("p", { className: "whitespace-pre-wrap text-og-sm leading-6 text-og-fg-subtle line-through", children: item.preview }),
2249
- /* @__PURE__ */ jsx9("p", { className: "whitespace-pre-wrap text-og-base leading-6 text-og-fg-muted", children: item.replacementPreview })
2250
- ] })
2251
- ) : corrected && item.action === "updated" ? (
2252
- // Edited in place, no replacement record: the memory is still live, so
2253
- // show its current text — NOT the archived treatment.
2254
- /* @__PURE__ */ jsxs7(Fragment3, { children: [
2255
- /* @__PURE__ */ jsx9("p", { className: "whitespace-pre-wrap text-og-base leading-6 text-og-fg-muted", children: item.preview }),
2256
- /* @__PURE__ */ jsx9(BodyNote, { tone: "muted", children: "Updated in place." })
2257
- ] })
2258
- ) : corrected ? (
2259
- // A correction with no replacement (and not an in-place update) archived the record.
2260
- /* @__PURE__ */ jsx9(BodyNote, { tone: "muted", children: "Archived." })
2261
- ) : /* @__PURE__ */ jsx9("p", { className: "whitespace-pre-wrap text-og-base leading-6 text-og-fg-muted", children: item.preview }),
2262
- item.deduped ? /* @__PURE__ */ jsx9(BodyNote, { tone: "muted", children: "Merged into an existing memory." }) : null,
2263
- deepLink ? /* @__PURE__ */ jsxs7(
2264
- "button",
2265
- {
2266
- type: "button",
2267
- onClick: () => onMemoryClick?.(targetId),
2268
- className: cn(
2269
- "group/memlink -mx-1 inline-flex w-fit items-center gap-1 rounded-og-sm px-1 py-0.5 text-left text-og-sm text-og-fg-subtle",
2270
- "outline-none transition-colors duration-150 hover:text-og-fg focus-visible:ring-2 focus-visible:ring-og-accent"
2271
- ),
2272
- children: [
2273
- "View in memory",
2274
- /* @__PURE__ */ jsx9(ArrowRightIcon, { className: "size-3.5 transition-transform duration-150 group-hover/memlink:translate-x-0.5" })
2275
- ]
2276
- }
2277
- ) : null
2278
- ]
2279
- }
2280
- );
2281
- }
2282
- function sandboxRowTitle(item) {
2283
- if (item.name === "sandbox.provision") {
2284
- if (item.status === "failed") return "Sandbox didn\u2019t start";
2285
- if (item.status === "running") return "Starting sandbox";
2286
- if (item.origin === "resumed") return "Sandbox reattached";
2287
- if (item.origin === "restored") return "Sandbox restored";
2288
- if (item.origin === "created") return "Sandbox created";
2289
- return "Sandbox ready";
2290
- }
2291
- return toolDisplayName(item.name);
2292
- }
2293
- function SandboxRow({ item }) {
2294
- return /* @__PURE__ */ jsxs7(
2295
- ActivityDisclosure,
2296
- {
2297
- icon: /* @__PURE__ */ jsx9(SquareTerminalIcon, { className: "size-3.5" }),
2298
- iconTone: item.status === "failed" ? "failed" : item.status === "running" ? "running" : "muted",
2299
- title: sandboxRowTitle(item),
2300
- running: item.status === "running",
2301
- failed: item.status === "failed",
2302
- cancelled: item.status === "cancelled",
2303
- preview: item.command ?? void 0,
2304
- children: [
2305
- item.command ? /* @__PURE__ */ jsx9(PayloadBlock, { label: "Command", value: item.command }) : null,
2306
- item.output ? /* @__PURE__ */ jsx9(PayloadBlock, { label: "Output", value: item.output }) : null
2307
- ]
2308
- }
2309
- );
2310
- }
2311
- function WorkerRow({
2312
- item,
2313
- onOpenSession
2314
- }) {
2315
- const running = item.status === "running";
2316
- const failed = item.status === "failed";
2317
- const cancelled = item.status === "cancelled";
2318
- const title = item.action === "spawn" ? running ? "Spawning worker" : failed ? "Worker spawn failed" : cancelled ? "Worker interrupted" : "Worker spawned" : running ? "Messaging worker" : failed ? "Worker message failed" : cancelled ? "Worker interrupted" : "Worker messaged";
2319
- const sessionId = item.workerSessionId;
2320
- const deepLink = Boolean(sessionId) && Boolean(onOpenSession) && !failed && !cancelled;
2321
- const inner = /* @__PURE__ */ jsxs7(Fragment3, { children: [
2322
- /* @__PURE__ */ jsx9("span", { className: "size-3.5 shrink-0", "aria-hidden": true }),
2323
- /* @__PURE__ */ jsx9("span", { className: cn("mt-px shrink-0", failed ? "text-og-status-failed" : "text-og-accent"), children: /* @__PURE__ */ jsx9(BotIcon, { className: "size-3.5" }) }),
2324
- /* @__PURE__ */ jsxs7("div", { className: "min-w-0 flex-1", children: [
2325
- /* @__PURE__ */ jsx9(
2326
- "span",
2327
- {
2328
- className: cn(
2329
- "text-og-base font-medium",
2330
- running ? "og-shimmer-text" : failed ? "text-og-status-failed" : "text-og-fg"
2331
- ),
2332
- children: title
2333
- }
2334
- ),
2335
- item.prompt ? /* @__PURE__ */ jsx9("p", { className: "mt-0.5 truncate text-og-sm text-og-fg-muted", children: truncate(item.prompt, 140) }) : null
2336
- ] }),
2337
- failed ? /* @__PURE__ */ jsxs7("span", { className: "inline-flex shrink-0 self-center items-center gap-1.5 font-og-mono text-og-xs leading-none text-og-status-failed", children: [
2338
- /* @__PURE__ */ jsx9("span", { className: "size-1.5 rounded-full bg-og-status-failed" }),
2339
- "failed"
2340
- ] }) : cancelled ? /* @__PURE__ */ jsx9("span", { className: "og-cancelled-chip shrink-0 self-center font-og-mono text-og-xs leading-none text-og-fg-subtle", children: "interrupted" }) : deepLink ? /* @__PURE__ */ jsx9(
2341
- ArrowRightIcon,
2342
- {
2343
- "aria-hidden": true,
2344
- className: "mt-0.5 size-3.5 shrink-0 text-og-fg-subtle transition-[transform,color] duration-150 group-hover/worker:translate-x-0.5 group-hover/worker:text-og-fg"
2345
- }
2346
- ) : null
2347
- ] });
2348
- if (deepLink && sessionId && onOpenSession) {
2349
- return /* @__PURE__ */ jsx9(
2350
- "button",
2351
- {
2352
- type: "button",
2353
- onClick: () => onOpenSession(sessionId),
2354
- className: cn(
2355
- "group/worker -mx-1.5 flex w-full items-start gap-2 rounded-og-sm px-1.5 py-1.5 text-left",
2356
- "outline-none transition-colors duration-150 hover:bg-og-surface-1 focus-visible:ring-2 focus-visible:ring-og-accent",
2357
- "pointer-coarse:py-2.5"
2358
- ),
2359
- children: inner
2360
- }
2361
- );
2362
- }
2363
- return /* @__PURE__ */ jsx9("div", { className: "flex items-start gap-2 px-1.5 py-1.5", children: inner });
2364
- }
2365
-
2366
- // src/timeline/turn-summary.tsx
2367
- import { CheckIcon, ChevronRightIcon as ChevronRightIcon2, CircleSlashIcon, TriangleAlertIcon } from "lucide-react";
2368
- import { Component, useMemo as useMemo2, useState as useState7 } from "react";
2369
- import { Collapsible as Collapsible2 } from "radix-ui";
2370
- import { Fragment as Fragment4, jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
2371
- var BUILT_IN_TURN_SUMMARY_FACET_IDS = [
2372
- "steps",
2373
- "files",
2374
- "commands",
2375
- "screenshots",
2376
- "memories",
2377
- "duration"
2378
- ];
2379
- function TurnSummary({
2380
- items,
2381
- outcome,
2382
- failureText,
2383
- durationMs,
2384
- defaultOpen,
2385
- bare,
2386
- facets: facetConfiguration,
2387
- children
2388
- }) {
2389
- const forcedDefaultOpen = useForcedDefaultOpen();
2390
- const [open, setOpen] = useState7(defaultOpen ?? forcedDefaultOpen ?? false);
2391
- const enter = useEntranceAnimation();
2392
- const context = useMemo2(
2393
- () => createTurnSummaryContext(items, outcome, failureText, durationMs),
2394
- [items, outcome, failureText, durationMs]
2395
- );
2396
- const facetDefinitions = useMemo2(
2397
- () => resolveTurnSummaryFacets(facetConfiguration),
2398
- [facetConfiguration]
2399
- );
2400
- const facets = useMemo2(
2401
- () => facetDefinitions.flatMap((facet) => {
2402
- try {
2403
- const result = facet.summarize(context);
2404
- return result && hasFacetContent(result.content) ? [{ facet, result }] : [];
2405
- } catch {
2406
- return [];
2407
- }
2408
- }),
2409
- [context, facetDefinitions]
2410
- );
2411
- return /* @__PURE__ */ jsxs8(
2412
- Collapsible2.Root,
2413
- {
2414
- open,
2415
- onOpenChange: setOpen,
2416
- className: enter && !bare ? "animate-og-enter" : void 0,
2417
- children: [
2418
- /* @__PURE__ */ jsxs8(
2419
- Collapsible2.Trigger,
2420
- {
2421
- className: cn(
2422
- // Both the top-level turn fold and a nested cluster fold render as a
2423
- // FLAT rail row — chevron + glyph + facets on the page background, no
2424
- // border, no fill. Only a hover tint hints the row is expandable, so a
2425
- // collapsed turn never reads as a boxed card. The top-level row is a
2426
- // touch larger (base text, size-5 glyph, wider gap) so it still reads
2427
- // as a turn landmark above the nested cluster rows it groups.
2428
- "group flex w-full items-center rounded-og-sm text-left transition-colors",
2429
- // A folded turn is a touch target on coarse pointers: grow the row so it
2430
- // clears the 40px minimum without disturbing the calm desktop rhythm.
2431
- "pointer-coarse:py-2.5",
2432
- bare ? "gap-2 px-1.5 py-1.5 text-og-sm text-og-fg-muted" : "-mx-2 gap-2.5 px-2 py-1.5 text-og-base text-og-fg-muted",
2433
- // A failed fold keeps its red accent (glyph + inline reason below) and a
2434
- // faint red hover wash so attention still lands there; every other
2435
- // outcome gets the neutral surface hover.
2436
- outcome === "failed" ? "hover:bg-og-status-failed/[0.06] hover:text-og-fg" : "hover:bg-og-surface-1 hover:text-og-fg"
2437
- ),
2438
- children: [
2439
- /* @__PURE__ */ jsx10(ChevronRightIcon2, { className: "size-3.5 shrink-0 text-og-fg-subtle transition-transform duration-150 group-data-[state=open]:rotate-90" }),
2440
- /* @__PURE__ */ jsx10(
2441
- "span",
2442
- {
2443
- className: cn(
2444
- "inline-flex shrink-0 items-center justify-center",
2445
- bare ? "size-3.5" : "size-5",
2446
- outcome === "failed" ? "text-og-status-failed" : "text-og-fg-subtle"
2447
- ),
2448
- children: outcome === "failed" ? /* @__PURE__ */ jsx10(TriangleAlertIcon, { className: "size-3" }) : outcome === "cancelled" ? /* @__PURE__ */ jsx10(CircleSlashIcon, { className: "size-3" }) : outcome === "complete" ? /* @__PURE__ */ jsx10(CheckIcon, { className: bare ? "size-3" : "size-3.5" }) : /* @__PURE__ */ jsx10("span", { className: "size-1.5 animate-og-pulse rounded-full bg-og-fg-subtle" })
2449
- }
2450
- ),
2451
- /* @__PURE__ */ jsxs8("span", { className: cn("min-w-0 flex-1 truncate", bare ? "text-og-sm" : "text-og-fg-muted"), children: [
2452
- facets.map(({ facet, result }, index) => /* @__PURE__ */ jsx10(FacetRenderBoundary, { children: /* @__PURE__ */ jsxs8(Fragment4, { children: [
2453
- index > 0 ? " \xB7 " : null,
2454
- /* @__PURE__ */ jsxs8("span", { "aria-label": result.ariaLabel, title: result.title, children: [
2455
- result.icon ? /* @__PURE__ */ jsx10("span", { "aria-hidden": true, className: "mr-1 inline-flex align-[-0.125em]", children: result.icon }) : null,
2456
- result.content
2457
- ] })
2458
- ] }) }, facet.id)),
2459
- outcome === "failed" && failureText ? /* @__PURE__ */ jsxs8("span", { className: "text-og-status-failed", children: [
2460
- " \xB7 ",
2461
- failureText
2462
- ] }) : null,
2463
- outcome === "cancelled" ? /* @__PURE__ */ jsx10("span", { className: "text-og-fg-subtle", children: " \xB7 interrupted" }) : null
2464
- ] }),
2465
- /* @__PURE__ */ jsx10(
2466
- "span",
2467
- {
2468
- "aria-hidden": true,
2469
- className: cn(
2470
- "ml-auto shrink-0 pl-2 text-og-xs text-og-fg-subtle transition-opacity duration-150",
2471
- "opacity-0 group-hover:opacity-100 group-focus-visible:opacity-100",
2472
- "pointer-coarse:opacity-100"
2473
- ),
2474
- children: open ? "hide steps" : "show steps"
2475
- }
2476
- )
2477
- ]
2478
- }
2479
- ),
2480
- /* @__PURE__ */ jsx10(Collapsible2.Content, { className: "overflow-hidden data-[state=closed]:animate-og-collapse data-[state=open]:animate-og-expand", children: /* @__PURE__ */ jsx10("div", { className: bare ? "pt-1 pl-5" : "pt-2", children }) })
2481
- ]
2482
- }
2483
- );
2484
- }
2485
- function createTurnSummaryContext(items, outcome, failureText, durationMs) {
2486
- const itemSnapshot = Object.freeze([...items]);
2487
- const toolCalls = Object.freeze(
2488
- itemSnapshot.filter((item) => item.kind === "tool-call")
2489
- );
2490
- const settled = itemSnapshot.every((item) => {
2491
- if (item.kind === "reasoning") {
2492
- return !item.streaming;
2493
- }
2494
- if (item.kind === "tool-call" || item.kind === "worker" || item.kind === "sandbox") {
2495
- return item.status !== "running";
2496
- }
2497
- return true;
2498
- });
2499
- return Object.freeze({
2500
- items: itemSnapshot,
2501
- toolCalls,
2502
- outcome,
2503
- failureText,
2504
- durationMs,
2505
- settled
2506
- });
2507
- }
2508
- var BUILT_IN_TURN_SUMMARY_FACETS = Object.freeze([
2509
- {
2510
- id: "steps",
2511
- summarize: ({ items }) => ({
2512
- content: `${items.length} ${items.length === 1 ? "step" : "steps"}`
2513
- })
2514
- },
2515
- {
2516
- id: "files",
2517
- summarize: ({ toolCalls }) => {
2518
- let files = 0;
2519
- for (const item of toolCalls) {
2520
- if (isApplyPatch(item)) {
2521
- files += applyPatchOps(item.raw).length;
2522
- }
2523
- }
2524
- return files ? { content: `${files} ${files === 1 ? "file" : "files"} edited` } : null;
2525
- }
2526
- },
2527
- {
2528
- id: "commands",
2529
- summarize: ({ toolCalls }) => {
2530
- const commands = toolCalls.filter((item) => item.name === "exec_command").length;
2531
- return commands ? { content: `${commands} ${commands === 1 ? "command" : "commands"}` } : null;
2532
- }
2533
- },
2534
- {
2535
- id: "screenshots",
2536
- summarize: ({ toolCalls }) => {
2537
- let screenshots = 0;
2538
- for (const item of toolCalls) {
2539
- if ((rawTypeOf(item) === "computer_call" || item.name === "computer_call" || item.name === "computer_screenshot") && (screenshotDataUrl(item.output) !== null || mediaPreviewFact(item.output) !== null)) {
2540
- screenshots += 1;
2541
- }
2542
- }
2543
- return screenshots ? {
2544
- content: `${screenshots} ${screenshots === 1 ? "screenshot" : "screenshots"}`
2545
- } : null;
2546
- }
2547
- },
2548
- {
2549
- id: "memories",
2550
- summarize: ({ items }) => {
2551
- let saved = 0;
2552
- let updated = 0;
2553
- for (const item of items) {
2554
- if (item.kind !== "memory") {
2555
- continue;
2556
- }
2557
- if (item.variant === "corrected") {
2558
- updated += 1;
2559
- } else {
2560
- saved += 1;
2561
- }
2562
- }
2563
- const parts = [];
2564
- if (saved) {
2565
- parts.push(`${saved} ${saved === 1 ? "memory" : "memories"} saved`);
2566
- }
2567
- if (updated) {
2568
- parts.push(`${updated} ${updated === 1 ? "memory" : "memories"} updated`);
2569
- }
2570
- return parts.length > 0 ? { content: parts.join(" \xB7 ") } : null;
2571
- }
2572
- },
2573
- {
2574
- id: "duration",
2575
- summarize: ({ durationMs }) => {
2576
- const duration = formatDurationFacet(durationMs);
2577
- return duration ? { content: duration } : null;
2578
- }
2579
- }
2580
- ]);
2581
- function resolveTurnSummaryFacets(configuration) {
2582
- const requested = configuration?.replace ?? [
2583
- ...BUILT_IN_TURN_SUMMARY_FACETS.filter(
2584
- (facet) => !configuration?.remove?.includes(facet.id)
2585
- ),
2586
- ...configuration?.add ?? []
2587
- ];
2588
- const seen = /* @__PURE__ */ new Set();
2589
- return requested.filter((facet) => {
2590
- if (!facet.id || seen.has(facet.id)) {
2591
- return false;
2592
- }
2593
- seen.add(facet.id);
2594
- return true;
2595
- });
2596
- }
2597
- function hasFacetContent(content) {
2598
- return content !== null && content !== void 0 && content !== false && content !== "";
2599
- }
2600
- var FacetRenderBoundary = class extends Component {
2601
- state = { failed: false };
2602
- static getDerivedStateFromError() {
2603
- return { failed: true };
2604
- }
2605
- render() {
2606
- return this.state.failed ? null : this.props.children;
2607
- }
2608
- };
2609
- function formatDurationFacet(durationMs) {
2610
- if (durationMs === void 0 || !Number.isFinite(durationMs) || durationMs < 1e3) {
2611
- return null;
2612
- }
2613
- const totalSeconds = Math.floor(durationMs / 1e3);
2614
- if (totalSeconds < 60) {
2615
- return `${totalSeconds}s`;
2616
- }
2617
- const totalMinutes = Math.floor(totalSeconds / 60);
2618
- if (totalMinutes < 60) {
2619
- return `${totalMinutes}m`;
2620
- }
2621
- const hours = Math.floor(totalMinutes / 60);
2622
- const minutes = totalMinutes % 60;
2623
- return `${hours}h ${String(minutes).padStart(2, "0")}m`;
2624
- }
2625
-
2626
- // src/components/markdown.tsx
2627
- import { memo } from "react";
2628
- import ReactMarkdown from "react-markdown";
2629
- import remarkGfm from "remark-gfm";
2630
- import { jsx as jsx11 } from "react/jsx-runtime";
2631
- var components = {
2632
- h1: ({ children, ...props }) => /* @__PURE__ */ jsx11(
2633
- "h1",
2634
- {
2635
- className: "mt-5 mb-2.5 text-xl font-semibold tracking-tight text-og-fg first:mt-0",
2636
- ...props,
2637
- children
2638
- }
2639
- ),
2640
- h2: ({ children, ...props }) => /* @__PURE__ */ jsx11("h2", { className: "mt-5 mb-2 text-lg font-semibold tracking-tight text-og-fg first:mt-0", ...props, children }),
2641
- h3: ({ children, ...props }) => /* @__PURE__ */ jsx11(
2642
- "h3",
2643
- {
2644
- className: "mt-4 mb-1.5 text-og-md font-semibold tracking-tight text-og-fg first:mt-0",
2645
- ...props,
2646
- children
2647
- }
2648
- ),
2649
- h4: ({ children, ...props }) => /* @__PURE__ */ jsx11(
2650
- "h4",
2651
- {
2652
- className: "mt-4 mb-1.5 text-og-sm font-semibold uppercase tracking-[0.04em] text-og-fg-muted first:mt-0",
2653
- ...props,
2654
- children
2655
- }
2656
- ),
2657
- p: ({ children, ...props }) => /* @__PURE__ */ jsx11("p", { className: "my-2.5 leading-7 first:mt-0 last:mb-0", ...props, children }),
2658
- strong: ({ children, ...props }) => /* @__PURE__ */ jsx11("strong", { className: "font-semibold text-og-fg", ...props, children }),
2659
- em: ({ children, ...props }) => /* @__PURE__ */ jsx11("em", { className: "italic", ...props, children }),
2660
- a: ({ children, ...props }) => /* @__PURE__ */ jsx11(
2661
- "a",
2662
- {
2663
- className: "break-words font-medium text-og-accent underline-offset-2 hover:underline",
2664
- target: "_blank",
2665
- rel: "noreferrer noopener",
2666
- ...props,
2667
- children
2668
- }
2669
- ),
2670
- ul: ({ children, ...props }) => /* @__PURE__ */ jsx11(
2671
- "ul",
2672
- {
2673
- className: "my-2.5 ml-5 flex list-disc flex-col gap-1 marker:text-og-fg-subtle first:mt-0 last:mb-0",
2674
- ...props,
2675
- children
2676
- }
2677
- ),
2678
- ol: ({ children, ...props }) => /* @__PURE__ */ jsx11(
2679
- "ol",
2680
- {
2681
- className: "my-2.5 ml-5 flex list-decimal flex-col gap-1 marker:text-og-fg-subtle first:mt-0 last:mb-0",
2682
- ...props,
2683
- children
2684
- }
2685
- ),
2686
- // GFM task-list items carry a leading checkbox <input>; `list-none` + a
2687
- // negative margin pull the checkbox back to the bullet column so it aligns
2688
- // with the text.
2689
- li: ({ children, ...props }) => /* @__PURE__ */ jsx11(
2690
- "li",
2691
- {
2692
- className: "leading-7 marker:text-og-fg-subtle [&>ul]:my-1 [&>ol]:my-1 [&:has(>input)]:list-none [&:has(>input)]:-ml-5",
2693
- ...props,
2694
- children
2695
- }
2696
- ),
2697
- input: ({ type, ...props }) => type === "checkbox" ? /* @__PURE__ */ jsx11(
2698
- "input",
2699
- {
2700
- ...props,
2701
- type: "checkbox",
2702
- disabled: true,
2703
- className: "mr-2 size-3.5 translate-y-[2px] cursor-default accent-og-accent align-baseline"
2704
- }
2705
- ) : /* @__PURE__ */ jsx11("input", { type, ...props }),
2706
- blockquote: ({ children, ...props }) => /* @__PURE__ */ jsx11(
2707
- "blockquote",
2708
- {
2709
- className: "my-3 border-l-2 border-og-border-strong pl-3.5 text-og-fg-muted [&>p]:my-1.5 first:mt-0 last:mb-0",
2710
- ...props,
2711
- children
2712
- }
2713
- ),
2714
- hr: (props) => /* @__PURE__ */ jsx11("hr", { className: "my-4 border-0 border-t border-og-border", ...props }),
2715
- // Inline `code` vs fenced code blocks. react-markdown v10 no longer passes an
2716
- // `inline` flag; a fenced block is a <code> whose parent is <pre> (styled by
2717
- // the `pre` renderer), so a `code` reaching here is treated as inline.
2718
- code: ({ children, className: _className, ...props }) => /* @__PURE__ */ jsx11(
2719
- "code",
2720
- {
2721
- className: "rounded-og-xs border border-og-border bg-og-surface-1 px-1 py-0.5 font-og-mono text-og-sm text-og-fg",
2722
- ...props,
2723
- children
2724
- }
2725
- ),
2726
- // Fenced code blocks — mirror the timeline's PayloadBlock <pre> styling for
2727
- // visual consistency (bordered, scrollable, mono, surface background).
2728
- pre: ({ children, ...props }) => /* @__PURE__ */ jsx11(
2729
- "pre",
2730
- {
2731
- className: "my-3 max-h-96 overflow-auto rounded-og-md border border-og-border bg-og-bg/60 p-3 font-og-mono text-og-sm text-og-fg-muted [&>code]:border-0 [&>code]:bg-transparent [&>code]:p-0 [&>code]:text-inherit first:mt-0 last:mb-0",
2732
- ...props,
2733
- children
2734
- }
2735
- ),
2736
- table: ({ children, ...props }) => /* @__PURE__ */ jsx11("div", { className: "my-3 max-w-full overflow-x-auto rounded-og-md border border-og-border first:mt-0 last:mb-0", children: /* @__PURE__ */ jsx11("table", { className: "w-full border-collapse text-og-base", ...props, children }) }),
2737
- thead: ({ children, ...props }) => /* @__PURE__ */ jsx11("thead", { className: "bg-og-surface-1", ...props, children }),
2738
- th: ({ children, ...props }) => /* @__PURE__ */ jsx11(
2739
- "th",
2740
- {
2741
- className: "border-b border-og-border px-3 py-1.5 text-left font-medium text-og-fg",
2742
- ...props,
2743
- children
2744
- }
2745
- ),
2746
- td: ({ children, ...props }) => /* @__PURE__ */ jsx11(
2747
- "td",
2748
- {
2749
- className: "border-b border-og-border px-3 py-1.5 align-top text-og-fg-muted [tr:last-child>&]:border-b-0",
2750
- ...props,
2751
- children
2752
- }
2753
- ),
2754
- img: ({ alt, ...props }) => /* @__PURE__ */ jsx11(
2755
- "img",
2756
- {
2757
- alt: alt ?? "",
2758
- className: "my-3 max-w-full rounded-og-md border border-og-border",
2759
- ...props
2760
- }
2761
- )
2762
- };
2763
- function MarkdownImpl({ children, className }) {
2764
- return (
2765
- // `min-w-0` lets the prose shrink inside flex parents (message bubbles) so
2766
- // long links and code blocks wrap/scroll instead of forcing overflow.
2767
- /* @__PURE__ */ jsx11("div", { className: cn("min-w-0 break-words", className), children: /* @__PURE__ */ jsx11(ReactMarkdown, { remarkPlugins: [remarkGfm], components, children }) })
2768
- );
2769
- }
2770
- var Markdown = memo(MarkdownImpl);
2771
-
2772
- // src/components/session-status.tsx
2773
- import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
2774
- var SESSION_STATUS_META = {
2775
- queued: {
2776
- label: "Queued",
2777
- dotClassName: "bg-og-status-queued",
2778
- badgeClassName: "text-og-fg-muted border-og-border bg-og-status-queued/10",
2779
- pulse: true
2780
- },
2781
- running: {
2782
- label: "Running",
2783
- dotClassName: "bg-og-status-running",
2784
- badgeClassName: "text-og-status-running border-og-status-running/30 bg-og-status-running/10",
2785
- pulse: true
2786
- },
2787
- recovering: {
2788
- label: "Recovering",
2789
- dotClassName: "bg-og-status-running",
2790
- badgeClassName: "text-og-status-running border-og-status-running/30 bg-og-status-running/10",
2791
- pulse: true
2792
- },
2793
- waiting_capacity: {
2794
- label: "Waiting for capacity",
2795
- dotClassName: "bg-og-status-waiting",
2796
- badgeClassName: "text-og-status-waiting border-og-status-waiting/35 bg-og-status-waiting/10",
2797
- pulse: true
2798
- },
2799
- idle: {
2800
- label: "Idle",
2801
- dotClassName: "bg-og-status-idle",
2802
- badgeClassName: "text-og-status-idle border-og-status-idle/30 bg-og-status-idle/10",
2803
- pulse: false
2804
- },
2805
- requires_action: {
2806
- label: "Waiting on you",
2807
- dotClassName: "bg-og-status-waiting",
2808
- badgeClassName: "text-og-status-waiting border-og-status-waiting/35 bg-og-status-waiting/10",
2809
- pulse: true
2810
- },
2811
- failed: {
2812
- label: "Failed",
2813
- dotClassName: "bg-og-status-failed",
2814
- badgeClassName: "text-og-status-failed border-og-status-failed/35 bg-og-status-failed/10",
2815
- pulse: false
2816
- },
2817
- cancelled: {
2818
- label: "Cancelled",
2819
- dotClassName: "bg-og-status-cancelled",
2820
- badgeClassName: "text-og-fg-subtle border-og-border bg-og-status-cancelled/10",
2821
- pulse: false
2822
- }
2823
- };
2824
- function SessionStatus({ status, label, size = "md", className }) {
2825
- const meta = SESSION_STATUS_META[status];
2826
- return /* @__PURE__ */ jsxs9(
2827
- "span",
2828
- {
2829
- "data-status": status,
2830
- className: cn(
2831
- "og-root inline-flex shrink-0 items-center rounded-full border font-medium",
2832
- size === "sm" ? "gap-1 px-1.5 py-px text-og-xs" : "gap-1.5 px-2 py-0.5 text-xs",
2833
- meta.badgeClassName,
2834
- className
2835
- ),
2836
- children: [
2837
- /* @__PURE__ */ jsx12(StatusDot, { status, className: size === "sm" ? "size-1" : "size-1.5" }),
2838
- label ?? meta.label
2839
- ]
2840
- }
2841
- );
2842
- }
2843
- function StatusDot({ status, className }) {
2844
- const meta = SESSION_STATUS_META[status];
2845
- return /* @__PURE__ */ jsx12(
2846
- "span",
2847
- {
2848
- className: cn(
2849
- "relative inline-flex size-1.5 shrink-0 rounded-full",
2850
- meta.dotClassName,
2851
- className
2852
- ),
2853
- children: meta.pulse ? /* @__PURE__ */ jsx12("span", { className: cn("absolute inset-0 animate-og-pulse rounded-full", meta.dotClassName) }) : null
2854
- }
2855
- );
2856
- }
2857
-
2858
- // src/components/message-timeline.tsx
2859
- import {
2860
- ArrowDownIcon,
2861
- ArrowRightIcon as ArrowRightIcon2,
2862
- BotIcon as BotIcon2,
2863
- CheckCircle2Icon,
2864
- CheckIcon as CheckIcon2,
2865
- ChevronRightIcon as ChevronRightIcon3,
2866
- PauseCircleIcon,
2867
- PauseIcon,
2868
- PencilLineIcon,
2869
- PlayIcon,
2870
- RefreshCwIcon,
2871
- TargetIcon,
2872
- Trash2Icon,
2873
- TriangleAlertIcon as TriangleAlertIcon2,
2874
- XCircleIcon
2875
- } from "lucide-react";
2876
- import { AnimatePresence as AnimatePresence2, motion as motion2 } from "motion/react";
2877
- import { Collapsible as Collapsible3 } from "radix-ui";
2878
- import {
2879
- memo as memo2,
2880
- useCallback as useCallback2,
2881
- useEffect as useEffect4,
2882
- useLayoutEffect,
2883
- useMemo as useMemo3,
2884
- useRef as useRef3,
2885
- useState as useState8
2886
- } from "react";
2887
- import { Fragment as Fragment5, jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
2888
- var INITIAL_MOUNTED_GROUPS = 1;
2889
- function MessageTimeline({
2890
- events,
2891
- items,
2892
- status,
2893
- renderMessageText,
2894
- onOpenSession,
2895
- onMemoryClick,
2896
- onReconnect,
2897
- resolveProviderLogo,
2898
- toolRegistry = defaultToolRegistry,
2899
- turnSummary,
2900
- autoFollow = true,
2901
- hasOlder = false,
2902
- loadingOlder = false,
2903
- onLoadOlder,
2904
- emptyState,
2905
- className
2906
- }) {
2907
- const resolvedItems = useMemo3(() => items ?? buildTimeline(events ?? []), [items, events]);
2908
- const allGroups = useMemo3(() => groupTimeline(resolvedItems), [resolvedItems]);
2909
- const keyedGroups = useStableTimelineGroupKeys(allGroups);
2910
- const { mountedGroups: groups, mountingOlderGroups } = useProgressivelyMountedGroups(keyedGroups);
2911
- const firstGroupKey = allGroups[0] ? timelineGroupKey(allGroups[0]) : null;
2912
- const scrollRef = useRef3(null);
2913
- const topSentinelRef = useRef3(null);
2914
- const previousBulkFirstKeyRef = useRef3(void 0);
2915
- const [pinned, setPinned] = useState8(true);
2916
- const [bulkActive, setBulkActive] = useState8(true);
2917
- const [revealed, setRevealed] = useState8(false);
2918
- const programmaticScrollTargetsRef = useRef3([]);
2919
- const assignScrollTop = useCallback2((node, value) => {
2920
- const previous = node.scrollTop;
2921
- node.scrollTop = value;
2922
- if (node.scrollTop === previous) {
2923
- return;
2924
- }
2925
- const pending = programmaticScrollTargetsRef.current;
2926
- pending.push(node.scrollTop);
2927
- if (pending.length > 32) {
2928
- pending.splice(0, pending.length - 32);
2929
- }
2930
- }, []);
2931
- const pinnedRef = useRef3(true);
2932
- const anchorRef = useRef3(null);
2933
- const lastItem = resolvedItems[resolvedItems.length - 1];
2934
- const streaming = lastItem !== void 0 && (lastItem.kind === "agent-message" || lastItem.kind === "reasoning") && lastItem.streaming;
2935
- const working = status === "running" && !streaming;
2936
- const firstKeyChangedForBulk = previousBulkFirstKeyRef.current !== void 0 && previousBulkFirstKeyRef.current !== firstGroupKey;
2937
- const bulkRender = allGroups.length > 0 && (bulkActive || firstKeyChangedForBulk || mountingOlderGroups);
2938
- const captureAnchor = useCallback2(() => {
2939
- const node = scrollRef.current;
2940
- const inner = node?.firstElementChild;
2941
- if (!node || !inner) {
2942
- anchorRef.current = null;
2943
- return;
2944
- }
2945
- const containerTop = node.getBoundingClientRect().top;
2946
- const findVisible = (selector) => {
2947
- for (const candidate of inner.querySelectorAll(selector)) {
2948
- if (candidate instanceof HTMLElement && candidate.dataset.ogTimelineChrome !== void 0) {
2949
- continue;
2950
- }
2951
- const rect = candidate.getBoundingClientRect();
2952
- if (rect.bottom > containerTop + 1 && rect.height > 0) {
2953
- return candidate;
2954
- }
2955
- }
2956
- return null;
2957
- };
2958
- const anchor = findVisible("[data-og-timeline-row-anchor]") ?? findVisible("[data-og-timeline-group-anchor]");
2959
- if (anchor) {
2960
- const rect = anchor.getBoundingClientRect();
2961
- anchorRef.current = { el: anchor, top: rect.top - containerTop };
2962
- return;
2963
- }
2964
- anchorRef.current = null;
2965
- }, []);
2966
- const restoreAnchor = useCallback2(
2967
- (node) => {
2968
- if (autoFollow && pinnedRef.current) {
2969
- assignScrollTop(node, node.scrollHeight);
2970
- return;
2971
- }
2972
- const anchor = anchorRef.current;
2973
- if (!anchor || !anchor.el.isConnected) {
2974
- return;
2975
- }
2976
- const containerTop = node.getBoundingClientRect().top;
2977
- const now = anchor.el.getBoundingClientRect().top - containerTop;
2978
- const diff = now - anchor.top;
2979
- if (diff !== 0) {
2980
- assignScrollTop(node, node.scrollTop + diff);
2981
- }
2982
- },
2983
- [assignScrollTop, autoFollow]
2984
- );
2985
- useLayoutEffect(() => {
2986
- const node = scrollRef.current;
2987
- if (node) {
2988
- restoreAnchor(node);
2989
- }
2990
- if (!revealed && groups.length > 0) {
2991
- setRevealed(true);
2992
- }
2993
- }, [resolvedItems, working, revealed, groups.length, restoreAnchor]);
2994
- useLayoutEffect(() => {
2995
- if (allGroups.length === 0 && revealed) {
2996
- setRevealed(false);
2997
- }
2998
- }, [allGroups.length, revealed]);
2999
- useLayoutEffect(() => {
3000
- previousBulkFirstKeyRef.current = firstGroupKey;
3001
- if (!bulkRender) {
3002
- return;
3003
- }
3004
- setBulkActive(true);
3005
- if (mountingOlderGroups) {
3006
- return;
3007
- }
3008
- const frame = requestFrame(() => setBulkActive(false));
3009
- return () => cancelFrame(frame);
3010
- }, [bulkRender, firstGroupKey, mountingOlderGroups]);
3011
- useEffect4(() => {
3012
- const root = scrollRef.current;
3013
- const target = topSentinelRef.current;
3014
- if (!root || !target || mountingOlderGroups || !hasOlder || loadingOlder || !onLoadOlder || typeof IntersectionObserver === "undefined") {
3015
- return;
3016
- }
3017
- const observer = new IntersectionObserver(
3018
- (entries) => {
3019
- if (entries.some((entry) => entry.isIntersecting)) {
3020
- onLoadOlder();
3021
- }
3022
- },
3023
- { root, rootMargin: "1600px 0px 0px 0px" }
3024
- );
3025
- observer.observe(target);
3026
- return () => observer.disconnect();
3027
- }, [hasOlder, loadingOlder, onLoadOlder, firstGroupKey, mountingOlderGroups]);
3028
- useEffect4(() => {
3029
- const node = scrollRef.current;
3030
- const inner = node?.firstElementChild;
3031
- if (!node || !inner || typeof ResizeObserver === "undefined") {
3032
- return;
3033
- }
3034
- const observer = new ResizeObserver(() => {
3035
- const current = scrollRef.current;
3036
- if (!current) {
3037
- return;
3038
- }
3039
- restoreAnchor(current);
3040
- });
3041
- observer.observe(inner);
3042
- return () => observer.disconnect();
3043
- }, [restoreAnchor]);
3044
- const onScroll = () => {
3045
- const node = scrollRef.current;
3046
- if (!node) {
3047
- return;
3048
- }
3049
- const pending = programmaticScrollTargetsRef.current;
3050
- const programmaticIndex = pending.findIndex((target) => Math.abs(node.scrollTop - target) <= 1);
3051
- const programmatic = programmaticIndex >= 0;
3052
- if (programmatic) {
3053
- pending.splice(0, programmaticIndex + 1);
3054
- } else {
3055
- pending.length = 0;
3056
- }
3057
- const nextPinned = node.scrollHeight - node.scrollTop - node.clientHeight < 48;
3058
- if (nextPinned || !programmatic) {
3059
- pinnedRef.current = nextPinned;
3060
- setPinned(nextPinned);
3061
- }
3062
- if (!programmatic) {
3063
- captureAnchor();
3064
- }
3065
- };
3066
- return /* @__PURE__ */ jsx13(LightboxProvider, { children: /* @__PURE__ */ jsx13(EntranceAnimationProvider, { value: !bulkRender, children: /* @__PURE__ */ jsxs10("div", { className: cn("og-root relative flex min-h-0 flex-col", className), children: [
3067
- /* @__PURE__ */ jsx13(
3068
- "div",
3069
- {
3070
- ref: scrollRef,
3071
- onScroll,
3072
- style: groups.length > 0 && !revealed ? { visibility: "hidden" } : void 0,
3073
- className: "min-h-0 flex-1 overflow-y-auto overscroll-contain px-4 py-6 [overflow-anchor:none] sm:px-6",
3074
- children: /* @__PURE__ */ jsxs10("div", { className: "mx-auto flex w-full max-w-3xl flex-col gap-5", children: [
3075
- groups.length === 0 && !working ? emptyState ?? /* @__PURE__ */ jsx13("p", { className: "py-10 text-center text-sm text-og-fg-subtle", children: "No activity yet." }) : null,
3076
- hasOlder && !mountingOlderGroups ? /* @__PURE__ */ jsx13(
3077
- "div",
3078
- {
3079
- ref: topSentinelRef,
3080
- "data-og-top-sentinel": "",
3081
- "data-og-timeline-chrome": "",
3082
- "aria-hidden": "true",
3083
- className: "h-px w-full shrink-0"
3084
- }
3085
- ) : null,
3086
- loadingOlder ? /* @__PURE__ */ jsx13("div", { "data-og-timeline-chrome": "", className: "flex items-center gap-2 text-sm", children: /* @__PURE__ */ jsx13("span", { className: "og-shimmer-text font-medium", children: "Loading earlier activity\u2026" }) }) : null,
3087
- groups.map(({ group, key }, index) => /* @__PURE__ */ jsx13("div", { "data-og-timeline-group-anchor": "", children: /* @__PURE__ */ jsx13(
3088
- TimelineGroupView,
3089
- {
3090
- group,
3091
- renderMessageText,
3092
- onOpenSession,
3093
- onMemoryClick,
3094
- onReconnect,
3095
- resolveProviderLogo,
3096
- toolRegistry,
3097
- turnSummary,
3098
- foldLiveCluster: isAgentProgress(groups[index + 1]?.group)
3099
- }
3100
- ) }, key)),
3101
- working ? /* @__PURE__ */ jsx13("div", { className: "flex items-center gap-2 text-sm", children: /* @__PURE__ */ jsx13("span", { className: "og-shimmer-text font-medium", children: "Working\u2026" }) }) : null
3102
- ] })
3103
- }
3104
- ),
3105
- /* @__PURE__ */ jsx13(AnimatePresence2, { children: !pinned && autoFollow ? /* @__PURE__ */ jsxs10(
3106
- motion2.button,
3107
- {
3108
- type: "button",
3109
- initial: { opacity: 0, y: 8 },
3110
- animate: { opacity: 1, y: 0 },
3111
- exit: { opacity: 0, y: 8 },
3112
- transition: { duration: 0.15, ease: "easeOut" },
3113
- onClick: () => {
3114
- const node = scrollRef.current;
3115
- if (node) {
3116
- node.scrollTo({ top: node.scrollHeight, behavior: "smooth" });
3117
- }
3118
- pinnedRef.current = true;
3119
- setPinned(true);
3120
- },
3121
- className: cn(
3122
- "absolute bottom-4 left-1/2 -translate-x-1/2",
3123
- "inline-flex items-center gap-1.5 rounded-full border border-og-border bg-og-surface-3/90 px-3 py-1.5",
3124
- "text-xs font-medium text-og-fg shadow-og-md backdrop-blur",
3125
- "hover:border-og-border-strong"
3126
- ),
3127
- children: [
3128
- /* @__PURE__ */ jsx13(ArrowDownIcon, { className: "size-3.5" }),
3129
- "Jump to latest"
3130
- ]
3131
- }
3132
- ) : null })
3133
- ] }) }) });
3134
- }
3135
- function useStableTimelineGroupKeys(allGroups) {
3136
- const previousRef = useRef3([]);
3137
- const keyedGroups = useMemo3(() => {
3138
- const previousByItemId = /* @__PURE__ */ new Map();
3139
- for (const previous of previousRef.current) {
3140
- for (const itemId of timelineGroupItemIds(previous.group)) {
3141
- previousByItemId.set(itemId, previous);
3142
- }
3143
- }
3144
- const usedKeys = /* @__PURE__ */ new Set();
3145
- return allGroups.map((group, index) => {
3146
- const itemIds = timelineGroupItemIds(group);
3147
- let retainedKey;
3148
- for (const itemId of itemIds) {
3149
- const previous = previousByItemId.get(itemId);
3150
- if (previous && !usedKeys.has(previous.key)) {
3151
- retainedKey = previous.key;
3152
- break;
3153
- }
3154
- }
3155
- const canonicalKey = timelineGroupKey(group);
3156
- let key = retainedKey ?? canonicalKey;
3157
- let collision = 0;
3158
- while (usedKeys.has(key)) {
3159
- key = `${canonicalKey}:${index}:${collision}`;
3160
- collision += 1;
3161
- }
3162
- usedKeys.add(key);
3163
- return { group, key };
3164
- });
3165
- }, [allGroups]);
3166
- useLayoutEffect(() => {
3167
- previousRef.current = keyedGroups;
3168
- }, [keyedGroups]);
3169
- return keyedGroups;
3170
- }
3171
- function useProgressivelyMountedGroups(allGroups) {
3172
- const previousGroupKeysRef = useRef3([]);
3173
- const groupKeys = useMemo3(() => {
3174
- const nextKeys = allGroups.map((group) => group.key);
3175
- const previousKeys = previousGroupKeysRef.current;
3176
- return nextKeys.length === previousKeys.length && nextKeys.every((key, index) => key === previousKeys[index]) ? previousKeys : nextKeys;
3177
- }, [allGroups]);
3178
- useLayoutEffect(() => {
3179
- previousGroupKeysRef.current = groupKeys;
3180
- }, [groupKeys]);
3181
- const [window2, setWindow] = useState8(() => ({
3182
- groupKeys,
3183
- visibleStart: Math.max(0, allGroups.length - INITIAL_MOUNTED_GROUPS)
3184
- }));
3185
- const lastPossibleStart = Math.max(0, allGroups.length - INITIAL_MOUNTED_GROUPS);
3186
- let visibleStart = 0;
3187
- if (allGroups.length > 0) {
3188
- const currentIndexByKey = new Map(groupKeys.map((key, index) => [key, index]));
3189
- let retainedStart;
3190
- for (const key of window2.groupKeys.slice(window2.visibleStart)) {
3191
- const index = currentIndexByKey.get(key);
3192
- if (index !== void 0) {
3193
- retainedStart = index;
3194
- break;
3195
- }
3196
- }
3197
- visibleStart = retainedStart === void 0 ? lastPossibleStart : Math.min(retainedStart, lastPossibleStart);
3198
- }
3199
- useEffect4(() => {
3200
- if (window2.groupKeys !== groupKeys || window2.visibleStart !== visibleStart) {
3201
- setWindow({ groupKeys, visibleStart });
3202
- return;
3203
- }
3204
- if (visibleStart === 0) {
3205
- return;
3206
- }
3207
- const frame = requestFrame(() => {
3208
- setWindow(
3209
- (current) => current.groupKeys === groupKeys && current.visibleStart > 0 ? { ...current, visibleStart: current.visibleStart - 1 } : current
3210
- );
3211
- });
3212
- return () => cancelFrame(frame);
3213
- }, [groupKeys, visibleStart, window2.groupKeys, window2.visibleStart]);
3214
- return {
3215
- mountedGroups: allGroups.slice(visibleStart),
3216
- mountingOlderGroups: visibleStart > 0
3217
- };
3218
- }
3219
- function requestFrame(callback) {
3220
- if (typeof requestAnimationFrame === "function") {
3221
- return requestAnimationFrame(callback);
3222
- }
3223
- return window.setTimeout(() => callback(performance.now()), 16);
3224
- }
3225
- function cancelFrame(id) {
3226
- if (typeof cancelAnimationFrame === "function") {
3227
- cancelAnimationFrame(id);
3228
- return;
3229
- }
3230
- window.clearTimeout(id);
3231
- }
3232
- var TimelineGroupView = memo2(function TimelineGroupView2({
3233
- group,
3234
- renderMessageText,
3235
- onOpenSession,
3236
- onMemoryClick,
3237
- onReconnect,
3238
- resolveProviderLogo,
3239
- toolRegistry,
3240
- turnSummary,
3241
- insideTurn = false,
3242
- foldLiveCluster = false
3243
- }) {
3244
- switch (group.kind) {
3245
- case "activity":
3246
- return group.outcome || foldLiveCluster && clusterIsSettled(group) ? /* @__PURE__ */ jsx13(
3247
- TurnSummary,
3248
- {
3249
- items: group.items,
3250
- outcome: group.outcome,
3251
- failureText: insideTurn ? void 0 : group.failureText,
3252
- defaultOpen: !insideTurn && group.outcome === "failed" ? true : void 0,
3253
- bare: insideTurn,
3254
- facets: turnSummary?.facets,
3255
- children: /* @__PURE__ */ jsx13(
3256
- ActivityRail,
3257
- {
3258
- items: group.items,
3259
- onOpenSession,
3260
- onMemoryClick,
3261
- toolRegistry,
3262
- bare: insideTurn
3263
- }
3264
- )
3265
- }
3266
- ) : (
3267
- // A nested live cluster hangs on the turn's rail (bare); a top-level one
3268
- // owns its own rail.
3269
- /* @__PURE__ */ jsx13(
3270
- ActivityRail,
3271
- {
3272
- items: group.items,
3273
- onOpenSession,
3274
- onMemoryClick,
3275
- toolRegistry,
3276
- bare: insideTurn
3277
- }
3278
- )
3279
- );
3280
- case "turn": {
3281
- const activityItems = flattenActivityItems(group.groups);
3282
- const body = group.groups.map((child) => /* @__PURE__ */ jsx13(
3283
- TimelineGroupView2,
3284
- {
3285
- group: child,
3286
- renderMessageText,
3287
- onOpenSession,
3288
- onMemoryClick,
3289
- onReconnect,
3290
- resolveProviderLogo,
3291
- toolRegistry,
3292
- turnSummary,
3293
- insideTurn: true
3294
- },
3295
- timelineGroupKey(child)
3296
- ));
3297
- return /* @__PURE__ */ jsx13(
3298
- TurnSummary,
3299
- {
3300
- items: activityItems,
3301
- outcome: group.outcome,
3302
- failureText: insideTurn ? void 0 : group.failureText,
3303
- durationMs: durationBetween(group.startedAt, group.endedAt),
3304
- defaultOpen: !insideTurn && group.outcome === "failed" ? true : void 0,
3305
- bare: insideTurn,
3306
- facets: turnSummary?.facets,
3307
- children: insideTurn ? (
3308
- // A nested turn is already on an ancestor rail — its body just stacks
3309
- // flush (the bare-node body already indents it), so no second rule.
3310
- /* @__PURE__ */ jsx13("div", { className: "flex flex-col gap-4", children: body })
3311
- ) : (
3312
- // The top-level turn draws THE rail: one thin continuous rule that
3313
- // every nested node and step hangs off of.
3314
- /* @__PURE__ */ jsx13("div", { className: "flex flex-col gap-4 border-l-2 border-og-border pl-3 sm:pl-4", children: body })
3315
- )
3316
- }
3317
- );
3318
- }
3319
- case "item":
3320
- return /* @__PURE__ */ jsx13(
3321
- TimelineRow,
3322
- {
3323
- item: group.item,
3324
- renderMessageText,
3325
- onReconnect,
3326
- resolveProviderLogo,
3327
- onOpenSession
3328
- }
3329
- );
3330
- }
3331
- });
3332
- function timelineGroupKey(group) {
3333
- switch (group.kind) {
3334
- case "item":
3335
- return group.item.id;
3336
- case "activity":
3337
- return group.id;
3338
- case "turn":
3339
- return group.id;
3340
- }
3341
- }
3342
- function timelineGroupItemIds(group) {
3343
- switch (group.kind) {
3344
- case "item":
3345
- return [group.item.id];
3346
- case "activity":
3347
- return group.items.map((item) => item.id);
3348
- case "turn":
3349
- return group.groups.flatMap(timelineGroupItemIds);
3350
- }
3351
- }
3352
- function isAgentProgress(next) {
3353
- if (!next) {
3354
- return false;
3355
- }
3356
- return next.kind === "activity" || next.kind === "turn" || next.kind === "item" && next.item.kind === "agent-message";
3357
- }
3358
- function clusterIsSettled(group) {
3359
- return group.items.every((item) => {
3360
- if (item.kind === "reasoning") {
3361
- return !item.streaming;
3362
- }
3363
- if (item.kind === "memory" || item.kind === "fleet-decision") {
3364
- return true;
3365
- }
3366
- return item.status !== "running";
3367
- });
3368
- }
3369
- function flattenActivityItems(groups) {
3370
- const items = [];
3371
- for (const group of groups) {
3372
- if (group.kind === "activity") {
3373
- items.push(...group.items);
3374
- } else if (group.kind === "turn") {
3375
- items.push(...flattenActivityItems(group.groups));
3376
- }
3377
- }
3378
- return items;
3379
- }
3380
- function durationBetween(startedAt, endedAt) {
3381
- const started = Date.parse(startedAt);
3382
- const ended = Date.parse(endedAt);
3383
- if (!Number.isFinite(started) || !Number.isFinite(ended) || ended < started) {
3384
- return void 0;
3385
- }
3386
- return ended - started;
3387
- }
3388
- function TimelineRow({
3389
- item,
3390
- renderMessageText,
3391
- onReconnect,
3392
- resolveProviderLogo,
3393
- onOpenSession
3394
- }) {
3395
- switch (item.kind) {
3396
- case "user-message":
3397
- return /* @__PURE__ */ jsx13(UserMessageRow, { item, renderMessageText });
3398
- case "agent-message":
3399
- return /* @__PURE__ */ jsx13(AgentMessageRow, { item, renderMessageText });
3400
- case "worker-completion":
3401
- return /* @__PURE__ */ jsx13(WorkerCompletionRow, { item, onOpenSession });
3402
- case "session-status":
3403
- return /* @__PURE__ */ jsx13(SessionStatusRow, { item });
3404
- case "goal":
3405
- return /* @__PURE__ */ jsx13(GoalRow, { item });
3406
- case "machine-input-batch":
3407
- return /* @__PURE__ */ jsx13(MachineInputBatchRow, { item });
3408
- case "notice":
3409
- return /* @__PURE__ */ jsx13(NoticeRow, { item });
3410
- case "auth-needed":
3411
- return /* @__PURE__ */ jsx13(
3412
- AuthNeededRow,
3413
- {
3414
- item,
3415
- onReconnect,
3416
- resolveProviderLogo
3417
- }
3418
- );
3419
- default:
3420
- return null;
3421
- }
3422
- }
3423
- function UserMessageRow({
3424
- item,
3425
- renderMessageText
3426
- }) {
3427
- const enter = useEntranceAnimation();
3428
- return /* @__PURE__ */ jsx13("div", { className: cn(enter && "animate-og-enter", "flex justify-end"), children: /* @__PURE__ */ jsx13("div", { className: "flex max-w-[85%] min-w-0 flex-col items-end gap-1", children: /* @__PURE__ */ jsx13("div", { className: "w-fit max-w-full min-w-0 rounded-og-lg rounded-br-og-xs border border-og-border bg-og-surface-2 px-4 py-2.5 text-og-md leading-6 text-og-fg", children: renderMessageText ? renderMessageText(item.text, item) : /* @__PURE__ */ jsx13(Markdown, { children: item.text }) }) }) });
3429
- }
3430
- function AgentMessageRow({
3431
- item,
3432
- renderMessageText
3433
- }) {
3434
- const enter = useEntranceAnimation();
3435
- const caret = item.streaming ? /* @__PURE__ */ jsx13(
3436
- "span",
3437
- {
3438
- className: "ml-0.5 inline-block h-[1.1em] w-[2px] translate-y-[3px] animate-og-blink rounded-full bg-og-accent",
3439
- "aria-hidden": true
3440
- }
3441
- ) : null;
3442
- return /* @__PURE__ */ jsx13("div", { className: cn(enter && "animate-og-enter", "min-w-0 text-og-md leading-7 text-og-fg"), children: renderMessageText ? /* @__PURE__ */ jsxs10(Fragment5, { children: [
3443
- renderMessageText(item.text, item),
3444
- caret
3445
- ] }) : (
3446
- // While streaming, let the caret ride the end of the last rendered line:
3447
- // the trailing block (usually a <p>) flows inline so the caret sits on
3448
- // its baseline instead of dropping to a new line.
3449
- /* @__PURE__ */ jsxs10("div", { className: item.streaming ? "[&_>div>:last-child]:inline" : void 0, children: [
3450
- /* @__PURE__ */ jsx13(Markdown, { children: item.text }),
3451
- caret
3452
- ] })
3453
- ) });
3454
- }
3455
- function workerCompletionMeta(item) {
3456
- if (item.childStatus === "failed") {
3457
- return {
3458
- label: "Worker failed",
3459
- icon: XCircleIcon,
3460
- iconClass: "text-og-status-failed",
3461
- accentClass: "border-og-status-failed/60"
3462
- };
3463
- }
3464
- if (item.goalStatus === "paused") {
3465
- return {
3466
- label: "Worker paused",
3467
- icon: PauseCircleIcon,
3468
- iconClass: "text-og-status-waiting",
3469
- accentClass: "border-og-status-waiting/50"
3470
- };
3471
- }
3472
- if (item.goalStatus === "completed") {
3473
- return {
3474
- label: "Worker completed",
3475
- icon: CheckCircle2Icon,
3476
- iconClass: "text-og-status-idle",
3477
- accentClass: "border-og-status-idle/45"
3478
- };
3479
- }
3480
- return {
3481
- label: "Worker reported back",
3482
- icon: BotIcon2,
3483
- iconClass: "text-og-accent",
3484
- accentClass: "border-og-border-strong"
3485
- };
3486
- }
3487
- function WorkerCompletionRow({
3488
- item,
3489
- onOpenSession
3490
- }) {
3491
- const enter = useEntranceAnimation();
3492
- const [open, setOpen] = useState8(false);
3493
- const meta = workerCompletionMeta(item);
3494
- const Icon = meta.icon;
3495
- const showPausedReason = item.childStatus !== "failed" && item.goalStatus === "paused" && Boolean(item.pausedReason?.trim());
3496
- const details = [
3497
- ...item.text.trim() ? [{ label: "Report", value: item.text.trim() }] : [],
3498
- ...item.evidence?.trim() ? [{ label: "Evidence", value: item.evidence.trim(), muted: true }] : [],
3499
- ...showPausedReason ? [{ label: "Paused because", value: item.pausedReason.trim(), muted: true }] : []
3500
- ];
3501
- const hasDetails = details.length > 0;
3502
- return /* @__PURE__ */ jsx13("div", { className: cn(enter && "animate-og-enter", "min-w-0"), children: /* @__PURE__ */ jsxs10("div", { className: cn("flex flex-col gap-2 border-l-2 pl-3", meta.accentClass), children: [
3503
- /* @__PURE__ */ jsxs10("div", { className: "flex items-start gap-2.5", children: [
3504
- /* @__PURE__ */ jsx13("span", { className: cn("mt-0.5 shrink-0", meta.iconClass), children: /* @__PURE__ */ jsx13(Icon, { className: "size-4" }) }),
3505
- /* @__PURE__ */ jsx13("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsxs10("p", { className: "text-og-base leading-5 text-og-fg", children: [
3506
- /* @__PURE__ */ jsx13("span", { className: "font-medium", children: meta.label }),
3507
- item.goalText ? /* @__PURE__ */ jsxs10("span", { className: "text-og-fg-muted", children: [
3508
- " \xB7 ",
3509
- truncate(item.goalText, 90)
3510
- ] }) : null
3511
- ] }) }),
3512
- item.childSessionId && onOpenSession ? /* @__PURE__ */ jsxs10(
3513
- "button",
3514
- {
3515
- type: "button",
3516
- onClick: () => onOpenSession(item.childSessionId),
3517
- className: cn(
3518
- "-my-0.5 -mr-1 inline-flex shrink-0 items-center gap-1 rounded-og-sm px-2 py-1 text-og-sm font-medium text-og-fg-muted pointer-coarse:py-2",
3519
- "outline-none transition-colors duration-150 hover:bg-og-surface-2 hover:text-og-fg",
3520
- "focus-visible:ring-2 focus-visible:ring-og-accent"
3521
- ),
3522
- children: [
3523
- "View session",
3524
- /* @__PURE__ */ jsx13(ArrowRightIcon2, { className: "size-3.5" })
3525
- ]
3526
- }
3527
- ) : null
3528
- ] }),
3529
- hasDetails ? /* @__PURE__ */ jsxs10(Collapsible3.Root, { open, onOpenChange: setOpen, children: [
3530
- /* @__PURE__ */ jsx13(Collapsible3.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs10(
3531
- "button",
3532
- {
3533
- type: "button",
3534
- className: cn(
3535
- "group/wc -mx-1 inline-flex w-fit items-center gap-1 rounded-og-sm px-1 py-0.5 text-og-xs font-medium text-og-fg-subtle",
3536
- "outline-none transition-colors duration-150 hover:text-og-fg-muted focus-visible:ring-2 focus-visible:ring-og-accent"
3537
- ),
3538
- children: [
3539
- /* @__PURE__ */ jsx13(ChevronRightIcon3, { className: "size-3 transition-transform duration-150 ease-og-in-out group-data-[state=open]/wc:rotate-90" }),
3540
- open ? "Hide details" : "Show details"
3541
- ]
3542
- }
3543
- ) }),
3544
- /* @__PURE__ */ jsx13(Collapsible3.Content, { className: "overflow-hidden data-[state=closed]:animate-og-collapse data-[state=open]:animate-og-expand", children: /* @__PURE__ */ jsx13("div", { className: "ml-1 mt-1.5 flex flex-col gap-2.5", children: details.map((detail) => /* @__PURE__ */ jsxs10("div", { className: "min-w-0", children: [
3545
- /* @__PURE__ */ jsx13("p", { className: "mb-1 text-og-xs font-medium uppercase tracking-[0.08em] text-og-fg-subtle", children: detail.label }),
3546
- /* @__PURE__ */ jsx13(
3547
- "p",
3548
- {
3549
- className: cn(
3550
- "whitespace-pre-wrap break-words text-og-sm leading-6",
3551
- detail.muted ? "text-og-fg-subtle" : "text-og-fg-muted"
3552
- ),
3553
- children: detail.value
3554
- }
3555
- )
3556
- ] }, detail.label)) }) })
3557
- ] }) : null
3558
- ] }) });
3559
- }
3560
- function SessionStatusRow({ item }) {
3561
- const enter = useEntranceAnimation();
3562
- const meta = SESSION_STATUS_META[item.status];
3563
- return /* @__PURE__ */ jsxs10(
3564
- "div",
3565
- {
3566
- className: cn(
3567
- enter && "animate-og-enter",
3568
- "flex items-center gap-3 text-og-xs text-og-fg-subtle"
3569
- ),
3570
- role: "status",
3571
- children: [
3572
- /* @__PURE__ */ jsx13("span", { className: "h-px flex-1 bg-og-border" }),
3573
- /* @__PURE__ */ jsxs10("span", { className: "inline-flex items-center gap-1.5", children: [
3574
- /* @__PURE__ */ jsx13(StatusDot, { status: item.status, className: "size-1" }),
3575
- meta.label.toLowerCase(),
3576
- " \xB7 ",
3577
- formatRelativeTime(item.occurredAt)
3578
- ] }),
3579
- /* @__PURE__ */ jsx13("span", { className: "h-px flex-1 bg-og-border" })
3580
- ]
3581
- }
3582
- );
3583
- }
3584
- var NEUTRAL_PILL = "border-og-border bg-og-surface-1 text-og-fg-muted";
3585
- var GOAL_META = {
3586
- set: {
3587
- label: "Goal set",
3588
- pill: "border-og-accent/30 bg-og-accent/10 text-og-accent",
3589
- icon: TargetIcon
3590
- },
3591
- updated: { label: "Goal updated", pill: NEUTRAL_PILL, icon: PencilLineIcon },
3592
- completed: {
3593
- label: "Goal completed",
3594
- pill: "border-og-status-idle/30 bg-og-status-idle/10 text-og-status-idle",
3595
- icon: CheckIcon2
3596
- },
3597
- paused: {
3598
- label: "Goal paused",
3599
- pill: "border-og-status-waiting/35 bg-og-status-waiting/10 text-og-status-waiting",
3600
- icon: PauseIcon
3601
- },
3602
- resumed: { label: "Goal resumed", pill: NEUTRAL_PILL, icon: PlayIcon },
3603
- cleared: { label: "Goal cleared", pill: NEUTRAL_PILL, icon: Trash2Icon },
3604
- continuation: { label: "Continuing toward the goal", pill: NEUTRAL_PILL, icon: ArrowRightIcon2 }
3605
- };
3606
- function GoalRow({ item }) {
3607
- const enter = useEntranceAnimation();
3608
- const { label, pill, icon: Icon } = GOAL_META[item.action];
3609
- return /* @__PURE__ */ jsx13("div", { className: cn(enter && "animate-og-enter", "flex justify-center"), children: /* @__PURE__ */ jsxs10(
3610
- "span",
3611
- {
3612
- className: cn(
3613
- "inline-flex max-w-full items-center gap-1.5 rounded-full border px-3 py-1 text-og-sm",
3614
- pill
3615
- ),
3616
- children: [
3617
- /* @__PURE__ */ jsx13(Icon, { className: "size-3.5 shrink-0" }),
3618
- /* @__PURE__ */ jsxs10("span", { className: "truncate", children: [
3619
- label,
3620
- item.text ? `: ${truncate(item.text, 90)}` : ""
3621
- ] })
3622
- ]
3623
- }
3624
- ) });
3625
- }
3626
- var MACHINE_INPUT_META = {
3627
- scheduled_occurrence: "Scheduled update",
3628
- goal_continuation: "Goal continued",
3629
- agent_message: "Agent update",
3630
- agent_steer_instruction: "Agent direction",
3631
- child_terminal_result: "Agent finished"
3632
- };
3633
- function MachineInputBatchRow({ item }) {
3634
- const enter = useEntranceAnimation();
3635
- const visible = item.members.slice(0, 3);
3636
- return /* @__PURE__ */ jsxs10(
3637
- "div",
3638
- {
3639
- className: cn(
3640
- enter && "animate-og-enter",
3641
- "rounded-og-md border border-og-border/70 bg-og-surface-1/55 px-3 py-2.5"
3642
- ),
3643
- children: [
3644
- item.members.length > 1 && /* @__PURE__ */ jsxs10("div", { className: "mb-2 text-xs font-medium text-og-fg-subtle", children: [
3645
- item.members.length,
3646
- " updates joined this turn"
3647
- ] }),
3648
- /* @__PURE__ */ jsx13("div", { className: "space-y-2", children: visible.map((member) => /* @__PURE__ */ jsx13(MachineInputRow, { member }, member.id)) }),
3649
- item.members.length > visible.length && /* @__PURE__ */ jsxs10("details", { className: "mt-2 pl-8 text-xs text-og-fg-muted", children: [
3650
- /* @__PURE__ */ jsxs10("summary", { className: "cursor-pointer select-none hover:text-og-fg", children: [
3651
- "Show ",
3652
- item.members.length - visible.length,
3653
- " more"
3654
- ] }),
3655
- /* @__PURE__ */ jsx13("div", { className: "mt-2 space-y-2", children: item.members.slice(visible.length).map((member) => /* @__PURE__ */ jsx13(MachineInputRow, { member }, member.id)) })
3656
- ] })
3657
- ]
3658
- }
3659
- );
3660
- }
3661
- function MachineInputRow({ member }) {
3662
- const source = readableMachineInputSource(member.sourceId);
3663
- return /* @__PURE__ */ jsxs10("div", { className: "flex min-w-0 items-start gap-2.5", children: [
3664
- /* @__PURE__ */ jsx13("span", { className: "mt-2 size-1.5 shrink-0 rounded-full bg-og-fg-subtle", "aria-hidden": true }),
3665
- /* @__PURE__ */ jsxs10("div", { className: "min-w-0 flex-1", children: [
3666
- /* @__PURE__ */ jsx13("span", { className: "text-xs font-medium text-og-fg-muted", children: MACHINE_INPUT_META[member.kind] }),
3667
- source && /* @__PURE__ */ jsxs10("span", { className: "ml-1.5 text-xs text-og-fg-subtle", children: [
3668
- "from ",
3669
- source
3670
- ] }),
3671
- member.summary && /* @__PURE__ */ jsx13("p", { className: "mt-0.5 whitespace-pre-wrap break-words text-sm leading-5 text-og-fg", children: truncate(cleanMachineInputSummary(member.summary), 320) })
3672
- ] })
3673
- ] });
3674
- }
3675
- function readableMachineInputSource(sourceId) {
3676
- const value = sourceId.trim();
3677
- if (!value || /^[0-9a-f]{8}-[0-9a-f-]{27,}$/i.test(value)) return null;
3678
- if (/^(goal|schedule|system):/i.test(value)) return null;
3679
- return value.replaceAll("_", " ");
3680
- }
3681
- function cleanMachineInputSummary(summary) {
3682
- return summary.replace(/^\[[A-Z][A-Z _-]*(?:\s+\d+\/\d+)?\]\s*/, "").trim();
3683
- }
3684
- function NoticeRow({ item }) {
3685
- const enter = useEntranceAnimation();
3686
- const tone = item.tone === "failed" ? "border-og-status-failed/35 bg-og-status-failed/10 text-og-status-failed" : item.tone === "waiting" ? "border-og-status-waiting/35 bg-og-status-waiting/10 text-og-status-waiting" : "border-og-border bg-og-surface-1 text-og-fg-muted";
3687
- return /* @__PURE__ */ jsxs10(
3688
- "div",
3689
- {
3690
- className: cn(
3691
- enter && "animate-og-enter",
3692
- "flex items-start gap-2.5 rounded-og-md border px-3.5 py-2.5 text-sm",
3693
- tone
3694
- ),
3695
- role: "status",
3696
- children: [
3697
- /* @__PURE__ */ jsx13(
3698
- TriangleAlertIcon2,
3699
- {
3700
- className: cn("mt-0.5 size-4 shrink-0", item.tone === "cancelled" && "opacity-60")
3701
- }
3702
- ),
3703
- /* @__PURE__ */ jsxs10("div", { className: "min-w-0 flex-1", children: [
3704
- /* @__PURE__ */ jsx13("span", { className: "whitespace-pre-wrap break-words", children: item.text }),
3705
- item.details ? /* @__PURE__ */ jsxs10("details", { className: "mt-2 text-xs", children: [
3706
- /* @__PURE__ */ jsx13("summary", { className: "cursor-pointer font-medium", children: item.details.label }),
3707
- /* @__PURE__ */ jsx13("pre", { className: "mt-2 max-h-64 overflow-auto whitespace-pre-wrap break-all rounded-og-sm bg-black/5 p-2 font-mono dark:bg-white/5", children: JSON.stringify(item.details.value, null, 2) })
3708
- ] }) : null
3709
- ] }),
3710
- item.action ? /* @__PURE__ */ jsx13(
3711
- "a",
3712
- {
3713
- className: "shrink-0 rounded-og-sm border border-current/25 px-2 py-1 text-xs font-medium hover:bg-current/10",
3714
- href: item.action.url,
3715
- rel: "noreferrer",
3716
- target: "_blank",
3717
- children: item.action.label
3718
- }
3719
- ) : null
3720
- ]
3721
- }
3722
- );
3723
- }
3724
- function AuthNeededRow({
3725
- item,
3726
- onReconnect,
3727
- resolveProviderLogo
3728
- }) {
3729
- const enter = useEntranceAnimation();
3730
- const [busy, setBusy] = useState8(false);
3731
- const [failed, setFailed] = useState8(false);
3732
- const provider = providerLabel(item.providerDomain);
3733
- const unavailable = item.reason === "unsupported_auth" || item.reason === "resource_scope_unavailable";
3734
- const missing = item.reason === "missing_connection";
3735
- const actionLabel = missing ? "Connect" : "Reconnect";
3736
- const start = async () => {
3737
- if (!onReconnect || busy) {
3738
- return;
3739
- }
3740
- setBusy(true);
3741
- setFailed(false);
3742
- try {
3743
- await onReconnect(item);
3744
- setBusy(false);
3745
- } catch {
3746
- setFailed(true);
3747
- setBusy(false);
3748
- }
3749
- };
3750
- return /* @__PURE__ */ jsxs10("div", { className: cn(enter && "animate-og-enter", "flex flex-col gap-2"), role: "status", children: [
3751
- /* @__PURE__ */ jsxs10("div", { className: "flex flex-col gap-3 rounded-og-lg border border-og-border bg-og-surface-1 px-3.5 py-3 sm:flex-row sm:items-center", children: [
3752
- /* @__PURE__ */ jsxs10("div", { className: "flex min-w-0 flex-1 items-center gap-3", children: [
3753
- /* @__PURE__ */ jsx13(
3754
- AuthProviderLogo,
3755
- {
3756
- src: resolveProviderLogo?.(item.providerDomain) ?? null,
3757
- label: provider
3758
- }
3759
- ),
3760
- /* @__PURE__ */ jsxs10("div", { className: "min-w-0", children: [
3761
- /* @__PURE__ */ jsx13("p", { className: "truncate text-og-md font-medium text-og-fg", children: unavailable ? `${provider} tools unavailable` : `${actionLabel} ${provider}` }),
3762
- /* @__PURE__ */ jsx13("p", { className: "truncate text-og-sm text-og-fg-subtle", children: authReasonLine(item.reason) })
3763
- ] })
3764
- ] }),
3765
- !unavailable && onReconnect ? /* @__PURE__ */ jsxs10(
3766
- "button",
3767
- {
3768
- type: "button",
3769
- onClick: () => void start(),
3770
- disabled: busy,
3771
- className: cn(
3772
- "inline-flex w-full shrink-0 items-center justify-center gap-1.5 rounded-og-md bg-og-accent px-3 py-1.5 text-sm font-medium text-og-accent-fg sm:w-auto",
3773
- "transition-colors hover:bg-og-accent-strong disabled:opacity-70 pointer-coarse:min-h-9"
3774
- ),
3775
- children: [
3776
- /* @__PURE__ */ jsx13(RefreshCwIcon, { className: cn("size-3.5", busy && "animate-og-spin"), "aria-hidden": true }),
3777
- busy ? "Opening\u2026" : actionLabel
3778
- ]
3779
- }
3780
- ) : !unavailable && item.authorizationUrl ? /* @__PURE__ */ jsxs10(
3781
- "a",
3782
- {
3783
- href: item.authorizationUrl,
3784
- rel: "noreferrer",
3785
- target: "_blank",
3786
- className: cn(
3787
- "inline-flex w-full shrink-0 items-center justify-center gap-1.5 rounded-og-md bg-og-accent px-3 py-1.5 text-sm font-medium text-og-accent-fg sm:w-auto",
3788
- "transition-colors hover:bg-og-accent-strong pointer-coarse:min-h-9"
3789
- ),
3790
- children: [
3791
- /* @__PURE__ */ jsx13(RefreshCwIcon, { className: "size-3.5", "aria-hidden": true }),
3792
- actionLabel
3793
- ]
3794
- }
3795
- ) : null
3796
- ] }),
3797
- !unavailable ? /* @__PURE__ */ jsxs10("p", { className: "px-1 text-og-xs text-og-fg-subtle", children: [
3798
- "This tool call wasn't replayed. After ",
3799
- missing ? "connecting" : "reconnecting",
3800
- ", send a new message to try again."
3801
- ] }) : null,
3802
- failed ? /* @__PURE__ */ jsxs10("p", { className: "px-1 text-og-xs text-og-status-failed", children: [
3803
- "Couldn't start ",
3804
- missing ? "connecting" : "reconnecting",
3805
- " ",
3806
- provider,
3807
- ". Try again."
3808
- ] }) : null
3809
- ] });
3810
- }
3811
- function AuthProviderLogo({ src, label }) {
3812
- const [failed, setFailed] = useState8(false);
3813
- useEffect4(() => setFailed(false), [src]);
3814
- const showImage = src && !failed;
3815
- return /* @__PURE__ */ jsx13(
3816
- "span",
3817
- {
3818
- className: "relative flex size-10 shrink-0 items-center justify-center overflow-hidden rounded-og-md border border-og-border bg-og-surface-2 text-sm font-semibold text-og-fg-muted",
3819
- "aria-hidden": true,
3820
- children: showImage ? /* @__PURE__ */ jsx13(
3821
- "img",
3822
- {
3823
- src,
3824
- alt: "",
3825
- loading: "lazy",
3826
- decoding: "async",
3827
- className: "size-full object-contain p-1.5",
3828
- onError: () => setFailed(true)
3829
- }
3830
- ) : /* @__PURE__ */ jsx13("span", { children: monogram(label) })
3831
- }
3832
- );
3833
- }
3834
- function monogram(label) {
3835
- const words = label.trim().split(/\s+/).filter(Boolean);
3836
- if (words.length === 0) {
3837
- return "?";
3838
- }
3839
- if (words.length === 1) {
3840
- return words[0].slice(0, 2).toUpperCase();
3841
- }
3842
- return (words[0][0] + words[1][0]).toUpperCase();
3843
- }
3844
- function providerLabel(domain) {
3845
- const host = domain.trim().replace(/^https?:\/\//, "").replace(/^www\./, "").split("/")[0] ?? "";
3846
- const first = host.split(".")[0] ?? host;
3847
- if (!first) {
3848
- return "this service";
3849
- }
3850
- return first.charAt(0).toUpperCase() + first.slice(1);
3851
- }
3852
- function authReasonLine(reason) {
3853
- switch (reason) {
3854
- case "insufficient_scope":
3855
- return "It needs additional access to continue.";
3856
- case "missing_connection":
3857
- return "It isn't connected yet.";
3858
- case "expired":
3859
- case "refresh_failed":
3860
- return "Its access expired.";
3861
- case "unsupported_auth":
3862
- return "This connection cannot authenticate the configured tool endpoint.";
3863
- case "resource_scope_unavailable":
3864
- return "This tool endpoint cannot enforce the selected repository access.";
3865
- default:
3866
- return "Its connection needs attention.";
3867
- }
3868
- }
3869
-
3870
- export {
3871
- QueueSurface,
3872
- defaultHumanInputFormMessages,
3873
- HumanInputForm,
3874
- answersFromDrafts,
3875
- rawTypeOf,
3876
- createToolRegistry,
3877
- sandboxCommandExitCode,
3878
- parseExecBannerSessionId,
3879
- stripExecBanner,
3880
- execTruncated,
3881
- isExecSessionLostBanner,
3882
- looksBinary,
3883
- controlCaret,
3884
- v4aToGitFileDiff,
3885
- applyPatchOps,
3886
- isApplyPatch,
3887
- redactSecrets,
3888
- parseToolArgs,
3889
- tailPeek,
3890
- unwrapMcpOutput,
3891
- DisclosureDefaultsProvider,
3892
- useLightbox,
3893
- useLightboxOptional,
3894
- LightboxProvider,
3895
- ActivityDisclosure,
3896
- TermBlock,
3897
- PayloadBlock,
3898
- BodyNote,
3899
- MediaSkeleton,
3900
- MediaEmpty,
3901
- Thumbnail,
3902
- ScreenshotFigure,
3903
- useThemeType,
3904
- gitFileDiffToPatch,
3905
- PierreDiff,
3906
- defaultToolRegistry,
3907
- createDefaultToolRegistry,
3908
- ActivityRail,
3909
- BUILT_IN_TURN_SUMMARY_FACET_IDS,
3910
- TurnSummary,
3911
- Markdown,
3912
- SESSION_STATUS_META,
3913
- SessionStatus,
3914
- StatusDot,
3915
- MessageTimeline,
3916
- TimelineRow
3917
- };
3918
- //# sourceMappingURL=chunk-ZMNPFZWL.js.map