@mcp-b/react-components 0.47.0 → 0.49.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 (274) hide show
  1. package/dist/AgentChatQueue-C_Jaw3Ia.d.ts +48 -0
  2. package/dist/AgentToolRunsContext-GMe_hSnD.d.ts +35 -0
  3. package/dist/Avatar-o2NO1fCG.d.ts +124 -0
  4. package/dist/{Button-CZt3yywF.d.ts → Button-DjONW5UW.d.ts} +1 -1
  5. package/dist/{CodeBlock-C380GD5t.d.ts → CodeBlock--r6GS8YV.d.ts} +8 -2
  6. package/dist/{CodeBlock-DMHZiw86.js → CodeBlock-g8sADidM.js} +7 -7
  7. package/dist/Correspondent-7K6uNLUm.d.ts +64 -0
  8. package/dist/{FileTree-BHebfvkK.js → FileTree-H8mMg4rV.js} +20 -29
  9. package/dist/{IconButton-BAUFhUk8.d.ts → IconButton-ByiyjkYE.d.ts} +2 -2
  10. package/dist/{Message-D_vCVEGB.d.ts → Message-DyaTBiV7.d.ts} +17 -4
  11. package/dist/MessageScrollerVirtual-D4afYwVB.d.ts +84 -0
  12. package/dist/{PromptInput-DtJHyp0S.d.ts → PromptInput-C4Mofitz.d.ts} +44 -31
  13. package/dist/PromptInputApproval-D2hpn54U.d.ts +44 -0
  14. package/dist/Separator-CzhtLYE1.d.ts +41 -0
  15. package/dist/Toolbar-CGY004u0.d.ts +155 -0
  16. package/dist/{Workspace-C_zHq9KZ.d.ts → Workspace-HzGrWDX3.d.ts} +14 -3
  17. package/dist/{WorkspaceFile-Dq-GC0_T.d.ts → WorkspaceFile-Bouauobc.d.ts} +1 -1
  18. package/dist/{WorkspaceFileView-ChIJz-fl.js → WorkspaceFileView-DYPtRVpM.js} +4 -3
  19. package/dist/{WorkspaceLink-B1d2GIGl.js → WorkspaceLink-BYZG-V_I.js} +8 -91
  20. package/dist/{WorkspaceMessageResponse-Dg_aNpoj.js → WorkspaceMessageResponse-CUJk9_P5.js} +6 -3
  21. package/dist/components/agents-sdk/AgentChat.d.ts +198 -2
  22. package/dist/components/agents-sdk/AgentChat.js +525 -670
  23. package/dist/components/agents-sdk/AgentChatQueue.d.ts +2 -0
  24. package/dist/components/agents-sdk/AgentChatQueue.js +206 -0
  25. package/dist/components/agents-sdk/AgentEvent.js +1 -1
  26. package/dist/components/agents-sdk/AgentToolRunsContext.d.ts +2 -2
  27. package/dist/components/agents-sdk/AgentToolRunsContext.js +1 -36
  28. package/dist/components/agents-sdk/BrowserLiveScreen.js +21 -13
  29. package/dist/components/agents-sdk/BrowserReplay.d.ts +1 -1
  30. package/dist/components/agents-sdk/BrowserRunPanel.d.ts +3 -0
  31. package/dist/components/agents-sdk/BrowserRunPanel.js +31 -30
  32. package/dist/components/agents-sdk/EmployeeChrome.d.ts +212 -0
  33. package/dist/components/agents-sdk/EmployeeChrome.js +555 -0
  34. package/dist/components/agents-sdk/ManagerOffice.d.ts +115 -85
  35. package/dist/components/agents-sdk/ManagerOffice.js +545 -1154
  36. package/dist/components/agents-sdk/McpConnectionRequest.d.ts +4 -4
  37. package/dist/components/agents-sdk/McpConnectionRequest.js +3 -2
  38. package/dist/components/agents-sdk/McpConnectorForm.d.ts +38 -1
  39. package/dist/components/agents-sdk/McpPluginCatalog.d.ts +93 -1
  40. package/dist/components/agents-sdk/McpPluginCatalog.js +3 -2
  41. package/dist/components/agents-sdk/McpServerIcon.d.ts +17 -0
  42. package/dist/components/agents-sdk/McpServerIcon.js +25 -0
  43. package/dist/components/agents-sdk/McpServerPicker.d.ts +4 -3
  44. package/dist/components/agents-sdk/McpServerPicker.js +2 -1
  45. package/dist/components/agents-sdk/ModelSelector.d.ts +4 -4
  46. package/dist/components/agents-sdk/ModelSelector.js +3 -3
  47. package/dist/components/agents-sdk/PromptInputApproval.d.ts +1 -43
  48. package/dist/components/agents-sdk/PromptInputCommands.d.ts +1 -1
  49. package/dist/components/agents-sdk/PromptInputCommands.js +1 -2
  50. package/dist/components/agents-sdk/SessionCompaction.d.ts +88 -1
  51. package/dist/components/agents-sdk/SessionCompaction.js +2 -2
  52. package/dist/components/agents-sdk/SubagentRunDetails.d.ts +30 -1
  53. package/dist/components/agents-sdk/SubagentRunDetails.js +57 -1
  54. package/dist/components/agents-sdk/SubagentRunIndicator.d.ts +9 -9
  55. package/dist/components/agents-sdk/SubagentRunIndicator.js +18 -23
  56. package/dist/components/agents-sdk/SubagentRunList.d.ts +6 -3
  57. package/dist/components/agents-sdk/SubagentRunList.js +4 -2
  58. package/dist/components/agents-sdk/SubagentRunPanel.d.ts +60 -0
  59. package/dist/components/agents-sdk/SubagentRunPanel.js +255 -0
  60. package/dist/components/agents-sdk/SubagentRunSelector.d.ts +8 -4
  61. package/dist/components/agents-sdk/SubagentRunSelector.js +4 -2
  62. package/dist/components/agents-sdk/ThinkChat.d.ts +102 -2
  63. package/dist/components/agents-sdk/ThinkChat.js +233 -2
  64. package/dist/components/agents-sdk/ThinkChatActivity.d.ts +76 -1
  65. package/dist/components/agents-sdk/ThinkChatActivity.js +17 -9
  66. package/dist/components/agents-sdk/ThinkChatContext.d.ts +27 -1
  67. package/dist/components/agents-sdk/ThinkChatContext.js +1 -1
  68. package/dist/components/agents-sdk/ThinkChatToolPanels.js +23 -18
  69. package/dist/components/agents-sdk/ThinkExecutionDetail.js +1 -1
  70. package/dist/components/agents-sdk/ThinkExecutionStatus.d.ts +1 -1
  71. package/dist/components/agents-sdk/ThinkExecutionWorkbench.d.ts +85 -28
  72. package/dist/components/agents-sdk/ThinkExecutionWorkbench.js +158 -101
  73. package/dist/components/agents-sdk/ThinkFullApp.d.ts +40 -158
  74. package/dist/components/agents-sdk/ThinkFullApp.js +71 -285
  75. package/dist/components/agents-sdk/ThinkRecoveryNotice.d.ts +18 -1
  76. package/dist/components/agents-sdk/ThinkRoutineActions.d.ts +51 -0
  77. package/dist/components/agents-sdk/ThinkRoutineActions.js +201 -0
  78. package/dist/components/agents-sdk/ThinkRoutineBrowser.d.ts +4 -1
  79. package/dist/components/agents-sdk/ThinkRoutineBrowser.js +16 -14
  80. package/dist/components/agents-sdk/ThinkRoutineDetail.js +12 -12
  81. package/dist/components/agents-sdk/ThinkRoutineForm.d.ts +2 -1
  82. package/dist/components/agents-sdk/ThinkRoutineForm.js +11 -11
  83. package/dist/components/agents-sdk/ThinkRoutineRuns.js +6 -6
  84. package/dist/components/agents-sdk/ThinkThreadPicker.d.ts +90 -1
  85. package/dist/components/agents-sdk/ThinkThreadPicker.js +2 -2
  86. package/dist/components/agents-sdk/Workspace.d.ts +2 -2
  87. package/dist/components/agents-sdk/Workspace.js +20 -23
  88. package/dist/components/agents-sdk/WorkspaceBrowser.d.ts +1 -1
  89. package/dist/components/agents-sdk/WorkspaceBrowser.js +1 -1
  90. package/dist/components/agents-sdk/WorkspaceConcept.d.ts +3 -2
  91. package/dist/components/agents-sdk/WorkspaceConcept.js +3 -3
  92. package/dist/components/agents-sdk/WorkspaceCorrespondence.d.ts +15 -10
  93. package/dist/components/agents-sdk/WorkspaceCorrespondence.js +43 -40
  94. package/dist/components/agents-sdk/WorkspaceExecution.d.ts +31 -31
  95. package/dist/components/agents-sdk/WorkspaceExecution.js +115 -192
  96. package/dist/components/agents-sdk/WorkspaceExplorer.d.ts +5 -2
  97. package/dist/components/agents-sdk/WorkspaceExplorer.js +3 -2
  98. package/dist/components/agents-sdk/WorkspaceFile.d.ts +1 -1
  99. package/dist/components/agents-sdk/WorkspaceFileView.d.ts +1 -1
  100. package/dist/components/agents-sdk/WorkspaceFileView.js +1 -1
  101. package/dist/components/agents-sdk/WorkspaceLink.js +1 -1
  102. package/dist/components/agents-sdk/WorkspaceLive.d.ts +60 -1
  103. package/dist/components/agents-sdk/WorkspaceLive.js +33 -5
  104. package/dist/components/agents-sdk/WorkspaceMessageResponse.d.ts +47 -1
  105. package/dist/components/agents-sdk/WorkspaceMessageResponse.js +1 -1
  106. package/dist/components/agents-sdk/WorkspaceMountManager.d.ts +3 -2
  107. package/dist/components/agents-sdk/WorkspaceMountManager.js +5 -8
  108. package/dist/components/agents-sdk/WorkspaceNavigationRestoration.d.ts +38 -0
  109. package/dist/components/agents-sdk/WorkspaceNavigationRestoration.js +86 -0
  110. package/dist/components/agents-sdk/WorkspaceProject.d.ts +44 -15
  111. package/dist/components/agents-sdk/WorkspaceProject.js +74 -51
  112. package/dist/components/agents-sdk/WorkspaceUserScript.d.ts +1 -1
  113. package/dist/components/agents-sdk/WorkspaceUserScript.js +5 -2
  114. package/dist/components/ai-sdk/Activity.d.ts +1 -1
  115. package/dist/components/ai-sdk/AgentAttention.d.ts +2 -2
  116. package/dist/components/ai-sdk/AgentChatStartScreen.d.ts +89 -2
  117. package/dist/components/ai-sdk/AgentChatStartScreen.js +63 -42
  118. package/dist/components/ai-sdk/AgentMessageParts.d.ts +45 -1
  119. package/dist/components/ai-sdk/Approval.d.ts +1 -1
  120. package/dist/components/ai-sdk/Artifact.d.ts +2 -2
  121. package/dist/components/ai-sdk/Artifact.js +2 -2
  122. package/dist/components/ai-sdk/ChainOfThought.d.ts +1 -1
  123. package/dist/components/ai-sdk/CodeBlock.d.ts +1 -1
  124. package/dist/components/ai-sdk/CodeBlock.js +1 -1
  125. package/dist/components/ai-sdk/ComposerLink.js +1 -2
  126. package/dist/components/ai-sdk/ConnectedAppCards.d.ts +16 -1
  127. package/dist/components/ai-sdk/ConnectedAppCards.js +69 -94
  128. package/dist/components/ai-sdk/Context.d.ts +7 -3
  129. package/dist/components/ai-sdk/Context.js +7 -17
  130. package/dist/components/ai-sdk/Conversation.d.ts +2 -2
  131. package/dist/components/ai-sdk/Correspondent.d.ts +2 -0
  132. package/dist/components/ai-sdk/Correspondent.js +145 -0
  133. package/dist/components/ai-sdk/Goal.d.ts +3 -3
  134. package/dist/components/ai-sdk/Goal.js +2 -2
  135. package/dist/components/ai-sdk/InlineCitation.d.ts +1 -1
  136. package/dist/components/ai-sdk/InlineCitation.js +1 -1
  137. package/dist/components/ai-sdk/MediaPreviewCard.d.ts +1 -1
  138. package/dist/components/ai-sdk/Message.d.ts +2 -2
  139. package/dist/components/ai-sdk/Message.js +11 -2
  140. package/dist/components/ai-sdk/MessageScroller.d.ts +1 -1
  141. package/dist/components/ai-sdk/MessageScrollerVirtual.d.ts +2 -76
  142. package/dist/components/ai-sdk/MessageScrollerVirtual.js +38 -4
  143. package/dist/components/ai-sdk/Plan.d.ts +1 -1
  144. package/dist/components/ai-sdk/PromptInput.d.ts +2 -2
  145. package/dist/components/ai-sdk/PromptInput.js +170 -226
  146. package/dist/components/ai-sdk/PromptInputComposerEditor.js +32 -9
  147. package/dist/components/ai-sdk/Queue.d.ts +28 -5
  148. package/dist/components/ai-sdk/Queue.js +19 -4
  149. package/dist/components/ai-sdk/Reasoning.d.ts +1 -1
  150. package/dist/components/ai-sdk/Reasoning.js +4 -4
  151. package/dist/components/ai-sdk/Sources.d.ts +1 -1
  152. package/dist/components/ai-sdk/Task.d.ts +1 -1
  153. package/dist/components/extension/ChatGptSignInScreen.d.ts +1 -1
  154. package/dist/components/extension/CodexModelSelector.d.ts +5 -0
  155. package/dist/components/extension/ConversationTabPicker.d.ts +1 -0
  156. package/dist/components/extension/ConversationTabPicker.js +1 -1
  157. package/dist/components/foundations/AlertDialog.d.ts +1 -1
  158. package/dist/components/foundations/AppIcon.d.ts +3 -2
  159. package/dist/components/foundations/Autocomplete.js +6 -1
  160. package/dist/components/foundations/Avatar.d.ts +1 -121
  161. package/dist/components/foundations/Button.d.ts +1 -1
  162. package/dist/components/foundations/Card.d.ts +22 -27
  163. package/dist/components/foundations/Card.js +51 -32
  164. package/dist/components/foundations/CheckboxGroup.d.ts +1 -1
  165. package/dist/components/foundations/Collapsible.d.ts +1 -1
  166. package/dist/components/foundations/Combobox.js +6 -1
  167. package/dist/components/foundations/Dialog.d.ts +106 -1
  168. package/dist/components/foundations/EmptyState.d.ts +1 -1
  169. package/dist/components/foundations/Field.d.ts +2 -1
  170. package/dist/components/foundations/Fieldset.d.ts +1 -1
  171. package/dist/components/foundations/Form.d.ts +4 -4
  172. package/dist/components/foundations/IconButton.d.ts +1 -1
  173. package/dist/components/foundations/Label.d.ts +1 -1
  174. package/dist/components/foundations/LinkButton.d.ts +2 -2
  175. package/dist/components/foundations/Meter.d.ts +1 -1
  176. package/dist/components/foundations/NumberField.d.ts +1 -1
  177. package/dist/components/foundations/ScrollArea.d.ts +1 -1
  178. package/dist/components/foundations/SearchField.d.ts +1 -1
  179. package/dist/components/foundations/Select.js +6 -1
  180. package/dist/components/foundations/Separator.d.ts +1 -40
  181. package/dist/components/foundations/Stepper.d.ts +1 -1
  182. package/dist/components/foundations/Textarea.d.ts +1 -1
  183. package/dist/components/foundations/Toast.d.ts +5 -1
  184. package/dist/components/foundations/Toggle.d.ts +70 -1
  185. package/dist/components/foundations/ToggleGroup.d.ts +3 -2
  186. package/dist/components/foundations/Toolbar.d.ts +1 -151
  187. package/dist/components/foundations/TransitionSurface.d.ts +1 -1
  188. package/dist/components/general-purpose/ActionGuide.d.ts +10 -26
  189. package/dist/components/general-purpose/ActionGuide.js +4 -18
  190. package/dist/components/general-purpose/AppTopBar.d.ts +4 -2
  191. package/dist/components/general-purpose/Commit.d.ts +2 -2
  192. package/dist/components/general-purpose/Commit.js +1 -1
  193. package/dist/components/general-purpose/EnvironmentVariables.d.ts +2 -2
  194. package/dist/components/general-purpose/FileTree.d.ts +1 -7
  195. package/dist/components/general-purpose/FileTree.js +1 -1
  196. package/dist/components/general-purpose/PricingBillingToggle.js +1 -1
  197. package/dist/components/general-purpose/PricingPlanCard.d.ts +4 -0
  198. package/dist/components/general-purpose/PricingUsageCalculator.js +1 -1
  199. package/dist/components/general-purpose/ResizableSidePanel.d.ts +2 -2
  200. package/dist/components/general-purpose/ResponsiveSidebarShell.d.ts +128 -2
  201. package/dist/components/general-purpose/ResponsiveSidebarShell.js +119 -101
  202. package/dist/components/general-purpose/SettingsFormDialog.d.ts +14 -27
  203. package/dist/components/general-purpose/SettingsFormDialog.js +40 -70
  204. package/dist/components/general-purpose/SetupChecklist.d.ts +1 -0
  205. package/dist/components/general-purpose/SetupChecklist.js +76 -1
  206. package/dist/components/general-purpose/Terminal.d.ts +3 -3
  207. package/dist/components/general-purpose/Terminal.js +10 -5
  208. package/dist/components/general-purpose/TestResults.d.ts +23 -11
  209. package/dist/components/general-purpose/TestResults.js +48 -50
  210. package/dist/components/general-purpose/ThemeModeControl.d.ts +2 -0
  211. package/dist/components/general-purpose/WebPreview.d.ts +29 -4
  212. package/dist/components/general-purpose/WebPreview.js +37 -12
  213. package/dist/components/nanites/AgentConnection.js +1 -1
  214. package/dist/components/nanites/AgentToolDetail.d.ts +13 -11
  215. package/dist/components/nanites/AgentToolDetail.js +20 -41
  216. package/dist/{copy-button-C0JyjClr.d.ts → copy-button-OUwOdgEm.d.ts} +1 -1
  217. package/dist/mcp-server-mAErsxHU.js +27 -0
  218. package/dist/styles/activity.css +1 -96
  219. package/dist/styles/agent-chat.css +75 -102
  220. package/dist/styles/agent-tool-detail.css +0 -16
  221. package/dist/styles/base.css +3 -3
  222. package/dist/styles/browser-run-panel.css +1 -15
  223. package/dist/styles/button.css +7 -1
  224. package/dist/styles/code-block.css +12 -0
  225. package/dist/styles/composition-motion.css +0 -2
  226. package/dist/styles/correspondent.css +73 -0
  227. package/dist/styles/employee-chrome.css +43 -0
  228. package/dist/styles/file-tree.css +5 -0
  229. package/dist/styles/index.css +5 -2
  230. package/dist/styles/manager-office.css +380 -1086
  231. package/dist/styles/message.css +2 -10
  232. package/dist/styles/queue.css +71 -0
  233. package/dist/styles/subagent-run.css +122 -6
  234. package/dist/styles/test-results.css +2 -5
  235. package/dist/styles/think-chat-activity.css +13 -0
  236. package/dist/styles/think-chat-tool-panels.css +81 -0
  237. package/dist/styles/think-execution-workbench.css +2 -8
  238. package/dist/styles/think-full-app.css +42 -251
  239. package/dist/styles/{think-routine-library.css → think-routine.css} +64 -80
  240. package/dist/styles/web-preview.css +15 -1
  241. package/dist/utils/mcp-server-catalog.d.ts +1112 -2
  242. package/dist/utils/mcp-server-catalog.js +28 -9
  243. package/dist/utils/structured-code.d.ts +1 -1
  244. package/dist/{workspace-assets-CxpEHsac.js → workspace-assets-Bg7XhPsk.js} +16 -2
  245. package/package.json +7 -3
  246. package/dist/AgentChat-BLmQghkt.d.ts +0 -327
  247. package/dist/AgentChatStartScreen-Bkv7Avni.d.ts +0 -84
  248. package/dist/AgentMessageParts-C7L-Mv9U.d.ts +0 -46
  249. package/dist/AgentToolRunsContext-jtmveaRE.d.ts +0 -57
  250. package/dist/Dialog-B_FhRWaz.d.ts +0 -107
  251. package/dist/McpConnectorForm-CeYNY0MI.d.ts +0 -39
  252. package/dist/McpPluginCatalog-3qWu8oK1.d.ts +0 -92
  253. package/dist/ResponsiveSidebarShell-BTVPxLJK.d.ts +0 -123
  254. package/dist/SessionCompaction-CmTJFpzj.d.ts +0 -89
  255. package/dist/SetupChecklist-CwRjIDH4.js +0 -77
  256. package/dist/ThinkChat-CwMdEum8.d.ts +0 -185
  257. package/dist/ThinkChat-DLDta57t.js +0 -332
  258. package/dist/ThinkChatActivity-B3lGVS-6.d.ts +0 -77
  259. package/dist/ThinkChatContext-COIgzkYp.d.ts +0 -28
  260. package/dist/ThinkRecoveryNotice-DGWr94rk.d.ts +0 -19
  261. package/dist/ThinkThreadPicker-yFz4vvIf.d.ts +0 -91
  262. package/dist/Toggle-DLrIf5YH.d.ts +0 -69
  263. package/dist/WorkspaceLive-DLGhtIly.d.ts +0 -49
  264. package/dist/WorkspaceMessageResponse-kJYU8Onj.d.ts +0 -48
  265. package/dist/components/agents-sdk/ThinkFullAppViewSwitch.d.ts +0 -31
  266. package/dist/components/agents-sdk/ThinkFullAppViewSwitch.js +0 -34
  267. package/dist/components/agents-sdk/ThinkRoutineLibrary.d.ts +0 -80
  268. package/dist/components/agents-sdk/ThinkRoutineLibrary.js +0 -159
  269. package/dist/components/agents-sdk/ThinkSidepanel.d.ts +0 -200
  270. package/dist/components/agents-sdk/ThinkSidepanel.js +0 -775
  271. package/dist/mcp-server-7NR24ASj.js +0 -69
  272. package/dist/mcp-server-catalog-C_g7C-9o.d.ts +0 -1108
  273. package/dist/styles/think-sidepanel.css +0 -78
  274. package/dist/think-agent-Cip5KAPj.d.ts +0 -7
@@ -1,23 +1,21 @@
1
- import { getMcpServerIconSrc } from "../../utils/mcp-server-catalog.js";
1
+ import { findCatalogMcpServerCard, getMcpServerIconSrc } from "../../utils/mcp-server-catalog.js";
2
2
  import { t as cx } from "../../class-names-BiMDVpUo.js";
3
- import { B as PlusIcon, C as FolderIcon, D as LinkIcon, H as RefreshIcon, K as SpinnerIcon, L as PauseIcon, P as MonitorIcon, R as PencilIcon, T as InfoIcon, _ as DotIcon, a as ArrowUpIcon, b as EyeIcon, d as CheckIcon, et as WarningIcon, f as ChevronDownIcon, j as MessageSquareIcon, n as ArrowDownIcon, nt as XIcon, p as ChevronRightIcon, u as CalendarIcon, v as DownloadIcon, z as PlayIcon } from "../../icons-cuEtsgj9.js";
3
+ 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-cuEtsgj9.js";
4
4
  import { Collapsible } from "../foundations/Collapsible.js";
5
5
  import { Button } from "../foundations/Button.js";
6
6
  import { Tooltip } from "../foundations/Tooltip.js";
7
+ import { EmptyState } from "../foundations/EmptyState.js";
7
8
  import { Avatar } from "../foundations/Avatar.js";
8
9
  import { AppIcon } from "../foundations/AppIcon.js";
9
- import { n as findCatalogMcpServerCard } from "../../mcp-server-7NR24ASj.js";
10
- import { EmptyState } from "../foundations/EmptyState.js";
11
- import { Menu } from "../foundations/Menu.js";
12
- import { AgentAttention, AgentAttentionActions, AgentAttentionBody, AgentAttentionHeader } from "../ai-sdk/AgentAttention.js";
13
10
  import { LinkButton } from "../foundations/LinkButton.js";
14
- import { Select } from "../foundations/Select.js";
15
11
  import "../foundations/icons.js";
16
- import { AppTopBar } from "../general-purpose/AppTopBar.js";
17
- import { ResponsiveSidebarShell } from "../general-purpose/ResponsiveSidebarShell.js";
12
+ import { AgentAttention, AgentAttentionActions, AgentAttentionBody, AgentAttentionHeader } from "../ai-sdk/AgentAttention.js";
13
+ import { CorrespondentName, correspondentHandleLabel } from "../ai-sdk/Correspondent.js";
18
14
  import { getThinkExecutionRunStatus } from "./ThinkExecutionRun.js";
19
15
  import * as React from "react";
20
16
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
17
+ import { useRender } from "@base-ui/react/use-render";
18
+ import { mergeProps } from "@base-ui/react/merge-props";
21
19
  //#region src/components/_internal/chrome-profile-colors.ts
22
20
  const PALETTE = [
23
21
  {
@@ -90,6 +88,18 @@ function chromeProfileColor(seed, taken) {
90
88
  }
91
89
  //#endregion
92
90
  //#region src/components/agents-sdk/ManagerOffice.tsx
91
+ const OfficeContext = React.createContext(null);
92
+ const EmployeeContext = React.createContext(null);
93
+ function useOffice() {
94
+ const value = React.useContext(OfficeContext);
95
+ if (!value) throw new Error("ManagerOffice parts require ManagerOffice.Root.");
96
+ return value;
97
+ }
98
+ function useEmployee() {
99
+ const value = React.useContext(EmployeeContext);
100
+ if (!value) throw new Error("Employee parts require ManagerOffice.Employee.");
101
+ return value;
102
+ }
93
103
  const statusLabels = {
94
104
  "needs-you": "Waiting on you",
95
105
  working: "Working",
@@ -124,26 +134,12 @@ function employeeStatusText(employee) {
124
134
  const label = statusLabels[employee.status];
125
135
  return count ? `${label} · ${count} handoff${count === 1 ? "" : "s"}` : label;
126
136
  }
127
- function statusIcon(status) {
128
- if (status === "needs-you" || status === "issue") return /* @__PURE__ */ jsx(WarningIcon, {});
129
- if (status === "unavailable") return /* @__PURE__ */ jsx(XIcon, {});
130
- if (status === "working" || status === "connecting") return /* @__PURE__ */ jsx(SpinnerIcon, {});
131
- if (status === "offline") return /* @__PURE__ */ jsx(MonitorIcon, {});
132
- return /* @__PURE__ */ jsx(PauseIcon, {});
133
- }
134
137
  function EmployeePresence({ employee }) {
135
- const label = employeeStatusText(employee);
136
- return /* @__PURE__ */ jsxs(Tooltip.Root, { children: [/* @__PURE__ */ jsx(Tooltip.Trigger, { render: /* @__PURE__ */ jsx("span", {
138
+ return /* @__PURE__ */ jsx("span", {
137
139
  className: "manager-office__nav-status",
138
140
  "data-status": employee.status,
139
- role: "img",
140
- "aria-label": label,
141
- children: statusIcon(employee.status)
142
- }) }), /* @__PURE__ */ jsx(Tooltip.Portal, { children: /* @__PURE__ */ jsx(Tooltip.Positioner, {
143
- side: "top",
144
- sideOffset: 6,
145
- children: /* @__PURE__ */ jsx(Tooltip.Popup, { children: label })
146
- }) })] });
141
+ "aria-hidden": "true"
142
+ });
147
143
  }
148
144
  /**
149
145
  * Each employee is a Chrome profile, so the bubble wears its profile color —
@@ -355,15 +351,6 @@ function relativeTime(timestamp, now) {
355
351
  if (elapsed < day) return `${Math.floor(elapsed / hour)}h`;
356
352
  return `${Math.floor(elapsed / day)}d`;
357
353
  }
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
- }
367
354
  function Timestamp({ now, timestamp }) {
368
355
  const date = new Date(timestamp);
369
356
  return /* @__PURE__ */ jsx("time", {
@@ -372,16 +359,6 @@ function Timestamp({ now, timestamp }) {
372
359
  children: relativeTime(timestamp, now)
373
360
  });
374
361
  }
375
- const channelDirectionLabels = {
376
- input: "In",
377
- output: "Out",
378
- both: "In · Out"
379
- };
380
- function channelDirectionIcon(direction) {
381
- if (direction === "input") return /* @__PURE__ */ jsx(ArrowDownIcon, {});
382
- if (direction === "output") return /* @__PURE__ */ jsx(ArrowUpIcon, {});
383
- return /* @__PURE__ */ jsx(RefreshIcon, {});
384
- }
385
362
  /**
386
363
  * Deliberately the same three glyphs the employee statuses use: a channel that
387
364
  * needs a sign-in is the same kind of event as an employee that needs one, and
@@ -439,13 +416,6 @@ function ChannelRow({ channel }) {
439
416
  children: channel.detail ?? channelStatusLabels[channel.status]
440
417
  })]
441
418
  }),
442
- /* @__PURE__ */ jsx("span", {
443
- className: "manager-office__channel-direction",
444
- "aria-label": `Direction: ${channelDirectionLabels[channel.direction]}`,
445
- role: "img",
446
- title: channelDirectionLabels[channel.direction],
447
- children: channelDirectionIcon(channel.direction)
448
- }),
449
419
  /* @__PURE__ */ jsxs("span", {
450
420
  className: "manager-office__channel-status",
451
421
  "data-status": channel.status,
@@ -528,32 +498,30 @@ function ManagerOfficeSidebarAlert({ className, detail, title, ...props }) {
528
498
  * content, but the Workforce header, roster identity, status language, scrolling,
529
499
  * and footer placement stay component-owned and therefore cannot drift.
530
500
  */
531
- function ManagerOfficeSidebar({ className, closeSidebarOnCompact, content, employees, renderLink, footer, officeActions, selectedEmployeeId, ...props }) {
501
+ function moveRosterFocus(event, layout) {
502
+ const nextKey = layout === "office" ? "ArrowDown" : "ArrowRight";
503
+ const prevKey = layout === "office" ? "ArrowUp" : "ArrowLeft";
504
+ if (event.key !== nextKey && event.key !== prevKey && event.key !== "Home" && event.key !== "End") return;
505
+ const links = [...event.currentTarget.querySelectorAll("a[href], button")];
506
+ const index = links.findIndex((link) => link === document.activeElement);
507
+ if (index < 0) return;
508
+ event.preventDefault();
509
+ const last = links.length - 1;
510
+ links[event.key === "Home" ? 0 : event.key === "End" ? last : event.key === nextKey ? Math.min(last, index + 1) : Math.max(0, index - 1)]?.focus();
511
+ }
512
+ function ManagerOfficeSidebar({ className, closeSidebarOnCompact, content, employees, renderLink, footer, layout = "office", officeActions, selectedEmployeeId, ...props }) {
532
513
  const rosterLabelId = React.useId();
533
- const employeeNavRef = React.useRef(null);
534
- const [employeeNavOverflows, setEmployeeNavOverflows] = React.useState(false);
535
514
  const profileColors = rosterProfileColors(employees);
536
- React.useLayoutEffect(() => {
537
- const employeeNav = employeeNavRef.current;
538
- if (!employeeNav) return;
539
- const syncOverflow = () => {
540
- const overflows = employeeNav.scrollWidth > employeeNav.clientWidth;
541
- setEmployeeNavOverflows((current) => current === overflows ? current : overflows);
542
- };
543
- syncOverflow();
544
- if (typeof ResizeObserver === "undefined") return;
545
- const observer = new ResizeObserver(syncOverflow);
546
- observer.observe(employeeNav);
547
- return () => observer.disconnect();
548
- }, [employees]);
515
+ const isChat = layout === "chat";
549
516
  return /* @__PURE__ */ jsx(Tooltip.Provider, { children: /* @__PURE__ */ jsxs("nav", {
550
517
  className: cx("manager-office__sidebar", className),
551
518
  "aria-label": "Workforce",
519
+ "data-layout": layout,
552
520
  ...props,
553
521
  children: [
554
522
  /* @__PURE__ */ jsxs("div", {
555
523
  className: "manager-office__sidebar-heading",
556
- children: [/* @__PURE__ */ jsx("strong", { children: "Workforce" }), officeActions ? /* @__PURE__ */ jsx("span", {
524
+ children: [isChat ? null : /* @__PURE__ */ jsx("strong", { children: "Workforce" }), officeActions ? /* @__PURE__ */ jsx("span", {
557
525
  className: "manager-office__sidebar-actions",
558
526
  children: officeActions
559
527
  }) : null]
@@ -564,12 +532,13 @@ function ManagerOfficeSidebar({ className, closeSidebarOnCompact, content, emplo
564
532
  children: "Employees"
565
533
  }),
566
534
  /* @__PURE__ */ jsx("ul", {
567
- ref: employeeNavRef,
568
535
  className: "manager-office__employee-nav",
536
+ role: "list",
569
537
  "aria-labelledby": rosterLabelId,
570
- "data-overflowing": employeeNavOverflows ? "true" : void 0,
538
+ onKeyDown: (event) => moveRosterFocus(event, layout),
571
539
  children: employees.map((employee, index) => {
572
540
  const selected = selectedEmployeeId === employee.id;
541
+ const status = employeeStatusText(employee);
573
542
  return /* @__PURE__ */ jsx("li", {
574
543
  className: "manager-office__employee-group",
575
544
  children: /* @__PURE__ */ jsxs(LinkButton, {
@@ -583,21 +552,25 @@ function ManagerOfficeSidebar({ className, closeSidebarOnCompact, content, emplo
583
552
  size: "sm",
584
553
  className: "manager-office__employee-link",
585
554
  "aria-current": selected ? "page" : void 0,
586
- "aria-label": `Open ${employee.name} · ${employeeStatusText(employee)}`,
587
- title: `${employee.name} · ${employeeStatusText(employee)}`,
555
+ "aria-label": `Open ${employee.name} · ${status}`,
556
+ title: isChat ? `${employee.name} · ${status}` : void 0,
588
557
  children: [/* @__PURE__ */ jsxs("span", {
589
558
  className: "manager-office__employee-avatar",
590
559
  children: [/* @__PURE__ */ jsx(EmployeeAvatar, {
591
560
  employee,
592
561
  color: profileColors.get(employee.id),
593
- index
562
+ index,
563
+ size: isChat ? "sm" : "md"
594
564
  }), /* @__PURE__ */ jsx(EmployeePresence, { employee })]
595
- }), /* @__PURE__ */ jsx("span", {
596
- className: "manager-office__identity sigvelo-visually-hidden",
597
- children: /* @__PURE__ */ jsx("strong", {
565
+ }), isChat ? null : /* @__PURE__ */ jsxs("span", {
566
+ className: "manager-office__identity",
567
+ children: [/* @__PURE__ */ jsx("strong", {
598
568
  className: "sigvelo-truncate",
599
569
  children: employee.name
600
- })
570
+ }), /* @__PURE__ */ jsx("small", {
571
+ className: "sigvelo-truncate",
572
+ children: statusLabels[employee.status]
573
+ })]
601
574
  })]
602
575
  })
603
576
  }, employee.id);
@@ -614,864 +587,510 @@ function ManagerOfficeSidebar({ className, closeSidebarOnCompact, content, emplo
614
587
  ]
615
588
  }) });
616
589
  }
617
- function AttentionView({ employees, renderLink, now }) {
618
- const rows = employees.flatMap((employee) => isConnected(employee) ? employee.handoffs.map((handoff) => ({
619
- employee,
620
- handoff
621
- })) : []);
622
- if (!rows.length) return /* @__PURE__ */ jsx("section", {
623
- className: "manager-office__attention",
624
- "data-recipe": "page",
625
- "aria-label": "Waiting on you",
626
- children: /* @__PURE__ */ jsx(EmptyState, {
627
- icon: /* @__PURE__ */ jsx(CheckIcon, {}),
628
- title: "No active handoffs",
629
- description: "Employee connection state remains visible in the roster."
630
- })
631
- });
632
- return /* @__PURE__ */ jsx("section", {
633
- className: "manager-office__attention",
634
- "data-recipe": "page",
635
- "aria-label": "Waiting on you",
636
- children: /* @__PURE__ */ jsx("ul", {
637
- className: "manager-office__attention-list sigvelo-stack-list",
638
- children: rows.map(({ employee, handoff }) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(HandoffCard, {
639
- employee,
640
- handoff,
641
- renderLink,
642
- now,
643
- showEmployee: true
644
- }) }, `${employee.id}:${handoff.id}`))
645
- })
646
- });
590
+ function isReviewWork(work) {
591
+ return work.status === "attention" || work.status === "error";
647
592
  }
648
- const dashboardLanes = [
649
- "working",
650
- "needs-you",
651
- "done",
652
- "idle"
653
- ];
654
- const analyticsDateFormatter = new Intl.DateTimeFormat(void 0, {
655
- day: "numeric",
656
- month: "short"
657
- });
658
- function analyticsDateLabel(timestamp) {
659
- return timestamp ? analyticsDateFormatter.format(timestamp) : "—";
593
+ /** Finished or failed work the manager should open in chat — not a live-tab wait. */
594
+ function reviewWorkFor(employee) {
595
+ const waiting = new Set(employee.handoffs.map((handoff) => handoff.workId));
596
+ return employee.work.filter((work) => isReviewWork(work) && !waiting.has(work.id));
660
597
  }
661
- function toggleDashboardFilter(setter, value, checked) {
662
- setter((current) => {
663
- const next = new Set(current);
664
- if (checked) next.add(value);
665
- else next.delete(value);
666
- return next;
667
- });
598
+ function workingSetOf(work) {
599
+ return work.workingSet ?? [];
668
600
  }
669
- const dashboardLaneCopy = {
670
- working: {
671
- title: "In progress",
672
- description: "Employees working now"
673
- },
674
- "needs-you": {
675
- title: "Waiting on you",
676
- description: "Blocked or waiting for you"
677
- },
678
- done: {
679
- title: "Done",
680
- description: "Fresh outcomes to review"
681
- },
682
- idle: {
683
- title: "Idle",
684
- description: "Not working — assign something now"
601
+ function workingSetKey(item) {
602
+ if (item.kind === "file" || item.kind === "folder") return `${item.kind}:${item.path}`;
603
+ if (item.kind === "link") return `link:${item.href}`;
604
+ return `correspondent:${correspondentHandleLabel(item.correspondent.handle)}`;
605
+ }
606
+ function safeHttpUrl(url) {
607
+ try {
608
+ const parsed = new URL(url);
609
+ if (parsed.protocol !== "https:" && parsed.protocol !== "http:") return void 0;
610
+ return parsed.href;
611
+ } catch {
612
+ return;
685
613
  }
686
- };
687
- function dashboardCards(employees, lane) {
688
- if (lane === "idle") return employees.flatMap((employee) => {
689
- if (!isConnected(employee)) return [];
690
- const hasCurrentWork = employee.work.some((work) => [
691
- "running",
692
- "attention",
693
- "error",
694
- "interrupted"
695
- ].includes(work.status));
696
- return employee.status === "idle" && !hasCurrentWork ? [{
697
- employee,
698
- lane
699
- }] : [];
614
+ }
615
+ function providerCardForHref(href) {
616
+ let parsed;
617
+ try {
618
+ parsed = new URL(href);
619
+ } catch {
620
+ return;
621
+ }
622
+ const host = parsed.hostname.toLowerCase();
623
+ if (host === "docs.google.com" || host.endsWith(".docs.google.com")) {
624
+ if (parsed.pathname.includes("/spreadsheets/")) return findCatalogMcpServerCard({ id: "google-sheets" });
625
+ if (parsed.pathname.includes("/document/")) return findCatalogMcpServerCard({ id: "google-docs" });
626
+ if (parsed.pathname.includes("/presentation/")) return findCatalogMcpServerCard({ id: "google-slides" });
627
+ }
628
+ if (host === "drive.google.com" || host.endsWith(".drive.google.com")) return findCatalogMcpServerCard({ id: "google-drive" });
629
+ }
630
+ function workingSetLinkDetail(item) {
631
+ const card = providerCardForHref(item.href);
632
+ if (card) return card.name;
633
+ try {
634
+ return new URL(item.href).hostname.replace(/^www\./u, "");
635
+ } catch {
636
+ return item.href;
637
+ }
638
+ }
639
+ function WorkingSetMark({ item }) {
640
+ if (item.kind === "file") return /* @__PURE__ */ jsx(FileIcon, {});
641
+ if (item.kind === "folder") return /* @__PURE__ */ jsx(FolderIcon, {});
642
+ const card = providerCardForHref(item.href);
643
+ const src = card ? getMcpServerIconSrc(card) : void 0;
644
+ if (src) return /* @__PURE__ */ jsxs(AppIcon.Root, {
645
+ size: "xs",
646
+ variant: "artwork",
647
+ "aria-hidden": "true",
648
+ children: [/* @__PURE__ */ jsx(AppIcon.Image, {
649
+ src,
650
+ alt: ""
651
+ }), /* @__PURE__ */ jsx(AppIcon.Fallback, { children: (card?.name ?? item.title).slice(0, 1) })]
700
652
  });
701
- return employees.flatMap((employee) => {
702
- if (!isConnected(employee)) return lane === "needs-you" ? [{
703
- employee,
704
- lane
705
- }] : [];
706
- if (lane === "working") {
707
- const work = employee.work.find((candidate) => candidate.status === "running");
708
- return work ? [{
709
- employee,
710
- lane,
711
- work
712
- }] : [];
713
- }
714
- if (lane === "done") {
715
- const work = employee.work.find((candidate) => candidate.status === "attention");
716
- return work ? [{
717
- employee,
718
- lane,
719
- work
720
- }] : [];
721
- }
722
- const handoff = employee.handoffs[0];
723
- if (handoff) return [{
724
- employee,
725
- lane,
726
- handoff,
727
- work: employee.work.find((candidate) => candidate.id === handoff.workId)
728
- }];
729
- const work = employee.work.find((candidate) => ["error", "interrupted"].includes(candidate.status));
730
- return work ? [{
653
+ return /* @__PURE__ */ jsx(LinkIcon, {});
654
+ }
655
+ function routineDetail(routine) {
656
+ const schedule = routine.enabled ? routine.task.schedule : `Paused · ${routine.task.schedule}`;
657
+ const finishedRuns = routine.runs.filter((run) => run.completedAt != null);
658
+ if (!finishedRuns.length) return schedule;
659
+ return `${schedule} · ${finishedRuns.filter((run) => {
660
+ const status = getThinkExecutionRunStatus(run);
661
+ return status === "completed" || status === "complete";
662
+ }).length} of ${finishedRuns.length} recent runs completed`;
663
+ }
664
+ /**
665
+ * Where a work link sits decides whether it draws its own surface: a row in a
666
+ * work list is a bounded row, while a lane heading sits inside the lane card,
667
+ * which already draws one.
668
+ */
669
+ const workLinkClassNames = {
670
+ row: "manager-office__work-link",
671
+ lane: "manager-office__lane-title"
672
+ };
673
+ /** The link onto a work thread, shared by standalone rows and lane headings. */
674
+ function WorkLink({ employee, placement, renderLink, now, showEmployee, work }) {
675
+ return /* @__PURE__ */ jsxs(LinkButton, {
676
+ render: renderLink({
677
+ kind: "work",
731
678
  employee,
732
- lane,
733
679
  work
734
- }] : [];
735
- });
736
- }
737
- function DashboardBrowserPreview({ card }) {
738
- const connectedEmployee = isConnected(card.employee) ? card.employee : null;
739
- const disconnectedDescription = isConnected(card.employee) ? "" : card.employee.statusDescription;
740
- const title = connectedEmployee ? (card.lane === "done" ? card.work?.title : connectedEmployee.browserPreview?.title) ?? card.work?.title ?? "Ready for a new assignment" : "Browser is offline";
741
- const url = connectedEmployee ? connectedEmployee.browserPreview?.url ?? "New tab" : disconnectedDescription;
742
- const state = card.lane === "working" ? "Live" : card.lane === "needs-you" ? "Paused" : card.lane === "done" ? "Result ready" : connectedEmployee ? "Idle" : "Disconnected";
743
- return /* @__PURE__ */ jsxs("div", {
744
- className: "manager-office__browser-preview",
745
- "data-lane": card.lane,
746
- role: "img",
747
- "aria-label": `${card.employee.name} browser preview: ${title}. ${state}.`,
680
+ }),
681
+ variant: "ghost",
682
+ color: "neutral",
683
+ size: "sm",
684
+ className: workLinkClassNames[placement],
685
+ "aria-label": `Open ${work.title} to ${threadStatusLabel(work.status).toLowerCase()}`,
748
686
  children: [
749
- /* @__PURE__ */ jsxs("div", {
750
- className: "manager-office__browser-chrome",
751
- "aria-hidden": "true",
752
- children: [
753
- /* @__PURE__ */ jsx("span", {}),
754
- /* @__PURE__ */ jsx("span", {}),
755
- /* @__PURE__ */ jsx("span", {}),
756
- /* @__PURE__ */ jsx("small", { children: url })
757
- ]
758
- }),
759
- /* @__PURE__ */ jsxs("div", {
760
- className: "manager-office__browser-page",
761
- "aria-hidden": "true",
762
- children: [
763
- /* @__PURE__ */ jsx("span", { className: "manager-office__browser-page-mark" }),
764
- /* @__PURE__ */ jsxs("span", {
765
- className: "manager-office__browser-page-copy",
766
- children: [/* @__PURE__ */ jsx("strong", { children: title }), /* @__PURE__ */ jsx("small", { children: card.work?.title ?? card.handoff?.workTitle ?? (connectedEmployee ? url : "") })]
767
- }),
768
- /* @__PURE__ */ jsxs("span", {
769
- className: "manager-office__browser-page-lines",
770
- children: [
771
- /* @__PURE__ */ jsx("i", {}),
772
- /* @__PURE__ */ jsx("i", {}),
773
- /* @__PURE__ */ jsx("i", {})
774
- ]
775
- }),
776
- card.lane === "working" ? /* @__PURE__ */ jsx("span", { className: "manager-office__browser-cursor" }) : null
777
- ]
778
- }),
687
+ /* @__PURE__ */ jsx(ThreadStatusIcon, { status: work.status }),
779
688
  /* @__PURE__ */ jsxs("span", {
780
- className: "manager-office__browser-state",
781
- "aria-hidden": "true",
782
- children: [card.lane === "working" ? /* @__PURE__ */ jsx(SpinnerIcon, {}) : card.lane === "done" ? /* @__PURE__ */ jsx(CheckIcon, {}) : null, state]
783
- })
689
+ className: "manager-office__identity",
690
+ children: [/* @__PURE__ */ jsxs("strong", {
691
+ className: "sigvelo-truncate",
692
+ children: [work.title, work.status === "attention" ? /* @__PURE__ */ jsx("span", {
693
+ className: "manager-office__unread-dot",
694
+ "aria-hidden": "true"
695
+ }) : null]
696
+ }), /* @__PURE__ */ jsxs("small", {
697
+ className: "sigvelo-truncate",
698
+ children: [
699
+ showEmployee ? `${employee.name} · ` : null,
700
+ threadStatusLabel(work.status),
701
+ " · ",
702
+ /* @__PURE__ */ jsx(Timestamp, {
703
+ timestamp: work.updatedAt,
704
+ now
705
+ })
706
+ ]
707
+ })]
708
+ }),
709
+ /* @__PURE__ */ jsx(ChevronRightIcon, { className: "manager-office__row-chevron" })
784
710
  ]
785
711
  });
786
712
  }
787
- function DashboardConnections({ employee }) {
788
- if (!isConnected(employee)) return /* @__PURE__ */ jsx("span", {
789
- className: "manager-office__connection-empty",
790
- children: "Browser connection offline"
713
+ function workingSetItemCaption(item) {
714
+ if (item.kind === "link") return workingSetLinkDetail(item);
715
+ return item.kind === "folder" ? "Workspace folder" : "Workspace file";
716
+ }
717
+ function WorkingSetAttachment(props) {
718
+ const { caption, label, mark, title } = props;
719
+ const contents = /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
720
+ className: "manager-office__working-set-mark",
721
+ "aria-hidden": "true",
722
+ children: mark
723
+ }), /* @__PURE__ */ jsx("strong", {
724
+ className: "sigvelo-truncate",
725
+ children: title
726
+ })] });
727
+ const link = "href" in props ? /* @__PURE__ */ jsx(LinkButton, {
728
+ href: props.href,
729
+ target: "_blank",
730
+ rel: "noreferrer",
731
+ variant: "ghost",
732
+ color: "neutral",
733
+ size: "sm",
734
+ className: "manager-office__working-set-link",
735
+ "aria-label": label,
736
+ children: contents
737
+ }) : /* @__PURE__ */ jsx(LinkButton, {
738
+ render: props.render,
739
+ variant: "ghost",
740
+ color: "neutral",
741
+ size: "sm",
742
+ className: "manager-office__working-set-link",
743
+ "aria-label": label,
744
+ children: contents
791
745
  });
792
- if (!employee.channels.length) return /* @__PURE__ */ jsx("span", {
793
- className: "manager-office__connection-empty",
794
- children: "No connectors yet"
746
+ return /* @__PURE__ */ jsxs(Tooltip.Root, { children: [/* @__PURE__ */ jsx(Tooltip.Trigger, { render: link }), /* @__PURE__ */ jsx(Tooltip.Portal, { children: /* @__PURE__ */ jsx(Tooltip.Positioner, {
747
+ side: "bottom",
748
+ sideOffset: 6,
749
+ children: /* @__PURE__ */ jsx(Tooltip.Popup, { children: caption })
750
+ }) })] });
751
+ }
752
+ function WorkingSetItemRow({ employee, item, renderLink, work }) {
753
+ if (item.kind === "correspondent") return /* @__PURE__ */ jsx("li", {
754
+ className: "manager-office__working-set-item",
755
+ children: /* @__PURE__ */ jsx(CorrespondentName, { correspondent: item.correspondent })
795
756
  });
796
- return /* @__PURE__ */ jsx("div", {
797
- className: "manager-office__dashboard-connections",
798
- "aria-label": "Connections",
799
- children: /* @__PURE__ */ jsx("span", {
800
- className: "manager-office__connection-icons",
801
- children: employee.channels.slice(0, 4).map((channel) => {
802
- const statusLabel = channel.status === "connected" ? "Connected" : channel.status === "needs-auth" ? "Needs sign-in" : "Connection error";
803
- return /* @__PURE__ */ jsxs(Tooltip.Root, { children: [/* @__PURE__ */ jsx(Tooltip.Trigger, {
804
- "aria-label": `${channel.name}: ${statusLabel}`,
805
- delay: 300,
806
- render: /* @__PURE__ */ jsx(AppIcon.Root, {
807
- size: "xs",
808
- "data-status": channel.status
809
- }),
810
- role: "img",
811
- children: /* @__PURE__ */ jsx(ChannelMark, { channel })
812
- }), /* @__PURE__ */ jsx(Tooltip.Portal, { children: /* @__PURE__ */ jsx(Tooltip.Positioner, {
813
- side: "top",
814
- sideOffset: 6,
815
- children: /* @__PURE__ */ jsxs(Tooltip.Popup, { children: [
816
- channel.name,
817
- " · ",
818
- statusLabel
819
- ] })
820
- }) })] }, channel.id);
757
+ const caption = workingSetItemCaption(item);
758
+ const mark = /* @__PURE__ */ jsx(WorkingSetMark, { item });
759
+ if (item.kind === "link") {
760
+ const href = safeHttpUrl(item.href);
761
+ if (!href) return null;
762
+ return /* @__PURE__ */ jsx("li", {
763
+ className: "manager-office__working-set-item",
764
+ children: /* @__PURE__ */ jsx(WorkingSetAttachment, {
765
+ caption,
766
+ label: `${item.title} (${caption}, opens in a new tab)`,
767
+ href,
768
+ mark,
769
+ title: item.title
821
770
  })
771
+ });
772
+ }
773
+ const location = item.kind === "folder" ? "folder" : "file";
774
+ return /* @__PURE__ */ jsx("li", {
775
+ className: "manager-office__working-set-item",
776
+ children: /* @__PURE__ */ jsx(WorkingSetAttachment, {
777
+ caption,
778
+ label: `Open ${item.title} ${location} in workspace`,
779
+ render: renderLink({
780
+ kind: "workspace",
781
+ employee,
782
+ work,
783
+ path: item.path
784
+ }),
785
+ mark,
786
+ title: item.title
822
787
  })
823
788
  });
824
789
  }
825
- function dashboardCardId(card) {
826
- return `${card.lane}:${card.employee.id}:${card.work?.id ?? card.handoff?.id ?? "employee"}`;
827
- }
828
- function DashboardCard({ card, collapsed, color, index, now, onToggleCollapsed, renderLink }) {
829
- const connectedEmployee = isConnected(card.employee) ? card.employee : null;
830
- const disconnectedDescription = isConnected(card.employee) ? "" : card.employee.statusDescription;
831
- const title = card.handoff?.reason ?? card.work?.title ?? (connectedEmployee ? "No active work" : "Reconnect employee");
832
- const detail = card.handoff?.request ?? (connectedEmployee ? connectedEmployee.role : disconnectedDescription);
790
+ function WorkLane({ employee, now, renderLink, work }) {
791
+ const titleId = React.useId();
792
+ const workingSet = workingSetOf(work);
833
793
  return /* @__PURE__ */ jsxs("article", {
834
- className: "manager-office__dashboard-card",
835
- "data-collapsed": collapsed || void 0,
836
- "data-lane": card.lane,
837
- children: [/* @__PURE__ */ jsxs("header", {
838
- className: "manager-office__dashboard-card-header",
839
- children: [
840
- /* @__PURE__ */ jsx(EmployeeAvatar, {
841
- employee: card.employee,
842
- color,
843
- index,
844
- size: "md"
845
- }),
846
- /* @__PURE__ */ jsxs("span", {
847
- className: "manager-office__dashboard-card-owner",
848
- children: [/* @__PURE__ */ jsx("strong", { children: card.employee.name }), /* @__PURE__ */ jsx("small", {
849
- className: "sigvelo-truncate",
850
- children: connectedEmployee ? connectedEmployee.role : "Employee offline"
851
- })]
852
- }),
853
- /* @__PURE__ */ jsx(Button, {
854
- "aria-expanded": !collapsed,
855
- "aria-label": `${collapsed ? "Expand" : "Collapse"} ${card.employee.name} card`,
856
- className: "manager-office__dashboard-card-toggle",
857
- color: "neutral",
858
- onClick: onToggleCollapsed,
859
- size: "sm",
860
- type: "button",
861
- variant: "ghost",
862
- children: collapsed ? /* @__PURE__ */ jsx(ChevronRightIcon, {}) : /* @__PURE__ */ jsx(ChevronDownIcon, {})
794
+ className: "manager-office__lane",
795
+ "aria-labelledby": titleId,
796
+ children: [
797
+ /* @__PURE__ */ jsx("h3", {
798
+ id: titleId,
799
+ className: "manager-office__lane-heading",
800
+ children: /* @__PURE__ */ jsx(WorkLink, {
801
+ employee,
802
+ now,
803
+ placement: "lane",
804
+ renderLink,
805
+ showEmployee: false,
806
+ work
863
807
  })
864
- ]
865
- }), !collapsed ? /* @__PURE__ */ jsxs(Fragment, { children: [
866
- card.lane === "working" || card.lane === "needs-you" && card.handoff ? /* @__PURE__ */ jsx(DashboardBrowserPreview, { card }) : null,
867
- card.lane === "done" && card.work ? /* @__PURE__ */ jsxs("section", {
868
- className: "manager-office__outcome-summary",
869
- "aria-label": "Completed outcome",
870
- children: [
871
- /* @__PURE__ */ jsx("strong", { children: card.work.title }),
872
- /* @__PURE__ */ jsx("p", { children: card.work.summary ?? `${card.work.title} is complete and ready for review.` }),
873
- /* @__PURE__ */ jsxs("span", {
874
- className: "manager-office__dashboard-updated",
875
- children: [
876
- "Completed ",
877
- /* @__PURE__ */ jsx(Timestamp, {
878
- timestamp: card.work.updatedAt,
879
- now
880
- }),
881
- " ago"
882
- ]
883
- })
884
- ]
885
- }) : /* @__PURE__ */ jsxs("div", {
886
- className: "manager-office__dashboard-card-copy",
887
- children: [
888
- /* @__PURE__ */ jsx("strong", { children: title }),
889
- /* @__PURE__ */ jsx("small", { children: detail }),
890
- card.work ? /* @__PURE__ */ jsxs("span", {
891
- className: "manager-office__dashboard-updated",
892
- children: [
893
- "Updated ",
894
- /* @__PURE__ */ jsx(Timestamp, {
895
- timestamp: card.work.updatedAt,
896
- now
897
- }),
898
- " ago"
899
- ]
900
- }) : null
901
- ]
902
808
  }),
903
- /* @__PURE__ */ jsx(DashboardConnections, { employee: card.employee }),
904
- /* @__PURE__ */ jsx("footer", {
905
- className: "manager-office__dashboard-card-actions",
906
- children: connectedEmployee && card.lane === "idle" ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs(LinkButton, {
907
- render: renderLink({
908
- kind: "new-work",
909
- employee: connectedEmployee
910
- }),
911
- size: "sm",
912
- children: [/* @__PURE__ */ jsx(PlayIcon, {}), "Assign work"]
913
- }), /* @__PURE__ */ jsxs(LinkButton, {
914
- render: renderLink({
915
- kind: "new-routine",
916
- employee: connectedEmployee
917
- }),
918
- variant: "ghost",
919
- color: "neutral",
920
- size: "sm",
921
- children: [/* @__PURE__ */ jsx(CalendarIcon, {}), "Set routine"]
922
- })] }) : connectedEmployee && card.handoff ? /* @__PURE__ */ jsxs(LinkButton, {
923
- render: renderLink({
924
- kind: "handoff",
925
- employee: connectedEmployee,
926
- handoff: card.handoff
927
- }),
928
- size: "sm",
929
- children: [/* @__PURE__ */ jsx(EyeIcon, {}), "Help in browser"]
930
- }) : connectedEmployee && card.work ? /* @__PURE__ */ jsxs(LinkButton, {
931
- render: renderLink({
932
- kind: "work",
933
- employee: connectedEmployee,
934
- work: card.work
935
- }),
936
- size: "sm",
937
- children: [card.lane === "done" ? /* @__PURE__ */ jsx(CheckIcon, {}) : card.lane === "needs-you" ? /* @__PURE__ */ jsx(WarningIcon, {}) : /* @__PURE__ */ jsx(EyeIcon, {}), card.lane === "done" ? "Review result" : card.lane === "needs-you" ? "Open issue" : "Watch work"]
938
- }) : /* @__PURE__ */ jsxs(LinkButton, {
939
- render: renderLink({
940
- kind: "employee",
941
- employee: card.employee
942
- }),
943
- size: "sm",
944
- children: [/* @__PURE__ */ jsx(RefreshIcon, {}), "Reconnect"]
945
- })
946
- })
947
- ] }) : null]
948
- });
949
- }
950
- function DashboardFilterMenu({ label, onToggle, options, selected }) {
951
- return /* @__PURE__ */ jsxs(Menu.Root, { children: [/* @__PURE__ */ jsxs(Button, {
952
- variant: "outline",
953
- color: "neutral",
954
- size: "sm",
955
- "aria-label": `${label} filter`,
956
- className: "manager-office__filter-trigger",
957
- "data-active": selected.size || void 0,
958
- render: /* @__PURE__ */ jsx(Menu.Trigger, { unstyled: true }),
959
- children: [
960
- /* @__PURE__ */ jsx("span", { children: label }),
961
- selected.size ? /* @__PURE__ */ jsx("strong", { children: selected.size }) : null,
962
- /* @__PURE__ */ jsx(ChevronDownIcon, {})
809
+ work.summary ? /* @__PURE__ */ jsx("p", {
810
+ className: "manager-office__lane-summary",
811
+ children: work.summary
812
+ }) : null,
813
+ workingSet.length ? /* @__PURE__ */ jsx("ul", {
814
+ className: "manager-office__working-set",
815
+ role: "list",
816
+ "aria-label": "Working set",
817
+ children: workingSet.map((item) => /* @__PURE__ */ jsx(WorkingSetItemRow, {
818
+ employee,
819
+ item,
820
+ renderLink,
821
+ work
822
+ }, workingSetKey(item)))
823
+ }) : null
963
824
  ]
964
- }), /* @__PURE__ */ jsx(Menu.Portal, { children: /* @__PURE__ */ jsx(Menu.Positioner, {
965
- sideOffset: 6,
966
- align: "start",
967
- children: /* @__PURE__ */ jsx(Menu.Popup, {
968
- className: "manager-office__filter-popup",
969
- children: /* @__PURE__ */ jsxs(Menu.Group, { children: [/* @__PURE__ */ jsx(Menu.GroupLabel, { children: label }), options.map((option) => /* @__PURE__ */ jsxs(Menu.CheckboxItem, {
970
- checked: selected.has(option.value),
971
- onCheckedChange: (checked) => onToggle(option.value, checked === true),
972
- children: [/* @__PURE__ */ jsx(Menu.CheckboxItemIndicator, {}), option.label]
973
- }, option.value))] })
974
- })
975
- }) })] });
825
+ });
976
826
  }
977
- function AssignWorkMenu({ employees, profileColors, renderLink }) {
978
- return /* @__PURE__ */ jsxs(Menu.Root, { children: [/* @__PURE__ */ jsxs(Button, {
979
- size: "sm",
980
- className: "manager-office__assignment-trigger",
981
- disabled: !employees.length,
982
- render: /* @__PURE__ */ jsx(Menu.Trigger, { unstyled: true }),
983
- children: ["Assign work", /* @__PURE__ */ jsx(ChevronDownIcon, {})]
984
- }), /* @__PURE__ */ jsx(Menu.Portal, { children: /* @__PURE__ */ jsx(Menu.Positioner, {
985
- align: "end",
986
- sideOffset: 6,
987
- children: /* @__PURE__ */ jsx(Menu.Popup, {
988
- "aria-label": "Choose an AI employee",
989
- className: "manager-office__assignment-popup",
990
- children: /* @__PURE__ */ jsxs(Menu.Group, { children: [/* @__PURE__ */ jsx(Menu.GroupLabel, { children: "Choose an employee" }), employees.map((employee, index) => /* @__PURE__ */ jsxs(Menu.Item, {
991
- "aria-label": `Assign work to ${employee.name}`,
992
- className: "manager-office__assignment-item",
993
- render: renderLink({
994
- kind: "new-work",
995
- employee
996
- }),
997
- children: [
998
- /* @__PURE__ */ jsx(EmployeeAvatar, {
999
- employee,
1000
- color: profileColors.get(employee.id),
1001
- index
1002
- }),
1003
- /* @__PURE__ */ jsxs("span", { children: [/* @__PURE__ */ jsx("strong", { children: employee.name }), /* @__PURE__ */ jsx("small", {
1004
- className: "sigvelo-truncate",
1005
- children: employee.role
1006
- })] }),
1007
- /* @__PURE__ */ jsx(ChevronRightIcon, {})
1008
- ]
1009
- }, employee.id))] })
827
+ function ManagerOfficeAttention({ className, ...props }) {
828
+ const { employees, renderLink, now } = useOffice();
829
+ const waits = employees.flatMap((employee) => isConnected(employee) ? employee.handoffs.map((handoff) => ({
830
+ employee,
831
+ handoff
832
+ })) : []);
833
+ const reviews = employees.flatMap((employee) => isConnected(employee) ? reviewWorkFor(employee).map((work) => ({
834
+ employee,
835
+ work
836
+ })) : []);
837
+ if (!waits.length && !reviews.length) return /* @__PURE__ */ jsx("div", {
838
+ ...props,
839
+ className: cx("manager-office__attention", className),
840
+ "data-recipe": "page",
841
+ children: /* @__PURE__ */ jsx(EmptyState, {
842
+ icon: /* @__PURE__ */ jsx(CheckIcon, {}),
843
+ title: "Nothing needs you",
844
+ description: "Employee connection state remains visible in the roster."
1010
845
  })
1011
- }) })] });
1012
- }
1013
- function employeeMatchesUtilization(employee, selected) {
1014
- if (!selected.size) return true;
1015
- if (!isConnected(employee)) return selected.has("connector-issue");
1016
- const matches = [];
1017
- if (employee.browserPreview) matches.push("browser");
1018
- if (employee.routines.length) matches.push("routines");
1019
- else matches.push("no-routines");
1020
- if (employee.channels.some((channel) => channel.status !== "connected")) matches.push("connector-issue");
1021
- return matches.some((value) => selected.has(value));
1022
- }
1023
- function niceAxisMaximum(values) {
1024
- const maximum = Math.max(...values, 1);
1025
- const roughStep = maximum / 2;
1026
- const magnitude = 10 ** Math.floor(Math.log10(roughStep));
1027
- const normalized = roughStep / magnitude;
1028
- const step = (normalized <= 1 ? 1 : normalized <= 2 ? 2 : normalized <= 5 ? 5 : 10) * magnitude;
1029
- return Math.ceil(maximum / step) * step;
1030
- }
1031
- function chartY(value, maximum, height = 76) {
1032
- return height - 4 - value / maximum * (height - 10);
1033
- }
1034
- function chartPath(values, maximum, width = 260, height = 76) {
1035
- if (!values.length) return "";
1036
- return values.map((value, index) => {
1037
- const x = values.length === 1 ? width / 2 : index / (values.length - 1) * width;
1038
- const y = chartY(value, maximum, height);
1039
- return `${index ? "L" : "M"}${x.toFixed(1)},${y.toFixed(1)}`;
1040
- }).join(" ");
1041
- }
1042
- function chartAreaPath(values, maximum, width = 260, height = 76) {
1043
- const line = chartPath(values, maximum, width, height);
1044
- return line ? `${line} L${width},${height - 4} L0,${height - 4} Z` : "";
846
+ });
847
+ const both = waits.length > 0 && reviews.length > 0;
848
+ return /* @__PURE__ */ jsxs("div", {
849
+ ...props,
850
+ className: cx("manager-office__attention", className),
851
+ "data-recipe": "page",
852
+ children: [waits.length ? /* @__PURE__ */ jsxs("div", {
853
+ className: "manager-office__attention-group",
854
+ children: [both ? /* @__PURE__ */ jsx("h2", {
855
+ className: "manager-office__section-title",
856
+ children: "Needs you in the browser"
857
+ }) : null, /* @__PURE__ */ jsx("ul", {
858
+ className: "manager-office__attention-list sigvelo-stack-list",
859
+ "aria-label": "Waiting on you",
860
+ children: waits.map(({ employee, handoff }) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(HandoffCard, {
861
+ employee,
862
+ handoff,
863
+ renderLink,
864
+ now,
865
+ showEmployee: true
866
+ }) }, `${employee.id}:${handoff.id}`))
867
+ })]
868
+ }) : null, reviews.length ? /* @__PURE__ */ jsxs("div", {
869
+ className: "manager-office__attention-group",
870
+ children: [/* @__PURE__ */ jsx("h2", {
871
+ className: "manager-office__section-title",
872
+ children: "Ready for you"
873
+ }), /* @__PURE__ */ jsx("ul", {
874
+ className: "manager-office__work-list sigvelo-stack-list",
875
+ "aria-label": "Ready for you",
876
+ children: reviews.map(({ employee, work }) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(WorkLink, {
877
+ employee,
878
+ work,
879
+ placement: "row",
880
+ renderLink,
881
+ now,
882
+ showEmployee: true
883
+ }) }, `${employee.id}:${work.id}`))
884
+ })]
885
+ }) : null]
886
+ });
1045
887
  }
1046
- function chartBars(values, maximum, width = 260, height = 76) {
1047
- const barWidth = Math.max(2, width / Math.max(values.length, 1) - 3);
1048
- return values.map((value, index) => {
1049
- const barHeight = Math.max(value ? 3 : 0, value / maximum * (height - 10));
1050
- const x = values.length === 1 ? width / 2 - barWidth / 2 : index / values.length * width;
1051
- return /* @__PURE__ */ jsx("rect", {
1052
- className: "manager-office__analytics-bar",
1053
- height: barHeight,
1054
- rx: "2",
1055
- width: barWidth,
1056
- x,
1057
- y: height - 4 - barHeight
1058
- }, index);
888
+ const employeeDefaults = {
889
+ className: "manager-office__employee-detail",
890
+ "data-recipe": "page"
891
+ };
892
+ /** Scope the selected employee without imposing dossier content or column order. */
893
+ function ManagerOfficeEmployeeRoot({ employee, render, ref, ...props }) {
894
+ const element = useRender({
895
+ defaultTagName: "div",
896
+ render,
897
+ ref,
898
+ props: mergeProps(employeeDefaults, props)
899
+ });
900
+ return /* @__PURE__ */ jsx(EmployeeContext.Provider, {
901
+ value: employee,
902
+ children: element
1059
903
  });
1060
904
  }
1061
- function AnalyticsSeries({ detail, label, tone, timestamps, value, values }) {
1062
- const axisMaximum = niceAxisMaximum(values);
1063
- const axisValue = (axisValue) => {
1064
- if (tone === "roi") return `${Math.round(axisValue)}×`;
1065
- if (tone === "workload") return `${Math.round(axisValue)}h`;
1066
- return String(Math.round(axisValue));
1067
- };
1068
- const middleIndex = Math.floor(Math.max(timestamps.length - 1, 0) / 2);
1069
- return /* @__PURE__ */ jsxs("article", {
1070
- className: "manager-office__analytics-series",
1071
- "data-tone": tone,
1072
- children: [/* @__PURE__ */ jsxs("span", {
1073
- className: "manager-office__analytics-series-copy",
1074
- children: [
1075
- /* @__PURE__ */ jsx("small", { children: label }),
1076
- /* @__PURE__ */ jsx("strong", { children: value }),
1077
- /* @__PURE__ */ jsx("span", { children: detail })
1078
- ]
905
+ function ManagerOfficeEmployeeHeader({ className, ...props }) {
906
+ const employee = useEmployee();
907
+ const { profileColors } = useOffice();
908
+ const profileColor = profileColors.get(employee.id) ?? chromeProfileColor(employee.id);
909
+ return /* @__PURE__ */ jsxs("header", {
910
+ ...props,
911
+ className: cx("manager-office__employee-header", className),
912
+ children: [/* @__PURE__ */ jsx(EmployeeAvatar, {
913
+ employee,
914
+ color: profileColor,
915
+ size: "lg"
1079
916
  }), /* @__PURE__ */ jsxs("div", {
1080
- className: "manager-office__analytics-chart",
1081
- role: "img",
1082
- "aria-label": `${label} by date over the selected period, from 0 to ${axisValue(axisMaximum)}`,
917
+ className: "manager-office__briefing",
1083
918
  children: [
1084
- /* @__PURE__ */ jsxs("span", {
1085
- className: "manager-office__analytics-y-axis",
1086
- "aria-hidden": "true",
1087
- children: [
1088
- /* @__PURE__ */ jsx("span", { children: axisValue(axisMaximum) }),
1089
- /* @__PURE__ */ jsx("span", { children: axisValue(axisMaximum / 2) }),
1090
- /* @__PURE__ */ jsx("span", { children: axisValue(0) })
1091
- ]
919
+ /* @__PURE__ */ jsx("strong", {
920
+ className: "sigvelo-truncate",
921
+ children: employee.name
1092
922
  }),
1093
- /* @__PURE__ */ jsxs("svg", {
1094
- viewBox: "0 0 260 76",
1095
- "aria-hidden": "true",
1096
- preserveAspectRatio: "none",
1097
- children: [
1098
- /* @__PURE__ */ jsx("path", {
1099
- className: "manager-office__analytics-gridline",
1100
- d: "M0 4H260M0 38H260M0 72H260"
1101
- }),
1102
- /* @__PURE__ */ jsx("path", {
1103
- className: "manager-office__analytics-axis-line",
1104
- d: "M0 4V72H260"
1105
- }),
1106
- tone === "outcomes" ? chartBars(values, axisMaximum) : /* @__PURE__ */ jsxs(Fragment, { children: [
1107
- /* @__PURE__ */ jsx("path", {
1108
- className: "manager-office__analytics-area",
1109
- d: chartAreaPath(values, axisMaximum)
1110
- }),
1111
- /* @__PURE__ */ jsx("path", {
1112
- className: "manager-office__analytics-line",
1113
- d: chartPath(values, axisMaximum)
1114
- }),
1115
- values.length ? /* @__PURE__ */ jsx("circle", {
1116
- className: "manager-office__analytics-endpoint",
1117
- cx: "260",
1118
- cy: chartY(values.at(-1) ?? 0, axisMaximum),
1119
- r: "3"
1120
- }) : null
1121
- ] })
1122
- ]
923
+ /* @__PURE__ */ jsx("small", {
924
+ className: "sigvelo-truncate",
925
+ children: employee.email
1123
926
  }),
1124
- /* @__PURE__ */ jsxs("span", {
1125
- className: "manager-office__analytics-x-axis",
1126
- "aria-hidden": "true",
1127
- children: [
1128
- /* @__PURE__ */ jsx("span", { children: analyticsDateLabel(timestamps[0]) }),
1129
- /* @__PURE__ */ jsx("span", { children: analyticsDateLabel(timestamps[middleIndex]) }),
1130
- /* @__PURE__ */ jsx("span", { children: analyticsDateLabel(timestamps.at(-1)) })
1131
- ]
927
+ /* @__PURE__ */ jsx("p", {
928
+ className: "manager-office__role",
929
+ children: employee.role
1132
930
  })
1133
931
  ]
1134
932
  })]
1135
933
  });
1136
934
  }
1137
- function aggregateAnalytics(analytics, employeeIds, now, rangeDays) {
1138
- const cutoff = now - rangeDays * 24 * 60 * 6e4;
1139
- const buckets = /* @__PURE__ */ new Map();
1140
- for (const employee of analytics) {
1141
- if (!employeeIds.has(employee.employeeId)) continue;
1142
- for (const point of employee.points) {
1143
- if (point.timestamp < cutoff || point.timestamp > now) continue;
1144
- const day = new Date(point.timestamp);
1145
- day.setHours(0, 0, 0, 0);
1146
- const timestamp = day.getTime();
1147
- const current = buckets.get(timestamp) ?? {
1148
- timestamp,
1149
- completed: 0,
1150
- workloadHours: 0,
1151
- estimatedCost: 0
1152
- };
1153
- current.completed += point.completed;
1154
- current.workloadHours += point.workloadHours;
1155
- current.estimatedCost += point.estimatedCost;
1156
- buckets.set(timestamp, current);
1157
- }
1158
- }
1159
- return [...buckets.values()].sort((left, right) => left.timestamp - right.timestamp);
935
+ function ManagerOfficeHandoffs({ className, ...props }) {
936
+ const employee = useEmployee();
937
+ const { renderLink, now } = useOffice();
938
+ return employee.handoffs.length ? /* @__PURE__ */ jsx("section", {
939
+ ...props,
940
+ className: cx("manager-office__employee-handoffs", className),
941
+ "aria-label": "Waiting on you",
942
+ children: employee.handoffs.map((handoff) => /* @__PURE__ */ jsx(HandoffCard, {
943
+ employee,
944
+ handoff,
945
+ renderLink,
946
+ now,
947
+ showEmployee: false
948
+ }, handoff.id))
949
+ }) : null;
1160
950
  }
1161
- function DashboardAnalytics({ analytics, currency, employeeIds, now, onExportReport, rangeDays, setRangeDays }) {
1162
- const points = aggregateAnalytics(analytics, new Set(employeeIds), now, rangeDays);
1163
- const completed = points.reduce((sum, point) => sum + point.completed, 0);
1164
- const workload = points.reduce((sum, point) => sum + point.workloadHours, 0);
1165
- const hourlyWageEquivalent = 45;
1166
- const monthlyCostPerEmployee = 28;
1167
- const monthlyAICost = employeeIds.length * monthlyCostPerEmployee;
1168
- const selectedPeriodAICost = monthlyAICost * rangeDays / 30;
1169
- const laborValue = workload * hourlyWageEquivalent;
1170
- const roiMultiple = selectedPeriodAICost ? laborValue / selectedPeriodAICost : 0;
1171
- const dailyAICost = monthlyAICost / 30;
1172
- const roiValues = points.map((point) => dailyAICost ? point.workloadHours * hourlyWageEquivalent / dailyAICost : 0);
1173
- const money = React.useMemo(() => new Intl.NumberFormat(void 0, {
1174
- currency,
1175
- maximumFractionDigits: 0,
1176
- style: "currency"
1177
- }), [currency]);
951
+ function ManagerOfficeWorkSection({ className, ...props }) {
952
+ const employee = useEmployee();
953
+ const { renderLink, now } = useOffice();
1178
954
  return /* @__PURE__ */ jsxs("section", {
1179
- className: "manager-office__analytics",
1180
- "aria-labelledby": "manager-office-analytics-title",
1181
- children: [/* @__PURE__ */ jsxs("header", {
1182
- className: "manager-office__analytics-header",
1183
- children: [/* @__PURE__ */ jsx("h2", {
1184
- id: "manager-office-analytics-title",
1185
- children: "Your workforce at a glance"
1186
- }), /* @__PURE__ */ jsxs("span", {
1187
- className: "manager-office__analytics-actions",
1188
- children: [/* @__PURE__ */ jsxs(Select.Root, {
1189
- value: String(rangeDays),
1190
- onValueChange: (value) => setRangeDays(Number(value)),
1191
- children: [/* @__PURE__ */ jsxs(Select.Trigger, {
1192
- className: "manager-office__analytics-range",
1193
- "aria-label": "Analytics time range",
1194
- children: [
1195
- /* @__PURE__ */ jsx(CalendarIcon, {}),
1196
- /* @__PURE__ */ jsxs("span", { children: [
1197
- /* @__PURE__ */ jsx("span", {
1198
- className: "manager-office__analytics-range-prefix",
1199
- children: "Last "
1200
- }),
1201
- rangeDays,
1202
- " days"
1203
- ] }),
1204
- /* @__PURE__ */ jsx(Select.Icon, { children: /* @__PURE__ */ jsx(ChevronDownIcon, {}) })
1205
- ]
1206
- }), /* @__PURE__ */ jsx(Select.Portal, { children: /* @__PURE__ */ jsx(Select.Positioner, {
1207
- sideOffset: 4,
1208
- children: /* @__PURE__ */ jsx(Select.Popup, { children: /* @__PURE__ */ jsx(Select.List, { children: [
1209
- 7,
1210
- 30,
1211
- 90
1212
- ].map((days) => /* @__PURE__ */ jsxs(Select.Item, {
1213
- value: String(days),
1214
- children: [/* @__PURE__ */ jsx(Select.ItemIndicator, {}), /* @__PURE__ */ jsxs(Select.ItemText, { children: [
1215
- "Last ",
1216
- days,
1217
- " days"
1218
- ] })]
1219
- }, days)) }) })
1220
- }) })]
1221
- }), onExportReport ? /* @__PURE__ */ jsxs(Button, {
1222
- "aria-label": "Export report",
1223
- className: "manager-office__analytics-export",
1224
- title: "Export report",
1225
- type: "button",
1226
- size: "sm",
1227
- variant: "outline",
1228
- onClick: () => onExportReport({
1229
- employeeIds,
1230
- rangeDays
1231
- }),
1232
- children: [/* @__PURE__ */ jsx(DownloadIcon, {}), /* @__PURE__ */ jsxs("span", {
1233
- className: "manager-office__analytics-export-label",
1234
- children: ["Export", /* @__PURE__ */ jsx("span", {
1235
- className: "manager-office__export-report-suffix",
1236
- children: " report"
1237
- })]
1238
- })]
1239
- }) : null]
1240
- })]
1241
- }), /* @__PURE__ */ jsxs("div", {
1242
- className: "manager-office__analytics-series-grid",
1243
- children: [
1244
- /* @__PURE__ */ jsx(AnalyticsSeries, {
1245
- detail: `${(completed / Math.max(employeeIds.length, 1)).toFixed(1)} per employee`,
1246
- label: "Completed outcomes",
1247
- tone: "outcomes",
1248
- timestamps: points.map((point) => point.timestamp),
1249
- value: String(completed),
1250
- values: points.map((point) => point.completed)
1251
- }),
1252
- /* @__PURE__ */ jsx(AnalyticsSeries, {
1253
- detail: `${(workload / Math.max(employeeIds.length, 1)).toFixed(1)}h per employee`,
1254
- label: "Workload",
1255
- tone: "workload",
1256
- timestamps: points.map((point) => point.timestamp),
1257
- value: `${Math.round(workload)}h`,
1258
- values: points.map((point) => point.workloadHours)
1259
- }),
1260
- /* @__PURE__ */ jsx(AnalyticsSeries, {
1261
- detail: `${money.format(hourlyWageEquivalent)}/hr equivalent · ${money.format(monthlyCostPerEmployee)}/employee/mo`,
1262
- label: "Return on investment",
1263
- tone: "roi",
1264
- timestamps: points.map((point) => point.timestamp),
1265
- value: `${roiMultiple.toFixed(1)}×`,
1266
- values: roiValues
1267
- })
1268
- ]
955
+ ...props,
956
+ className: cx("manager-office__section", className),
957
+ children: [/* @__PURE__ */ jsx("header", {
958
+ className: "manager-office__section-header",
959
+ children: /* @__PURE__ */ jsxs("h2", {
960
+ className: "manager-office__section-title",
961
+ children: [/* @__PURE__ */ jsx(MessageSquareIcon, {}), "Work"]
962
+ })
963
+ }), /* @__PURE__ */ jsx("div", {
964
+ className: "manager-office__section-content",
965
+ children: employee.work.length ? /* @__PURE__ */ jsx("ul", {
966
+ className: "manager-office__work-list sigvelo-stack-list",
967
+ children: employee.work.map((work) => /* @__PURE__ */ jsx("li", { children: workingSetOf(work).length ? /* @__PURE__ */ jsx(WorkLane, {
968
+ employee,
969
+ now,
970
+ renderLink,
971
+ work
972
+ }) : /* @__PURE__ */ jsx(WorkLink, {
973
+ employee,
974
+ now,
975
+ placement: "row",
976
+ renderLink,
977
+ showEmployee: false,
978
+ work
979
+ }) }, work.id))
980
+ }) : /* @__PURE__ */ jsx("p", {
981
+ className: "manager-office__section-empty",
982
+ children: "No work yet."
983
+ })
1269
984
  })]
1270
985
  });
1271
986
  }
1272
- function DashboardView({ analytics, analyticsCurrency, employees, now, onExportReport, profileColors, renderLink }) {
1273
- const lanes = dashboardLanes;
1274
- const [rangeDays, setRangeDays] = React.useState(30);
1275
- const [employeeFilters, setEmployeeFilters] = React.useState(() => /* @__PURE__ */ new Set());
1276
- const [appFilters, setAppFilters] = React.useState(() => /* @__PURE__ */ new Set());
1277
- const [utilizationFilters, setUtilizationFilters] = React.useState(() => /* @__PURE__ */ new Set());
1278
- const [collapsedLanes, setCollapsedLanes] = React.useState(() => /* @__PURE__ */ new Set());
1279
- const [collapsedCards, setCollapsedCards] = React.useState(() => /* @__PURE__ */ new Set());
1280
- const filteredEmployees = employees.filter((employee) => {
1281
- const connected = isConnected(employee);
1282
- if (employeeFilters.size && !employeeFilters.has(employee.id)) return false;
1283
- if (appFilters.size && (!connected || !employee.channels.some((channel) => appFilters.has(channel.name)))) return false;
1284
- return employeeMatchesUtilization(employee, utilizationFilters);
1285
- });
1286
- const cardsByLane = new Map(lanes.map((lane) => [lane, dashboardCards(filteredEmployees, lane)]));
1287
- const appOptions = [...new Set(employees.flatMap((employee) => isConnected(employee) ? employee.channels.map((channel) => channel.name) : []))].sort((left, right) => left.localeCompare(right)).map((name) => ({
1288
- label: name,
1289
- value: name
1290
- }));
1291
- const filtersActive = employeeFilters.size > 0 || appFilters.size > 0 || utilizationFilters.size > 0;
1292
- const activeFilterCount = employeeFilters.size + appFilters.size + utilizationFilters.size;
1293
- const clearFilters = () => {
1294
- setEmployeeFilters(/* @__PURE__ */ new Set());
1295
- setAppFilters(/* @__PURE__ */ new Set());
1296
- setUtilizationFilters(/* @__PURE__ */ new Set());
1297
- };
1298
- const toggleLane = (lane) => setCollapsedLanes((current) => {
1299
- const next = new Set(current);
1300
- if (next.has(lane)) next.delete(lane);
1301
- else next.add(lane);
1302
- return next;
1303
- });
1304
- const toggleCard = (cardId) => setCollapsedCards((current) => {
1305
- const next = new Set(current);
1306
- if (next.has(cardId)) next.delete(cardId);
1307
- else next.add(cardId);
1308
- return next;
1309
- });
1310
- return /* @__PURE__ */ jsxs("div", {
1311
- className: "manager-office__dashboard-content",
1312
- "data-recipe": "page",
1313
- children: [
1314
- /* @__PURE__ */ jsxs("section", {
1315
- className: "manager-office__dashboard-controls",
1316
- "aria-label": "Workforce controls",
1317
- children: [/* @__PURE__ */ jsx("div", {
1318
- className: "manager-office__workforce-actions",
1319
- "aria-label": "Workforce actions",
1320
- children: /* @__PURE__ */ jsx(AssignWorkMenu, {
1321
- employees: employees.filter(isConnected),
1322
- profileColors,
1323
- renderLink
1324
- })
1325
- }), /* @__PURE__ */ jsxs("section", {
1326
- className: "manager-office__filters",
1327
- "aria-label": "Filter AI employees",
1328
- children: [/* @__PURE__ */ jsxs("div", {
1329
- className: "manager-office__filters-main",
1330
- children: [/* @__PURE__ */ jsxs("div", {
1331
- className: "manager-office__filters-heading",
1332
- children: [/* @__PURE__ */ jsx("strong", { children: "Filters" }), filtersActive ? /* @__PURE__ */ jsxs("span", { children: [activeFilterCount, " active"] }) : null]
1333
- }), /* @__PURE__ */ jsxs("div", {
1334
- className: "manager-office__filter-categories",
1335
- children: [
1336
- /* @__PURE__ */ jsx(DashboardFilterMenu, {
1337
- label: "Employee",
1338
- options: employees.map((employee) => ({
1339
- label: employee.name,
1340
- value: employee.id
1341
- })),
1342
- selected: employeeFilters,
1343
- onToggle: (value, checked) => toggleDashboardFilter(setEmployeeFilters, value, checked)
1344
- }),
1345
- /* @__PURE__ */ jsx(DashboardFilterMenu, {
1346
- label: "Apps",
1347
- options: appOptions,
1348
- selected: appFilters,
1349
- onToggle: (value, checked) => toggleDashboardFilter(setAppFilters, value, checked)
1350
- }),
1351
- /* @__PURE__ */ jsx(DashboardFilterMenu, {
1352
- label: "Utilization",
1353
- options: [
1354
- {
1355
- label: "Live browser connected",
1356
- value: "browser"
1357
- },
1358
- {
1359
- label: "Has routines",
1360
- value: "routines"
1361
- },
1362
- {
1363
- label: "No routines",
1364
- value: "no-routines"
1365
- },
1366
- {
1367
- label: "Connection issue",
1368
- value: "connector-issue"
1369
- }
1370
- ],
1371
- selected: utilizationFilters,
1372
- onToggle: (value, checked) => toggleDashboardFilter(setUtilizationFilters, value, checked)
1373
- }),
1374
- filtersActive ? /* @__PURE__ */ jsxs(Button, {
1375
- className: "manager-office__filter-clear",
1376
- type: "button",
1377
- variant: "ghost",
1378
- size: "sm",
1379
- onClick: clearFilters,
1380
- children: [/* @__PURE__ */ jsx(XIcon, {}), "Clear filters"]
1381
- }) : null
1382
- ]
1383
- })]
1384
- }), /* @__PURE__ */ jsxs("p", {
1385
- "aria-live": "polite",
987
+ function ManagerOfficeRoutines({ className, ...props }) {
988
+ const employee = useEmployee();
989
+ const { renderLink } = useOffice();
990
+ return /* @__PURE__ */ jsx("section", {
991
+ ...props,
992
+ className: cx("manager-office__section", className),
993
+ "aria-label": "Routines",
994
+ children: /* @__PURE__ */ jsxs(Collapsible.Root, {
995
+ defaultOpen: true,
996
+ children: [/* @__PURE__ */ jsxs(Button, {
997
+ render: /* @__PURE__ */ jsx(Collapsible.Trigger, { unstyled: true }),
998
+ type: "button",
999
+ variant: "ghost",
1000
+ color: "neutral",
1001
+ size: "sm",
1002
+ className: "manager-office__routine-trigger",
1003
+ children: [/* @__PURE__ */ jsxs("span", {
1004
+ className: "manager-office__identity",
1005
+ children: [/* @__PURE__ */ jsx(CalendarIcon, {}), /* @__PURE__ */ jsx("strong", { children: "Routines" })]
1006
+ }), /* @__PURE__ */ jsx(ChevronDownIcon, { className: "sigvelo-disclosure-chevron" })]
1007
+ }), /* @__PURE__ */ jsx(Collapsible.Panel, {
1008
+ unstyled: true,
1009
+ children: employee.routines.length ? /* @__PURE__ */ jsx("ul", {
1010
+ className: "manager-office__routine-list sigvelo-stack-list",
1011
+ children: employee.routines.map((routine) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(LinkButton, {
1012
+ render: renderLink({
1013
+ kind: "routine",
1014
+ employee,
1015
+ routine
1016
+ }),
1017
+ variant: "ghost",
1018
+ color: "neutral",
1019
+ size: "sm",
1020
+ className: "manager-office__routine-link",
1386
1021
  children: [
1387
- "Showing ",
1388
- /* @__PURE__ */ jsx("strong", { children: filteredEmployees.length }),
1389
- " of ",
1390
- employees.length,
1391
- " employees"
1392
- ]
1393
- })]
1394
- })]
1395
- }),
1396
- analytics.length ? /* @__PURE__ */ jsx(DashboardAnalytics, {
1397
- analytics,
1398
- currency: analyticsCurrency,
1399
- employeeIds: filteredEmployees.map((employee) => employee.id),
1400
- now,
1401
- onExportReport,
1402
- rangeDays,
1403
- setRangeDays
1404
- }) : null,
1405
- /* @__PURE__ */ jsx("div", {
1406
- className: "manager-office__kanban",
1407
- "aria-label": "AI employee progress board",
1408
- style: { gridTemplateColumns: lanes.map((lane) => collapsedLanes.has(lane) ? "4rem" : "minmax(15rem, 1fr)").join(" ") },
1409
- children: lanes.map((lane) => {
1410
- const cards = cardsByLane.get(lane) ?? [];
1411
- const visibleCards = cards.slice(0, 5);
1412
- const headingId = `manager-office-lane-${lane}`;
1413
- const collapsed = collapsedLanes.has(lane);
1414
- return /* @__PURE__ */ jsxs("section", {
1415
- className: "manager-office__kanban-lane",
1416
- "data-collapsed": collapsed || void 0,
1417
- "data-lane": lane,
1418
- "aria-labelledby": headingId,
1419
- children: [/* @__PURE__ */ jsxs("header", {
1420
- className: "manager-office__kanban-lane-header",
1421
- children: [/* @__PURE__ */ jsxs("span", { children: [/* @__PURE__ */ jsx("h3", {
1422
- id: headingId,
1423
- children: dashboardLaneCopy[lane].title
1424
- }), /* @__PURE__ */ jsx("small", { children: dashboardLaneCopy[lane].description })] }), /* @__PURE__ */ jsxs("span", {
1425
- className: "manager-office__kanban-lane-actions",
1022
+ routine.enabled ? /* @__PURE__ */ jsx(CalendarIcon, {}) : /* @__PURE__ */ jsx(PauseIcon, {}),
1023
+ /* @__PURE__ */ jsxs("span", {
1024
+ className: "manager-office__identity",
1426
1025
  children: [/* @__PURE__ */ jsx("strong", {
1427
- "aria-label": `${cards.length} items`,
1428
- children: cards.length
1429
- }), /* @__PURE__ */ jsx(Button, {
1430
- "aria-expanded": !collapsed,
1431
- "aria-label": `${collapsed ? "Expand" : "Collapse"} ${dashboardLaneCopy[lane].title} column`,
1432
- className: "manager-office__kanban-lane-toggle",
1433
- color: "neutral",
1434
- onClick: () => toggleLane(lane),
1435
- size: "sm",
1436
- type: "button",
1437
- variant: "ghost",
1438
- children: collapsed ? /* @__PURE__ */ jsx(ChevronRightIcon, {}) : /* @__PURE__ */ jsx(ChevronDownIcon, {})
1026
+ className: "sigvelo-truncate",
1027
+ children: routine.name
1028
+ }), /* @__PURE__ */ jsx("small", {
1029
+ className: "sigvelo-truncate",
1030
+ children: routineDetail(routine)
1439
1031
  })]
1440
- })]
1441
- }), !collapsed ? /* @__PURE__ */ jsxs("div", {
1442
- className: "manager-office__kanban-cards",
1443
- children: [
1444
- visibleCards.map((card) => /* @__PURE__ */ jsx(DashboardCard, {
1445
- card,
1446
- collapsed: collapsedCards.has(dashboardCardId(card)),
1447
- color: profileColors.get(card.employee.id),
1448
- index: employees.indexOf(card.employee),
1449
- now,
1450
- onToggleCollapsed: () => toggleCard(dashboardCardId(card)),
1451
- renderLink
1452
- }, dashboardCardId(card))),
1453
- !cards.length ? /* @__PURE__ */ jsx("p", {
1454
- className: "manager-office__kanban-empty",
1455
- children: "Nothing here right now."
1456
- }) : null,
1457
- cards.length > visibleCards.length ? /* @__PURE__ */ jsxs("p", {
1458
- className: "manager-office__kanban-more",
1459
- children: [
1460
- "+",
1461
- cards.length - visibleCards.length,
1462
- " more match · Refine filters to narrow"
1463
- ]
1464
- }) : null
1465
- ]
1466
- }) : null]
1467
- }, lane);
1032
+ }),
1033
+ /* @__PURE__ */ jsx(ChevronRightIcon, { className: "manager-office__row-chevron" })
1034
+ ]
1035
+ }) }, routine.id))
1036
+ }) : /* @__PURE__ */ jsx("p", {
1037
+ className: "manager-office__section-empty",
1038
+ children: "No routines yet."
1468
1039
  })
1040
+ })]
1041
+ })
1042
+ });
1043
+ }
1044
+ function ManagerOfficeChannels({ className, ...props }) {
1045
+ const employee = useEmployee();
1046
+ return /* @__PURE__ */ jsxs("section", {
1047
+ ...props,
1048
+ className: cx("manager-office__section", className),
1049
+ children: [/* @__PURE__ */ jsx("header", {
1050
+ className: "manager-office__section-header",
1051
+ children: /* @__PURE__ */ jsxs("h2", {
1052
+ className: "manager-office__section-title",
1053
+ children: [/* @__PURE__ */ jsx(LinkIcon, {}), "Channels"]
1469
1054
  })
1470
- ]
1055
+ }), /* @__PURE__ */ jsx("div", {
1056
+ className: "manager-office__section-content",
1057
+ children: employee.channels.length ? /* @__PURE__ */ jsx("ul", {
1058
+ className: "manager-office__channel-list sigvelo-stack-list",
1059
+ children: employee.channels.map((channel) => /* @__PURE__ */ jsx(ChannelRow, { channel }, channel.id))
1060
+ }) : /* @__PURE__ */ jsx("p", {
1061
+ className: "manager-office__section-empty",
1062
+ children: "Nothing connected yet."
1063
+ })
1064
+ })]
1065
+ });
1066
+ }
1067
+ function ManagerOfficeMain({ render, ref, ...props }) {
1068
+ return useRender({
1069
+ defaultTagName: "main",
1070
+ render,
1071
+ ref,
1072
+ props: mergeProps({ className: "manager-office__main" }, props)
1471
1073
  });
1472
1074
  }
1473
- function EmployeeDetail({ employee, renderLink, now, profileColor }) {
1474
- if (!isConnected(employee)) return /* @__PURE__ */ jsx("div", {
1075
+ function ManagerOfficeColumns({ render, ref, ...props }) {
1076
+ return useRender({
1077
+ defaultTagName: "div",
1078
+ render,
1079
+ ref,
1080
+ props: mergeProps({ className: "manager-office__employee-columns" }, props)
1081
+ });
1082
+ }
1083
+ function ManagerOfficeAside({ render, ref, ...props }) {
1084
+ return useRender({
1085
+ defaultTagName: "aside",
1086
+ render,
1087
+ ref,
1088
+ props: mergeProps({ className: "manager-office__employee-aside" }, props)
1089
+ });
1090
+ }
1091
+ /** Honest disconnected state; the host chooses when and where to display it. */
1092
+ function ManagerOfficeConnectionState({ employee }) {
1093
+ return /* @__PURE__ */ jsx("div", {
1475
1094
  "data-recipe": "page",
1476
1095
  children: /* @__PURE__ */ jsx(EmptyState, {
1477
1096
  icon: employee.status === "connecting" ? /* @__PURE__ */ jsx(SpinnerIcon, {}) : /* @__PURE__ */ jsx(MonitorIcon, {}),
@@ -1479,278 +1098,50 @@ function EmployeeDetail({ employee, renderLink, now, profileColor }) {
1479
1098
  description: employee.statusDescription
1480
1099
  })
1481
1100
  });
1482
- return /* @__PURE__ */ jsxs("div", {
1483
- className: "manager-office__employee-detail",
1484
- "data-recipe": "page",
1485
- children: [
1486
- /* @__PURE__ */ jsxs("header", {
1487
- className: "manager-office__employee-header",
1488
- children: [/* @__PURE__ */ jsx(EmployeeAvatar, {
1489
- employee,
1490
- color: profileColor,
1491
- size: "lg"
1492
- }), /* @__PURE__ */ jsxs("span", {
1493
- className: "manager-office__identity",
1494
- children: [/* @__PURE__ */ jsx("strong", {
1495
- className: "sigvelo-truncate",
1496
- children: employee.name
1497
- }), /* @__PURE__ */ jsxs("small", {
1498
- className: "manager-office__role sigvelo-truncate",
1499
- children: [
1500
- employee.email,
1501
- " · ",
1502
- employee.role
1503
- ]
1504
- })]
1505
- })]
1506
- }),
1507
- employee.handoffs.length ? /* @__PURE__ */ jsx("section", {
1508
- className: "manager-office__employee-handoffs",
1509
- "aria-label": "Waiting on you",
1510
- children: employee.handoffs.map((handoff) => /* @__PURE__ */ jsx(HandoffCard, {
1511
- employee,
1512
- handoff,
1513
- renderLink,
1514
- now,
1515
- showEmployee: false
1516
- }, handoff.id))
1517
- }) : null,
1518
- /* @__PURE__ */ jsxs("div", {
1519
- className: "manager-office__employee-columns",
1520
- children: [/* @__PURE__ */ jsxs("section", {
1521
- className: "manager-office__section",
1522
- children: [/* @__PURE__ */ jsx("header", {
1523
- className: "manager-office__section-header",
1524
- children: /* @__PURE__ */ jsxs("h2", {
1525
- className: "manager-office__section-title",
1526
- children: [/* @__PURE__ */ jsx(MessageSquareIcon, {}), "Work"]
1527
- })
1528
- }), /* @__PURE__ */ jsx("div", {
1529
- className: "manager-office__section-content",
1530
- children: employee.work.length ? /* @__PURE__ */ jsx("ul", {
1531
- className: "manager-office__work-list sigvelo-stack-list",
1532
- children: employee.work.map((work) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(LinkButton, {
1533
- render: renderLink({
1534
- kind: "work",
1535
- employee,
1536
- work
1537
- }),
1538
- variant: "ghost",
1539
- color: "neutral",
1540
- size: "sm",
1541
- className: "manager-office__work-link",
1542
- children: [
1543
- /* @__PURE__ */ jsx(ThreadStatusIcon, { status: work.status }),
1544
- /* @__PURE__ */ jsxs("span", {
1545
- className: "manager-office__identity",
1546
- children: [/* @__PURE__ */ jsxs("strong", {
1547
- className: "sigvelo-truncate",
1548
- children: [work.title, work.status === "attention" ? /* @__PURE__ */ jsx("span", {
1549
- className: "manager-office__unread-dot",
1550
- "aria-hidden": "true"
1551
- }) : null]
1552
- }), /* @__PURE__ */ jsxs("small", {
1553
- className: "sigvelo-truncate",
1554
- children: [
1555
- threadStatusLabel(work.status),
1556
- " ·",
1557
- " ",
1558
- /* @__PURE__ */ jsx(Timestamp, {
1559
- timestamp: work.updatedAt,
1560
- now
1561
- })
1562
- ]
1563
- })]
1564
- }),
1565
- /* @__PURE__ */ jsx(ChevronRightIcon, { className: "manager-office__row-chevron" })
1566
- ]
1567
- }) }, work.id))
1568
- }) : /* @__PURE__ */ jsx(EmptyState, { description: "No work yet." })
1569
- })]
1570
- }), /* @__PURE__ */ jsxs("aside", {
1571
- className: "manager-office__employee-aside",
1572
- children: [/* @__PURE__ */ jsx("section", {
1573
- className: "manager-office__section",
1574
- "aria-label": "Routines",
1575
- children: /* @__PURE__ */ jsxs(Collapsible.Root, {
1576
- defaultOpen: true,
1577
- children: [/* @__PURE__ */ jsxs(Button, {
1578
- render: /* @__PURE__ */ jsx(Collapsible.Trigger, { unstyled: true }),
1579
- type: "button",
1580
- variant: "ghost",
1581
- color: "neutral",
1582
- size: "sm",
1583
- className: "manager-office__routine-trigger",
1584
- children: [/* @__PURE__ */ jsxs("span", {
1585
- className: "manager-office__identity",
1586
- children: [/* @__PURE__ */ jsx(CalendarIcon, {}), /* @__PURE__ */ jsx("strong", { children: "Routines" })]
1587
- }), /* @__PURE__ */ jsx(ChevronDownIcon, { className: "sigvelo-disclosure-chevron" })]
1588
- }), /* @__PURE__ */ jsx(Collapsible.Panel, {
1589
- unstyled: true,
1590
- children: employee.routines.length ? /* @__PURE__ */ jsx("ul", {
1591
- className: "manager-office__routine-list sigvelo-stack-list",
1592
- children: employee.routines.map((routine) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(LinkButton, {
1593
- render: renderLink({
1594
- kind: "routine",
1595
- employee,
1596
- routine
1597
- }),
1598
- variant: "ghost",
1599
- color: "neutral",
1600
- size: "sm",
1601
- className: "manager-office__routine-link",
1602
- children: [
1603
- routine.enabled ? /* @__PURE__ */ jsx(CalendarIcon, {}) : /* @__PURE__ */ jsx(PauseIcon, {}),
1604
- /* @__PURE__ */ jsxs("span", {
1605
- className: "manager-office__identity",
1606
- children: [/* @__PURE__ */ jsx("strong", {
1607
- className: "sigvelo-truncate",
1608
- children: routine.name
1609
- }), /* @__PURE__ */ jsx("small", {
1610
- className: "sigvelo-truncate",
1611
- children: routineDetail(routine)
1612
- })]
1613
- }),
1614
- /* @__PURE__ */ jsx(ChevronRightIcon, { className: "manager-office__row-chevron" })
1615
- ]
1616
- }) }, routine.id))
1617
- }) : /* @__PURE__ */ jsx(EmptyState, { description: "No routines yet." })
1618
- })]
1619
- })
1620
- }), /* @__PURE__ */ jsxs("section", {
1621
- className: "manager-office__section",
1622
- children: [/* @__PURE__ */ jsx("header", {
1623
- className: "manager-office__section-header",
1624
- children: /* @__PURE__ */ jsxs("h2", {
1625
- className: "manager-office__section-title",
1626
- children: [/* @__PURE__ */ jsx(LinkIcon, {}), "Inputs & outputs"]
1627
- })
1628
- }), /* @__PURE__ */ jsx("div", {
1629
- className: "manager-office__section-content",
1630
- children: employee.channels.length ? /* @__PURE__ */ jsx("ul", {
1631
- className: "manager-office__channel-list sigvelo-stack-list",
1632
- children: employee.channels.map((channel) => /* @__PURE__ */ jsx(ChannelRow, { channel }, channel.id))
1633
- }) : /* @__PURE__ */ jsx(EmptyState, { description: "Nothing connected yet." })
1634
- })]
1635
- })]
1636
- })]
1637
- })
1638
- ]
1639
- });
1640
1101
  }
1641
- /**
1642
- * Multi-employee manager office: a dashboard, aggregate handoffs, employee
1643
- * roster, and one employee dossier. The consuming app owns authentication,
1644
- * Agent connections, routing, and the selected employee's full work surface.
1645
- */
1646
- function ManagerOffice({ analytics = [], analyticsCurrency = "USD", className, emptyOfficeAction, employees, renderLink, officeActions, onExportReport, renderEmployeeActions, sidebarTogglePlacement = "sidebar", style, view, ...props }) {
1647
- const titleId = React.useId();
1102
+ /** Office data and relative-time boundary; hosts compose their shell and routed content. */
1103
+ function ManagerOfficeRoot({ employees, renderLink, render, ref, ...props }) {
1648
1104
  const [now, setNow] = React.useState(Date.now);
1649
1105
  React.useEffect(() => {
1650
1106
  const interval = window.setInterval(() => setNow(Date.now()), 6e4);
1651
1107
  return () => window.clearInterval(interval);
1652
1108
  }, []);
1653
- const selectedEmployee = view.kind === "employee" ? employees.find((employee) => employee.id === view.employeeId) : void 0;
1654
- const profileColors = rosterProfileColors(employees);
1655
- if (view.kind === "dashboard") return /* @__PURE__ */ jsx(Tooltip.Provider, { children: /* @__PURE__ */ jsxs("div", {
1656
- className: cx("manager-office", "manager-office--dashboard", className),
1657
- style,
1658
- ...props,
1659
- children: [/* @__PURE__ */ jsxs(AppTopBar.Root, {
1660
- "aria-label": "Workforce controls",
1661
- titleAlign: "start",
1662
- children: [/* @__PURE__ */ jsx(AppTopBar.Title, { render: /* @__PURE__ */ jsx("h1", {
1663
- id: titleId,
1664
- children: "Workforce"
1665
- }) }), officeActions ? /* @__PURE__ */ jsx(AppTopBar.Trailing, { children: officeActions }) : null]
1666
- }), /* @__PURE__ */ jsx("main", {
1667
- className: "manager-office__dashboard",
1668
- "aria-labelledby": titleId,
1669
- children: !employees.length ? /* @__PURE__ */ jsx(EmptyState, {
1670
- icon: /* @__PURE__ */ jsx(PlusIcon, {}),
1671
- title: "Add your first employee",
1672
- description: "Connect another profile to manage it here.",
1673
- children: emptyOfficeAction
1674
- }) : /* @__PURE__ */ jsx(DashboardView, {
1675
- analytics,
1676
- analyticsCurrency,
1677
- employees,
1678
- now,
1679
- onExportReport,
1680
- profileColors,
1681
- renderLink
1682
- })
1683
- })]
1684
- }) });
1685
- const title = view.kind === "attention" ? "Waiting on you" : selectedEmployee?.name ?? "Employee";
1686
- const mainLabel = view.kind === "attention" ? "Waiting on you" : `${selectedEmployee?.name ?? "Employee"} details`;
1687
- return /* @__PURE__ */ jsx(Tooltip.Provider, { children: /* @__PURE__ */ jsx(ResponsiveSidebarShell, {
1688
- className: cx("manager-office", className),
1689
- style,
1690
- sidebarLabel: "employees",
1691
- sidebarTogglePlacement,
1692
- showMainLabel: "Show workforce",
1693
- sidebar: ({ closeSidebarOnCompact }) => /* @__PURE__ */ jsx(ManagerOfficeSidebar, {
1694
- closeSidebarOnCompact,
1695
- employees,
1696
- renderLink,
1697
- officeActions,
1698
- selectedEmployeeId: view.kind === "employee" ? view.employeeId : null
1699
- }),
1700
- bar: {
1701
- label: "Workforce controls",
1702
- titleRender: /* @__PURE__ */ jsx("h1", {
1703
- id: titleId,
1704
- children: title
1705
- }),
1706
- title,
1707
- actions: selectedEmployee && isConnected(selectedEmployee) ? /* @__PURE__ */ jsxs(Fragment, { children: [
1708
- /* @__PURE__ */ jsx(AppTopBar.Link, {
1709
- label: `Start new work with ${selectedEmployee.name}`,
1710
- tooltip: "New work",
1711
- render: renderLink({
1712
- kind: "new-work",
1713
- employee: selectedEmployee
1714
- }),
1715
- children: /* @__PURE__ */ jsx(PencilIcon, {})
1716
- }),
1717
- /* @__PURE__ */ jsx(AppTopBar.Link, {
1718
- label: `Open ${selectedEmployee.name} workspace`,
1719
- tooltip: "Workspace",
1720
- render: renderLink({
1721
- kind: "workspace",
1722
- employee: selectedEmployee
1723
- }),
1724
- children: /* @__PURE__ */ jsx(FolderIcon, {})
1725
- }),
1726
- renderEmployeeActions?.(selectedEmployee)
1727
- ] }) : void 0
1728
- },
1729
- ...props,
1730
- children: /* @__PURE__ */ jsx("main", {
1731
- className: "manager-office__main",
1732
- "aria-label": mainLabel,
1733
- children: !employees.length ? /* @__PURE__ */ jsx(EmptyState, {
1734
- icon: /* @__PURE__ */ jsx(PlusIcon, {}),
1735
- title: "Add your first employee",
1736
- description: "Connect another profile to manage it here.",
1737
- children: emptyOfficeAction
1738
- }) : view.kind === "attention" ? /* @__PURE__ */ jsx(AttentionView, {
1739
- employees,
1740
- renderLink,
1741
- now
1742
- }) : selectedEmployee ? /* @__PURE__ */ jsx(EmployeeDetail, {
1743
- employee: selectedEmployee,
1744
- renderLink,
1745
- now,
1746
- profileColor: profileColors.get(selectedEmployee.id)
1747
- }) : /* @__PURE__ */ jsx(EmptyState, {
1748
- icon: /* @__PURE__ */ jsx(WarningIcon, {}),
1749
- title: "Employee unavailable",
1750
- description: "Choose another employee from the roster."
1751
- })
1752
- })
1753
- }) });
1109
+ const profileColors = React.useMemo(() => rosterProfileColors(employees), [employees]);
1110
+ const value = React.useMemo(() => ({
1111
+ employees,
1112
+ renderLink,
1113
+ now,
1114
+ profileColors
1115
+ }), [
1116
+ employees,
1117
+ renderLink,
1118
+ now,
1119
+ profileColors
1120
+ ]);
1121
+ const element = useRender({
1122
+ defaultTagName: "div",
1123
+ render,
1124
+ ref,
1125
+ props: mergeProps({ className: "manager-office" }, props)
1126
+ });
1127
+ return /* @__PURE__ */ jsx(OfficeContext.Provider, {
1128
+ value,
1129
+ children: /* @__PURE__ */ jsx(Tooltip.Provider, { children: element })
1130
+ });
1754
1131
  }
1132
+ const ManagerOffice = {
1133
+ Root: ManagerOfficeRoot,
1134
+ Main: ManagerOfficeMain,
1135
+ Attention: ManagerOfficeAttention,
1136
+ Employee: ManagerOfficeEmployeeRoot,
1137
+ EmployeeHeader: ManagerOfficeEmployeeHeader,
1138
+ Handoffs: ManagerOfficeHandoffs,
1139
+ Columns: ManagerOfficeColumns,
1140
+ Aside: ManagerOfficeAside,
1141
+ Work: ManagerOfficeWorkSection,
1142
+ Routines: ManagerOfficeRoutines,
1143
+ Channels: ManagerOfficeChannels,
1144
+ ConnectionState: ManagerOfficeConnectionState
1145
+ };
1755
1146
  //#endregion
1756
1147
  export { ManagerOffice, ManagerOfficeSidebar, ManagerOfficeSidebarAlert };