@mcp-b/react-components 0.10.0 → 0.12.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 (84) hide show
  1. package/dist/{AgentChat-B9LD_WF1.d.ts → AgentChat-CRmsKg9B.d.ts} +10 -6
  2. package/dist/{BrowserLiveView-ZktFZiMD.d.ts → BrowserLiveView-BV5qgFgI.d.ts} +11 -10
  3. package/dist/{BrowserReplay-6G-mnwcn.d.ts → BrowserReplay-xWvRjRAC.d.ts} +2 -1
  4. package/dist/{Menu-B5vDqZe_.d.ts → Menu-BLhnNnRK.d.ts} +3 -0
  5. package/dist/{ModelSelector-DXtpcRmT.js → ModelSelector-BB-xB-Es.js} +16 -13
  6. package/dist/{PromptInput-D6-G24p7.d.ts → PromptInput-IyM6ZETj.d.ts} +13 -45
  7. package/dist/ThinkChat-B3wYahor.js +190 -0
  8. package/dist/{ThinkChatActivity-B2UD95My.d.ts → ThinkChatActivity-F4KFPcJA.d.ts} +4 -4
  9. package/dist/ThinkChatContext-C3Eb1Xpi.d.ts +16 -0
  10. package/dist/{ThinkChatToolParts-DnUiZgCC.d.ts → ThinkChatToolParts-Cv4o7j6F.d.ts} +13 -5
  11. package/dist/components/AgentChat.d.ts +1 -1
  12. package/dist/components/AgentChat.js +57 -23
  13. package/dist/components/AgentConnection.d.ts +3 -14
  14. package/dist/components/AgentConnection.js +7 -111
  15. package/dist/components/Badge.js +1 -15
  16. package/dist/components/BrowserLiveView.d.ts +1 -1
  17. package/dist/components/BrowserLiveView.js +14 -10
  18. package/dist/components/BrowserReplay.d.ts +1 -1
  19. package/dist/components/BrowserRunPanel.d.ts +46 -0
  20. package/dist/components/BrowserRunPanel.js +159 -0
  21. package/dist/components/ChatGptSignInScreen.js +1 -1
  22. package/dist/components/CodexModelSelector.d.ts +63 -0
  23. package/dist/components/CodexModelSelector.js +148 -0
  24. package/dist/components/Commit.d.ts +2 -2
  25. package/dist/components/Commit.js +10 -22
  26. package/dist/components/Conversation.d.ts +2 -6
  27. package/dist/components/Conversation.js +2 -3
  28. package/dist/components/EnvironmentVariables.d.ts +2 -7
  29. package/dist/components/EnvironmentVariables.js +10 -33
  30. package/dist/components/Marker.js +1 -15
  31. package/dist/components/McpServerPicker.d.ts +31 -6
  32. package/dist/components/McpServerPicker.js +129 -67
  33. package/dist/components/Menu.d.ts +1 -1
  34. package/dist/components/Menu.js +2 -2
  35. package/dist/components/Message.d.ts +3 -2
  36. package/dist/components/Message.js +10 -3
  37. package/dist/components/ModelSelector.d.ts +11 -8
  38. package/dist/components/ModelSelector.js +1 -1
  39. package/dist/components/PromptInput.d.ts +2 -2
  40. package/dist/components/PromptInput.js +49 -98
  41. package/dist/components/Queue.d.ts +1 -12
  42. package/dist/components/Reasoning.js +2 -15
  43. package/dist/components/Stepper.js +1 -7
  44. package/dist/components/ThinkChat.d.ts +30 -30
  45. package/dist/components/ThinkChat.js +1 -152
  46. package/dist/components/ThinkChatActivity.d.ts +2 -2
  47. package/dist/components/ThinkChatActivity.js +3 -10
  48. package/dist/components/ThinkChatContext.d.ts +2 -2
  49. package/dist/components/ThinkChatContext.js +9 -2
  50. package/dist/components/ThinkChatToolPanels.d.ts +1 -1
  51. package/dist/components/ThinkChatToolPanels.js +19 -7
  52. package/dist/components/ThinkChatToolParts.d.ts +1 -1
  53. package/dist/components/ThinkExecutionWorkbench.d.ts +10 -7
  54. package/dist/components/ThinkExecutionWorkbench.js +382 -359
  55. package/dist/components/ThinkFullApp.d.ts +16 -13
  56. package/dist/components/ThinkFullApp.js +28 -18
  57. package/dist/components/ThinkThreadPicker.d.ts +1 -31
  58. package/dist/components/ThinkThreadPicker.js +32 -171
  59. package/dist/components/ThinkThreadShell.d.ts +35 -0
  60. package/dist/components/ThinkThreadShell.js +146 -0
  61. package/dist/components/WorkspaceExplorer.js +3 -1
  62. package/dist/merge-refs-DF_7w2x_.js +18 -0
  63. package/dist/styles/agent-chat.css +4 -1
  64. package/dist/styles/agent-connection.css +0 -166
  65. package/dist/styles/browser-run-panel.css +125 -0
  66. package/dist/styles/codex-model-selector.css +197 -0
  67. package/dist/styles/index.css +5 -0
  68. package/dist/styles/mcp-server-picker.css +62 -15
  69. package/dist/styles/message.css +1 -1
  70. package/dist/styles/model-selector.css +20 -8
  71. package/dist/styles/prompt-input.css +5 -0
  72. package/dist/styles/streamdown.css +2 -48
  73. package/dist/styles/think-execution-workbench.css +337 -0
  74. package/dist/styles/think-full-app.css +15 -390
  75. package/dist/styles/think-resize-handle.css +33 -0
  76. package/dist/styles/think-thread-picker.css +0 -238
  77. package/dist/styles/think-thread-shell.css +219 -0
  78. package/dist/styles/workspace-explorer.css +8 -2
  79. package/dist/summarize-tool-input-BUJsENSn.js +12 -0
  80. package/dist/utils/mcp-server-catalog.d.ts +2 -3
  81. package/package.json +2 -2
  82. package/dist/ThinkChatContext-BLAAb8J5.d.ts +0 -28
  83. package/dist/components/useStickToBottom.d.ts +0 -33
  84. package/dist/components/useStickToBottom.js +0 -107
@@ -0,0 +1,159 @@
1
+ import { t as cx } from "../class-names-9UtZwb0J.js";
2
+ import { L as XIcon, M as SpinnerIcon } from "../icons-D2Q5n5C1.js";
3
+ import { Button } from "./Button.js";
4
+ import { BrowserLiveView } from "./BrowserLiveView.js";
5
+ import { WebPreview, WebPreviewNavigation, WebPreviewNavigationButton, WebPreviewUrl } from "./WebPreview.js";
6
+ import * as React from "react";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ //#region src/components/BrowserRunPanel.tsx
9
+ function isInspectablePage(target) {
10
+ const pageUrl = target.pageUrl;
11
+ return Boolean(pageUrl && !pageUrl.startsWith("about:") && !pageUrl.startsWith("chrome:") && !pageUrl.startsWith("devtools:"));
12
+ }
13
+ function targetLabel(target) {
14
+ return target.title || target.pageUrl || target.targetId;
15
+ }
16
+ function targetGlyph(target) {
17
+ return (target.title || target.pageUrl || target.targetId).trim().charAt(0).toUpperCase() || "•";
18
+ }
19
+ function pickTarget(targets, targetId) {
20
+ return (targetId ? targets.find((target) => target.targetId === targetId) : void 0) ?? targets.find(isInspectablePage) ?? targets[0];
21
+ }
22
+ function BrowserRunPanelState({ children, role, tone = "neutral" }) {
23
+ return /* @__PURE__ */ jsx("div", {
24
+ className: "web-preview__body--empty browser-run-panel__state",
25
+ "data-tone": tone,
26
+ role: role ?? (tone === "danger" ? "alert" : void 0),
27
+ children
28
+ });
29
+ }
30
+ /**
31
+ * Right-side Browser Run panel for `ThinkFullApp.workbenchPanels`.
32
+ *
33
+ * The app owns `createBrowserRuntime()`, `connector.liveView()`, polling, and
34
+ * session cleanup. This component only renders upstream `BrowserLiveView`
35
+ * data and calls app-provided refresh/close callbacks.
36
+ */
37
+ function BrowserRunPanel({ liveView, onRefresh, onCloseSession, loading, error, label = "Browser", empty = "No live browser session", fallback, className, ref, ...props }) {
38
+ const [selectedTargetId, setSelectedTargetId] = React.useState();
39
+ const [receivedAt, setReceivedAt] = React.useState(() => Date.now());
40
+ const tabRefs = React.useRef(/* @__PURE__ */ new Map());
41
+ const tabListId = React.useId();
42
+ React.useEffect(() => {
43
+ if (liveView) setReceivedAt(Date.now());
44
+ }, [liveView]);
45
+ const targets = liveView?.targets ?? [];
46
+ const target = pickTarget(targets, selectedTargetId);
47
+ const pageUrl = target?.pageUrl ?? "";
48
+ const selectTarget = React.useCallback((nextTarget) => {
49
+ setSelectedTargetId(nextTarget.targetId);
50
+ }, []);
51
+ const handleTabListKeyDown = (event) => {
52
+ const currentIndex = targets.findIndex((candidate) => candidate.targetId === target?.targetId);
53
+ if (currentIndex < 0) return;
54
+ let nextIndex;
55
+ if (event.key === "ArrowRight") nextIndex = (currentIndex + 1) % targets.length;
56
+ if (event.key === "ArrowLeft") nextIndex = (currentIndex - 1 + targets.length) % targets.length;
57
+ if (event.key === "Home") nextIndex = 0;
58
+ if (event.key === "End") nextIndex = targets.length - 1;
59
+ if (nextIndex === void 0) return;
60
+ event.preventDefault();
61
+ const nextTarget = targets[nextIndex];
62
+ if (!nextTarget) return;
63
+ selectTarget(nextTarget);
64
+ tabRefs.current.get(nextTarget.targetId)?.focus();
65
+ };
66
+ return /* @__PURE__ */ jsxs(WebPreview, {
67
+ ref,
68
+ className: cx("browser-run-panel", className),
69
+ url: pageUrl,
70
+ role: "region",
71
+ "aria-label": typeof label === "string" ? label : "Browser",
72
+ ...props,
73
+ children: [
74
+ targets.length > 1 ? /* @__PURE__ */ jsx(WebPreviewNavigation, { children: /* @__PURE__ */ jsx("div", {
75
+ id: tabListId,
76
+ className: "browser-run-panel__tabs",
77
+ role: "tablist",
78
+ "aria-label": "Open browser pages",
79
+ onKeyDown: handleTabListKeyDown,
80
+ children: targets.map((candidate) => {
81
+ const selected = candidate.targetId === target?.targetId;
82
+ return /* @__PURE__ */ jsxs(Button, {
83
+ ref: (node) => {
84
+ if (node) tabRefs.current.set(candidate.targetId, node);
85
+ else tabRefs.current.delete(candidate.targetId);
86
+ },
87
+ type: "button",
88
+ variant: "ghost",
89
+ color: "neutral",
90
+ size: "sm",
91
+ className: "browser-run-panel__tab",
92
+ role: "tab",
93
+ id: `${tabListId}-${candidate.targetId}`,
94
+ "aria-selected": selected,
95
+ "aria-controls": `${tabListId}-panel`,
96
+ tabIndex: selected ? 0 : -1,
97
+ onClick: () => selectTarget(candidate),
98
+ children: [/* @__PURE__ */ jsx("span", {
99
+ className: "browser-run-panel__tab-glyph",
100
+ "aria-hidden": "true",
101
+ children: targetGlyph(candidate)
102
+ }), /* @__PURE__ */ jsx("span", {
103
+ className: "browser-run-panel__tab-title",
104
+ children: targetLabel(candidate)
105
+ })]
106
+ }, candidate.targetId);
107
+ })
108
+ }) }) : null,
109
+ /* @__PURE__ */ jsxs(WebPreviewNavigation, {
110
+ className: "browser-run-panel__address-bar",
111
+ children: [
112
+ /* @__PURE__ */ jsx(WebPreviewUrl, {
113
+ "aria-label": "Browser page URL",
114
+ placeholder: "Waiting for browser session",
115
+ readOnly: true
116
+ }),
117
+ onRefresh ? /* @__PURE__ */ jsx(WebPreviewNavigationButton, {
118
+ action: "reload",
119
+ label: "Refresh browser view",
120
+ disabled: loading,
121
+ onClick: () => void onRefresh()
122
+ }) : null,
123
+ onCloseSession ? /* @__PURE__ */ jsx(WebPreviewNavigationButton, {
124
+ label: "Close browser session",
125
+ onClick: () => void onCloseSession(),
126
+ children: /* @__PURE__ */ jsx(XIcon, {})
127
+ }) : null
128
+ ]
129
+ }),
130
+ error ? /* @__PURE__ */ jsx(BrowserRunPanelState, {
131
+ tone: "danger",
132
+ children: error
133
+ }) : null,
134
+ /* @__PURE__ */ jsx("div", {
135
+ id: `${tabListId}-panel`,
136
+ className: "web-preview__body browser-run-panel__body",
137
+ role: targets.length > 1 ? "tabpanel" : void 0,
138
+ "aria-labelledby": targets.length > 1 && target ? `${tabListId}-${target.targetId}` : void 0,
139
+ "aria-busy": loading || void 0,
140
+ children: target && liveView ? /* @__PURE__ */ jsx(BrowserLiveView, {
141
+ source: {
142
+ url: target.url,
143
+ targetId: target.targetId,
144
+ expiresInMs: liveView.expiresInMs
145
+ },
146
+ receivedAt,
147
+ pageTitle: target.title ?? target.pageUrl,
148
+ fallback,
149
+ className: "browser-run-panel__live-view"
150
+ }) : loading ? /* @__PURE__ */ jsxs(BrowserRunPanelState, {
151
+ role: "status",
152
+ children: [/* @__PURE__ */ jsx(SpinnerIcon, { className: "browser-run-panel__spinner" }), "Loading browser session"]
153
+ }) : /* @__PURE__ */ jsx(BrowserRunPanelState, { children: empty })
154
+ })
155
+ ]
156
+ });
157
+ }
158
+ //#endregion
159
+ export { BrowserRunPanel };
@@ -1,7 +1,7 @@
1
1
  import { t as cx } from "../class-names-9UtZwb0J.js";
2
2
  import { M as SpinnerIcon } from "../icons-D2Q5n5C1.js";
3
3
  import { Button } from "./Button.js";
4
- import { u as ModelSelectorLogo } from "../ModelSelector-DXtpcRmT.js";
4
+ import { u as ModelSelectorLogo } from "../ModelSelector-BB-xB-Es.js";
5
5
  import "react";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
7
7
  //#region src/components/ChatGptSignInScreen.tsx
@@ -0,0 +1,63 @@
1
+ import * as React from "react";
2
+
3
+ //#region src/components/CodexModelSelector.d.ts
4
+ /** One server-supported value for a Codex response setting. */
5
+ interface CodexModelSelectorSetting {
6
+ readonly id: string;
7
+ readonly label: string;
8
+ /** Optional explanation shown below the option, such as its usage impact. */
9
+ readonly description?: string;
10
+ }
11
+ interface CodexModelSelectorProps {
12
+ /** Model options allowed by the consuming app. Keep authentication and entitlement checks server-side. */
13
+ readonly models: readonly CodexModelSelectorSetting[];
14
+ /** Current model id used by the consuming app's AI SDK provider. */
15
+ readonly selectedModelId?: string | null;
16
+ /** Called only with an id from the app-provided catalog. */
17
+ readonly onSelectModel: (modelId: string) => void;
18
+ /** Server-supported reasoning effort values for the selected model. */
19
+ readonly effortOptions?: readonly CodexModelSelectorSetting[];
20
+ readonly selectedEffortId?: string | null;
21
+ readonly onSelectEffort?: (effortId: string) => void;
22
+ /** Server-supported response-speed values for the selected model. */
23
+ readonly speedOptions?: readonly CodexModelSelectorSetting[];
24
+ readonly selectedSpeedId?: string | null;
25
+ readonly onSelectSpeed?: (speedId: string) => void;
26
+ /** Restores all values to the consuming app's preferred defaults. */
27
+ readonly onReset?: () => void;
28
+ readonly disabled?: boolean;
29
+ readonly className?: string;
30
+ /** Controlled menu open state. */
31
+ readonly open?: boolean;
32
+ /** Initial menu state for uncontrolled usage. */
33
+ readonly defaultOpen?: boolean;
34
+ readonly onOpenChange?: (open: boolean) => void;
35
+ readonly "aria-label"?: string;
36
+ }
37
+ /**
38
+ * A compact Codex-style response settings picker: model, reasoning effort,
39
+ * response speed, and reset are kept in one cascading menu.
40
+ *
41
+ * The consuming app supplies every selectable value. This component only
42
+ * renders those values and never guesses model ids or account entitlements.
43
+ */
44
+ declare function CodexModelSelector({
45
+ models,
46
+ selectedModelId,
47
+ onSelectModel,
48
+ effortOptions,
49
+ selectedEffortId,
50
+ onSelectEffort,
51
+ speedOptions,
52
+ selectedSpeedId,
53
+ onSelectSpeed,
54
+ onReset,
55
+ disabled,
56
+ className,
57
+ open,
58
+ defaultOpen,
59
+ onOpenChange,
60
+ "aria-label": ariaLabel
61
+ }: CodexModelSelectorProps): React.JSX.Element;
62
+ //#endregion
63
+ export { CodexModelSelector, CodexModelSelectorProps, CodexModelSelectorSetting };
@@ -0,0 +1,148 @@
1
+ import { t as cx } from "../class-names-9UtZwb0J.js";
2
+ import { a as CheckIcon, c as ChevronRightIcon, k as RefreshIcon, o as ChevronDownIcon } from "../icons-D2Q5n5C1.js";
3
+ import { MenuContent, MenuGroup, MenuGroupLabel, MenuItem, MenuRadioGroup, MenuRadioItem, MenuRadioItemIndicator, MenuRoot, MenuSeparator, MenuSub, MenuSubContent, MenuSubmenuTrigger, MenuTrigger } from "./Menu.js";
4
+ import * as React from "react";
5
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
+ //#region src/components/CodexModelSelector.tsx
7
+ /**
8
+ * A compact Codex-style response settings picker: model, reasoning effort,
9
+ * response speed, and reset are kept in one cascading menu.
10
+ *
11
+ * The consuming app supplies every selectable value. This component only
12
+ * renders those values and never guesses model ids or account entitlements.
13
+ */
14
+ function CodexModelSelector({ models, selectedModelId = null, onSelectModel, effortOptions = [], selectedEffortId = null, onSelectEffort, speedOptions = [], selectedSpeedId = null, onSelectSpeed, onReset, disabled = false, className, open, defaultOpen, onOpenChange, "aria-label": ariaLabel = "Codex response settings" }) {
15
+ const [internalOpen, setInternalOpen] = React.useState(defaultOpen);
16
+ const selectedModel = models.find((model) => model.id === selectedModelId);
17
+ const selectedEffort = effortOptions.find((option) => option.id === selectedEffortId);
18
+ const selectedSpeed = speedOptions.find((option) => option.id === selectedSpeedId);
19
+ const currentOpen = open ?? internalOpen;
20
+ const handleOpenChange = React.useCallback((nextOpen) => {
21
+ if (open === void 0) setInternalOpen(nextOpen);
22
+ onOpenChange?.(nextOpen);
23
+ }, [onOpenChange, open]);
24
+ const handleSelectModel = React.useCallback((modelId) => {
25
+ onSelectModel(modelId);
26
+ handleOpenChange(false);
27
+ }, [handleOpenChange, onSelectModel]);
28
+ const handleSelectEffort = React.useCallback((effortId) => {
29
+ onSelectEffort?.(effortId);
30
+ handleOpenChange(false);
31
+ }, [handleOpenChange, onSelectEffort]);
32
+ const handleSelectSpeed = React.useCallback((speedId) => {
33
+ onSelectSpeed?.(speedId);
34
+ handleOpenChange(false);
35
+ }, [handleOpenChange, onSelectSpeed]);
36
+ const handleReset = React.useCallback(() => {
37
+ onReset?.();
38
+ handleOpenChange(false);
39
+ }, [handleOpenChange, onReset]);
40
+ return /* @__PURE__ */ jsxs(MenuRoot, {
41
+ open: currentOpen,
42
+ onOpenChange: handleOpenChange,
43
+ children: [/* @__PURE__ */ jsxs(MenuTrigger, {
44
+ unstyled: true,
45
+ className: cx("codex-model-selector__trigger", className),
46
+ disabled,
47
+ "aria-label": ariaLabel,
48
+ children: [/* @__PURE__ */ jsxs("span", {
49
+ className: "codex-model-selector__summary",
50
+ children: [/* @__PURE__ */ jsx("span", { children: selectedModel?.label ?? "Select model" }), selectedEffort ? /* @__PURE__ */ jsx("span", {
51
+ className: cx("codex-model-selector__summary-effort", selectedEffort.id === "ultra" && "codex-model-selector__summary-effort--ultra"),
52
+ children: selectedEffort.label
53
+ }) : null]
54
+ }), /* @__PURE__ */ jsx(ChevronDownIcon, { className: "codex-model-selector__trigger-icon" })]
55
+ }), /* @__PURE__ */ jsxs(MenuContent, {
56
+ className: "codex-model-selector__menu",
57
+ side: "top",
58
+ align: "end",
59
+ children: [
60
+ /* @__PURE__ */ jsx(CodexModelSelectorSubmenu, {
61
+ label: "Model",
62
+ value: selectedModel?.label ?? "Select",
63
+ disabled: models.length === 0,
64
+ children: /* @__PURE__ */ jsx(MenuRadioGroup, {
65
+ value: selectedModelId ?? void 0,
66
+ onValueChange: handleSelectModel,
67
+ children: models.map((model) => /* @__PURE__ */ jsx(CodexModelSelectorRadioItem, {
68
+ value: model.id,
69
+ description: model.description,
70
+ children: model.label
71
+ }, model.id))
72
+ })
73
+ }),
74
+ effortOptions.length > 0 && onSelectEffort ? /* @__PURE__ */ jsx(CodexModelSelectorSubmenu, {
75
+ label: "Effort",
76
+ value: selectedEffort?.label ?? "Select",
77
+ children: /* @__PURE__ */ jsx(MenuRadioGroup, {
78
+ value: selectedEffortId ?? void 0,
79
+ onValueChange: handleSelectEffort,
80
+ children: effortOptions.map((option) => /* @__PURE__ */ jsx(CodexModelSelectorRadioItem, {
81
+ value: option.id,
82
+ description: option.description,
83
+ children: option.label
84
+ }, option.id))
85
+ })
86
+ }) : null,
87
+ speedOptions.length > 0 && onSelectSpeed ? /* @__PURE__ */ jsx(CodexModelSelectorSubmenu, {
88
+ label: "Speed",
89
+ value: selectedSpeed?.label ?? "Select",
90
+ children: /* @__PURE__ */ jsx(MenuRadioGroup, {
91
+ value: selectedSpeedId ?? void 0,
92
+ onValueChange: handleSelectSpeed,
93
+ children: speedOptions.map((option) => /* @__PURE__ */ jsx(CodexModelSelectorRadioItem, {
94
+ value: option.id,
95
+ description: option.description,
96
+ children: option.label
97
+ }, option.id))
98
+ })
99
+ }) : null,
100
+ onReset ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(MenuSeparator, {}), /* @__PURE__ */ jsxs(MenuItem, {
101
+ className: "codex-model-selector__reset",
102
+ onClick: handleReset,
103
+ children: ["Reset to default", /* @__PURE__ */ jsx(RefreshIcon, { className: "codex-model-selector__reset-icon" })]
104
+ })] }) : null
105
+ ]
106
+ })]
107
+ });
108
+ }
109
+ function CodexModelSelectorSubmenu({ label, value, disabled = false, children }) {
110
+ return /* @__PURE__ */ jsxs(MenuSub, { children: [/* @__PURE__ */ jsxs(MenuSubmenuTrigger, {
111
+ className: "codex-model-selector__submenu-trigger",
112
+ disabled,
113
+ children: [
114
+ /* @__PURE__ */ jsx("span", { children: label }),
115
+ /* @__PURE__ */ jsx("span", {
116
+ className: "codex-model-selector__submenu-value",
117
+ children: value
118
+ }),
119
+ /* @__PURE__ */ jsx(ChevronRightIcon, { className: "codex-model-selector__submenu-icon" })
120
+ ]
121
+ }), /* @__PURE__ */ jsx(MenuSubContent, {
122
+ className: cx("codex-model-selector__submenu", `codex-model-selector__submenu--${label.toLowerCase()}`),
123
+ side: "right",
124
+ align: "start",
125
+ children: /* @__PURE__ */ jsxs(MenuGroup, { children: [/* @__PURE__ */ jsx(MenuGroupLabel, {
126
+ className: "codex-model-selector__submenu-title",
127
+ children: label
128
+ }), children] })
129
+ })] });
130
+ }
131
+ function CodexModelSelectorRadioItem({ children, description, ...props }) {
132
+ return /* @__PURE__ */ jsxs(MenuRadioItem, {
133
+ className: "codex-model-selector__option",
134
+ ...props,
135
+ children: [/* @__PURE__ */ jsxs("span", { children: [/* @__PURE__ */ jsx("span", {
136
+ className: "codex-model-selector__option-label",
137
+ children
138
+ }), description ? /* @__PURE__ */ jsx("span", {
139
+ className: "codex-model-selector__option-description",
140
+ children: description
141
+ }) : null] }), /* @__PURE__ */ jsx(MenuRadioItemIndicator, {
142
+ className: "codex-model-selector__option-indicator",
143
+ children: /* @__PURE__ */ jsx(CheckIcon, {})
144
+ })]
145
+ });
146
+ }
147
+ //#endregion
148
+ export { CodexModelSelector };
@@ -1,5 +1,5 @@
1
1
  import { CollapsiblePanelProps, CollapsibleRootProps, CollapsibleTriggerProps } from "./Collapsible.js";
2
- import { r as ButtonProps } from "../Button-Ct5I6aTu.js";
2
+ import { t as CopyButtonProps } from "../copy-button-BKXqGiNm.js";
3
3
  import * as React from "react";
4
4
 
5
5
  //#region src/components/Commit.d.ts
@@ -133,7 +133,7 @@ declare function CommitHash({
133
133
  }: CommitHashProps & {
134
134
  ref?: React.Ref<HTMLSpanElement>;
135
135
  }): React.JSX.Element;
136
- interface CommitCopyButtonProps extends Omit<ButtonProps, "children" | "variant" | "size" | "color" | "className" | "onClick"> {
136
+ interface CommitCopyButtonProps extends Omit<CopyButtonProps, "label" | "stopPropagation" | "text"> {
137
137
  hash: string;
138
138
  label?: string;
139
139
  className?: string;
@@ -1,11 +1,10 @@
1
1
  import { CollapsiblePanel, CollapsibleRoot, CollapsibleTrigger } from "./Collapsible.js";
2
2
  import { t as cx } from "../class-names-9UtZwb0J.js";
3
- import { a as CheckIcon, c as ChevronRightIcon, h as FileIcon, l as CopyIcon } from "../icons-D2Q5n5C1.js";
4
- import { Button } from "./Button.js";
5
- import { Tooltip, TooltipPopup, TooltipPortal, TooltipPositioner, TooltipTrigger } from "./Tooltip.js";
3
+ import { c as ChevronRightIcon, h as FileIcon } from "../icons-D2Q5n5C1.js";
4
+ import { t as CopyButton } from "../copy-button-C6JSKtFE.js";
6
5
  import { Avatar } from "./Avatar.js";
7
6
  import { Badge } from "./Badge.js";
8
- import * as React from "react";
7
+ import "react";
9
8
  import { jsx, jsxs } from "react/jsx-runtime";
10
9
  //#region src/components/Commit.tsx
11
10
  const FILE_STATUS_COLOR = {
@@ -141,25 +140,14 @@ function CommitHash({ className, children, hash, ref, ...props }) {
141
140
  });
142
141
  }
143
142
  function CommitCopyButton({ className, hash, label = "Copy hash", onClick, ...props }) {
144
- const [copied, setCopied] = React.useState(false);
145
- const handleClick = React.useCallback(async (e) => {
146
- e.stopPropagation();
147
- try {
148
- await navigator.clipboard.writeText(hash);
149
- setCopied(true);
150
- window.setTimeout(() => setCopied(false), 1500);
151
- } catch {}
152
- onClick?.(e);
153
- }, [hash, onClick]);
154
- return /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, { render: /* @__PURE__ */ jsx(Button, {
155
- variant: "ghost",
156
- size: "icon",
157
- "aria-label": label,
158
- className: cx("commit__copy", className),
143
+ return /* @__PURE__ */ jsx(CopyButton, {
159
144
  ...props,
160
- onClick: handleClick,
161
- children: copied ? /* @__PURE__ */ jsx(CheckIcon, {}) : /* @__PURE__ */ jsx(CopyIcon, {})
162
- }) }), /* @__PURE__ */ jsx(TooltipPortal, { children: /* @__PURE__ */ jsx(TooltipPositioner, { children: /* @__PURE__ */ jsx(TooltipPopup, { children: copied ? "Copied" : label }) }) })] });
145
+ text: hash,
146
+ label,
147
+ stopPropagation: true,
148
+ className: cx("commit__copy", className),
149
+ onClick
150
+ });
163
151
  }
164
152
  function CommitTimestamp({ className, children, date, ref, ...props }) {
165
153
  return /* @__PURE__ */ jsx("time", {
@@ -4,12 +4,8 @@ import * as React from "react";
4
4
  import { UIMessage } from "ai";
5
5
 
6
6
  //#region src/components/Conversation.d.ts
7
- /** AI SDK `UIMessage`, or a plain text fallback for non-chat exports. */
8
- type ConversationMessage = UIMessage | {
9
- id?: string;
10
- role: string;
11
- content?: string;
12
- };
7
+ /** Whole AI SDK message accepted by transcript export helpers. */
8
+ type ConversationMessage = UIMessage;
13
9
  interface ConversationProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "children"> {
14
10
  /** Additional class names for layout only; do not override scroll behavior from apps. */
15
11
  className?: string;
@@ -133,11 +133,10 @@ function ConversationScrollButton({ className, variant = "outline", color = "neu
133
133
  const ROLE_HEADING = {
134
134
  user: "### User",
135
135
  assistant: "### Assistant",
136
- system: "### System",
137
- tool: "### Tool"
136
+ system: "### System"
138
137
  };
139
138
  function defaultFormatMessage(message) {
140
- return `${ROLE_HEADING[message.role] ?? `### ${message.role}`}\n\n${("parts" in message ? message.parts.filter((part) => isTextUIPart(part) || isReasoningUIPart(part)).map((part) => part.text).join("") : message.content ?? "").trim()}`;
139
+ return `${ROLE_HEADING[message.role]}\n\n${message.parts.filter((part) => isTextUIPart(part) || isReasoningUIPart(part)).map((part) => part.text).join("").trim()}`;
141
140
  }
142
141
  /**
143
142
  * Converts a conversation to a Markdown document with a heading per message.
@@ -1,4 +1,4 @@
1
- import { r as ButtonProps } from "../Button-Ct5I6aTu.js";
1
+ import { t as CopyButtonProps } from "../copy-button-BKXqGiNm.js";
2
2
  import * as React from "react";
3
3
 
4
4
  //#region src/components/EnvironmentVariables.d.ts
@@ -142,15 +142,10 @@ declare function EnvironmentVariableValue({
142
142
  ref?: React.Ref<HTMLSpanElement>;
143
143
  }): React.JSX.Element;
144
144
  type EnvironmentVariableCopyFormat = "name" | "value" | "export";
145
- interface EnvironmentVariableCopyButtonProps extends Omit<ButtonProps, "children" | "variant" | "size" | "color" | "className" | "onClick" | "onError"> {
145
+ interface EnvironmentVariableCopyButtonProps extends Omit<CopyButtonProps, "label" | "stopPropagation" | "text"> {
146
146
  format?: EnvironmentVariableCopyFormat;
147
147
  copyFormat?: EnvironmentVariableCopyFormat;
148
148
  label?: string;
149
- className?: string;
150
- onClick?: React.MouseEventHandler<HTMLButtonElement>;
151
- onCopy?: () => void;
152
- onError?: (error: Error) => void;
153
- timeout?: number;
154
149
  }
155
150
  declare function EnvironmentVariableCopyButton({
156
151
  className,
@@ -1,7 +1,6 @@
1
1
  import { t as cx } from "../class-names-9UtZwb0J.js";
2
- import { a as CheckIcon, l as CopyIcon, m as EyeOffIcon, p as EyeIcon } from "../icons-D2Q5n5C1.js";
3
- import { Button } from "./Button.js";
4
- import { Tooltip, TooltipPopup, TooltipPortal, TooltipPositioner, TooltipTrigger } from "./Tooltip.js";
2
+ import { m as EyeOffIcon, p as EyeIcon } from "../icons-D2Q5n5C1.js";
3
+ import { t as CopyButton } from "../copy-button-C6JSKtFE.js";
5
4
  import { Badge } from "./Badge.js";
6
5
  import { Switch, SwitchThumb } from "./Switch.js";
7
6
  import * as React from "react";
@@ -171,41 +170,19 @@ function EnvironmentVariableValue({ className, children, ref, ...props }) {
171
170
  }
172
171
  function EnvironmentVariableCopyButton({ className, format = "value", copyFormat, label, onClick, onCopy, onError, timeout = 1500, ...props }) {
173
172
  const { name, value } = useVariableContext();
174
- const [copied, setCopied] = React.useState(false);
175
- const timeoutRef = React.useRef(null);
176
173
  const resolvedFormat = copyFormat ?? format;
177
174
  const text = resolvedFormat === "name" ? name : resolvedFormat === "export" ? `export ${name}="${value}"` : value;
178
175
  const buttonLabel = label ?? `Copy ${resolvedFormat}`;
179
- const handleClick = React.useCallback(async (e) => {
180
- try {
181
- await navigator.clipboard.writeText(text);
182
- setCopied(true);
183
- onCopy?.();
184
- if (timeoutRef.current !== null) window.clearTimeout(timeoutRef.current);
185
- timeoutRef.current = window.setTimeout(() => setCopied(false), timeout);
186
- } catch (error) {
187
- onError?.(error);
188
- }
189
- onClick?.(e);
190
- }, [
191
- onClick,
192
- onCopy,
193
- onError,
176
+ return /* @__PURE__ */ jsx(CopyButton, {
177
+ ...props,
194
178
  text,
195
- timeout
196
- ]);
197
- React.useEffect(() => () => {
198
- if (timeoutRef.current !== null) window.clearTimeout(timeoutRef.current);
199
- }, []);
200
- return /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, { render: /* @__PURE__ */ jsx(Button, {
201
- variant: "ghost",
202
- size: "icon",
203
- "aria-label": buttonLabel,
179
+ label: buttonLabel,
180
+ timeout,
204
181
  className: cx("environment-variables__copy", className),
205
- ...props,
206
- onClick: handleClick,
207
- children: copied ? /* @__PURE__ */ jsx(CheckIcon, {}) : /* @__PURE__ */ jsx(CopyIcon, {})
208
- }) }), /* @__PURE__ */ jsx(TooltipPortal, { children: /* @__PURE__ */ jsx(TooltipPositioner, { children: /* @__PURE__ */ jsx(TooltipPopup, { children: copied ? "Copied" : buttonLabel }) }) })] });
182
+ onCopy,
183
+ onError,
184
+ onClick
185
+ });
209
186
  }
210
187
  function EnvironmentVariableRequired({ className, children, ref, ...props }) {
211
188
  return /* @__PURE__ */ jsx(Badge, {
@@ -1,25 +1,11 @@
1
1
  import { t as cx } from "../class-names-9UtZwb0J.js";
2
+ import { n as mergeRefs } from "../merge-refs-DF_7w2x_.js";
2
3
  import * as React from "react";
3
4
  import { jsx } from "react/jsx-runtime";
4
5
  //#region src/components/Marker.tsx
5
6
  function markerVariants({ variant = "default", className } = {}) {
6
7
  return cx("marker", `marker--${variant ?? "default"}`, className);
7
8
  }
8
- function assignRef(ref, value) {
9
- if (!ref) return;
10
- if (typeof ref === "function") {
11
- ref(value);
12
- return;
13
- }
14
- ref.current = value;
15
- }
16
- function mergeRefs(...refs) {
17
- const activeRefs = refs.filter(Boolean);
18
- if (activeRefs.length === 0) return void 0;
19
- return (value) => {
20
- for (const activeRef of activeRefs) assignRef(activeRef, value);
21
- };
22
- }
23
9
  function isEventHandler(propName, value) {
24
10
  return /^on[A-Z]/.test(propName) && typeof value === "function";
25
11
  }
@@ -1,16 +1,30 @@
1
1
  import { McpServerCard } from "../utils/mcp-server-catalog.js";
2
2
  import * as React from "react";
3
+ import { MCPServer, MCPServersState } from "agents";
3
4
 
4
5
  //#region src/components/McpServerPicker.d.ts
5
6
  interface McpServerPickerProps {
6
7
  /** MCP servers to show in the plus-menu picker. */
7
8
  servers: readonly McpServerCard[];
8
9
  /** Called when the user chooses a server; hosts own OAuth and connection state. */
9
- onConnect: (server: McpServerCard) => void | Promise<void>;
10
+ onConnect?: (server: McpServerCard) => void | Promise<void>;
11
+ /** Upstream Agents SDK MCP state from `getMcpServers()` or `useAgent({ onMcpUpdate })`. */
12
+ mcp?: MCPServersState;
13
+ /** Called when an OAuth server needs user authorization. */
14
+ onAuthorize?: McpServerConnectionAction;
15
+ /** Called when a failed server should retry through an app-owned Agent RPC. */
16
+ onRetry?: McpServerConnectionAction;
17
+ /** Called when a ready/connected server should refresh discovery through an app-owned Agent RPC. */
18
+ onRefresh?: McpServerConnectionAction;
19
+ /** Called when a server transport should close but the stored config should remain. */
20
+ onDisconnect?: McpServerConnectionAction;
10
21
  /** Offset from the plus trigger to the menu, useful for prompt composers. */
11
22
  sideOffset?: number;
23
+ /** Accessible name for the plus trigger. */
24
+ triggerLabel?: string;
12
25
  }
13
- type McpServerPickerItemsProps = Pick<McpServerPickerProps, "servers" | "onConnect">;
26
+ type McpServerConnectionAction = (serverId: string, server: MCPServer) => void | Promise<void>;
27
+ type McpServerPickerItemsProps = Omit<McpServerPickerProps, "sideOffset" | "triggerLabel">;
14
28
  /**
15
29
  * Prompt plus-menu picker for choosing an MCP server and handing connection
16
30
  * work back to the host app.
@@ -18,11 +32,22 @@ type McpServerPickerItemsProps = Pick<McpServerPickerProps, "servers" | "onConne
18
32
  declare function McpServerPicker({
19
33
  servers,
20
34
  onConnect,
21
- sideOffset
35
+ mcp,
36
+ onAuthorize,
37
+ onDisconnect,
38
+ onRefresh,
39
+ onRetry,
40
+ sideOffset,
41
+ triggerLabel
22
42
  }: McpServerPickerProps): React.JSX.Element;
23
43
  declare function McpServerPickerItems({
24
44
  servers,
25
- onConnect
26
- }: McpServerPickerItemsProps): React.JSX.Element | React.JSX.Element[];
45
+ onConnect,
46
+ mcp,
47
+ onAuthorize,
48
+ onDisconnect,
49
+ onRefresh,
50
+ onRetry
51
+ }: McpServerPickerItemsProps): React.JSX.Element;
27
52
  //#endregion
28
- export { McpServerPicker, McpServerPickerItems, McpServerPickerItemsProps, McpServerPickerProps };
53
+ export { McpServerConnectionAction, McpServerPicker, McpServerPickerItems, McpServerPickerItemsProps, McpServerPickerProps };