@mcp-b/react-components 0.20.4 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/dist/{AgentActivity-D2SHSGFX.d.ts → AgentActivity-D3OvrC02.d.ts} +14 -1
  2. package/dist/{AgentChat-C-ZyXbJz.d.ts → AgentChat-Dvkn8lce.d.ts} +23 -0
  3. package/dist/AgentChatStartScreen-CvXJBr4y.d.ts +57 -0
  4. package/dist/{ModelSelector-pecWyOFI.js → ModelSelector-CEd8M9eK.js} +14 -7
  5. package/dist/{ThinkChatActivity-CdbL0aoA.d.ts → ThinkChatActivity-FY1VWXgh.d.ts} +8 -7
  6. package/dist/{ThinkChatActivitySummary-D1xOrNrq.d.ts → ThinkChatActivitySummary-kr5fE0wg.d.ts} +14 -5
  7. package/dist/{ToggleGroup-DNd6cDJZ.d.ts → ToggleGroup-BW1jrhAF.d.ts} +10 -0
  8. package/dist/components/Activity.d.ts +33 -17
  9. package/dist/components/Activity.js +39 -27
  10. package/dist/components/AgentActivity.d.ts +1 -1
  11. package/dist/components/AgentActivityPreview.d.ts +1 -1
  12. package/dist/components/AgentActivityPreview.js +2 -2
  13. package/dist/components/AgentChat.d.ts +1 -1
  14. package/dist/components/AgentChat.js +142 -129
  15. package/dist/components/AgentChatStartScreen.d.ts +2 -0
  16. package/dist/components/AgentChatStartScreen.js +82 -0
  17. package/dist/components/Approval.js +2 -4
  18. package/dist/components/BrowserLiveView.js +5 -7
  19. package/dist/components/BrowserReplay.js +5 -4
  20. package/dist/components/BrowserRunPanel.js +1 -1
  21. package/dist/components/ChatGptSignInScreen.js +1 -1
  22. package/dist/components/Conversation.d.ts +1 -22
  23. package/dist/components/Conversation.js +2 -29
  24. package/dist/components/EmptyState.d.ts +46 -0
  25. package/dist/components/EmptyState.js +50 -0
  26. package/dist/components/Kbd.d.ts +32 -0
  27. package/dist/components/Kbd.js +34 -0
  28. package/dist/components/MessageScroller.js +1 -0
  29. package/dist/components/ModelSelector.d.ts +10 -4
  30. package/dist/components/ModelSelector.js +2 -2
  31. package/dist/components/PricingBillingToggle.js +1 -0
  32. package/dist/components/PromptInput.js +3 -2
  33. package/dist/components/Reasoning.js +1 -1
  34. package/dist/components/StatusPill.d.ts +43 -0
  35. package/dist/components/StatusPill.js +35 -0
  36. package/dist/components/Stepper.js +1 -5
  37. package/dist/components/TestResults.js +15 -15
  38. package/dist/components/ThinkChat.d.ts +9 -3
  39. package/dist/components/ThinkChatActivity.d.ts +2 -2
  40. package/dist/components/ThinkChatActivity.js +27 -15
  41. package/dist/components/ThinkChatActivitySummary.d.ts +2 -2
  42. package/dist/components/ThinkChatActivitySummary.js +69 -66
  43. package/dist/components/ThinkExecutionDetail.js +4 -4
  44. package/dist/components/ThinkExecutionRun.js +2 -2
  45. package/dist/components/ThinkExecutionWorkbench.js +5 -4
  46. package/dist/components/ThinkFullAppViewSwitch.d.ts +1 -1
  47. package/dist/components/ThinkRoutine.js +2 -10
  48. package/dist/components/ThinkRoutineBrowser.js +1 -0
  49. package/dist/components/ThinkRoutineRuns.js +3 -2
  50. package/dist/components/ThinkThreadPicker.js +4 -2
  51. package/dist/components/ToggleGroup.d.ts +1 -1
  52. package/dist/components/ToggleGroup.js +54 -7
  53. package/dist/components/ToolInvocation.js +1 -1
  54. package/dist/styles/accordion.css +2 -1
  55. package/dist/styles/activity-header.css +45 -25
  56. package/dist/styles/activity.css +26 -4
  57. package/dist/styles/agent-activity-preview-overlay.css +51 -12
  58. package/dist/styles/agent-activity-preview.css +34 -33
  59. package/dist/styles/agent-attention.css +9 -16
  60. package/dist/styles/agent-chat.css +199 -0
  61. package/dist/styles/agent-connection.css +10 -10
  62. package/dist/styles/alert-dialog.css +5 -2
  63. package/dist/styles/app-top-bar.css +4 -4
  64. package/dist/styles/approval.css +1 -7
  65. package/dist/styles/artifact.css +5 -5
  66. package/dist/styles/attachment-preview.css +1 -1
  67. package/dist/styles/badge.css +1 -1
  68. package/dist/styles/base-ui-motion.css +1 -1
  69. package/dist/styles/base.css +110 -3
  70. package/dist/styles/browser-control-overlay.css +16 -6
  71. package/dist/styles/browser-live-view.css +5 -38
  72. package/dist/styles/browser-replay.css +4 -8
  73. package/dist/styles/browser-run-panel.css +5 -19
  74. package/dist/styles/button.css +4 -2
  75. package/dist/styles/card.css +4 -4
  76. package/dist/styles/chain-of-thought.css +1 -2
  77. package/dist/styles/chatgpt-sign-in-screen.css +9 -7
  78. package/dist/styles/checkbox-group.css +4 -4
  79. package/dist/styles/code-block.css +9 -9
  80. package/dist/styles/commit.css +1 -1
  81. package/dist/styles/context-menu.css +1 -1
  82. package/dist/styles/conversation.css +7 -42
  83. package/dist/styles/description-list.css +2 -2
  84. package/dist/styles/dialog.css +17 -2
  85. package/dist/styles/empty-state.css +48 -0
  86. package/dist/styles/environment-variables.css +8 -8
  87. package/dist/styles/field.css +2 -2
  88. package/dist/styles/fieldset.css +1 -1
  89. package/dist/styles/file-tree.css +1 -1
  90. package/dist/styles/github-motion-mark.css +1 -1
  91. package/dist/styles/index.css +3 -0
  92. package/dist/styles/inline-citation.css +1 -1
  93. package/dist/styles/kbd.css +40 -0
  94. package/dist/styles/label.css +1 -1
  95. package/dist/styles/mcp-server-picker.css +1 -1
  96. package/dist/styles/media-preview-card.css +5 -3
  97. package/dist/styles/menu.css +1 -1
  98. package/dist/styles/message-scroller.css +7 -25
  99. package/dist/styles/message.css +5 -7
  100. package/dist/styles/model-selector.css +5 -8
  101. package/dist/styles/plan.css +1 -1
  102. package/dist/styles/popover.css +1 -1
  103. package/dist/styles/preview-card.css +1 -1
  104. package/dist/styles/pricing-page.css +37 -35
  105. package/dist/styles/prompt-input.css +19 -41
  106. package/dist/styles/queue.css +3 -3
  107. package/dist/styles/recipes.css +92 -9
  108. package/dist/styles/resizable-side-panel.css +1 -1
  109. package/dist/styles/responsive-sidebar-shell.css +5 -6
  110. package/dist/styles/scrollbars.css +32 -3
  111. package/dist/styles/sources.css +2 -2
  112. package/dist/styles/status-pill.css +39 -0
  113. package/dist/styles/stepper.css +2 -2
  114. package/dist/styles/streamdown.css +39 -35
  115. package/dist/styles/subagent-run.css +3 -3
  116. package/dist/styles/switch.css +1 -3
  117. package/dist/styles/tabs.css +1 -1
  118. package/dist/styles/task.css +2 -2
  119. package/dist/styles/terminal.css +6 -6
  120. package/dist/styles/test-results.css +2 -3
  121. package/dist/styles/textarea.css +1 -1
  122. package/dist/styles/theme-mode-control.css +3 -4
  123. package/dist/styles/think-execution-status.css +4 -23
  124. package/dist/styles/think-execution-workbench.css +3 -4
  125. package/dist/styles/think-full-app.css +3 -3
  126. package/dist/styles/think-routine-library.css +22 -24
  127. package/dist/styles/think-thread-picker.css +20 -47
  128. package/dist/styles/toast.css +2 -2
  129. package/dist/styles/toggle-group.css +76 -3
  130. package/dist/styles/tooltip.css +1 -2
  131. package/dist/styles/utilities.css +73 -0
  132. package/dist/styles/web-preview.css +4 -4
  133. package/dist/styles/workspace-explorer.css +6 -8
  134. package/package.json +2 -2
@@ -3,8 +3,9 @@ import { H as QueueIcon, I as MoveToFrontIcon, U as RefreshIcon, V as PlusIcon,
3
3
  import { n as MessageAction, r as MessageActions, t as Message } from "../Message-DzuteocT.js";
4
4
  import { AgentMessageParts } from "./AgentMessageParts.js";
5
5
  import { Context, ContextContent, ContextContentBody, ContextContentHeader, ContextTrigger, getContextUsage, getContextUsedTokens } from "./Context.js";
6
+ import { EmptyState } from "./EmptyState.js";
6
7
  import { MessageScroller, MessageScrollerButton, MessageScrollerContent, MessageScrollerItem, MessageScrollerProvider, MessageScrollerViewport } from "./MessageScroller.js";
7
- import { ConversationEmptyState } from "./Conversation.js";
8
+ import { AgentChatStartScreen } from "./AgentChatStartScreen.js";
8
9
  import { AgentChatMessageEditor } from "./AgentChatMessageEditor.js";
9
10
  import { Marker, MarkerContent } from "./Marker.js";
10
11
  import { Menu } from "./Menu.js";
@@ -108,7 +109,7 @@ function getEditableUserText(message) {
108
109
  * transport. Product code that talks to a Cloudflare Think agent should render
109
110
  * `ThinkChat`; use this directly only for plain AI SDK or read-only messages.
110
111
  */
111
- function AgentChat({ className, messages, status = "ready", onSubmit, showComposer = onSubmit !== void 0, onStop, placeholder = "Ask anything...", disabled, emptyState, composerHeader, composerTools, slashCommands, mentionCommands, contextSelector, composerEndTools, voiceInput, beforeVoiceStart, composerAddMenuItems, notice, onRegenerate, onEditAndResend, onApprovalResponse, thinkStub, approvalsEnabled = true, permissionModeControl, onExecutionSettled, pendingApprovals: durableApprovals = EMPTY_PENDING_APPROVALS, contextWindow, renderPart, renderMessageAfter, ref }) {
112
+ function AgentChat({ className, messages, status = "ready", onSubmit, showComposer = onSubmit !== void 0, onStop, placeholder = "Ask anything...", disabled, emptyState, startScreen, composerHeader, composerTools, slashCommands, mentionCommands, contextSelector, composerEndTools, voiceInput, beforeVoiceStart, composerAddMenuItems, notice, onRegenerate, onEditAndResend, onApprovalResponse, thinkStub, approvalsEnabled = true, permissionModeControl, onExecutionSettled, pendingApprovals: durableApprovals = EMPTY_PENDING_APPROVALS, contextWindow, renderPart, renderMessageAfter, showAssistantActions, isMessageScrollAnchor, ref }) {
112
113
  const [copyAnnouncement, setCopyAnnouncement] = React.useState("");
113
114
  const [composerDraft, setComposerDraft] = React.useState("");
114
115
  const [composerReferences, setComposerReferences] = React.useState([]);
@@ -286,6 +287,131 @@ function AgentChat({ className, messages, status = "ready", onSubmit, showCompos
286
287
  editButtonRef.current?.focus();
287
288
  restoreEditFocus.current = false;
288
289
  }, [editingMessageId]);
290
+ const composer = showComposer ? /* @__PURE__ */ jsxs("div", {
291
+ ref: observeAgentChatComposer,
292
+ className: "agent-chat__composer",
293
+ children: [
294
+ /* @__PURE__ */ jsx("div", {
295
+ className: "agent-chat__notice",
296
+ role: "status",
297
+ "aria-atomic": "true",
298
+ children: notice
299
+ }),
300
+ pendingPrompts.length ? /* @__PURE__ */ jsx("section", {
301
+ className: "agent-chat__queued",
302
+ "aria-label": "Queued messages",
303
+ children: /* @__PURE__ */ jsx("ul", {
304
+ className: "agent-chat__queued-list",
305
+ children: pendingPrompts.map((pending) => {
306
+ const messageText = pending.message.text || "Queued message";
307
+ return /* @__PURE__ */ jsxs("li", {
308
+ className: "agent-chat__queued-message",
309
+ children: [
310
+ /* @__PURE__ */ jsx("span", {
311
+ className: "agent-chat__queued-indicator",
312
+ "aria-hidden": "true",
313
+ children: /* @__PURE__ */ jsx(QueueIcon, {})
314
+ }),
315
+ /* @__PURE__ */ jsx("span", {
316
+ className: "agent-chat__queued-text sigvelo-truncate sigvelo-truncate-grow",
317
+ children: messageText
318
+ }),
319
+ /* @__PURE__ */ jsxs("button", {
320
+ type: "button",
321
+ className: "agent-chat__queued-action",
322
+ "aria-label": `Move queued message to front: ${messageText}`,
323
+ onClick: () => setPendingPrompts((current) => [pending, ...current.filter((item) => item !== pending)]),
324
+ children: [/* @__PURE__ */ jsx(MoveToFrontIcon, {}), "Move to front"]
325
+ }),
326
+ /* @__PURE__ */ jsx("button", {
327
+ type: "button",
328
+ className: "agent-chat__queued-action agent-chat__queued-remove",
329
+ "aria-label": `Remove queued message: ${messageText}`,
330
+ onClick: () => setPendingPrompts((current) => current.filter((item) => item !== pending)),
331
+ children: /* @__PURE__ */ jsx(TrashIcon, {})
332
+ })
333
+ ]
334
+ }, pending.id);
335
+ })
336
+ })
337
+ }) : null,
338
+ /* @__PURE__ */ jsx(PromptInput, {
339
+ multiple: true,
340
+ onSubmit: handleSubmit,
341
+ children: pendingApproval ? /* @__PURE__ */ jsx(PromptInputApproval, {
342
+ part: "part" in pendingApproval ? pendingApproval.part : void 0,
343
+ approval: "approval" in pendingApproval ? pendingApproval.approval : void 0,
344
+ count: pendingApprovalItems.length,
345
+ onRespond: onApprovalResponse,
346
+ thinkStub,
347
+ onExecutionSettled,
348
+ onSkip: () => {
349
+ const id = "part" in pendingApproval ? getApprovalStateKey(pendingApproval.part) : pendingApproval.approval.executionId;
350
+ if (id) updateApprovalSession((current) => ({
351
+ ...current,
352
+ skippedApprovalIds: [...current.skippedApprovalIds, id]
353
+ }));
354
+ }
355
+ }) : /* @__PURE__ */ jsxs(Fragment, { children: [
356
+ composerHeader ? /* @__PURE__ */ jsx(PromptInputHeader, { children: composerHeader }) : null,
357
+ /* @__PURE__ */ jsx(PromptInputAttachments, {}),
358
+ /* @__PURE__ */ jsxs(PromptInputBody, { children: [/* @__PURE__ */ jsx(PromptInputReferences, {
359
+ references: composerReferences,
360
+ onRemove: removeComposerReference
361
+ }), slashCommands || mentionCommands ? /* @__PURE__ */ jsx(PromptInputCommandComposer, {
362
+ "aria-label": "Message",
363
+ placeholder: composerReferences.length ? "" : placeholder,
364
+ disabled,
365
+ commands: slashCommands?.items ?? [],
366
+ mentionCommands: mentionCommands?.items,
367
+ value: composerDraft,
368
+ onValueChange: setComposerDraft,
369
+ onCommandSelect: selectComposerCommand
370
+ }) : /* @__PURE__ */ jsx(PromptInputTextarea, {
371
+ "aria-label": "Message",
372
+ placeholder,
373
+ disabled,
374
+ value: composerDraft,
375
+ onChange: (event) => setComposerDraft(event.currentTarget.value)
376
+ })] }),
377
+ /* @__PURE__ */ jsxs(PromptInputFooter, { children: [/* @__PURE__ */ jsxs(PromptInputTools, { children: [
378
+ /* @__PURE__ */ jsx(AgentChatAddMenu, { children: composerAddMenuItems }),
379
+ contextSelector ? /* @__PURE__ */ jsx(PromptInputContextSelector, { ...contextSelector }) : null,
380
+ approvalsWired ? /* @__PURE__ */ jsx(PromptInputPermissionSelector, {
381
+ value: permissionMode,
382
+ onValueChange: setPermissionMode
383
+ }) : null,
384
+ composerTools
385
+ ] }), /* @__PURE__ */ jsxs("div", {
386
+ className: "prompt-input__footer-end",
387
+ children: [
388
+ composerEndTools,
389
+ voiceInput ? /* @__PURE__ */ jsx(PromptInputDictation, {
390
+ voice: voiceInput,
391
+ beforeStart: beforeVoiceStart,
392
+ disabled
393
+ }) : null,
394
+ contextWindow ? /* @__PURE__ */ jsxs(Context, {
395
+ usedTokens: getContextUsedTokens(contextUsage),
396
+ maxTokens: contextWindow.maxTokens,
397
+ usage: contextUsage,
398
+ modelId: contextWindow.modelId,
399
+ children: [/* @__PURE__ */ jsx(ContextTrigger, {}), /* @__PURE__ */ jsxs(ContextContent, { children: [/* @__PURE__ */ jsx(ContextContentHeader, {}), /* @__PURE__ */ jsx(ContextContentBody, {})] })]
400
+ }) : null,
401
+ /* @__PURE__ */ jsx(AgentChatSubmitAction, {
402
+ status,
403
+ onStop,
404
+ disabled,
405
+ hasDraft: Boolean(composerDraft.trim() || composerReferences.length)
406
+ })
407
+ ]
408
+ })] })
409
+ ] })
410
+ })
411
+ ]
412
+ }) : null;
413
+ const showsStartScreen = messages.length === 0 && showComposer && startScreen !== false && (startScreen !== void 0 || emptyState === void 0);
414
+ const startScreenProps = startScreen && typeof startScreen === "object" ? startScreen : void 0;
289
415
  return /* @__PURE__ */ jsxs(TransitionSurface, {
290
416
  ref,
291
417
  variant: "fade",
@@ -298,7 +424,10 @@ function AgentChat({ className, messages, status = "ready", onSubmit, showCompos
298
424
  "aria-atomic": "true",
299
425
  children: copyAnnouncement
300
426
  }),
301
- /* @__PURE__ */ jsx(MessageScrollerProvider, {
427
+ showsStartScreen ? /* @__PURE__ */ jsx(AgentChatStartScreen, {
428
+ ...startScreenProps,
429
+ composer
430
+ }) : /* @__PURE__ */ jsx(MessageScrollerProvider, {
302
431
  autoScroll: true,
303
432
  defaultScrollPosition: "last-anchor",
304
433
  children: /* @__PURE__ */ jsxs(MessageScroller, {
@@ -308,13 +437,16 @@ function AgentChat({ className, messages, status = "ready", onSubmit, showCompos
308
437
  className: "agent-chat__transcript-content",
309
438
  children: [messages.length === 0 ? /* @__PURE__ */ jsx(MessageScrollerItem, {
310
439
  className: "conversation__empty-row",
311
- children: emptyState ?? /* @__PURE__ */ jsx(ConversationEmptyState, {
440
+ children: emptyState ?? /* @__PURE__ */ jsx(EmptyState, {
312
441
  title: "Start a conversation",
313
442
  description: "Ask the agent to inspect, plan, or build."
314
443
  })
315
444
  }) : null, messages.map((message, messageIndex) => /* @__PURE__ */ jsx(MessageScrollerItem, {
316
445
  messageId: message.id,
317
- scrollAnchor: message.role === "user",
446
+ scrollAnchor: isMessageScrollAnchor?.({
447
+ message,
448
+ messageIndex
449
+ }) ?? message.role === "user",
318
450
  children: isCompactionMessage(message) ? /* @__PURE__ */ jsx(Marker, {
319
451
  variant: "separator",
320
452
  children: /* @__PURE__ */ jsx(MarkerContent, { children: getMessageText(message) || "Conversation compacted" })
@@ -355,7 +487,10 @@ function AgentChat({ className, messages, status = "ready", onSubmit, showCompos
355
487
  children: /* @__PURE__ */ jsx(PencilIcon, {})
356
488
  })
357
489
  }) : null,
358
- message.role === "assistant" ? /* @__PURE__ */ jsx(AgentChatAssistantActions, {
490
+ message.role === "assistant" && (showAssistantActions?.({
491
+ message,
492
+ messageIndex
493
+ }) ?? true) ? /* @__PURE__ */ jsx(AgentChatAssistantActions, {
359
494
  message,
360
495
  responseNumber: assistantResponseNumbers[messageIndex],
361
496
  showCopy: messageIndex !== newestAssistantIndex || status !== "streaming" && status !== "submitted",
@@ -373,129 +508,7 @@ function AgentChat({ className, messages, status = "ready", onSubmit, showCompos
373
508
  })]
374
509
  })
375
510
  }),
376
- showComposer ? /* @__PURE__ */ jsxs("div", {
377
- ref: observeAgentChatComposer,
378
- className: "agent-chat__composer",
379
- children: [
380
- /* @__PURE__ */ jsx("div", {
381
- className: "agent-chat__notice",
382
- role: "status",
383
- "aria-atomic": "true",
384
- children: notice
385
- }),
386
- pendingPrompts.length ? /* @__PURE__ */ jsx("section", {
387
- className: "agent-chat__queued",
388
- "aria-label": "Queued messages",
389
- children: /* @__PURE__ */ jsx("ul", {
390
- className: "agent-chat__queued-list",
391
- children: pendingPrompts.map((pending) => {
392
- const messageText = pending.message.text || "Queued message";
393
- return /* @__PURE__ */ jsxs("li", {
394
- className: "agent-chat__queued-message",
395
- children: [
396
- /* @__PURE__ */ jsx("span", {
397
- className: "agent-chat__queued-indicator",
398
- "aria-hidden": "true",
399
- children: /* @__PURE__ */ jsx(QueueIcon, {})
400
- }),
401
- /* @__PURE__ */ jsx("span", {
402
- className: "agent-chat__queued-text sigvelo-truncate sigvelo-truncate-grow",
403
- children: messageText
404
- }),
405
- /* @__PURE__ */ jsxs("button", {
406
- type: "button",
407
- className: "agent-chat__queued-action",
408
- "aria-label": `Move queued message to front: ${messageText}`,
409
- onClick: () => setPendingPrompts((current) => [pending, ...current.filter((item) => item !== pending)]),
410
- children: [/* @__PURE__ */ jsx(MoveToFrontIcon, {}), "Move to front"]
411
- }),
412
- /* @__PURE__ */ jsx("button", {
413
- type: "button",
414
- className: "agent-chat__queued-action agent-chat__queued-remove",
415
- "aria-label": `Remove queued message: ${messageText}`,
416
- onClick: () => setPendingPrompts((current) => current.filter((item) => item !== pending)),
417
- children: /* @__PURE__ */ jsx(TrashIcon, {})
418
- })
419
- ]
420
- }, pending.id);
421
- })
422
- })
423
- }) : null,
424
- /* @__PURE__ */ jsx(PromptInput, {
425
- multiple: true,
426
- onSubmit: handleSubmit,
427
- children: pendingApproval ? /* @__PURE__ */ jsx(PromptInputApproval, {
428
- part: "part" in pendingApproval ? pendingApproval.part : void 0,
429
- approval: "approval" in pendingApproval ? pendingApproval.approval : void 0,
430
- count: pendingApprovalItems.length,
431
- onRespond: onApprovalResponse,
432
- thinkStub,
433
- onExecutionSettled,
434
- onSkip: () => {
435
- const id = "part" in pendingApproval ? getApprovalStateKey(pendingApproval.part) : pendingApproval.approval.executionId;
436
- if (id) updateApprovalSession((current) => ({
437
- ...current,
438
- skippedApprovalIds: [...current.skippedApprovalIds, id]
439
- }));
440
- }
441
- }) : /* @__PURE__ */ jsxs(Fragment, { children: [
442
- composerHeader ? /* @__PURE__ */ jsx(PromptInputHeader, { children: composerHeader }) : null,
443
- /* @__PURE__ */ jsx(PromptInputAttachments, {}),
444
- /* @__PURE__ */ jsxs(PromptInputBody, { children: [/* @__PURE__ */ jsx(PromptInputReferences, {
445
- references: composerReferences,
446
- onRemove: removeComposerReference
447
- }), slashCommands || mentionCommands ? /* @__PURE__ */ jsx(PromptInputCommandComposer, {
448
- "aria-label": "Message",
449
- placeholder: composerReferences.length ? "" : placeholder,
450
- disabled,
451
- commands: slashCommands?.items ?? [],
452
- mentionCommands: mentionCommands?.items,
453
- value: composerDraft,
454
- onValueChange: setComposerDraft,
455
- onCommandSelect: selectComposerCommand
456
- }) : /* @__PURE__ */ jsx(PromptInputTextarea, {
457
- "aria-label": "Message",
458
- placeholder,
459
- disabled,
460
- value: composerDraft,
461
- onChange: (event) => setComposerDraft(event.currentTarget.value)
462
- })] }),
463
- /* @__PURE__ */ jsxs(PromptInputFooter, { children: [/* @__PURE__ */ jsxs(PromptInputTools, { children: [
464
- /* @__PURE__ */ jsx(AgentChatAddMenu, { children: composerAddMenuItems }),
465
- contextSelector ? /* @__PURE__ */ jsx(PromptInputContextSelector, { ...contextSelector }) : null,
466
- approvalsWired ? /* @__PURE__ */ jsx(PromptInputPermissionSelector, {
467
- value: permissionMode,
468
- onValueChange: setPermissionMode
469
- }) : null,
470
- composerTools
471
- ] }), /* @__PURE__ */ jsxs("div", {
472
- className: "prompt-input__footer-end",
473
- children: [
474
- composerEndTools,
475
- voiceInput ? /* @__PURE__ */ jsx(PromptInputDictation, {
476
- voice: voiceInput,
477
- beforeStart: beforeVoiceStart,
478
- disabled
479
- }) : null,
480
- contextWindow ? /* @__PURE__ */ jsxs(Context, {
481
- usedTokens: getContextUsedTokens(contextUsage),
482
- maxTokens: contextWindow.maxTokens,
483
- usage: contextUsage,
484
- modelId: contextWindow.modelId,
485
- children: [/* @__PURE__ */ jsx(ContextTrigger, {}), /* @__PURE__ */ jsxs(ContextContent, { children: [/* @__PURE__ */ jsx(ContextContentHeader, {}), /* @__PURE__ */ jsx(ContextContentBody, {})] })]
486
- }) : null,
487
- /* @__PURE__ */ jsx(AgentChatSubmitAction, {
488
- status,
489
- onStop,
490
- disabled,
491
- hasDraft: Boolean(composerDraft.trim() || composerReferences.length)
492
- })
493
- ]
494
- })] })
495
- ] })
496
- })
497
- ]
498
- }) : null
511
+ showsStartScreen ? null : composer
499
512
  ]
500
513
  });
501
514
  }
@@ -0,0 +1,2 @@
1
+ import { a as AgentChatStarterListProps, i as AgentChatStarterList, n as AgentChatStartScreenProps, o as AgentChatStarterProps, r as AgentChatStarter, t as AgentChatStartScreen } from "../AgentChatStartScreen-CvXJBr4y.js";
2
+ export { AgentChatStartScreen, AgentChatStartScreenProps, AgentChatStarter, AgentChatStarterList, AgentChatStarterListProps, AgentChatStarterProps };
@@ -0,0 +1,82 @@
1
+ import { t as cx } from "../class-names-BiMDVpUo.js";
2
+ import { et as XIcon } from "../icons-DyOM0EJs.js";
3
+ import { Button } from "./Button.js";
4
+ import * as React from "react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ //#region src/components/AgentChatStartScreen.tsx
7
+ /**
8
+ * Welcoming first-turn layout for `AgentChat` and `ThinkChat`.
9
+ *
10
+ * `AgentChat` normally creates this component through its `startScreen` prop so
11
+ * the same live composer moves from the center of the empty view to the pinned
12
+ * transcript position after the first message.
13
+ */
14
+ function AgentChatStartScreen({ heading = "What should we work on?", composer, children, className, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, ...props }) {
15
+ const headingId = React.useId();
16
+ return /* @__PURE__ */ jsx("section", {
17
+ "data-slot": "agent-chat-start-screen",
18
+ className: cx("agent-chat-start-screen", className),
19
+ "aria-label": ariaLabel,
20
+ "aria-labelledby": ariaLabel ? void 0 : ariaLabelledBy ?? (heading ? headingId : void 0),
21
+ ...props,
22
+ children: /* @__PURE__ */ jsxs("div", {
23
+ className: "agent-chat-start-screen__content",
24
+ children: [
25
+ heading ? /* @__PURE__ */ jsx("h2", {
26
+ id: headingId,
27
+ className: "agent-chat-start-screen__heading",
28
+ children: heading
29
+ }) : null,
30
+ composer,
31
+ children ? /* @__PURE__ */ jsx("div", {
32
+ className: "agent-chat-start-screen__starters",
33
+ children
34
+ }) : null
35
+ ]
36
+ })
37
+ });
38
+ }
39
+ /** Semantic list for first-turn prompts below an `AgentChatStartScreen`. */
40
+ function AgentChatStarterList({ className, ...props }) {
41
+ return /* @__PURE__ */ jsx("ul", {
42
+ "data-slot": "agent-chat-starter-list",
43
+ role: "list",
44
+ className: cx("agent-chat-starter-list", className),
45
+ ...props
46
+ });
47
+ }
48
+ /** One full-width, keyboard-native starter prompt. */
49
+ function AgentChatStarter({ icon, muted = false, onDismiss, dismissLabel, children, className, type = "button", ...props }) {
50
+ return /* @__PURE__ */ jsxs("li", {
51
+ "data-slot": "agent-chat-starter",
52
+ className: "agent-chat-starter",
53
+ children: [/* @__PURE__ */ jsxs(Button, {
54
+ ...props,
55
+ type,
56
+ variant: "ghost",
57
+ color: "neutral",
58
+ className: cx("agent-chat-starter__action", className),
59
+ "data-muted": muted ? "" : void 0,
60
+ children: [icon ? /* @__PURE__ */ jsx("span", {
61
+ className: "agent-chat-starter__icon",
62
+ "aria-hidden": "true",
63
+ children: icon
64
+ }) : null, /* @__PURE__ */ jsx("span", {
65
+ className: "agent-chat-starter__label",
66
+ children
67
+ })]
68
+ }), onDismiss ? /* @__PURE__ */ jsx(Button, {
69
+ type: "button",
70
+ variant: "ghost",
71
+ color: "neutral",
72
+ size: "lg",
73
+ iconOnly: true,
74
+ className: "agent-chat-starter__dismiss",
75
+ "aria-label": dismissLabel ?? "Dismiss suggestion",
76
+ onClick: onDismiss,
77
+ children: /* @__PURE__ */ jsx(XIcon, {})
78
+ }) : null]
79
+ });
80
+ }
81
+ //#endregion
82
+ export { AgentChatStartScreen, AgentChatStarter, AgentChatStarterList };
@@ -1,6 +1,7 @@
1
1
  import { t as cx } from "../class-names-BiMDVpUo.js";
2
2
  import { z as PencilIcon } from "../icons-DyOM0EJs.js";
3
3
  import { Button } from "./Button.js";
4
+ import { Kbd } from "./Kbd.js";
4
5
  import * as React from "react";
5
6
  import { jsx, jsxs } from "react/jsx-runtime";
6
7
  //#region src/components/Approval.tsx
@@ -207,10 +208,7 @@ function ApprovalDecision({ className, onDecision, onSkip, subject = "this actio
207
208
  className: "approval__submit",
208
209
  disabled: busy,
209
210
  onClick: () => void respond(selected === "approve"),
210
- children: [busy ? "Submitting…" : selected === "approve" ? "Approve" : "Submit denial", !busy ? /* @__PURE__ */ jsx("kbd", {
211
- className: "approval__kbd",
212
- children: "⏎"
213
- }) : null]
211
+ children: [busy ? "Submitting…" : selected === "approve" ? "Approve" : "Submit denial", !busy ? /* @__PURE__ */ jsx(Kbd, { children: "⏎" }) : null]
214
212
  })
215
213
  ]
216
214
  }),
@@ -3,7 +3,7 @@ import { K as SpinnerIcon, k as MaximizeIcon } from "../icons-DyOM0EJs.js";
3
3
  import { Button } from "./Button.js";
4
4
  import { Dialog } from "./Dialog.js";
5
5
  import { TransitionSurface } from "./TransitionSurface.js";
6
- import { Badge } from "./Badge.js";
6
+ import { StatusPill } from "./StatusPill.js";
7
7
  import * as React from "react";
8
8
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9
9
  //#region src/components/BrowserLiveView.tsx
@@ -79,14 +79,12 @@ function BrowserLiveView({ source, receivedAt, pageTitle, fallback, className, .
79
79
  const live = !expired && !failed;
80
80
  const frameTitle = pageTitle ? `Live browser view — ${pageTitle}` : "Live browser view";
81
81
  const view = live ? /* @__PURE__ */ jsxs(Fragment, { children: [
82
- /* @__PURE__ */ jsxs(Badge, {
82
+ /* @__PURE__ */ jsx(StatusPill, {
83
+ busy: true,
83
84
  size: "sm",
84
85
  color: "destructive",
85
86
  className: "browser-live-view__badge",
86
- children: [/* @__PURE__ */ jsx("span", {
87
- className: "browser-live-view__badge-dot",
88
- "aria-hidden": true
89
- }), "Live"]
87
+ children: "Live"
90
88
  }),
91
89
  /* @__PURE__ */ jsx("iframe", {
92
90
  className: "browser-live-view__frame",
@@ -101,7 +99,7 @@ function BrowserLiveView({ source, receivedAt, pageTitle, fallback, className, .
101
99
  frameState === "loading" ? /* @__PURE__ */ jsxs(TransitionSurface, {
102
100
  className: "browser-live-view__state",
103
101
  role: "status",
104
- children: [/* @__PURE__ */ jsx(SpinnerIcon, { className: "browser-live-view__state-spinner" }), "Connecting live view…"]
102
+ children: [/* @__PURE__ */ jsx(SpinnerIcon, {}), "Connecting live view…"]
105
103
  }) : null
106
104
  ] }) : fallback ?? /* @__PURE__ */ jsx(EndedState, {
107
105
  title: failed ? "Live view unavailable" : "Live view ended",
@@ -2,6 +2,7 @@ import { t as cx } from "../class-names-BiMDVpUo.js";
2
2
  import { B as PlayIcon, R as PauseIcon } from "../icons-DyOM0EJs.js";
3
3
  import { Button } from "./Button.js";
4
4
  import { r as formatClock } from "../format-S6uWyoSb.js";
5
+ import { EmptyState } from "./EmptyState.js";
5
6
  import { Slider } from "./Slider.js";
6
7
  import * as React from "react";
7
8
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -135,14 +136,14 @@ function BrowserReplay({ className, events, autoPlay, ref, ...props }) {
135
136
  ref: stageRef,
136
137
  className: "browser-replay__stage"
137
138
  }),
138
- events.length < 2 ? /* @__PURE__ */ jsx("div", {
139
+ events.length < 2 ? /* @__PURE__ */ jsx(EmptyState, {
139
140
  className: "browser-replay__empty",
140
- children: "No browser recording"
141
+ description: "No browser recording"
141
142
  }) : null,
142
- hasError ? /* @__PURE__ */ jsx("div", {
143
+ hasError ? /* @__PURE__ */ jsx(EmptyState, {
143
144
  className: "browser-replay__empty",
144
145
  role: "alert",
145
- children: "Browser replay could not be loaded"
146
+ description: "Browser replay could not be loaded"
146
147
  }) : null
147
148
  ]
148
149
  }), /* @__PURE__ */ jsxs("div", {
@@ -56,7 +56,7 @@ function BrowserRunPanel({ liveView, onRefresh, onCloseSession, loading, error,
56
56
  className: "browser-run-panel__live-view"
57
57
  }) : loading ? /* @__PURE__ */ jsxs(BrowserRunPanelState, {
58
58
  role: "status",
59
- children: [/* @__PURE__ */ jsx(SpinnerIcon, { className: "browser-run-panel__spinner" }), "Loading browser session"]
59
+ children: [/* @__PURE__ */ jsx(SpinnerIcon, {}), "Loading browser session"]
60
60
  }) : /* @__PURE__ */ jsx(BrowserRunPanelState, { children: empty });
61
61
  const bodyProps = {
62
62
  className: "web-preview__body browser-run-panel__body",
@@ -1,7 +1,7 @@
1
1
  import { t as cx } from "../class-names-BiMDVpUo.js";
2
2
  import { K as SpinnerIcon } from "../icons-DyOM0EJs.js";
3
3
  import { Button } from "./Button.js";
4
- import { u as ModelSelectorLogo } from "../ModelSelector-pecWyOFI.js";
4
+ import { u as ModelSelectorLogo } from "../ModelSelector-CEd8M9eK.js";
5
5
  import "react";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
7
7
  //#region src/components/ChatGptSignInScreen.tsx
@@ -76,27 +76,6 @@ declare function ConversationItem({
76
76
  scrollAnchor,
77
77
  ...props
78
78
  }: ConversationItemProps): React.JSX.Element;
79
- interface ConversationEmptyStateProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "title"> {
80
- title?: React.ReactNode;
81
- description?: React.ReactNode;
82
- icon?: React.ReactNode;
83
- }
84
- /**
85
- * Placeholder shown when there are no messages yet. Renders an icon, title,
86
- * and description stacked vertically; pass `children` to override the
87
- * default layout entirely.
88
- */
89
- declare function ConversationEmptyState({
90
- className,
91
- title,
92
- description,
93
- icon,
94
- children,
95
- ref,
96
- ...props
97
- }: ConversationEmptyStateProps & {
98
- ref?: React.Ref<HTMLDivElement>;
99
- }): React.JSX.Element;
100
79
  interface ConversationScrollButtonProps extends Omit<MessageScrollerButtonProps, "children"> {
101
80
  /** Accessible label for the button. */
102
81
  label?: string;
@@ -157,4 +136,4 @@ declare function ConversationDownload({
157
136
  ref?: React.Ref<HTMLButtonElement>;
158
137
  }): React.JSX.Element | null;
159
138
  //#endregion
160
- export { Conversation, ConversationContent, ConversationContentProps, ConversationDownload, ConversationDownloadProps, ConversationEmptyState, ConversationEmptyStateProps, ConversationItem, ConversationItemProps, ConversationMessage, ConversationProps, ConversationScrollButton, ConversationScrollButtonProps, messagesToMarkdown };
139
+ export { Conversation, ConversationContent, ConversationContentProps, ConversationDownload, ConversationDownloadProps, ConversationItem, ConversationItemProps, ConversationMessage, ConversationProps, ConversationScrollButton, ConversationScrollButtonProps, messagesToMarkdown };
@@ -4,7 +4,7 @@ import { Button } from "./Button.js";
4
4
  import { t as assignRef } from "../merge-refs-DF_7w2x_.js";
5
5
  import { MessageScroller, MessageScrollerButton, MessageScrollerContent, MessageScrollerItem, MessageScrollerProvider, MessageScrollerViewport } from "./MessageScroller.js";
6
6
  import * as React from "react";
7
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
+ import { jsx } from "react/jsx-runtime";
8
8
  import { isReasoningUIPart, isTextUIPart } from "ai";
9
9
  //#region src/components/Conversation.tsx
10
10
  /**
@@ -84,33 +84,6 @@ function ConversationItem({ className, scrollAnchor = false, ...props }) {
84
84
  });
85
85
  }
86
86
  /**
87
- * Placeholder shown when there are no messages yet. Renders an icon, title,
88
- * and description stacked vertically; pass `children` to override the
89
- * default layout entirely.
90
- */
91
- function ConversationEmptyState({ className, title = "No messages yet", description = "Start a conversation to see messages here", icon, children, ref, ...props }) {
92
- return /* @__PURE__ */ jsx("div", {
93
- ref,
94
- className: cx("conversation__empty", className),
95
- ...props,
96
- children: children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
97
- icon ? /* @__PURE__ */ jsx("span", {
98
- className: "conversation__empty-icon",
99
- "aria-hidden": "true",
100
- children: icon
101
- }) : null,
102
- title ? /* @__PURE__ */ jsx("div", {
103
- className: "conversation__empty-title",
104
- children: title
105
- }) : null,
106
- description ? /* @__PURE__ */ jsx("div", {
107
- className: "conversation__empty-description",
108
- children: description
109
- }) : null
110
- ] })
111
- });
112
- }
113
- /**
114
87
  * Floating button that scrolls the conversation to the latest message.
115
88
  * Hidden from view and tab order while the viewport is already at the end.
116
89
  */
@@ -178,4 +151,4 @@ function ConversationDownload({ className, messages, filename = "conversation.md
178
151
  });
179
152
  }
180
153
  //#endregion
181
- export { Conversation, ConversationContent, ConversationDownload, ConversationEmptyState, ConversationItem, ConversationScrollButton, messagesToMarkdown };
154
+ export { Conversation, ConversationContent, ConversationDownload, ConversationItem, ConversationScrollButton, messagesToMarkdown };
@@ -0,0 +1,46 @@
1
+ import * as React from "react";
2
+
3
+ //#region src/components/EmptyState.d.ts
4
+ interface EmptyStateProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "title"> {
5
+ /** Optional glyph above the title, in a quiet circular well. */
6
+ icon?: React.ReactNode;
7
+ /** What is absent, as a short noun phrase. */
8
+ title?: React.ReactNode;
9
+ /** One sentence on how to make it non-empty. */
10
+ description?: React.ReactNode;
11
+ }
12
+ /**
13
+ * Placeholder for a region that has nothing in it yet.
14
+ *
15
+ * There is no size prop. A one-line "No results" and a full centred block are
16
+ * the same component with different content — pass only `description` for the
17
+ * first and add `icon` and `title` for the second. Filling and centring a
18
+ * region is the container's job, not this component's; set
19
+ * `--sigvelo-recipe-empty-state-padding-block` where a roomier well is wanted.
20
+ *
21
+ * `children` replaces the whole stack, for the cases that need an action.
22
+ *
23
+ * @example
24
+ * ```tsx
25
+ * <EmptyState description="No runs yet." />
26
+ *
27
+ * <EmptyState
28
+ * icon={<MessageIcon />}
29
+ * title="Start a conversation"
30
+ * description="Ask the agent to inspect, plan, or build."
31
+ * />
32
+ * ```
33
+ */
34
+ declare function EmptyState({
35
+ className,
36
+ icon,
37
+ title,
38
+ description,
39
+ children,
40
+ ref,
41
+ ...props
42
+ }: EmptyStateProps & {
43
+ ref?: React.Ref<HTMLDivElement>;
44
+ }): React.JSX.Element;
45
+ //#endregion
46
+ export { EmptyState, EmptyStateProps };