@mcp-b/react-components 0.39.0 → 0.40.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 (94) hide show
  1. package/dist/{CodeBlock-DO4Hdu1R.js → CodeBlock-CWk1FVtm.js} +1 -1
  2. package/dist/{FileTree-DbQMpvxV.js → FileTree-xqHYBw4g.js} +1 -1
  3. package/dist/{ToggleGroup-BrQZOQn_.d.ts → ToggleGroup-_pQMyHGM.d.ts} +1 -1
  4. package/dist/{WorkspaceFileView-D0r7xnq5.js → WorkspaceFileView-Lab3om3F.js} +3 -3
  5. package/dist/components/agents-sdk/AgentActivity.js +1 -1
  6. package/dist/components/agents-sdk/AgentActivityPreview.js +2 -2
  7. package/dist/components/agents-sdk/AgentChat.js +2 -2
  8. package/dist/components/agents-sdk/BrowserLiveView.js +2 -2
  9. package/dist/components/agents-sdk/BrowserReplay.js +1 -1
  10. package/dist/components/agents-sdk/BrowserRunPanel.d.ts +72 -25
  11. package/dist/components/agents-sdk/BrowserRunPanel.js +110 -63
  12. package/dist/components/agents-sdk/McpConnectionRequest.js +1 -1
  13. package/dist/components/agents-sdk/McpPluginCatalog.js +2 -2
  14. package/dist/components/agents-sdk/McpServerPicker.js +1 -1
  15. package/dist/components/agents-sdk/ModelSelector.js +2 -2
  16. package/dist/components/agents-sdk/PromptInputCommands.js +1 -1
  17. package/dist/components/agents-sdk/SubagentRunIndicator.js +1 -1
  18. package/dist/components/agents-sdk/SubagentRunSelector.js +1 -1
  19. package/dist/components/agents-sdk/ThinkChat.js +1 -1
  20. package/dist/components/agents-sdk/ThinkChatActivity.js +1 -1
  21. package/dist/components/agents-sdk/ThinkChatToolPanels.js +1 -1
  22. package/dist/components/agents-sdk/ThinkExecutionDetail.js +1 -1
  23. package/dist/components/agents-sdk/ThinkExecutionStatus.js +1 -1
  24. package/dist/components/agents-sdk/ThinkExecutionWorkbench.js +2 -2
  25. package/dist/components/agents-sdk/ThinkFullApp.js +5 -5
  26. package/dist/components/agents-sdk/ThinkFullAppViewSwitch.d.ts +1 -1
  27. package/dist/components/agents-sdk/ThinkFullAppViewSwitch.js +1 -1
  28. package/dist/components/agents-sdk/ThinkRoutineBrowser.js +1 -1
  29. package/dist/components/agents-sdk/ThinkRoutineDetail.js +1 -1
  30. package/dist/components/agents-sdk/ThinkRoutineForm.js +1 -1
  31. package/dist/components/agents-sdk/ThinkRoutineLibrary.js +2 -2
  32. package/dist/components/agents-sdk/ThinkThreadPicker.js +2 -2
  33. package/dist/components/agents-sdk/WorkspaceBrowser.js +1 -1
  34. package/dist/components/agents-sdk/WorkspaceExplorer.js +1 -1
  35. package/dist/components/agents-sdk/WorkspaceFileView.js +1 -1
  36. package/dist/components/agents-sdk/WorkspaceHeader.js +1 -1
  37. package/dist/components/agents-sdk/WorkspaceMountManager.js +1 -1
  38. package/dist/components/ai-sdk/Activity.js +1 -1
  39. package/dist/components/ai-sdk/AgentChatStartScreen.js +1 -1
  40. package/dist/components/ai-sdk/Approval.js +1 -1
  41. package/dist/components/ai-sdk/Artifact.js +1 -1
  42. package/dist/components/ai-sdk/ChainOfThought.d.ts +1 -1
  43. package/dist/components/ai-sdk/ChainOfThought.js +1 -1
  44. package/dist/components/ai-sdk/Checkpoint.js +1 -1
  45. package/dist/components/ai-sdk/CodeBlock.js +1 -1
  46. package/dist/components/ai-sdk/Conversation.js +1 -1
  47. package/dist/components/ai-sdk/Goal.js +1 -1
  48. package/dist/components/ai-sdk/MediaPreviewCard.js +1 -1
  49. package/dist/components/ai-sdk/Message.js +1 -1
  50. package/dist/components/ai-sdk/MessageScroller.js +1 -1
  51. package/dist/components/ai-sdk/MessageScrollerVirtual.js +1 -1
  52. package/dist/components/ai-sdk/Plan.js +1 -1
  53. package/dist/components/ai-sdk/PromptInput.js +1 -1
  54. package/dist/components/ai-sdk/Queue.js +1 -1
  55. package/dist/components/ai-sdk/Reasoning.js +1 -1
  56. package/dist/components/ai-sdk/Sources.js +1 -1
  57. package/dist/components/ai-sdk/Task.js +1 -1
  58. package/dist/components/extension/ChatGptSignInScreen.d.ts +21 -10
  59. package/dist/components/extension/ChatGptSignInScreen.js +42 -34
  60. package/dist/components/extension/CodexModelSelector.js +1 -1
  61. package/dist/components/extension/ConversationTabPicker.js +1 -1
  62. package/dist/components/foundations/Checkbox.js +1 -1
  63. package/dist/components/foundations/ContextMenu.js +1 -1
  64. package/dist/components/foundations/Menubar.js +1 -1
  65. package/dist/components/foundations/SearchField.js +1 -1
  66. package/dist/components/foundations/Select.js +1 -1
  67. package/dist/components/foundations/Stepper.js +1 -1
  68. package/dist/components/foundations/Toast.js +1 -1
  69. package/dist/components/foundations/ToggleGroup.d.ts +1 -1
  70. package/dist/components/foundations/ToggleGroup.js +1 -1
  71. package/dist/components/foundations/icons.d.ts +2 -2
  72. package/dist/components/foundations/icons.js +2 -2
  73. package/dist/components/general-purpose/Commit.js +2 -2
  74. package/dist/components/general-purpose/EnvironmentVariables.js +2 -2
  75. package/dist/components/general-purpose/FileTree.js +1 -1
  76. package/dist/components/general-purpose/PricingBillingToggle.js +1 -1
  77. package/dist/components/general-purpose/PricingPlanCard.js +1 -1
  78. package/dist/components/general-purpose/PricingUsageCalculator.js +1 -1
  79. package/dist/components/general-purpose/ResponsiveSidebarShell.js +1 -1
  80. package/dist/components/general-purpose/SetupChecklist.js +1 -1
  81. package/dist/components/general-purpose/Terminal.js +2 -2
  82. package/dist/components/general-purpose/TestResults.js +1 -1
  83. package/dist/components/general-purpose/ThemeModeControl.js +1 -1
  84. package/dist/components/general-purpose/WebPreview.js +1 -1
  85. package/dist/components/nanites/AgentConnection.js +2 -2
  86. package/dist/components/nanites/AgentToolDetail.js +4 -4
  87. package/dist/{copy-button-4YvddK4e.js → copy-button-Bc7jsYv_.js} +1 -1
  88. package/dist/{icons-BGZ916hb.d.ts → icons-DwgNir1Q.d.ts} +6 -1
  89. package/dist/{icons-B4mGvCvc.js → icons-MmIXciMO.js} +3 -2
  90. package/dist/styles/browser-run-panel.css +3 -1
  91. package/dist/styles/chatgpt-sign-in-screen.css +6 -0
  92. package/dist/styles/think-full-app.css +8 -0
  93. package/package.json +2 -2
  94. package/dist/{ThinkChat-BES_3Mb-.js → ThinkChat-DkA4Wr71.js} +1 -1
@@ -1,6 +1,6 @@
1
1
  import { t as cx } from "./class-names-BiMDVpUo.js";
2
2
  import { Select } from "./components/foundations/Select.js";
3
- import { t as CopyButton } from "./copy-button-4YvddK4e.js";
3
+ import { t as CopyButton } from "./copy-button-Bc7jsYv_.js";
4
4
  import * as React from "react";
5
5
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
6
  import { createHighlighter } from "shiki";
@@ -1,5 +1,5 @@
1
1
  import { t as cx } from "./class-names-BiMDVpUo.js";
2
- import { C as FileIcon, T as FolderOpenIcon, m as ChevronRightIcon, w as FolderIcon } from "./icons-B4mGvCvc.js";
2
+ import { C as FileIcon, T as FolderOpenIcon, m as ChevronRightIcon, w as FolderIcon } from "./icons-MmIXciMO.js";
3
3
  import { t as NavigationLink } from "./navigation-link-kqMa81v5.js";
4
4
  import * as React from "react";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -1,7 +1,7 @@
1
1
  import { r as ToggleVariantsOptions } from "./Toggle-DLrIf5YH.js";
2
2
  import * as React from "react";
3
- import { ToggleGroup } from "@base-ui/react/toggle-group";
4
3
  import { Toggle } from "@base-ui/react/toggle";
4
+ import { ToggleGroup } from "@base-ui/react/toggle-group";
5
5
 
6
6
  //#region src/components/foundations/ToggleGroup.d.ts
7
7
  type ToggleGroupSize = ToggleVariantsOptions["size"];
@@ -1,10 +1,10 @@
1
- import { A as MaximizeIcon, d as CheckIcon, h as CodeIcon, r as ArrowLeftIcon, tt as WarningIcon, x as EyeIcon, y as DownloadIcon } from "./icons-B4mGvCvc.js";
1
+ import { d as CheckIcon, h as CodeIcon, j as MaximizeIcon, nt as WarningIcon, r as ArrowLeftIcon, x as EyeIcon, y as DownloadIcon } from "./icons-MmIXciMO.js";
2
2
  import { r as formatClock } from "./format-DB2mX9DA.js";
3
- import { a as CodeBlockCopyButton, i as CodeBlockContent, r as CodeBlockContainer, t as CodeBlock } from "./CodeBlock-DO4Hdu1R.js";
3
+ import { a as CodeBlockCopyButton, i as CodeBlockContent, r as CodeBlockContainer, t as CodeBlock } from "./CodeBlock-CWk1FVtm.js";
4
+ import { AppTopBar } from "./components/general-purpose/AppTopBar.js";
4
5
  import { inferWorkspaceLanguage, inferWorkspaceMedia, isWorkspaceMarkdownPath, isWorkspaceSkillPath, parseWorkspaceSkill } from "./components/agents-sdk/WorkspaceFile.js";
5
6
  import { c as useWorkspaceNavigationContext, s as useWorkspaceNavigationRestoration } from "./WorkspaceLink-DtH66bAY.js";
6
7
  import { n as createWorkspaceRehypePlugins, t as WorkspaceMessageResponse } from "./WorkspaceMessageResponse-CJCmGvTx.js";
7
- import { AppTopBar } from "./components/general-purpose/AppTopBar.js";
8
8
  import { WorkspaceHeader } from "./components/agents-sdk/WorkspaceHeader.js";
9
9
  import * as React from "react";
10
10
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -1,5 +1,5 @@
1
1
  import { inferFaviconUrl } from "../../utils/favicon.js";
2
- import { $ as TerminalIcon, B as PencilIcon, C as FileIcon, F as MonitorIcon, G as SearchIcon, O as InfoIcon, k as LinkIcon, nt as WrenchIcon, tt as WarningIcon } from "../../icons-B4mGvCvc.js";
2
+ import { A as LinkIcon, C as FileIcon, I as MonitorIcon, K as SearchIcon, O as InfoIcon, V as PencilIcon, et as TerminalIcon, nt as WarningIcon, rt as WrenchIcon } from "../../icons-MmIXciMO.js";
3
3
  import * as React from "react";
4
4
  import { jsx } from "react/jsx-runtime";
5
5
  //#region src/components/agents-sdk/AgentActivity.tsx
@@ -1,10 +1,10 @@
1
1
  import { t as cx } from "../../class-names-BiMDVpUo.js";
2
- import { C as FileIcon, J as SpinnerIcon, j as McpIcon, rt as XIcon, tt as WarningIcon } from "../../icons-B4mGvCvc.js";
2
+ import { C as FileIcon, M as McpIcon, Y as SpinnerIcon, it as XIcon, nt as WarningIcon } from "../../icons-MmIXciMO.js";
3
3
  import { ActivityHeader } from "../ai-sdk/Activity.js";
4
4
  import { Button } from "../foundations/Button.js";
5
5
  import { t as NavigationLink } from "../../navigation-link-kqMa81v5.js";
6
- import { AgentActivityFavicon, AgentActivityIcon } from "./AgentActivity.js";
7
6
  import { AppIcon } from "../foundations/AppIcon.js";
7
+ import { AgentActivityFavicon, AgentActivityIcon } from "./AgentActivity.js";
8
8
  import "react";
9
9
  import { jsx, jsxs } from "react/jsx-runtime";
10
10
  //#region src/components/agents-sdk/AgentActivityPreview.tsx
@@ -1,6 +1,6 @@
1
1
  import { t as cx } from "../../class-names-BiMDVpUo.js";
2
2
  import { ExpansionStateProvider } from "../ai-sdk/ExpansionState.js";
3
- import { B as PencilIcon, H as PlusIcon, J as SpinnerIcon, L as MoveToFrontIcon, U as QueueIcon, W as RefreshIcon, et as TrashIcon, t as ArchiveIcon } from "../../icons-B4mGvCvc.js";
3
+ import { G as RefreshIcon, R as MoveToFrontIcon, U as PlusIcon, V as PencilIcon, W as QueueIcon, Y as SpinnerIcon, t as ArchiveIcon, tt as TrashIcon } from "../../icons-MmIXciMO.js";
4
4
  import { Button } from "../foundations/Button.js";
5
5
  import { AgentChatMessageEditor } from "../ai-sdk/AgentChatMessageEditor.js";
6
6
  import { IconButton } from "../foundations/IconButton.js";
@@ -10,7 +10,7 @@ import { AgentChatStartScreen } from "../ai-sdk/AgentChatStartScreen.js";
10
10
  import { Message, MessageAction, MessageActions } from "../ai-sdk/Message.js";
11
11
  import { AgentMessageParts } from "../ai-sdk/AgentMessageParts.js";
12
12
  import { Marker, MarkerContent } from "../foundations/Marker.js";
13
- import { t as CopyButton } from "../../copy-button-4YvddK4e.js";
13
+ import { t as CopyButton } from "../../copy-button-Bc7jsYv_.js";
14
14
  import { Context, ContextContent, ContextContentBody, ContextContentHeader, ContextTrigger, getContextUsage, getContextUsedTokens } from "../ai-sdk/Context.js";
15
15
  import { VirtualMessageScroller } from "../ai-sdk/MessageScrollerVirtual.js";
16
16
  import { QueueItem, QueueItemActions, QueueItemContent } from "../ai-sdk/Queue.js";
@@ -1,9 +1,9 @@
1
1
  import { t as cx } from "../../class-names-BiMDVpUo.js";
2
- import { A as MaximizeIcon, J as SpinnerIcon } from "../../icons-B4mGvCvc.js";
2
+ import { Y as SpinnerIcon, j as MaximizeIcon } from "../../icons-MmIXciMO.js";
3
3
  import { Button } from "../foundations/Button.js";
4
4
  import { Dialog } from "../foundations/Dialog.js";
5
- import { TransitionSurface } from "../foundations/TransitionSurface.js";
6
5
  import { StatusPill } from "../foundations/StatusPill.js";
6
+ import { TransitionSurface } from "../foundations/TransitionSurface.js";
7
7
  import * as React from "react";
8
8
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9
9
  //#region src/components/agents-sdk/BrowserLiveView.tsx
@@ -1,5 +1,5 @@
1
1
  import { t as cx } from "../../class-names-BiMDVpUo.js";
2
- import { V as PlayIcon, z as PauseIcon } from "../../icons-B4mGvCvc.js";
2
+ import { B as PauseIcon, H as PlayIcon } from "../../icons-MmIXciMO.js";
3
3
  import { IconButton } from "../foundations/IconButton.js";
4
4
  import { r as formatClock } from "../../format-DB2mX9DA.js";
5
5
  import { EmptyState } from "../foundations/EmptyState.js";
@@ -2,7 +2,26 @@ import * as React from "react";
2
2
  import { BrowserLiveView } from "agents/browser";
3
3
 
4
4
  //#region src/components/agents-sdk/BrowserRunPanel.d.ts
5
- interface BrowserRunPanelProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "children"> {
5
+ /**
6
+ * One entry of the drawn tab strip. The panel synthesizes browser chrome
7
+ * around content Chrome itself never paints, so a tab is whatever record of a
8
+ * page the host holds — a Browser Run target, a claimed extension tab — cut
9
+ * down to the identity and words the strip needs.
10
+ */
11
+ interface BrowserRunPanelTab {
12
+ /** Stable identity; the strip's selection value. Hosts stringify their own ids. */
13
+ id: string;
14
+ title?: string;
15
+ url?: string;
16
+ }
17
+ interface BrowserRunPanelCommonProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "children"> {
18
+ /** Error from the host's browser session or transport. */
19
+ error?: React.ReactNode;
20
+ /** Panel heading. */
21
+ label?: React.ReactNode;
22
+ ref?: React.Ref<HTMLDivElement>;
23
+ }
24
+ interface BrowserRunPanelHostedProps extends BrowserRunPanelCommonProps {
6
25
  /** Host-side Browser Run Live View data from `connector.liveView()`. */
7
26
  liveView?: BrowserLiveView;
8
27
  /** Refreshes the Live View URL before it expires. */
@@ -11,36 +30,64 @@ interface BrowserRunPanelProps extends Omit<React.HTMLAttributes<HTMLDivElement>
11
30
  onCloseSession?: () => void | Promise<void>;
12
31
  /** True while the app is fetching Live View data. */
13
32
  loading?: boolean;
14
- /** Error from the app-owned browser session fetch/refresh path. */
15
- error?: React.ReactNode;
16
- /** Panel heading. */
17
- label?: React.ReactNode;
18
33
  /** Empty state shown when there is no shared browser session. */
19
34
  empty?: React.ReactNode;
20
35
  /** Fallback passed through to `BrowserLiveView` after URL expiry/failure. */
21
36
  fallback?: React.ReactNode;
37
+ children?: never;
38
+ tabs?: never;
39
+ selectedTabId?: never;
40
+ onSelectTab?: never;
41
+ url?: never;
42
+ onOpenUrl?: never;
43
+ urlPlaceholder?: never;
44
+ urlDisabled?: never;
45
+ urlLabel?: never;
46
+ navigation?: never;
47
+ }
48
+ interface BrowserRunPanelStreamedProps extends BrowserRunPanelCommonProps {
49
+ /**
50
+ * The host's own browser surface — typically a `BrowserLiveView` carrying a
51
+ * host-fed stream. The panel frames it with the drawn tab strip and address
52
+ * bar; the host keeps everything transport: media, input, reconnection.
53
+ */
54
+ children: React.ReactNode;
55
+ /** The drawn tab strip; it renders only with more than one entry. */
56
+ tabs?: readonly BrowserRunPanelTab[];
57
+ /** Controlled selection over `tabs`; null selects nothing. */
58
+ selectedTabId?: string | null;
59
+ /** A viewer picked a tab it is not watching; the host grants or ignores it. */
60
+ onSelectTab?: (tabId: string) => void;
61
+ /** Address bar value: the streamed page's current URL. */
62
+ url?: string;
63
+ /** Commits an address-bar entry. Absent, the address bar is read-only. */
64
+ onOpenUrl?: (url: string) => void;
65
+ urlPlaceholder?: string;
66
+ urlDisabled?: boolean;
67
+ /** Accessible name for the address input. */
68
+ urlLabel?: string;
69
+ /** Navigation controls before the address input, e.g. Back and Reload. */
70
+ navigation?: React.ReactNode;
71
+ liveView?: never;
72
+ onRefresh?: never;
73
+ onCloseSession?: never;
74
+ loading?: never;
75
+ empty?: never;
76
+ fallback?: never;
22
77
  }
78
+ type BrowserRunPanelProps = BrowserRunPanelHostedProps | BrowserRunPanelStreamedProps;
23
79
  /**
24
- * Right-side Browser Run panel for `ThinkFullApp.workbenchPanels`.
80
+ * Browser panel chrome — drawn tab strip, address bar, framed body — for
81
+ * browser surfaces Chrome itself never paints.
25
82
  *
26
- * The app owns `createBrowserRuntime()`, `connector.liveView()`, polling, and
27
- * session cleanup. This component only renders upstream `BrowserLiveView`
28
- * data and calls app-provided refresh/close callbacks.
83
+ * Two hosts fill it in. A Browser Run host passes upstream `BrowserLiveView`
84
+ * data from `connector.liveView()`, and the panel derives tabs, address, and
85
+ * an embedded live view itself, calling app-provided refresh/close callbacks.
86
+ * A streaming host instead passes `children` — its own live surface — with
87
+ * the tab strip, address bar, and navigation controlled from the host's own
88
+ * records, because a remote screencast carries only page pixels and every
89
+ * piece of chrome around it has to be synthesized from host state.
29
90
  */
30
- declare function BrowserRunPanel({
31
- liveView,
32
- onRefresh,
33
- onCloseSession,
34
- loading,
35
- error,
36
- label,
37
- empty,
38
- fallback,
39
- className,
40
- ref,
41
- ...props
42
- }: BrowserRunPanelProps & {
43
- ref?: React.Ref<HTMLDivElement>;
44
- }): React.JSX.Element;
91
+ declare function BrowserRunPanel(props: BrowserRunPanelProps): React.JSX.Element;
45
92
  //#endregion
46
- export { BrowserRunPanel, BrowserRunPanelProps };
93
+ export { BrowserRunPanel, BrowserRunPanelProps, BrowserRunPanelTab };
@@ -1,21 +1,21 @@
1
1
  import { t as cx } from "../../class-names-BiMDVpUo.js";
2
- import { J as SpinnerIcon, rt as XIcon } from "../../icons-B4mGvCvc.js";
2
+ import { Y as SpinnerIcon, it as XIcon } from "../../icons-MmIXciMO.js";
3
3
  import { Button } from "../foundations/Button.js";
4
4
  import { Tabs } from "../foundations/Tabs.js";
5
- import { BrowserLiveView } from "./BrowserLiveView.js";
6
5
  import { WebPreview, WebPreviewNavigation, WebPreviewNavigationButton, WebPreviewUrl } from "../general-purpose/WebPreview.js";
6
+ import { BrowserLiveView } from "./BrowserLiveView.js";
7
7
  import * as React from "react";
8
- import { jsx, jsxs } from "react/jsx-runtime";
8
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9
9
  //#region src/components/agents-sdk/BrowserRunPanel.tsx
10
10
  function isInspectablePage(target) {
11
11
  const pageUrl = target.pageUrl;
12
12
  return Boolean(pageUrl && !pageUrl.startsWith("about:") && !pageUrl.startsWith("chrome:") && !pageUrl.startsWith("devtools:"));
13
13
  }
14
- function targetLabel(target) {
15
- return target.title || target.pageUrl || target.targetId;
14
+ function tabLabel(tab) {
15
+ return tab.title || tab.url || tab.id;
16
16
  }
17
- function targetGlyph(target) {
18
- return (target.title || target.pageUrl || target.targetId).trim().charAt(0).toUpperCase() || "•";
17
+ function tabGlyph(tab) {
18
+ return tabLabel(tab).trim().charAt(0).toUpperCase() || "•";
19
19
  }
20
20
  function pickTarget(targets, targetId) {
21
21
  return (targetId ? targets.find((target) => target.targetId === targetId) : void 0) ?? targets.find(isInspectablePage) ?? targets[0];
@@ -28,60 +28,33 @@ function BrowserRunPanelState({ children, role, tone = "neutral" }) {
28
28
  children
29
29
  });
30
30
  }
31
- /**
32
- * Right-side Browser Run panel for `ThinkFullApp.workbenchPanels`.
33
- *
34
- * The app owns `createBrowserRuntime()`, `connector.liveView()`, polling, and
35
- * session cleanup. This component only renders upstream `BrowserLiveView`
36
- * data and calls app-provided refresh/close callbacks.
37
- */
38
- function BrowserRunPanel({ liveView, onRefresh, onCloseSession, loading, error, label = "Browser", empty = "No live browser session", fallback, className, ref, ...props }) {
39
- const [requestedTargetId, setRequestedTargetId] = React.useState();
40
- const [receivedAt, setReceivedAt] = React.useState(() => Date.now());
41
- React.useEffect(() => {
42
- if (liveView) setReceivedAt(Date.now());
43
- }, [liveView]);
44
- const targets = liveView?.targets ?? [];
45
- const target = pickTarget(targets, requestedTargetId);
46
- const pageUrl = target?.pageUrl ?? "";
47
- const body = target && liveView ? /* @__PURE__ */ jsx(BrowserLiveView, {
48
- source: {
49
- url: target.url,
50
- targetId: target.targetId,
51
- expiresInMs: liveView.expiresInMs
52
- },
53
- receivedAt,
54
- pageTitle: target.title ?? target.pageUrl,
55
- fallback,
56
- className: "browser-run-panel__live-view"
57
- }) : loading ? /* @__PURE__ */ jsxs(BrowserRunPanelState, {
58
- role: "status",
59
- children: [/* @__PURE__ */ jsx(SpinnerIcon, {}), "Loading browser session"]
60
- }) : /* @__PURE__ */ jsx(BrowserRunPanelState, { children: empty });
31
+ /** The one rendering of the panel chrome, whichever mode filled its props in. */
32
+ function BrowserRunPanelFrame({ body, bodyBusy, bodyTabValue, className, error, label = "Browser", navigation, navigationEnd, onOpenUrl, onSelectTab, ref, selectedTabId, tabs, url, urlDisabled, urlLabel = "Browser page URL", urlPlaceholder, urlReadOnly, ...props }) {
61
33
  const bodyProps = {
62
34
  className: "web-preview__body browser-run-panel__body",
63
- "aria-busy": loading || void 0
35
+ "aria-busy": bodyBusy || void 0
64
36
  };
65
37
  return /* @__PURE__ */ jsxs(Tabs.Root, {
66
38
  className: cx("browser-run-panel", className),
67
- value: target?.targetId ?? null,
39
+ value: selectedTabId ?? null,
68
40
  onValueChange: (value) => {
69
- if (typeof value === "string") setRequestedTargetId(value);
41
+ if (typeof value === "string" && value !== selectedTabId) onSelectTab?.(value);
70
42
  },
71
43
  render: /* @__PURE__ */ jsx(WebPreview, {
72
44
  ref,
73
- url: pageUrl,
45
+ url,
46
+ ...onOpenUrl ? { onUrlChange: onOpenUrl } : {},
74
47
  role: "region",
75
48
  "aria-label": typeof label === "string" ? label : "Browser",
76
49
  ...props
77
50
  }),
78
51
  children: [
79
- targets.length > 1 ? /* @__PURE__ */ jsx(WebPreviewNavigation, { children: /* @__PURE__ */ jsxs(Tabs.List, {
52
+ tabs.length > 1 ? /* @__PURE__ */ jsx(WebPreviewNavigation, { children: /* @__PURE__ */ jsxs(Tabs.List, {
80
53
  className: "browser-run-panel__tabs",
81
54
  "aria-label": "Open browser pages",
82
55
  activateOnFocus: true,
83
- children: [targets.map((candidate) => /* @__PURE__ */ jsxs(Tabs.Tab, {
84
- value: candidate.targetId,
56
+ children: [tabs.map((tab) => /* @__PURE__ */ jsxs(Tabs.Tab, {
57
+ value: tab.id,
85
58
  className: "browser-run-panel__tab",
86
59
  render: /* @__PURE__ */ jsx(Button, {
87
60
  type: "button",
@@ -92,41 +65,33 @@ function BrowserRunPanel({ liveView, onRefresh, onCloseSession, loading, error,
92
65
  children: [/* @__PURE__ */ jsx("span", {
93
66
  className: "browser-run-panel__tab-glyph",
94
67
  "aria-hidden": "true",
95
- children: targetGlyph(candidate)
68
+ children: tabGlyph(tab)
96
69
  }), /* @__PURE__ */ jsx("span", {
97
70
  className: "browser-run-panel__tab-title sigvelo-truncate",
98
- children: targetLabel(candidate)
71
+ children: tabLabel(tab)
99
72
  })]
100
- }, candidate.targetId)), /* @__PURE__ */ jsx(Tabs.Indicator, {})]
73
+ }, tab.id)), /* @__PURE__ */ jsx(Tabs.Indicator, {})]
101
74
  }) }) : null,
102
75
  /* @__PURE__ */ jsxs(WebPreviewNavigation, {
103
76
  className: "browser-run-panel__address-bar",
104
77
  children: [
78
+ navigation,
105
79
  /* @__PURE__ */ jsx(WebPreviewUrl, {
106
- "aria-label": "Browser page URL",
107
- placeholder: "Waiting for browser session",
108
- readOnly: true
80
+ "aria-label": urlLabel,
81
+ placeholder: urlPlaceholder,
82
+ readOnly: urlReadOnly,
83
+ disabled: urlDisabled
109
84
  }),
110
- onRefresh ? /* @__PURE__ */ jsx(WebPreviewNavigationButton, {
111
- action: "reload",
112
- label: "Refresh browser view",
113
- disabled: loading,
114
- onClick: () => void onRefresh()
115
- }) : null,
116
- onCloseSession ? /* @__PURE__ */ jsx(WebPreviewNavigationButton, {
117
- label: "Close browser session",
118
- onClick: () => void onCloseSession(),
119
- children: /* @__PURE__ */ jsx(XIcon, {})
120
- }) : null
85
+ navigationEnd
121
86
  ]
122
87
  }),
123
88
  error ? /* @__PURE__ */ jsx(BrowserRunPanelState, {
124
89
  tone: "danger",
125
90
  children: error
126
91
  }) : null,
127
- targets.length > 1 && target ? /* @__PURE__ */ jsx(Tabs.Panel, {
92
+ bodyTabValue !== void 0 ? /* @__PURE__ */ jsx(Tabs.Panel, {
128
93
  ...bodyProps,
129
- value: target.targetId,
94
+ value: bodyTabValue,
130
95
  children: body
131
96
  }) : /* @__PURE__ */ jsx("div", {
132
97
  ...bodyProps,
@@ -135,5 +100,87 @@ function BrowserRunPanel({ liveView, onRefresh, onCloseSession, loading, error,
135
100
  ]
136
101
  });
137
102
  }
103
+ function HostedBrowserRunPanel({ liveView, onRefresh, onCloseSession, loading, error, label, empty = "No live browser session", fallback, ...props }) {
104
+ const [requestedTargetId, setRequestedTargetId] = React.useState();
105
+ const [receivedAt, setReceivedAt] = React.useState(() => Date.now());
106
+ React.useEffect(() => {
107
+ if (liveView) setReceivedAt(Date.now());
108
+ }, [liveView]);
109
+ const targets = liveView?.targets ?? [];
110
+ const target = pickTarget(targets, requestedTargetId);
111
+ const body = target && liveView ? /* @__PURE__ */ jsx(BrowserLiveView, {
112
+ source: {
113
+ url: target.url,
114
+ targetId: target.targetId,
115
+ expiresInMs: liveView.expiresInMs
116
+ },
117
+ receivedAt,
118
+ pageTitle: target.title ?? target.pageUrl,
119
+ fallback
120
+ }) : loading ? /* @__PURE__ */ jsxs(BrowserRunPanelState, {
121
+ role: "status",
122
+ children: [/* @__PURE__ */ jsx(SpinnerIcon, {}), "Loading browser session"]
123
+ }) : /* @__PURE__ */ jsx(BrowserRunPanelState, { children: empty });
124
+ return /* @__PURE__ */ jsx(BrowserRunPanelFrame, {
125
+ ...props,
126
+ body,
127
+ bodyBusy: loading,
128
+ bodyTabValue: targets.length > 1 && target ? target.targetId : void 0,
129
+ error,
130
+ label,
131
+ navigationEnd: /* @__PURE__ */ jsxs(Fragment, { children: [onRefresh ? /* @__PURE__ */ jsx(WebPreviewNavigationButton, {
132
+ action: "reload",
133
+ label: "Refresh browser view",
134
+ disabled: loading,
135
+ onClick: () => void onRefresh()
136
+ }) : null, onCloseSession ? /* @__PURE__ */ jsx(WebPreviewNavigationButton, {
137
+ label: "Close browser session",
138
+ onClick: () => void onCloseSession(),
139
+ children: /* @__PURE__ */ jsx(XIcon, {})
140
+ }) : null] }),
141
+ onSelectTab: setRequestedTargetId,
142
+ selectedTabId: target?.targetId ?? null,
143
+ tabs: targets.map((candidate) => ({
144
+ id: candidate.targetId,
145
+ ...candidate.title === void 0 ? {} : { title: candidate.title },
146
+ ...candidate.pageUrl === void 0 ? {} : { url: candidate.pageUrl }
147
+ })),
148
+ url: target?.pageUrl ?? "",
149
+ urlPlaceholder: "Waiting for browser session",
150
+ urlReadOnly: true
151
+ });
152
+ }
153
+ function StreamedBrowserRunPanel({ children, tabs = [], selectedTabId = null, onSelectTab, url = "", onOpenUrl, urlPlaceholder, urlDisabled, urlLabel, navigation, ...props }) {
154
+ return /* @__PURE__ */ jsx(BrowserRunPanelFrame, {
155
+ ...props,
156
+ body: children,
157
+ navigation,
158
+ onOpenUrl,
159
+ onSelectTab,
160
+ selectedTabId,
161
+ tabs,
162
+ url,
163
+ urlDisabled,
164
+ urlLabel,
165
+ urlPlaceholder,
166
+ urlReadOnly: onOpenUrl === void 0 || void 0
167
+ });
168
+ }
169
+ /**
170
+ * Browser panel chrome — drawn tab strip, address bar, framed body — for
171
+ * browser surfaces Chrome itself never paints.
172
+ *
173
+ * Two hosts fill it in. A Browser Run host passes upstream `BrowserLiveView`
174
+ * data from `connector.liveView()`, and the panel derives tabs, address, and
175
+ * an embedded live view itself, calling app-provided refresh/close callbacks.
176
+ * A streaming host instead passes `children` — its own live surface — with
177
+ * the tab strip, address bar, and navigation controlled from the host's own
178
+ * records, because a remote screencast carries only page pixels and every
179
+ * piece of chrome around it has to be synthesized from host state.
180
+ */
181
+ function BrowserRunPanel(props) {
182
+ if (props.children !== void 0) return /* @__PURE__ */ jsx(StreamedBrowserRunPanel, { ...props });
183
+ return /* @__PURE__ */ jsx(HostedBrowserRunPanel, { ...props });
184
+ }
138
185
  //#endregion
139
186
  export { BrowserRunPanel };
@@ -1,5 +1,5 @@
1
1
  import { t as cx } from "../../class-names-BiMDVpUo.js";
2
- import { J as SpinnerIcon, d as CheckIcon, j as McpIcon, tt as WarningIcon } from "../../icons-B4mGvCvc.js";
2
+ import { M as McpIcon, Y as SpinnerIcon, d as CheckIcon, nt as WarningIcon } from "../../icons-MmIXciMO.js";
3
3
  import { Button } from "../foundations/Button.js";
4
4
  import { AgentAttention, AgentAttentionActions, AgentAttentionBody, AgentAttentionHeader } from "../ai-sdk/AgentAttention.js";
5
5
  import { i as formatErrorMessage } from "../../format-DB2mX9DA.js";
@@ -1,5 +1,5 @@
1
1
  import { t as cx } from "../../class-names-BiMDVpUo.js";
2
- import { H as PlusIcon, J as SpinnerIcon, b as EllipsisIcon, o as ArrowUpRightIcon, rt as XIcon, tt as WarningIcon } from "../../icons-B4mGvCvc.js";
2
+ import { U as PlusIcon, Y as SpinnerIcon, b as EllipsisIcon, it as XIcon, nt as WarningIcon, o as ArrowUpRightIcon } from "../../icons-MmIXciMO.js";
3
3
  import { Button } from "../foundations/Button.js";
4
4
  import { AgentAttention, AgentAttentionBody, AgentAttentionHeader } from "../ai-sdk/AgentAttention.js";
5
5
  import { IconButton } from "../foundations/IconButton.js";
@@ -7,8 +7,8 @@ import { Dialog } from "../foundations/Dialog.js";
7
7
  import { i as formatErrorMessage } from "../../format-DB2mX9DA.js";
8
8
  import { Separator } from "../foundations/Separator.js";
9
9
  import { AppIcon } from "../foundations/AppIcon.js";
10
- import { n as getMcpServerProjection, t as McpServerIcon } from "../../mcp-server-SD_S-IpB.js";
11
10
  import { SearchField } from "../foundations/SearchField.js";
11
+ import { n as getMcpServerProjection, t as McpServerIcon } from "../../mcp-server-SD_S-IpB.js";
12
12
  import * as React from "react";
13
13
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
14
14
  //#region src/components/agents-sdk/McpPluginCatalog.tsx
@@ -1,5 +1,5 @@
1
1
  import { n as mergeBaseClassName } from "../../class-names-BiMDVpUo.js";
2
- import { J as SpinnerIcon, P as MinusIcon, d as CheckIcon, tt as WarningIcon } from "../../icons-B4mGvCvc.js";
2
+ import { F as MinusIcon, Y as SpinnerIcon, d as CheckIcon, nt as WarningIcon } from "../../icons-MmIXciMO.js";
3
3
  import { buttonVariants } from "../foundations/Button.js";
4
4
  import { Menu } from "../foundations/Menu.js";
5
5
  import { Dialog } from "../foundations/Dialog.js";
@@ -1,13 +1,13 @@
1
1
  import { t as cx } from "../../class-names-BiMDVpUo.js";
2
- import { G as SearchIcon, f as ChevronDownIcon } from "../../icons-B4mGvCvc.js";
2
+ import { K as SearchIcon, f as ChevronDownIcon } from "../../icons-MmIXciMO.js";
3
3
  import { Button } from "../foundations/Button.js";
4
4
  import { Autocomplete } from "../foundations/Autocomplete.js";
5
5
  import { Dialog } from "../foundations/Dialog.js";
6
6
  import { o as titleCase } from "../../format-DB2mX9DA.js";
7
7
  import { Separator } from "../foundations/Separator.js";
8
8
  import { ScrollArea } from "../foundations/ScrollArea.js";
9
- import { EmptyState } from "../foundations/EmptyState.js";
10
9
  import { t as ProviderLogo } from "../../provider-logos-zjZycgV6.js";
10
+ import { EmptyState } from "../foundations/EmptyState.js";
11
11
  import * as React from "react";
12
12
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
13
13
  import { createPortal } from "react-dom";
@@ -1,4 +1,4 @@
1
- import { c as BoxIcon, j as McpIcon } from "../../icons-B4mGvCvc.js";
1
+ import { M as McpIcon, c as BoxIcon } from "../../icons-MmIXciMO.js";
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  //#region src/components/agents-sdk/PromptInputCommands.tsx
4
4
  /** Project whole upstream Agents MCP state into composer mention commands. */
@@ -1,5 +1,5 @@
1
1
  import { t as cx } from "../../class-names-BiMDVpUo.js";
2
- import { J as SpinnerIcon, X as StopIcon, d as CheckIcon, tt as WarningIcon } from "../../icons-B4mGvCvc.js";
2
+ import { Y as SpinnerIcon, Z as StopIcon, d as CheckIcon, nt as WarningIcon } from "../../icons-MmIXciMO.js";
3
3
  import "react";
4
4
  import { jsx } from "react/jsx-runtime";
5
5
  //#region src/components/agents-sdk/SubagentRunIndicator.tsx
@@ -1,5 +1,5 @@
1
1
  import { t as cx } from "../../class-names-BiMDVpUo.js";
2
- import { l as BrainIcon } from "../../icons-B4mGvCvc.js";
2
+ import { l as BrainIcon } from "../../icons-MmIXciMO.js";
3
3
  import { buttonVariants } from "../foundations/Button.js";
4
4
  import { Tooltip } from "../foundations/Tooltip.js";
5
5
  import { t as NavigationLink } from "../../navigation-link-kqMa81v5.js";
@@ -1,2 +1,2 @@
1
- import { a as thinkPendingExecutionApprovalsQueryOptions, i as ThinkChatRoot, n as ThinkChatMessages, o as useThinkChat, r as ThinkChatProvider, s as useThinkPendingExecutionApprovals, t as ThinkChat } from "../../ThinkChat-BES_3Mb-.js";
1
+ import { a as thinkPendingExecutionApprovalsQueryOptions, i as ThinkChatRoot, n as ThinkChatMessages, o as useThinkChat, r as ThinkChatProvider, s as useThinkPendingExecutionApprovals, t as ThinkChat } from "../../ThinkChat-DkA4Wr71.js";
2
2
  export { ThinkChat, ThinkChatMessages, ThinkChatProvider, ThinkChatRoot, thinkPendingExecutionApprovalsQueryOptions, useThinkChat, useThinkPendingExecutionApprovals };
@@ -2,9 +2,9 @@ import { useExpansionState } from "../ai-sdk/ExpansionState.js";
2
2
  import { Activity, ActivityContent, ActivityItem, ActivityItemGroup, ActivityText, ActivityTrigger } from "../ai-sdk/Activity.js";
3
3
  import { Button } from "../foundations/Button.js";
4
4
  import { MessageResponse } from "../ai-sdk/Message.js";
5
- import { AgentActivityFavicon, AgentActivityIcon } from "./AgentActivity.js";
6
5
  import { useOptionalAgentToolRuns } from "./AgentToolRunsContext.js";
7
6
  import { SubagentRunList } from "./SubagentRunList.js";
7
+ import { AgentActivityFavicon, AgentActivityIcon } from "./AgentActivity.js";
8
8
  import { useOptionalThinkChatLive } from "./ThinkChatContext.js";
9
9
  import { isBrowserToolPart, isExecuteToolPart, isFetchToolPart, isPartWorking, isSessionContextToolPart, isSkillToolPart, isThinkChatActivityPart, isWorkspaceToolPart } from "./ThinkChatToolParts.js";
10
10
  import { ThinkChatBrowserPanel, ThinkChatExecutePanel, ThinkChatFetchPanel, ThinkChatSessionContextPanel, ThinkChatSkillPanel, ThinkChatWorkspacePanel } from "./ThinkChatToolPanels.js";
@@ -1,7 +1,7 @@
1
1
  import { ActivityOutput, ActivityPanel } from "../ai-sdk/Activity.js";
2
2
  import { Tabs } from "../foundations/Tabs.js";
3
3
  import { a as formatUnknownValue } from "../../format-DB2mX9DA.js";
4
- import { t as CodeBlock } from "../../CodeBlock-DO4Hdu1R.js";
4
+ import { t as CodeBlock } from "../../CodeBlock-CWk1FVtm.js";
5
5
  import { BrowserLiveView } from "./BrowserLiveView.js";
6
6
  import { inferWorkspaceLanguage } from "./WorkspaceFile.js";
7
7
  import { displayUrl, isSessionContextToolFailure } from "./ThinkChatToolParts.js";
@@ -1,5 +1,5 @@
1
1
  import { t as cx } from "../../class-names-BiMDVpUo.js";
2
- import { $ as TerminalIcon, C as FileIcon, O as InfoIcon, W as RefreshIcon, d as CheckIcon, n as ArrowDownIcon, rt as XIcon } from "../../icons-B4mGvCvc.js";
2
+ import { C as FileIcon, G as RefreshIcon, O as InfoIcon, d as CheckIcon, et as TerminalIcon, it as XIcon, n as ArrowDownIcon } from "../../icons-MmIXciMO.js";
3
3
  import { Activity, ActivityContent, ActivityItem, ActivityItemGroup, ActivityOutput, ActivityPanel, ActivityTrigger } from "../ai-sdk/Activity.js";
4
4
  import { a as formatUnknownValue } from "../../format-DB2mX9DA.js";
5
5
  import { EmptyState } from "../foundations/EmptyState.js";
@@ -1,5 +1,5 @@
1
1
  import { t as cx } from "../../class-names-BiMDVpUo.js";
2
- import { J as SpinnerIcon, O as InfoIcon, d as CheckIcon, rt as XIcon, z as PauseIcon } from "../../icons-B4mGvCvc.js";
2
+ import { B as PauseIcon, O as InfoIcon, Y as SpinnerIcon, d as CheckIcon, it as XIcon } from "../../icons-MmIXciMO.js";
3
3
  import { Tooltip } from "../foundations/Tooltip.js";
4
4
  import { formatThinkExecutionRunProgress, formatThinkExecutionStatus, getThinkExecutionRunStatus, getThinkExecutionRunStatusTone, getThinkExecutionRunSubtitle, getThinkExecutionRunTitle } from "./ThinkExecutionRun.js";
5
5
  import "react";
@@ -1,15 +1,15 @@
1
1
  import { t as cx } from "../../class-names-BiMDVpUo.js";
2
- import { W as RefreshIcon, b as EllipsisIcon } from "../../icons-B4mGvCvc.js";
2
+ import { G as RefreshIcon, b as EllipsisIcon } from "../../icons-MmIXciMO.js";
3
3
  import { buttonVariants } from "../foundations/Button.js";
4
4
  import { IconButton } from "../foundations/IconButton.js";
5
5
  import { Menu } from "../foundations/Menu.js";
6
6
  import { i as formatErrorMessage } from "../../format-DB2mX9DA.js";
7
7
  import { t as NavigationLink } from "../../navigation-link-kqMa81v5.js";
8
8
  import { EmptyState } from "../foundations/EmptyState.js";
9
+ import { AppTopBar } from "../general-purpose/AppTopBar.js";
9
10
  import { getThinkExecutionRunAccessibleName, getThinkExecutionRunId, getThinkExecutionRunStatus, getThinkExecutionRunStatusTone, isSameThinkExecutionRun, isThinkSubmissionRun } from "./ThinkExecutionRun.js";
10
11
  import { ThinkExecutionRunSummary } from "./ThinkExecutionStatus.js";
11
12
  import { ThinkExecutionDetail } from "./ThinkExecutionDetail.js";
12
- import { AppTopBar } from "../general-purpose/AppTopBar.js";
13
13
  import * as React from "react";
14
14
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
15
15
  import { queryOptions, useMutation, useSuspenseQuery } from "@tanstack/react-query";
@@ -1,15 +1,15 @@
1
1
  import { t as cx } from "../../class-names-BiMDVpUo.js";
2
- import { $ as TerminalIcon, C as FileIcon, J as SpinnerIcon, c as BoxIcon, f as ChevronDownIcon } from "../../icons-B4mGvCvc.js";
2
+ import { C as FileIcon, Y as SpinnerIcon, c as BoxIcon, et as TerminalIcon, f as ChevronDownIcon } from "../../icons-MmIXciMO.js";
3
3
  import { Button } from "../foundations/Button.js";
4
4
  import { n as mergeRefs } from "../../merge-refs-DF_7w2x_.js";
5
5
  import { ScrollArea } from "../foundations/ScrollArea.js";
6
6
  import { EmptyState } from "../foundations/EmptyState.js";
7
- import { McpPluginCatalog } from "./McpPluginCatalog.js";
8
- import { a as WorkspaceNavigationRestorationBoundary, i as WorkspaceNavigationFocusRestorer, n as WorkspaceNavigationProvider } from "../../WorkspaceLink-DtH66bAY.js";
9
- import { c as resolveThinkApprovalProps, s as useThinkPendingExecutionApprovals, t as ThinkChat } from "../../ThinkChat-BES_3Mb-.js";
10
7
  import { AppTopBar } from "../general-purpose/AppTopBar.js";
11
- import { ThinkExecutionWorkbench } from "./ThinkExecutionWorkbench.js";
12
8
  import { ResizableSidePanel } from "../general-purpose/ResizableSidePanel.js";
9
+ import { a as WorkspaceNavigationRestorationBoundary, i as WorkspaceNavigationFocusRestorer, n as WorkspaceNavigationProvider } from "../../WorkspaceLink-DtH66bAY.js";
10
+ import { c as resolveThinkApprovalProps, s as useThinkPendingExecutionApprovals, t as ThinkChat } from "../../ThinkChat-DkA4Wr71.js";
11
+ import { McpPluginCatalog } from "./McpPluginCatalog.js";
12
+ import { ThinkExecutionWorkbench } from "./ThinkExecutionWorkbench.js";
13
13
  import { ThinkFullAppViewSwitch } from "./ThinkFullAppViewSwitch.js";
14
14
  import { ThinkThreadStatusIndicators } from "./ThinkThreadPicker.js";
15
15
  import { ThinkThreadShell } from "./ThinkThreadShell.js";