@sandbox-agent/react 0.3.1 → 0.3.2

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.
package/dist/index.d.ts CHANGED
@@ -1,7 +1,174 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { CSSProperties } from 'react';
2
+ import { RefObject, ReactNode, KeyboardEvent, Ref, TextareaHTMLAttributes, CSSProperties } from 'react';
3
3
  import { SandboxAgent, TerminalExitStatus, TerminalErrorStatus } from 'sandbox-agent';
4
4
 
5
+ type PermissionReply = "once" | "always" | "reject";
6
+ type PermissionOption = {
7
+ optionId: string;
8
+ name: string;
9
+ kind: string;
10
+ };
11
+ type TranscriptEntry = {
12
+ id: string;
13
+ eventId?: string;
14
+ kind: "message" | "tool" | "meta" | "reasoning" | "permission";
15
+ time: string;
16
+ role?: "user" | "assistant";
17
+ text?: string;
18
+ toolName?: string;
19
+ toolInput?: string;
20
+ toolOutput?: string;
21
+ toolStatus?: string;
22
+ reasoning?: {
23
+ text: string;
24
+ visibility?: string;
25
+ };
26
+ meta?: {
27
+ title: string;
28
+ detail?: string;
29
+ severity?: "info" | "error";
30
+ };
31
+ permission?: {
32
+ permissionId: string;
33
+ title: string;
34
+ description?: string;
35
+ options: PermissionOption[];
36
+ resolved?: boolean;
37
+ selectedOptionId?: string;
38
+ };
39
+ };
40
+ interface AgentTranscriptClassNames {
41
+ root: string;
42
+ divider: string;
43
+ dividerLine: string;
44
+ dividerText: string;
45
+ message: string;
46
+ messageContent: string;
47
+ messageText: string;
48
+ error: string;
49
+ toolGroupSingle: string;
50
+ toolGroupContainer: string;
51
+ toolGroupHeader: string;
52
+ toolGroupIcon: string;
53
+ toolGroupLabel: string;
54
+ toolGroupChevron: string;
55
+ toolGroupBody: string;
56
+ toolItem: string;
57
+ toolItemConnector: string;
58
+ toolItemDot: string;
59
+ toolItemLine: string;
60
+ toolItemContent: string;
61
+ toolItemHeader: string;
62
+ toolItemIcon: string;
63
+ toolItemLabel: string;
64
+ toolItemSpinner: string;
65
+ toolItemLink: string;
66
+ toolItemChevron: string;
67
+ toolItemBody: string;
68
+ toolSection: string;
69
+ toolSectionTitle: string;
70
+ toolCode: string;
71
+ toolCodeMuted: string;
72
+ permissionPrompt: string;
73
+ permissionHeader: string;
74
+ permissionIcon: string;
75
+ permissionTitle: string;
76
+ permissionDescription: string;
77
+ permissionActions: string;
78
+ permissionButton: string;
79
+ permissionAutoResolved: string;
80
+ thinkingRow: string;
81
+ thinkingAvatar: string;
82
+ thinkingAvatarImage: string;
83
+ thinkingAvatarLabel: string;
84
+ thinkingIndicator: string;
85
+ thinkingDot: string;
86
+ endAnchor: string;
87
+ }
88
+ interface PermissionOptionRenderContext {
89
+ entry: TranscriptEntry;
90
+ option: PermissionOption;
91
+ label: string;
92
+ reply: PermissionReply;
93
+ selected: boolean;
94
+ dimmed: boolean;
95
+ resolved: boolean;
96
+ }
97
+ interface AgentTranscriptProps {
98
+ entries: TranscriptEntry[];
99
+ className?: string;
100
+ classNames?: Partial<AgentTranscriptClassNames>;
101
+ endRef?: RefObject<HTMLDivElement>;
102
+ sessionError?: string | null;
103
+ eventError?: string | null;
104
+ isThinking?: boolean;
105
+ agentId?: string;
106
+ onEventClick?: (eventId: string) => void;
107
+ onPermissionReply?: (permissionId: string, reply: PermissionReply) => void;
108
+ isDividerEntry?: (entry: TranscriptEntry) => boolean;
109
+ canOpenEvent?: (entry: TranscriptEntry) => boolean;
110
+ getToolGroupSummary?: (entries: TranscriptEntry[]) => string;
111
+ renderMessageText?: (entry: TranscriptEntry) => ReactNode;
112
+ renderInlinePendingIndicator?: () => ReactNode;
113
+ renderThinkingState?: (context: {
114
+ agentId?: string;
115
+ }) => ReactNode;
116
+ renderToolItemIcon?: (entry: TranscriptEntry) => ReactNode;
117
+ renderToolGroupIcon?: (entries: TranscriptEntry[], expanded: boolean) => ReactNode;
118
+ renderChevron?: (expanded: boolean) => ReactNode;
119
+ renderEventLinkContent?: (entry: TranscriptEntry) => ReactNode;
120
+ renderPermissionIcon?: (entry: TranscriptEntry) => ReactNode;
121
+ renderPermissionOptionContent?: (context: PermissionOptionRenderContext) => ReactNode;
122
+ }
123
+ declare const AgentTranscript: ({ entries, className, classNames: classNameOverrides, endRef, sessionError, eventError, isThinking, agentId, onEventClick, onPermissionReply, isDividerEntry, canOpenEvent, getToolGroupSummary, renderMessageText, renderInlinePendingIndicator, renderThinkingState, renderToolItemIcon, renderToolGroupIcon, renderChevron, renderEventLinkContent, renderPermissionIcon, renderPermissionOptionContent, }: AgentTranscriptProps) => react_jsx_runtime.JSX.Element;
124
+
125
+ interface ChatComposerClassNames {
126
+ root: string;
127
+ form: string;
128
+ input: string;
129
+ submit: string;
130
+ submitContent: string;
131
+ }
132
+ interface ChatComposerProps {
133
+ message: string;
134
+ onMessageChange: (value: string) => void;
135
+ onSubmit: () => void;
136
+ onKeyDown?: (event: KeyboardEvent<HTMLTextAreaElement>) => void;
137
+ placeholder?: string;
138
+ disabled?: boolean;
139
+ submitDisabled?: boolean;
140
+ allowEmptySubmit?: boolean;
141
+ submitLabel?: string;
142
+ className?: string;
143
+ classNames?: Partial<ChatComposerClassNames>;
144
+ inputRef?: Ref<HTMLTextAreaElement>;
145
+ rows?: number;
146
+ textareaProps?: Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, "className" | "disabled" | "onChange" | "onKeyDown" | "placeholder" | "rows" | "value">;
147
+ renderSubmitContent?: () => ReactNode;
148
+ renderFooter?: () => ReactNode;
149
+ }
150
+ declare const ChatComposer: ({ message, onMessageChange, onSubmit, onKeyDown, placeholder, disabled, submitDisabled, allowEmptySubmit, submitLabel, className, classNames: classNameOverrides, inputRef, rows, textareaProps, renderSubmitContent, renderFooter, }: ChatComposerProps) => react_jsx_runtime.JSX.Element;
151
+
152
+ interface AgentConversationClassNames {
153
+ root: string;
154
+ transcript: string;
155
+ emptyState: string;
156
+ composer: string;
157
+ }
158
+ interface AgentConversationProps {
159
+ entries: TranscriptEntry[];
160
+ className?: string;
161
+ classNames?: Partial<AgentConversationClassNames>;
162
+ emptyState?: ReactNode;
163
+ transcriptClassName?: string;
164
+ transcriptClassNames?: Partial<AgentTranscriptClassNames>;
165
+ composerClassName?: string;
166
+ composerClassNames?: Partial<ChatComposerClassNames>;
167
+ transcriptProps?: Omit<AgentTranscriptProps, "entries" | "className" | "classNames">;
168
+ composerProps?: Omit<ChatComposerProps, "className" | "classNames">;
169
+ }
170
+ declare const AgentConversation: ({ entries, className, classNames: classNameOverrides, emptyState, transcriptClassName, transcriptClassNames, composerClassName, composerClassNames, transcriptProps, composerProps, }: AgentConversationProps) => react_jsx_runtime.JSX.Element;
171
+
5
172
  type ProcessTerminalClient = Pick<SandboxAgent, "connectProcessTerminal">;
6
173
  interface ProcessTerminalProps {
7
174
  client: ProcessTerminalClient;
@@ -9,10 +176,12 @@ interface ProcessTerminalProps {
9
176
  className?: string;
10
177
  style?: CSSProperties;
11
178
  terminalStyle?: CSSProperties;
179
+ statusBarStyleOverride?: CSSProperties;
12
180
  height?: number | string;
181
+ showStatusBar?: boolean;
13
182
  onExit?: (status: TerminalExitStatus) => void;
14
183
  onError?: (error: TerminalErrorStatus | Error) => void;
15
184
  }
16
- declare const ProcessTerminal: ({ client, processId, className, style, terminalStyle, height, onExit, onError, }: ProcessTerminalProps) => react_jsx_runtime.JSX.Element;
185
+ declare const ProcessTerminal: ({ client, processId, className, style, terminalStyle, statusBarStyleOverride, height, showStatusBar, onExit, onError, }: ProcessTerminalProps) => react_jsx_runtime.JSX.Element;
17
186
 
18
- export { ProcessTerminal, type ProcessTerminalClient, type ProcessTerminalProps };
187
+ export { AgentConversation, type AgentConversationClassNames, type AgentConversationProps, AgentTranscript, type AgentTranscriptClassNames, type AgentTranscriptProps, ChatComposer, type ChatComposerClassNames, type ChatComposerProps, type PermissionOption, type PermissionOptionRenderContext, type PermissionReply, ProcessTerminal, type ProcessTerminalClient, type ProcessTerminalProps, type TranscriptEntry };
package/dist/index.js CHANGED
@@ -1,6 +1,620 @@
1
- // src/ProcessTerminal.tsx
2
- import { useEffect, useRef, useState } from "react";
1
+ // src/AgentTranscript.tsx
2
+ import { useMemo, useState } from "react";
3
3
  import { jsx, jsxs } from "react/jsx-runtime";
4
+ var DEFAULT_CLASS_NAMES = {
5
+ root: "sa-agent-transcript",
6
+ divider: "sa-agent-transcript-divider",
7
+ dividerLine: "sa-agent-transcript-divider-line",
8
+ dividerText: "sa-agent-transcript-divider-text",
9
+ message: "sa-agent-transcript-message",
10
+ messageContent: "sa-agent-transcript-message-content",
11
+ messageText: "sa-agent-transcript-message-text",
12
+ error: "sa-agent-transcript-error",
13
+ toolGroupSingle: "sa-agent-transcript-tool-group-single",
14
+ toolGroupContainer: "sa-agent-transcript-tool-group",
15
+ toolGroupHeader: "sa-agent-transcript-tool-group-header",
16
+ toolGroupIcon: "sa-agent-transcript-tool-group-icon",
17
+ toolGroupLabel: "sa-agent-transcript-tool-group-label",
18
+ toolGroupChevron: "sa-agent-transcript-tool-group-chevron",
19
+ toolGroupBody: "sa-agent-transcript-tool-group-body",
20
+ toolItem: "sa-agent-transcript-tool-item",
21
+ toolItemConnector: "sa-agent-transcript-tool-item-connector",
22
+ toolItemDot: "sa-agent-transcript-tool-item-dot",
23
+ toolItemLine: "sa-agent-transcript-tool-item-line",
24
+ toolItemContent: "sa-agent-transcript-tool-item-content",
25
+ toolItemHeader: "sa-agent-transcript-tool-item-header",
26
+ toolItemIcon: "sa-agent-transcript-tool-item-icon",
27
+ toolItemLabel: "sa-agent-transcript-tool-item-label",
28
+ toolItemSpinner: "sa-agent-transcript-tool-item-spinner",
29
+ toolItemLink: "sa-agent-transcript-tool-item-link",
30
+ toolItemChevron: "sa-agent-transcript-tool-item-chevron",
31
+ toolItemBody: "sa-agent-transcript-tool-item-body",
32
+ toolSection: "sa-agent-transcript-tool-section",
33
+ toolSectionTitle: "sa-agent-transcript-tool-section-title",
34
+ toolCode: "sa-agent-transcript-tool-code",
35
+ toolCodeMuted: "sa-agent-transcript-tool-code-muted",
36
+ permissionPrompt: "sa-agent-transcript-permission-prompt",
37
+ permissionHeader: "sa-agent-transcript-permission-header",
38
+ permissionIcon: "sa-agent-transcript-permission-icon",
39
+ permissionTitle: "sa-agent-transcript-permission-title",
40
+ permissionDescription: "sa-agent-transcript-permission-description",
41
+ permissionActions: "sa-agent-transcript-permission-actions",
42
+ permissionButton: "sa-agent-transcript-permission-button",
43
+ permissionAutoResolved: "sa-agent-transcript-permission-auto-resolved",
44
+ thinkingRow: "sa-agent-transcript-thinking-row",
45
+ thinkingAvatar: "sa-agent-transcript-thinking-avatar",
46
+ thinkingAvatarImage: "sa-agent-transcript-thinking-avatar-image",
47
+ thinkingAvatarLabel: "sa-agent-transcript-thinking-avatar-label",
48
+ thinkingIndicator: "sa-agent-transcript-thinking-indicator",
49
+ thinkingDot: "sa-agent-transcript-thinking-dot",
50
+ endAnchor: "sa-agent-transcript-end"
51
+ };
52
+ var DEFAULT_DIVIDER_TITLES = /* @__PURE__ */ new Set(["Session Started", "Turn Started", "Turn Ended"]);
53
+ var cx = (...values) => values.filter(Boolean).join(" ");
54
+ var mergeClassNames = (defaults, overrides) => ({
55
+ root: cx(defaults.root, overrides?.root),
56
+ divider: cx(defaults.divider, overrides?.divider),
57
+ dividerLine: cx(defaults.dividerLine, overrides?.dividerLine),
58
+ dividerText: cx(defaults.dividerText, overrides?.dividerText),
59
+ message: cx(defaults.message, overrides?.message),
60
+ messageContent: cx(defaults.messageContent, overrides?.messageContent),
61
+ messageText: cx(defaults.messageText, overrides?.messageText),
62
+ error: cx(defaults.error, overrides?.error),
63
+ toolGroupSingle: cx(defaults.toolGroupSingle, overrides?.toolGroupSingle),
64
+ toolGroupContainer: cx(defaults.toolGroupContainer, overrides?.toolGroupContainer),
65
+ toolGroupHeader: cx(defaults.toolGroupHeader, overrides?.toolGroupHeader),
66
+ toolGroupIcon: cx(defaults.toolGroupIcon, overrides?.toolGroupIcon),
67
+ toolGroupLabel: cx(defaults.toolGroupLabel, overrides?.toolGroupLabel),
68
+ toolGroupChevron: cx(defaults.toolGroupChevron, overrides?.toolGroupChevron),
69
+ toolGroupBody: cx(defaults.toolGroupBody, overrides?.toolGroupBody),
70
+ toolItem: cx(defaults.toolItem, overrides?.toolItem),
71
+ toolItemConnector: cx(defaults.toolItemConnector, overrides?.toolItemConnector),
72
+ toolItemDot: cx(defaults.toolItemDot, overrides?.toolItemDot),
73
+ toolItemLine: cx(defaults.toolItemLine, overrides?.toolItemLine),
74
+ toolItemContent: cx(defaults.toolItemContent, overrides?.toolItemContent),
75
+ toolItemHeader: cx(defaults.toolItemHeader, overrides?.toolItemHeader),
76
+ toolItemIcon: cx(defaults.toolItemIcon, overrides?.toolItemIcon),
77
+ toolItemLabel: cx(defaults.toolItemLabel, overrides?.toolItemLabel),
78
+ toolItemSpinner: cx(defaults.toolItemSpinner, overrides?.toolItemSpinner),
79
+ toolItemLink: cx(defaults.toolItemLink, overrides?.toolItemLink),
80
+ toolItemChevron: cx(defaults.toolItemChevron, overrides?.toolItemChevron),
81
+ toolItemBody: cx(defaults.toolItemBody, overrides?.toolItemBody),
82
+ toolSection: cx(defaults.toolSection, overrides?.toolSection),
83
+ toolSectionTitle: cx(defaults.toolSectionTitle, overrides?.toolSectionTitle),
84
+ toolCode: cx(defaults.toolCode, overrides?.toolCode),
85
+ toolCodeMuted: cx(defaults.toolCodeMuted, overrides?.toolCodeMuted),
86
+ permissionPrompt: cx(defaults.permissionPrompt, overrides?.permissionPrompt),
87
+ permissionHeader: cx(defaults.permissionHeader, overrides?.permissionHeader),
88
+ permissionIcon: cx(defaults.permissionIcon, overrides?.permissionIcon),
89
+ permissionTitle: cx(defaults.permissionTitle, overrides?.permissionTitle),
90
+ permissionDescription: cx(defaults.permissionDescription, overrides?.permissionDescription),
91
+ permissionActions: cx(defaults.permissionActions, overrides?.permissionActions),
92
+ permissionButton: cx(defaults.permissionButton, overrides?.permissionButton),
93
+ permissionAutoResolved: cx(defaults.permissionAutoResolved, overrides?.permissionAutoResolved),
94
+ thinkingRow: cx(defaults.thinkingRow, overrides?.thinkingRow),
95
+ thinkingAvatar: cx(defaults.thinkingAvatar, overrides?.thinkingAvatar),
96
+ thinkingAvatarImage: cx(defaults.thinkingAvatarImage, overrides?.thinkingAvatarImage),
97
+ thinkingAvatarLabel: cx(defaults.thinkingAvatarLabel, overrides?.thinkingAvatarLabel),
98
+ thinkingIndicator: cx(defaults.thinkingIndicator, overrides?.thinkingIndicator),
99
+ thinkingDot: cx(defaults.thinkingDot, overrides?.thinkingDot),
100
+ endAnchor: cx(defaults.endAnchor, overrides?.endAnchor)
101
+ });
102
+ var getMessageVariant = (entry) => {
103
+ if (entry.kind === "tool") return "tool";
104
+ if (entry.kind === "meta") return entry.meta?.severity === "error" ? "error" : "system";
105
+ if (entry.kind === "reasoning") return "assistant";
106
+ if (entry.kind === "permission") return "system";
107
+ if (entry.role === "user") return "user";
108
+ return "assistant";
109
+ };
110
+ var getToolItemLabel = (entry) => {
111
+ if (entry.kind === "tool") {
112
+ const statusLabel = entry.toolStatus && entry.toolStatus !== "completed" ? ` (${entry.toolStatus.replaceAll("_", " ")})` : "";
113
+ return `${entry.toolName ?? "tool"}${statusLabel}`;
114
+ }
115
+ if (entry.kind === "reasoning") {
116
+ return `Reasoning${entry.reasoning?.visibility ? ` (${entry.reasoning.visibility})` : ""}`;
117
+ }
118
+ return entry.meta?.title ?? "Status";
119
+ };
120
+ var getDefaultToolItemIcon = (entry) => {
121
+ if (entry.kind === "tool") return "Tool";
122
+ if (entry.kind === "reasoning") return "Thought";
123
+ return entry.meta?.severity === "error" ? "Error" : "Info";
124
+ };
125
+ var getDefaultToolGroupSummary = (entries) => {
126
+ const count = entries.length;
127
+ return `${count} Event${count === 1 ? "" : "s"}`;
128
+ };
129
+ var getPermissionReplyForOption = (kind) => {
130
+ if (kind === "allow_once") return "once";
131
+ if (kind === "allow_always") return "always";
132
+ return "reject";
133
+ };
134
+ var getPermissionOptionLabel = (option) => {
135
+ if (option.name) return option.name;
136
+ if (option.kind === "allow_once") return "Allow Once";
137
+ if (option.kind === "allow_always") return "Always Allow";
138
+ if (option.kind === "reject_once") return "Reject";
139
+ if (option.kind === "reject_always") return "Reject Always";
140
+ return option.kind;
141
+ };
142
+ var getPermissionOptionTone = (kind) => kind.startsWith("allow") ? "allow" : "reject";
143
+ var defaultRenderMessageText = (entry) => entry.text;
144
+ var defaultRenderPendingIndicator = () => "...";
145
+ var defaultRenderChevron = (expanded) => expanded ? "\u25BE" : "\u25B8";
146
+ var defaultRenderEventLinkContent = () => "Open";
147
+ var defaultRenderPermissionIcon = () => "Permission";
148
+ var defaultRenderPermissionOptionContent = ({ label }) => label;
149
+ var defaultIsDividerEntry = (entry) => entry.kind === "meta" && DEFAULT_DIVIDER_TITLES.has(entry.meta?.title ?? "");
150
+ var defaultCanOpenEvent = (entry) => Boolean(entry.eventId);
151
+ var buildGroupedEntries = (entries, isDividerEntry) => {
152
+ const groupedEntries = [];
153
+ let currentToolGroup = [];
154
+ const flushToolGroup = () => {
155
+ if (currentToolGroup.length === 0) {
156
+ return;
157
+ }
158
+ groupedEntries.push({ type: "tool-group", entries: currentToolGroup });
159
+ currentToolGroup = [];
160
+ };
161
+ for (const entry of entries) {
162
+ if (isDividerEntry(entry)) {
163
+ flushToolGroup();
164
+ groupedEntries.push({ type: "divider", entries: [entry] });
165
+ continue;
166
+ }
167
+ if (entry.kind === "permission") {
168
+ flushToolGroup();
169
+ groupedEntries.push({ type: "permission", entries: [entry] });
170
+ continue;
171
+ }
172
+ if (entry.kind === "tool" || entry.kind === "reasoning" || entry.kind === "meta") {
173
+ currentToolGroup.push(entry);
174
+ continue;
175
+ }
176
+ flushToolGroup();
177
+ groupedEntries.push({ type: "message", entries: [entry] });
178
+ }
179
+ flushToolGroup();
180
+ return groupedEntries;
181
+ };
182
+ var ToolItem = ({
183
+ entry,
184
+ isLast,
185
+ classNames,
186
+ onEventClick,
187
+ canOpenEvent,
188
+ renderInlinePendingIndicator,
189
+ renderToolItemIcon,
190
+ renderChevron,
191
+ renderEventLinkContent
192
+ }) => {
193
+ const [expanded, setExpanded] = useState(false);
194
+ const isTool = entry.kind === "tool";
195
+ const isReasoning = entry.kind === "reasoning";
196
+ const isMeta = entry.kind === "meta";
197
+ const isComplete = isTool && (entry.toolStatus === "completed" || entry.toolStatus === "failed");
198
+ const isFailed = isTool && entry.toolStatus === "failed";
199
+ const isInProgress = isTool && entry.toolStatus === "in_progress";
200
+ const hasContent = isTool ? Boolean(entry.toolInput || entry.toolOutput) : isReasoning ? Boolean(entry.reasoning?.text?.trim()) : Boolean(entry.meta?.detail?.trim());
201
+ const showEventLink = Boolean(entry.eventId && onEventClick && canOpenEvent(entry));
202
+ return /* @__PURE__ */ jsxs(
203
+ "div",
204
+ {
205
+ className: cx(classNames.toolItem, isLast && "last", isFailed && "failed"),
206
+ "data-slot": "tool-item",
207
+ "data-kind": entry.kind,
208
+ "data-state": entry.toolStatus,
209
+ "data-last": isLast ? "true" : void 0,
210
+ "data-failed": isFailed ? "true" : void 0,
211
+ children: [
212
+ /* @__PURE__ */ jsxs("div", { className: classNames.toolItemConnector, "data-slot": "tool-item-connector", children: [
213
+ /* @__PURE__ */ jsx("div", { className: classNames.toolItemDot, "data-slot": "tool-item-dot" }),
214
+ !isLast ? /* @__PURE__ */ jsx("div", { className: classNames.toolItemLine, "data-slot": "tool-item-line" }) : null
215
+ ] }),
216
+ /* @__PURE__ */ jsxs("div", { className: classNames.toolItemContent, "data-slot": "tool-item-content", children: [
217
+ /* @__PURE__ */ jsxs(
218
+ "button",
219
+ {
220
+ type: "button",
221
+ className: cx(classNames.toolItemHeader, expanded && "expanded"),
222
+ "data-slot": "tool-item-header",
223
+ "data-expanded": expanded ? "true" : void 0,
224
+ "data-has-content": hasContent ? "true" : void 0,
225
+ disabled: !hasContent,
226
+ onClick: () => {
227
+ if (hasContent) {
228
+ setExpanded((value) => !value);
229
+ }
230
+ },
231
+ children: [
232
+ /* @__PURE__ */ jsx("span", { className: classNames.toolItemIcon, "data-slot": "tool-item-icon", children: renderToolItemIcon(entry) }),
233
+ /* @__PURE__ */ jsx("span", { className: classNames.toolItemLabel, "data-slot": "tool-item-label", children: getToolItemLabel(entry) }),
234
+ isInProgress ? /* @__PURE__ */ jsx("span", { className: classNames.toolItemSpinner, "data-slot": "tool-item-spinner", children: renderInlinePendingIndicator() }) : null,
235
+ showEventLink ? /* @__PURE__ */ jsx(
236
+ "span",
237
+ {
238
+ className: classNames.toolItemLink,
239
+ "data-slot": "tool-item-link",
240
+ role: "button",
241
+ tabIndex: 0,
242
+ onClick: (event) => {
243
+ event.stopPropagation();
244
+ onEventClick?.(entry.eventId);
245
+ },
246
+ onKeyDown: (event) => {
247
+ if (event.key === "Enter" || event.key === " ") {
248
+ event.preventDefault();
249
+ event.stopPropagation();
250
+ onEventClick?.(entry.eventId);
251
+ }
252
+ },
253
+ children: renderEventLinkContent(entry)
254
+ }
255
+ ) : null,
256
+ hasContent ? /* @__PURE__ */ jsx("span", { className: classNames.toolItemChevron, "data-slot": "tool-item-chevron", children: renderChevron(expanded) }) : null
257
+ ]
258
+ }
259
+ ),
260
+ expanded && hasContent ? /* @__PURE__ */ jsxs("div", { className: classNames.toolItemBody, "data-slot": "tool-item-body", children: [
261
+ isTool && entry.toolInput ? /* @__PURE__ */ jsxs("div", { className: classNames.toolSection, "data-slot": "tool-section", "data-section": "input", children: [
262
+ /* @__PURE__ */ jsx("div", { className: classNames.toolSectionTitle, "data-slot": "tool-section-title", children: "Input" }),
263
+ /* @__PURE__ */ jsx("pre", { className: classNames.toolCode, "data-slot": "tool-code", children: entry.toolInput })
264
+ ] }) : null,
265
+ isTool && isComplete && entry.toolOutput ? /* @__PURE__ */ jsxs("div", { className: classNames.toolSection, "data-slot": "tool-section", "data-section": "output", children: [
266
+ /* @__PURE__ */ jsx("div", { className: classNames.toolSectionTitle, "data-slot": "tool-section-title", children: "Output" }),
267
+ /* @__PURE__ */ jsx("pre", { className: classNames.toolCode, "data-slot": "tool-code", children: entry.toolOutput })
268
+ ] }) : null,
269
+ isReasoning && entry.reasoning?.text ? /* @__PURE__ */ jsx("div", { className: classNames.toolSection, "data-slot": "tool-section", "data-section": "reasoning", children: /* @__PURE__ */ jsx("pre", { className: cx(classNames.toolCode, classNames.toolCodeMuted), "data-slot": "tool-code", children: entry.reasoning.text }) }) : null,
270
+ isMeta && entry.meta?.detail ? /* @__PURE__ */ jsx("div", { className: classNames.toolSection, "data-slot": "tool-section", "data-section": "meta", children: /* @__PURE__ */ jsx("pre", { className: classNames.toolCode, "data-slot": "tool-code", children: entry.meta.detail }) }) : null
271
+ ] }) : null
272
+ ] })
273
+ ]
274
+ }
275
+ );
276
+ };
277
+ var ToolGroup = ({
278
+ entries,
279
+ classNames,
280
+ onEventClick,
281
+ canOpenEvent,
282
+ getToolGroupSummary,
283
+ renderInlinePendingIndicator,
284
+ renderToolItemIcon,
285
+ renderToolGroupIcon,
286
+ renderChevron,
287
+ renderEventLinkContent
288
+ }) => {
289
+ const [expanded, setExpanded] = useState(false);
290
+ const hasFailed = entries.some((entry) => entry.kind === "tool" && entry.toolStatus === "failed");
291
+ if (entries.length === 1) {
292
+ return /* @__PURE__ */ jsx("div", { className: classNames.toolGroupSingle, "data-slot": "tool-group-single", children: /* @__PURE__ */ jsx(
293
+ ToolItem,
294
+ {
295
+ entry: entries[0],
296
+ isLast: true,
297
+ classNames,
298
+ onEventClick,
299
+ canOpenEvent,
300
+ renderInlinePendingIndicator,
301
+ renderToolItemIcon,
302
+ renderChevron,
303
+ renderEventLinkContent
304
+ }
305
+ ) });
306
+ }
307
+ return /* @__PURE__ */ jsxs("div", { className: cx(classNames.toolGroupContainer, hasFailed && "failed"), "data-slot": "tool-group", "data-failed": hasFailed ? "true" : void 0, children: [
308
+ /* @__PURE__ */ jsxs(
309
+ "button",
310
+ {
311
+ type: "button",
312
+ className: cx(classNames.toolGroupHeader, expanded && "expanded"),
313
+ "data-slot": "tool-group-header",
314
+ "data-expanded": expanded ? "true" : void 0,
315
+ onClick: () => setExpanded((value) => !value),
316
+ children: [
317
+ /* @__PURE__ */ jsx("span", { className: classNames.toolGroupIcon, "data-slot": "tool-group-icon", children: renderToolGroupIcon(entries, expanded) }),
318
+ /* @__PURE__ */ jsx("span", { className: classNames.toolGroupLabel, "data-slot": "tool-group-label", children: getToolGroupSummary(entries) }),
319
+ /* @__PURE__ */ jsx("span", { className: classNames.toolGroupChevron, "data-slot": "tool-group-chevron", children: renderChevron(expanded) })
320
+ ]
321
+ }
322
+ ),
323
+ expanded ? /* @__PURE__ */ jsx("div", { className: classNames.toolGroupBody, "data-slot": "tool-group-body", children: entries.map((entry, index) => /* @__PURE__ */ jsx(
324
+ ToolItem,
325
+ {
326
+ entry,
327
+ isLast: index === entries.length - 1,
328
+ classNames,
329
+ onEventClick,
330
+ canOpenEvent,
331
+ renderInlinePendingIndicator,
332
+ renderToolItemIcon,
333
+ renderChevron,
334
+ renderEventLinkContent
335
+ },
336
+ entry.id
337
+ )) }) : null
338
+ ] });
339
+ };
340
+ var PermissionPrompt = ({
341
+ entry,
342
+ classNames,
343
+ onPermissionReply,
344
+ renderPermissionIcon,
345
+ renderPermissionOptionContent
346
+ }) => {
347
+ const permission = entry.permission;
348
+ if (!permission) {
349
+ return null;
350
+ }
351
+ const resolved = Boolean(permission.resolved);
352
+ const selectedOptionId = permission.selectedOptionId;
353
+ const canReply = Boolean(onPermissionReply) && !resolved;
354
+ return /* @__PURE__ */ jsxs("div", { className: cx(classNames.permissionPrompt, resolved && "resolved"), "data-slot": "permission-prompt", "data-resolved": resolved ? "true" : void 0, children: [
355
+ /* @__PURE__ */ jsxs("div", { className: classNames.permissionHeader, "data-slot": "permission-header", children: [
356
+ /* @__PURE__ */ jsx("span", { className: classNames.permissionIcon, "data-slot": "permission-icon", children: renderPermissionIcon(entry) }),
357
+ /* @__PURE__ */ jsx("span", { className: classNames.permissionTitle, "data-slot": "permission-title", children: permission.title })
358
+ ] }),
359
+ permission.description ? /* @__PURE__ */ jsx("div", { className: classNames.permissionDescription, "data-slot": "permission-description", children: permission.description }) : null,
360
+ /* @__PURE__ */ jsxs("div", { className: classNames.permissionActions, "data-slot": "permission-actions", children: [
361
+ permission.options.map((option) => {
362
+ const reply = getPermissionReplyForOption(option.kind);
363
+ const label = getPermissionOptionLabel(option);
364
+ const selected = resolved && selectedOptionId === option.optionId;
365
+ const dimmed = resolved && !selected && selectedOptionId != null;
366
+ const tone = getPermissionOptionTone(option.kind);
367
+ return /* @__PURE__ */ jsx(
368
+ "button",
369
+ {
370
+ type: "button",
371
+ className: cx(classNames.permissionButton, tone, selected && "selected", dimmed && "dimmed"),
372
+ "data-slot": "permission-button",
373
+ "data-tone": tone,
374
+ "data-selected": selected ? "true" : void 0,
375
+ "data-dimmed": dimmed ? "true" : void 0,
376
+ disabled: !canReply,
377
+ onClick: () => onPermissionReply?.(permission.permissionId, reply),
378
+ children: renderPermissionOptionContent({
379
+ entry,
380
+ option,
381
+ label,
382
+ reply,
383
+ selected,
384
+ dimmed,
385
+ resolved
386
+ })
387
+ },
388
+ option.optionId
389
+ );
390
+ }),
391
+ resolved && !selectedOptionId ? /* @__PURE__ */ jsx("span", { className: classNames.permissionAutoResolved, "data-slot": "permission-auto-resolved", children: "Auto-resolved" }) : null
392
+ ] })
393
+ ] });
394
+ };
395
+ var AgentTranscript = ({
396
+ entries,
397
+ className,
398
+ classNames: classNameOverrides,
399
+ endRef,
400
+ sessionError,
401
+ eventError,
402
+ isThinking,
403
+ agentId,
404
+ onEventClick,
405
+ onPermissionReply,
406
+ isDividerEntry = defaultIsDividerEntry,
407
+ canOpenEvent = defaultCanOpenEvent,
408
+ getToolGroupSummary = getDefaultToolGroupSummary,
409
+ renderMessageText = defaultRenderMessageText,
410
+ renderInlinePendingIndicator = defaultRenderPendingIndicator,
411
+ renderThinkingState,
412
+ renderToolItemIcon = getDefaultToolItemIcon,
413
+ renderToolGroupIcon = () => null,
414
+ renderChevron = defaultRenderChevron,
415
+ renderEventLinkContent = defaultRenderEventLinkContent,
416
+ renderPermissionIcon = defaultRenderPermissionIcon,
417
+ renderPermissionOptionContent = defaultRenderPermissionOptionContent
418
+ }) => {
419
+ const resolvedClassNames = useMemo(() => mergeClassNames(DEFAULT_CLASS_NAMES, classNameOverrides), [classNameOverrides]);
420
+ const groupedEntries = useMemo(() => buildGroupedEntries(entries, isDividerEntry), [entries, isDividerEntry]);
421
+ return /* @__PURE__ */ jsxs("div", { className: cx(resolvedClassNames.root, className), "data-slot": "root", children: [
422
+ groupedEntries.map((group, index) => {
423
+ if (group.type === "divider") {
424
+ const entry2 = group.entries[0];
425
+ const title = entry2.meta?.title ?? "Status";
426
+ return /* @__PURE__ */ jsxs("div", { className: resolvedClassNames.divider, "data-slot": "divider", children: [
427
+ /* @__PURE__ */ jsx("div", { className: resolvedClassNames.dividerLine, "data-slot": "divider-line" }),
428
+ /* @__PURE__ */ jsx("span", { className: resolvedClassNames.dividerText, "data-slot": "divider-text", children: title }),
429
+ /* @__PURE__ */ jsx("div", { className: resolvedClassNames.dividerLine, "data-slot": "divider-line" })
430
+ ] }, entry2.id);
431
+ }
432
+ if (group.type === "tool-group") {
433
+ return /* @__PURE__ */ jsx(
434
+ ToolGroup,
435
+ {
436
+ entries: group.entries,
437
+ classNames: resolvedClassNames,
438
+ onEventClick,
439
+ canOpenEvent,
440
+ getToolGroupSummary,
441
+ renderInlinePendingIndicator,
442
+ renderToolItemIcon,
443
+ renderToolGroupIcon,
444
+ renderChevron,
445
+ renderEventLinkContent
446
+ },
447
+ `tool-group-${index}`
448
+ );
449
+ }
450
+ if (group.type === "permission") {
451
+ const entry2 = group.entries[0];
452
+ return /* @__PURE__ */ jsx(
453
+ PermissionPrompt,
454
+ {
455
+ entry: entry2,
456
+ classNames: resolvedClassNames,
457
+ onPermissionReply,
458
+ renderPermissionIcon,
459
+ renderPermissionOptionContent
460
+ },
461
+ entry2.id
462
+ );
463
+ }
464
+ const entry = group.entries[0];
465
+ const messageVariant = getMessageVariant(entry);
466
+ return /* @__PURE__ */ jsx(
467
+ "div",
468
+ {
469
+ className: cx(resolvedClassNames.message, messageVariant, "no-avatar"),
470
+ "data-slot": "message",
471
+ "data-kind": entry.kind,
472
+ "data-role": entry.role,
473
+ "data-variant": messageVariant,
474
+ "data-severity": entry.meta?.severity,
475
+ children: /* @__PURE__ */ jsx("div", { className: resolvedClassNames.messageContent, "data-slot": "message-content", children: entry.text ? /* @__PURE__ */ jsx("div", { className: resolvedClassNames.messageText, "data-slot": "message-text", children: renderMessageText(entry) }) : /* @__PURE__ */ jsx("span", { className: resolvedClassNames.thinkingIndicator, "data-slot": "thinking-indicator", children: renderInlinePendingIndicator() }) })
476
+ },
477
+ entry.id
478
+ );
479
+ }),
480
+ sessionError ? /* @__PURE__ */ jsx("div", { className: resolvedClassNames.error, "data-slot": "error", "data-source": "session", children: sessionError }) : null,
481
+ eventError ? /* @__PURE__ */ jsx("div", { className: resolvedClassNames.error, "data-slot": "error", "data-source": "event", children: eventError }) : null,
482
+ isThinking ? renderThinkingState?.({ agentId }) ?? /* @__PURE__ */ jsx("div", { className: resolvedClassNames.thinkingRow, "data-slot": "thinking-row", children: /* @__PURE__ */ jsx("span", { className: resolvedClassNames.thinkingIndicator, "data-slot": "thinking-indicator", children: "Thinking..." }) }) : null,
483
+ /* @__PURE__ */ jsx("div", { ref: endRef, className: resolvedClassNames.endAnchor, "data-slot": "end-anchor" })
484
+ ] });
485
+ };
486
+
487
+ // src/ChatComposer.tsx
488
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
489
+ var DEFAULT_CLASS_NAMES2 = {
490
+ root: "sa-chat-composer",
491
+ form: "sa-chat-composer-form",
492
+ input: "sa-chat-composer-input",
493
+ submit: "sa-chat-composer-submit",
494
+ submitContent: "sa-chat-composer-submit-content"
495
+ };
496
+ var cx2 = (...values) => values.filter(Boolean).join(" ");
497
+ var mergeClassNames2 = (defaults, overrides) => ({
498
+ root: cx2(defaults.root, overrides?.root),
499
+ form: cx2(defaults.form, overrides?.form),
500
+ input: cx2(defaults.input, overrides?.input),
501
+ submit: cx2(defaults.submit, overrides?.submit),
502
+ submitContent: cx2(defaults.submitContent, overrides?.submitContent)
503
+ });
504
+ var ChatComposer = ({
505
+ message,
506
+ onMessageChange,
507
+ onSubmit,
508
+ onKeyDown,
509
+ placeholder,
510
+ disabled = false,
511
+ submitDisabled = false,
512
+ allowEmptySubmit = false,
513
+ submitLabel = "Send",
514
+ className,
515
+ classNames: classNameOverrides,
516
+ inputRef,
517
+ rows = 1,
518
+ textareaProps,
519
+ renderSubmitContent,
520
+ renderFooter
521
+ }) => {
522
+ const resolvedClassNames = mergeClassNames2(DEFAULT_CLASS_NAMES2, classNameOverrides);
523
+ const isSubmitDisabled = disabled || submitDisabled || !allowEmptySubmit && message.trim().length === 0;
524
+ return /* @__PURE__ */ jsx2("div", { className: cx2(resolvedClassNames.root, className), "data-slot": "root", children: /* @__PURE__ */ jsxs2(
525
+ "form",
526
+ {
527
+ className: resolvedClassNames.form,
528
+ "data-slot": "form",
529
+ onSubmit: (event) => {
530
+ event.preventDefault();
531
+ if (!isSubmitDisabled) {
532
+ onSubmit();
533
+ }
534
+ },
535
+ children: [
536
+ /* @__PURE__ */ jsx2(
537
+ "textarea",
538
+ {
539
+ ...textareaProps,
540
+ ref: inputRef,
541
+ className: resolvedClassNames.input,
542
+ "data-slot": "input",
543
+ "data-disabled": disabled ? "true" : void 0,
544
+ "data-empty": message.trim().length === 0 ? "true" : void 0,
545
+ value: message,
546
+ onChange: (event) => onMessageChange(event.target.value),
547
+ onKeyDown,
548
+ placeholder,
549
+ rows,
550
+ disabled
551
+ }
552
+ ),
553
+ renderFooter?.(),
554
+ /* @__PURE__ */ jsx2(
555
+ "button",
556
+ {
557
+ type: "submit",
558
+ className: resolvedClassNames.submit,
559
+ "data-slot": "submit",
560
+ "data-disabled": isSubmitDisabled ? "true" : void 0,
561
+ disabled: isSubmitDisabled,
562
+ "aria-label": submitLabel,
563
+ title: submitLabel,
564
+ children: /* @__PURE__ */ jsx2("span", { className: resolvedClassNames.submitContent, "data-slot": "submit-content", children: renderSubmitContent?.() ?? submitLabel })
565
+ }
566
+ )
567
+ ]
568
+ }
569
+ ) });
570
+ };
571
+
572
+ // src/AgentConversation.tsx
573
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
574
+ var DEFAULT_CLASS_NAMES3 = {
575
+ root: "sa-agent-conversation",
576
+ transcript: "sa-agent-conversation-transcript",
577
+ emptyState: "sa-agent-conversation-empty-state",
578
+ composer: "sa-agent-conversation-composer"
579
+ };
580
+ var cx3 = (...values) => values.filter(Boolean).join(" ");
581
+ var mergeClassNames3 = (defaults, overrides) => ({
582
+ root: cx3(defaults.root, overrides?.root),
583
+ transcript: cx3(defaults.transcript, overrides?.transcript),
584
+ emptyState: cx3(defaults.emptyState, overrides?.emptyState),
585
+ composer: cx3(defaults.composer, overrides?.composer)
586
+ });
587
+ var AgentConversation = ({
588
+ entries,
589
+ className,
590
+ classNames: classNameOverrides,
591
+ emptyState,
592
+ transcriptClassName,
593
+ transcriptClassNames,
594
+ composerClassName,
595
+ composerClassNames,
596
+ transcriptProps,
597
+ composerProps
598
+ }) => {
599
+ const resolvedClassNames = mergeClassNames3(DEFAULT_CLASS_NAMES3, classNameOverrides);
600
+ const hasTranscriptContent = entries.length > 0 || Boolean(transcriptProps?.sessionError) || Boolean(transcriptProps?.eventError);
601
+ return /* @__PURE__ */ jsxs3("div", { className: cx3(resolvedClassNames.root, className), "data-slot": "root", children: [
602
+ hasTranscriptContent ? /* @__PURE__ */ jsx3(
603
+ AgentTranscript,
604
+ {
605
+ entries,
606
+ className: cx3(resolvedClassNames.transcript, transcriptClassName),
607
+ classNames: transcriptClassNames,
608
+ ...transcriptProps
609
+ }
610
+ ) : emptyState ? /* @__PURE__ */ jsx3("div", { className: resolvedClassNames.emptyState, "data-slot": "empty-state", children: emptyState }) : null,
611
+ composerProps ? /* @__PURE__ */ jsx3(ChatComposer, { className: cx3(resolvedClassNames.composer, composerClassName), classNames: composerClassNames, ...composerProps }) : null
612
+ ] });
613
+ };
614
+
615
+ // src/ProcessTerminal.tsx
616
+ import { useEffect, useRef, useState as useState2 } from "react";
617
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
4
618
  var terminalTheme = {
5
619
  background: "#09090b",
6
620
  foreground: "#f4f4f5",
@@ -71,14 +685,16 @@ var ProcessTerminal = ({
71
685
  className,
72
686
  style,
73
687
  terminalStyle,
688
+ statusBarStyleOverride,
74
689
  height = 360,
690
+ showStatusBar = true,
75
691
  onExit,
76
692
  onError
77
693
  }) => {
78
694
  const hostRef = useRef(null);
79
- const [connectionState, setConnectionState] = useState("connecting");
80
- const [statusMessage, setStatusMessage] = useState("Connecting to PTY...");
81
- const [exitCode, setExitCode] = useState(null);
695
+ const [connectionState, setConnectionState] = useState2("connecting");
696
+ const [statusMessage, setStatusMessage] = useState2("Connecting to PTY...");
697
+ const [exitCode, setExitCode] = useState2(null);
82
698
  useEffect(() => {
83
699
  let cancelled = false;
84
700
  let terminal = null;
@@ -157,9 +773,7 @@ var ProcessTerminal = ({
157
773
  }
158
774
  setConnectionState("closed");
159
775
  setExitCode(frame.exitCode ?? null);
160
- setStatusMessage(
161
- frame.exitCode == null ? "Process exited." : `Process exited with code ${frame.exitCode}.`
162
- );
776
+ setStatusMessage(frame.exitCode == null ? "Process exited." : `Process exited with code ${frame.exitCode}.`);
163
777
  onExit?.(frame);
164
778
  });
165
779
  nextSession.onError((error) => {
@@ -199,15 +813,15 @@ var ProcessTerminal = ({
199
813
  terminal?.dispose();
200
814
  };
201
815
  }, [client, onError, onExit, processId]);
202
- return /* @__PURE__ */ jsxs("div", { className, style: { ...shellStyle, ...style }, children: [
203
- /* @__PURE__ */ jsxs("div", { style: statusBarStyle, children: [
204
- /* @__PURE__ */ jsx("span", { style: { color: getStatusColor(connectionState) }, children: statusMessage }),
205
- exitCode != null ? /* @__PURE__ */ jsxs("span", { style: exitCodeStyle, children: [
816
+ return /* @__PURE__ */ jsxs4("div", { className, style: { ...shellStyle, ...style }, children: [
817
+ showStatusBar ? /* @__PURE__ */ jsxs4("div", { style: { ...statusBarStyle, ...statusBarStyleOverride }, children: [
818
+ /* @__PURE__ */ jsx4("span", { style: { color: getStatusColor(connectionState) }, children: statusMessage }),
819
+ exitCode != null ? /* @__PURE__ */ jsxs4("span", { style: exitCodeStyle, children: [
206
820
  "exit=",
207
821
  exitCode
208
822
  ] }) : null
209
- ] }),
210
- /* @__PURE__ */ jsx(
823
+ ] }) : null,
824
+ /* @__PURE__ */ jsx4(
211
825
  "div",
212
826
  {
213
827
  ref: hostRef,
@@ -225,6 +839,9 @@ var ProcessTerminal = ({
225
839
  ] });
226
840
  };
227
841
  export {
842
+ AgentConversation,
843
+ AgentTranscript,
844
+ ChatComposer,
228
845
  ProcessTerminal
229
846
  };
230
847
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ProcessTerminal.tsx"],"sourcesContent":["\"use client\";\n\nimport type { FitAddon as GhosttyFitAddon, Terminal as GhosttyTerminal } from \"ghostty-web\";\nimport type { CSSProperties } from \"react\";\nimport { useEffect, useRef, useState } from \"react\";\nimport type { SandboxAgent, TerminalErrorStatus, TerminalExitStatus } from \"sandbox-agent\";\n\ntype ConnectionState = \"connecting\" | \"ready\" | \"closed\" | \"error\";\n\nexport type ProcessTerminalClient = Pick<SandboxAgent, \"connectProcessTerminal\">;\n\nexport interface ProcessTerminalProps {\n client: ProcessTerminalClient;\n processId: string;\n className?: string;\n style?: CSSProperties;\n terminalStyle?: CSSProperties;\n height?: number | string;\n onExit?: (status: TerminalExitStatus) => void;\n onError?: (error: TerminalErrorStatus | Error) => void;\n}\n\nconst terminalTheme = {\n background: \"#09090b\",\n foreground: \"#f4f4f5\",\n cursor: \"#f97316\",\n cursorAccent: \"#09090b\",\n selectionBackground: \"#27272a\",\n black: \"#18181b\",\n red: \"#f87171\",\n green: \"#4ade80\",\n yellow: \"#fbbf24\",\n blue: \"#60a5fa\",\n magenta: \"#f472b6\",\n cyan: \"#22d3ee\",\n white: \"#e4e4e7\",\n brightBlack: \"#3f3f46\",\n brightRed: \"#fb7185\",\n brightGreen: \"#86efac\",\n brightYellow: \"#fde047\",\n brightBlue: \"#93c5fd\",\n brightMagenta: \"#f9a8d4\",\n brightCyan: \"#67e8f9\",\n brightWhite: \"#fafafa\",\n};\n\nconst shellStyle: CSSProperties = {\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n borderRadius: 10,\n background: \"rgba(0, 0, 0, 0.3)\",\n};\n\nconst statusBarStyle: CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: 12,\n padding: \"8px 12px\",\n borderBottom: \"1px solid rgba(255, 255, 255, 0.08)\",\n background: \"rgba(0, 0, 0, 0.2)\",\n color: \"rgba(244, 244, 245, 0.86)\",\n fontSize: 11,\n lineHeight: 1.4,\n};\n\nconst hostBaseStyle: CSSProperties = {\n minHeight: 320,\n padding: 10,\n overflow: \"hidden\",\n};\n\nconst exitCodeStyle: CSSProperties = {\n fontFamily: \"ui-monospace, SFMono-Regular, SF Mono, Menlo, monospace\",\n opacity: 0.72,\n};\n\nconst getStatusColor = (state: ConnectionState): string => {\n switch (state) {\n case \"ready\":\n return \"#4ade80\";\n case \"error\":\n return \"#fb7185\";\n case \"closed\":\n return \"#fbbf24\";\n default:\n return \"rgba(244, 244, 245, 0.72)\";\n }\n};\n\nexport const ProcessTerminal = ({\n client,\n processId,\n className,\n style,\n terminalStyle,\n height = 360,\n onExit,\n onError,\n}: ProcessTerminalProps) => {\n const hostRef = useRef<HTMLDivElement | null>(null);\n const [connectionState, setConnectionState] = useState<ConnectionState>(\"connecting\");\n const [statusMessage, setStatusMessage] = useState(\"Connecting to PTY...\");\n const [exitCode, setExitCode] = useState<number | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n let terminal: GhosttyTerminal | null = null;\n let fitAddon: GhosttyFitAddon | null = null;\n let session: ReturnType<ProcessTerminalClient[\"connectProcessTerminal\"]> | null = null;\n let resizeRaf = 0;\n let removeDataListener: { dispose(): void } | null = null;\n let removeResizeListener: { dispose(): void } | null = null;\n\n setConnectionState(\"connecting\");\n setStatusMessage(\"Connecting to PTY...\");\n setExitCode(null);\n\n const syncSize = () => {\n if (!terminal || !session) {\n return;\n }\n\n session.resize({\n cols: terminal.cols,\n rows: terminal.rows,\n });\n };\n\n const connect = async () => {\n try {\n const ghostty = await import(\"ghostty-web\");\n await ghostty.init();\n\n if (cancelled || !hostRef.current) {\n return;\n }\n\n terminal = new ghostty.Terminal({\n allowTransparency: true,\n cursorBlink: true,\n cursorStyle: \"block\",\n fontFamily: \"ui-monospace, SFMono-Regular, SF Mono, Menlo, monospace\",\n fontSize: 13,\n smoothScrollDuration: 90,\n theme: terminalTheme,\n });\n fitAddon = new ghostty.FitAddon();\n\n terminal.open(hostRef.current);\n const terminalRoot = hostRef.current.firstElementChild;\n if (terminalRoot instanceof HTMLElement) {\n terminalRoot.style.width = \"100%\";\n terminalRoot.style.height = \"100%\";\n }\n terminal.loadAddon(fitAddon);\n fitAddon.fit();\n fitAddon.observeResize();\n terminal.focus();\n\n removeDataListener = terminal.onData((data) => {\n session?.sendInput(data);\n });\n\n removeResizeListener = terminal.onResize(() => {\n if (resizeRaf) {\n window.cancelAnimationFrame(resizeRaf);\n }\n resizeRaf = window.requestAnimationFrame(syncSize);\n });\n\n const nextSession = client.connectProcessTerminal(processId);\n session = nextSession;\n\n nextSession.onReady((frame) => {\n if (cancelled || frame.type !== \"ready\") {\n return;\n }\n\n setConnectionState(\"ready\");\n setStatusMessage(\"Connected\");\n syncSize();\n });\n\n nextSession.onData((bytes) => {\n if (cancelled || !terminal) {\n return;\n }\n terminal.write(bytes);\n });\n\n nextSession.onExit((frame) => {\n if (cancelled || frame.type !== \"exit\") {\n return;\n }\n\n setConnectionState(\"closed\");\n setExitCode(frame.exitCode ?? null);\n setStatusMessage(\n frame.exitCode == null ? \"Process exited.\" : `Process exited with code ${frame.exitCode}.`\n );\n onExit?.(frame);\n });\n\n nextSession.onError((error) => {\n if (cancelled) {\n return;\n }\n\n setConnectionState(\"error\");\n setStatusMessage(error instanceof Error ? error.message : error.message);\n onError?.(error);\n });\n\n nextSession.onClose(() => {\n if (cancelled) {\n return;\n }\n\n setConnectionState((current) => (current === \"error\" ? current : \"closed\"));\n setStatusMessage((current) => (current === \"Connected\" ? \"Terminal disconnected.\" : current));\n });\n } catch (error) {\n if (cancelled) {\n return;\n }\n\n const nextError = error instanceof Error ? error : new Error(\"Failed to initialize terminal.\");\n setConnectionState(\"error\");\n setStatusMessage(nextError.message);\n onError?.(nextError);\n }\n };\n\n void connect();\n\n return () => {\n cancelled = true;\n if (resizeRaf) {\n window.cancelAnimationFrame(resizeRaf);\n }\n removeDataListener?.dispose();\n removeResizeListener?.dispose();\n session?.close();\n terminal?.dispose();\n };\n }, [client, onError, onExit, processId]);\n\n return (\n <div className={className} style={{ ...shellStyle, ...style }}>\n <div style={statusBarStyle}>\n <span style={{ color: getStatusColor(connectionState) }}>{statusMessage}</span>\n {exitCode != null ? <span style={exitCodeStyle}>exit={exitCode}</span> : null}\n </div>\n <div\n ref={hostRef}\n role=\"presentation\"\n style={{\n ...hostBaseStyle,\n height,\n ...terminalStyle,\n }}\n onClick={() => {\n hostRef.current?.querySelector(\"textarea\")?.focus();\n }}\n />\n </div>\n );\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/AgentTranscript.tsx","../src/ChatComposer.tsx","../src/AgentConversation.tsx","../src/ProcessTerminal.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ReactNode, RefObject } from \"react\";\nimport { useMemo, useState } from \"react\";\n\nexport type PermissionReply = \"once\" | \"always\" | \"reject\";\n\nexport type PermissionOption = {\n optionId: string;\n name: string;\n kind: string;\n};\n\nexport type TranscriptEntry = {\n id: string;\n eventId?: string;\n kind: \"message\" | \"tool\" | \"meta\" | \"reasoning\" | \"permission\";\n time: string;\n role?: \"user\" | \"assistant\";\n text?: string;\n toolName?: string;\n toolInput?: string;\n toolOutput?: string;\n toolStatus?: string;\n reasoning?: { text: string; visibility?: string };\n meta?: { title: string; detail?: string; severity?: \"info\" | \"error\" };\n permission?: {\n permissionId: string;\n title: string;\n description?: string;\n options: PermissionOption[];\n resolved?: boolean;\n selectedOptionId?: string;\n };\n};\n\nexport interface AgentTranscriptClassNames {\n root: string;\n divider: string;\n dividerLine: string;\n dividerText: string;\n message: string;\n messageContent: string;\n messageText: string;\n error: string;\n toolGroupSingle: string;\n toolGroupContainer: string;\n toolGroupHeader: string;\n toolGroupIcon: string;\n toolGroupLabel: string;\n toolGroupChevron: string;\n toolGroupBody: string;\n toolItem: string;\n toolItemConnector: string;\n toolItemDot: string;\n toolItemLine: string;\n toolItemContent: string;\n toolItemHeader: string;\n toolItemIcon: string;\n toolItemLabel: string;\n toolItemSpinner: string;\n toolItemLink: string;\n toolItemChevron: string;\n toolItemBody: string;\n toolSection: string;\n toolSectionTitle: string;\n toolCode: string;\n toolCodeMuted: string;\n permissionPrompt: string;\n permissionHeader: string;\n permissionIcon: string;\n permissionTitle: string;\n permissionDescription: string;\n permissionActions: string;\n permissionButton: string;\n permissionAutoResolved: string;\n thinkingRow: string;\n thinkingAvatar: string;\n thinkingAvatarImage: string;\n thinkingAvatarLabel: string;\n thinkingIndicator: string;\n thinkingDot: string;\n endAnchor: string;\n}\n\nexport interface PermissionOptionRenderContext {\n entry: TranscriptEntry;\n option: PermissionOption;\n label: string;\n reply: PermissionReply;\n selected: boolean;\n dimmed: boolean;\n resolved: boolean;\n}\n\nexport interface AgentTranscriptProps {\n entries: TranscriptEntry[];\n className?: string;\n classNames?: Partial<AgentTranscriptClassNames>;\n endRef?: RefObject<HTMLDivElement>;\n sessionError?: string | null;\n eventError?: string | null;\n isThinking?: boolean;\n agentId?: string;\n onEventClick?: (eventId: string) => void;\n onPermissionReply?: (permissionId: string, reply: PermissionReply) => void;\n isDividerEntry?: (entry: TranscriptEntry) => boolean;\n canOpenEvent?: (entry: TranscriptEntry) => boolean;\n getToolGroupSummary?: (entries: TranscriptEntry[]) => string;\n renderMessageText?: (entry: TranscriptEntry) => ReactNode;\n renderInlinePendingIndicator?: () => ReactNode;\n renderThinkingState?: (context: { agentId?: string }) => ReactNode;\n renderToolItemIcon?: (entry: TranscriptEntry) => ReactNode;\n renderToolGroupIcon?: (entries: TranscriptEntry[], expanded: boolean) => ReactNode;\n renderChevron?: (expanded: boolean) => ReactNode;\n renderEventLinkContent?: (entry: TranscriptEntry) => ReactNode;\n renderPermissionIcon?: (entry: TranscriptEntry) => ReactNode;\n renderPermissionOptionContent?: (context: PermissionOptionRenderContext) => ReactNode;\n}\n\ntype GroupedEntries =\n | { type: \"message\"; entries: TranscriptEntry[] }\n | { type: \"tool-group\"; entries: TranscriptEntry[] }\n | { type: \"divider\"; entries: TranscriptEntry[] }\n | { type: \"permission\"; entries: TranscriptEntry[] };\n\nconst DEFAULT_CLASS_NAMES: AgentTranscriptClassNames = {\n root: \"sa-agent-transcript\",\n divider: \"sa-agent-transcript-divider\",\n dividerLine: \"sa-agent-transcript-divider-line\",\n dividerText: \"sa-agent-transcript-divider-text\",\n message: \"sa-agent-transcript-message\",\n messageContent: \"sa-agent-transcript-message-content\",\n messageText: \"sa-agent-transcript-message-text\",\n error: \"sa-agent-transcript-error\",\n toolGroupSingle: \"sa-agent-transcript-tool-group-single\",\n toolGroupContainer: \"sa-agent-transcript-tool-group\",\n toolGroupHeader: \"sa-agent-transcript-tool-group-header\",\n toolGroupIcon: \"sa-agent-transcript-tool-group-icon\",\n toolGroupLabel: \"sa-agent-transcript-tool-group-label\",\n toolGroupChevron: \"sa-agent-transcript-tool-group-chevron\",\n toolGroupBody: \"sa-agent-transcript-tool-group-body\",\n toolItem: \"sa-agent-transcript-tool-item\",\n toolItemConnector: \"sa-agent-transcript-tool-item-connector\",\n toolItemDot: \"sa-agent-transcript-tool-item-dot\",\n toolItemLine: \"sa-agent-transcript-tool-item-line\",\n toolItemContent: \"sa-agent-transcript-tool-item-content\",\n toolItemHeader: \"sa-agent-transcript-tool-item-header\",\n toolItemIcon: \"sa-agent-transcript-tool-item-icon\",\n toolItemLabel: \"sa-agent-transcript-tool-item-label\",\n toolItemSpinner: \"sa-agent-transcript-tool-item-spinner\",\n toolItemLink: \"sa-agent-transcript-tool-item-link\",\n toolItemChevron: \"sa-agent-transcript-tool-item-chevron\",\n toolItemBody: \"sa-agent-transcript-tool-item-body\",\n toolSection: \"sa-agent-transcript-tool-section\",\n toolSectionTitle: \"sa-agent-transcript-tool-section-title\",\n toolCode: \"sa-agent-transcript-tool-code\",\n toolCodeMuted: \"sa-agent-transcript-tool-code-muted\",\n permissionPrompt: \"sa-agent-transcript-permission-prompt\",\n permissionHeader: \"sa-agent-transcript-permission-header\",\n permissionIcon: \"sa-agent-transcript-permission-icon\",\n permissionTitle: \"sa-agent-transcript-permission-title\",\n permissionDescription: \"sa-agent-transcript-permission-description\",\n permissionActions: \"sa-agent-transcript-permission-actions\",\n permissionButton: \"sa-agent-transcript-permission-button\",\n permissionAutoResolved: \"sa-agent-transcript-permission-auto-resolved\",\n thinkingRow: \"sa-agent-transcript-thinking-row\",\n thinkingAvatar: \"sa-agent-transcript-thinking-avatar\",\n thinkingAvatarImage: \"sa-agent-transcript-thinking-avatar-image\",\n thinkingAvatarLabel: \"sa-agent-transcript-thinking-avatar-label\",\n thinkingIndicator: \"sa-agent-transcript-thinking-indicator\",\n thinkingDot: \"sa-agent-transcript-thinking-dot\",\n endAnchor: \"sa-agent-transcript-end\",\n};\n\nconst DEFAULT_DIVIDER_TITLES = new Set([\"Session Started\", \"Turn Started\", \"Turn Ended\"]);\n\nconst cx = (...values: Array<string | false | null | undefined>) => values.filter(Boolean).join(\" \");\n\nconst mergeClassNames = (defaults: AgentTranscriptClassNames, overrides?: Partial<AgentTranscriptClassNames>): AgentTranscriptClassNames => ({\n root: cx(defaults.root, overrides?.root),\n divider: cx(defaults.divider, overrides?.divider),\n dividerLine: cx(defaults.dividerLine, overrides?.dividerLine),\n dividerText: cx(defaults.dividerText, overrides?.dividerText),\n message: cx(defaults.message, overrides?.message),\n messageContent: cx(defaults.messageContent, overrides?.messageContent),\n messageText: cx(defaults.messageText, overrides?.messageText),\n error: cx(defaults.error, overrides?.error),\n toolGroupSingle: cx(defaults.toolGroupSingle, overrides?.toolGroupSingle),\n toolGroupContainer: cx(defaults.toolGroupContainer, overrides?.toolGroupContainer),\n toolGroupHeader: cx(defaults.toolGroupHeader, overrides?.toolGroupHeader),\n toolGroupIcon: cx(defaults.toolGroupIcon, overrides?.toolGroupIcon),\n toolGroupLabel: cx(defaults.toolGroupLabel, overrides?.toolGroupLabel),\n toolGroupChevron: cx(defaults.toolGroupChevron, overrides?.toolGroupChevron),\n toolGroupBody: cx(defaults.toolGroupBody, overrides?.toolGroupBody),\n toolItem: cx(defaults.toolItem, overrides?.toolItem),\n toolItemConnector: cx(defaults.toolItemConnector, overrides?.toolItemConnector),\n toolItemDot: cx(defaults.toolItemDot, overrides?.toolItemDot),\n toolItemLine: cx(defaults.toolItemLine, overrides?.toolItemLine),\n toolItemContent: cx(defaults.toolItemContent, overrides?.toolItemContent),\n toolItemHeader: cx(defaults.toolItemHeader, overrides?.toolItemHeader),\n toolItemIcon: cx(defaults.toolItemIcon, overrides?.toolItemIcon),\n toolItemLabel: cx(defaults.toolItemLabel, overrides?.toolItemLabel),\n toolItemSpinner: cx(defaults.toolItemSpinner, overrides?.toolItemSpinner),\n toolItemLink: cx(defaults.toolItemLink, overrides?.toolItemLink),\n toolItemChevron: cx(defaults.toolItemChevron, overrides?.toolItemChevron),\n toolItemBody: cx(defaults.toolItemBody, overrides?.toolItemBody),\n toolSection: cx(defaults.toolSection, overrides?.toolSection),\n toolSectionTitle: cx(defaults.toolSectionTitle, overrides?.toolSectionTitle),\n toolCode: cx(defaults.toolCode, overrides?.toolCode),\n toolCodeMuted: cx(defaults.toolCodeMuted, overrides?.toolCodeMuted),\n permissionPrompt: cx(defaults.permissionPrompt, overrides?.permissionPrompt),\n permissionHeader: cx(defaults.permissionHeader, overrides?.permissionHeader),\n permissionIcon: cx(defaults.permissionIcon, overrides?.permissionIcon),\n permissionTitle: cx(defaults.permissionTitle, overrides?.permissionTitle),\n permissionDescription: cx(defaults.permissionDescription, overrides?.permissionDescription),\n permissionActions: cx(defaults.permissionActions, overrides?.permissionActions),\n permissionButton: cx(defaults.permissionButton, overrides?.permissionButton),\n permissionAutoResolved: cx(defaults.permissionAutoResolved, overrides?.permissionAutoResolved),\n thinkingRow: cx(defaults.thinkingRow, overrides?.thinkingRow),\n thinkingAvatar: cx(defaults.thinkingAvatar, overrides?.thinkingAvatar),\n thinkingAvatarImage: cx(defaults.thinkingAvatarImage, overrides?.thinkingAvatarImage),\n thinkingAvatarLabel: cx(defaults.thinkingAvatarLabel, overrides?.thinkingAvatarLabel),\n thinkingIndicator: cx(defaults.thinkingIndicator, overrides?.thinkingIndicator),\n thinkingDot: cx(defaults.thinkingDot, overrides?.thinkingDot),\n endAnchor: cx(defaults.endAnchor, overrides?.endAnchor),\n});\n\nconst getMessageVariant = (entry: TranscriptEntry) => {\n if (entry.kind === \"tool\") return \"tool\";\n if (entry.kind === \"meta\") return entry.meta?.severity === \"error\" ? \"error\" : \"system\";\n if (entry.kind === \"reasoning\") return \"assistant\";\n if (entry.kind === \"permission\") return \"system\";\n if (entry.role === \"user\") return \"user\";\n return \"assistant\";\n};\n\nconst getToolItemLabel = (entry: TranscriptEntry) => {\n if (entry.kind === \"tool\") {\n const statusLabel = entry.toolStatus && entry.toolStatus !== \"completed\" ? ` (${entry.toolStatus.replaceAll(\"_\", \" \")})` : \"\";\n return `${entry.toolName ?? \"tool\"}${statusLabel}`;\n }\n\n if (entry.kind === \"reasoning\") {\n return `Reasoning${entry.reasoning?.visibility ? ` (${entry.reasoning.visibility})` : \"\"}`;\n }\n\n return entry.meta?.title ?? \"Status\";\n};\n\nconst getDefaultToolItemIcon = (entry: TranscriptEntry) => {\n if (entry.kind === \"tool\") return \"Tool\";\n if (entry.kind === \"reasoning\") return \"Thought\";\n return entry.meta?.severity === \"error\" ? \"Error\" : \"Info\";\n};\n\nconst getDefaultToolGroupSummary = (entries: TranscriptEntry[]) => {\n const count = entries.length;\n return `${count} Event${count === 1 ? \"\" : \"s\"}`;\n};\n\nconst getPermissionReplyForOption = (kind: string): PermissionReply => {\n if (kind === \"allow_once\") return \"once\";\n if (kind === \"allow_always\") return \"always\";\n return \"reject\";\n};\n\nconst getPermissionOptionLabel = (option: PermissionOption) => {\n if (option.name) return option.name;\n if (option.kind === \"allow_once\") return \"Allow Once\";\n if (option.kind === \"allow_always\") return \"Always Allow\";\n if (option.kind === \"reject_once\") return \"Reject\";\n if (option.kind === \"reject_always\") return \"Reject Always\";\n return option.kind;\n};\n\nconst getPermissionOptionTone = (kind: string) => (kind.startsWith(\"allow\") ? \"allow\" : \"reject\");\n\nconst defaultRenderMessageText = (entry: TranscriptEntry) => entry.text;\nconst defaultRenderPendingIndicator = () => \"...\";\nconst defaultRenderChevron = (expanded: boolean) => (expanded ? \"▾\" : \"▸\");\nconst defaultRenderEventLinkContent = () => \"Open\";\nconst defaultRenderPermissionIcon = () => \"Permission\";\nconst defaultRenderPermissionOptionContent = ({ label }: PermissionOptionRenderContext) => label;\nconst defaultIsDividerEntry = (entry: TranscriptEntry) => entry.kind === \"meta\" && DEFAULT_DIVIDER_TITLES.has(entry.meta?.title ?? \"\");\n\nconst defaultCanOpenEvent = (entry: TranscriptEntry) => Boolean(entry.eventId);\n\nconst buildGroupedEntries = (entries: TranscriptEntry[], isDividerEntry: (entry: TranscriptEntry) => boolean): GroupedEntries[] => {\n const groupedEntries: GroupedEntries[] = [];\n let currentToolGroup: TranscriptEntry[] = [];\n\n const flushToolGroup = () => {\n if (currentToolGroup.length === 0) {\n return;\n }\n groupedEntries.push({ type: \"tool-group\", entries: currentToolGroup });\n currentToolGroup = [];\n };\n\n for (const entry of entries) {\n if (isDividerEntry(entry)) {\n flushToolGroup();\n groupedEntries.push({ type: \"divider\", entries: [entry] });\n continue;\n }\n\n if (entry.kind === \"permission\") {\n flushToolGroup();\n groupedEntries.push({ type: \"permission\", entries: [entry] });\n continue;\n }\n\n if (entry.kind === \"tool\" || entry.kind === \"reasoning\" || entry.kind === \"meta\") {\n currentToolGroup.push(entry);\n continue;\n }\n\n flushToolGroup();\n groupedEntries.push({ type: \"message\", entries: [entry] });\n }\n\n flushToolGroup();\n return groupedEntries;\n};\n\nconst ToolItem = ({\n entry,\n isLast,\n classNames,\n onEventClick,\n canOpenEvent,\n renderInlinePendingIndicator,\n renderToolItemIcon,\n renderChevron,\n renderEventLinkContent,\n}: {\n entry: TranscriptEntry;\n isLast: boolean;\n classNames: AgentTranscriptClassNames;\n onEventClick?: (eventId: string) => void;\n canOpenEvent: (entry: TranscriptEntry) => boolean;\n renderInlinePendingIndicator: () => ReactNode;\n renderToolItemIcon: (entry: TranscriptEntry) => ReactNode;\n renderChevron: (expanded: boolean) => ReactNode;\n renderEventLinkContent: (entry: TranscriptEntry) => ReactNode;\n}) => {\n const [expanded, setExpanded] = useState(false);\n const isTool = entry.kind === \"tool\";\n const isReasoning = entry.kind === \"reasoning\";\n const isMeta = entry.kind === \"meta\";\n const isComplete = isTool && (entry.toolStatus === \"completed\" || entry.toolStatus === \"failed\");\n const isFailed = isTool && entry.toolStatus === \"failed\";\n const isInProgress = isTool && entry.toolStatus === \"in_progress\";\n const hasContent = isTool\n ? Boolean(entry.toolInput || entry.toolOutput)\n : isReasoning\n ? Boolean(entry.reasoning?.text?.trim())\n : Boolean(entry.meta?.detail?.trim());\n const showEventLink = Boolean(entry.eventId && onEventClick && canOpenEvent(entry));\n\n return (\n <div\n className={cx(classNames.toolItem, isLast && \"last\", isFailed && \"failed\")}\n data-slot=\"tool-item\"\n data-kind={entry.kind}\n data-state={entry.toolStatus}\n data-last={isLast ? \"true\" : undefined}\n data-failed={isFailed ? \"true\" : undefined}\n >\n <div className={classNames.toolItemConnector} data-slot=\"tool-item-connector\">\n <div className={classNames.toolItemDot} data-slot=\"tool-item-dot\" />\n {!isLast ? <div className={classNames.toolItemLine} data-slot=\"tool-item-line\" /> : null}\n </div>\n <div className={classNames.toolItemContent} data-slot=\"tool-item-content\">\n <button\n type=\"button\"\n className={cx(classNames.toolItemHeader, expanded && \"expanded\")}\n data-slot=\"tool-item-header\"\n data-expanded={expanded ? \"true\" : undefined}\n data-has-content={hasContent ? \"true\" : undefined}\n disabled={!hasContent}\n onClick={() => {\n if (hasContent) {\n setExpanded((value) => !value);\n }\n }}\n >\n <span className={classNames.toolItemIcon} data-slot=\"tool-item-icon\">\n {renderToolItemIcon(entry)}\n </span>\n <span className={classNames.toolItemLabel} data-slot=\"tool-item-label\">\n {getToolItemLabel(entry)}\n </span>\n {isInProgress ? (\n <span className={classNames.toolItemSpinner} data-slot=\"tool-item-spinner\">\n {renderInlinePendingIndicator()}\n </span>\n ) : null}\n {showEventLink ? (\n <span\n className={classNames.toolItemLink}\n data-slot=\"tool-item-link\"\n role=\"button\"\n tabIndex={0}\n onClick={(event) => {\n event.stopPropagation();\n onEventClick?.(entry.eventId!);\n }}\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n event.stopPropagation();\n onEventClick?.(entry.eventId!);\n }\n }}\n >\n {renderEventLinkContent(entry)}\n </span>\n ) : null}\n {hasContent ? (\n <span className={classNames.toolItemChevron} data-slot=\"tool-item-chevron\">\n {renderChevron(expanded)}\n </span>\n ) : null}\n </button>\n {expanded && hasContent ? (\n <div className={classNames.toolItemBody} data-slot=\"tool-item-body\">\n {isTool && entry.toolInput ? (\n <div className={classNames.toolSection} data-slot=\"tool-section\" data-section=\"input\">\n <div className={classNames.toolSectionTitle} data-slot=\"tool-section-title\">\n Input\n </div>\n <pre className={classNames.toolCode} data-slot=\"tool-code\">\n {entry.toolInput}\n </pre>\n </div>\n ) : null}\n {isTool && isComplete && entry.toolOutput ? (\n <div className={classNames.toolSection} data-slot=\"tool-section\" data-section=\"output\">\n <div className={classNames.toolSectionTitle} data-slot=\"tool-section-title\">\n Output\n </div>\n <pre className={classNames.toolCode} data-slot=\"tool-code\">\n {entry.toolOutput}\n </pre>\n </div>\n ) : null}\n {isReasoning && entry.reasoning?.text ? (\n <div className={classNames.toolSection} data-slot=\"tool-section\" data-section=\"reasoning\">\n <pre className={cx(classNames.toolCode, classNames.toolCodeMuted)} data-slot=\"tool-code\">\n {entry.reasoning.text}\n </pre>\n </div>\n ) : null}\n {isMeta && entry.meta?.detail ? (\n <div className={classNames.toolSection} data-slot=\"tool-section\" data-section=\"meta\">\n <pre className={classNames.toolCode} data-slot=\"tool-code\">\n {entry.meta.detail}\n </pre>\n </div>\n ) : null}\n </div>\n ) : null}\n </div>\n </div>\n );\n};\n\nconst ToolGroup = ({\n entries,\n classNames,\n onEventClick,\n canOpenEvent,\n getToolGroupSummary,\n renderInlinePendingIndicator,\n renderToolItemIcon,\n renderToolGroupIcon,\n renderChevron,\n renderEventLinkContent,\n}: {\n entries: TranscriptEntry[];\n classNames: AgentTranscriptClassNames;\n onEventClick?: (eventId: string) => void;\n canOpenEvent: (entry: TranscriptEntry) => boolean;\n getToolGroupSummary: (entries: TranscriptEntry[]) => string;\n renderInlinePendingIndicator: () => ReactNode;\n renderToolItemIcon: (entry: TranscriptEntry) => ReactNode;\n renderToolGroupIcon: (entries: TranscriptEntry[], expanded: boolean) => ReactNode;\n renderChevron: (expanded: boolean) => ReactNode;\n renderEventLinkContent: (entry: TranscriptEntry) => ReactNode;\n}) => {\n const [expanded, setExpanded] = useState(false);\n const hasFailed = entries.some((entry) => entry.kind === \"tool\" && entry.toolStatus === \"failed\");\n\n if (entries.length === 1) {\n return (\n <div className={classNames.toolGroupSingle} data-slot=\"tool-group-single\">\n <ToolItem\n entry={entries[0]}\n isLast={true}\n classNames={classNames}\n onEventClick={onEventClick}\n canOpenEvent={canOpenEvent}\n renderInlinePendingIndicator={renderInlinePendingIndicator}\n renderToolItemIcon={renderToolItemIcon}\n renderChevron={renderChevron}\n renderEventLinkContent={renderEventLinkContent}\n />\n </div>\n );\n }\n\n return (\n <div className={cx(classNames.toolGroupContainer, hasFailed && \"failed\")} data-slot=\"tool-group\" data-failed={hasFailed ? \"true\" : undefined}>\n <button\n type=\"button\"\n className={cx(classNames.toolGroupHeader, expanded && \"expanded\")}\n data-slot=\"tool-group-header\"\n data-expanded={expanded ? \"true\" : undefined}\n onClick={() => setExpanded((value) => !value)}\n >\n <span className={classNames.toolGroupIcon} data-slot=\"tool-group-icon\">\n {renderToolGroupIcon(entries, expanded)}\n </span>\n <span className={classNames.toolGroupLabel} data-slot=\"tool-group-label\">\n {getToolGroupSummary(entries)}\n </span>\n <span className={classNames.toolGroupChevron} data-slot=\"tool-group-chevron\">\n {renderChevron(expanded)}\n </span>\n </button>\n {expanded ? (\n <div className={classNames.toolGroupBody} data-slot=\"tool-group-body\">\n {entries.map((entry, index) => (\n <ToolItem\n key={entry.id}\n entry={entry}\n isLast={index === entries.length - 1}\n classNames={classNames}\n onEventClick={onEventClick}\n canOpenEvent={canOpenEvent}\n renderInlinePendingIndicator={renderInlinePendingIndicator}\n renderToolItemIcon={renderToolItemIcon}\n renderChevron={renderChevron}\n renderEventLinkContent={renderEventLinkContent}\n />\n ))}\n </div>\n ) : null}\n </div>\n );\n};\n\nconst PermissionPrompt = ({\n entry,\n classNames,\n onPermissionReply,\n renderPermissionIcon,\n renderPermissionOptionContent,\n}: {\n entry: TranscriptEntry;\n classNames: AgentTranscriptClassNames;\n onPermissionReply?: (permissionId: string, reply: PermissionReply) => void;\n renderPermissionIcon: (entry: TranscriptEntry) => ReactNode;\n renderPermissionOptionContent: (context: PermissionOptionRenderContext) => ReactNode;\n}) => {\n const permission = entry.permission;\n if (!permission) {\n return null;\n }\n\n const resolved = Boolean(permission.resolved);\n const selectedOptionId = permission.selectedOptionId;\n const canReply = Boolean(onPermissionReply) && !resolved;\n\n return (\n <div className={cx(classNames.permissionPrompt, resolved && \"resolved\")} data-slot=\"permission-prompt\" data-resolved={resolved ? \"true\" : undefined}>\n <div className={classNames.permissionHeader} data-slot=\"permission-header\">\n <span className={classNames.permissionIcon} data-slot=\"permission-icon\">\n {renderPermissionIcon(entry)}\n </span>\n <span className={classNames.permissionTitle} data-slot=\"permission-title\">\n {permission.title}\n </span>\n </div>\n {permission.description ? (\n <div className={classNames.permissionDescription} data-slot=\"permission-description\">\n {permission.description}\n </div>\n ) : null}\n <div className={classNames.permissionActions} data-slot=\"permission-actions\">\n {permission.options.map((option) => {\n const reply = getPermissionReplyForOption(option.kind);\n const label = getPermissionOptionLabel(option);\n const selected = resolved && selectedOptionId === option.optionId;\n const dimmed = resolved && !selected && selectedOptionId != null;\n const tone = getPermissionOptionTone(option.kind);\n\n return (\n <button\n key={option.optionId}\n type=\"button\"\n className={cx(classNames.permissionButton, tone, selected && \"selected\", dimmed && \"dimmed\")}\n data-slot=\"permission-button\"\n data-tone={tone}\n data-selected={selected ? \"true\" : undefined}\n data-dimmed={dimmed ? \"true\" : undefined}\n disabled={!canReply}\n onClick={() => onPermissionReply?.(permission.permissionId, reply)}\n >\n {renderPermissionOptionContent({\n entry,\n option,\n label,\n reply,\n selected,\n dimmed,\n resolved,\n })}\n </button>\n );\n })}\n {resolved && !selectedOptionId ? (\n <span className={classNames.permissionAutoResolved} data-slot=\"permission-auto-resolved\">\n Auto-resolved\n </span>\n ) : null}\n </div>\n </div>\n );\n};\n\nexport const AgentTranscript = ({\n entries,\n className,\n classNames: classNameOverrides,\n endRef,\n sessionError,\n eventError,\n isThinking,\n agentId,\n onEventClick,\n onPermissionReply,\n isDividerEntry = defaultIsDividerEntry,\n canOpenEvent = defaultCanOpenEvent,\n getToolGroupSummary = getDefaultToolGroupSummary,\n renderMessageText = defaultRenderMessageText,\n renderInlinePendingIndicator = defaultRenderPendingIndicator,\n renderThinkingState,\n renderToolItemIcon = getDefaultToolItemIcon,\n renderToolGroupIcon = () => null,\n renderChevron = defaultRenderChevron,\n renderEventLinkContent = defaultRenderEventLinkContent,\n renderPermissionIcon = defaultRenderPermissionIcon,\n renderPermissionOptionContent = defaultRenderPermissionOptionContent,\n}: AgentTranscriptProps) => {\n const resolvedClassNames = useMemo(() => mergeClassNames(DEFAULT_CLASS_NAMES, classNameOverrides), [classNameOverrides]);\n const groupedEntries = useMemo(() => buildGroupedEntries(entries, isDividerEntry), [entries, isDividerEntry]);\n\n return (\n <div className={cx(resolvedClassNames.root, className)} data-slot=\"root\">\n {groupedEntries.map((group, index) => {\n if (group.type === \"divider\") {\n const entry = group.entries[0];\n const title = entry.meta?.title ?? \"Status\";\n return (\n <div key={entry.id} className={resolvedClassNames.divider} data-slot=\"divider\">\n <div className={resolvedClassNames.dividerLine} data-slot=\"divider-line\" />\n <span className={resolvedClassNames.dividerText} data-slot=\"divider-text\">\n {title}\n </span>\n <div className={resolvedClassNames.dividerLine} data-slot=\"divider-line\" />\n </div>\n );\n }\n\n if (group.type === \"tool-group\") {\n return (\n <ToolGroup\n key={`tool-group-${index}`}\n entries={group.entries}\n classNames={resolvedClassNames}\n onEventClick={onEventClick}\n canOpenEvent={canOpenEvent}\n getToolGroupSummary={getToolGroupSummary}\n renderInlinePendingIndicator={renderInlinePendingIndicator}\n renderToolItemIcon={renderToolItemIcon}\n renderToolGroupIcon={renderToolGroupIcon}\n renderChevron={renderChevron}\n renderEventLinkContent={renderEventLinkContent}\n />\n );\n }\n\n if (group.type === \"permission\") {\n const entry = group.entries[0];\n return (\n <PermissionPrompt\n key={entry.id}\n entry={entry}\n classNames={resolvedClassNames}\n onPermissionReply={onPermissionReply}\n renderPermissionIcon={renderPermissionIcon}\n renderPermissionOptionContent={renderPermissionOptionContent}\n />\n );\n }\n\n const entry = group.entries[0];\n const messageVariant = getMessageVariant(entry);\n\n return (\n <div\n key={entry.id}\n className={cx(resolvedClassNames.message, messageVariant, \"no-avatar\")}\n data-slot=\"message\"\n data-kind={entry.kind}\n data-role={entry.role}\n data-variant={messageVariant}\n data-severity={entry.meta?.severity}\n >\n <div className={resolvedClassNames.messageContent} data-slot=\"message-content\">\n {entry.text ? (\n <div className={resolvedClassNames.messageText} data-slot=\"message-text\">\n {renderMessageText(entry)}\n </div>\n ) : (\n <span className={resolvedClassNames.thinkingIndicator} data-slot=\"thinking-indicator\">\n {renderInlinePendingIndicator()}\n </span>\n )}\n </div>\n </div>\n );\n })}\n {sessionError ? (\n <div className={resolvedClassNames.error} data-slot=\"error\" data-source=\"session\">\n {sessionError}\n </div>\n ) : null}\n {eventError ? (\n <div className={resolvedClassNames.error} data-slot=\"error\" data-source=\"event\">\n {eventError}\n </div>\n ) : null}\n {isThinking\n ? (renderThinkingState?.({ agentId }) ?? (\n <div className={resolvedClassNames.thinkingRow} data-slot=\"thinking-row\">\n <span className={resolvedClassNames.thinkingIndicator} data-slot=\"thinking-indicator\">\n Thinking...\n </span>\n </div>\n ))\n : null}\n <div ref={endRef} className={resolvedClassNames.endAnchor} data-slot=\"end-anchor\" />\n </div>\n );\n};\n","\"use client\";\n\nimport type { KeyboardEvent, ReactNode, Ref, TextareaHTMLAttributes } from \"react\";\n\nexport interface ChatComposerClassNames {\n root: string;\n form: string;\n input: string;\n submit: string;\n submitContent: string;\n}\n\nexport interface ChatComposerProps {\n message: string;\n onMessageChange: (value: string) => void;\n onSubmit: () => void;\n onKeyDown?: (event: KeyboardEvent<HTMLTextAreaElement>) => void;\n placeholder?: string;\n disabled?: boolean;\n submitDisabled?: boolean;\n allowEmptySubmit?: boolean;\n submitLabel?: string;\n className?: string;\n classNames?: Partial<ChatComposerClassNames>;\n inputRef?: Ref<HTMLTextAreaElement>;\n rows?: number;\n textareaProps?: Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, \"className\" | \"disabled\" | \"onChange\" | \"onKeyDown\" | \"placeholder\" | \"rows\" | \"value\">;\n renderSubmitContent?: () => ReactNode;\n renderFooter?: () => ReactNode;\n}\n\nconst DEFAULT_CLASS_NAMES: ChatComposerClassNames = {\n root: \"sa-chat-composer\",\n form: \"sa-chat-composer-form\",\n input: \"sa-chat-composer-input\",\n submit: \"sa-chat-composer-submit\",\n submitContent: \"sa-chat-composer-submit-content\",\n};\n\nconst cx = (...values: Array<string | false | null | undefined>) => values.filter(Boolean).join(\" \");\n\nconst mergeClassNames = (defaults: ChatComposerClassNames, overrides?: Partial<ChatComposerClassNames>): ChatComposerClassNames => ({\n root: cx(defaults.root, overrides?.root),\n form: cx(defaults.form, overrides?.form),\n input: cx(defaults.input, overrides?.input),\n submit: cx(defaults.submit, overrides?.submit),\n submitContent: cx(defaults.submitContent, overrides?.submitContent),\n});\n\nexport const ChatComposer = ({\n message,\n onMessageChange,\n onSubmit,\n onKeyDown,\n placeholder,\n disabled = false,\n submitDisabled = false,\n allowEmptySubmit = false,\n submitLabel = \"Send\",\n className,\n classNames: classNameOverrides,\n inputRef,\n rows = 1,\n textareaProps,\n renderSubmitContent,\n renderFooter,\n}: ChatComposerProps) => {\n const resolvedClassNames = mergeClassNames(DEFAULT_CLASS_NAMES, classNameOverrides);\n const isSubmitDisabled = disabled || submitDisabled || (!allowEmptySubmit && message.trim().length === 0);\n\n return (\n <div className={cx(resolvedClassNames.root, className)} data-slot=\"root\">\n <form\n className={resolvedClassNames.form}\n data-slot=\"form\"\n onSubmit={(event) => {\n event.preventDefault();\n if (!isSubmitDisabled) {\n onSubmit();\n }\n }}\n >\n <textarea\n {...textareaProps}\n ref={inputRef}\n className={resolvedClassNames.input}\n data-slot=\"input\"\n data-disabled={disabled ? \"true\" : undefined}\n data-empty={message.trim().length === 0 ? \"true\" : undefined}\n value={message}\n onChange={(event) => onMessageChange(event.target.value)}\n onKeyDown={onKeyDown}\n placeholder={placeholder}\n rows={rows}\n disabled={disabled}\n />\n {renderFooter?.()}\n <button\n type=\"submit\"\n className={resolvedClassNames.submit}\n data-slot=\"submit\"\n data-disabled={isSubmitDisabled ? \"true\" : undefined}\n disabled={isSubmitDisabled}\n aria-label={submitLabel}\n title={submitLabel}\n >\n <span className={resolvedClassNames.submitContent} data-slot=\"submit-content\">\n {renderSubmitContent?.() ?? submitLabel}\n </span>\n </button>\n </form>\n </div>\n );\n};\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport { AgentTranscript, type AgentTranscriptClassNames, type AgentTranscriptProps, type TranscriptEntry } from \"./AgentTranscript.tsx\";\nimport { ChatComposer, type ChatComposerClassNames, type ChatComposerProps } from \"./ChatComposer.tsx\";\n\nexport interface AgentConversationClassNames {\n root: string;\n transcript: string;\n emptyState: string;\n composer: string;\n}\n\nexport interface AgentConversationProps {\n entries: TranscriptEntry[];\n className?: string;\n classNames?: Partial<AgentConversationClassNames>;\n emptyState?: ReactNode;\n transcriptClassName?: string;\n transcriptClassNames?: Partial<AgentTranscriptClassNames>;\n composerClassName?: string;\n composerClassNames?: Partial<ChatComposerClassNames>;\n transcriptProps?: Omit<AgentTranscriptProps, \"entries\" | \"className\" | \"classNames\">;\n composerProps?: Omit<ChatComposerProps, \"className\" | \"classNames\">;\n}\n\nconst DEFAULT_CLASS_NAMES: AgentConversationClassNames = {\n root: \"sa-agent-conversation\",\n transcript: \"sa-agent-conversation-transcript\",\n emptyState: \"sa-agent-conversation-empty-state\",\n composer: \"sa-agent-conversation-composer\",\n};\n\nconst cx = (...values: Array<string | false | null | undefined>) => values.filter(Boolean).join(\" \");\n\nconst mergeClassNames = (defaults: AgentConversationClassNames, overrides?: Partial<AgentConversationClassNames>): AgentConversationClassNames => ({\n root: cx(defaults.root, overrides?.root),\n transcript: cx(defaults.transcript, overrides?.transcript),\n emptyState: cx(defaults.emptyState, overrides?.emptyState),\n composer: cx(defaults.composer, overrides?.composer),\n});\n\nexport const AgentConversation = ({\n entries,\n className,\n classNames: classNameOverrides,\n emptyState,\n transcriptClassName,\n transcriptClassNames,\n composerClassName,\n composerClassNames,\n transcriptProps,\n composerProps,\n}: AgentConversationProps) => {\n const resolvedClassNames = mergeClassNames(DEFAULT_CLASS_NAMES, classNameOverrides);\n const hasTranscriptContent = entries.length > 0 || Boolean(transcriptProps?.sessionError) || Boolean(transcriptProps?.eventError);\n\n return (\n <div className={cx(resolvedClassNames.root, className)} data-slot=\"root\">\n {hasTranscriptContent ? (\n <AgentTranscript\n entries={entries}\n className={cx(resolvedClassNames.transcript, transcriptClassName)}\n classNames={transcriptClassNames}\n {...transcriptProps}\n />\n ) : emptyState ? (\n <div className={resolvedClassNames.emptyState} data-slot=\"empty-state\">\n {emptyState}\n </div>\n ) : null}\n {composerProps ? (\n <ChatComposer className={cx(resolvedClassNames.composer, composerClassName)} classNames={composerClassNames} {...composerProps} />\n ) : null}\n </div>\n );\n};\n","\"use client\";\n\nimport type { FitAddon as GhosttyFitAddon, Terminal as GhosttyTerminal } from \"ghostty-web\";\nimport type { CSSProperties } from \"react\";\nimport { useEffect, useRef, useState } from \"react\";\nimport type {\n SandboxAgent,\n TerminalErrorStatus,\n TerminalExitStatus,\n TerminalReadyStatus,\n} from \"sandbox-agent\";\n\ntype ConnectionState = \"connecting\" | \"ready\" | \"closed\" | \"error\";\n\nexport type ProcessTerminalClient = Pick<SandboxAgent, \"connectProcessTerminal\">;\n\nexport interface ProcessTerminalProps {\n client: ProcessTerminalClient;\n processId: string;\n className?: string;\n style?: CSSProperties;\n terminalStyle?: CSSProperties;\n statusBarStyleOverride?: CSSProperties;\n height?: number | string;\n showStatusBar?: boolean;\n onExit?: (status: TerminalExitStatus) => void;\n onError?: (error: TerminalErrorStatus | Error) => void;\n}\n\nconst terminalTheme = {\n background: \"#09090b\",\n foreground: \"#f4f4f5\",\n cursor: \"#f97316\",\n cursorAccent: \"#09090b\",\n selectionBackground: \"#27272a\",\n black: \"#18181b\",\n red: \"#f87171\",\n green: \"#4ade80\",\n yellow: \"#fbbf24\",\n blue: \"#60a5fa\",\n magenta: \"#f472b6\",\n cyan: \"#22d3ee\",\n white: \"#e4e4e7\",\n brightBlack: \"#3f3f46\",\n brightRed: \"#fb7185\",\n brightGreen: \"#86efac\",\n brightYellow: \"#fde047\",\n brightBlue: \"#93c5fd\",\n brightMagenta: \"#f9a8d4\",\n brightCyan: \"#67e8f9\",\n brightWhite: \"#fafafa\",\n};\n\nconst shellStyle: CSSProperties = {\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n borderRadius: 10,\n background: \"rgba(0, 0, 0, 0.3)\",\n};\n\nconst statusBarStyle: CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: 12,\n padding: \"8px 12px\",\n borderBottom: \"1px solid rgba(255, 255, 255, 0.08)\",\n background: \"rgba(0, 0, 0, 0.2)\",\n color: \"rgba(244, 244, 245, 0.86)\",\n fontSize: 11,\n lineHeight: 1.4,\n};\n\nconst hostBaseStyle: CSSProperties = {\n minHeight: 320,\n padding: 10,\n overflow: \"hidden\",\n};\n\nconst exitCodeStyle: CSSProperties = {\n fontFamily: \"ui-monospace, SFMono-Regular, SF Mono, Menlo, monospace\",\n opacity: 0.72,\n};\n\nconst getStatusColor = (state: ConnectionState): string => {\n switch (state) {\n case \"ready\":\n return \"#4ade80\";\n case \"error\":\n return \"#fb7185\";\n case \"closed\":\n return \"#fbbf24\";\n default:\n return \"rgba(244, 244, 245, 0.72)\";\n }\n};\n\nexport const ProcessTerminal = ({\n client,\n processId,\n className,\n style,\n terminalStyle,\n statusBarStyleOverride,\n height = 360,\n showStatusBar = true,\n onExit,\n onError,\n}: ProcessTerminalProps) => {\n const hostRef = useRef<HTMLDivElement | null>(null);\n const [connectionState, setConnectionState] = useState<ConnectionState>(\"connecting\");\n const [statusMessage, setStatusMessage] = useState(\"Connecting to PTY...\");\n const [exitCode, setExitCode] = useState<number | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n let terminal: GhosttyTerminal | null = null;\n let fitAddon: GhosttyFitAddon | null = null;\n let session: ReturnType<ProcessTerminalClient[\"connectProcessTerminal\"]> | null = null;\n let resizeRaf = 0;\n let removeDataListener: { dispose(): void } | null = null;\n let removeResizeListener: { dispose(): void } | null = null;\n\n setConnectionState(\"connecting\");\n setStatusMessage(\"Connecting to PTY...\");\n setExitCode(null);\n\n const syncSize = () => {\n if (!terminal || !session) {\n return;\n }\n\n session.resize({\n cols: terminal.cols,\n rows: terminal.rows,\n });\n };\n\n const connect = async () => {\n try {\n const ghostty = await import(\"ghostty-web\");\n await ghostty.init();\n\n if (cancelled || !hostRef.current) {\n return;\n }\n\n terminal = new ghostty.Terminal({\n allowTransparency: true,\n cursorBlink: true,\n cursorStyle: \"block\",\n fontFamily: \"ui-monospace, SFMono-Regular, SF Mono, Menlo, monospace\",\n fontSize: 13,\n smoothScrollDuration: 90,\n theme: terminalTheme,\n });\n fitAddon = new ghostty.FitAddon();\n\n terminal.open(hostRef.current);\n const terminalRoot = hostRef.current.firstElementChild;\n if (terminalRoot instanceof HTMLElement) {\n terminalRoot.style.width = \"100%\";\n terminalRoot.style.height = \"100%\";\n }\n terminal.loadAddon(fitAddon);\n fitAddon.fit();\n fitAddon.observeResize();\n terminal.focus();\n\n removeDataListener = terminal.onData((data) => {\n session?.sendInput(data);\n });\n\n removeResizeListener = terminal.onResize(() => {\n if (resizeRaf) {\n window.cancelAnimationFrame(resizeRaf);\n }\n resizeRaf = window.requestAnimationFrame(syncSize);\n });\n\n const nextSession = client.connectProcessTerminal(processId);\n session = nextSession;\n\n nextSession.onReady((frame: TerminalReadyStatus) => {\n if (cancelled || frame.type !== \"ready\") {\n return;\n }\n\n setConnectionState(\"ready\");\n setStatusMessage(\"Connected\");\n syncSize();\n });\n\n nextSession.onData((bytes: Uint8Array) => {\n if (cancelled || !terminal) {\n return;\n }\n terminal.write(bytes);\n });\n\n nextSession.onExit((frame: TerminalExitStatus) => {\n if (cancelled || frame.type !== \"exit\") {\n return;\n }\n\n setConnectionState(\"closed\");\n setExitCode(frame.exitCode ?? null);\n setStatusMessage(frame.exitCode == null ? \"Process exited.\" : `Process exited with code ${frame.exitCode}.`);\n onExit?.(frame);\n });\n\n nextSession.onError((error: TerminalErrorStatus | Error) => {\n if (cancelled) {\n return;\n }\n\n setConnectionState(\"error\");\n setStatusMessage(error instanceof Error ? error.message : error.message);\n onError?.(error);\n });\n\n nextSession.onClose(() => {\n if (cancelled) {\n return;\n }\n\n setConnectionState((current) => (current === \"error\" ? current : \"closed\"));\n setStatusMessage((current) => (current === \"Connected\" ? \"Terminal disconnected.\" : current));\n });\n } catch (error) {\n if (cancelled) {\n return;\n }\n\n const nextError = error instanceof Error ? error : new Error(\"Failed to initialize terminal.\");\n setConnectionState(\"error\");\n setStatusMessage(nextError.message);\n onError?.(nextError);\n }\n };\n\n void connect();\n\n return () => {\n cancelled = true;\n if (resizeRaf) {\n window.cancelAnimationFrame(resizeRaf);\n }\n removeDataListener?.dispose();\n removeResizeListener?.dispose();\n session?.close();\n terminal?.dispose();\n };\n }, [client, onError, onExit, processId]);\n\n return (\n <div className={className} style={{ ...shellStyle, ...style }}>\n {showStatusBar ? (\n <div style={{ ...statusBarStyle, ...statusBarStyleOverride }}>\n <span style={{ color: getStatusColor(connectionState) }}>{statusMessage}</span>\n {exitCode != null ? <span style={exitCodeStyle}>exit={exitCode}</span> : null}\n </div>\n ) : null}\n <div\n ref={hostRef}\n role=\"presentation\"\n style={{\n ...hostBaseStyle,\n height,\n ...terminalStyle,\n }}\n onClick={() => {\n hostRef.current?.querySelector(\"textarea\")?.focus();\n }}\n />\n </div>\n );\n};\n"],"mappings":"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","names":["entry","jsx","jsxs","DEFAULT_CLASS_NAMES","cx","mergeClassNames","jsx","jsxs","DEFAULT_CLASS_NAMES","cx","mergeClassNames","useState","jsx","jsxs"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sandbox-agent/react",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "React components for Sandbox Agent frontend integrations",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -31,7 +31,7 @@
31
31
  "react": "^18.3.1",
32
32
  "tsup": "^8.0.0",
33
33
  "typescript": "^5.7.0",
34
- "sandbox-agent": "0.3.1"
34
+ "sandbox-agent": "0.3.2"
35
35
  },
36
36
  "scripts": {
37
37
  "build": "tsup",