@mcp-b/react-components 0.49.0 → 0.50.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 (196) hide show
  1. package/dist/{AgentChatQueue-C_Jaw3Ia.d.ts → AgentChatQueue-MrHhV901.d.ts} +1 -1
  2. package/dist/AgentMessageParts-C7L-Mv9U.d.ts +46 -0
  3. package/dist/AppTopBar-CVkLRdk7.d.ts +99 -0
  4. package/dist/{CodeBlock-g8sADidM.js → CodeBlock-BMK6CW9D.js} +1 -1
  5. package/dist/Dialog-88GF7_Th.d.ts +107 -0
  6. package/dist/{FileTree-H8mMg4rV.js → FileTree-okaLnS5j.js} +20 -9
  7. package/dist/Form-CM7GNTwR.d.ts +91 -0
  8. package/dist/ManagerOffice-5pEFpoV3.js +1146 -0
  9. package/dist/McpConnectorForm--HB0MEGC.d.ts +39 -0
  10. package/dist/{Menu-yb6QXWA3.d.ts → Menu-CgfUZhZd.d.ts} +1 -1
  11. package/dist/Popover-CgHG5DtS.d.ts +220 -0
  12. package/dist/{PromptInput-C4Mofitz.d.ts → PromptInput-DGPrCTPl.d.ts} +3 -2
  13. package/dist/ResponsiveSidebarShell-CAmmtQTR.d.ts +128 -0
  14. package/dist/SessionCompaction-CmTJFpzj.d.ts +89 -0
  15. package/dist/SetupChecklist-O6qmgwz4.js +77 -0
  16. package/dist/ThinkChatActivity-DENkintt.d.ts +77 -0
  17. package/dist/ThinkChatContext-COIgzkYp.d.ts +28 -0
  18. package/dist/ThinkRoutine-Cb1DdaHa.d.ts +30 -0
  19. package/dist/ThinkThreadPicker-yetGX_s5.d.ts +91 -0
  20. package/dist/{WorkspaceFileView-DYPtRVpM.js → WorkspaceFileView-ncZuIWhC.js} +2 -2
  21. package/dist/WorkspaceMessageResponse-8lOSAbw_.d.ts +48 -0
  22. package/dist/codex-model-catalog-BBN_gWcc.d.ts +155 -0
  23. package/dist/components/agents-sdk/AgentActivity.js +1 -1
  24. package/dist/components/agents-sdk/AgentChat.d.ts +3 -3
  25. package/dist/components/agents-sdk/AgentChat.js +8 -8
  26. package/dist/components/agents-sdk/AgentChatQueue.d.ts +1 -1
  27. package/dist/components/agents-sdk/AgentEvent.js +2 -2
  28. package/dist/components/agents-sdk/BrowserLiveScreen.js +1 -1
  29. package/dist/components/agents-sdk/BrowserLiveView.js +1 -1
  30. package/dist/components/agents-sdk/BrowserReplay.js +1 -1
  31. package/dist/components/agents-sdk/BrowserRunPanel.js +1 -1
  32. package/dist/components/agents-sdk/DiscordConnectionDialog.d.ts +20 -0
  33. package/dist/components/agents-sdk/DiscordConnectionDialog.js +65 -0
  34. package/dist/components/agents-sdk/EmployeeApp.d.ts +49 -0
  35. package/dist/components/agents-sdk/EmployeeApp.js +57 -0
  36. package/dist/components/agents-sdk/EmployeeChat.d.ts +63 -0
  37. package/dist/components/agents-sdk/EmployeeChat.js +84 -0
  38. package/dist/components/agents-sdk/EmployeeChrome.d.ts +10 -2
  39. package/dist/components/agents-sdk/EmployeeChrome.js +26 -16
  40. package/dist/components/agents-sdk/EmployeeSchedules.d.ts +24 -0
  41. package/dist/components/agents-sdk/EmployeeSchedules.js +105 -0
  42. package/dist/components/agents-sdk/EmployeeStartScreen.d.ts +43 -0
  43. package/dist/components/agents-sdk/EmployeeStartScreen.js +133 -0
  44. package/dist/components/agents-sdk/ManagerAccountActions.d.ts +29 -0
  45. package/dist/components/agents-sdk/ManagerAccountActions.js +62 -0
  46. package/dist/components/agents-sdk/ManagerOffice.d.ts +1 -1
  47. package/dist/components/agents-sdk/ManagerOffice.js +1 -1145
  48. package/dist/components/agents-sdk/ManagerOfficeScreens.d.ts +49 -0
  49. package/dist/components/agents-sdk/ManagerOfficeScreens.js +198 -0
  50. package/dist/components/agents-sdk/McpConnectionRequest.d.ts +1 -1
  51. package/dist/components/agents-sdk/McpConnectionRequest.js +3 -3
  52. package/dist/components/agents-sdk/McpConnectorForm.d.ts +1 -38
  53. package/dist/components/agents-sdk/McpConnectorForm.js +1 -1
  54. package/dist/components/agents-sdk/McpPluginCatalog.d.ts +3 -3
  55. package/dist/components/agents-sdk/McpPluginCatalog.js +4 -4
  56. package/dist/components/agents-sdk/McpServerIcon.d.ts +1 -1
  57. package/dist/components/agents-sdk/McpServerPicker.d.ts +4 -4
  58. package/dist/components/agents-sdk/McpServerPicker.js +2 -2
  59. package/dist/components/agents-sdk/ModelEndpointDialog.d.ts +31 -0
  60. package/dist/components/agents-sdk/ModelEndpointDialog.js +118 -0
  61. package/dist/components/agents-sdk/ModelSelector.d.ts +1 -1
  62. package/dist/components/agents-sdk/ModelSelector.js +4 -4
  63. package/dist/components/agents-sdk/PromptInputApproval.js +1 -1
  64. package/dist/components/agents-sdk/PromptInputCommands.d.ts +1 -1
  65. package/dist/components/agents-sdk/PromptInputCommands.js +1 -1
  66. package/dist/components/agents-sdk/SessionCompaction.d.ts +1 -88
  67. package/dist/components/agents-sdk/SlackConnectionDialog.d.ts +18 -0
  68. package/dist/components/agents-sdk/SlackConnectionDialog.js +48 -0
  69. package/dist/components/agents-sdk/SubagentRunIndicator.js +1 -1
  70. package/dist/components/agents-sdk/SubagentRunPanel.js +1 -1
  71. package/dist/components/agents-sdk/SubagentRunSelector.js +1 -1
  72. package/dist/components/agents-sdk/ThinkChat.d.ts +6 -6
  73. package/dist/components/agents-sdk/ThinkChatActivity.d.ts +1 -76
  74. package/dist/components/agents-sdk/ThinkChatActivity.js +3 -3
  75. package/dist/components/agents-sdk/ThinkChatContext.d.ts +1 -27
  76. package/dist/components/agents-sdk/ThinkChatToolPanels.js +2 -2
  77. package/dist/components/agents-sdk/ThinkExecutionDetail.js +2 -2
  78. package/dist/components/agents-sdk/ThinkExecutionStatus.js +1 -1
  79. package/dist/components/agents-sdk/ThinkExecutionWorkbench.d.ts +1 -1
  80. package/dist/components/agents-sdk/ThinkExecutionWorkbench.js +3 -3
  81. package/dist/components/agents-sdk/ThinkRecoveryNotice.d.ts +1 -1
  82. package/dist/components/agents-sdk/ThinkRecoveryNotice.js +1 -1
  83. package/dist/components/agents-sdk/ThinkRoutine.d.ts +1 -29
  84. package/dist/components/agents-sdk/ThinkRoutineActions.d.ts +2 -2
  85. package/dist/components/agents-sdk/ThinkRoutineActions.js +1 -1
  86. package/dist/components/agents-sdk/ThinkRoutineBrowser.d.ts +1 -1
  87. package/dist/components/agents-sdk/ThinkRoutineBrowser.js +3 -3
  88. package/dist/components/agents-sdk/ThinkRoutineDetail.d.ts +1 -1
  89. package/dist/components/agents-sdk/ThinkRoutineForm.js +4 -4
  90. package/dist/components/agents-sdk/ThinkRoutineRuns.js +1 -1
  91. package/dist/components/agents-sdk/ThinkThreadPicker.d.ts +1 -90
  92. package/dist/components/agents-sdk/ThinkThreadPicker.js +3 -3
  93. package/dist/components/agents-sdk/WorkspaceBrowser.js +1 -1
  94. package/dist/components/agents-sdk/WorkspaceCorrespondence.js +6 -6
  95. package/dist/components/agents-sdk/WorkspaceExecution.js +7 -7
  96. package/dist/components/agents-sdk/WorkspaceExplorer.js +1 -1
  97. package/dist/components/agents-sdk/WorkspaceFileView.js +1 -1
  98. package/dist/components/agents-sdk/WorkspaceHeader.js +1 -1
  99. package/dist/components/agents-sdk/WorkspaceMessageResponse.d.ts +1 -47
  100. package/dist/components/agents-sdk/WorkspaceMountManager.js +2 -2
  101. package/dist/components/agents-sdk/WorkspaceProject.js +4 -4
  102. package/dist/components/agents-sdk/WorkspaceUserScript.js +4 -4
  103. package/dist/components/ai-sdk/Activity.js +1 -1
  104. package/dist/components/ai-sdk/AgentChatMessageEditor.js +5 -1
  105. package/dist/components/ai-sdk/AgentChatStartScreen.d.ts +1 -1
  106. package/dist/components/ai-sdk/AgentChatStartScreen.js +1 -1
  107. package/dist/components/ai-sdk/AgentMessageParts.d.ts +1 -45
  108. package/dist/components/ai-sdk/Approval.js +2 -2
  109. package/dist/components/ai-sdk/Artifact.js +1 -1
  110. package/dist/components/ai-sdk/ChainOfThought.js +1 -1
  111. package/dist/components/ai-sdk/Checkpoint.js +1 -1
  112. package/dist/components/ai-sdk/CodeBlock.js +1 -1
  113. package/dist/components/ai-sdk/ComposerLink.js +1 -1
  114. package/dist/components/ai-sdk/ConnectedAppCards.js +3 -3
  115. package/dist/components/ai-sdk/Context.d.ts +1 -1
  116. package/dist/components/ai-sdk/Context.js +1 -1
  117. package/dist/components/ai-sdk/Conversation.js +1 -1
  118. package/dist/components/ai-sdk/Goal.js +1 -1
  119. package/dist/components/ai-sdk/MediaPreviewCard.js +1 -1
  120. package/dist/components/ai-sdk/Message.js +2 -2
  121. package/dist/components/ai-sdk/MessageScroller.js +1 -1
  122. package/dist/components/ai-sdk/MessageScrollerVirtual.js +2 -1
  123. package/dist/components/ai-sdk/Plan.d.ts +1 -1
  124. package/dist/components/ai-sdk/Plan.js +1 -1
  125. package/dist/components/ai-sdk/PromptInput.d.ts +1 -1
  126. package/dist/components/ai-sdk/PromptInput.js +7 -7
  127. package/dist/components/ai-sdk/Queue.js +1 -1
  128. package/dist/components/ai-sdk/Reasoning.js +1 -1
  129. package/dist/components/ai-sdk/Sources.js +1 -1
  130. package/dist/components/ai-sdk/Task.js +1 -1
  131. package/dist/components/extension/ChatGptSignInScreen.js +1 -1
  132. package/dist/components/extension/CodexModelSelector.d.ts +2 -2
  133. package/dist/components/extension/CodexModelSelector.js +3 -3
  134. package/dist/components/extension/ConversationTabPicker.js +2 -2
  135. package/dist/components/foundations/Checkbox.js +1 -1
  136. package/dist/components/foundations/Collapsible.js +1 -1
  137. package/dist/components/foundations/ContextMenu.d.ts +10 -23
  138. package/dist/components/foundations/ContextMenu.js +3 -2
  139. package/dist/components/foundations/Dialog.d.ts +1 -106
  140. package/dist/components/foundations/Form.d.ts +1 -90
  141. package/dist/components/foundations/Menu.d.ts +1 -1
  142. package/dist/components/foundations/Menubar.d.ts +1 -1
  143. package/dist/components/foundations/Menubar.js +1 -1
  144. package/dist/components/foundations/Popover.d.ts +1 -219
  145. package/dist/components/foundations/PreviewCard.d.ts +1 -1
  146. package/dist/components/foundations/SearchField.js +1 -1
  147. package/dist/components/foundations/Select.js +1 -1
  148. package/dist/components/foundations/Stepper.js +1 -1
  149. package/dist/components/foundations/Toast.js +1 -1
  150. package/dist/components/foundations/ToggleGroup.d.ts +1 -1
  151. package/dist/components/foundations/ToggleGroup.js +1 -1
  152. package/dist/components/foundations/Tooltip.d.ts +1 -1
  153. package/dist/components/foundations/icons.js +1 -1
  154. package/dist/components/general-purpose/AccountSignInDialog.d.ts +26 -0
  155. package/dist/components/general-purpose/AccountSignInDialog.js +25 -0
  156. package/dist/components/general-purpose/AppTopBar.d.ts +1 -98
  157. package/dist/components/general-purpose/Commit.js +2 -2
  158. package/dist/components/general-purpose/EnvironmentVariables.js +2 -2
  159. package/dist/components/general-purpose/FileTree.js +1 -1
  160. package/dist/components/general-purpose/NotificationPrompt.d.ts +13 -0
  161. package/dist/components/general-purpose/NotificationPrompt.js +18 -0
  162. package/dist/components/general-purpose/PricingPlanCard.js +2 -2
  163. package/dist/components/general-purpose/PricingUsageCalculator.js +2 -2
  164. package/dist/components/general-purpose/ResponsiveSidebarShell.d.ts +1 -127
  165. package/dist/components/general-purpose/ResponsiveSidebarShell.js +124 -72
  166. package/dist/components/general-purpose/SettingsFormDialog.d.ts +2 -2
  167. package/dist/components/general-purpose/SettingsFormDialog.js +2 -2
  168. package/dist/components/general-purpose/SetupChecklist.js +1 -76
  169. package/dist/components/general-purpose/StatusScreen.d.ts +10 -0
  170. package/dist/components/general-purpose/StatusScreen.js +13 -0
  171. package/dist/components/general-purpose/Terminal.js +2 -2
  172. package/dist/components/general-purpose/TestResults.js +1 -1
  173. package/dist/components/general-purpose/ThemeModeControl.js +2 -2
  174. package/dist/components/general-purpose/WebPreview.js +2 -2
  175. package/dist/components/nanites/AgentConnection.js +2 -2
  176. package/dist/components/nanites/AgentToolDetail.d.ts +1 -1
  177. package/dist/components/nanites/AgentToolDetail.js +4 -4
  178. package/dist/{copy-button-CSDuDfdP.js → copy-button-Dk2vRe9j.js} +1 -1
  179. package/dist/mcp-server-catalog-D9p4gGeJ.d.ts +1112 -0
  180. package/dist/styles/accessibility.css +20 -0
  181. package/dist/styles/agent-chat.css +1 -1
  182. package/dist/styles/base.css +0 -8
  183. package/dist/styles/codex-model-selector.css +4 -0
  184. package/dist/styles/color-contrast.test.ts +212 -0
  185. package/dist/styles/employee-app.css +29 -0
  186. package/dist/styles/file-tree.css +5 -1
  187. package/dist/styles/index.css +2 -0
  188. package/dist/styles/manager-office.css +5 -5
  189. package/dist/styles/manager-work.css +93 -0
  190. package/dist/styles/responsive-sidebar-shell.css +1 -1
  191. package/dist/utils/codex-model-catalog.d.ts +1 -135
  192. package/dist/utils/codex-model-catalog.js +22 -5
  193. package/dist/utils/mcp-server-catalog.d.ts +1 -1111
  194. package/dist/{workspace-assets-Bg7XhPsk.js → workspace-assets-wW_lQLYK.js} +2 -2
  195. package/package.json +3 -3
  196. package/dist/{icons-cuEtsgj9.js → icons-CeGfXO21.js} +1 -1
@@ -0,0 +1,1146 @@
1
+ import { findCatalogMcpServerCard, getMcpServerIconSrc } from "./utils/mcp-server-catalog.js";
2
+ import { t as cx } from "./class-names-BiMDVpUo.js";
3
+ import { Collapsible } from "./components/foundations/Collapsible.js";
4
+ import { C as FolderIcon, D as LinkIcon, K as SpinnerIcon, L as PauseIcon, P as MonitorIcon, S as FileIcon, T as InfoIcon, _ as DotIcon, d as CheckIcon, et as WarningIcon, f as ChevronDownIcon, j as MessageSquareIcon, p as ChevronRightIcon, u as CalendarIcon } from "./icons-CeGfXO21.js";
5
+ import { Button } from "./components/foundations/Button.js";
6
+ import { AgentAttention, AgentAttentionActions, AgentAttentionBody, AgentAttentionHeader } from "./components/ai-sdk/AgentAttention.js";
7
+ import { Tooltip } from "./components/foundations/Tooltip.js";
8
+ import { Avatar } from "./components/foundations/Avatar.js";
9
+ import { CorrespondentName, correspondentHandleLabel } from "./components/ai-sdk/Correspondent.js";
10
+ import { AppIcon } from "./components/foundations/AppIcon.js";
11
+ import { EmptyState } from "./components/foundations/EmptyState.js";
12
+ import { LinkButton } from "./components/foundations/LinkButton.js";
13
+ import { getThinkExecutionRunStatus } from "./components/agents-sdk/ThinkExecutionRun.js";
14
+ import * as React from "react";
15
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
16
+ import { useRender } from "@base-ui/react/use-render";
17
+ import { mergeProps } from "@base-ui/react/merge-props";
18
+ //#region src/components/_internal/chrome-profile-colors.ts
19
+ const PALETTE = [
20
+ {
21
+ bg: "#ffab40",
22
+ fg: "#1f1f1f"
23
+ },
24
+ {
25
+ bg: "#43a047",
26
+ fg: "#ffffff"
27
+ },
28
+ {
29
+ bg: "#199da9",
30
+ fg: "#ffffff"
31
+ },
32
+ {
33
+ bg: "#5d93e4",
34
+ fg: "#ffffff"
35
+ },
36
+ {
37
+ bg: "#ffaebd",
38
+ fg: "#1f1f1f"
39
+ },
40
+ {
41
+ bg: "#bd165c",
42
+ fg: "#ffffff"
43
+ },
44
+ {
45
+ bg: "#b71c1c",
46
+ fg: "#ffffff"
47
+ },
48
+ {
49
+ bg: "#2e7d32",
50
+ fg: "#ffffff"
51
+ },
52
+ {
53
+ bg: "#006e78",
54
+ fg: "#ffffff"
55
+ },
56
+ {
57
+ bg: "#1565c0",
58
+ fg: "#ffffff"
59
+ },
60
+ {
61
+ bg: "#5b3689",
62
+ fg: "#ffffff"
63
+ }
64
+ ];
65
+ /** FNV-1a, for a stable pick from the same seat across reloads. */
66
+ function hash(seed) {
67
+ let value = 2166136261;
68
+ for (let index = 0; index < seed.length; index++) {
69
+ value ^= seed.charCodeAt(index);
70
+ value = Math.imul(value, 16777619);
71
+ }
72
+ return value >>> 0;
73
+ }
74
+ /**
75
+ * Deterministic Chrome-style profile color for one identity. Pass the set of
76
+ * `bg` values already assigned to the rest of the roster so two profiles only
77
+ * share a color once the palette is exhausted, exactly as Chrome avoids
78
+ * colors in use by other profiles.
79
+ */
80
+ function chromeProfileColor(seed, taken) {
81
+ const start = hash(seed) % PALETTE.length;
82
+ for (let offset = 0; offset < PALETTE.length; offset++) {
83
+ const candidate = PALETTE[(start + offset) % PALETTE.length];
84
+ if (!taken?.has(candidate.bg)) return candidate;
85
+ }
86
+ return PALETTE[start];
87
+ }
88
+ //#endregion
89
+ //#region src/components/agents-sdk/ManagerOffice.tsx
90
+ const OfficeContext = React.createContext(null);
91
+ const EmployeeContext = React.createContext(null);
92
+ function useOffice() {
93
+ const value = React.useContext(OfficeContext);
94
+ if (!value) throw new Error("ManagerOffice parts require ManagerOffice.Root.");
95
+ return value;
96
+ }
97
+ function useEmployee() {
98
+ const value = React.useContext(EmployeeContext);
99
+ if (!value) throw new Error("Employee parts require ManagerOffice.Employee.");
100
+ return value;
101
+ }
102
+ const statusLabels = {
103
+ "needs-you": "Waiting on you",
104
+ working: "Working",
105
+ idle: "Idle",
106
+ issue: "Waiting on you",
107
+ offline: "Offline",
108
+ connecting: "Connecting…",
109
+ unavailable: "Unavailable"
110
+ };
111
+ /**
112
+ * Named positively, so a status added to the union later is disconnected until
113
+ * someone says otherwise. The negative form — "not offline, connecting, or
114
+ * unavailable" — silently admits every new status, and the first thing this
115
+ * component does with a connected employee is read `handoffs`, which a
116
+ * disconnected one does not carry.
117
+ */
118
+ const CONNECTED_STATUSES = {
119
+ "needs-you": true,
120
+ working: true,
121
+ idle: true,
122
+ issue: true
123
+ };
124
+ function isConnected(employee) {
125
+ return employee.status in CONNECTED_STATUSES;
126
+ }
127
+ function employeeAttentionCount(employee) {
128
+ return isConnected(employee) ? employee.handoffs.length : 0;
129
+ }
130
+ /** The roster spells out what its handoff count measures. */
131
+ function employeeStatusText(employee) {
132
+ const count = employeeAttentionCount(employee);
133
+ const label = statusLabels[employee.status];
134
+ return count ? `${label} · ${count} handoff${count === 1 ? "" : "s"}` : label;
135
+ }
136
+ function EmployeePresence({ employee }) {
137
+ return /* @__PURE__ */ jsx("span", {
138
+ className: "manager-office__nav-status",
139
+ "data-status": employee.status,
140
+ "aria-hidden": "true"
141
+ });
142
+ }
143
+ /**
144
+ * Each employee is a Chrome profile, so the bubble wears its profile color —
145
+ * the same palette Chrome assigns profiles from. Chrome's pick is per-machine
146
+ * state the host can't read, so the roster re-derives it: a stable hash per
147
+ * seat, skipping colors already worn by earlier roster entries the way Chrome
148
+ * skips colors in use by other profiles.
149
+ */
150
+ function rosterProfileColors(employees) {
151
+ const taken = /* @__PURE__ */ new Set();
152
+ const colors = /* @__PURE__ */ new Map();
153
+ for (const employee of employees) {
154
+ const color = chromeProfileColor(employee.id, taken);
155
+ taken.add(color.bg);
156
+ colors.set(employee.id, color);
157
+ }
158
+ return colors;
159
+ }
160
+ function EmployeeAvatar({ color, employee, index = 0, size = "sm" }) {
161
+ const variant = index % 4;
162
+ return /* @__PURE__ */ jsx(Avatar.Root, {
163
+ size,
164
+ shape: "rounded",
165
+ className: "manager-office__employee-character",
166
+ "aria-hidden": "true",
167
+ children: /* @__PURE__ */ jsxs(Avatar.Fallback, {
168
+ className: "manager-office__employee-character-fallback",
169
+ style: {
170
+ color: color.fg,
171
+ backgroundColor: "transparent"
172
+ },
173
+ children: [/* @__PURE__ */ jsxs("svg", {
174
+ viewBox: "0 0 36 36",
175
+ focusable: "false",
176
+ role: "presentation",
177
+ style: { fill: color.bg },
178
+ children: [
179
+ /* @__PURE__ */ jsx("rect", {
180
+ x: "5",
181
+ y: "6",
182
+ width: "26",
183
+ height: "25",
184
+ rx: "7"
185
+ }),
186
+ /* @__PURE__ */ jsx("rect", {
187
+ x: "8",
188
+ y: "28",
189
+ width: "8",
190
+ height: "5",
191
+ rx: "2.5",
192
+ opacity: "0.78"
193
+ }),
194
+ /* @__PURE__ */ jsx("rect", {
195
+ x: "20",
196
+ y: "28",
197
+ width: "8",
198
+ height: "5",
199
+ rx: "2.5",
200
+ opacity: "0.78"
201
+ }),
202
+ variant === 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("path", { d: "M10 7c.6-3 3.2-5 6.2-5h3.6c3 0 5.6 2 6.2 5Z" }), /* @__PURE__ */ jsx("circle", {
203
+ cx: "18",
204
+ cy: "3",
205
+ r: "1.8"
206
+ })] }) : variant === 1 ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("rect", {
207
+ x: "2.5",
208
+ y: "13",
209
+ width: "4",
210
+ height: "10",
211
+ rx: "2"
212
+ }), /* @__PURE__ */ jsx("rect", {
213
+ x: "29.5",
214
+ y: "13",
215
+ width: "4",
216
+ height: "10",
217
+ rx: "2"
218
+ })] }) : variant === 2 ? /* @__PURE__ */ jsx("path", {
219
+ d: "M11 6V3.5h14V6M15 3.5V1.5h6v2",
220
+ fill: "none",
221
+ stroke: color.bg,
222
+ strokeWidth: "2",
223
+ strokeLinecap: "round",
224
+ strokeLinejoin: "round"
225
+ }) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("path", { d: "M12 7V3l4 3 4-4 4 5Z" }), /* @__PURE__ */ jsx("circle", {
226
+ cx: "26.5",
227
+ cy: "7",
228
+ r: "2"
229
+ })] }),
230
+ /* @__PURE__ */ jsx("g", {
231
+ className: "manager-office__employee-character-face",
232
+ fill: color.fg,
233
+ children: variant === 1 ? /* @__PURE__ */ jsxs(Fragment, { children: [
234
+ /* @__PURE__ */ jsx("rect", {
235
+ className: "manager-office__employee-character-visor",
236
+ x: "10",
237
+ y: "14",
238
+ width: "16",
239
+ height: "8",
240
+ rx: "4",
241
+ opacity: "0.94"
242
+ }),
243
+ /* @__PURE__ */ jsx("circle", {
244
+ cx: "14",
245
+ cy: "18",
246
+ r: "1.5",
247
+ fill: color.bg
248
+ }),
249
+ /* @__PURE__ */ jsx("circle", {
250
+ cx: "22",
251
+ cy: "18",
252
+ r: "1.5",
253
+ fill: color.bg
254
+ })
255
+ ] }) : variant === 3 ? /* @__PURE__ */ jsxs("g", {
256
+ className: "manager-office__employee-character-glasses",
257
+ children: [
258
+ /* @__PURE__ */ jsx("circle", {
259
+ className: "manager-office__employee-character-lens",
260
+ cx: "13.5",
261
+ cy: "17",
262
+ r: "3"
263
+ }),
264
+ /* @__PURE__ */ jsx("circle", {
265
+ className: "manager-office__employee-character-lens",
266
+ cx: "22.5",
267
+ cy: "17",
268
+ r: "3"
269
+ }),
270
+ /* @__PURE__ */ jsx("path", {
271
+ className: "manager-office__employee-character-bridge",
272
+ d: "M16.5 17h3"
273
+ })
274
+ ]
275
+ }) : /* @__PURE__ */ jsxs(Fragment, { children: [
276
+ /* @__PURE__ */ jsx("circle", {
277
+ cx: "13.5",
278
+ cy: "17",
279
+ r: "3.2"
280
+ }),
281
+ /* @__PURE__ */ jsx("circle", {
282
+ cx: "22.5",
283
+ cy: "17",
284
+ r: "3.2"
285
+ }),
286
+ /* @__PURE__ */ jsx("circle", {
287
+ cx: "14.5",
288
+ cy: "16",
289
+ r: "1",
290
+ fill: color.bg,
291
+ opacity: "0.72"
292
+ }),
293
+ /* @__PURE__ */ jsx("circle", {
294
+ cx: "23.5",
295
+ cy: "16",
296
+ r: "1",
297
+ fill: color.bg,
298
+ opacity: "0.72"
299
+ })
300
+ ] })
301
+ }),
302
+ /* @__PURE__ */ jsx("path", {
303
+ className: "manager-office__employee-character-shine",
304
+ d: "M9 11c2-2 4.7-3 7.7-3",
305
+ fill: "none",
306
+ stroke: color.fg,
307
+ strokeWidth: "1.5",
308
+ strokeLinecap: "round"
309
+ })
310
+ ]
311
+ }), /* @__PURE__ */ jsx("span", {
312
+ className: "sigvelo-visually-hidden",
313
+ children: employee.initials
314
+ })]
315
+ })
316
+ });
317
+ }
318
+ /**
319
+ * One glyph per manager action, not one glyph per backend state. Both an
320
+ * employee asking for a person (`needs-you`) and one blocked by an issue
321
+ * (`issue`) require the same response here, so the roster presents both as
322
+ * "Waiting on you" with the warning glyph. An unreachable employee remains a
323
+ * distinct shape because there is no work for the manager to resume yet.
324
+ *
325
+ * `working` and `connecting` deliberately share the spinner: both mean "in
326
+ * motion, wait", and mistaking one for the other costs the manager nothing.
327
+ */
328
+ function ThreadStatusIcon({ status }) {
329
+ return /* @__PURE__ */ jsx("span", {
330
+ className: "manager-office__thread-status",
331
+ "data-status": status,
332
+ "aria-hidden": "true",
333
+ children: status === "running" ? /* @__PURE__ */ jsx(SpinnerIcon, {}) : status === "error" ? /* @__PURE__ */ jsx(WarningIcon, {}) : status === "interrupted" ? /* @__PURE__ */ jsx(PauseIcon, {}) : /* @__PURE__ */ jsx(DotIcon, {})
334
+ });
335
+ }
336
+ function threadStatusLabel(status) {
337
+ if (status === "attention") return "Update ready";
338
+ if (status === "running") return "Working";
339
+ if (status === "error") return "Issue";
340
+ if (status === "interrupted") return "Stopped";
341
+ return "Updated";
342
+ }
343
+ function relativeTime(timestamp, now) {
344
+ const elapsed = Math.max(0, now - timestamp);
345
+ const minute = 6e4;
346
+ const hour = 60 * minute;
347
+ const day = 24 * hour;
348
+ if (elapsed < minute) return "now";
349
+ if (elapsed < hour) return `${Math.floor(elapsed / minute)}m`;
350
+ if (elapsed < day) return `${Math.floor(elapsed / hour)}h`;
351
+ return `${Math.floor(elapsed / day)}d`;
352
+ }
353
+ function Timestamp({ now, timestamp }) {
354
+ const date = new Date(timestamp);
355
+ return /* @__PURE__ */ jsx("time", {
356
+ dateTime: date.toISOString(),
357
+ title: date.toLocaleString(),
358
+ children: relativeTime(timestamp, now)
359
+ });
360
+ }
361
+ /**
362
+ * Deliberately the same three glyphs the employee statuses use: a channel that
363
+ * needs a sign-in is the same kind of event as an employee that needs one, and
364
+ * a manager should not have to learn a second vocabulary for it.
365
+ */
366
+ function channelStatusIcon(status) {
367
+ if (status === "connected") return /* @__PURE__ */ jsx(CheckIcon, {});
368
+ if (status === "needs-auth") return /* @__PURE__ */ jsx(InfoIcon, {});
369
+ return /* @__PURE__ */ jsx(WarningIcon, {});
370
+ }
371
+ const channelStatusLabels = {
372
+ connected: "Connected",
373
+ "needs-auth": "Needs sign-in",
374
+ error: "Error"
375
+ };
376
+ function ChannelMark({ channel }) {
377
+ if (channel.icon) return /* @__PURE__ */ jsx("span", {
378
+ className: "manager-office__channel-mark",
379
+ children: channel.icon
380
+ });
381
+ const card = findCatalogMcpServerCard({
382
+ id: channel.id,
383
+ name: channel.name
384
+ });
385
+ const src = card ? getMcpServerIconSrc(card) : void 0;
386
+ if (src) return /* @__PURE__ */ jsx("span", {
387
+ className: "manager-office__channel-mark",
388
+ children: /* @__PURE__ */ jsx("img", {
389
+ alt: "",
390
+ className: "sigvelo-brand-mark sigvelo-brand-mark--colorful",
391
+ decoding: "async",
392
+ referrerPolicy: "no-referrer",
393
+ src
394
+ })
395
+ });
396
+ return /* @__PURE__ */ jsx(AppIcon.Fallback, { children: channel.name.slice(0, 1) });
397
+ }
398
+ function ChannelRow({ channel }) {
399
+ return /* @__PURE__ */ jsxs("li", {
400
+ className: "manager-office__channel",
401
+ "data-status": channel.status,
402
+ children: [
403
+ /* @__PURE__ */ jsx(AppIcon.Root, {
404
+ size: "sm",
405
+ "aria-hidden": "true",
406
+ children: /* @__PURE__ */ jsx(ChannelMark, { channel })
407
+ }),
408
+ /* @__PURE__ */ jsxs("span", {
409
+ className: "manager-office__identity",
410
+ children: [/* @__PURE__ */ jsx("strong", {
411
+ className: "sigvelo-truncate",
412
+ children: channel.name
413
+ }), /* @__PURE__ */ jsx("small", {
414
+ className: "sigvelo-truncate",
415
+ children: channel.detail ?? channelStatusLabels[channel.status]
416
+ })]
417
+ }),
418
+ /* @__PURE__ */ jsxs("span", {
419
+ className: "manager-office__channel-status",
420
+ "data-status": channel.status,
421
+ title: channelStatusLabels[channel.status],
422
+ children: [channelStatusIcon(channel.status), /* @__PURE__ */ jsx("span", {
423
+ className: "sigvelo-visually-hidden",
424
+ children: channelStatusLabels[channel.status]
425
+ })]
426
+ })
427
+ ]
428
+ });
429
+ }
430
+ /**
431
+ * A handoff is the one thing on this surface that is waiting on a person, so
432
+ * it gets the surface built for that — `AgentAttention` in its warning tone —
433
+ * rather than another ghost row indistinguishable from the work beneath it.
434
+ * The action is a link into the owning work, because that is where the single
435
+ * approval surface lives; nothing is approved or dismissed from the roster.
436
+ */
437
+ function HandoffCard({ employee, handoff, renderLink, now, showEmployee }) {
438
+ return /* @__PURE__ */ jsxs(AgentAttention, {
439
+ tone: "attention",
440
+ className: cx("manager-office__handoff", !handoff.request && "manager-office__handoff--bare"),
441
+ children: [
442
+ /* @__PURE__ */ jsx(AgentAttentionHeader, {
443
+ icon: /* @__PURE__ */ jsx(InfoIcon, {}),
444
+ title: handoff.reason,
445
+ description: /* @__PURE__ */ jsxs(Fragment, { children: [
446
+ showEmployee ? `${employee.name} · ` : null,
447
+ handoff.workTitle,
448
+ " · ",
449
+ /* @__PURE__ */ jsx(Timestamp, {
450
+ timestamp: handoff.createdAt,
451
+ now
452
+ })
453
+ ] })
454
+ }),
455
+ handoff.request ? /* @__PURE__ */ jsx(AgentAttentionBody, {
456
+ className: "manager-office__handoff-ask",
457
+ children: handoff.request
458
+ }) : null,
459
+ /* @__PURE__ */ jsx(AgentAttentionActions, { children: /* @__PURE__ */ jsxs(LinkButton, {
460
+ render: renderLink({
461
+ kind: "handoff",
462
+ employee,
463
+ handoff
464
+ }),
465
+ size: "sm",
466
+ "aria-label": `Open ${handoff.workTitle} to ${handoff.reason.toLowerCase()}`,
467
+ children: [/* @__PURE__ */ jsx(MonitorIcon, {}), "Open browser"]
468
+ }) })
469
+ ]
470
+ });
471
+ }
472
+ /** Dense nested action for an employee alert already signalled by the roster status. */
473
+ function ManagerOfficeSidebarAlert({ className, detail, title, ...props }) {
474
+ return /* @__PURE__ */ jsxs(LinkButton, {
475
+ variant: "ghost",
476
+ color: "neutral",
477
+ size: "sm",
478
+ className: cx("manager-office__sidebar-alert", className),
479
+ ...props,
480
+ children: [/* @__PURE__ */ jsxs("span", {
481
+ className: "manager-office__sidebar-alert-copy",
482
+ children: [/* @__PURE__ */ jsx("strong", { children: title }), /* @__PURE__ */ jsxs("span", {
483
+ className: "manager-office__sidebar-alert-meta",
484
+ children: [detail ? /* @__PURE__ */ jsx("small", { children: detail }) : null, /* @__PURE__ */ jsx("span", {
485
+ className: "manager-office__sidebar-alert-status",
486
+ children: "Blocked"
487
+ })]
488
+ })]
489
+ }), /* @__PURE__ */ jsx(ChevronRightIcon, {
490
+ className: "manager-office__sidebar-alert-chevron",
491
+ "aria-hidden": "true"
492
+ })]
493
+ });
494
+ }
495
+ /**
496
+ * Shared Manager Office rail. Stories and host shells may add employee-owned
497
+ * content, but the Workforce header, roster identity, status language, scrolling,
498
+ * and footer placement stay component-owned and therefore cannot drift.
499
+ */
500
+ function moveRosterFocus(event, layout) {
501
+ const nextKey = layout === "office" ? "ArrowDown" : "ArrowRight";
502
+ const prevKey = layout === "office" ? "ArrowUp" : "ArrowLeft";
503
+ if (event.key !== nextKey && event.key !== prevKey && event.key !== "Home" && event.key !== "End") return;
504
+ const links = [...event.currentTarget.querySelectorAll("a[href], button")];
505
+ const index = links.findIndex((link) => link === document.activeElement);
506
+ if (index < 0) return;
507
+ event.preventDefault();
508
+ const last = links.length - 1;
509
+ links[event.key === "Home" ? 0 : event.key === "End" ? last : event.key === nextKey ? Math.min(last, index + 1) : Math.max(0, index - 1)]?.focus();
510
+ }
511
+ function ManagerOfficeSidebar({ className, closeSidebarOnCompact, content, employees, renderLink, footer, layout = "office", officeActions, selectedEmployeeId, ...props }) {
512
+ const rosterLabelId = React.useId();
513
+ const profileColors = rosterProfileColors(employees);
514
+ const isChat = layout === "chat";
515
+ return /* @__PURE__ */ jsx(Tooltip.Provider, { children: /* @__PURE__ */ jsxs("nav", {
516
+ className: cx("manager-office__sidebar", className),
517
+ "aria-label": "Workforce",
518
+ "data-layout": layout,
519
+ ...props,
520
+ children: [
521
+ /* @__PURE__ */ jsxs("div", {
522
+ className: "manager-office__sidebar-heading",
523
+ children: [isChat ? null : /* @__PURE__ */ jsx("strong", { children: "Workforce" }), officeActions ? /* @__PURE__ */ jsx("span", {
524
+ className: "manager-office__sidebar-actions",
525
+ children: officeActions
526
+ }) : null]
527
+ }),
528
+ /* @__PURE__ */ jsx("p", {
529
+ className: "manager-office__nav-label sigvelo-visually-hidden",
530
+ id: rosterLabelId,
531
+ children: "Employees"
532
+ }),
533
+ /* @__PURE__ */ jsx("ul", {
534
+ className: "manager-office__employee-nav",
535
+ role: "list",
536
+ "aria-labelledby": rosterLabelId,
537
+ onKeyDown: (event) => moveRosterFocus(event, layout),
538
+ children: employees.map((employee, index) => {
539
+ const selected = selectedEmployeeId === employee.id;
540
+ const status = employeeStatusText(employee);
541
+ return /* @__PURE__ */ jsx("li", {
542
+ className: "manager-office__employee-group",
543
+ children: /* @__PURE__ */ jsxs(LinkButton, {
544
+ render: renderLink({
545
+ kind: "employee",
546
+ employee
547
+ }),
548
+ onClick: closeSidebarOnCompact,
549
+ variant: "ghost",
550
+ color: "neutral",
551
+ size: "sm",
552
+ className: "manager-office__employee-link",
553
+ "aria-current": selected ? "page" : void 0,
554
+ "aria-label": `Open ${employee.name} · ${status}`,
555
+ title: isChat ? `${employee.name} · ${status}` : void 0,
556
+ children: [/* @__PURE__ */ jsxs("span", {
557
+ className: "manager-office__employee-avatar",
558
+ children: [/* @__PURE__ */ jsx(EmployeeAvatar, {
559
+ employee,
560
+ color: profileColors.get(employee.id),
561
+ index,
562
+ size: isChat ? "sm" : "md"
563
+ }), /* @__PURE__ */ jsx(EmployeePresence, { employee })]
564
+ }), isChat ? null : /* @__PURE__ */ jsxs("span", {
565
+ className: "manager-office__identity",
566
+ children: [/* @__PURE__ */ jsx("strong", {
567
+ className: "sigvelo-truncate",
568
+ children: employee.name
569
+ }), /* @__PURE__ */ jsx("small", {
570
+ className: "sigvelo-truncate",
571
+ children: statusLabels[employee.status]
572
+ })]
573
+ })]
574
+ })
575
+ }, employee.id);
576
+ })
577
+ }),
578
+ content ? /* @__PURE__ */ jsx("div", {
579
+ className: "manager-office__sidebar-content",
580
+ children: content
581
+ }) : null,
582
+ footer ? /* @__PURE__ */ jsx("div", {
583
+ className: "manager-office__sidebar-footer",
584
+ children: footer
585
+ }) : null
586
+ ]
587
+ }) });
588
+ }
589
+ function isReviewWork(work) {
590
+ return work.status === "attention" || work.status === "error";
591
+ }
592
+ /** Finished or failed work the manager should open in chat — not a live-tab wait. */
593
+ function reviewWorkFor(employee) {
594
+ const waiting = new Set(employee.handoffs.map((handoff) => handoff.workId));
595
+ return employee.work.filter((work) => isReviewWork(work) && !waiting.has(work.id));
596
+ }
597
+ function workingSetOf(work) {
598
+ return work.workingSet ?? [];
599
+ }
600
+ function workingSetKey(item) {
601
+ if (item.kind === "file" || item.kind === "folder") return `${item.kind}:${item.path}`;
602
+ if (item.kind === "link") return `link:${item.href}`;
603
+ return `correspondent:${correspondentHandleLabel(item.correspondent.handle)}`;
604
+ }
605
+ function safeHttpUrl(url) {
606
+ try {
607
+ const parsed = new URL(url);
608
+ if (parsed.protocol !== "https:" && parsed.protocol !== "http:") return void 0;
609
+ return parsed.href;
610
+ } catch {
611
+ return;
612
+ }
613
+ }
614
+ function providerCardForHref(href) {
615
+ let parsed;
616
+ try {
617
+ parsed = new URL(href);
618
+ } catch {
619
+ return;
620
+ }
621
+ const host = parsed.hostname.toLowerCase();
622
+ if (host === "docs.google.com" || host.endsWith(".docs.google.com")) {
623
+ if (parsed.pathname.includes("/spreadsheets/")) return findCatalogMcpServerCard({ id: "google-sheets" });
624
+ if (parsed.pathname.includes("/document/")) return findCatalogMcpServerCard({ id: "google-docs" });
625
+ if (parsed.pathname.includes("/presentation/")) return findCatalogMcpServerCard({ id: "google-slides" });
626
+ }
627
+ if (host === "drive.google.com" || host.endsWith(".drive.google.com")) return findCatalogMcpServerCard({ id: "google-drive" });
628
+ }
629
+ function workingSetLinkDetail(item) {
630
+ const card = providerCardForHref(item.href);
631
+ if (card) return card.name;
632
+ try {
633
+ return new URL(item.href).hostname.replace(/^www\./u, "");
634
+ } catch {
635
+ return item.href;
636
+ }
637
+ }
638
+ function WorkingSetMark({ item }) {
639
+ if (item.kind === "file") return /* @__PURE__ */ jsx(FileIcon, {});
640
+ if (item.kind === "folder") return /* @__PURE__ */ jsx(FolderIcon, {});
641
+ const card = providerCardForHref(item.href);
642
+ const src = card ? getMcpServerIconSrc(card) : void 0;
643
+ if (src) return /* @__PURE__ */ jsxs(AppIcon.Root, {
644
+ size: "xs",
645
+ variant: "artwork",
646
+ "aria-hidden": "true",
647
+ children: [/* @__PURE__ */ jsx(AppIcon.Image, {
648
+ src,
649
+ alt: ""
650
+ }), /* @__PURE__ */ jsx(AppIcon.Fallback, { children: (card?.name ?? item.title).slice(0, 1) })]
651
+ });
652
+ return /* @__PURE__ */ jsx(LinkIcon, {});
653
+ }
654
+ function routineDetail(routine) {
655
+ const schedule = routine.enabled ? routine.task.schedule : `Paused · ${routine.task.schedule}`;
656
+ const finishedRuns = routine.runs.filter((run) => run.completedAt != null);
657
+ if (!finishedRuns.length) return schedule;
658
+ return `${schedule} · ${finishedRuns.filter((run) => {
659
+ const status = getThinkExecutionRunStatus(run);
660
+ return status === "completed" || status === "complete";
661
+ }).length} of ${finishedRuns.length} recent runs completed`;
662
+ }
663
+ /**
664
+ * Where a work link sits decides whether it draws its own surface: a row in a
665
+ * work list is a bounded row, while a lane heading sits inside the lane card,
666
+ * which already draws one.
667
+ */
668
+ const workLinkClassNames = {
669
+ row: "manager-office__work-link",
670
+ lane: "manager-office__lane-title"
671
+ };
672
+ /** The link onto a work thread, shared by standalone rows and lane headings. */
673
+ function WorkLink({ employee, placement, renderLink, now, showEmployee, work }) {
674
+ return /* @__PURE__ */ jsxs(LinkButton, {
675
+ render: renderLink({
676
+ kind: "work",
677
+ employee,
678
+ work
679
+ }),
680
+ variant: "ghost",
681
+ color: "neutral",
682
+ size: "sm",
683
+ className: workLinkClassNames[placement],
684
+ "aria-label": `Open ${work.title} to ${threadStatusLabel(work.status).toLowerCase()}`,
685
+ children: [
686
+ /* @__PURE__ */ jsx(ThreadStatusIcon, { status: work.status }),
687
+ /* @__PURE__ */ jsxs("span", {
688
+ className: "manager-office__identity",
689
+ children: [/* @__PURE__ */ jsxs("strong", {
690
+ className: "sigvelo-truncate",
691
+ children: [work.title, work.status === "attention" ? /* @__PURE__ */ jsx("span", {
692
+ className: "manager-office__unread-dot",
693
+ "aria-hidden": "true"
694
+ }) : null]
695
+ }), /* @__PURE__ */ jsxs("small", {
696
+ className: "sigvelo-truncate",
697
+ children: [
698
+ showEmployee ? `${employee.name} · ` : null,
699
+ threadStatusLabel(work.status),
700
+ " · ",
701
+ /* @__PURE__ */ jsx(Timestamp, {
702
+ timestamp: work.updatedAt,
703
+ now
704
+ })
705
+ ]
706
+ })]
707
+ }),
708
+ /* @__PURE__ */ jsx(ChevronRightIcon, { className: "manager-office__row-chevron" })
709
+ ]
710
+ });
711
+ }
712
+ function workingSetItemCaption(item) {
713
+ if (item.kind === "link") return workingSetLinkDetail(item);
714
+ return item.kind === "folder" ? "Workspace folder" : "Workspace file";
715
+ }
716
+ function WorkingSetAttachment(props) {
717
+ const { caption, label, mark, title } = props;
718
+ const contents = /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
719
+ className: "manager-office__working-set-mark",
720
+ "aria-hidden": "true",
721
+ children: mark
722
+ }), /* @__PURE__ */ jsx("strong", {
723
+ className: "sigvelo-truncate",
724
+ children: title
725
+ })] });
726
+ const link = "href" in props ? /* @__PURE__ */ jsx(LinkButton, {
727
+ href: props.href,
728
+ target: "_blank",
729
+ rel: "noreferrer",
730
+ variant: "ghost",
731
+ color: "neutral",
732
+ size: "sm",
733
+ className: "manager-office__working-set-link",
734
+ "aria-label": label,
735
+ children: contents
736
+ }) : /* @__PURE__ */ jsx(LinkButton, {
737
+ render: props.render,
738
+ variant: "ghost",
739
+ color: "neutral",
740
+ size: "sm",
741
+ className: "manager-office__working-set-link",
742
+ "aria-label": label,
743
+ children: contents
744
+ });
745
+ return /* @__PURE__ */ jsxs(Tooltip.Root, { children: [/* @__PURE__ */ jsx(Tooltip.Trigger, { render: link }), /* @__PURE__ */ jsx(Tooltip.Portal, { children: /* @__PURE__ */ jsx(Tooltip.Positioner, {
746
+ side: "bottom",
747
+ sideOffset: 6,
748
+ children: /* @__PURE__ */ jsx(Tooltip.Popup, { children: caption })
749
+ }) })] });
750
+ }
751
+ function WorkingSetItemRow({ employee, item, renderLink, work }) {
752
+ if (item.kind === "correspondent") return /* @__PURE__ */ jsx("li", {
753
+ className: "manager-office__working-set-item",
754
+ children: /* @__PURE__ */ jsx(CorrespondentName, { correspondent: item.correspondent })
755
+ });
756
+ const caption = workingSetItemCaption(item);
757
+ const mark = /* @__PURE__ */ jsx(WorkingSetMark, { item });
758
+ if (item.kind === "link") {
759
+ const href = safeHttpUrl(item.href);
760
+ if (!href) return null;
761
+ return /* @__PURE__ */ jsx("li", {
762
+ className: "manager-office__working-set-item",
763
+ children: /* @__PURE__ */ jsx(WorkingSetAttachment, {
764
+ caption,
765
+ label: `${item.title} (${caption}, opens in a new tab)`,
766
+ href,
767
+ mark,
768
+ title: item.title
769
+ })
770
+ });
771
+ }
772
+ const location = item.kind === "folder" ? "folder" : "file";
773
+ return /* @__PURE__ */ jsx("li", {
774
+ className: "manager-office__working-set-item",
775
+ children: /* @__PURE__ */ jsx(WorkingSetAttachment, {
776
+ caption,
777
+ label: `Open ${item.title} ${location} in workspace`,
778
+ render: renderLink({
779
+ kind: "workspace",
780
+ employee,
781
+ work,
782
+ path: item.path
783
+ }),
784
+ mark,
785
+ title: item.title
786
+ })
787
+ });
788
+ }
789
+ function WorkLane({ employee, now, renderLink, work }) {
790
+ const titleId = React.useId();
791
+ const workingSet = workingSetOf(work);
792
+ return /* @__PURE__ */ jsxs("article", {
793
+ className: "manager-office__lane",
794
+ "aria-labelledby": titleId,
795
+ children: [
796
+ /* @__PURE__ */ jsx("h3", {
797
+ id: titleId,
798
+ className: "manager-office__lane-heading",
799
+ children: /* @__PURE__ */ jsx(WorkLink, {
800
+ employee,
801
+ now,
802
+ placement: "lane",
803
+ renderLink,
804
+ showEmployee: false,
805
+ work
806
+ })
807
+ }),
808
+ work.summary ? /* @__PURE__ */ jsx("p", {
809
+ className: "manager-office__lane-summary",
810
+ children: work.summary
811
+ }) : null,
812
+ workingSet.length ? /* @__PURE__ */ jsx("ul", {
813
+ className: "manager-office__working-set",
814
+ role: "list",
815
+ "aria-label": "Working set",
816
+ children: workingSet.map((item) => /* @__PURE__ */ jsx(WorkingSetItemRow, {
817
+ employee,
818
+ item,
819
+ renderLink,
820
+ work
821
+ }, workingSetKey(item)))
822
+ }) : null
823
+ ]
824
+ });
825
+ }
826
+ function ManagerOfficeAttention({ className, ...props }) {
827
+ const { employees, renderLink, now } = useOffice();
828
+ const waits = employees.flatMap((employee) => isConnected(employee) ? employee.handoffs.map((handoff) => ({
829
+ employee,
830
+ handoff
831
+ })) : []);
832
+ const reviews = employees.flatMap((employee) => isConnected(employee) ? reviewWorkFor(employee).map((work) => ({
833
+ employee,
834
+ work
835
+ })) : []);
836
+ if (!waits.length && !reviews.length) return /* @__PURE__ */ jsx("div", {
837
+ ...props,
838
+ className: cx("manager-office__attention", className),
839
+ "data-recipe": "page",
840
+ children: /* @__PURE__ */ jsx(EmptyState, {
841
+ icon: /* @__PURE__ */ jsx(CheckIcon, {}),
842
+ title: "Nothing needs you",
843
+ description: "Employee connection state remains visible in the roster."
844
+ })
845
+ });
846
+ const both = waits.length > 0 && reviews.length > 0;
847
+ return /* @__PURE__ */ jsxs("div", {
848
+ ...props,
849
+ className: cx("manager-office__attention", className),
850
+ "data-recipe": "page",
851
+ children: [waits.length ? /* @__PURE__ */ jsxs("div", {
852
+ className: "manager-office__attention-group",
853
+ children: [both ? /* @__PURE__ */ jsx("h2", {
854
+ className: "manager-office__section-title",
855
+ children: "Needs you in the browser"
856
+ }) : null, /* @__PURE__ */ jsx("ul", {
857
+ className: "manager-office__attention-list sigvelo-stack-list",
858
+ "aria-label": "Waiting on you",
859
+ children: waits.map(({ employee, handoff }) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(HandoffCard, {
860
+ employee,
861
+ handoff,
862
+ renderLink,
863
+ now,
864
+ showEmployee: true
865
+ }) }, `${employee.id}:${handoff.id}`))
866
+ })]
867
+ }) : null, reviews.length ? /* @__PURE__ */ jsxs("div", {
868
+ className: "manager-office__attention-group",
869
+ children: [/* @__PURE__ */ jsx("h2", {
870
+ className: "manager-office__section-title",
871
+ children: "Ready for you"
872
+ }), /* @__PURE__ */ jsx("ul", {
873
+ className: "manager-office__work-list sigvelo-stack-list",
874
+ "aria-label": "Ready for you",
875
+ children: reviews.map(({ employee, work }) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(WorkLink, {
876
+ employee,
877
+ work,
878
+ placement: "row",
879
+ renderLink,
880
+ now,
881
+ showEmployee: true
882
+ }) }, `${employee.id}:${work.id}`))
883
+ })]
884
+ }) : null]
885
+ });
886
+ }
887
+ const employeeDefaults = {
888
+ className: "manager-office__employee-detail",
889
+ "data-recipe": "page"
890
+ };
891
+ /** Scope the selected employee without imposing dossier content or column order. */
892
+ function ManagerOfficeEmployeeRoot({ employee, render, ref, ...props }) {
893
+ const element = useRender({
894
+ defaultTagName: "div",
895
+ render,
896
+ ref,
897
+ props: mergeProps(employeeDefaults, props)
898
+ });
899
+ return /* @__PURE__ */ jsx(EmployeeContext.Provider, {
900
+ value: employee,
901
+ children: element
902
+ });
903
+ }
904
+ function ManagerOfficeEmployeeHeader({ className, ...props }) {
905
+ const employee = useEmployee();
906
+ const { profileColors } = useOffice();
907
+ const profileColor = profileColors.get(employee.id) ?? chromeProfileColor(employee.id);
908
+ return /* @__PURE__ */ jsxs("header", {
909
+ ...props,
910
+ className: cx("manager-office__employee-header", className),
911
+ children: [/* @__PURE__ */ jsx(EmployeeAvatar, {
912
+ employee,
913
+ color: profileColor,
914
+ size: "lg"
915
+ }), /* @__PURE__ */ jsxs("div", {
916
+ className: "manager-office__briefing",
917
+ children: [
918
+ /* @__PURE__ */ jsx("strong", {
919
+ className: "sigvelo-truncate",
920
+ children: employee.name
921
+ }),
922
+ /* @__PURE__ */ jsx("small", {
923
+ className: "sigvelo-truncate",
924
+ children: employee.email
925
+ }),
926
+ /* @__PURE__ */ jsx("p", {
927
+ className: "manager-office__role",
928
+ children: employee.role
929
+ })
930
+ ]
931
+ })]
932
+ });
933
+ }
934
+ function ManagerOfficeHandoffs({ className, ...props }) {
935
+ const employee = useEmployee();
936
+ const { renderLink, now } = useOffice();
937
+ return employee.handoffs.length ? /* @__PURE__ */ jsx("section", {
938
+ ...props,
939
+ className: cx("manager-office__employee-handoffs", className),
940
+ "aria-label": "Waiting on you",
941
+ children: employee.handoffs.map((handoff) => /* @__PURE__ */ jsx(HandoffCard, {
942
+ employee,
943
+ handoff,
944
+ renderLink,
945
+ now,
946
+ showEmployee: false
947
+ }, handoff.id))
948
+ }) : null;
949
+ }
950
+ function ManagerOfficeWorkSection({ className, ...props }) {
951
+ const employee = useEmployee();
952
+ const { renderLink, now } = useOffice();
953
+ return /* @__PURE__ */ jsxs("section", {
954
+ ...props,
955
+ className: cx("manager-office__section", className),
956
+ children: [/* @__PURE__ */ jsx("header", {
957
+ className: "manager-office__section-header",
958
+ children: /* @__PURE__ */ jsxs("h2", {
959
+ className: "manager-office__section-title",
960
+ children: [/* @__PURE__ */ jsx(MessageSquareIcon, {}), "Work"]
961
+ })
962
+ }), /* @__PURE__ */ jsx("div", {
963
+ className: "manager-office__section-content",
964
+ children: employee.work.length ? /* @__PURE__ */ jsx("ul", {
965
+ className: "manager-office__work-list sigvelo-stack-list",
966
+ children: employee.work.map((work) => /* @__PURE__ */ jsx("li", { children: workingSetOf(work).length ? /* @__PURE__ */ jsx(WorkLane, {
967
+ employee,
968
+ now,
969
+ renderLink,
970
+ work
971
+ }) : /* @__PURE__ */ jsx(WorkLink, {
972
+ employee,
973
+ now,
974
+ placement: "row",
975
+ renderLink,
976
+ showEmployee: false,
977
+ work
978
+ }) }, work.id))
979
+ }) : /* @__PURE__ */ jsx("p", {
980
+ className: "manager-office__section-empty",
981
+ children: "No work yet."
982
+ })
983
+ })]
984
+ });
985
+ }
986
+ function ManagerOfficeRoutines({ className, ...props }) {
987
+ const employee = useEmployee();
988
+ const { renderLink } = useOffice();
989
+ return /* @__PURE__ */ jsx("section", {
990
+ ...props,
991
+ className: cx("manager-office__section", className),
992
+ "aria-label": "Routines",
993
+ children: /* @__PURE__ */ jsxs(Collapsible.Root, {
994
+ defaultOpen: true,
995
+ children: [/* @__PURE__ */ jsxs(Button, {
996
+ render: /* @__PURE__ */ jsx(Collapsible.Trigger, { unstyled: true }),
997
+ type: "button",
998
+ variant: "ghost",
999
+ color: "neutral",
1000
+ size: "sm",
1001
+ className: "manager-office__routine-trigger",
1002
+ children: [/* @__PURE__ */ jsxs("span", {
1003
+ className: "manager-office__identity",
1004
+ children: [/* @__PURE__ */ jsx(CalendarIcon, {}), /* @__PURE__ */ jsx("strong", { children: "Routines" })]
1005
+ }), /* @__PURE__ */ jsx(ChevronDownIcon, { className: "sigvelo-disclosure-chevron" })]
1006
+ }), /* @__PURE__ */ jsx(Collapsible.Panel, {
1007
+ unstyled: true,
1008
+ children: employee.routines.length ? /* @__PURE__ */ jsx("ul", {
1009
+ className: "manager-office__routine-list sigvelo-stack-list",
1010
+ children: employee.routines.map((routine) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(LinkButton, {
1011
+ render: renderLink({
1012
+ kind: "routine",
1013
+ employee,
1014
+ routine
1015
+ }),
1016
+ variant: "ghost",
1017
+ color: "neutral",
1018
+ size: "sm",
1019
+ className: "manager-office__routine-link",
1020
+ children: [
1021
+ routine.enabled ? /* @__PURE__ */ jsx(CalendarIcon, {}) : /* @__PURE__ */ jsx(PauseIcon, {}),
1022
+ /* @__PURE__ */ jsxs("span", {
1023
+ className: "manager-office__identity",
1024
+ children: [/* @__PURE__ */ jsx("strong", {
1025
+ className: "sigvelo-truncate",
1026
+ children: routine.name
1027
+ }), /* @__PURE__ */ jsx("small", {
1028
+ className: "sigvelo-truncate",
1029
+ children: routineDetail(routine)
1030
+ })]
1031
+ }),
1032
+ /* @__PURE__ */ jsx(ChevronRightIcon, { className: "manager-office__row-chevron" })
1033
+ ]
1034
+ }) }, routine.id))
1035
+ }) : /* @__PURE__ */ jsx("p", {
1036
+ className: "manager-office__section-empty",
1037
+ children: "No routines yet."
1038
+ })
1039
+ })]
1040
+ })
1041
+ });
1042
+ }
1043
+ function ManagerOfficeChannels({ className, ...props }) {
1044
+ const employee = useEmployee();
1045
+ return /* @__PURE__ */ jsxs("section", {
1046
+ ...props,
1047
+ className: cx("manager-office__section", className),
1048
+ children: [/* @__PURE__ */ jsx("header", {
1049
+ className: "manager-office__section-header",
1050
+ children: /* @__PURE__ */ jsxs("h2", {
1051
+ className: "manager-office__section-title",
1052
+ children: [/* @__PURE__ */ jsx(LinkIcon, {}), "Channels"]
1053
+ })
1054
+ }), /* @__PURE__ */ jsx("div", {
1055
+ className: "manager-office__section-content",
1056
+ children: employee.channels.length ? /* @__PURE__ */ jsx("ul", {
1057
+ className: "manager-office__channel-list sigvelo-stack-list",
1058
+ children: employee.channels.map((channel) => /* @__PURE__ */ jsx(ChannelRow, { channel }, channel.id))
1059
+ }) : /* @__PURE__ */ jsx("p", {
1060
+ className: "manager-office__section-empty",
1061
+ children: "Nothing connected yet."
1062
+ })
1063
+ })]
1064
+ });
1065
+ }
1066
+ function ManagerOfficeMain({ render, ref, ...props }) {
1067
+ return useRender({
1068
+ defaultTagName: "main",
1069
+ render,
1070
+ ref,
1071
+ props: mergeProps({ className: "manager-office__main" }, props)
1072
+ });
1073
+ }
1074
+ function ManagerOfficeColumns({ render, ref, ...props }) {
1075
+ return useRender({
1076
+ defaultTagName: "div",
1077
+ render,
1078
+ ref,
1079
+ props: mergeProps({ className: "manager-office__employee-columns" }, props)
1080
+ });
1081
+ }
1082
+ function ManagerOfficeAside({ render, ref, ...props }) {
1083
+ return useRender({
1084
+ defaultTagName: "aside",
1085
+ render,
1086
+ ref,
1087
+ props: mergeProps({ className: "manager-office__employee-aside" }, props)
1088
+ });
1089
+ }
1090
+ /** Honest disconnected state; the host chooses when and where to display it. */
1091
+ function ManagerOfficeConnectionState({ employee }) {
1092
+ return /* @__PURE__ */ jsx("div", {
1093
+ "data-recipe": "page",
1094
+ children: /* @__PURE__ */ jsx(EmptyState, {
1095
+ icon: employee.status === "connecting" ? /* @__PURE__ */ jsx(SpinnerIcon, {}) : /* @__PURE__ */ jsx(MonitorIcon, {}),
1096
+ title: `${employee.name} is ${statusLabels[employee.status].toLowerCase()}`,
1097
+ description: employee.statusDescription
1098
+ })
1099
+ });
1100
+ }
1101
+ /** Office data and relative-time boundary; hosts compose their shell and routed content. */
1102
+ function ManagerOfficeRoot({ employees, renderLink, render, ref, ...props }) {
1103
+ const [now, setNow] = React.useState(Date.now);
1104
+ React.useEffect(() => {
1105
+ const interval = window.setInterval(() => setNow(Date.now()), 6e4);
1106
+ return () => window.clearInterval(interval);
1107
+ }, []);
1108
+ const profileColors = React.useMemo(() => rosterProfileColors(employees), [employees]);
1109
+ const value = React.useMemo(() => ({
1110
+ employees,
1111
+ renderLink,
1112
+ now,
1113
+ profileColors
1114
+ }), [
1115
+ employees,
1116
+ renderLink,
1117
+ now,
1118
+ profileColors
1119
+ ]);
1120
+ const element = useRender({
1121
+ defaultTagName: "div",
1122
+ render,
1123
+ ref,
1124
+ props: mergeProps({ className: "manager-office" }, props)
1125
+ });
1126
+ return /* @__PURE__ */ jsx(OfficeContext.Provider, {
1127
+ value,
1128
+ children: /* @__PURE__ */ jsx(Tooltip.Provider, { children: element })
1129
+ });
1130
+ }
1131
+ const ManagerOffice = {
1132
+ Root: ManagerOfficeRoot,
1133
+ Main: ManagerOfficeMain,
1134
+ Attention: ManagerOfficeAttention,
1135
+ Employee: ManagerOfficeEmployeeRoot,
1136
+ EmployeeHeader: ManagerOfficeEmployeeHeader,
1137
+ Handoffs: ManagerOfficeHandoffs,
1138
+ Columns: ManagerOfficeColumns,
1139
+ Aside: ManagerOfficeAside,
1140
+ Work: ManagerOfficeWorkSection,
1141
+ Routines: ManagerOfficeRoutines,
1142
+ Channels: ManagerOfficeChannels,
1143
+ ConnectionState: ManagerOfficeConnectionState
1144
+ };
1145
+ //#endregion
1146
+ export { ManagerOfficeSidebar as n, ManagerOfficeSidebarAlert as r, ManagerOffice as t };