@opengeni/react 0.34.2 → 0.34.3

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 (59) hide show
  1. package/dist/{chunk-A2WITZTI.js → chunk-4NMH6UJ3.js} +2 -2
  2. package/dist/{chunk-GZ4KR67U.js → chunk-ALA3UGWB.js} +2 -2
  3. package/dist/chunk-ATSTR5P3.js +138 -0
  4. package/dist/chunk-ATSTR5P3.js.map +1 -0
  5. package/dist/{chunk-KZRUYCL4.js → chunk-FT2TXNGZ.js} +5 -2
  6. package/dist/chunk-FT2TXNGZ.js.map +1 -0
  7. package/dist/{chunk-4QOQ2DSR.js → chunk-LAKLF4PA.js} +14 -1
  8. package/dist/chunk-LAKLF4PA.js.map +1 -0
  9. package/dist/{chunk-TCCE5ZU5.js → chunk-MEGI4FS6.js} +38 -9
  10. package/dist/chunk-MEGI4FS6.js.map +1 -0
  11. package/dist/{chunk-MS3FBZ6A.js → chunk-PVW56EVR.js} +105 -62
  12. package/dist/chunk-PVW56EVR.js.map +1 -0
  13. package/dist/{chunk-L7R5RK6A.js → chunk-QRYJCWGD.js} +1199 -897
  14. package/dist/chunk-QRYJCWGD.js.map +1 -0
  15. package/dist/components/chat-composer.d.ts +2 -1
  16. package/dist/components/composer.d.ts +8 -2
  17. package/dist/components/copy-button.d.ts +4 -2
  18. package/dist/components/tip-follow.d.ts +3 -0
  19. package/dist/composer.d.ts +2 -1
  20. package/dist/composer.js +4 -3
  21. package/dist/index.d.ts +2 -2
  22. package/dist/index.js +105 -101
  23. package/dist/index.js.map +1 -1
  24. package/dist/lib/format.d.ts +2 -0
  25. package/dist/machines.js +2 -2
  26. package/dist/session-ui.js +4 -3
  27. package/dist/session.js +4 -4
  28. package/dist/timeline/index.d.ts +1 -1
  29. package/dist/timeline/parsers.d.ts +5 -0
  30. package/dist/timeline/projection.d.ts +1 -12
  31. package/dist/timeline/tool-display-name.d.ts +17 -6
  32. package/dist/workstream-control-event.d.ts +6 -0
  33. package/package.json +1 -1
  34. package/src/components/chat-composer.tsx +1 -1
  35. package/src/components/composer-transcription-control.tsx +70 -57
  36. package/src/components/composer.tsx +197 -126
  37. package/src/components/copy-button.tsx +27 -8
  38. package/src/components/message-timeline.tsx +236 -39
  39. package/src/components/tip-follow.ts +15 -0
  40. package/src/composer.ts +1 -1
  41. package/src/hooks/use-composer.ts +7 -1
  42. package/src/index.ts +2 -1
  43. package/src/lib/format.ts +14 -0
  44. package/src/timeline/index.ts +2 -0
  45. package/src/timeline/parsers.ts +18 -1
  46. package/src/timeline/projection.ts +50 -20
  47. package/src/timeline/registry.ts +15 -2
  48. package/src/timeline/shared.tsx +30 -28
  49. package/src/timeline/tool-display-name.ts +30 -11
  50. package/src/timeline/tool-renderers.tsx +347 -16
  51. package/src/timeline/turn-summary.tsx +5 -2
  52. package/src/workstream-control-event.ts +6 -0
  53. package/dist/chunk-4QOQ2DSR.js.map +0 -1
  54. package/dist/chunk-KZRUYCL4.js.map +0 -1
  55. package/dist/chunk-L7R5RK6A.js.map +0 -1
  56. package/dist/chunk-MS3FBZ6A.js.map +0 -1
  57. package/dist/chunk-TCCE5ZU5.js.map +0 -1
  58. /package/dist/{chunk-A2WITZTI.js.map → chunk-4NMH6UJ3.js.map} +0 -0
  59. /package/dist/{chunk-GZ4KR67U.js.map → chunk-ALA3UGWB.js.map} +0 -0
@@ -4,7 +4,8 @@ import type { SlashCommand } from "../commands/types";
4
4
  import type { ComposerState } from "../hooks/use-composer";
5
5
  import type { UseFileAttachmentsResult } from "../hooks/use-file-attachments";
6
6
  import type { SlashCommandContext } from "../hooks/use-slash-commands";
7
- import { OPEN_WORKSTREAM_CONTROL_EVENT, type ChatComposerMessages, type ComposerControlLinks } from "./composer";
7
+ import { OPEN_WORKSTREAM_CONTROL_EVENT } from "../workstream-control-event";
8
+ import { type ChatComposerMessages, type ComposerControlLinks } from "./composer";
8
9
  import { type ComposerTranscriptionControlProps } from "./composer-transcription-control";
9
10
  export { OPEN_WORKSTREAM_CONTROL_EVENT };
10
11
  export type ChatComposerProps = {
@@ -5,7 +5,8 @@ import type { ComposerState } from "../hooks/use-composer";
5
5
  import type { UseFileAttachmentsResult } from "../hooks/use-file-attachments";
6
6
  import { type ConfirmState, type SlashCommandContext } from "../hooks/use-slash-commands";
7
7
  import type { PickerModelRow } from "../model-policy";
8
- export declare const OPEN_WORKSTREAM_CONTROL_EVENT = "opengeni:open-workstream-control";
8
+ import { OPEN_WORKSTREAM_CONTROL_EVENT } from "../workstream-control-event";
9
+ export { OPEN_WORKSTREAM_CONTROL_EVENT };
9
10
  export type ComposerDelivery = Pick<ComposerState, "value" | "setValue" | "send" | "steer" | "sending" | "canSend" | "error" | "clearError">;
10
11
  export type ComposerDraftState = Pick<ComposerState, "draftConflict" | "draftSaving" | "resolveDraftConflict" | "restoredResources" | "removeRestoredResource">;
11
12
  export type ComposerControlState = Pick<ComposerState, "pause" | "pausing" | "resume" | "resumeScope" | "resuming">;
@@ -91,6 +92,12 @@ export type UseChatComposerControllerOptions = {
91
92
  onPaste?: ((event: ClipboardEvent<HTMLTextAreaElement>) => void) | undefined;
92
93
  messages?: Partial<ChatComposerMessages> | undefined;
93
94
  };
95
+ /**
96
+ * Autosize a composer textarea up to `maxPx` without the classic height→0
97
+ * measure collapse (that flash expands the timeline flex sibling and yanks
98
+ * tip-follow while a stream is pinned).
99
+ */
100
+ export declare function applyComposerTextareaHeight(textarea: HTMLTextAreaElement, maxPx?: number): void;
94
101
  /**
95
102
  * Headless interaction layer for a chat composer. It is the single owner of
96
103
  * delivery guards, keyboard routing, command interception, drag/drop, focus,
@@ -274,4 +281,3 @@ export type ComposerSendButtonProps = Omit<ButtonHTMLAttributes<HTMLButtonElemen
274
281
  export declare const SendButton: import("react").ForwardRefExoticComponent<ComposerSendButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
275
282
  export declare function Help(): import("react/jsx-runtime").JSX.Element;
276
283
  export declare function Status(): import("react/jsx-runtime").JSX.Element;
277
- export {};
@@ -7,7 +7,7 @@ export type CopyButtonProps = {
7
7
  className?: string | undefined;
8
8
  /**
9
9
  * `always` — visible control.
10
- * `group-hover` — parent must use `group/copy`; fades in on hover/focus.
10
+ * `group-hover` — parent must use `group/copy`; fades in on hover/focus-visible.
11
11
  */
12
12
  reveal?: "always" | "group-hover" | undefined;
13
13
  };
@@ -17,10 +17,12 @@ export type CopyButtonProps = {
17
17
  */
18
18
  export declare function CopyButton({ text, label, className, reveal, }: CopyButtonProps): import("react/jsx-runtime").JSX.Element;
19
19
  /** Hover-reveal chrome around a message / turn so {@link CopyButton} can fade in. */
20
- export declare function CopyHoverFrame({ children, className, copyText, label, align, }: {
20
+ export declare function CopyHoverFrame({ children, className, copyText, label, align, trailing, }: {
21
21
  children: ReactNode;
22
22
  className?: string | undefined;
23
23
  copyText: string;
24
24
  label: string;
25
25
  align?: "start" | "end" | undefined;
26
+ /** Optional footer meta (e.g. sent/finished clock) — immediately after the copy control. */
27
+ trailing?: ReactNode | undefined;
26
28
  }): import("react/jsx-runtime").JSX.Element;
@@ -56,6 +56,9 @@ export declare const TIP_FOLLOW_VELOCITY_ARM_DEBT_PX = 72;
56
56
  export declare const TIP_FOLLOW_VELOCITY_DECAY_MS: number;
57
57
  /** Reader-up pixels above clamp budget that count as leaving the tip. */
58
58
  export declare const TIP_FOLLOW_READER_UP_EPS_PX = 2;
59
+ /** @internal */ export declare function setScrollEndSupportForTests(value: boolean | null): void;
60
+ /** True when the engine exposes element `scrollend` (prefer over rAF leave). */
61
+ export declare function supportsScrollEndEvent(): boolean;
59
62
  /** @deprecated Shrink lock removed; kept so old imports do not break. */
60
63
  export declare const TIP_FOLLOW_SHRINK_LOCK_MS = 0;
61
64
  /** @deprecated Absorb thresholds removed — growth track is continuous. */
@@ -3,7 +3,8 @@
3
3
  *
4
4
  * `import * as Composer from "@opengeni/react/composer"`.
5
5
  */
6
- export { Actions, AttachButton, Attachments, CommandPalette, Confirmation, Controls, Footer, Frame, Help, Hint, Input, ModelPicker, OPEN_WORKSTREAM_CONTROL_EVENT, PauseButton, PausedState, RestoredResources, Root, SendButton, Status, Surface, defaultChatComposerMessages, useChatComposer, useChatComposerController, } from "./components/composer";
6
+ export { OPEN_WORKSTREAM_CONTROL_EVENT } from "./workstream-control-event";
7
+ export { Actions, AttachButton, Attachments, CommandPalette, Confirmation, Controls, Footer, Frame, Help, Hint, Input, ModelPicker, PauseButton, PausedState, RestoredResources, Root, SendButton, Status, Surface, defaultChatComposerMessages, useChatComposer, useChatComposerController, } from "./components/composer";
7
8
  export type { ChatComposerController, ChatComposerContextValue, ChatComposerMessages, ComposerActionsProps, ComposerAttachButtonProps, ComposerCommandPaletteProps, ComposerControlLinks, ComposerControlState, ComposerControlsProps, ComposerDelivery, ComposerDraftState, ComposerFooterProps, ComposerFrameProps, ComposerHintProps, ComposerInputProps, ComposerModelPickerProps, ComposerPauseButtonProps, ComposerRootProps, ComposerSendButtonProps, ComposerSubmitBlocker, ComposerSubmitMode, ComposerSurfaceProps, UseChatComposerControllerOptions, } from "./components/composer";
8
9
  export { ComposerTranscriptionControl } from "./components/composer-transcription-control";
9
10
  export type { ComposerTranscriptionControlProps, ComposerTranscriptionMessages, } from "./components/composer-transcription-control";
package/dist/composer.js CHANGED
@@ -24,12 +24,13 @@ import {
24
24
  useChatComposer,
25
25
  useChatComposerController,
26
26
  useVoiceInput
27
- } from "./chunk-MS3FBZ6A.js";
28
- import "./chunk-KZRUYCL4.js";
27
+ } from "./chunk-PVW56EVR.js";
28
+ import "./chunk-FT2TXNGZ.js";
29
29
  import "./chunk-7CJOAW3V.js";
30
30
  import "./chunk-U255M5EZ.js";
31
+ import "./chunk-ATSTR5P3.js";
31
32
  import "./chunk-TK7G6XLT.js";
32
- import "./chunk-4QOQ2DSR.js";
33
+ import "./chunk-LAKLF4PA.js";
33
34
  export {
34
35
  Actions,
35
36
  AttachButton,
package/dist/index.d.ts CHANGED
@@ -25,7 +25,7 @@ export type { QueueSurfaceProps } from "./components/queue-surface";
25
25
  export { SessionChrome, sessionChromeGoalPillState } from "./components/session-chrome";
26
26
  export type { SessionChromeAgentsSignal, SessionChromeProps, SessionChromeSignalId, SessionChromeSignalTone, } from "./components/session-chrome";
27
27
  export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./components/tooltip";
28
- export { OPEN_WORKSTREAM_CONTROL_EVENT } from "./components/chat-composer";
28
+ export { OPEN_WORKSTREAM_CONTROL_EVENT } from "./workstream-control-event";
29
29
  export { useGoal, isGoalEvent } from "./hooks/use-goal";
30
30
  export type { UseGoalOptions, UseGoalResult } from "./hooks/use-goal";
31
31
  export { useSessionControl } from "./hooks/use-session-control";
@@ -141,4 +141,4 @@ export type { CodexAccountsClientLike, UseCodexAccountsOptions, UseCodexAccounts
141
141
  export { gitFileDiffToPatch } from "./lib/git-patch";
142
142
  export { xtermThemeFromTokens } from "./lib/xterm-theme";
143
143
  export { cn } from "./lib/cn";
144
- export { CREDIT_EXHAUSTION_MESSAGE, formatBytes, formatRelativeTime, humanizeFailureReason, isCreditExhaustion, stringifyPayload, truncate, tryParseJson, } from "./lib/format";
144
+ export { CREDIT_EXHAUSTION_MESSAGE, formatBytes, formatClockTime, formatRelativeTime, humanizeFailureReason, isCreditExhaustion, stringifyPayload, truncate, tryParseJson, } from "./lib/format";
package/dist/index.js CHANGED
@@ -25,7 +25,7 @@ import {
25
25
  healthPulses,
26
26
  pointsFor,
27
27
  useMachines
28
- } from "./chunk-GZ4KR67U.js";
28
+ } from "./chunk-ALA3UGWB.js";
29
29
  import {
30
30
  SESSION_EVENT_BROWSER_MAX_BYTES,
31
31
  SESSION_EVENT_BROWSER_MAX_COUNT,
@@ -52,7 +52,7 @@ import {
52
52
  useSessionLineage,
53
53
  useSessionMcpApprovalPolicy,
54
54
  useTurnQueue
55
- } from "./chunk-A2WITZTI.js";
55
+ } from "./chunk-4NMH6UJ3.js";
56
56
  import {
57
57
  ActivityDisclosure,
58
58
  ActivityRail,
@@ -78,10 +78,6 @@ import {
78
78
  TermBlock,
79
79
  Thumbnail,
80
80
  TimelineRow,
81
- Tooltip,
82
- TooltipContent,
83
- TooltipProvider,
84
- TooltipTrigger,
85
81
  TurnSummary,
86
82
  answersFromDrafts,
87
83
  applyPatchOps,
@@ -108,10 +104,9 @@ import {
108
104
  unwrapMcpOutput,
109
105
  useLightbox,
110
106
  useLightboxOptional,
111
- usePortalTokenStyle,
112
107
  useThemeType,
113
108
  v4aToGitFileDiff
114
- } from "./chunk-L7R5RK6A.js";
109
+ } from "./chunk-QRYJCWGD.js";
115
110
  import {
116
111
  buildTimeline,
117
112
  creditExhaustedFromEvents,
@@ -119,7 +114,7 @@ import {
119
114
  groupTimeline,
120
115
  sessionStatusFromEvents,
121
116
  toolDisplayName
122
- } from "./chunk-TCCE5ZU5.js";
117
+ } from "./chunk-MEGI4FS6.js";
123
118
  import {
124
119
  Actions,
125
120
  AttachButton,
@@ -159,14 +154,14 @@ import {
159
154
  useSlashCommands,
160
155
  useTranscription,
161
156
  useVoiceInput
162
- } from "./chunk-MS3FBZ6A.js";
157
+ } from "./chunk-PVW56EVR.js";
163
158
  import {
164
159
  FILE_ONLY_MESSAGE_TEXT,
165
160
  composeSendInput,
166
161
  shouldSteerOnKey,
167
162
  shouldSubmitOnKey,
168
163
  useComposer
169
- } from "./chunk-KZRUYCL4.js";
164
+ } from "./chunk-FT2TXNGZ.js";
170
165
  import {
171
166
  useMutationRunner,
172
167
  useOpenGeni,
@@ -190,6 +185,13 @@ import {
190
185
  runnableLatencyModesForModel,
191
186
  sortPickerRows
192
187
  } from "./chunk-U255M5EZ.js";
188
+ import {
189
+ Tooltip,
190
+ TooltipContent,
191
+ TooltipProvider,
192
+ TooltipTrigger,
193
+ usePortalTokenStyle
194
+ } from "./chunk-ATSTR5P3.js";
193
195
  import {
194
196
  cn
195
197
  } from "./chunk-TK7G6XLT.js";
@@ -198,13 +200,14 @@ import {
198
200
  CREDIT_EXHAUSTION_MESSAGE,
199
201
  composerSubmissionErrorMessage,
200
202
  formatBytes,
203
+ formatClockTime,
201
204
  formatRelativeTime,
202
205
  humanizeFailureReason,
203
206
  isCreditExhaustion,
204
207
  stringifyPayload,
205
208
  truncate,
206
209
  tryParseJson
207
- } from "./chunk-4QOQ2DSR.js";
210
+ } from "./chunk-LAKLF4PA.js";
208
211
  import "./chunk-YDNWMKXO.js";
209
212
 
210
213
  // src/hooks/use-last-started-turn-policy.ts
@@ -259,77 +262,6 @@ function useLastStartedTurnPolicy(sessionId, options = {}) {
259
262
  };
260
263
  }
261
264
 
262
- // src/components/chat-composer.tsx
263
- import { jsx, jsxs } from "react/jsx-runtime";
264
- function ChatComposer({
265
- composer,
266
- effectiveControl,
267
- queuedAheadCount,
268
- canControlWorkspace,
269
- controlLinks,
270
- placeholder,
271
- disabled,
272
- autoFocus,
273
- hint,
274
- controlsStart,
275
- transcription,
276
- header,
277
- onPaste,
278
- attachments,
279
- models,
280
- selectedModel,
281
- onSelectModel,
282
- className,
283
- commands,
284
- commandContext,
285
- onClearView,
286
- messages
287
- }) {
288
- const controller = useChatComposerController({
289
- delivery: composer,
290
- draft: composer,
291
- control: composer,
292
- effectiveControl,
293
- queuedAheadCount,
294
- canControlWorkspace,
295
- controlLinks,
296
- disabled,
297
- attachments,
298
- commands,
299
- commandContext,
300
- onClearView,
301
- onPaste,
302
- messages
303
- });
304
- const hasControls = Boolean(attachments || models || controlsStart || transcription);
305
- return /* @__PURE__ */ jsxs(Root, { controller, className, children: [
306
- /* @__PURE__ */ jsxs(Frame, { children: [
307
- /* @__PURE__ */ jsx(CommandPalette2, {}),
308
- /* @__PURE__ */ jsxs(Surface, { children: [
309
- /* @__PURE__ */ jsx(PausedState, {}),
310
- /* @__PURE__ */ jsx(RestoredResources, {}),
311
- /* @__PURE__ */ jsx(Attachments, {}),
312
- header,
313
- /* @__PURE__ */ jsx(Input, { placeholder, autoFocus }),
314
- controller.confirmState ? /* @__PURE__ */ jsx(Confirmation, {}) : /* @__PURE__ */ jsxs(Footer, { children: [
315
- hasControls ? /* @__PURE__ */ jsxs(Controls, { children: [
316
- /* @__PURE__ */ jsx(AttachButton, {}),
317
- transcription ? /* @__PURE__ */ jsx(ComposerTranscriptionControl, { ...transcription }) : null,
318
- models ? /* @__PURE__ */ jsx(ModelPicker2, { models, value: selectedModel, onChange: onSelectModel }) : null,
319
- controlsStart
320
- ] }) : /* @__PURE__ */ jsx(Hint, { children: hint }),
321
- /* @__PURE__ */ jsxs(Actions, { children: [
322
- /* @__PURE__ */ jsx(PauseButton, {}),
323
- /* @__PURE__ */ jsx(SendButton, {})
324
- ] })
325
- ] })
326
- ] })
327
- ] }),
328
- /* @__PURE__ */ jsx(Help, {}),
329
- /* @__PURE__ */ jsx(Status, {})
330
- ] });
331
- }
332
-
333
265
  // src/hooks/use-scheduled-tasks.ts
334
266
  import { useCallback as useCallback2 } from "react";
335
267
  function useScheduledTasks(options = {}) {
@@ -3241,7 +3173,7 @@ function useMachineChip(input) {
3241
3173
  // src/components/approval-surface.tsx
3242
3174
  import { CheckIcon, ShieldCheckIcon, XIcon } from "lucide-react";
3243
3175
  import { useEffect as useEffect12, useId, useRef as useRef11, useState as useState10 } from "react";
3244
- import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
3176
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3245
3177
  var defaultApprovalSurfaceMessages = {
3246
3178
  title: "Approval required",
3247
3179
  description: "Review the requested action before the agent continues.",
@@ -3311,7 +3243,7 @@ function ApprovalSurface({
3311
3243
  }
3312
3244
  };
3313
3245
  const errorMessage = decisionError?.message ?? (error instanceof Error ? error.message : error);
3314
- return /* @__PURE__ */ jsxs2(
3246
+ return /* @__PURE__ */ jsxs(
3315
3247
  "section",
3316
3248
  {
3317
3249
  className: cn(
@@ -3320,29 +3252,29 @@ function ApprovalSurface({
3320
3252
  ),
3321
3253
  "aria-labelledby": titleId,
3322
3254
  children: [
3323
- /* @__PURE__ */ jsxs2("header", { className: "flex items-start gap-3", children: [
3324
- /* @__PURE__ */ jsx2("span", { className: "mt-0.5 inline-flex size-8 shrink-0 items-center justify-center rounded-og-md bg-og-status-waiting/12 text-og-status-waiting", children: /* @__PURE__ */ jsx2(ShieldCheckIcon, { "aria-hidden": "true", className: "size-4" }) }),
3325
- /* @__PURE__ */ jsxs2("div", { className: "min-w-0", children: [
3326
- /* @__PURE__ */ jsx2("h2", { id: titleId, className: "text-og-md font-semibold text-og-fg", children: messages.title }),
3327
- /* @__PURE__ */ jsx2("p", { className: "mt-0.5 text-og-sm text-og-fg-muted", children: messages.description })
3255
+ /* @__PURE__ */ jsxs("header", { className: "flex items-start gap-3", children: [
3256
+ /* @__PURE__ */ jsx("span", { className: "mt-0.5 inline-flex size-8 shrink-0 items-center justify-center rounded-og-md bg-og-status-waiting/12 text-og-status-waiting", children: /* @__PURE__ */ jsx(ShieldCheckIcon, { "aria-hidden": "true", className: "size-4" }) }),
3257
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
3258
+ /* @__PURE__ */ jsx("h2", { id: titleId, className: "text-og-md font-semibold text-og-fg", children: messages.title }),
3259
+ /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-og-sm text-og-fg-muted", children: messages.description })
3328
3260
  ] })
3329
3261
  ] }),
3330
- /* @__PURE__ */ jsx2("div", { className: "flex flex-col gap-2", children: approvals.map((approval) => {
3262
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: approvals.map((approval) => {
3331
3263
  const approvalKey = approvalOwnershipKey(approval);
3332
3264
  const active = pending?.approvalKey === approvalKey ? pending.decision : null;
3333
3265
  const argumentsPreview = approvalArgumentsPreview(approval.arguments);
3334
- return /* @__PURE__ */ jsxs2(
3266
+ return /* @__PURE__ */ jsxs(
3335
3267
  "article",
3336
3268
  {
3337
3269
  "data-approval-id": approval.id,
3338
3270
  className: "rounded-og-md border border-og-border bg-og-surface-1 p-3",
3339
3271
  children: [
3340
- renderApproval ? renderApproval(approval) : /* @__PURE__ */ jsxs2(Fragment, { children: [
3341
- /* @__PURE__ */ jsx2("p", { className: "text-og-sm font-medium text-og-fg", children: messages.formatToolName(approval.name) }),
3342
- argumentsPreview !== null ? /* @__PURE__ */ jsx2("pre", { className: "mt-2 max-h-48 overflow-auto whitespace-pre-wrap break-words rounded-og-sm bg-og-surface-2 p-2 font-mono text-og-xs text-og-fg-muted", children: argumentsPreview }) : null
3272
+ renderApproval ? renderApproval(approval) : /* @__PURE__ */ jsxs(Fragment, { children: [
3273
+ /* @__PURE__ */ jsx("p", { className: "text-og-sm font-medium text-og-fg", children: messages.formatToolName(approval.name) }),
3274
+ argumentsPreview !== null ? /* @__PURE__ */ jsx("pre", { className: "mt-2 max-h-48 overflow-auto whitespace-pre-wrap break-words rounded-og-sm bg-og-surface-2 p-2 font-mono text-og-xs text-og-fg-muted", children: argumentsPreview }) : null
3343
3275
  ] }),
3344
- /* @__PURE__ */ jsxs2("div", { className: "mt-3 flex flex-wrap justify-end gap-2", children: [
3345
- /* @__PURE__ */ jsxs2(
3276
+ /* @__PURE__ */ jsxs("div", { className: "mt-3 flex flex-wrap justify-end gap-2", children: [
3277
+ /* @__PURE__ */ jsxs(
3346
3278
  "button",
3347
3279
  {
3348
3280
  type: "button",
@@ -3350,12 +3282,12 @@ function ApprovalSurface({
3350
3282
  onClick: () => void decide(approval, "reject"),
3351
3283
  className: "inline-flex min-h-9 items-center gap-1.5 rounded-og-md border border-og-border px-3 py-1.5 text-og-sm font-medium text-og-fg-muted transition-colors hover:bg-og-surface-2 hover:text-og-fg disabled:opacity-50",
3352
3284
  children: [
3353
- /* @__PURE__ */ jsx2(XIcon, { "aria-hidden": "true", className: "size-3.5" }),
3285
+ /* @__PURE__ */ jsx(XIcon, { "aria-hidden": "true", className: "size-3.5" }),
3354
3286
  active === "reject" ? messages.rejecting : messages.reject
3355
3287
  ]
3356
3288
  }
3357
3289
  ),
3358
- /* @__PURE__ */ jsxs2(
3290
+ /* @__PURE__ */ jsxs(
3359
3291
  "button",
3360
3292
  {
3361
3293
  type: "button",
@@ -3363,7 +3295,7 @@ function ApprovalSurface({
3363
3295
  onClick: () => void decide(approval, "approve"),
3364
3296
  className: "inline-flex min-h-9 items-center gap-1.5 rounded-og-md bg-og-accent px-3 py-1.5 text-og-sm font-medium text-og-accent-fg transition-colors hover:bg-og-accent-strong disabled:opacity-50",
3365
3297
  children: [
3366
- /* @__PURE__ */ jsx2(CheckIcon, { "aria-hidden": "true", className: "size-3.5" }),
3298
+ /* @__PURE__ */ jsx(CheckIcon, { "aria-hidden": "true", className: "size-3.5" }),
3367
3299
  active === "approve" ? messages.approving : messages.approve
3368
3300
  ]
3369
3301
  }
@@ -3374,12 +3306,83 @@ function ApprovalSurface({
3374
3306
  approval.id
3375
3307
  );
3376
3308
  }) }),
3377
- errorMessage ? /* @__PURE__ */ jsx2("p", { role: "alert", className: "text-og-sm text-og-status-failed", children: errorMessage }) : null
3309
+ errorMessage ? /* @__PURE__ */ jsx("p", { role: "alert", className: "text-og-sm text-og-status-failed", children: errorMessage }) : null
3378
3310
  ]
3379
3311
  }
3380
3312
  );
3381
3313
  }
3382
3314
 
3315
+ // src/components/chat-composer.tsx
3316
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
3317
+ function ChatComposer({
3318
+ composer,
3319
+ effectiveControl,
3320
+ queuedAheadCount,
3321
+ canControlWorkspace,
3322
+ controlLinks,
3323
+ placeholder,
3324
+ disabled,
3325
+ autoFocus,
3326
+ hint,
3327
+ controlsStart,
3328
+ transcription,
3329
+ header,
3330
+ onPaste,
3331
+ attachments,
3332
+ models,
3333
+ selectedModel,
3334
+ onSelectModel,
3335
+ className,
3336
+ commands,
3337
+ commandContext,
3338
+ onClearView,
3339
+ messages
3340
+ }) {
3341
+ const controller = useChatComposerController({
3342
+ delivery: composer,
3343
+ draft: composer,
3344
+ control: composer,
3345
+ effectiveControl,
3346
+ queuedAheadCount,
3347
+ canControlWorkspace,
3348
+ controlLinks,
3349
+ disabled,
3350
+ attachments,
3351
+ commands,
3352
+ commandContext,
3353
+ onClearView,
3354
+ onPaste,
3355
+ messages
3356
+ });
3357
+ const hasControls = Boolean(attachments || models || controlsStart || transcription);
3358
+ return /* @__PURE__ */ jsxs2(Root, { controller, className, children: [
3359
+ /* @__PURE__ */ jsxs2(Frame, { children: [
3360
+ /* @__PURE__ */ jsx2(CommandPalette2, {}),
3361
+ /* @__PURE__ */ jsxs2(Surface, { children: [
3362
+ /* @__PURE__ */ jsx2(PausedState, {}),
3363
+ /* @__PURE__ */ jsx2(RestoredResources, {}),
3364
+ /* @__PURE__ */ jsx2(Attachments, {}),
3365
+ header,
3366
+ /* @__PURE__ */ jsx2(Input, { placeholder, autoFocus }),
3367
+ controller.confirmState ? /* @__PURE__ */ jsx2(Confirmation, {}) : /* @__PURE__ */ jsxs2(Footer, { children: [
3368
+ hasControls ? /* @__PURE__ */ jsxs2(Controls, { children: [
3369
+ /* @__PURE__ */ jsx2(AttachButton, {}),
3370
+ transcription ? /* @__PURE__ */ jsx2(ComposerTranscriptionControl, { ...transcription }) : null,
3371
+ models ? /* @__PURE__ */ jsx2(ModelPicker2, { models, value: selectedModel, onChange: onSelectModel }) : null,
3372
+ controlsStart
3373
+ ] }) : /* @__PURE__ */ jsx2(Hint, { children: hint }),
3374
+ /* @__PURE__ */ jsxs2(Actions, { children: [
3375
+ /* @__PURE__ */ jsx2(PauseButton, {}),
3376
+ /* @__PURE__ */ jsx2(SendButton, {})
3377
+ ] })
3378
+ ] })
3379
+ ] })
3380
+ ] }),
3381
+ /* @__PURE__ */ jsx2(Help, {}),
3382
+ /* @__PURE__ */ jsx2(Status, {})
3383
+ ] });
3384
+ }
3385
+
3383
3386
  // src/components/fleet-tile.tsx
3384
3387
  import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
3385
3388
  function sessionDisplayTitle(session) {
@@ -8488,6 +8491,7 @@ export {
8488
8491
  firstMissingRequiredArg,
8489
8492
  formatAsOf,
8490
8493
  formatBytes,
8494
+ formatClockTime,
8491
8495
  formatRelativeTime,
8492
8496
  gitFileDiffToPatch,
8493
8497
  groupPickerRowsByBillingClass,