@mcp-b/react-components 0.46.2 → 0.46.4

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.
@@ -1,4 +1,4 @@
1
- import { d as McpServerSetupAuthFieldName, l as McpServerSetupAuth } from "./mcp-server-catalog-Cbu483Zb.js";
1
+ import { d as McpServerSetupAuthFieldName, l as McpServerSetupAuth } from "./mcp-server-catalog-C_g7C-9o.js";
2
2
  import * as React from "react";
3
3
 
4
4
  //#region src/components/agents-sdk/McpConnectorForm.d.ts
@@ -1,5 +1,5 @@
1
- import { o as McpServerCard } from "./mcp-server-catalog-Cbu483Zb.js";
2
- import { r as McpConnectorFormValues } from "./McpConnectorForm-BETdVBRk.js";
1
+ import { o as McpServerCard } from "./mcp-server-catalog-C_g7C-9o.js";
2
+ import { r as McpConnectorFormValues } from "./McpConnectorForm-CeYNY0MI.js";
3
3
  import { l as DialogProps } from "./Dialog-B_FhRWaz.js";
4
4
  import * as React from "react";
5
5
  import { MCPServersState } from "agents";
@@ -16,19 +16,37 @@ const BROWSER_LIVE_SCREEN_NEGOTIATION_TIMEOUT_MS = 1e4;
16
16
  */
17
17
  function BrowserLiveScreen({ sendSignal: sendHostSignal, subscribeSignals, protocol, getIceServers, label = "Employee browser", controlLabel = "Control employee browser", tabs = [], requestedTabId }) {
18
18
  const video = useRef(null);
19
+ const input = useRef(null);
20
+ const [videoElement, setVideoElement] = useState(null);
19
21
  const track = useRef(null);
20
22
  const attachVideo = useCallback((element) => {
21
23
  video.current = element;
22
24
  if (element) element.srcObject = track.current;
25
+ setVideoElement(element);
23
26
  }, []);
24
27
  const showTrack = useCallback((stream) => {
25
28
  track.current = stream;
26
- if (video.current) video.current.srcObject = stream;
29
+ if (video.current) {
30
+ video.current.srcObject = stream;
31
+ syncInputBounds();
32
+ }
27
33
  }, []);
28
34
  const channel = useRef(null);
29
35
  const geometry = useRef(null);
30
36
  const [phase, setPhase] = useState("connecting");
31
37
  const [failure, setFailure] = useState(null);
38
+ const syncVideoInputBounds = useEffectEvent(() => syncInputBounds());
39
+ useEffect(() => {
40
+ if (!videoElement) return;
41
+ videoElement.addEventListener("resize", syncVideoInputBounds);
42
+ const observer = new ResizeObserver(syncVideoInputBounds);
43
+ observer.observe(videoElement);
44
+ syncVideoInputBounds();
45
+ return () => {
46
+ videoElement.removeEventListener("resize", syncVideoInputBounds);
47
+ observer.disconnect();
48
+ };
49
+ }, [videoElement]);
32
50
  const sendSignal = useEffectEvent((viewerId, payload) => sendHostSignal({
33
51
  viewerId,
34
52
  payload
@@ -46,7 +64,6 @@ function BrowserLiveScreen({ sendSignal: sendHostSignal, subscribeSignals, proto
46
64
  }));
47
65
  });
48
66
  const dataChannelLabel = protocol.dataChannelLabel;
49
- const input = useRef(null);
50
67
  const handleWheel = useEffectEvent((event) => {
51
68
  event.preventDefault();
52
69
  const point = toPagePoint(event);
@@ -60,14 +77,27 @@ function BrowserLiveScreen({ sendSignal: sendHostSignal, subscribeSignals, proto
60
77
  modifiers: modifiers(event)
61
78
  }]);
62
79
  });
80
+ const [keyboardOpen, setKeyboardOpen] = useState(false);
81
+ const touch = useRef(null);
82
+ const mousePress = useRef(null);
83
+ function cancelPointerState() {
84
+ const activeTouch = touch.current;
85
+ const activeMouse = mousePress.current;
86
+ if (activeTouch) clearTimeout(activeTouch.holdTimer);
87
+ touch.current = null;
88
+ mousePress.current = null;
89
+ const releases = [];
90
+ if (activeTouch?.mode === "drag") releases.push(release(activeTouch.lastPage, "left", 0, 1, 0));
91
+ if (activeMouse?.pressed) releases.push(release(activeMouse.lastPage, activeMouse.button, 0, activeMouse.clickCount, activeMouse.modifiers));
92
+ sendInput(releases);
93
+ }
63
94
  const attachInput = useCallback((element) => {
95
+ if (input.current !== element) cancelPointerState();
64
96
  input.current?.removeEventListener("wheel", handleWheel);
65
97
  input.current = element;
66
98
  element?.addEventListener("wheel", handleWheel, { passive: false });
99
+ syncInputBounds();
67
100
  }, []);
68
- const [keyboardOpen, setKeyboardOpen] = useState(false);
69
- const touch = useRef(null);
70
- const mousePress = useRef(null);
71
101
  const [streamed, setStreamed] = useState(null);
72
102
  useEffect(() => {
73
103
  let disposed = false;
@@ -90,6 +120,7 @@ function BrowserLiveScreen({ sendSignal: sendHostSignal, subscribeSignals, proto
90
120
  const closing = connection;
91
121
  const closingViewerId = viewerId;
92
122
  connection = void 0;
123
+ cancelPointerState();
93
124
  channel.current = null;
94
125
  geometry.current = null;
95
126
  if (!disposed) setStreamed(null);
@@ -188,14 +219,19 @@ function BrowserLiveScreen({ sendSignal: sendHostSignal, subscribeSignals, proto
188
219
  const status = parseStatus(event.data);
189
220
  if (!status) return;
190
221
  if (status.kind === "idle") {
222
+ cancelPointerState();
191
223
  geometry.current = null;
224
+ syncInputBounds();
192
225
  setFailure(null);
193
226
  setPhase("idle");
194
227
  setStreamed(null);
195
228
  return;
196
229
  }
197
230
  if (status.kind === "streaming") {
231
+ const previous = geometry.current;
232
+ if (previous?.tabId !== status.tabId || previous.streamGeneration !== status.streamGeneration) cancelPointerState();
198
233
  geometry.current = status;
234
+ syncInputBounds();
199
235
  setFailure(null);
200
236
  setPhase("streaming");
201
237
  setStreamed(status);
@@ -275,11 +311,29 @@ function BrowserLiveScreen({ sendSignal: sendHostSignal, subscribeSignals, proto
275
311
  renderedTop: bounds.top + (bounds.height - renderedHeight) / 2,
276
312
  renderedWidth,
277
313
  renderedHeight,
278
- zoomX: renderedWidth / status.metadata.deviceWidth,
279
- zoomY: renderedHeight / status.metadata.deviceHeight,
280
- offsetTop: status.metadata.offsetTop
314
+ zoom: renderedWidth / status.metadata.deviceWidth
281
315
  };
282
316
  }
317
+ function syncInputBounds() {
318
+ const element = input.current;
319
+ if (!element) return;
320
+ const view = currentViewGeometry();
321
+ const surface = element.parentElement;
322
+ if (!view || !surface) {
323
+ element.style.removeProperty("inset");
324
+ element.style.removeProperty("left");
325
+ element.style.removeProperty("top");
326
+ element.style.removeProperty("width");
327
+ element.style.removeProperty("height");
328
+ return;
329
+ }
330
+ const bounds = surface.getBoundingClientRect();
331
+ element.style.inset = "auto";
332
+ element.style.left = `${view.renderedLeft - bounds.left}px`;
333
+ element.style.top = `${view.renderedTop - bounds.top}px`;
334
+ element.style.width = `${view.renderedWidth}px`;
335
+ element.style.height = `${view.renderedHeight}px`;
336
+ }
283
337
  function toPagePoint(event) {
284
338
  const view = currentViewGeometry();
285
339
  return view ? pointWithin(view, event) : null;
@@ -303,7 +357,7 @@ function BrowserLiveScreen({ sendSignal: sendHostSignal, subscribeSignals, proto
303
357
  lastPage: startPage,
304
358
  holdTimer: setTimeout(() => {
305
359
  gesture.mode = "drag";
306
- sendInput([move(startPage, 0), press(startPage)]);
360
+ sendInput([move(startPage, 0, 0), press(startPage, "left", 1, 1, 0)]);
307
361
  }, TOUCH_HOLD_MS)
308
362
  };
309
363
  touch.current = gesture;
@@ -322,8 +376,8 @@ function BrowserLiveScreen({ sendSignal: sendHostSignal, subscribeSignals, proto
322
376
  gesture.mode = "scroll";
323
377
  }
324
378
  if (gesture.mode === "scroll") {
325
- const deltaX = (gesture.lastClient.x - client.x) / gesture.view.zoomX;
326
- const deltaY = (gesture.lastClient.y - client.y) / gesture.view.zoomY;
379
+ const deltaX = (gesture.lastClient.x - client.x) / gesture.view.zoom;
380
+ const deltaY = (gesture.lastClient.y - client.y) / gesture.view.zoom;
327
381
  gesture.lastClient = client;
328
382
  if (deltaX !== 0 || deltaY !== 0) sendInput([{
329
383
  kind: "mouse",
@@ -337,7 +391,7 @@ function BrowserLiveScreen({ sendSignal: sendHostSignal, subscribeSignals, proto
337
391
  const point = pointWithin(gesture.view, event);
338
392
  if (!point) return;
339
393
  gesture.lastPage = point;
340
- sendInput([move(point, 1)]);
394
+ sendInput([move(point, 1, 0)]);
341
395
  }
342
396
  function endTouch(event, cancelled) {
343
397
  const gesture = touch.current;
@@ -348,13 +402,21 @@ function BrowserLiveScreen({ sendSignal: sendHostSignal, subscribeSignals, proto
348
402
  if (gesture.mode === "pending") {
349
403
  if (cancelled) return;
350
404
  sendInput([
351
- move(gesture.startPage, 0),
352
- press(gesture.startPage),
353
- release(gesture.startPage)
405
+ move(gesture.startPage, 0, 0),
406
+ press(gesture.startPage, "left", 1, 1, 0),
407
+ release(gesture.startPage, "left", 0, 1, 0)
354
408
  ]);
355
409
  return;
356
410
  }
357
- if (gesture.mode === "drag") sendInput([release(gesture.lastPage)]);
411
+ if (gesture.mode === "drag") sendInput([release(gesture.lastPage, "left", 0, 1, 0)]);
412
+ }
413
+ function endMouse(event) {
414
+ const gesture = mousePress.current;
415
+ if (!gesture || event.pointerId !== gesture.pointerId) return;
416
+ const point = toPagePoint(event) ?? gesture.lastPage;
417
+ mousePress.current = null;
418
+ if (!gesture.pressed) return;
419
+ sendInput([release(point, gesture.button, event.buttons, gesture.clickCount, modifiers(event))]);
358
420
  }
359
421
  const notice = failure ?? (phase === "streaming" ? void 0 : PHASE_TEXT[phase]);
360
422
  const streamedTab = streamed ? tabs.find((tab) => tab.tabId === streamed.tabId) : void 0;
@@ -425,7 +487,7 @@ function BrowserLiveScreen({ sendSignal: sendHostSignal, subscribeSignals, proto
425
487
  onKeyDown: (event) => {
426
488
  event.currentTarget.removeAttribute("data-pointer-focus");
427
489
  if (event.nativeEvent.isComposing) return;
428
- if (event.key === "Enter") event.preventDefault();
490
+ if (event.key === "Enter" || event.key === "Tab") event.preventDefault();
429
491
  sendInput([{
430
492
  kind: "key",
431
493
  type: "keyDown",
@@ -459,6 +521,15 @@ function BrowserLiveScreen({ sendSignal: sendHostSignal, subscribeSignals, proto
459
521
  event.preventDefault();
460
522
  },
461
523
  onBlur: (event) => event.currentTarget.removeAttribute("data-pointer-focus"),
524
+ onMouseDown: (event) => {
525
+ const gesture = mousePress.current;
526
+ if (!gesture || gesture.pressed) return;
527
+ gesture.button = mouseButton(event.button);
528
+ gesture.clickCount = event.detail > 0 ? event.detail : 1;
529
+ gesture.modifiers = modifiers(event);
530
+ gesture.pressed = true;
531
+ sendInput([press(gesture.lastPage, gesture.button, event.buttons, gesture.clickCount, gesture.modifiers)]);
532
+ },
462
533
  onPointerDown: (event) => {
463
534
  event.currentTarget.dataset.pointerFocus = "";
464
535
  if (event.pointerType === "touch") {
@@ -467,9 +538,20 @@ function BrowserLiveScreen({ sendSignal: sendHostSignal, subscribeSignals, proto
467
538
  }
468
539
  const point = toPagePoint(event);
469
540
  if (point) {
541
+ const button = mouseButton(event.button);
542
+ const clickCount = event.detail > 0 ? event.detail : 1;
543
+ const modifierMask = modifiers(event);
544
+ const pressed = event.pointerType !== "mouse";
470
545
  event.currentTarget.setPointerCapture(event.pointerId);
471
- mousePress.current = point;
472
- sendInput([press(point)]);
546
+ mousePress.current = {
547
+ button,
548
+ clickCount,
549
+ lastPage: point,
550
+ modifiers: modifierMask,
551
+ pointerId: event.pointerId,
552
+ pressed
553
+ };
554
+ if (pressed) sendInput([press(point, button, event.buttons, clickCount, modifierMask)]);
473
555
  }
474
556
  },
475
557
  onPointerMove: (event) => {
@@ -479,8 +561,12 @@ function BrowserLiveScreen({ sendSignal: sendHostSignal, subscribeSignals, proto
479
561
  }
480
562
  const point = toPagePoint(event);
481
563
  if (point) {
482
- if (mousePress.current) mousePress.current = point;
483
- sendInput([move(point, event.buttons)]);
564
+ const modifierMask = modifiers(event);
565
+ if (mousePress.current) {
566
+ mousePress.current.lastPage = point;
567
+ mousePress.current.modifiers = modifierMask;
568
+ }
569
+ sendInput([move(point, event.buttons, modifierMask)]);
484
570
  }
485
571
  },
486
572
  onPointerUp: (event) => {
@@ -488,9 +574,7 @@ function BrowserLiveScreen({ sendSignal: sendHostSignal, subscribeSignals, proto
488
574
  endTouch(event, false);
489
575
  return;
490
576
  }
491
- const point = toPagePoint(event) ?? mousePress.current;
492
- mousePress.current = null;
493
- if (point) sendInput([release(point)]);
577
+ endMouse(event);
494
578
  if (event.currentTarget.hasPointerCapture(event.pointerId)) event.currentTarget.releasePointerCapture(event.pointerId);
495
579
  },
496
580
  onPointerCancel: (event) => {
@@ -498,9 +582,14 @@ function BrowserLiveScreen({ sendSignal: sendHostSignal, subscribeSignals, proto
498
582
  endTouch(event, true);
499
583
  return;
500
584
  }
501
- const point = toPagePoint(event) ?? mousePress.current;
502
- mousePress.current = null;
503
- if (point) sendInput([release(point)]);
585
+ endMouse(event);
586
+ },
587
+ onLostPointerCapture: (event) => {
588
+ if (event.pointerType === "touch") {
589
+ endTouch(event, true);
590
+ return;
591
+ }
592
+ endMouse(event);
504
593
  }
505
594
  }),
506
595
  /* @__PURE__ */ jsx(Button, {
@@ -590,36 +679,49 @@ function normalizeOpenUrl(raw) {
590
679
  }
591
680
  return null;
592
681
  }
593
- const press = (p) => ({
682
+ const press = (p, button, buttons, clickCount, modifierMask) => ({
594
683
  kind: "mouse",
595
684
  type: "mousePressed",
596
685
  ...p,
597
- button: "left",
598
- buttons: 1,
599
- clickCount: 1
686
+ button,
687
+ buttons,
688
+ clickCount,
689
+ modifiers: modifierMask
600
690
  });
601
- const release = (p) => ({
691
+ const release = (p, button, buttons, clickCount, modifierMask) => ({
602
692
  kind: "mouse",
603
693
  type: "mouseReleased",
604
694
  ...p,
605
- button: "left",
606
- buttons: 0,
607
- clickCount: 1
695
+ button,
696
+ buttons,
697
+ clickCount,
698
+ modifiers: modifierMask
608
699
  });
609
- const move = (p, buttons) => ({
700
+ const move = (p, buttons, modifierMask) => ({
610
701
  kind: "mouse",
611
702
  type: "mouseMoved",
612
703
  ...p,
613
- buttons
704
+ buttons,
705
+ modifiers: modifierMask
614
706
  });
707
+ function mouseButton(button) {
708
+ return MOUSE_BUTTONS[button] ?? "none";
709
+ }
710
+ const MOUSE_BUTTONS = {
711
+ 0: "left",
712
+ 1: "middle",
713
+ 2: "right",
714
+ 3: "back",
715
+ 4: "forward"
716
+ };
615
717
  /** A client point in the picture's own page coordinates, or null if outside it. */
616
718
  function pointWithin(view, event) {
617
719
  const renderedX = event.clientX - view.renderedLeft;
618
720
  const renderedY = event.clientY - view.renderedTop;
619
721
  if (renderedX < 0 || renderedY < 0 || renderedX > view.renderedWidth || renderedY > view.renderedHeight) return null;
620
722
  return {
621
- x: renderedX / view.zoomX,
622
- y: renderedY / view.zoomY - view.offsetTop
723
+ x: renderedX / view.zoom,
724
+ y: renderedY / view.zoom
623
725
  };
624
726
  }
625
727
  /** CDP's modifier bitmask: alt, ctrl, meta, shift. */
@@ -1,4 +1,5 @@
1
1
  import { n as ResponsiveSidebarShell } from "../../ResponsiveSidebarShell-BTVPxLJK.js";
2
+ import { ThinkRoutine } from "./ThinkRoutine.js";
2
3
  import * as React from "react";
3
4
 
4
5
  //#region src/components/agents-sdk/ManagerOffice.d.ts
@@ -44,20 +45,6 @@ interface ManagerOfficeWork {
44
45
  /** Unix timestamp in milliseconds of the latest lifecycle transition. */
45
46
  updatedAt: number;
46
47
  }
47
- interface ManagerOfficeRoutine {
48
- /** Stable routine identity. */
49
- id: string;
50
- /** Human-readable recurring responsibility. */
51
- name: string;
52
- /** Human-readable schedule supplied by the host. */
53
- schedule: string;
54
- /** Whether future occurrences are enabled. */
55
- enabled: boolean;
56
- /** Completed runs among the bounded recent run history. */
57
- completedRuns: number;
58
- /** Terminal runs among the bounded recent run history. */
59
- finishedRuns: number;
60
- }
61
48
  /** Which way work moves through a channel, from the employee's side. */
62
49
  type ManagerOfficeChannelDirection = "input" | "output" | "both";
63
50
  type ManagerOfficeChannelStatus = "connected" | "needs-auth" | "error";
@@ -117,7 +104,8 @@ interface ManagerOfficeConnectedEmployee extends ManagerOfficeEmployeeBase {
117
104
  role: string;
118
105
  handoffs: readonly ManagerOfficeHandoff[];
119
106
  work: readonly ManagerOfficeWork[];
120
- routines: readonly ManagerOfficeRoutine[];
107
+ /** Whole upstream-backed routines, including their native task, schedule, and runs. */
108
+ routines: readonly ThinkRoutine[];
121
109
  /** Every service the employee reads from or acts on. Empty is meaningful. */
122
110
  channels: readonly ManagerOfficeChannel[];
123
111
  /** The live tab the manager can glance at from the office. */
@@ -151,7 +139,7 @@ type ManagerOfficeDestination = {
151
139
  } | {
152
140
  kind: "routine";
153
141
  employee: ManagerOfficeConnectedEmployee;
154
- routine: ManagerOfficeRoutine;
142
+ routine: ThinkRoutine;
155
143
  } | {
156
144
  kind: "new-work";
157
145
  employee: ManagerOfficeConnectedEmployee;
@@ -260,4 +248,4 @@ declare function ManagerOffice({
260
248
  ...props
261
249
  }: ManagerOfficeProps): React.JSX.Element;
262
250
  //#endregion
263
- export { ManagerOffice, ManagerOfficeAnalyticsPoint, ManagerOfficeBrowserPreview, ManagerOfficeChannel, ManagerOfficeChannelDirection, ManagerOfficeChannelStatus, ManagerOfficeConnectedEmployee, ManagerOfficeDestination, ManagerOfficeDisconnectedEmployee, ManagerOfficeEmployee, ManagerOfficeEmployeeAnalytics, ManagerOfficeEmployeeStatus, ManagerOfficeHandoff, ManagerOfficeProps, ManagerOfficeReportSelection, ManagerOfficeRoutine, ManagerOfficeSidebar, ManagerOfficeSidebarAlert, ManagerOfficeSidebarAlertProps, ManagerOfficeSidebarProps, ManagerOfficeView, ManagerOfficeWork, ManagerOfficeWorkStatus };
251
+ export { ManagerOffice, ManagerOfficeAnalyticsPoint, ManagerOfficeBrowserPreview, ManagerOfficeChannel, ManagerOfficeChannelDirection, ManagerOfficeChannelStatus, ManagerOfficeConnectedEmployee, ManagerOfficeDestination, ManagerOfficeDisconnectedEmployee, ManagerOfficeEmployee, ManagerOfficeEmployeeAnalytics, ManagerOfficeEmployeeStatus, ManagerOfficeHandoff, ManagerOfficeProps, ManagerOfficeReportSelection, ManagerOfficeSidebar, ManagerOfficeSidebarAlert, ManagerOfficeSidebarAlertProps, ManagerOfficeSidebarProps, ManagerOfficeView, ManagerOfficeWork, ManagerOfficeWorkStatus };
@@ -15,6 +15,7 @@ import { LinkButton } from "../foundations/LinkButton.js";
15
15
  import "../foundations/icons.js";
16
16
  import { AppTopBar } from "../general-purpose/AppTopBar.js";
17
17
  import { ResponsiveSidebarShell } from "../general-purpose/ResponsiveSidebarShell.js";
18
+ import { getThinkExecutionRunStatus } from "./ThinkExecutionRun.js";
18
19
  import * as React from "react";
19
20
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
20
21
  //#region src/components/_internal/chrome-profile-colors.ts
@@ -354,6 +355,15 @@ function relativeTime(timestamp, now) {
354
355
  if (elapsed < day) return `${Math.floor(elapsed / hour)}h`;
355
356
  return `${Math.floor(elapsed / day)}d`;
356
357
  }
358
+ function routineDetail(routine) {
359
+ const schedule = routine.enabled ? routine.task.schedule : `Paused · ${routine.task.schedule}`;
360
+ const finishedRuns = routine.runs.filter((run) => run.completedAt != null);
361
+ if (!finishedRuns.length) return schedule;
362
+ return `${schedule} · ${finishedRuns.filter((run) => {
363
+ const status = getThinkExecutionRunStatus(run);
364
+ return status === "completed" || status === "complete";
365
+ }).length} of ${finishedRuns.length} recent runs completed`;
366
+ }
357
367
  function Timestamp({ now, timestamp }) {
358
368
  const date = new Date(timestamp);
359
369
  return /* @__PURE__ */ jsx("time", {
@@ -938,10 +948,14 @@ function DashboardCard({ card, collapsed, color, index, now, onToggleCollapsed,
938
948
  });
939
949
  }
940
950
  function DashboardFilterMenu({ label, onToggle, options, selected }) {
941
- return /* @__PURE__ */ jsxs(Menu.Root, { children: [/* @__PURE__ */ jsxs(Menu.Trigger, {
951
+ return /* @__PURE__ */ jsxs(Menu.Root, { children: [/* @__PURE__ */ jsxs(Button, {
952
+ variant: "outline",
953
+ color: "neutral",
954
+ size: "sm",
942
955
  "aria-label": `${label} filter`,
943
956
  className: "manager-office__filter-trigger",
944
957
  "data-active": selected.size || void 0,
958
+ render: /* @__PURE__ */ jsx(Menu.Trigger, { unstyled: true }),
945
959
  children: [
946
960
  /* @__PURE__ */ jsx("span", { children: label }),
947
961
  selected.size ? /* @__PURE__ */ jsx("strong", { children: selected.size }) : null,
@@ -961,10 +975,12 @@ function DashboardFilterMenu({ label, onToggle, options, selected }) {
961
975
  }) })] });
962
976
  }
963
977
  function AssignWorkMenu({ employees, profileColors, renderLink }) {
964
- return /* @__PURE__ */ jsxs(Menu.Root, { children: [/* @__PURE__ */ jsxs(Menu.Trigger, {
978
+ return /* @__PURE__ */ jsxs(Menu.Root, { children: [/* @__PURE__ */ jsxs(Button, {
979
+ size: "sm",
965
980
  className: "manager-office__assignment-trigger",
966
981
  disabled: !employees.length,
967
- children: [/* @__PURE__ */ jsx("span", { children: "Assign work" }), /* @__PURE__ */ jsx(ChevronDownIcon, {})]
982
+ render: /* @__PURE__ */ jsx(Menu.Trigger, { unstyled: true }),
983
+ children: ["Assign work", /* @__PURE__ */ jsx(ChevronDownIcon, {})]
968
984
  }), /* @__PURE__ */ jsx(Menu.Portal, { children: /* @__PURE__ */ jsx(Menu.Positioner, {
969
985
  align: "end",
970
986
  sideOffset: 6,
@@ -1592,7 +1608,7 @@ function EmployeeDetail({ employee, renderLink, now, profileColor }) {
1592
1608
  children: routine.name
1593
1609
  }), /* @__PURE__ */ jsx("small", {
1594
1610
  className: "sigvelo-truncate",
1595
- children: routine.enabled ? routine.schedule : `Paused · ${routine.schedule}`
1611
+ children: routineDetail(routine)
1596
1612
  })]
1597
1613
  }),
1598
1614
  /* @__PURE__ */ jsx(ChevronRightIcon, { className: "manager-office__row-chevron" })
@@ -1,4 +1,4 @@
1
- import { o as McpServerCard } from "../../mcp-server-catalog-Cbu483Zb.js";
1
+ import { o as McpServerCard } from "../../mcp-server-catalog-C_g7C-9o.js";
2
2
  import * as React from "react";
3
3
  import { DynamicToolUIPart, ToolUIPart } from "ai";
4
4
  import { MCPServersState } from "agents";
@@ -1,2 +1,2 @@
1
- import { n as McpConnectorFormProps, r as McpConnectorFormValues, t as McpConnectorForm } from "../../McpConnectorForm-BETdVBRk.js";
1
+ import { n as McpConnectorFormProps, r as McpConnectorFormValues, t as McpConnectorForm } from "../../McpConnectorForm-CeYNY0MI.js";
2
2
  export { McpConnectorForm, McpConnectorFormProps, McpConnectorFormValues };
@@ -1,2 +1,2 @@
1
- import { a as McpPluginDetailsDialogProps, i as McpPluginDetailsDialog, n as McpPluginCatalogProps, r as McpPluginDetails, t as McpPluginCatalog } from "../../McpPluginCatalog-C6ip9IvL.js";
1
+ import { a as McpPluginDetailsDialogProps, i as McpPluginDetailsDialog, n as McpPluginCatalogProps, r as McpPluginDetails, t as McpPluginCatalog } from "../../McpPluginCatalog-3qWu8oK1.js";
2
2
  export { McpPluginCatalog, McpPluginCatalogProps, McpPluginDetails, McpPluginDetailsDialog, McpPluginDetailsDialogProps };
@@ -1,6 +1,6 @@
1
1
  import { s as MenuItemProps, t as Menu } from "../../Menu-yb6QXWA3.js";
2
- import { o as McpServerCard } from "../../mcp-server-catalog-Cbu483Zb.js";
3
- import { n as McpConnectorFormProps } from "../../McpConnectorForm-BETdVBRk.js";
2
+ import { o as McpServerCard } from "../../mcp-server-catalog-C_g7C-9o.js";
3
+ import { n as McpConnectorFormProps } from "../../McpConnectorForm-CeYNY0MI.js";
4
4
  import { l as DialogProps } from "../../Dialog-B_FhRWaz.js";
5
5
  import * as React from "react";
6
6
  import { MCPServersState } from "agents";
@@ -1,7 +1,7 @@
1
1
  import { l as WorkspaceNavigationAdapter } from "../../WorkspaceLink-Bh9-Jo1r.js";
2
2
  import { n as AgentToolEventsValue } from "../../AgentToolRunsContext-jtmveaRE.js";
3
3
  import { n as ResponsiveSidebarShell, t as AppBarSlots } from "../../ResponsiveSidebarShell-BTVPxLJK.js";
4
- import { n as McpPluginCatalogProps } from "../../McpPluginCatalog-C6ip9IvL.js";
4
+ import { n as McpPluginCatalogProps } from "../../McpPluginCatalog-3qWu8oK1.js";
5
5
  import { ThinkChatMessagesProps } from "./ThinkChat.js";
6
6
  import { ThinkThreadStatusSummary } from "./ThinkThreadPicker.js";
7
7
  import { r as WorkspaceFileAssetResolver } from "../../WorkspaceFile-Dq-GC0_T.js";
@@ -1,7 +1,7 @@
1
+ import { ThinkRoutine } from "./ThinkRoutine.js";
1
2
  import { ThinkChatDraft } from "./ThinkChat.js";
2
3
  import { ThinkThreadItem } from "./ThinkThreadPicker.js";
3
4
  import { ThinkFullAppAgent, ThinkFullAppConversation, ThinkFullAppProps } from "./ThinkFullApp.js";
4
- import { ThinkRoutine } from "./ThinkRoutine.js";
5
5
  import { SetupChecklistEntry } from "../general-purpose/SetupChecklist.js";
6
6
  import * as React from "react";
7
7
  import { UIMessage } from "ai";
@@ -18,8 +18,8 @@ import { AppTopBar } from "../general-purpose/AppTopBar.js";
18
18
  import { t as SetupChecklistAction } from "../../SetupChecklist-DyPZWzK2.js";
19
19
  import { NaniteMark } from "../nanites/NaniteScene.js";
20
20
  import { SubagentRunLabel } from "./SubagentRunIndicator.js";
21
- import { McpServerPickerAction, McpServerPickerItems } from "./McpServerPicker.js";
22
21
  import { getThinkExecutionRunId } from "./ThinkExecutionRun.js";
22
+ import { McpServerPickerAction, McpServerPickerItems } from "./McpServerPicker.js";
23
23
  import { ThinkThreadPicker, summarizeThinkThreads } from "./ThinkThreadPicker.js";
24
24
  import { ThinkFullApp } from "./ThinkFullApp.js";
25
25
  import { ThinkRoutineLibrary } from "./ThinkRoutineLibrary.js";
@@ -420,6 +420,30 @@ declare const MANUAL_MCP_SERVER_CARDS: readonly [{
420
420
  readonly url: "https://developers.asana.com/docs/connecting-mcp-clients-to-asanas-v2-server";
421
421
  }];
422
422
  };
423
+ }, {
424
+ readonly id: "github";
425
+ readonly name: "GitHub";
426
+ readonly url: "https://api.githubcopilot.com/mcp/";
427
+ readonly description: "Clone, push, and open pull requests as a connected GitHub account";
428
+ readonly category: "Manual";
429
+ readonly manualSetup: {
430
+ readonly auth: {
431
+ readonly type: "bearer";
432
+ readonly label: "Personal access token (classic)";
433
+ readonly fields: readonly [{
434
+ readonly name: "bearerToken";
435
+ readonly label: "Personal access token";
436
+ readonly inputType: "password";
437
+ readonly placeholder: "ghp_…";
438
+ readonly required: true;
439
+ }];
440
+ };
441
+ readonly description: "Paste a classic personal access token with all scopes from the agent's own GitHub account — the account is the access boundary. Git and the GitHub API both authenticate as this account.";
442
+ readonly links: readonly [{
443
+ readonly label: "Create a classic token";
444
+ readonly url: "https://github.com/settings/tokens";
445
+ }];
446
+ };
423
447
  }, {
424
448
  readonly id: "gmail";
425
449
  readonly name: "Gmail";
@@ -1,18 +1,20 @@
1
1
  /*
2
- * Standalone stylesheet for browser-control chrome mounted in a closed shadow
3
- * root. It intentionally uses system colors so it remains legible on arbitrary
4
- * pages without leaking the full document-level token sheet into the host.
2
+ * Browser-control chrome, mounted in a closed shadow root on someone else's
3
+ * page. This standalone design-system leaf is isolated by `:host { all:
4
+ * initial }`, so it shares no variable, scale, or primitive with the document
5
+ * stylesheet.
5
6
  *
6
- * Every length here is a literal on purpose. The token layer does not exist
7
- * inside this shadow root, so a --sigvelo-* reference resolves to nothing and
8
- * takes its whole declaration with it silently, and only on a real host page,
9
- * which is the one place this is hard to notice. Keep the values on the 4px
10
- * grid by hand; audit:css-recipes checks both halves of that.
7
+ * Every length is a literal on purpose. A --sigvelo-* reference here resolves
8
+ * to nothing and silently takes its whole declaration with it, and only on a
9
+ * real host page the one place that is hardest to notice. Keep the values on
10
+ * the 4px grid by hand.
11
+ *
12
+ * System colors keep the chrome legible on an arbitrary page's palette and in
13
+ * forced-colors mode.
11
14
  */
12
15
 
13
16
  :host {
14
17
  --browser-control-accent: Highlight;
15
- --browser-control-accent-text: HighlightText;
16
18
  --browser-control-warning: Mark;
17
19
  --browser-control-warning-text: MarkText;
18
20
  --browser-control-shadow: color-mix(in srgb, CanvasText 28%, transparent);
@@ -31,50 +33,56 @@
31
33
  z-index: 2147483647;
32
34
  }
33
35
 
36
+ /*
37
+ * Only the waiting mode draws an edge. A tab under agent control is identified
38
+ * by its pointer; a border around the whole viewport reads as an error state
39
+ * and hides the page's own chrome. Waiting is the exception because the page
40
+ * is being handed back and the user has to notice.
41
+ */
34
42
  :host .frame {
35
- background: color-mix(in srgb, var(--browser-control-accent) 5%, transparent);
36
- border: 3px solid color-mix(in srgb, var(--browser-control-accent) 88%, transparent);
37
- box-shadow: inset 0 0 18px color-mix(in srgb, var(--browser-control-accent) 28%, transparent);
43
+ box-shadow:
44
+ inset 0 0 0 3px var(--browser-control-warning),
45
+ inset 0 0 24px color-mix(in srgb, var(--browser-control-warning) 32%, transparent);
38
46
  box-sizing: border-box;
39
47
  inset: 0;
40
48
  pointer-events: none;
41
49
  position: fixed;
42
50
  }
43
51
 
44
- :host .frame.waiting {
45
- background: color-mix(in srgb, var(--browser-control-warning) 12%, transparent);
46
- border-color: var(--browser-control-warning);
47
- box-shadow: inset 0 0 18px color-mix(in srgb, var(--browser-control-warning) 32%, transparent);
48
- }
49
-
52
+ /*
53
+ * The pointer artwork. The file is cropped to its alpha, and the alpha includes
54
+ * the soft white halo -- so the arrow's ink apex, which is what the eye reads as
55
+ * the point, sits 5px into a 40x41 image, or 3.41px once `contain` renders it
56
+ * 28px tall. The box is offset by that much and the pivot moved onto it, so the
57
+ * apex lands on the page's pointer and every rotation the planner emits turns
58
+ * about it. Shifting the background instead would do the same thing and clip the
59
+ * halo off the leading edge.
60
+ *
61
+ * Position comes from the Web Animations API during a move and from
62
+ * --think-cursor-x/y at rest; no transform transition, since a CSS transition
63
+ * and a script-driven animation would fight over the same property.
64
+ */
50
65
  :host .cursor {
51
- filter: drop-shadow(0 2px 4px var(--browser-control-shadow));
66
+ background: url(../assets/browser-control-cursor.png) no-repeat 0 0 / contain;
67
+ /* Two shadows rather than one: a tight halo that separates the artwork from
68
+ whatever it is over, and a wide one that reads as the accent glow. */
69
+ filter: drop-shadow(0 0 6px color-mix(in srgb, var(--browser-control-accent) 90%, transparent))
70
+ drop-shadow(0 0 15px color-mix(in srgb, var(--browser-control-accent) 48%, transparent));
52
71
  height: 28px;
53
- left: 0;
54
- opacity: 0;
72
+ left: -3.41px;
55
73
  pointer-events: none;
56
74
  position: fixed;
57
- top: 0;
75
+ top: -3.41px;
58
76
  transform: translate3d(var(--think-cursor-x, 16px), var(--think-cursor-y, 16px), 0);
59
- transition:
60
- transform 140ms cubic-bezier(0.2, 0.8, 0.2, 1),
61
- opacity 80ms linear;
77
+ /* The ink apex, not the box corner and not the centre. The offset above puts
78
+ this point on the pointer, and the body swings around it. */
79
+ transform-origin: 3.41px 3.41px;
62
80
  width: 28px;
63
81
  }
64
82
 
65
- :host .cursor.visible {
66
- opacity: 1;
67
- }
68
-
69
- :host .cursor path {
70
- fill: var(--browser-control-accent);
71
- stroke: var(--browser-control-accent-text);
72
- }
73
-
74
83
  :host button {
75
84
  appearance: none;
76
85
  border-radius: 999px;
77
- box-shadow: 0 2px 10px var(--browser-control-shadow);
78
86
  cursor: pointer;
79
87
  font:
80
88
  600 12px/1.2 system-ui,
@@ -92,41 +100,6 @@
92
100
  opacity: 0.72;
93
101
  }
94
102
 
95
- :host .takeover,
96
- :host .owner {
97
- background: var(--browser-control-accent);
98
- border: solid 1px var(--browser-control-accent-text);
99
- box-shadow: 0 2px 10px var(--browser-control-shadow);
100
- color: var(--browser-control-accent-text);
101
- }
102
-
103
- :host .takeover {
104
- pointer-events: none;
105
- position: fixed;
106
- right: 10px;
107
- top: 10px;
108
- }
109
-
110
- :host .takeover.takeover-armed {
111
- pointer-events: auto;
112
- }
113
-
114
- :host .owner {
115
- border-radius: 999px;
116
- font:
117
- 600 12px/1.2 system-ui,
118
- sans-serif;
119
- left: 10px;
120
- max-width: min(360px, 60vw);
121
- overflow: hidden;
122
- padding: 8px 12px;
123
- pointer-events: none;
124
- position: fixed;
125
- text-overflow: ellipsis;
126
- top: 10px;
127
- white-space: nowrap;
128
- }
129
-
130
103
  :host .banner {
131
104
  align-items: center;
132
105
  background: var(--browser-control-warning);
@@ -158,6 +131,7 @@
158
131
  :host .banner .done,
159
132
  :host .banner .cannot {
160
133
  border: solid 1px currentcolor;
134
+ box-shadow: 0 2px 10px var(--browser-control-shadow);
161
135
  color: inherit;
162
136
  flex-shrink: 0;
163
137
  }
@@ -171,12 +145,6 @@
171
145
  box-shadow: none;
172
146
  }
173
147
 
174
- @media (prefers-reduced-motion: reduce) {
175
- :host .cursor {
176
- transition: none;
177
- }
178
- }
179
-
180
148
  @media print {
181
149
  :host {
182
150
  display: none !important;
@@ -184,10 +152,8 @@
184
152
  }
185
153
 
186
154
  @media (forced-colors: active) {
187
- :host .frame,
188
- :host .takeover,
189
- :host .owner,
190
155
  :host .banner {
191
- forced-color-adjust: none;
156
+ background: Canvas;
157
+ color: CanvasText;
192
158
  }
193
159
  }
@@ -0,0 +1,46 @@
1
+ /*
2
+ * Standalone extension interstitial. It intentionally does not load the token
3
+ * cascade; system colors follow the user's light, dark, and forced-color theme.
4
+ */
5
+
6
+ .extension-status-page {
7
+ background: Canvas;
8
+ color: CanvasText;
9
+ color-scheme: light dark;
10
+ display: grid;
11
+ font:
12
+ 0.875rem/1.5 system-ui,
13
+ -apple-system,
14
+ BlinkMacSystemFont,
15
+ "Segoe UI",
16
+ Roboto,
17
+ sans-serif;
18
+ margin: 0;
19
+ min-block-size: 100dvb;
20
+ place-items: center;
21
+ }
22
+
23
+ .extension-status {
24
+ /* Mirrors --sigvelo-layout-gutter without loading the document token sheet. */
25
+ display: grid;
26
+ gap: 0.75rem;
27
+ justify-items: center;
28
+ max-inline-size: 30rem;
29
+ padding: 0.75rem;
30
+ text-align: center;
31
+ }
32
+
33
+ .extension-status h1 {
34
+ font-size: inherit;
35
+ font-weight: 600;
36
+ margin: 0;
37
+ }
38
+
39
+ .extension-status p {
40
+ color: GrayText;
41
+ margin: 0;
42
+ }
43
+
44
+ .extension-status button {
45
+ font: inherit;
46
+ }
@@ -86,7 +86,6 @@
86
86
  @import "./artifact.css" layer(components);
87
87
  @import "./browser-live-view.css" layer(components);
88
88
  @import "./browser-live-screen.css" layer(components);
89
- @import "./browser-control-overlay.css" layer(components);
90
89
  @import "./browser-run-panel.css" layer(components);
91
90
  @import "./chain-of-thought.css" layer(components);
92
91
  @import "./checkpoint.css" layer(components);
@@ -12,12 +12,6 @@
12
12
  background: var(--sigvelo-color-surface);
13
13
  }
14
14
 
15
- .manager-office--dashboard .app-top-bar__title {
16
- font-size: var(--sigvelo-text-base);
17
- font-weight: var(--sigvelo-font-weight-bold);
18
- line-height: var(--sigvelo-text-base-leading);
19
- }
20
-
21
15
  .manager-office__dashboard {
22
16
  min-inline-size: 0;
23
17
  min-block-size: 0;
@@ -180,24 +174,6 @@
180
174
  background: transparent;
181
175
  }
182
176
 
183
- .manager-office__add-employee {
184
- min-inline-size: var(--sigvelo-control-height-md);
185
- min-block-size: var(--sigvelo-control-height-md);
186
- padding: var(--sigvelo-spacing-1);
187
- border: 0;
188
- border-radius: var(--sigvelo-radius-md);
189
- background: transparent;
190
- }
191
-
192
- .manager-office__add-employee:hover:not([data-disabled]) {
193
- background: var(--sigvelo-color-neutral-bg-subtle);
194
- }
195
-
196
- .manager-office__add-employee > svg {
197
- inline-size: var(--sigvelo-density-compact-control-icon-size);
198
- block-size: var(--sigvelo-density-compact-control-icon-size);
199
- }
200
-
201
177
  .manager-office__filters-main {
202
178
  flex: 1;
203
179
  min-inline-size: 0;
@@ -240,14 +216,8 @@
240
216
  }
241
217
 
242
218
  .manager-office__filter-trigger {
243
- min-block-size: var(--sigvelo-control-height-md);
244
219
  flex: none;
245
- display: inline-flex;
246
- align-items: center;
247
220
  gap: var(--sigvelo-spacing-1);
248
- border-color: var(--sigvelo-color-neutral-border-muted);
249
- background: var(--sigvelo-color-surface);
250
- font-size: var(--sigvelo-text-xs);
251
221
  }
252
222
 
253
223
  .manager-office__filter-trigger[data-active] {
@@ -260,12 +230,6 @@
260
230
  font-size: var(--sigvelo-text-2xs);
261
231
  }
262
232
 
263
- .manager-office__filter-trigger > svg {
264
- inline-size: var(--sigvelo-density-compact-control-icon-size);
265
- block-size: var(--sigvelo-density-compact-control-icon-size);
266
- color: var(--sigvelo-color-text-muted);
267
- }
268
-
269
233
  .manager-office__filter-clear {
270
234
  flex: none;
271
235
  gap: var(--sigvelo-spacing-1);
@@ -296,13 +260,8 @@
296
260
 
297
261
  .manager-office__analytics {
298
262
  min-inline-size: 0;
299
- padding: var(--sigvelo-spacing-4);
300
263
  display: grid;
301
- gap: var(--sigvelo-spacing-3);
302
- border: var(--sigvelo-border-style) var(--sigvelo-border-width)
303
- var(--sigvelo-color-neutral-border-subtle);
304
- border-radius: var(--sigvelo-radius-lg);
305
- background: color-mix(in oklab, var(--sigvelo-color-neutral-bg-subtle), transparent 38%);
264
+ gap: var(--sigvelo-layout-gap);
306
265
  }
307
266
 
308
267
  .manager-office__analytics-header {
@@ -315,9 +274,6 @@
315
274
 
316
275
  .manager-office__analytics-header h2 {
317
276
  margin: 0;
318
- }
319
-
320
- .manager-office__analytics-header h2 {
321
277
  font-size: var(--sigvelo-text-base);
322
278
  line-height: var(--sigvelo-text-base-leading);
323
279
  }
@@ -357,15 +313,11 @@
357
313
 
358
314
  .manager-office__analytics-series {
359
315
  min-inline-size: 0;
360
- padding: var(--sigvelo-spacing-3);
316
+ padding: var(--sigvelo-spacing-3) 0;
361
317
  display: grid;
362
318
  grid-template-columns: minmax(0, 1fr);
363
319
  align-content: start;
364
320
  gap: var(--sigvelo-spacing-2);
365
- border: var(--sigvelo-border-style) var(--sigvelo-border-width)
366
- var(--sigvelo-color-neutral-border-muted);
367
- border-radius: var(--sigvelo-radius-md);
368
- background: var(--sigvelo-color-surface);
369
321
  color: var(--sigvelo-color-viz-series-1);
370
322
  }
371
323
 
@@ -492,34 +444,10 @@
492
444
  }
493
445
 
494
446
  .manager-office__assignment-trigger {
495
- min-block-size: var(--sigvelo-control-height-md);
496
- display: inline-flex;
497
- align-items: center;
498
- justify-content: flex-start;
499
- gap: var(--sigvelo-spacing-2);
500
- border-color: var(--sigvelo-color-primary-bg);
501
- background: var(--sigvelo-color-primary-bg);
502
- color: var(--sigvelo-color-primary-text-on-bg);
503
- font-size: var(--sigvelo-text-xs);
447
+ flex: none;
504
448
  white-space: nowrap;
505
449
  }
506
450
 
507
- .manager-office__assignment-trigger > svg {
508
- inline-size: var(--sigvelo-density-compact-control-icon-size);
509
- block-size: var(--sigvelo-density-compact-control-icon-size);
510
- }
511
-
512
- .manager-office__assignment-trigger > svg:last-child {
513
- }
514
-
515
- .manager-office__assignment-trigger:hover:not([data-disabled]) {
516
- background: var(--sigvelo-color-primary-bg-hover);
517
- }
518
-
519
- .manager-office__assignment-trigger:active:not([data-disabled]) {
520
- background: var(--sigvelo-color-primary-bg-press);
521
- }
522
-
523
451
  .manager-office__assignment-popup {
524
452
  inline-size: min(22rem, calc(100vw - 2 * var(--sigvelo-spacing-4)));
525
453
  max-block-size: 24rem;
@@ -696,7 +624,6 @@
696
624
  border-radius: var(--sigvelo-radius-md);
697
625
  background: var(--sigvelo-color-surface);
698
626
  color: var(--sigvelo-color-text);
699
- box-shadow: var(--sigvelo-elevation-raised);
700
627
  }
701
628
 
702
629
  .manager-office__dashboard-card-header {
@@ -709,7 +636,6 @@
709
636
 
710
637
  .manager-office__dashboard-card[data-collapsed] {
711
638
  gap: 0;
712
- box-shadow: none;
713
639
  }
714
640
 
715
641
  .manager-office__dashboard-card-owner,
@@ -765,10 +691,10 @@
765
691
  }
766
692
 
767
693
  .manager-office__browser-chrome {
768
- block-size: 1.45rem;
694
+ block-size: var(--sigvelo-spacing-6);
769
695
  padding-inline: var(--sigvelo-spacing-2);
770
696
  display: grid;
771
- grid-template-columns: repeat(3, 0.35rem) minmax(0, 1fr);
697
+ grid-template-columns: repeat(3, var(--sigvelo-spacing-1-5)) minmax(0, 1fr);
772
698
  align-items: center;
773
699
  gap: var(--sigvelo-spacing-1);
774
700
  border-block-end: var(--sigvelo-border-style) var(--sigvelo-border-width)
@@ -777,8 +703,8 @@
777
703
  }
778
704
 
779
705
  .manager-office__browser-chrome > span {
780
- inline-size: 0.35rem;
781
- block-size: 0.35rem;
706
+ inline-size: var(--sigvelo-spacing-1-5);
707
+ block-size: var(--sigvelo-spacing-1-5);
782
708
  border-radius: 50%;
783
709
  background: var(--sigvelo-color-neutral-border);
784
710
  }
@@ -789,14 +715,15 @@
789
715
  min-inline-size: 0;
790
716
  overflow: hidden;
791
717
  color: var(--sigvelo-color-text-subtle);
792
- font-size: 0.55em;
718
+ font-size: var(--sigvelo-text-2xs);
719
+ line-height: var(--sigvelo-text-2xs-leading);
793
720
  text-overflow: ellipsis;
794
721
  white-space: nowrap;
795
722
  }
796
723
 
797
724
  .manager-office__browser-page {
798
725
  position: absolute;
799
- inset: 1.45rem 0 0;
726
+ inset: var(--sigvelo-spacing-6) 0 0;
800
727
  padding: var(--sigvelo-spacing-3);
801
728
  display: grid;
802
729
  grid-template-columns: auto minmax(0, 1fr);
@@ -809,8 +736,8 @@
809
736
  }
810
737
 
811
738
  .manager-office__browser-page-mark {
812
- inline-size: 1.35rem;
813
- block-size: 1.35rem;
739
+ inline-size: var(--sigvelo-spacing-5);
740
+ block-size: var(--sigvelo-spacing-5);
814
741
  border-radius: var(--sigvelo-radius-sm);
815
742
  background: var(--sigvelo-color-primary-bg);
816
743
  }
@@ -818,7 +745,7 @@
818
745
  min-inline-size: 0;
819
746
  display: grid;
820
747
  align-content: start;
821
- gap: 2px;
748
+ gap: var(--sigvelo-spacing-0-5);
822
749
  }
823
750
  .manager-office__browser-page-copy strong,
824
751
  .manager-office__browser-page-copy small {
@@ -827,13 +754,13 @@
827
754
  white-space: nowrap;
828
755
  }
829
756
  .manager-office__browser-page-copy strong {
830
- font-size: 0.68em;
831
- line-height: var(--sigvelo-leading-tight);
757
+ font-size: var(--sigvelo-text-2xs);
758
+ line-height: var(--sigvelo-text-2xs-leading);
832
759
  }
833
760
  .manager-office__browser-page-copy small {
834
761
  color: var(--sigvelo-color-text-muted);
835
- font-size: 0.52em;
836
- line-height: var(--sigvelo-leading-tight);
762
+ font-size: var(--sigvelo-text-2xs);
763
+ line-height: var(--sigvelo-text-2xs-leading);
837
764
  }
838
765
  .manager-office__browser-page-lines {
839
766
  grid-column: 1 / -1;
@@ -857,11 +784,11 @@
857
784
  position: absolute;
858
785
  inset-inline-end: 22%;
859
786
  inset-block-end: 22%;
860
- inline-size: 0.55rem;
861
- block-size: 0.75rem;
787
+ inline-size: var(--sigvelo-spacing-2-5);
788
+ block-size: var(--sigvelo-spacing-3);
862
789
  background: var(--sigvelo-color-text);
863
790
  clip-path: polygon(0 0, 100% 70%, 58% 72%, 42% 100%);
864
- animation: manager-office-browser-cursor 2.8s ease-in-out infinite;
791
+ animation: manager-office-browser-cursor 2.8s var(--sigvelo-ease-standard) infinite;
865
792
  }
866
793
  @keyframes manager-office-browser-cursor {
867
794
  0%,
@@ -880,12 +807,13 @@
880
807
  align-items: center;
881
808
  gap: var(--sigvelo-spacing-1);
882
809
  color: var(--sigvelo-color-text-muted);
883
- font-size: 0.58em;
810
+ font-size: var(--sigvelo-text-2xs);
884
811
  font-weight: var(--sigvelo-font-weight-semibold);
812
+ line-height: var(--sigvelo-text-2xs-leading);
885
813
  }
886
814
  .manager-office__browser-state > svg {
887
- inline-size: 0.65rem;
888
- block-size: 0.65rem;
815
+ inline-size: var(--sigvelo-control-icon-size-xs);
816
+ block-size: var(--sigvelo-control-icon-size-xs);
889
817
  }
890
818
  .manager-office__browser-preview[data-lane="working"] .manager-office__browser-state {
891
819
  color: var(--sigvelo-color-primary-text);
@@ -954,9 +882,6 @@
954
882
  .manager-office__filters-main {
955
883
  flex: none;
956
884
  }
957
- .manager-office__analytics {
958
- padding: var(--sigvelo-spacing-3);
959
- }
960
885
  .manager-office__analytics-header {
961
886
  align-items: stretch;
962
887
  flex-direction: column;
@@ -993,10 +918,6 @@
993
918
  @media (width <= 38rem) {
994
919
  .manager-office__assignment-trigger {
995
920
  inline-size: auto;
996
- min-block-size: var(--sigvelo-density-compact-control-height);
997
- padding-inline: var(--sigvelo-spacing-2);
998
- gap: var(--sigvelo-spacing-1);
999
- font-size: var(--sigvelo-text-xs);
1000
921
  }
1001
922
  }
1002
923
 
@@ -1078,7 +999,7 @@
1078
999
  }
1079
1000
 
1080
1001
  .manager-office__employee-nav {
1081
- --manager-office-roster-scrollbar-size: 4px;
1002
+ --manager-office-roster-scrollbar-size: var(--sigvelo-spacing-1);
1082
1003
  min-inline-size: 0;
1083
1004
  margin: 0;
1084
1005
  padding: var(--sigvelo-spacing-1) var(--sigvelo-spacing-2);
@@ -1253,8 +1174,8 @@
1253
1174
  position: absolute;
1254
1175
  inset-inline-start: 50%;
1255
1176
  inset-block-end: -1px;
1256
- inline-size: 1.125rem;
1257
- block-size: 2px;
1177
+ inline-size: var(--sigvelo-spacing-4);
1178
+ block-size: var(--sigvelo-spacing-0-5);
1258
1179
  border-radius: var(--sigvelo-radius-full);
1259
1180
  background: var(--sigvelo-color-text);
1260
1181
  content: "";
@@ -1334,13 +1255,13 @@
1334
1255
  position: absolute;
1335
1256
  inset-inline-end: -1px;
1336
1257
  inset-block-end: -1px;
1337
- inline-size: 15px;
1338
- block-size: 15px;
1258
+ inline-size: var(--sigvelo-spacing-4);
1259
+ block-size: var(--sigvelo-spacing-4);
1339
1260
  display: grid;
1340
1261
  place-items: center;
1341
1262
  border-radius: var(--sigvelo-radius-xs);
1342
1263
  background: var(--sigvelo-color-surface);
1343
- box-shadow: 0 0 0 1.5px var(--sigvelo-color-surface);
1264
+ box-shadow: 0 0 0 var(--sigvelo-border-width) var(--sigvelo-color-surface);
1344
1265
  }
1345
1266
 
1346
1267
  .manager-office__identity {
@@ -1634,25 +1555,24 @@
1634
1555
  }
1635
1556
 
1636
1557
  .manager-office__nav-status > svg {
1637
- inline-size: 11px;
1638
- block-size: 11px;
1639
- stroke-width: 2.35;
1558
+ inline-size: var(--sigvelo-control-icon-size-xs);
1559
+ block-size: var(--sigvelo-control-icon-size-xs);
1640
1560
  }
1641
1561
 
1642
1562
  .manager-office__nav-status:is([data-status="needs-you"], [data-status="issue"]) {
1643
- color: light-dark(#b3261e, #ff8a80);
1563
+ color: var(--sigvelo-color-danger-text);
1644
1564
  }
1645
1565
 
1646
1566
  .manager-office__nav-status[data-status="unavailable"] {
1647
- color: light-dark(#7c2d12, #fb923c);
1567
+ color: var(--sigvelo-color-warning-text);
1648
1568
  }
1649
1569
 
1650
1570
  .manager-office__nav-status[data-status="idle"] {
1651
- color: light-dark(#087f5b, #4fd1a1);
1571
+ color: var(--sigvelo-color-text-muted);
1652
1572
  }
1653
1573
 
1654
1574
  .manager-office__nav-status[data-status="offline"] {
1655
- color: light-dark(#667085, #a7afbe);
1575
+ color: var(--sigvelo-color-text-muted);
1656
1576
  }
1657
1577
 
1658
1578
  .manager-office__thread-status[data-status="error"] {
@@ -1660,7 +1580,7 @@
1660
1580
  }
1661
1581
 
1662
1582
  .manager-office__nav-status:is([data-status="working"], [data-status="connecting"]) {
1663
- color: light-dark(#0b57d0, #69a7ff);
1583
+ color: var(--sigvelo-color-primary-text);
1664
1584
  }
1665
1585
 
1666
1586
  .manager-office__thread-status[data-status="running"] {
@@ -1,2 +1,2 @@
1
- import { a as MCP_SERVER_SETUP_AUTH, c as McpServerManualSetup, d as McpServerSetupAuthFieldName, f as McpServerSetupLink, h as getMcpServerRuntimeState, i as MANUAL_MCP_SERVER_CARDS, l as McpServerSetupAuth, m as getMcpServerIconSrc, n as DCR_MCP_SERVER_CARDS, o as McpServerCard, p as getMcpServerEntry, r as DEFAULT_MCP_SERVER_CARDS, s as McpServerCardIcon, t as CUSTOM_MCP_SERVER_CARD, u as McpServerSetupAuthField } from "../mcp-server-catalog-Cbu483Zb.js";
1
+ import { a as MCP_SERVER_SETUP_AUTH, c as McpServerManualSetup, d as McpServerSetupAuthFieldName, f as McpServerSetupLink, h as getMcpServerRuntimeState, i as MANUAL_MCP_SERVER_CARDS, l as McpServerSetupAuth, m as getMcpServerIconSrc, n as DCR_MCP_SERVER_CARDS, o as McpServerCard, p as getMcpServerEntry, r as DEFAULT_MCP_SERVER_CARDS, s as McpServerCardIcon, t as CUSTOM_MCP_SERVER_CARD, u as McpServerSetupAuthField } from "../mcp-server-catalog-C_g7C-9o.js";
2
2
  export { CUSTOM_MCP_SERVER_CARD, DCR_MCP_SERVER_CARDS, DEFAULT_MCP_SERVER_CARDS, MANUAL_MCP_SERVER_CARDS, MCP_SERVER_SETUP_AUTH, McpServerCard, McpServerCardIcon, McpServerManualSetup, McpServerSetupAuth, McpServerSetupAuthField, McpServerSetupAuthFieldName, McpServerSetupLink, getMcpServerEntry, getMcpServerIconSrc, getMcpServerRuntimeState };
@@ -1,4 +1,5 @@
1
1
  import { inferFaviconUrl } from "./favicon.js";
2
+ import { siAirtable, siAsana, siAtlassian, siCalendly, siCloudflare, siDatadog, siEgnyte, siGithub, siGitlab, siGrafana, siHubspot, siHuggingface, siLinear, siMiro, siNeon, siNotion, siPaypal, siPosthog, siPostman, siRailway, siSentry, siStripe, siSupabase, siWebflow, siWix, siZapier, siZoom } from "simple-icons";
2
3
  //#region src/utils/mcp-server-catalog.ts
3
4
  /**
4
5
  * Read the complete state emitted by the pinned Agents runtime.
@@ -38,6 +39,40 @@ function normalizeMcpServerUrl(url) {
38
39
  }
39
40
  const DCR_CATEGORY = "Auto";
40
41
  const MANUAL_CATEGORY = "Manual";
42
+ const SIMPLE_ICONS = Object.fromEntries([
43
+ siAirtable,
44
+ siAsana,
45
+ siAtlassian,
46
+ siCalendly,
47
+ siCloudflare,
48
+ siDatadog,
49
+ siEgnyte,
50
+ siGithub,
51
+ siGitlab,
52
+ siGrafana,
53
+ siHubspot,
54
+ siHuggingface,
55
+ siLinear,
56
+ siMiro,
57
+ siNeon,
58
+ siNotion,
59
+ siPaypal,
60
+ siPosthog,
61
+ siPostman,
62
+ siRailway,
63
+ siSentry,
64
+ siStripe,
65
+ siSupabase,
66
+ siWebflow,
67
+ siWix,
68
+ siZapier,
69
+ siZoom
70
+ ].map((icon) => [icon.slug, icon.svg]));
71
+ function bundledSimpleIcon(server) {
72
+ const slug = server.id === "zoom-workspace" ? "zoom" : server.id.replaceAll("-", "");
73
+ const svg = SIMPLE_ICONS[slug];
74
+ return svg ? `data:image/svg+xml,${encodeURIComponent(svg)}` : void 0;
75
+ }
41
76
  const MCP_SERVER_SETUP_AUTH = {
42
77
  bearer: {
43
78
  type: "bearer",
@@ -120,6 +155,8 @@ const CUSTOM_MCP_SERVER_CARD = {
120
155
  function getMcpServerIconSrc(server) {
121
156
  if (typeof server.icon === "string") return server.icon;
122
157
  if (server.icon?.src) return server.icon.src;
158
+ const bundled = bundledSimpleIcon(server);
159
+ if (bundled) return bundled;
123
160
  return inferFaviconUrl(server.url);
124
161
  }
125
162
  /** Remote MCP servers whose OAuth metadata exposes a registration_endpoint. */
@@ -425,6 +462,31 @@ const MANUAL_MCP_SERVER_CARDS = [
425
462
  ]
426
463
  }
427
464
  },
465
+ {
466
+ id: "github",
467
+ name: "GitHub",
468
+ url: "https://api.githubcopilot.com/mcp/",
469
+ description: "Clone, push, and open pull requests as a connected GitHub account",
470
+ category: MANUAL_CATEGORY,
471
+ manualSetup: {
472
+ auth: {
473
+ type: "bearer",
474
+ label: "Personal access token (classic)",
475
+ fields: [{
476
+ name: "bearerToken",
477
+ label: "Personal access token",
478
+ inputType: "password",
479
+ placeholder: "ghp_…",
480
+ required: true
481
+ }]
482
+ },
483
+ description: "Paste a classic personal access token with all scopes from the agent's own GitHub account — the account is the access boundary. Git and the GitHub API both authenticate as this account.",
484
+ links: [{
485
+ label: "Create a classic token",
486
+ url: "https://github.com/settings/tokens"
487
+ }]
488
+ }
489
+ },
428
490
  {
429
491
  id: "gmail",
430
492
  name: "Gmail",
@@ -870,6 +932,12 @@ const DEFAULT_MCP_SERVER_CARDS = [
870
932
  ...DCR_MCP_SERVER_CARDS,
871
933
  CUSTOM_MCP_SERVER_CARD,
872
934
  ...MANUAL_MCP_SERVER_CARDS
873
- ];
935
+ ].map((server) => {
936
+ const icon = bundledSimpleIcon(server);
937
+ return icon ? {
938
+ ...server,
939
+ icon
940
+ } : server;
941
+ });
874
942
  //#endregion
875
943
  export { CUSTOM_MCP_SERVER_CARD, DCR_MCP_SERVER_CARDS, DEFAULT_MCP_SERVER_CARDS, MANUAL_MCP_SERVER_CARDS, MCP_SERVER_SETUP_AUTH, getMcpServerEntry, getMcpServerIconSrc, getMcpServerRuntimeState };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-b/react-components",
3
- "version": "0.46.2",
3
+ "version": "0.46.4",
4
4
  "description": "MCP-B React components built on Base UI and shared design tokens, including Cloudflare Think chat primitives.",
5
5
  "homepage": "https://design-system.sigvelo.com",
6
6
  "bugs": {
@@ -50,10 +50,11 @@
50
50
  "react-icons": "^5.7.0",
51
51
  "rehype-slug": "^6.0.0",
52
52
  "shiki": "^3.23.0",
53
+ "simple-icons": "16.28.0",
53
54
  "streamdown": "^2.5.0",
54
55
  "unist-util-visit": "^5.1.0",
55
56
  "yet-another-react-lightbox": "^3.32.2",
56
- "@mcp-b/design-tokens": "0.46.2"
57
+ "@mcp-b/design-tokens": "0.46.4"
57
58
  },
58
59
  "devDependencies": {
59
60
  "@ai-sdk/react": "^3.0.249",