@mcp-b/react-components 0.7.1 → 0.8.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 (58) hide show
  1. package/dist/{CodeBlock-D9koxDA7.js → CodeBlock-XNQOupQ3.js} +1 -1
  2. package/dist/{FileTree-BdK93Uuu.js → FileTree-wMyZhhHO.js} +1 -1
  3. package/dist/{ModelSelector-MQvK-pNb.js → ModelSelector-9G_-GooI.js} +1 -1
  4. package/dist/{ThinkChatContext-CC94HL4u.d.ts → ThinkChatContext-BLAAb8J5.d.ts} +1 -1
  5. package/dist/components/Activity.js +1 -1
  6. package/dist/components/AgentChat.js +12 -7
  7. package/dist/components/AgentConnection.js +2 -2
  8. package/dist/components/Artifact.js +1 -1
  9. package/dist/components/BrowserLiveView.js +1 -1
  10. package/dist/components/BrowserReplay.js +1 -1
  11. package/dist/components/ChainOfThought.d.ts +1 -1
  12. package/dist/components/ChainOfThought.js +1 -1
  13. package/dist/components/ChatGptSignInScreen.js +2 -2
  14. package/dist/components/CodeBlock.js +1 -1
  15. package/dist/components/Commit.js +1 -1
  16. package/dist/components/ContextMenu.js +1 -1
  17. package/dist/components/Conversation.js +1 -1
  18. package/dist/components/Dialog.js +1 -1
  19. package/dist/components/EnvironmentVariables.js +1 -1
  20. package/dist/components/FileTree.js +1 -1
  21. package/dist/components/McpServerPicker.js +7 -5
  22. package/dist/components/Menubar.js +1 -1
  23. package/dist/components/Message.js +1 -1
  24. package/dist/components/MessageScroller.js +1 -1
  25. package/dist/components/ModelSelector.js +1 -1
  26. package/dist/components/NavigationMenu.js +1 -1
  27. package/dist/components/PromptInput.js +6 -5
  28. package/dist/components/Queue.js +1 -1
  29. package/dist/components/Reasoning.js +1 -1
  30. package/dist/components/Select.js +1 -1
  31. package/dist/components/Sources.js +1 -1
  32. package/dist/components/Stepper.js +1 -1
  33. package/dist/components/Task.js +1 -1
  34. package/dist/components/Terminal.js +4 -3
  35. package/dist/components/TestResults.js +1 -1
  36. package/dist/components/ThinkChat.d.ts +6 -8
  37. package/dist/components/ThinkChatActivity.js +4 -3
  38. package/dist/components/ThinkChatContext.d.ts +1 -1
  39. package/dist/components/ThinkChatToolPanels.js +1 -1
  40. package/dist/components/ThinkChatToolParts.js +4 -4
  41. package/dist/components/ThinkExecutionWorkbench.d.ts +27 -0
  42. package/dist/components/ThinkExecutionWorkbench.js +450 -0
  43. package/dist/components/ThinkFullApp.d.ts +47 -9
  44. package/dist/components/ThinkFullApp.js +155 -72
  45. package/dist/components/ThinkThreadPicker.d.ts +88 -0
  46. package/dist/components/ThinkThreadPicker.js +282 -0
  47. package/dist/components/WebPreview.js +1 -1
  48. package/dist/components/WorkspaceExplorer.js +5 -4
  49. package/dist/components/icons.d.ts +2 -2
  50. package/dist/components/icons.js +2 -2
  51. package/dist/{copy-button-TVhDAroI.js → copy-button-C6JSKtFE.js} +1 -1
  52. package/dist/{icons-BRI54ATJ.d.ts → icons-CbjtbIJK.d.ts} +2 -1
  53. package/dist/{icons-BAlTbWWP.js → icons-D2Q5n5C1.js} +11 -1
  54. package/dist/styles/index.css +1 -0
  55. package/dist/styles/think-full-app.css +439 -26
  56. package/dist/styles/think-thread-picker.css +449 -0
  57. package/dist/utils/mcp-server-catalog.d.ts +5 -2
  58. package/package.json +7 -8
@@ -1,65 +1,114 @@
1
1
  import { t as cx } from "../class-names-9UtZwb0J.js";
2
- import { h as FileIcon, n as ArrowLeftIcon } from "../icons-BAlTbWWP.js";
2
+ import { P as TerminalIcon, h as FileIcon, n as ArrowLeftIcon } from "../icons-D2Q5n5C1.js";
3
3
  import { Button } from "./Button.js";
4
+ import { Tooltip, TooltipPopup, TooltipPortal, TooltipPositioner, TooltipTrigger } from "./Tooltip.js";
5
+ import { ToggleGroup, ToggleGroupItem } from "./ToggleGroup.js";
4
6
  import { WorkspaceExplorer, useWorkspace } from "./WorkspaceExplorer.js";
5
7
  import { ThinkChat, useThinkPendingApprovals } from "./ThinkChat.js";
8
+ import { ThinkExecutionWorkbench } from "./ThinkExecutionWorkbench.js";
9
+ import { ThinkThreadShell } from "./ThinkThreadPicker.js";
6
10
  import * as React from "react";
7
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
11
+ import { jsx, jsxs } from "react/jsx-runtime";
8
12
  //#region src/components/ThinkFullApp.tsx
9
- const filesPanelDefaultWidth = 340;
10
- const filesPanelMinWidth = 300;
11
- const filesPanelMaxWidth = 600;
12
- const filesPanelKeyboardStep = 24;
13
- function clampFilesPanelWidth(width) {
14
- return Math.min(filesPanelMaxWidth, Math.max(filesPanelMinWidth, width));
13
+ const workbenchPanelDefaultWidth = 340;
14
+ const workbenchPanelMinWidth = 300;
15
+ const workbenchPanelMaxWidth = 600;
16
+ const workbenchPanelKeyboardStep = 24;
17
+ function clampWorkbenchPanelWidth(width) {
18
+ return Math.min(workbenchPanelMaxWidth, Math.max(workbenchPanelMinWidth, width));
15
19
  }
16
- function beginFilesPanelResize(event, current, apply) {
20
+ function beginWorkbenchPanelResize(event, current, apply) {
17
21
  event.preventDefault();
18
22
  const startX = event.clientX;
19
23
  const onMove = (move) => {
20
- apply(clampFilesPanelWidth(current - (move.clientX - startX)));
24
+ apply(clampWorkbenchPanelWidth(current - (move.clientX - startX)));
21
25
  };
22
26
  const onUp = () => {
23
27
  window.removeEventListener("pointermove", onMove);
24
28
  window.removeEventListener("pointerup", onUp);
29
+ window.removeEventListener("pointercancel", onUp);
25
30
  document.body.classList.remove("is-resizing-columns");
26
31
  };
27
32
  document.body.classList.add("is-resizing-columns");
28
33
  window.addEventListener("pointermove", onMove);
29
34
  window.addEventListener("pointerup", onUp);
35
+ window.addEventListener("pointercancel", onUp);
30
36
  }
31
- function WorkspacePanel({ onBack, source, root }) {
37
+ function WorkbenchBackButton({ onBack }) {
38
+ return /* @__PURE__ */ jsx(Button, {
39
+ type: "button",
40
+ variant: "ghost",
41
+ color: "neutral",
42
+ size: "icon-sm",
43
+ className: "think-full-app__workspace-back",
44
+ "aria-label": "Show chat",
45
+ onClick: onBack,
46
+ children: /* @__PURE__ */ jsx(ArrowLeftIcon, {})
47
+ });
48
+ }
49
+ function WorkspacePanel({ source, root }) {
32
50
  return /* @__PURE__ */ jsx(WorkspaceExplorer, {
33
51
  className: "think-full-app__workbench",
34
52
  workspace: useWorkspace({
35
53
  source,
36
54
  root
37
- }),
38
- title: onBack ? /* @__PURE__ */ jsxs("span", {
39
- className: "think-full-app__workspace-title",
40
- children: [/* @__PURE__ */ jsx(Button, {
41
- type: "button",
42
- variant: "ghost",
43
- color: "neutral",
44
- size: "icon-sm",
45
- className: "think-full-app__workspace-back",
46
- "aria-label": "Show chat",
47
- onClick: onBack,
48
- children: /* @__PURE__ */ jsx(ArrowLeftIcon, {})
49
- }), /* @__PURE__ */ jsx("span", { children: "Workspace" })]
50
- }) : void 0
55
+ })
51
56
  });
52
57
  }
53
- /** Combines ThinkChat with an optional resizable workspace file explorer shell. */
54
- function ThinkFullApp(props) {
55
- if (!props.agentStub) return /* @__PURE__ */ jsx(ThinkFullAppLayout, { ...props });
56
- return /* @__PURE__ */ jsx(ThinkFullAppWithApprovals, {
57
- ...props,
58
- agentStub: props.agentStub
58
+ function WorkbenchViewItem({ children, label, value }) {
59
+ return /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, { render: /* @__PURE__ */ jsx(ToggleGroupItem, {
60
+ type: "button",
61
+ className: "think-full-app__workbench-view-item",
62
+ value,
63
+ "aria-label": label,
64
+ children
65
+ }) }), /* @__PURE__ */ jsx(TooltipPortal, { children: /* @__PURE__ */ jsx(TooltipPositioner, {
66
+ side: "bottom",
67
+ sideOffset: 6,
68
+ children: /* @__PURE__ */ jsx(TooltipPopup, { children: label })
69
+ }) })] });
70
+ }
71
+ function WorkbenchViewSwitch({ value, onValueChange }) {
72
+ return /* @__PURE__ */ jsxs(ToggleGroup, {
73
+ className: "think-full-app__workbench-view-switch",
74
+ size: "sm",
75
+ value: [value],
76
+ "aria-label": "Workbench views",
77
+ onValueChange: (nextValue) => {
78
+ const [next] = nextValue;
79
+ if (next) onValueChange(next);
80
+ },
81
+ children: [/* @__PURE__ */ jsx(WorkbenchViewItem, {
82
+ value: "files",
83
+ label: "Files",
84
+ children: /* @__PURE__ */ jsx(FileIcon, {})
85
+ }), /* @__PURE__ */ jsx(WorkbenchViewItem, {
86
+ value: "execution",
87
+ label: "Execution",
88
+ children: /* @__PURE__ */ jsx(TerminalIcon, {})
89
+ })]
90
+ });
91
+ }
92
+ function WorkbenchPanel({ executionSource, view, workspace, workspaceRoot }) {
93
+ if (workspace) return /* @__PURE__ */ jsx("div", {
94
+ className: "think-full-app__workbench-panel",
95
+ "data-view": view,
96
+ children: view === "files" ? /* @__PURE__ */ jsx(WorkspacePanel, {
97
+ source: workspace,
98
+ root: workspaceRoot
99
+ }) : /* @__PURE__ */ jsx(ThinkExecutionWorkbench, {
100
+ source: executionSource,
101
+ title: "Execution"
102
+ })
103
+ });
104
+ return /* @__PURE__ */ jsx(ThinkExecutionWorkbench, {
105
+ source: executionSource,
106
+ title: "Execution"
59
107
  });
60
108
  }
61
- function ThinkFullAppWithApprovals({ agentStub, chat, messages, ...props }) {
62
- const approvals = useThinkPendingApprovals(agentStub, `${chat.messages.length}:${chat.status}`);
109
+ /** Combines ThinkChat with an optional resizable workbench shell. */
110
+ function ThinkFullApp({ agent, chat, className, defaultWorkbenchView, defaultThreadSidebarOpen, messages, onThreadSidebarOpenChange, onWorkbenchViewChange, ref, style, threadSidebar, threadSidebarOpen, workbenchView, workspace, workspaceRoot, ...props }) {
111
+ const approvals = useThinkPendingApprovals(agent.stub, `${chat.messages.length}:${chat.status}`);
63
112
  const resolvedMessages = React.useMemo(() => ({
64
113
  ...messages,
65
114
  executionApprovals: messages?.executionApprovals ?? approvals.executionApprovals,
@@ -69,44 +118,64 @@ function ThinkFullAppWithApprovals({ agentStub, chat, messages, ...props }) {
69
118
  approvals.pendingApprovals,
70
119
  messages
71
120
  ]);
72
- return /* @__PURE__ */ jsx(ThinkFullAppLayout, {
73
- ...props,
74
- chat,
75
- messages: resolvedMessages
76
- });
77
- }
78
- function ThinkFullAppLayout({ chat, className, messages, ref, style, workspace, workspaceRoot, ...props }) {
79
121
  const hasWorkspace = workspace !== void 0;
80
122
  const [mobileView, setMobileView] = React.useState("chat");
81
- const [filesPanelWidth, setFilesPanelWidth] = React.useState(filesPanelDefaultWidth);
82
- const activeMobileView = hasWorkspace && mobileView === "files" ? "files" : "chat";
83
- const isMobileFilesView = activeMobileView === "files";
123
+ const [innerWorkbenchView, setInnerWorkbenchView] = React.useState(defaultWorkbenchView ?? "files");
124
+ const [workbenchPanelWidth, setWorkbenchPanelWidth] = React.useState(workbenchPanelDefaultWidth);
125
+ const activeMobileView = mobileView === "workbench" ? "workbench" : "chat";
126
+ const isMobileWorkbenchView = activeMobileView === "workbench";
127
+ const activeWorkbenchView = hasWorkspace ? workbenchView ?? innerWorkbenchView : "execution";
128
+ const showShellTopbar = hasWorkspace || isMobileWorkbenchView;
84
129
  const rootStyle = {
85
130
  ...style,
86
- "--think-full-app-files-w": `${filesPanelWidth}px`
131
+ "--think-full-app-workbench-w": `${workbenchPanelWidth}px`
87
132
  };
88
- const resizeFilesPanelBy = (delta) => {
89
- setFilesPanelWidth((current) => clampFilesPanelWidth(current + delta));
133
+ const resizeWorkbenchPanelBy = (delta) => {
134
+ setWorkbenchPanelWidth((current) => clampWorkbenchPanelWidth(current + delta));
90
135
  };
91
- return /* @__PURE__ */ jsxs("div", {
136
+ const setWorkbenchView = React.useCallback((next) => {
137
+ if (!hasWorkspace) return;
138
+ if (workbenchView === void 0) setInnerWorkbenchView(next);
139
+ onWorkbenchViewChange?.(next);
140
+ }, [
141
+ hasWorkspace,
142
+ onWorkbenchViewChange,
143
+ workbenchView
144
+ ]);
145
+ const app = /* @__PURE__ */ jsxs("div", {
92
146
  ref,
93
147
  className: cx("think-full-app", className),
94
148
  "data-has-files": hasWorkspace ? "true" : "false",
149
+ "data-has-thread-sidebar": threadSidebar ? "true" : "false",
150
+ "data-has-workbench": "true",
151
+ "data-has-workbench-topbar": hasWorkspace ? "true" : "false",
95
152
  "data-mobile-view": activeMobileView,
96
153
  style: rootStyle,
97
154
  ...props,
98
155
  children: [
99
- hasWorkspace && !isMobileFilesView ? /* @__PURE__ */ jsx("header", {
156
+ showShellTopbar ? /* @__PURE__ */ jsxs("div", {
157
+ className: "think-full-app__topbar",
158
+ role: "toolbar",
159
+ "aria-label": "Workbench controls",
160
+ "data-mobile-only": hasWorkspace ? void 0 : "true",
161
+ children: [/* @__PURE__ */ jsx(WorkbenchBackButton, { onBack: () => setMobileView("chat") }), hasWorkspace ? /* @__PURE__ */ jsx(WorkbenchViewSwitch, {
162
+ value: activeWorkbenchView,
163
+ onValueChange: setWorkbenchView
164
+ }) : null]
165
+ }) : null,
166
+ !isMobileWorkbenchView ? /* @__PURE__ */ jsx("div", {
100
167
  className: "think-full-app__mobile-header",
168
+ role: "toolbar",
169
+ "aria-label": "Workbench",
101
170
  children: /* @__PURE__ */ jsx(Button, {
102
171
  type: "button",
103
172
  variant: "ghost",
104
173
  color: "neutral",
105
174
  size: "icon-sm",
106
175
  className: "think-full-app__mobile-action",
107
- "aria-label": "Show files",
108
- onClick: () => setMobileView("files"),
109
- children: /* @__PURE__ */ jsx(FileIcon, {})
176
+ "aria-label": hasWorkspace ? "Show workbench" : "Show execution",
177
+ onClick: () => setMobileView("workbench"),
178
+ children: hasWorkspace ? /* @__PURE__ */ jsx(FileIcon, {}) : /* @__PURE__ */ jsx(TerminalIcon, {})
110
179
  })
111
180
  }) : null,
112
181
  /* @__PURE__ */ jsx("section", {
@@ -118,12 +187,16 @@ function ThinkFullAppLayout({ chat, className, messages, ref, style, workspace,
118
187
  className: "think-full-app__chat-inner",
119
188
  children: [/* @__PURE__ */ jsx(ThinkChat.Provider, {
120
189
  chat,
121
- children: /* @__PURE__ */ jsx(ThinkChat.Messages, { ...messages })
190
+ children: /* @__PURE__ */ jsx(ThinkChat.Messages, { ...resolvedMessages })
122
191
  }), chat.error ? /* @__PURE__ */ jsxs("div", {
123
192
  className: "think-full-app__error",
124
193
  role: "alert",
125
- children: [chat.error.message, /* @__PURE__ */ jsx("button", {
194
+ children: [chat.error.message, /* @__PURE__ */ jsx(Button, {
126
195
  type: "button",
196
+ variant: "link",
197
+ color: "neutral",
198
+ size: "xs",
199
+ className: "think-full-app__error-dismiss",
127
200
  onClick: () => chat.clearError(),
128
201
  children: "Dismiss"
129
202
  })]
@@ -131,45 +204,55 @@ function ThinkFullAppLayout({ chat, className, messages, ref, style, workspace,
131
204
  })
132
205
  })
133
206
  }),
134
- workspace ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("button", {
207
+ /* @__PURE__ */ jsx("button", {
135
208
  type: "button",
136
209
  role: "separator",
137
- "aria-label": "Resize file panel",
210
+ "aria-label": "Resize workbench panel",
138
211
  "aria-orientation": "vertical",
139
- "aria-valuemin": filesPanelMinWidth,
140
- "aria-valuemax": filesPanelMaxWidth,
141
- "aria-valuenow": filesPanelWidth,
212
+ "aria-valuemin": workbenchPanelMinWidth,
213
+ "aria-valuemax": workbenchPanelMaxWidth,
214
+ "aria-valuenow": workbenchPanelWidth,
142
215
  className: "think-full-app__resizer",
143
- onPointerDown: (event) => beginFilesPanelResize(event, filesPanelWidth, setFilesPanelWidth),
216
+ onPointerDown: (event) => beginWorkbenchPanelResize(event, workbenchPanelWidth, setWorkbenchPanelWidth),
144
217
  onKeyDown: (event) => {
145
218
  if (event.key === "ArrowLeft") {
146
219
  event.preventDefault();
147
- resizeFilesPanelBy(filesPanelKeyboardStep);
220
+ resizeWorkbenchPanelBy(workbenchPanelKeyboardStep);
148
221
  } else if (event.key === "ArrowRight") {
149
222
  event.preventDefault();
150
- resizeFilesPanelBy(-24);
223
+ resizeWorkbenchPanelBy(-24);
151
224
  } else if (event.key === "Home") {
152
225
  event.preventDefault();
153
- setFilesPanelWidth(filesPanelMinWidth);
226
+ setWorkbenchPanelWidth(workbenchPanelMinWidth);
154
227
  } else if (event.key === "End") {
155
228
  event.preventDefault();
156
- setFilesPanelWidth(filesPanelMaxWidth);
229
+ setWorkbenchPanelWidth(workbenchPanelMaxWidth);
157
230
  }
158
231
  }
159
- }), /* @__PURE__ */ jsx("aside", {
232
+ }),
233
+ /* @__PURE__ */ jsx("aside", {
160
234
  className: "think-full-app__aside",
161
- "aria-label": "File explorer",
235
+ "aria-label": "Workbench",
162
236
  children: /* @__PURE__ */ jsx("div", {
163
- className: "think-full-app__files-slot",
164
- children: /* @__PURE__ */ jsx(WorkspacePanel, {
165
- source: workspace,
166
- root: workspaceRoot,
167
- onBack: () => setMobileView("chat")
237
+ className: "think-full-app__workbench-slot",
238
+ children: /* @__PURE__ */ jsx(WorkbenchPanel, {
239
+ executionSource: agent.stub,
240
+ workspace,
241
+ workspaceRoot,
242
+ view: activeWorkbenchView
168
243
  })
169
244
  })
170
- })] }) : null
245
+ })
171
246
  ]
172
247
  });
248
+ if (!threadSidebar) return app;
249
+ return /* @__PURE__ */ jsx(ThinkThreadShell, {
250
+ sidebar: threadSidebar,
251
+ sidebarOpen: threadSidebarOpen,
252
+ defaultSidebarOpen: defaultThreadSidebarOpen,
253
+ onSidebarOpenChange: onThreadSidebarOpenChange,
254
+ children: app
255
+ });
173
256
  }
174
257
  //#endregion
175
- export { ThinkFullApp };
258
+ export { ThinkExecutionWorkbench, ThinkFullApp };
@@ -0,0 +1,88 @@
1
+ import * as React from "react";
2
+
3
+ //#region src/components/ThinkThreadPicker.d.ts
4
+ interface ThinkThreadItem {
5
+ /** Stable child-agent/thread id passed back to the app's route state. */
6
+ id: string;
7
+ /** Human-readable thread title, usually generated by the parent Think agent. */
8
+ title: string;
9
+ /** Optional parent-owned preview for apps that render their own richer sidebar. */
10
+ lastMessagePreview?: string;
11
+ /** Timestamp from the parent registry or metadata row. `updatedAt` wins over `createdAt`. */
12
+ createdAt?: Date | number;
13
+ /** Timestamp from parent-owned thread metadata when available. */
14
+ updatedAt?: Date | number;
15
+ /** Preformatted timestamp label when the app already has one, such as "14m". */
16
+ updatedAtLabel?: string;
17
+ /** Optional upstream/app status string. The picker only displays it; it does not derive it. */
18
+ status?: string;
19
+ /** Human label for `status` when the raw upstream value is not user-facing. */
20
+ statusLabel?: string;
21
+ }
22
+ interface ThinkThreadPickerProps extends Omit<React.HTMLAttributes<HTMLElement>, "onSelect" | "title"> {
23
+ /** Threads from the parent agent, already sorted in the order the app wants to show. */
24
+ threads: readonly ThinkThreadItem[];
25
+ /** Selected child-agent/thread id. */
26
+ selectedId?: string;
27
+ /** Called when a thread row is selected; callers route this into `useAgent({ sub })`. */
28
+ onSelect: (id: string) => void;
29
+ /** Optional parent-agent create action, usually `parent.stub.createThread()`. */
30
+ onCreate?: () => void | Promise<void>;
31
+ /** Visible heading for the roster. */
32
+ title?: React.ReactNode;
33
+ /** Accessible label for the list navigation. */
34
+ "aria-label"?: string;
35
+ }
36
+ interface ThinkThreadShellProps extends React.HTMLAttributes<HTMLDivElement> {
37
+ /** Thread picker or app-owned sidebar shown beside the selected child shell. */
38
+ sidebar: React.ReactNode;
39
+ /** Whether the thread drawer is open. Omit for internal state. */
40
+ sidebarOpen?: boolean;
41
+ /** Initial thread drawer state when `sidebarOpen` is uncontrolled. */
42
+ defaultSidebarOpen?: boolean;
43
+ /** Called when the thread drawer is opened or closed. */
44
+ onSidebarOpenChange?: (open: boolean) => void;
45
+ }
46
+ /**
47
+ * Thread roster UI for sub-agent chat apps.
48
+ *
49
+ * This component does not call Think or Cloudflare RPC methods directly. Feed
50
+ * it from the parent agent's roster method, then route `onSelect` into the
51
+ * child `useAgent({ sub: [...] })` name. Keep backend contract notes beside the
52
+ * parent Think agent because `listThreads()`/`createThread()` are app-owned.
53
+ */
54
+ declare function ThinkThreadPicker({
55
+ threads,
56
+ selectedId,
57
+ onSelect,
58
+ onCreate,
59
+ className,
60
+ title,
61
+ "aria-label": ariaLabel,
62
+ ref,
63
+ ...props
64
+ }: ThinkThreadPickerProps & {
65
+ ref?: React.Ref<HTMLElement>;
66
+ }): React.JSX.Element;
67
+ /**
68
+ * Layout wrapper for a thread picker beside one selected `ThinkFullApp`.
69
+ *
70
+ * Mobile keeps the drawer at about 80% width so the selected chat remains
71
+ * visible as a preview. It only owns layout; callers still own the parent agent,
72
+ * selected child agent, chat hook, and shared workspace.
73
+ */
74
+ declare function ThinkThreadShell({
75
+ sidebar,
76
+ sidebarOpen,
77
+ defaultSidebarOpen,
78
+ onSidebarOpenChange,
79
+ className,
80
+ children,
81
+ ref,
82
+ style,
83
+ ...props
84
+ }: ThinkThreadShellProps & {
85
+ ref?: React.Ref<HTMLDivElement>;
86
+ }): React.JSX.Element;
87
+ //#endregion
88
+ export { ThinkThreadItem, ThinkThreadPicker, ThinkThreadPickerProps, ThinkThreadShell, ThinkThreadShellProps };