@mcp-b/react-components 0.41.0 → 0.43.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 (125) hide show
  1. package/dist/{AgentChat-DVr2giwD.d.ts → AgentChat-Bibfj7u1.d.ts} +1 -1
  2. package/dist/{AgentChatStartScreen-CO49yepa.d.ts → AgentChatStartScreen-Bkv7Avni.d.ts} +6 -0
  3. package/dist/McpPluginCatalog-mbGw8FTu.d.ts +92 -0
  4. package/dist/ResponsiveSidebarShell-DOXd5T-d.d.ts +111 -0
  5. package/dist/SetupChecklist-H1JRCIIe.js +77 -0
  6. package/dist/{ThinkChatActivity-DyGHj01E.d.ts → ThinkChatActivity-CgvmTXXB.d.ts} +4 -1
  7. package/dist/Workspace-F3raHdYV.d.ts +140 -0
  8. package/dist/{WorkspaceFileView-D0yFwoDr.js → WorkspaceFileView-DWMKxX_u.js} +15 -21
  9. package/dist/components/agents-sdk/AgentActivity.js +3 -2
  10. package/dist/components/agents-sdk/AgentChat.d.ts +1 -1
  11. package/dist/components/agents-sdk/AgentChat.js +1 -0
  12. package/dist/components/agents-sdk/BrowserRunPanel.js +2 -1
  13. package/dist/components/agents-sdk/ManagerOffice.d.ts +39 -27
  14. package/dist/components/agents-sdk/ManagerOffice.js +80 -44
  15. package/dist/components/agents-sdk/McpPluginCatalog.d.ts +1 -91
  16. package/dist/components/agents-sdk/McpPluginCatalog.js +3 -1
  17. package/dist/components/agents-sdk/ModelSelector.js +1 -1
  18. package/dist/components/agents-sdk/ThinkChat.d.ts +2 -2
  19. package/dist/components/agents-sdk/ThinkChatActivity.d.ts +1 -1
  20. package/dist/components/agents-sdk/ThinkChatActivity.js +18 -4
  21. package/dist/components/agents-sdk/ThinkChatToolPanels.js +6 -2
  22. package/dist/components/agents-sdk/ThinkExecutionDetail.js +2 -0
  23. package/dist/components/agents-sdk/ThinkExecutionWorkbench.js +1 -0
  24. package/dist/components/agents-sdk/ThinkFullApp.d.ts +56 -90
  25. package/dist/components/agents-sdk/ThinkFullApp.js +74 -122
  26. package/dist/components/agents-sdk/ThinkFullAppViewSwitch.d.ts +1 -1
  27. package/dist/components/agents-sdk/ThinkRoutineLibrary.d.ts +8 -6
  28. package/dist/components/agents-sdk/ThinkRoutineLibrary.js +71 -93
  29. package/dist/components/agents-sdk/ThinkSidepanel.d.ts +173 -0
  30. package/dist/components/agents-sdk/ThinkSidepanel.js +656 -0
  31. package/dist/components/agents-sdk/ThinkThreadPicker.d.ts +4 -5
  32. package/dist/components/agents-sdk/ThinkThreadPicker.js +6 -5
  33. package/dist/components/agents-sdk/Workspace.d.ts +1 -139
  34. package/dist/components/agents-sdk/WorkspaceBrowser.d.ts +1 -1
  35. package/dist/components/agents-sdk/WorkspaceExplorer.d.ts +1 -1
  36. package/dist/components/agents-sdk/WorkspaceExplorer.js +4 -3
  37. package/dist/components/agents-sdk/WorkspaceFileView.js +1 -1
  38. package/dist/components/ai-sdk/AgentChatStartScreen.d.ts +1 -1
  39. package/dist/components/ai-sdk/AgentChatStartScreen.js +5 -2
  40. package/dist/components/ai-sdk/MessageScroller.js +2 -1
  41. package/dist/components/ai-sdk/MessageScrollerVirtual.js +1 -0
  42. package/dist/components/ai-sdk/PromptInput.js +20 -14
  43. package/dist/components/extension/ChatGptSignInScreen.js +1 -0
  44. package/dist/components/foundations/ToggleGroup.d.ts +79 -1
  45. package/dist/components/foundations/Toolbar.d.ts +151 -1
  46. package/dist/components/general-purpose/AppFrame.js +1 -0
  47. package/dist/components/general-purpose/AppTopBar.d.ts +96 -1
  48. package/dist/components/general-purpose/ResizableSidePanel.d.ts +8 -0
  49. package/dist/components/general-purpose/ResizableSidePanel.js +3 -2
  50. package/dist/components/general-purpose/ResponsiveSidebarShell.d.ts +2 -95
  51. package/dist/components/general-purpose/ResponsiveSidebarShell.js +74 -74
  52. package/dist/components/general-purpose/SetupChecklist.js +1 -76
  53. package/dist/components/general-purpose/ThemeModeControl.js +1 -1
  54. package/dist/components/general-purpose/WebPreview.d.ts +3 -0
  55. package/dist/components/general-purpose/WebPreview.js +2 -2
  56. package/dist/components/nanites/AgentToolDetail.js +1 -0
  57. package/dist/styles/accordion.css +1 -0
  58. package/dist/styles/action-guide.css +8 -7
  59. package/dist/styles/activity-header.css +13 -39
  60. package/dist/styles/activity.css +40 -55
  61. package/dist/styles/agent-attention.css +14 -14
  62. package/dist/styles/agent-chat.css +80 -58
  63. package/dist/styles/agent-connection.css +10 -4
  64. package/dist/styles/agent-tool-detail.css +4 -4
  65. package/dist/styles/alert-dialog.css +4 -4
  66. package/dist/styles/app-frame.css +1 -3
  67. package/dist/styles/app-top-bar.css +5 -9
  68. package/dist/styles/approval.css +1 -0
  69. package/dist/styles/artifact.css +6 -6
  70. package/dist/styles/attachment-preview.css +5 -4
  71. package/dist/styles/browser-replay.css +6 -6
  72. package/dist/styles/browser-run-panel.css +1 -0
  73. package/dist/styles/button.css +15 -6
  74. package/dist/styles/card.css +5 -5
  75. package/dist/styles/chatgpt-sign-in-screen.css +1 -1
  76. package/dist/styles/code-block.css +14 -13
  77. package/dist/styles/codex-model-selector.css +2 -0
  78. package/dist/styles/collapsible.css +1 -0
  79. package/dist/styles/commit.css +6 -6
  80. package/dist/styles/context.css +9 -9
  81. package/dist/styles/conversation-tab-picker.css +1 -1
  82. package/dist/styles/conversation.css +6 -8
  83. package/dist/styles/dialog.css +4 -4
  84. package/dist/styles/empty-state.css +3 -3
  85. package/dist/styles/environment-variables.css +9 -9
  86. package/dist/styles/field.css +2 -1
  87. package/dist/styles/fieldset.css +2 -2
  88. package/dist/styles/index.css +4 -3
  89. package/dist/styles/manager-office.css +23 -29
  90. package/dist/styles/mcp-plugin-catalog.css +11 -10
  91. package/dist/styles/mcp-server-picker.css +3 -3
  92. package/dist/styles/message-scroller.css +9 -11
  93. package/dist/styles/message.css +43 -20
  94. package/dist/styles/navigation-menu.css +1 -0
  95. package/dist/styles/plan.css +13 -12
  96. package/dist/styles/pricing-page.css +26 -23
  97. package/dist/styles/prompt-input.css +18 -5
  98. package/dist/styles/queue.css +1 -0
  99. package/dist/styles/reasoning.css +1 -9
  100. package/dist/styles/recipes.css +28 -1
  101. package/dist/styles/responsive-sidebar-shell.css +55 -24
  102. package/dist/styles/separator.css +5 -5
  103. package/dist/styles/sources.css +4 -4
  104. package/dist/styles/stepper.css +1 -0
  105. package/dist/styles/streamdown.css +31 -21
  106. package/dist/styles/tabs.css +1 -0
  107. package/dist/styles/task.css +5 -17
  108. package/dist/styles/terminal.css +10 -10
  109. package/dist/styles/test-results.css +6 -6
  110. package/dist/styles/think-execution-status.css +2 -2
  111. package/dist/styles/think-execution-workbench.css +12 -15
  112. package/dist/styles/think-full-app.css +26 -64
  113. package/dist/styles/think-routine-library.css +26 -55
  114. package/dist/styles/think-sidepanel.css +74 -0
  115. package/dist/styles/think-thread-picker.css +9 -9
  116. package/dist/styles/utilities.css +33 -0
  117. package/dist/styles/web-preview.css +20 -19
  118. package/dist/styles/workspace-explorer.css +18 -21
  119. package/dist/styles/workspace-mount-manager.css +2 -2
  120. package/dist/utils/favicon.d.ts +6 -1
  121. package/dist/utils/favicon.js +18 -1
  122. package/package.json +2 -2
  123. package/dist/AppTopBar-ZdgmB_Lu.d.ts +0 -97
  124. package/dist/ToggleGroup-BrQZOQn_.d.ts +0 -80
  125. package/dist/Toolbar-CBOseBQr.d.ts +0 -152
@@ -102,39 +102,51 @@ interface ManagerOfficeDisconnectedEmployee extends ManagerOfficeEmployeeBase {
102
102
  }
103
103
  type ManagerOfficeEmployee = ManagerOfficeConnectedEmployee | ManagerOfficeDisconnectedEmployee;
104
104
  type ManagerOfficeEmployeeStatus = ManagerOfficeEmployee["status"];
105
- interface ManagerOfficeNavigation {
106
- /** App-owned route element for the aggregate handoff view. */
107
- renderAttentionLink(): React.ReactElement;
108
- /** App-owned route element for one employee. */
109
- renderEmployeeLink(employee: ManagerOfficeEmployee): React.ReactElement;
110
- /** App-owned route element for a handoff's exact work. */
111
- renderHandoffLink(employee: ManagerOfficeConnectedEmployee, handoff: ManagerOfficeHandoff): React.ReactElement;
112
- /** App-owned route element for one work item. */
113
- renderWorkLink(employee: ManagerOfficeConnectedEmployee, work: ManagerOfficeWork): React.ReactElement;
114
- /** App-owned route element for one recurring responsibility. */
115
- renderRoutineLink(employee: ManagerOfficeConnectedEmployee, routine: ManagerOfficeRoutine): React.ReactElement;
116
- /** App-owned route element for starting new work with one employee. */
117
- renderNewWorkLink(employee: ManagerOfficeConnectedEmployee): React.ReactElement;
118
- /** App-owned route element for browsing one employee's workspace. */
119
- renderWorkspaceLink(employee: ManagerOfficeConnectedEmployee): React.ReactElement;
120
- }
105
+ /**
106
+ * Every place the office can send a manager, as one discriminated union — the
107
+ * same shape `WorkspaceNavigationAdapter.renderLink` uses. Consumers map it
108
+ * with one `switch` instead of implementing seven factories.
109
+ */
110
+ type ManagerOfficeDestination = {
111
+ kind: "attention";
112
+ } | {
113
+ kind: "employee";
114
+ employee: ManagerOfficeEmployee;
115
+ } | {
116
+ kind: "handoff";
117
+ employee: ManagerOfficeConnectedEmployee;
118
+ handoff: ManagerOfficeHandoff;
119
+ } | {
120
+ kind: "work";
121
+ employee: ManagerOfficeConnectedEmployee;
122
+ work: ManagerOfficeWork;
123
+ } | {
124
+ kind: "routine";
125
+ employee: ManagerOfficeConnectedEmployee;
126
+ routine: ManagerOfficeRoutine;
127
+ } | {
128
+ kind: "new-work";
129
+ employee: ManagerOfficeConnectedEmployee;
130
+ } | {
131
+ kind: "workspace";
132
+ employee: ManagerOfficeConnectedEmployee;
133
+ };
121
134
  interface ManagerOfficeProps extends React.HTMLAttributes<HTMLDivElement> {
122
135
  /** Current disposable navigation projection; durable selection remains app-owned. */
123
136
  view: ManagerOfficeView;
124
137
  /** Employees projected from their owning runtimes. */
125
138
  employees: readonly ManagerOfficeEmployee[];
126
- /** Router elements supplied by the consuming app. */
127
- navigation: ManagerOfficeNavigation;
128
- /** Add/sign-out controls rendered in the office rail. Pass `null` for none. */
129
- officeActions: React.ReactNode;
139
+ /** Returns an app-owned route element for every office destination. */
140
+ renderLink: (destination: ManagerOfficeDestination) => React.ReactElement;
141
+ /** Add/sign-out controls rendered in the office rail. */
142
+ officeActions?: React.ReactNode;
130
143
  /**
131
144
  * Actions rendered for the selected connected employee. Compose interactive
132
- * controls through `AppTopBar.Control` so they join the toolbar; pass `null`
133
- * for none.
145
+ * controls through `AppTopBar.Control` so they join the toolbar.
134
146
  */
135
- renderEmployeeActions: (employee: ManagerOfficeConnectedEmployee) => React.ReactNode;
136
- /** Action shown in the empty office. Pass `null` for none. */
137
- emptyOfficeAction: React.ReactNode;
147
+ renderEmployeeActions?: (employee: ManagerOfficeConnectedEmployee) => React.ReactNode;
148
+ /** Action shown in the empty office. */
149
+ emptyOfficeAction?: React.ReactNode;
138
150
  }
139
151
  /**
140
152
  * Multi-employee manager office: aggregate handoffs, employee roster, and one
@@ -145,7 +157,7 @@ declare function ManagerOffice({
145
157
  className,
146
158
  emptyOfficeAction,
147
159
  employees,
148
- navigation,
160
+ renderLink,
149
161
  officeActions,
150
162
  renderEmployeeActions,
151
163
  style,
@@ -153,4 +165,4 @@ declare function ManagerOffice({
153
165
  ...props
154
166
  }: ManagerOfficeProps): React.JSX.Element;
155
167
  //#endregion
156
- export { ManagerOffice, ManagerOfficeChannel, ManagerOfficeChannelDirection, ManagerOfficeChannelStatus, ManagerOfficeConnectedEmployee, ManagerOfficeDisconnectedEmployee, ManagerOfficeEmployee, ManagerOfficeEmployeeStatus, ManagerOfficeHandoff, ManagerOfficeNavigation, ManagerOfficeProps, ManagerOfficeRoutine, ManagerOfficeView, ManagerOfficeWork, ManagerOfficeWorkStatus };
168
+ export { ManagerOffice, ManagerOfficeChannel, ManagerOfficeChannelDirection, ManagerOfficeChannelStatus, ManagerOfficeConnectedEmployee, ManagerOfficeDestination, ManagerOfficeDisconnectedEmployee, ManagerOfficeEmployee, ManagerOfficeEmployeeStatus, ManagerOfficeHandoff, ManagerOfficeProps, ManagerOfficeRoutine, ManagerOfficeView, ManagerOfficeWork, ManagerOfficeWorkStatus };
@@ -4,8 +4,8 @@ import { $ as WarningIcon, A as MessageSquareIcon, B as PlusIcon, C as FolderIco
4
4
  import { Button } from "../foundations/Button.js";
5
5
  import { AgentAttention, AgentAttentionActions, AgentAttentionBody, AgentAttentionHeader } from "../ai-sdk/AgentAttention.js";
6
6
  import { Tooltip } from "../foundations/Tooltip.js";
7
- import { EmptyState } from "../foundations/EmptyState.js";
8
7
  import { Avatar } from "../foundations/Avatar.js";
8
+ import { EmptyState } from "../foundations/EmptyState.js";
9
9
  import { AppIcon } from "../foundations/AppIcon.js";
10
10
  import { LinkButton } from "../foundations/LinkButton.js";
11
11
  import "../foundations/icons.js";
@@ -304,10 +304,10 @@ function ChannelRow({ channel }) {
304
304
  * The action is a link into the owning work, because that is where the single
305
305
  * approval surface lives; nothing is approved or dismissed from the roster.
306
306
  */
307
- function HandoffCard({ employee, handoff, navigation, now, showEmployee }) {
307
+ function HandoffCard({ employee, handoff, renderLink, now, showEmployee }) {
308
308
  return /* @__PURE__ */ jsxs(AgentAttention, {
309
309
  tone: "attention",
310
- className: "manager-office__handoff",
310
+ className: cx("manager-office__handoff", !handoff.request && "manager-office__handoff--bare"),
311
311
  children: [
312
312
  /* @__PURE__ */ jsx(AgentAttentionHeader, {
313
313
  icon: /* @__PURE__ */ jsx(InfoIcon, {}),
@@ -322,9 +322,16 @@ function HandoffCard({ employee, handoff, navigation, now, showEmployee }) {
322
322
  })
323
323
  ] })
324
324
  }),
325
- handoff.request ? /* @__PURE__ */ jsx(AgentAttentionBody, { children: handoff.request }) : null,
325
+ handoff.request ? /* @__PURE__ */ jsx(AgentAttentionBody, {
326
+ className: "manager-office__handoff-ask",
327
+ children: handoff.request
328
+ }) : null,
326
329
  /* @__PURE__ */ jsx(AgentAttentionActions, { children: /* @__PURE__ */ jsxs(LinkButton, {
327
- render: navigation.renderHandoffLink(employee, handoff),
330
+ render: renderLink({
331
+ kind: "handoff",
332
+ employee,
333
+ handoff
334
+ }),
328
335
  size: "sm",
329
336
  "aria-label": `Open ${handoff.workTitle} to ${handoff.reason.toLowerCase()}`,
330
337
  children: [/* @__PURE__ */ jsx(MonitorIcon, {}), "Open browser"]
@@ -332,7 +339,7 @@ function HandoffCard({ employee, handoff, navigation, now, showEmployee }) {
332
339
  ]
333
340
  });
334
341
  }
335
- function EmployeeSidebar({ closeSidebarOnCompact, employees, navigation, officeActions, profileColors, view }) {
342
+ function EmployeeSidebar({ closeSidebarOnCompact, employees, renderLink, officeActions, profileColors, view }) {
336
343
  const rosterLabelId = React.useId();
337
344
  const attentionCount = employees.reduce((total, employee) => total + employeeAttentionCount(employee), 0);
338
345
  const selectedEmployeeId = view.kind === "employee" ? view.employeeId : null;
@@ -348,7 +355,7 @@ function EmployeeSidebar({ closeSidebarOnCompact, employees, navigation, officeA
348
355
  })]
349
356
  }),
350
357
  /* @__PURE__ */ jsxs(LinkButton, {
351
- render: navigation.renderAttentionLink(),
358
+ render: renderLink({ kind: "attention" }),
352
359
  onClick: closeSidebarOnCompact,
353
360
  variant: "ghost",
354
361
  color: "neutral",
@@ -366,7 +373,10 @@ function EmployeeSidebar({ closeSidebarOnCompact, employees, navigation, officeA
366
373
  className: "manager-office__employee-nav sigvelo-stack-list",
367
374
  "aria-labelledby": rosterLabelId,
368
375
  children: employees.map((employee) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(LinkButton, {
369
- render: navigation.renderEmployeeLink(employee),
376
+ render: renderLink({
377
+ kind: "employee",
378
+ employee
379
+ }),
370
380
  onClick: closeSidebarOnCompact,
371
381
  variant: "ghost",
372
382
  color: "neutral",
@@ -400,39 +410,49 @@ function EmployeeSidebar({ closeSidebarOnCompact, employees, navigation, officeA
400
410
  ]
401
411
  });
402
412
  }
403
- function AttentionView({ employees, navigation, now }) {
413
+ function AttentionView({ employees, renderLink, now }) {
404
414
  const rows = employees.flatMap((employee) => isConnected(employee) ? employee.handoffs.map((handoff) => ({
405
415
  employee,
406
416
  handoff
407
417
  })) : []);
408
- if (!rows.length) return /* @__PURE__ */ jsx(EmptyState, {
409
- icon: /* @__PURE__ */ jsx(CheckIcon, {}),
410
- title: "No active handoffs",
411
- description: "Employee connection state remains visible in the roster."
418
+ if (!rows.length) return /* @__PURE__ */ jsx("section", {
419
+ className: "manager-office__attention",
420
+ "data-recipe": "page",
421
+ "aria-label": "Needs you",
422
+ children: /* @__PURE__ */ jsx(EmptyState, {
423
+ icon: /* @__PURE__ */ jsx(CheckIcon, {}),
424
+ title: "No active handoffs",
425
+ description: "Employee connection state remains visible in the roster."
426
+ })
412
427
  });
413
428
  return /* @__PURE__ */ jsx("section", {
414
429
  className: "manager-office__attention",
430
+ "data-recipe": "page",
415
431
  "aria-label": "Needs you",
416
432
  children: /* @__PURE__ */ jsx("ul", {
417
433
  className: "manager-office__attention-list sigvelo-stack-list",
418
434
  children: rows.map(({ employee, handoff }) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(HandoffCard, {
419
435
  employee,
420
436
  handoff,
421
- navigation,
437
+ renderLink,
422
438
  now,
423
439
  showEmployee: true
424
440
  }) }, `${employee.id}:${handoff.id}`))
425
441
  })
426
442
  });
427
443
  }
428
- function EmployeeDetail({ employee, navigation, now, profileColor }) {
429
- if (!isConnected(employee)) return /* @__PURE__ */ jsx(EmptyState, {
430
- icon: employee.status === "connecting" ? /* @__PURE__ */ jsx(SpinnerIcon, {}) : /* @__PURE__ */ jsx(MonitorIcon, {}),
431
- title: `${employee.name} is ${statusLabels[employee.status].toLowerCase()}`,
432
- description: employee.statusDescription
444
+ function EmployeeDetail({ employee, renderLink, now, profileColor }) {
445
+ if (!isConnected(employee)) return /* @__PURE__ */ jsx("div", {
446
+ "data-recipe": "page",
447
+ children: /* @__PURE__ */ jsx(EmptyState, {
448
+ icon: employee.status === "connecting" ? /* @__PURE__ */ jsx(SpinnerIcon, {}) : /* @__PURE__ */ jsx(MonitorIcon, {}),
449
+ title: `${employee.name} is ${statusLabels[employee.status].toLowerCase()}`,
450
+ description: employee.statusDescription
451
+ })
433
452
  });
434
453
  return /* @__PURE__ */ jsxs("div", {
435
454
  className: "manager-office__employee-detail",
455
+ "data-recipe": "page",
436
456
  children: [
437
457
  /* @__PURE__ */ jsxs("header", {
438
458
  className: "manager-office__employee-header",
@@ -466,7 +486,7 @@ function EmployeeDetail({ employee, navigation, now, profileColor }) {
466
486
  children: employee.handoffs.map((handoff) => /* @__PURE__ */ jsx(HandoffCard, {
467
487
  employee,
468
488
  handoff,
469
- navigation,
489
+ renderLink,
470
490
  now,
471
491
  showEmployee: false
472
492
  }, handoff.id))
@@ -486,7 +506,11 @@ function EmployeeDetail({ employee, navigation, now, profileColor }) {
486
506
  children: employee.work.length ? /* @__PURE__ */ jsx("ul", {
487
507
  className: "manager-office__work-list sigvelo-stack-list",
488
508
  children: employee.work.map((work) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(LinkButton, {
489
- render: navigation.renderWorkLink(employee, work),
509
+ render: renderLink({
510
+ kind: "work",
511
+ employee,
512
+ work
513
+ }),
490
514
  variant: "ghost",
491
515
  color: "neutral",
492
516
  size: "sm",
@@ -542,7 +566,11 @@ function EmployeeDetail({ employee, navigation, now, profileColor }) {
542
566
  children: employee.routines.length ? /* @__PURE__ */ jsx("ul", {
543
567
  className: "manager-office__routine-list sigvelo-stack-list",
544
568
  children: employee.routines.map((routine) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(LinkButton, {
545
- render: navigation.renderRoutineLink(employee, routine),
569
+ render: renderLink({
570
+ kind: "routine",
571
+ employee,
572
+ routine
573
+ }),
546
574
  variant: "ghost",
547
575
  color: "neutral",
548
576
  size: "sm",
@@ -591,7 +619,7 @@ function EmployeeDetail({ employee, navigation, now, profileColor }) {
591
619
  * employee dossier. The consuming app owns authentication, Agent connections,
592
620
  * routing, and the selected employee's full work surface.
593
621
  */
594
- function ManagerOffice({ className, emptyOfficeAction, employees, navigation, officeActions, renderEmployeeActions, style, view, ...props }) {
622
+ function ManagerOffice({ className, emptyOfficeAction, employees, renderLink, officeActions, renderEmployeeActions, style, view, ...props }) {
595
623
  const titleId = React.useId();
596
624
  const [now, setNow] = React.useState(Date.now);
597
625
  React.useEffect(() => {
@@ -609,29 +637,37 @@ function ManagerOffice({ className, emptyOfficeAction, employees, navigation, of
609
637
  sidebar: ({ closeSidebarOnCompact }) => /* @__PURE__ */ jsx(EmployeeSidebar, {
610
638
  closeSidebarOnCompact,
611
639
  employees,
612
- navigation,
640
+ renderLink,
613
641
  officeActions,
614
642
  profileColors,
615
643
  view
616
644
  }),
617
- topBarProps: { "aria-label": "Manager office controls" },
618
- topBarTitleRender: /* @__PURE__ */ jsx("h1", { id: titleId }),
619
- topBarTitle: title,
620
- topBarTrailing: selectedEmployee && isConnected(selectedEmployee) ? /* @__PURE__ */ jsxs(Fragment, { children: [
621
- /* @__PURE__ */ jsx(AppTopBar.Link, {
622
- label: `Start new work with ${selectedEmployee.name}`,
623
- tooltip: "New work",
624
- render: navigation.renderNewWorkLink(selectedEmployee),
625
- children: /* @__PURE__ */ jsx(PencilIcon, {})
626
- }),
627
- /* @__PURE__ */ jsx(AppTopBar.Link, {
628
- label: `Open ${selectedEmployee.name} workspace`,
629
- tooltip: "Workspace",
630
- render: navigation.renderWorkspaceLink(selectedEmployee),
631
- children: /* @__PURE__ */ jsx(FolderIcon, {})
632
- }),
633
- renderEmployeeActions(selectedEmployee)
634
- ] }) : void 0,
645
+ bar: {
646
+ label: "Manager office controls",
647
+ titleRender: /* @__PURE__ */ jsx("h1", { id: titleId }),
648
+ title,
649
+ actions: selectedEmployee && isConnected(selectedEmployee) ? /* @__PURE__ */ jsxs(Fragment, { children: [
650
+ /* @__PURE__ */ jsx(AppTopBar.Link, {
651
+ label: `Start new work with ${selectedEmployee.name}`,
652
+ tooltip: "New work",
653
+ render: renderLink({
654
+ kind: "new-work",
655
+ employee: selectedEmployee
656
+ }),
657
+ children: /* @__PURE__ */ jsx(PencilIcon, {})
658
+ }),
659
+ /* @__PURE__ */ jsx(AppTopBar.Link, {
660
+ label: `Open ${selectedEmployee.name} workspace`,
661
+ tooltip: "Workspace",
662
+ render: renderLink({
663
+ kind: "workspace",
664
+ employee: selectedEmployee
665
+ }),
666
+ children: /* @__PURE__ */ jsx(FolderIcon, {})
667
+ }),
668
+ renderEmployeeActions?.(selectedEmployee)
669
+ ] }) : void 0
670
+ },
635
671
  ...props,
636
672
  children: /* @__PURE__ */ jsx("main", {
637
673
  className: "manager-office__main",
@@ -643,11 +679,11 @@ function ManagerOffice({ className, emptyOfficeAction, employees, navigation, of
643
679
  children: emptyOfficeAction
644
680
  }) : view.kind === "attention" ? /* @__PURE__ */ jsx(AttentionView, {
645
681
  employees,
646
- navigation,
682
+ renderLink,
647
683
  now
648
684
  }) : selectedEmployee ? /* @__PURE__ */ jsx(EmployeeDetail, {
649
685
  employee: selectedEmployee,
650
- navigation,
686
+ renderLink,
651
687
  now,
652
688
  profileColor: profileColors.get(selectedEmployee.id)
653
689
  }) : /* @__PURE__ */ jsx(EmptyState, {
@@ -1,92 +1,2 @@
1
- import { o as McpServerCard } from "../../mcp-server-catalog-CCj2ItkV.js";
2
- import { r as McpConnectorFormValues } from "../../McpConnectorForm-MRm1r59e.js";
3
- import { l as DialogProps } from "../../Dialog-B_FhRWaz.js";
4
- import * as React from "react";
5
- import { MCPServersState } from "agents";
6
-
7
- //#region src/components/agents-sdk/McpPluginCatalog.d.ts
8
- /** Optional plugin-specific copy layered over the canonical MCP server card. */
9
- interface McpPluginDetails {
10
- developerName?: string;
11
- marketplaceName?: string;
12
- longDescription?: string;
13
- capabilities?: readonly string[];
14
- skills?: readonly string[];
15
- }
16
- interface McpPluginCatalogProps extends Omit<React.HTMLAttributes<HTMLElement>, "onSelect"> {
17
- /** Canonical connector cards. The directory does not create a second plugin registry. */
18
- servers: readonly McpServerCard[];
19
- /** Upstream Agents MCP state used to project connected and recovery states. */
20
- mcp?: MCPServersState;
21
- /** Optional plugin metadata keyed by the canonical server ID. */
22
- detailsByServerId?: Readonly<Record<string, McpPluginDetails | undefined>>;
23
- /** Server IDs promoted into the Featured section, in display order. */
24
- featuredServerIds?: readonly string[];
25
- /** Host product name paired with the plugin in the connection dialog. */
26
- brandName?: string;
27
- /** Host product mark paired with the plugin in the connection dialog. */
28
- brandLogo?: React.ReactNode;
29
- /** Product-authored trust and data-sharing copy. Pass null to omit it. */
30
- disclosure?: React.ReactNode;
31
- /** Starts or recovers the existing MCP connection path. */
32
- onConnect?: (server: McpServerCard) => void | Promise<void>;
33
- /** Removes the exact upstream MCP entry. */
34
- onDisconnect?: (serverId: string) => void | Promise<void>;
35
- /**
36
- * Connects a user-supplied MCP server. Providing it puts the "Custom
37
- * plugin" action in the bar, opening the shared connector setup dialog.
38
- */
39
- onAddCustom?: (values: McpConnectorFormValues) => void | Promise<void>;
40
- /** Accessible name only — the hosting tab or icon is the visible title. */
41
- heading?: React.ReactNode;
42
- searchLabel?: string;
43
- emptyMessage?: React.ReactNode;
44
- }
45
- interface McpPluginDetailsDialogProps {
46
- /** Selected canonical server card. Passing null closes the dialog. */
47
- server: McpServerCard | null;
48
- details?: McpPluginDetails;
49
- mcp?: MCPServersState;
50
- brandName?: string;
51
- brandLogo?: React.ReactNode;
52
- disclosure?: React.ReactNode;
53
- onConnect?: (server: McpServerCard) => void | Promise<void>;
54
- onDisconnect?: (serverId: string) => void | Promise<void>;
55
- onOpenChange: NonNullable<DialogProps["onOpenChange"]>;
56
- }
57
- /**
58
- * Searchable plugin directory backed by the same MCP cards and live Agents
59
- * state as {@link McpServerPicker}. Selecting a row opens the shared details
60
- * dialog; connecting still delegates to the host's existing MCP/OAuth path.
61
- */
62
- declare function McpPluginCatalog({
63
- servers,
64
- mcp,
65
- detailsByServerId,
66
- featuredServerIds,
67
- brandName,
68
- brandLogo,
69
- disclosure,
70
- onConnect,
71
- onDisconnect,
72
- onAddCustom,
73
- heading,
74
- searchLabel,
75
- emptyMessage,
76
- className,
77
- ...props
78
- }: McpPluginCatalogProps): React.JSX.Element;
79
- /** Reference-derived plugin detail surface without a parallel install state. */
80
- declare function McpPluginDetailsDialog({
81
- server,
82
- details,
83
- mcp,
84
- brandName,
85
- brandLogo,
86
- disclosure,
87
- onConnect,
88
- onDisconnect,
89
- onOpenChange
90
- }: McpPluginDetailsDialogProps): React.JSX.Element;
91
- //#endregion
1
+ import { a as McpPluginDetailsDialogProps, i as McpPluginDetailsDialog, n as McpPluginCatalogProps, r as McpPluginDetails, t as McpPluginCatalog } from "../../McpPluginCatalog-mbGw8FTu.js";
92
2
  export { McpPluginCatalog, McpPluginCatalogProps, McpPluginDetails, McpPluginDetailsDialog, McpPluginDetailsDialogProps };
@@ -129,7 +129,9 @@ function McpPluginCatalog({ servers, mcp, detailsByServerId, featuredServerIds =
129
129
  /** Reference-derived plugin detail surface without a parallel install state. */
130
130
  function McpPluginDetailsDialog({ server, details, mcp, brandName = "your AI", brandLogo = /* @__PURE__ */ jsx("img", {
131
131
  alt: "",
132
- src: new URL("../../assets/think-browser-host.png", import.meta.url).href
132
+ src: new URL("../../assets/think-browser-host.png", import.meta.url).href,
133
+ width: 128,
134
+ height: 128
133
135
  }), disclosure = /* @__PURE__ */ jsxs(Fragment, { children: [
134
136
  /* @__PURE__ */ jsxs("p", { children: [/* @__PURE__ */ jsx("strong", { children: "You're in control." }), " This plugin is limited to the account and permissions you approve, and you can disconnect it at any time."] }),
135
137
  /* @__PURE__ */ jsxs("p", { children: [/* @__PURE__ */ jsx("strong", { children: "Plugins may introduce elevated risk." }), " Only connect tools you trust. A compromised plugin could use its access to read or change data in the connected service."] }),
@@ -6,8 +6,8 @@ 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,9 +1,9 @@
1
1
  import { i as AgentMessageRenderPartContext } from "../../AgentMessageParts-C7L-Mv9U.js";
2
2
  import { K as PromptInputMessage } from "../../PromptInput-BRX7FhjH.js";
3
- import { r as AgentChatProps } from "../../AgentChat-DVr2giwD.js";
3
+ import { r as AgentChatProps } from "../../AgentChat-Bibfj7u1.js";
4
4
  import { n as AgentToolEventsValue } from "../../AgentToolRunsContext-daY67hFM.js";
5
5
  import { o as UseSessionCompactionResult } from "../../SessionCompaction-CmTJFpzj.js";
6
- import { o as createThinkChatActivityRenderer, r as ThinkChatActivityRendererOptions, t as ThinkChatActivity } from "../../ThinkChatActivity-DyGHj01E.js";
6
+ import { o as createThinkChatActivityRenderer, r as ThinkChatActivityRendererOptions, t as ThinkChatActivity } from "../../ThinkChatActivity-CgvmTXXB.js";
7
7
  import { i as ThinkChatValue } from "../../ThinkChatContext-COIgzkYp.js";
8
8
  import { t as ThinkRecoveryNotice } from "../../ThinkRecoveryNotice-DGWr94rk.js";
9
9
  import { n as WorkspaceHtmlArtifactRenderer } from "../../WorkspaceMessageResponse-D66ty4FO.js";
@@ -1,2 +1,2 @@
1
- import { a as ThinkChatToolRenderers, i as ThinkChatToolRenderer, n as ThinkChatActivityProps, o as createThinkChatActivityRenderer, r as ThinkChatActivityRendererOptions, s as renderThinkChatActivityPart, t as ThinkChatActivity } from "../../ThinkChatActivity-DyGHj01E.js";
1
+ import { a as ThinkChatToolRenderers, i as ThinkChatToolRenderer, n as ThinkChatActivityProps, o as createThinkChatActivityRenderer, r as ThinkChatActivityRendererOptions, s as renderThinkChatActivityPart, t as ThinkChatActivity } from "../../ThinkChatActivity-CgvmTXXB.js";
2
2
  export { ThinkChatActivity, ThinkChatActivityProps, ThinkChatActivityRendererOptions, ThinkChatToolRenderer, ThinkChatToolRenderers, createThinkChatActivityRenderer, renderThinkChatActivityPart };
@@ -32,7 +32,7 @@ function activityPartIcon(part) {
32
32
  * thousands-of-tools run expandable.
33
33
  */
34
34
  const VISIBLE_STEP_LIMIT = 100;
35
- function ThinkChatActivity({ parts, defaultOpen, isStreaming, toolRenderers, stateKey }) {
35
+ function ThinkChatActivity({ parts, defaultOpen, isStreaming, toolRenderers, settledAction, stateKey }) {
36
36
  const steps = parts.flatMap((part, index) => {
37
37
  const description = describeThinkChatActivityPart(part, toolRenderers);
38
38
  if (!description) return [];
@@ -59,8 +59,8 @@ function ThinkChatActivity({ parts, defaultOpen, isStreaming, toolRenderers, sta
59
59
  stateKey: scope,
60
60
  children: [/* @__PURE__ */ jsx(ActivityTrigger, {
61
61
  icon: header.url ? /* @__PURE__ */ jsx(AgentActivityFavicon, { url: header.url }) : /* @__PURE__ */ jsx(AgentActivityIcon, { kind: header.iconKind }),
62
- action: header.action,
63
- detail: header.detail
62
+ action: !streaming && settledAction ? settledAction : header.action,
63
+ detail: !streaming && settledAction ? void 0 : header.detail
64
64
  }), /* @__PURE__ */ jsxs(ActivityContent, { children: [hiddenStepCount > 0 ? /* @__PURE__ */ jsxs(Button, {
65
65
  size: "sm",
66
66
  variant: "ghost",
@@ -153,7 +153,18 @@ function ThinkChatActivityStep({ description, part, stateKey, toolRenderers }) {
153
153
  children: text
154
154
  });
155
155
  }
156
- function ThinkChatActivityGroup({ message, parts, renderAgentToolRunLink, isTrailing, toolRenderers, stateKey }) {
156
+ function terminalActivityAction(message) {
157
+ const metadata = message.metadata;
158
+ if (typeof metadata !== "object" || metadata === null || !("durationMs" in metadata) || typeof metadata.durationMs !== "number" || !Number.isFinite(metadata.durationMs) || metadata.durationMs < 0) return;
159
+ const totalSeconds = Math.max(1, Math.round(metadata.durationMs / 1e3));
160
+ const minutes = Math.floor(totalSeconds / 60);
161
+ const seconds = totalSeconds % 60;
162
+ const duration = minutes ? seconds ? `${minutes}m ${seconds}s` : `${minutes}m` : `${totalSeconds}s`;
163
+ const status = "status" in metadata ? metadata.status : void 0;
164
+ if (status === "completed") return `Worked for ${duration}`;
165
+ if (status === "aborted") return `You stopped after ${duration}`;
166
+ }
167
+ function ThinkChatActivityGroup({ message, parts, renderAgentToolRunLink, isTrailing, settledAction, toolRenderers, stateKey }) {
157
168
  const live = useOptionalThinkChatLive();
158
169
  const streaming = isTrailing && (live ? live.isStreaming && live.lastMessageId === message.id : parts.some(isPartWorking));
159
170
  const agentTools = useOptionalAgentToolRuns();
@@ -168,6 +179,7 @@ function ThinkChatActivityGroup({ message, parts, renderAgentToolRunLink, isTrai
168
179
  return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(ThinkChatActivity, {
169
180
  parts,
170
181
  isStreaming: streaming,
182
+ settledAction,
171
183
  toolRenderers,
172
184
  stateKey
173
185
  }), runs.length && renderAgentToolRunLink ? /* @__PURE__ */ jsx(SubagentRunList, {
@@ -212,11 +224,13 @@ function createThinkChatActivityRenderer({ excludeTools, renderAgentToolRunLink,
212
224
  if (partIndex !== start) return null;
213
225
  let end = partIndex;
214
226
  while (end + 1 < message.parts.length && runStarts[end + 1] === start) end++;
227
+ const isLastActivityRun = runStarts.findLast((runStart) => runStart !== -1) === start;
215
228
  return /* @__PURE__ */ jsx(ThinkChatActivityGroup, {
216
229
  message,
217
230
  parts: message.parts.slice(start, end + 1),
218
231
  stateKey: `${message.id}:${start}`,
219
232
  isTrailing: end === message.parts.length - 1,
233
+ settledAction: isLastActivityRun ? terminalActivityAction(message) : void 0,
220
234
  toolRenderers,
221
235
  renderAgentToolRunLink
222
236
  });
@@ -386,12 +386,16 @@ function ThinkChatBrowserPanel({ part }) {
386
386
  receivedAt: seenAt,
387
387
  fallback: media.screenshot ? /* @__PURE__ */ jsx("img", {
388
388
  src: media.screenshot,
389
- alt: "Last browser state"
389
+ alt: "Last browser state",
390
+ width: 16,
391
+ height: 10
390
392
  }) : void 0
391
393
  }) : media.screenshot ? /* @__PURE__ */ jsx("img", {
392
394
  className: "activity__browser-screenshot",
393
395
  src: media.screenshot,
394
- alt: "Browser screenshot"
396
+ alt: "Browser screenshot",
397
+ width: 16,
398
+ height: 10
395
399
  }) : null;
396
400
  const codeView = /* @__PURE__ */ jsx(ExecuteCodeView, {
397
401
  code,
@@ -17,6 +17,7 @@ function ThinkExecutionDetail({ className, emptyState = "Select a run to view it
17
17
  if (!run) return /* @__PURE__ */ jsx("section", {
18
18
  ref,
19
19
  className: cx("think-execution-detail", "think-execution-detail--empty", className),
20
+ "data-recipe": "page",
20
21
  role: "status",
21
22
  ...props,
22
23
  children: /* @__PURE__ */ jsx(EmptyState, { description: emptyState })
@@ -27,6 +28,7 @@ function ThinkExecutionDetail({ className, emptyState = "Select a run to view it
27
28
  return /* @__PURE__ */ jsxs("section", {
28
29
  ref,
29
30
  className: cx("think-execution-detail", className),
31
+ "data-recipe": "page",
30
32
  ...props,
31
33
  children: [
32
34
  /* @__PURE__ */ jsxs("header", {
@@ -142,6 +142,7 @@ function ThinkExecutionWorkbench({ backButton, className, pageSize = executionPa
142
142
  return /* @__PURE__ */ jsxs("div", {
143
143
  ref,
144
144
  className: cx("think-execution-workbench", className),
145
+ "data-recipe": "fill-host",
145
146
  ...props,
146
147
  children: [
147
148
  /* @__PURE__ */ jsxs(AppTopBar.Root, {