@datalayer/core 1.1.59 → 1.1.66

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 (366) hide show
  1. package/README.md +2 -2
  2. package/lib/api/DatalayerApi.d.ts +42 -1
  3. package/lib/api/DatalayerApi.js +90 -3
  4. package/lib/api/constants.d.ts +18 -0
  5. package/lib/api/constants.js +18 -0
  6. package/lib/api/contents/attachments.d.ts +9 -0
  7. package/lib/api/contents/attachments.js +43 -0
  8. package/lib/api/contents/bridges.d.ts +22 -0
  9. package/lib/api/contents/bridges.js +79 -0
  10. package/lib/api/contents/capabilities.d.ts +11 -0
  11. package/lib/api/contents/capabilities.js +21 -0
  12. package/lib/api/contents/cloudStorage.d.ts +31 -0
  13. package/lib/api/contents/cloudStorage.js +89 -0
  14. package/lib/api/contents/dataservers.d.ts +37 -0
  15. package/lib/api/contents/dataservers.js +121 -0
  16. package/lib/api/contents/datasets.d.ts +15 -0
  17. package/lib/api/contents/datasets.js +45 -0
  18. package/lib/api/contents/datasources.d.ts +70 -0
  19. package/lib/api/contents/datasources.js +149 -0
  20. package/lib/api/contents/generated.d.ts +1070 -0
  21. package/lib/api/contents/index.d.ts +16 -0
  22. package/lib/api/contents/index.js +20 -0
  23. package/lib/api/contents/mcp.d.ts +46 -0
  24. package/lib/api/contents/mcp.js +157 -0
  25. package/lib/api/contents/objects.d.ts +31 -0
  26. package/lib/api/contents/objects.js +88 -0
  27. package/lib/api/contents/operations.d.ts +3 -0
  28. package/lib/api/contents/operations.js +19 -0
  29. package/lib/api/contents/runtimeMounts.d.ts +40 -0
  30. package/lib/api/contents/runtimeMounts.js +59 -0
  31. package/lib/api/contents/sandboxUid.d.ts +53 -0
  32. package/lib/api/contents/sandboxUid.js +78 -0
  33. package/lib/api/contents/sources.d.ts +19 -0
  34. package/lib/api/contents/sources.js +119 -0
  35. package/lib/api/contents/sync.d.ts +18 -0
  36. package/lib/api/contents/sync.js +69 -0
  37. package/lib/api/contents/transfers.d.ts +38 -0
  38. package/lib/api/contents/transfers.js +123 -0
  39. package/lib/api/iam/connectedAgents.d.ts +39 -0
  40. package/lib/api/iam/connectedAgents.js +52 -0
  41. package/lib/api/iam/index.d.ts +2 -1
  42. package/lib/api/iam/index.js +2 -1
  43. package/lib/api/iam/mcpAlertRules.d.ts +51 -0
  44. package/lib/api/iam/mcpAlertRules.js +198 -0
  45. package/lib/api/iam/mcpAuditSettings.d.ts +46 -0
  46. package/lib/api/iam/mcpAuditSettings.js +120 -0
  47. package/lib/api/iam/mcpPolicy.d.ts +80 -0
  48. package/lib/api/iam/mcpPolicy.js +132 -0
  49. package/lib/api/iam/organizationTeams.d.ts +13 -0
  50. package/lib/api/iam/organizationTeams.js +43 -0
  51. package/lib/api/iam/serviceAgents.d.ts +68 -0
  52. package/lib/api/iam/serviceAgents.js +119 -0
  53. package/lib/api/index.d.ts +4 -1
  54. package/lib/api/index.js +3 -1
  55. package/lib/api/mcp/activity.d.ts +37 -0
  56. package/lib/api/mcp/activity.js +26 -0
  57. package/lib/api/mcp/alerts.d.ts +25 -0
  58. package/lib/api/mcp/alerts.js +51 -0
  59. package/lib/api/mcp/audit.d.ts +29 -0
  60. package/lib/api/mcp/audit.js +55 -0
  61. package/lib/api/mcp/bindings.d.ts +18 -0
  62. package/lib/api/mcp/bindings.js +42 -0
  63. package/lib/api/mcp/forwarding.d.ts +25 -0
  64. package/lib/api/mcp/forwarding.js +46 -0
  65. package/lib/api/mcp/gateway.d.ts +16 -0
  66. package/lib/api/mcp/gateway.js +70 -0
  67. package/lib/api/mcp/generated.d.ts +22 -0
  68. package/lib/api/mcp/generated.js +213 -0
  69. package/lib/api/mcp/index.d.ts +17 -0
  70. package/lib/api/mcp/index.js +25 -0
  71. package/lib/api/mcp/observability.d.ts +125 -0
  72. package/lib/api/mcp/observability.js +254 -0
  73. package/lib/api/mcp/operations.d.ts +83 -0
  74. package/lib/api/mcp/operations.js +50 -0
  75. package/lib/api/mcp/organizations.d.ts +102 -0
  76. package/lib/api/mcp/organizations.js +46 -0
  77. package/lib/api/mcp/policy.d.ts +9 -0
  78. package/lib/api/mcp/policy.js +23 -0
  79. package/lib/api/mcp/tasks.d.ts +49 -0
  80. package/lib/api/mcp/tasks.js +147 -0
  81. package/lib/api/utils/validation.d.ts +1 -1
  82. package/lib/api/utils/validation.js +1 -1
  83. package/lib/client/auth/index.js +0 -5
  84. package/lib/client/auth/storage.js +0 -5
  85. package/lib/client/auth/strategies.js +0 -5
  86. package/lib/client/base.d.ts +6 -0
  87. package/lib/client/base.js +8 -0
  88. package/lib/client/index.d.ts +0 -10
  89. package/lib/client/index.js +2 -2
  90. package/lib/client/mixins/ContentsMixin.d.ts +71 -0
  91. package/lib/client/mixins/ContentsMixin.js +157 -0
  92. package/lib/client/mixins/IAMMixin.d.ts +0 -31
  93. package/lib/client/mixins/IAMMixin.js +0 -58
  94. package/lib/components/animation/AnimatedText.d.ts +1 -0
  95. package/lib/components/animation/AnimatedText.js +0 -4
  96. package/lib/components/auth/SigInAPIKey.d.ts +1 -0
  97. package/lib/components/auth/SigInAPIKey.js +0 -6
  98. package/lib/components/auth/SignIn.d.ts +1 -0
  99. package/lib/components/auth/SignIn.js +0 -4
  100. package/lib/components/auth/SignIn.stories.d.ts +2 -2
  101. package/lib/components/avatars/BoringAvatar.d.ts +1 -1
  102. package/lib/components/avatars/BoringAvatar.stories.d.ts +1 -1
  103. package/lib/components/avatars/DLAvatar.d.ts +1 -1
  104. package/lib/components/avatars/DLAvatar.js +0 -4
  105. package/lib/components/avatars/UserAvatar.d.ts +18 -1
  106. package/lib/components/avatars/UserAvatar.js +14 -14
  107. package/lib/components/avatars/UserProfileAvatar.d.ts +1 -1
  108. package/lib/components/banners/NoAutomationBanner.d.ts +1 -1
  109. package/lib/components/billing/BillingEntitySelect.d.ts +10 -0
  110. package/lib/components/billing/BillingEntitySelect.js +0 -17
  111. package/lib/components/billing/index.js +0 -4
  112. package/lib/components/buttons/DownloadCSVButton.d.ts +1 -1
  113. package/lib/components/buttons/DownloadJsonButton.d.ts +1 -1
  114. package/lib/components/buttons/LongActionButton.d.ts +1 -0
  115. package/lib/components/buttons/LongActionButton.js +0 -4
  116. package/lib/components/buttons/UploadButton.d.ts +1 -0
  117. package/lib/components/buttons/UploadButton.js +0 -4
  118. package/lib/components/checkout/StripeCheckout.d.ts +1 -1
  119. package/lib/components/collaboration/LiveEditorCollaborators.d.ts +31 -0
  120. package/lib/components/collaboration/LiveEditorCollaborators.js +98 -53
  121. package/lib/components/collaboration/index.js +0 -4
  122. package/lib/components/confetti/ConfettiSuccess.d.ts +1 -1
  123. package/lib/components/contents/ContentSourceCard.d.ts +8 -0
  124. package/lib/components/contents/ContentSourceCard.js +23 -0
  125. package/lib/components/contents/HomeFolderObjectsBrowser.d.ts +10 -0
  126. package/lib/components/contents/HomeFolderObjectsBrowser.js +148 -0
  127. package/lib/components/contents/index.d.ts +2 -0
  128. package/lib/components/contents/index.js +6 -0
  129. package/lib/components/context/OrganizationSelect.d.ts +1 -1
  130. package/lib/components/display/AvatarSkeleton.d.ts +1 -1
  131. package/lib/components/display/BusyDots.d.ts +1 -1
  132. package/lib/components/display/CenteredSpinner.d.ts +1 -1
  133. package/lib/components/display/CodePreview.d.ts +1 -1
  134. package/lib/components/display/DatalayerBox.d.ts +7 -2
  135. package/lib/components/display/DatalayerBox.js +6 -6
  136. package/lib/components/display/HorizontalCenter.d.ts +1 -1
  137. package/lib/components/display/JupyterDialog.d.ts +1 -0
  138. package/lib/components/display/JupyterDialog.js +1 -7
  139. package/lib/components/display/Markdown.d.ts +1 -0
  140. package/lib/components/display/NotebookSkeleton.d.ts +1 -1
  141. package/lib/components/display/Placeholder.d.ts +1 -1
  142. package/lib/components/display/ToTopBranded.d.ts +1 -1
  143. package/lib/components/echarts/EChartsReact.d.ts +1 -1
  144. package/lib/components/flashes/FlashClosable.d.ts +1 -0
  145. package/lib/components/flashes/FlashClosable.js +0 -4
  146. package/lib/components/flashes/FlashGuest.d.ts +1 -1
  147. package/lib/components/flashes/FlashSurveys.d.ts +1 -1
  148. package/lib/components/flashes/FlashUnauthorized.d.ts +1 -0
  149. package/lib/components/flashes/FlashUnauthorized.js +0 -6
  150. package/lib/components/flashes/surveys/Survey2025_1.d.ts +1 -1
  151. package/lib/components/iam/ExternalTokenSilentLogin.d.ts +1 -1
  152. package/lib/components/index.d.ts +2 -0
  153. package/lib/components/index.js +2 -0
  154. package/lib/components/labels/StatusLabels.d.ts +10 -0
  155. package/lib/components/labels/StatusLabels.js +30 -1
  156. package/lib/components/labels/VisibilityLabel.d.ts +1 -1
  157. package/lib/components/landings/StepBlock.d.ts +1 -1
  158. package/lib/components/mcp/ClientBadge.d.ts +41 -0
  159. package/lib/components/mcp/ClientBadge.js +33 -0
  160. package/lib/components/mcp/McpErrorBlankslate.d.ts +21 -0
  161. package/lib/components/mcp/McpErrorBlankslate.js +17 -0
  162. package/lib/components/mcp/ScopeList.d.ts +28 -0
  163. package/lib/components/mcp/ScopeList.js +14 -0
  164. package/lib/components/mcp/index.d.ts +10 -0
  165. package/lib/components/mcp/index.js +18 -0
  166. package/lib/components/navbar/NavigationVisbilityObserver.d.ts +2 -1
  167. package/lib/components/navbar/SubdomainNavBar.d.ts +10 -5
  168. package/lib/components/navbar/SubdomainNavBar.js +2 -1
  169. package/lib/components/notebooks/JupyterNotebook.d.ts +1 -1
  170. package/lib/components/notebooks/JupyterNotebookToolbar.d.ts +1 -1
  171. package/lib/components/principal/PrincipalAppearance.d.ts +1 -0
  172. package/lib/components/principal/PrincipalAppearance.js +0 -8
  173. package/lib/components/principal/PrincipalAvatar.d.ts +9 -1
  174. package/lib/components/principal/PrincipalAvatar.js +25 -10
  175. package/lib/components/principal/PrincipalBadge.d.ts +1 -1
  176. package/lib/components/principal/PrincipalBanner.d.ts +1 -1
  177. package/lib/components/principal/PrincipalDetailsOverlay.d.ts +31 -1
  178. package/lib/components/principal/PrincipalDetailsOverlay.js +64 -33
  179. package/lib/components/principal/PrincipalHoverCard.d.ts +31 -0
  180. package/lib/components/principal/PrincipalHoverCard.js +52 -0
  181. package/lib/components/principal/PrincipalSwitcherMenu.d.ts +1 -0
  182. package/lib/components/principal/PrincipalSwitcherMenu.js +7 -15
  183. package/lib/components/principal/index.d.ts +2 -1
  184. package/lib/components/principal/index.js +2 -1
  185. package/lib/components/progress/ConsumptionBar.d.ts +1 -0
  186. package/lib/components/progress/ConsumptionBar.js +0 -4
  187. package/lib/components/progress/ProgressRing.d.ts +1 -0
  188. package/lib/components/progress/SpinnerBar.d.ts +1 -1
  189. package/lib/components/progress/Timer.d.ts +1 -0
  190. package/lib/components/progress/Timer.js +0 -4
  191. package/lib/components/screencapture/ScreencaptureButton.d.ts +1 -1
  192. package/lib/components/sharing/ShareAccessComponent.d.ts +15 -1
  193. package/lib/components/sharing/ShareAccessComponent.js +36 -23
  194. package/lib/components/sharing/SharingEditor.d.ts +17 -0
  195. package/lib/components/sharing/SharingEditor.js +0 -24
  196. package/lib/components/sparklines/Sparklines.js +3 -4
  197. package/lib/components/sparklines/index.js +0 -4
  198. package/lib/components/storage/ContentsBrowser.d.ts +25 -1
  199. package/lib/components/storage/ContentsBrowser.js +145 -52
  200. package/lib/components/storage/ContentsBrowserMock.d.ts +3 -0
  201. package/lib/components/storage/ContentsBrowserMock.js +75 -0
  202. package/lib/components/storage/ContentsItems.d.ts +2 -1
  203. package/lib/components/storage/ContentsItems.js +0 -4
  204. package/lib/components/storage/ContentsTable.d.ts +50 -0
  205. package/lib/components/storage/ContentsTable.js +134 -0
  206. package/lib/components/storage/HomeFolderDrive.d.ts +71 -0
  207. package/lib/components/storage/HomeFolderDrive.js +248 -0
  208. package/lib/components/storage/index.d.ts +2 -0
  209. package/lib/components/storage/index.js +2 -0
  210. package/lib/components/students/StudentItemStatus.d.ts +1 -1
  211. package/lib/components/students/StudentResultCircle.d.ts +1 -1
  212. package/lib/components/subnav/SubNav.d.ts +5 -5
  213. package/lib/components/subnav/SubNav.js +11 -9
  214. package/lib/components/tables/DataTable.d.ts +1 -1
  215. package/lib/components/text-reveal/TextRevealAnimation.d.ts +2 -2
  216. package/lib/components/text-reveal/useTextRevealAnimationLines.d.ts +1 -1
  217. package/lib/components/time/LiveRelativeTime.d.ts +1 -0
  218. package/lib/components/time/LiveRelativeTime.js +0 -8
  219. package/lib/components/time/index.js +0 -4
  220. package/lib/components/timeline/Timeline.d.ts +1 -1
  221. package/lib/components/timeline/index.js +0 -4
  222. package/lib/components/users/PeerIndicator.d.ts +1 -0
  223. package/lib/components/users/PeerIndicator.js +0 -4
  224. package/lib/config/Configuration.d.ts +15 -17
  225. package/lib/config/Configuration.js +7 -0
  226. package/lib/hooks/index.d.ts +2 -0
  227. package/lib/hooks/index.js +2 -0
  228. package/lib/hooks/layouts/LayoutBackdrop.d.ts +1 -1
  229. package/lib/hooks/layouts/LayoutScreencapture.d.ts +1 -1
  230. package/lib/hooks/useBackdrop.d.ts +1 -1
  231. package/lib/hooks/useBackdropJupyterLab.d.ts +3 -2
  232. package/lib/hooks/useBackdropJupyterLab.js +0 -4
  233. package/lib/hooks/useCache.d.ts +310 -105
  234. package/lib/hooks/useCache.js +142 -355
  235. package/lib/hooks/useContainsFocus.d.ts +1 -1
  236. package/lib/hooks/useContents.d.ts +313 -0
  237. package/lib/hooks/useContents.js +964 -0
  238. package/lib/hooks/useFocusTrap.d.ts +4 -4
  239. package/lib/hooks/useFocusTrap.js +1 -1
  240. package/lib/hooks/useMcp.d.ts +229 -0
  241. package/lib/hooks/useMcp.js +656 -0
  242. package/lib/hooks/useMobile.js +0 -5
  243. package/lib/hooks/useProjectStore.d.ts +3 -3
  244. package/lib/hooks/useProjectStore.js +4 -4
  245. package/lib/hooks/useRef.d.ts +1 -1
  246. package/lib/hooks/useRef.js +3 -0
  247. package/lib/hooks/useScreencapture.d.ts +2 -1
  248. package/lib/hooks/useScreencapture.js +0 -4
  249. package/lib/hooks/useToast.js +0 -4
  250. package/lib/hooks/useUser.js +42 -0
  251. package/lib/hooks/useVisibilityObserver.d.ts +1 -1
  252. package/lib/index.d.ts +4 -1
  253. package/lib/index.js +3 -1
  254. package/lib/mocks/components/FlashMock.d.ts +1 -1
  255. package/lib/mocks/views/ActionMenuMock.d.ts +1 -1
  256. package/lib/mocks/views/ChartMock.d.ts +1 -1
  257. package/lib/mocks/views/DashboardMock.d.ts +1 -1
  258. package/lib/mocks/views/FormMock.d.ts +1 -1
  259. package/lib/mocks/views/TableMock.d.ts +1 -1
  260. package/lib/mocks/views/WipMock.d.ts +1 -1
  261. package/lib/models/Credits.d.ts +16 -0
  262. package/lib/models/Credits.js +22 -0
  263. package/lib/models/McpAuditEvent.d.ts +52 -0
  264. package/lib/models/McpAuditEvent.js +5 -0
  265. package/lib/models/McpBinding.d.ts +51 -0
  266. package/lib/models/McpBinding.js +5 -0
  267. package/lib/models/McpPolicy.d.ts +77 -0
  268. package/lib/models/McpPolicy.js +5 -0
  269. package/lib/models/McpTask.d.ts +94 -0
  270. package/lib/models/McpTask.js +7 -0
  271. package/lib/models/StartedBy.d.ts +57 -0
  272. package/lib/models/StartedBy.js +81 -0
  273. package/lib/models/UserDTO.js +4 -2
  274. package/lib/models/contents/__fixtures__/solr-codec.json +57 -0
  275. package/lib/models/contents/__fixtures__/v1-contracts.json +66 -0
  276. package/lib/models/contents/fieldCase.d.ts +8 -0
  277. package/lib/models/contents/fieldCase.js +37 -0
  278. package/lib/models/contents/index.d.ts +2 -0
  279. package/lib/models/contents/index.js +6 -0
  280. package/lib/models/contents/permissions.d.ts +16 -0
  281. package/lib/models/contents/permissions.js +34 -0
  282. package/lib/models/index.d.ts +5 -1
  283. package/lib/models/index.js +5 -1
  284. package/lib/state/substates/CoreState.d.ts +15 -7
  285. package/lib/state/substates/CoreState.js +18 -14
  286. package/lib/state/substates/IAMState.d.ts +1 -1
  287. package/lib/state/substates/IAMState.js +5 -5
  288. package/lib/state/substates/ProfileState.js +0 -4
  289. package/lib/state/substates/index.d.ts +0 -1
  290. package/lib/state/substates/index.js +0 -1
  291. package/lib/utils/Jwt.d.ts +26 -0
  292. package/lib/utils/Jwt.js +37 -0
  293. package/lib/utils/WithSuspense.d.ts +1 -1
  294. package/lib/views/api-keys/APIKeyEdit.d.ts +1 -1
  295. package/lib/views/api-keys/APIKeyNew.d.ts +1 -1
  296. package/lib/views/api-keys/APIKeys.d.ts +1 -1
  297. package/lib/views/api-keys/APIKeys.js +30 -4
  298. package/lib/views/api-keys/APIKeysStandalone.d.ts +5 -1
  299. package/lib/views/api-keys/APIKeysStandalone.js +2 -2
  300. package/lib/views/datasources/DatasourceDetail.d.ts +12 -5
  301. package/lib/views/datasources/DatasourceDetail.js +80 -110
  302. package/lib/views/datasources/DatasourceNew.d.ts +14 -8
  303. package/lib/views/datasources/DatasourceNew.js +129 -118
  304. package/lib/views/datasources/Datasources.d.ts +39 -7
  305. package/lib/views/datasources/Datasources.js +95 -40
  306. package/lib/views/datasources/DatasourcesMock.d.ts +3 -0
  307. package/lib/views/datasources/DatasourcesMock.js +57 -0
  308. package/lib/views/iam/SignInSimple.d.ts +12 -0
  309. package/lib/views/iam/SignInSimple.js +4 -4
  310. package/lib/views/index.d.ts +1 -0
  311. package/lib/views/index.js +1 -0
  312. package/lib/views/mcp/AlertDestinations.d.ts +34 -0
  313. package/lib/views/mcp/AlertDestinations.js +75 -0
  314. package/lib/views/mcp/AlertRules.d.ts +32 -0
  315. package/lib/views/mcp/AlertRules.js +245 -0
  316. package/lib/views/mcp/AuditLog.d.ts +42 -0
  317. package/lib/views/mcp/AuditLog.js +144 -0
  318. package/lib/views/mcp/ConnectedAgents.d.ts +34 -0
  319. package/lib/views/mcp/ConnectedAgents.js +100 -0
  320. package/lib/views/mcp/EnterpriseConsole.d.ts +74 -0
  321. package/lib/views/mcp/EnterpriseConsole.js +173 -0
  322. package/lib/views/mcp/McpDashboard.d.ts +50 -0
  323. package/lib/views/mcp/McpDashboard.js +347 -0
  324. package/lib/views/mcp/McpHome.d.ts +92 -0
  325. package/lib/views/mcp/McpHome.js +153 -0
  326. package/lib/views/mcp/McpObservability.d.ts +50 -0
  327. package/lib/views/mcp/McpObservability.js +150 -0
  328. package/lib/views/mcp/OrganizationPolicy.d.ts +45 -0
  329. package/lib/views/mcp/OrganizationPolicy.js +107 -0
  330. package/lib/views/mcp/OrganizationUsage.d.ts +69 -0
  331. package/lib/views/mcp/OrganizationUsage.js +113 -0
  332. package/lib/views/mcp/PersonalPolicy.d.ts +54 -0
  333. package/lib/views/mcp/PersonalPolicy.js +125 -0
  334. package/lib/views/mcp/Policies.d.ts +53 -0
  335. package/lib/views/mcp/Policies.js +210 -0
  336. package/lib/views/mcp/PolicyForm.d.ts +67 -0
  337. package/lib/views/mcp/PolicyForm.js +91 -0
  338. package/lib/views/mcp/PolicyHistory.d.ts +45 -0
  339. package/lib/views/mcp/PolicyHistory.js +62 -0
  340. package/lib/views/mcp/ServiceAgents.d.ts +46 -0
  341. package/lib/views/mcp/ServiceAgents.js +194 -0
  342. package/lib/views/mcp/TeamPolicies.d.ts +33 -0
  343. package/lib/views/mcp/TeamPolicies.js +98 -0
  344. package/lib/views/mcp/format.d.ts +25 -0
  345. package/lib/views/mcp/format.js +77 -0
  346. package/lib/views/mcp/index.d.ts +29 -0
  347. package/lib/views/mcp/index.js +37 -0
  348. package/lib/views/mcp/types.d.ts +66 -0
  349. package/lib/views/mcp/types.js +5 -0
  350. package/lib/views/secrets/SecretEdit.d.ts +5 -1
  351. package/lib/views/secrets/SecretEdit.js +2 -2
  352. package/lib/views/secrets/SecretNew.d.ts +11 -1
  353. package/lib/views/secrets/SecretNew.js +2 -2
  354. package/lib/views/secrets/Secrets.d.ts +12 -1
  355. package/lib/views/secrets/Secrets.js +2 -2
  356. package/package.json +28 -24
  357. package/scripts/generate-contents-types.py +169 -0
  358. package/scripts/generate-mcp-types.py +233 -0
  359. package/lib/api/iam/datasources.d.ts +0 -86
  360. package/lib/api/iam/datasources.js +0 -185
  361. package/lib/components/toolbars/index.d.ts +0 -1
  362. package/lib/models/Datasource.d.ts +0 -181
  363. package/lib/models/Datasource.js +0 -154
  364. package/lib/state/substates/DatasourceState.d.ts +0 -11
  365. package/lib/state/substates/DatasourceState.js +0 -16
  366. /package/lib/{components/toolbars/index.js → api/contents/generated.js} +0 -0
@@ -0,0 +1,347 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useMemo, useRef, useState } from 'react';
3
+ import { ActionList, ActionMenu, Button, Heading, Label, Link, Select, Spinner, Text, } from '@primer/react';
4
+ import { Blankslate, DataTable, Dialog, Table, } from '@primer/react/experimental';
5
+ import { Box } from '@datalayer/primer-addons';
6
+ import { ChecklistIcon, KebabHorizontalIcon, PlayIcon, PlugIcon, StackIcon, TelescopeIcon, } from '@primer/octicons-react';
7
+ import { ClientBadge, McpErrorBlankslate } from '../../components/mcp/index.js';
8
+ import { useDisconnectAgent, useMcpActivity, useTerminateBinding, } from '../../hooks/useMcp.js';
9
+ import { useNavigate, useToast } from '../../hooks/index.js';
10
+ import { clientStatusOf, durationLabel, plural, timeAgo } from './format.js';
11
+ /** How a client's status is drawn. */
12
+ const STATUS_LOOK = {
13
+ active: { label: 'Active', variant: 'success' },
14
+ idle: { label: 'Idle', variant: 'attention' },
15
+ disconnected: { label: 'Disconnected', variant: 'secondary' },
16
+ };
17
+ /** What a client is working on, in one phrase. */
18
+ const boundTo = (client) => {
19
+ const call = client.lastCall;
20
+ if (!call) {
21
+ return '';
22
+ }
23
+ if (call.itemUid) {
24
+ return `Notebook ${call.itemUid}`;
25
+ }
26
+ if (call.sourceUid) {
27
+ return `Source ${call.sourceUid}`;
28
+ }
29
+ return '';
30
+ };
31
+ const countLook = (tone) => tone === 'danger' ? 'danger.fg' : 'fg.default';
32
+ const Count = ({ label, value, tone = 'neutral', note, }) => (_jsxs(Box, { sx: {
33
+ p: 3,
34
+ border: '1px solid',
35
+ borderColor: 'border.default',
36
+ borderRadius: 2,
37
+ bg: 'canvas.default',
38
+ minWidth: 0,
39
+ }, children: [_jsx(Text, { sx: {
40
+ display: 'block',
41
+ fontSize: 4,
42
+ fontWeight: 'bold',
43
+ color: countLook(tone),
44
+ }, children: value }), _jsx(Text, { sx: { display: 'block', fontSize: 0, color: 'fg.muted' }, children: label }), note && (_jsx(Text, { sx: { display: 'block', fontSize: 0, color: 'fg.subtle', mt: 1 }, children: note }))] }));
45
+ /** A panel that has nothing to show, and the step that would fill it. */
46
+ const PanelEmpty = ({ icon: Icon, heading, description, action, }) => (_jsxs(Blankslate, { border: true, spacious: true, children: [_jsx(Blankslate.Visual, { children: _jsx(Icon, { size: "medium" }) }), _jsx(Blankslate.Heading, { children: heading }), _jsx(Blankslate.Description, { children: _jsx(Text, { as: "p", sx: { textAlign: 'center', m: 0 }, children: description }) }), action && (_jsx(Button, { size: "small", onClick: action.onClick, children: action.label }))] }));
47
+ export const McpDashboard = ({ errorState, routes, org, showTitle = true, section, }) => {
48
+ /** Whether this section is the one being drawn. */
49
+ const draws = (name) => section === name;
50
+ const navigate = useNavigate();
51
+ const { enqueueToast } = useToast();
52
+ const activity = useMcpActivity(org ? { org } : {});
53
+ const disconnect = useDisconnectAgent();
54
+ const terminate = useTerminateBinding();
55
+ const [disconnecting, setDisconnecting] = useState(null);
56
+ const [terminating, setTerminating] = useState(null);
57
+ // Primer 37 types Dialog's focus refs with React 18's non-nullable
58
+ // `RefObject<HTMLElement>`. React 19's `useRef(null)` is nullable, and this
59
+ // ref is only handed to Dialog, so narrow it once here.
60
+ const returnFocusRef = useRef(null);
61
+ // The calls panel filters what is already in hand: the answer carries the
62
+ // last fifty calls, so narrowing them is a matter of the browser, not of
63
+ // another request.
64
+ const [callClient, setCallClient] = useState('');
65
+ const [callTool, setCallTool] = useState('');
66
+ const [callOutcome, setCallOutcome] = useState('');
67
+ const data = activity.data;
68
+ const clients = useMemo(() => (data?.clients ?? []).map(client => ({
69
+ ...client,
70
+ id: client.clientId,
71
+ status: clientStatusOf(client.lastCall?.at),
72
+ })), [data?.clients]);
73
+ const sandboxes = useMemo(() => (data?.sandboxes ?? []).map(binding => ({ ...binding, id: binding.uid })), [data?.sandboxes]);
74
+ const calls = useMemo(() => (data?.calls ?? []).map(call => ({ ...call, id: call.uid })), [data?.calls]);
75
+ const filteredCalls = useMemo(() => calls.filter(call => (!callClient || call.clientId === callClient) &&
76
+ (!callTool || call.tool === callTool) &&
77
+ (!callOutcome ||
78
+ (callOutcome === 'refused'
79
+ ? call.decision === 'refused'
80
+ : call.outcome === callOutcome))), [calls, callClient, callTool, callOutcome]);
81
+ const callTools = useMemo(() => [
82
+ ...new Set(calls.map(call => call.tool).filter(Boolean)),
83
+ ].sort(), [calls]);
84
+ const auditFor = (call) => {
85
+ const parameters = new URLSearchParams();
86
+ if (call.taskId) {
87
+ parameters.set('task', call.taskId);
88
+ }
89
+ else if (call.traceId) {
90
+ parameters.set('trace', call.traceId);
91
+ }
92
+ else {
93
+ if (call.clientId) {
94
+ parameters.set('agent', call.clientId);
95
+ }
96
+ if (call.tool) {
97
+ parameters.set('tool', call.tool);
98
+ }
99
+ }
100
+ const search = parameters.toString();
101
+ return search ? `${routes.audit}?${search}` : routes.audit;
102
+ };
103
+ const traceFor = (call) => {
104
+ if (call.taskId) {
105
+ return `${routes.observability}?task=${encodeURIComponent(call.taskId)}`;
106
+ }
107
+ if (call.traceId) {
108
+ return `${routes.observability}?trace=${encodeURIComponent(call.traceId)}`;
109
+ }
110
+ return null;
111
+ };
112
+ const confirmDisconnect = () => {
113
+ const client = disconnecting;
114
+ if (!client?.grantUid) {
115
+ return;
116
+ }
117
+ disconnect.mutate(client.grantUid, {
118
+ onSuccess: () => {
119
+ enqueueToast(`${client.clientName || client.clientId} is disconnected.`, {
120
+ variant: 'success',
121
+ });
122
+ setDisconnecting(null);
123
+ },
124
+ onError: reason => {
125
+ enqueueToast(`Could not disconnect: ${reason.message}`, {
126
+ variant: 'error',
127
+ });
128
+ setDisconnecting(null);
129
+ },
130
+ });
131
+ };
132
+ const confirmTerminate = () => {
133
+ const binding = terminating;
134
+ if (!binding) {
135
+ return;
136
+ }
137
+ terminate.mutate(binding.uid, {
138
+ onSuccess: () => {
139
+ enqueueToast(`Sandbox ${binding.uid} is terminated.`, {
140
+ variant: 'success',
141
+ });
142
+ setTerminating(null);
143
+ },
144
+ onError: reason => {
145
+ enqueueToast(`Could not terminate: ${reason.message}`, {
146
+ variant: 'error',
147
+ });
148
+ setTerminating(null);
149
+ },
150
+ });
151
+ };
152
+ const clientColumns = [
153
+ {
154
+ header: 'Client',
155
+ field: 'clientId',
156
+ rowHeader: true,
157
+ renderCell: row => (_jsx(ClientBadge, { clientId: row.clientId, clientName: row.clientName })),
158
+ },
159
+ {
160
+ header: 'Kind',
161
+ id: 'kind',
162
+ width: '110px',
163
+ // Service agents are principals of an organization and arrive with
164
+ // milestone 3; every grant IAM answers today is a delegation.
165
+ renderCell: () => (_jsx(Label, { size: "small", variant: "secondary", children: "Delegated" })),
166
+ },
167
+ {
168
+ header: 'Bound to',
169
+ id: 'bound',
170
+ width: 'growCollapse',
171
+ renderCell: row => (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: boundTo(row) || '—' })),
172
+ },
173
+ {
174
+ header: 'Last tool',
175
+ id: 'last-tool',
176
+ renderCell: row => row.lastCall ? (_jsxs(Box, { sx: { display: 'grid', gap: '2px', minWidth: 0 }, children: [_jsx(Text, { sx: { fontSize: 0 }, children: row.lastCall.tool || row.lastCall.method }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: timeAgo(row.lastCall.at) })] })) : (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "Nothing yet" })),
177
+ },
178
+ {
179
+ header: 'Status',
180
+ id: 'status',
181
+ width: '120px',
182
+ renderCell: row => (_jsx(Label, { size: "small", variant: STATUS_LOOK[row.status].variant, children: STATUS_LOOK[row.status].label })),
183
+ },
184
+ {
185
+ header: '',
186
+ id: 'actions',
187
+ width: '48px',
188
+ align: 'end',
189
+ renderCell: row => (_jsxs(ActionMenu, { children: [_jsx(ActionMenu.Anchor, { children: _jsx(Button, { variant: "invisible", size: "small", "aria-label": `Actions for ${row.clientName || row.clientId}`, icon: KebabHorizontalIcon }) }), _jsx(ActionMenu.Overlay, { align: "end", children: _jsxs(ActionList, { children: [_jsx(ActionList.Item, { onSelect: () => navigate(`${routes.audit}?agent=${encodeURIComponent(row.clientId)}`), children: "Audit" }), _jsx(ActionList.Divider, {}), _jsx(ActionList.Item, { variant: "danger", disabled: !row.grantUid, onSelect: () => setDisconnecting(row), children: "Disconnect" })] }) })] })),
190
+ },
191
+ ];
192
+ const sandboxColumns = [
193
+ {
194
+ header: 'Handle',
195
+ field: 'uid',
196
+ rowHeader: true,
197
+ renderCell: row => (_jsx(Text, { sx: { fontFamily: 'mono', fontSize: 0 }, children: row.uid })),
198
+ },
199
+ {
200
+ header: 'Provider',
201
+ id: 'provider',
202
+ width: '120px',
203
+ renderCell: row => (_jsx(Text, { sx: { fontSize: 0 }, children: row.sandboxProvider || 'datalayer' })),
204
+ },
205
+ {
206
+ header: 'Capabilities',
207
+ id: 'capabilities',
208
+ width: 'growCollapse',
209
+ renderCell: row => (_jsxs(Box, { sx: { display: 'flex', gap: 1, flexWrap: 'wrap' }, children: [(row.capabilities ?? []).map(capability => (_jsx(Label, { size: "small", variant: "secondary", children: capability }, capability))), (row.capabilities ?? []).length === 0 && (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "\u2014" }))] })),
210
+ },
211
+ {
212
+ header: 'Last used',
213
+ id: 'last-used',
214
+ width: '120px',
215
+ renderCell: row => (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: timeAgo(row.lastUsedAt ?? row.createdAt) || '—' })),
216
+ },
217
+ {
218
+ header: 'State',
219
+ id: 'state',
220
+ width: '150px',
221
+ renderCell: row => row.state === 'lost' ? (
222
+ // The loss is a fact of the session, not a hiccup: it is named
223
+ // with the error the next call was answered with.
224
+ _jsx(Label, { size: "small", variant: "danger", children: "SANDBOX_LOST" })) : (_jsx(Label, { size: "small", variant: row.state === 'active' ? 'success' : 'secondary', children: row.state ?? 'active' })),
225
+ },
226
+ {
227
+ header: '',
228
+ id: 'actions',
229
+ width: '110px',
230
+ align: 'end',
231
+ renderCell: row => (_jsx(Button, { size: "small", variant: "danger", disabled: row.state === 'closed', onClick: () => setTerminating(row), children: "Terminate" })),
232
+ },
233
+ ];
234
+ const callColumns = [
235
+ {
236
+ header: 'Tool',
237
+ field: 'tool',
238
+ rowHeader: true,
239
+ renderCell: row => (_jsxs(Box, { sx: { display: 'grid', gap: '2px', minWidth: 0 }, children: [_jsx(Text, { sx: { fontSize: 1 }, children: row.tool || row.method }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: timeAgo(row.at) })] })),
240
+ },
241
+ {
242
+ header: 'Client',
243
+ id: 'client',
244
+ renderCell: row => (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: row.clientId || '—' })),
245
+ },
246
+ {
247
+ header: 'On',
248
+ id: 'item',
249
+ width: 'growCollapse',
250
+ renderCell: row => (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: row.itemUid || row.sourceUid || '—' })),
251
+ },
252
+ {
253
+ header: 'Decision',
254
+ id: 'decision',
255
+ width: '110px',
256
+ renderCell: row => (_jsx(Label, { size: "small", variant: row.decision === 'refused' ? 'danger' : 'success', children: row.decision })),
257
+ },
258
+ {
259
+ header: 'Outcome',
260
+ id: 'outcome',
261
+ width: '110px',
262
+ renderCell: row => (_jsx(Text, { sx: {
263
+ fontSize: 0,
264
+ color: row.outcome === 'ok' ? 'fg.muted' : 'danger.fg',
265
+ }, children: row.outcome ?? '—' })),
266
+ },
267
+ {
268
+ header: 'Took',
269
+ id: 'duration',
270
+ width: '90px',
271
+ renderCell: row => (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: durationLabel(row.durationMs) || '—' })),
272
+ },
273
+ {
274
+ header: '',
275
+ id: 'links',
276
+ width: '150px',
277
+ align: 'end',
278
+ renderCell: row => {
279
+ const trace = traceFor(row);
280
+ return (_jsxs(Box, { sx: { display: 'flex', gap: 2, justifyContent: 'flex-end' }, children: [_jsx(Link, { as: "button", sx: { fontSize: 0, cursor: 'pointer' }, onClick: () => navigate(auditFor(row)), children: "Audit" }), trace && (_jsx(Link, { as: "button", sx: { fontSize: 0, cursor: 'pointer' }, onClick: () => navigate(trace), children: "Trace" }))] }));
281
+ },
282
+ },
283
+ ];
284
+ if (activity.isError) {
285
+ return (_jsx(Box, { sx: { display: 'grid', gap: 3 }, children: _jsx(McpErrorBlankslate, { state: errorState(activity.error, 'MCP activity'), onRetry: () => activity.refetch() }) }));
286
+ }
287
+ const loading = activity.isPending && !data;
288
+ return (_jsxs(Box, { sx: { display: 'grid', gap: 4, minWidth: 0 }, children: [showTitle && (_jsxs(Box, { children: [_jsx(Heading, { as: "h2", sx: { fontSize: 3, mb: 1 }, children: "MCP" }), _jsx(Text, { as: "p", sx: { color: 'fg.muted', fontSize: 1, m: 0 }, children: "What the agents connected to your workspace are doing right now." })] })), draws('overview') &&
289
+ (loading ? (_jsx(Box, { sx: { display: 'flex', justifyContent: 'center', py: 5 }, children: _jsx(Spinner, {}) })) : (_jsxs(Box, { sx: {
290
+ display: 'grid',
291
+ gap: 3,
292
+ gridTemplateColumns: [
293
+ 'repeat(2, 1fr)',
294
+ 'repeat(3, 1fr)',
295
+ 'repeat(6, 1fr)',
296
+ ],
297
+ }, children: [_jsx(Count, { label: "Clients connected", value: clients.length }), _jsx(Count, { label: "Sandboxes bound", value: sandboxes.filter(binding => (binding.state ?? 'active') === 'active').length }), _jsx(Count, { label: "Tasks running", value: data?.tasks.length ?? 0 }), _jsx(Count, { label: "Calls today", value: data?.today.calls ?? 0 }), _jsx(Count, { label: "Refusals today", value: data?.today.refusals ?? 0, tone: (data?.today.refusals ?? 0) > 0 ? 'danger' : 'neutral' }), _jsx(Count, { label: "Credits by agents", value: data?.today.credits ?? 0, note: "today" })] }))), draws('agents') &&
298
+ !loading &&
299
+ (clients.length > 0 ? (_jsxs(Table.Container, { children: [_jsx(Table.Title, { as: "h3", id: "mcp-clients", children: "Connected clients" }), _jsxs(Table.Subtitle, { as: "p", id: "mcp-clients-subtitle", children: [plural(clients.length, 'client'), " with a live grant on your workspace."] }), _jsx(DataTable, { "aria-labelledby": "mcp-clients", "aria-describedby": "mcp-clients-subtitle", data: clients, columns: clientColumns })] })) : (_jsx(PanelEmpty, { icon: PlugIcon, heading: "No client connected", description: "Connect Claude Code, Codex, Cursor, VS Code or any MCP client to your workspace, and it appears here on its first call.", action: {
300
+ label: 'Set up a client',
301
+ onClick: () => navigate(routes.access),
302
+ } }))), draws('runs') && !loading && (_jsxs(Box, { children: [_jsx(Heading, { as: "h3", sx: { fontSize: 1, mb: 2 }, children: "Running now" }), _jsx(PanelEmpty, { icon: PlayIcon, heading: "Nothing is running", description: (data?.tasks.length ?? 0) > 0
303
+ ? 'Tasks are running, and the live pane that shows their progress, their cell and their approvals arrives with durable execution in milestone 2.'
304
+ : 'A tool call that outlives its request becomes a task you can watch, cancel and answer. Durable execution arrives in milestone 2; until then every call finishes inside its own request and is listed under Recent calls.' })] })), draws('sandboxes') &&
305
+ !loading &&
306
+ (sandboxes.length > 0 ? (_jsxs(Table.Container, { children: [_jsx(Table.Title, { as: "h3", id: "mcp-sandboxes", children: "Sandboxes bound" }), _jsx(Table.Subtitle, { as: "p", id: "mcp-sandboxes-subtitle", children: "The sessions your agents execute in. Terminating one ends its open work." }), _jsx(DataTable, { "aria-labelledby": "mcp-sandboxes", "aria-describedby": "mcp-sandboxes-subtitle", data: sandboxes, columns: sandboxColumns })] })) : (_jsx(PanelEmpty, { icon: StackIcon, heading: "No sandbox bound", description: "An agent that launches a sandbox keeps it for the session; it appears here with its provider, its capabilities and what it is doing." }))), draws('calls') &&
307
+ !loading &&
308
+ (calls.length > 0 ? (_jsxs(Table.Container, { children: [_jsx(Table.Title, { as: "h3", id: "mcp-calls", children: "Recent calls" }), _jsx(Table.Subtitle, { as: "p", id: "mcp-calls-subtitle", children: "The last calls as they landed. Every one of them has an audit row that outlives this page." }), _jsx(Table.Actions, { children: _jsxs(Box, { sx: { display: 'flex', gap: 2, alignItems: 'center' }, children: [_jsxs(Select, { size: "small", "aria-label": "Filter by client", value: callClient, onChange: event => setCallClient(event.currentTarget.value), children: [_jsx(Select.Option, { value: "", children: "Every client" }), clients.map(client => (_jsx(Select.Option, { value: client.clientId, children: client.clientName || client.clientId }, client.clientId)))] }), _jsxs(Select, { size: "small", "aria-label": "Filter by tool", value: callTool, onChange: event => setCallTool(event.currentTarget.value), children: [_jsx(Select.Option, { value: "", children: "Every tool" }), callTools.map(tool => (_jsx(Select.Option, { value: tool, children: tool }, tool)))] }), _jsxs(Select, { size: "small", "aria-label": "Filter by outcome", value: callOutcome, onChange: event => setCallOutcome(event.currentTarget.value), children: [_jsx(Select.Option, { value: "", children: "Every outcome" }), _jsx(Select.Option, { value: "ok", children: "Succeeded" }), _jsx(Select.Option, { value: "error", children: "Failed" }), _jsx(Select.Option, { value: "refused", children: "Refused" })] })] }) }), filteredCalls.length > 0 ? (_jsx(DataTable, { "aria-labelledby": "mcp-calls", "aria-describedby": "mcp-calls-subtitle", data: filteredCalls, columns: callColumns })) : (_jsx(Box, { sx: {
309
+ p: 4,
310
+ textAlign: 'center',
311
+ color: 'fg.muted',
312
+ fontSize: 1,
313
+ }, children: "No call matches these filters." }))] })) : (_jsx(PanelEmpty, { icon: ChecklistIcon, heading: "No call yet", description: "Ask your agent to list your notebooks. The call, its decision and its outcome land here and in the audit log.", action: {
314
+ label: 'Open the audit log',
315
+ onClick: () => navigate(routes.audit),
316
+ } }))), !loading && (_jsxs(Box, { sx: {
317
+ display: 'flex',
318
+ gap: 3,
319
+ alignItems: 'center',
320
+ flexWrap: 'wrap',
321
+ }, children: [_jsx(Button, { size: "small", leadingVisual: TelescopeIcon, onClick: () => navigate(routes.observability), children: "Observability" }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: ["Refreshed ", timeAgo(data?.at) || 'just now', ", and again every ten seconds."] })] })), disconnecting && (_jsx(Dialog, { title: "Disconnect this client?", onClose: () => setDisconnecting(null), returnFocusRef: returnFocusRef, footerButtons: [
322
+ {
323
+ buttonType: 'default',
324
+ content: 'Keep it',
325
+ onClick: () => setDisconnecting(null),
326
+ },
327
+ {
328
+ buttonType: 'danger',
329
+ content: 'Disconnect',
330
+ onClick: confirmDisconnect,
331
+ disabled: disconnect.isPending,
332
+ },
333
+ ], children: _jsxs(Text, { sx: { fontSize: 1 }, children: [disconnecting.clientName || disconnecting.clientId, " loses its grant at once. Its next call is refused; an access token it still holds dies with its own short expiry. Nothing it already did is undone."] }) })), terminating && (_jsx(Dialog, { title: "Terminate this sandbox?", onClose: () => setTerminating(null), returnFocusRef: returnFocusRef, footerButtons: [
334
+ {
335
+ buttonType: 'default',
336
+ content: 'Keep it',
337
+ onClick: () => setTerminating(null),
338
+ },
339
+ {
340
+ buttonType: 'danger',
341
+ content: 'Terminate',
342
+ onClick: confirmTerminate,
343
+ disabled: terminate.isPending,
344
+ },
345
+ ], children: _jsxs(Text, { sx: { fontSize: 1 }, children: ["The runtime behind ", terminating.uid, " is stopped and its session closed. Work the agent has open there ends as", ' ', _jsx("code", { children: "SANDBOX_LOST" }), "; anything already written to a notebook stays."] }) }))] }));
346
+ };
347
+ export default McpDashboard;
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Access › MCP: how to connect a client, and what your agents may reach.
3
+ *
4
+ * This is the *setup and access* page, not the dashboard. It answers "how
5
+ * do I point my client at Datalayer" first — the endpoint, and one card per
6
+ * client with the command that writes its configuration — and then, in five
7
+ * summaries that link onward, "and what have they got": the agents
8
+ * connected, the runs, the toolsets, the notebooks and sources shared with
9
+ * an agent, and how the calls are behaving.
10
+ *
11
+ * What is happening *right now* is the dashboard's question, and the line
12
+ * at the top of the page opens it rather than answering it twice.
13
+ *
14
+ * Each card degrades to an explanatory empty state: a card with nothing in
15
+ * it says what would put something there.
16
+ *
17
+ * @module views/mcp/McpHome
18
+ */
19
+ import type { JSX } from 'react';
20
+ import { type McpRoutes } from './types';
21
+ export interface McpHomeProps {
22
+ /** Where this application puts the surfaces this view links to. */
23
+ routes: McpRoutes;
24
+ /** Where the per-client manuals live; each client appends its own name. */
25
+ clientDocsBase?: string;
26
+ showTitle?: boolean;
27
+ /**
28
+ * Whether to draw the summary cards beneath the setup.
29
+ *
30
+ * Off where they have a page of their own. This page answers "how do I
31
+ * connect one", and six cards about what connected agents are *doing* sat
32
+ * under that question answering a different one — a reader looking for a
33
+ * command scrolled past them, and a reader looking for the numbers had to
34
+ * know they were filed under Access.
35
+ */
36
+ showSummaries?: boolean;
37
+ /**
38
+ * Whether to draw the setup half — the endpoint and the per-client cards.
39
+ *
40
+ * Off where only the summaries are wanted, which is how the MCP overview
41
+ * mounts this: the two halves answer different questions and now live on
42
+ * different tabs, and one component drawing either keeps the wording and
43
+ * the data of each in one place rather than two that drift.
44
+ */
45
+ showSetup?: boolean;
46
+ /**
47
+ * Open a documentation page beside this view rather than navigating to it.
48
+ *
49
+ * A client's "Configuration and authorization" opens the panel the
50
+ * application has rather than navigating: reading how to configure Cursor
51
+ * should not mean losing the endpoint, the other clients and the command
52
+ * that were on screen — the page you are reading about is the page you
53
+ * just left.
54
+ *
55
+ * Required, and a callback rather than the store itself: this view knows a
56
+ * documentation *path* and nothing about how an application shows one. An
57
+ * optional one would mean a second behaviour nobody chose, kept alive by
58
+ * whichever caller forgot to pass it.
59
+ */
60
+ onOpenDocs: (path: string) => void;
61
+ }
62
+ /**
63
+ * The clients the documentation carries a page for, in the order it lists
64
+ * them, with the name `datalayer mcp setup` takes.
65
+ */
66
+ /**
67
+ * The command that writes a client's configuration.
68
+ *
69
+ * One function rather than the string written wherever it is shown. It is
70
+ * shown in two places that must not disagree — the Access view and the
71
+ * documentation page for each client — and a command a reader copies from
72
+ * the documentation that differs by a word from the one the interface shows
73
+ * is worse than either alone: it is two answers to "what do I run", and no
74
+ * way to tell which is current.
75
+ */
76
+ export declare const mcpSetupCommand: (client: string) => string;
77
+ export declare const MCP_CLIENTS: {
78
+ name: string;
79
+ setup: string;
80
+ }[];
81
+ /**
82
+ * A line of text with the button that copies it.
83
+ *
84
+ * Exported so the documentation shows a command the same way this view
85
+ * does: a reader who has seen one and then the other should not have to
86
+ * work out whether they are the same affordance.
87
+ */
88
+ export declare const Copyable: ({ text }: {
89
+ text: string;
90
+ }) => JSX.Element;
91
+ export declare const McpHome: ({ routes, clientDocsBase, showTitle, showSummaries, showSetup, onOpenDocs, }: McpHomeProps) => JSX.Element;
92
+ export default McpHome;
@@ -0,0 +1,153 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { Button, Heading, IconButton, Link, Text } from '@primer/react';
4
+ import { Box } from '@datalayer/primer-addons';
5
+ import { CheckIcon, CopyIcon, KeyIcon, PlugIcon, PulseIcon, ShareIcon, TelescopeIcon, ToolsIcon, } from '@primer/octicons-react';
6
+ import { useConnectedAgents, useMcpActivity, useMcpMetrics, useTasks, } from '../../hooks/useMcp.js';
7
+ import { useNavigate } from '../../hooks/index.js';
8
+ import { useCoreStore, useIAMStore } from '../../state/index.js';
9
+ import { plural, timeAgo } from './format.js';
10
+ /**
11
+ * The clients the documentation carries a page for, in the order it lists
12
+ * them, with the name `datalayer mcp setup` takes.
13
+ */
14
+ /**
15
+ * The command that writes a client's configuration.
16
+ *
17
+ * One function rather than the string written wherever it is shown. It is
18
+ * shown in two places that must not disagree — the Access view and the
19
+ * documentation page for each client — and a command a reader copies from
20
+ * the documentation that differs by a word from the one the interface shows
21
+ * is worse than either alone: it is two answers to "what do I run", and no
22
+ * way to tell which is current.
23
+ */
24
+ export const mcpSetupCommand = (client) => `datalayer mcp setup ${client}`;
25
+ export const MCP_CLIENTS = [
26
+ { name: 'Claude Code', setup: 'claude-code' },
27
+ { name: 'Claude Desktop', setup: 'claude-desktop' },
28
+ { name: 'Codex', setup: 'codex' },
29
+ { name: 'Cursor', setup: 'cursor' },
30
+ { name: 'VS Code', setup: 'vscode' },
31
+ { name: 'Windsurf', setup: 'windsurf' },
32
+ { name: 'Cline', setup: 'cline' },
33
+ ];
34
+ /**
35
+ * A line of text with the button that copies it.
36
+ *
37
+ * Exported so the documentation shows a command the same way this view
38
+ * does: a reader who has seen one and then the other should not have to
39
+ * work out whether they are the same affordance.
40
+ */
41
+ export const Copyable = ({ text }) => {
42
+ const [copied, setCopied] = useState(false);
43
+ return (_jsxs(Box, { sx: {
44
+ display: 'flex',
45
+ alignItems: 'center',
46
+ gap: 2,
47
+ p: 2,
48
+ bg: 'canvas.inset',
49
+ borderRadius: 2,
50
+ minWidth: 0,
51
+ }, children: [_jsx(Text, { sx: {
52
+ fontFamily: 'mono',
53
+ fontSize: 0,
54
+ flex: 1,
55
+ minWidth: 0,
56
+ overflow: 'hidden',
57
+ textOverflow: 'ellipsis',
58
+ whiteSpace: 'nowrap',
59
+ }, children: text }), _jsx(IconButton, { size: "small", variant: "invisible", "aria-label": copied ? 'Copied' : `Copy ${text}`, icon: copied ? CheckIcon : CopyIcon, onClick: () => {
60
+ navigator.clipboard?.writeText(text);
61
+ setCopied(true);
62
+ window.setTimeout(() => setCopied(false), 1500);
63
+ } })] }));
64
+ };
65
+ /** One of the five summaries: a heading, what it holds, and the way in. */
66
+ const Summary = ({ icon: Icon, title, children, action, }) => (_jsxs(Box, { sx: {
67
+ p: 3,
68
+ border: '1px solid',
69
+ borderColor: 'border.default',
70
+ borderRadius: 2,
71
+ display: 'grid',
72
+ gap: 2,
73
+ alignContent: 'start',
74
+ minWidth: 0,
75
+ }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Icon, { size: 16 }), _jsx(Text, { sx: { fontSize: 1, fontWeight: 'semibold' }, children: title })] }), _jsx(Box, { sx: { fontSize: 0, color: 'fg.muted', display: 'grid', gap: 1 }, children: children }), action && (_jsx(Box, { children: _jsx(Link, { as: "button", sx: { fontSize: 0, cursor: 'pointer' }, onClick: action.onClick, children: action.label }) }))] }));
76
+ export const McpHome = ({ routes, clientDocsBase = '/docs/mcp-clients', showTitle = true, showSummaries = true, showSetup = true, onOpenDocs, }) => {
77
+ const navigate = useNavigate();
78
+ const endpoint = useCoreStore(state => state.configuration.jupyterMcpServerUrl);
79
+ // Whether there is a token, never what it is: this page shows an address
80
+ // and a status, and a credential belongs on neither.
81
+ const signedIn = Boolean(useIAMStore(state => state.token));
82
+ const agents = useConnectedAgents();
83
+ const tasks = useTasks({ limit: 5 });
84
+ const activity = useMcpActivity();
85
+ const metrics = useMcpMetrics();
86
+ const connected = agents.data ?? [];
87
+ const runs = tasks.data?.items ?? [];
88
+ const live = activity.data?.clients.length ?? 0;
89
+ return (_jsxs(Box, { sx: { display: 'grid', gap: 4, minWidth: 0 }, children: [showTitle && (_jsxs(Box, { children: [_jsx(Heading, { as: "h2", sx: { fontSize: 3, mb: 1 }, children: "MCP" }), _jsx(Text, { as: "p", sx: { color: 'fg.muted', fontSize: 1, m: 0 }, children: "Connect your agents to your notebooks, data and sandboxes through the Model Context Protocol." })] })), showSetup && (_jsxs(_Fragment, { children: [_jsxs(Box, { sx: {
90
+ display: 'flex',
91
+ alignItems: 'center',
92
+ gap: 3,
93
+ flexWrap: 'wrap',
94
+ p: 3,
95
+ borderRadius: 2,
96
+ bg: 'canvas.subtle',
97
+ border: '1px solid',
98
+ borderColor: 'border.default',
99
+ }, children: [_jsx(Text, { sx: { fontSize: 1 }, children: live > 0
100
+ ? `${plural(live, 'client')} connected right now.`
101
+ : 'No client is connected right now.' }), _jsx(Button, { size: "small", leadingVisual: PulseIcon, onClick: () => navigate(routes.dashboard), children: "What is going on" })] }), _jsxs(Box, { sx: { display: 'grid', gap: 2 }, children: [_jsx(Heading, { as: "h3", sx: { fontSize: 2 }, children: "The endpoint" }), _jsx(Copyable, { text: endpoint || 'https://mcp.datalayer.run/mcp' }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(KeyIcon, { size: 14 }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: signedIn
102
+ ? 'You are signed in, so a client you set up from here authorizes through OAuth without a shared token.'
103
+ : 'Sign in to authorize a client through OAuth; without it a client can only use a personal access token.' })] })] }), _jsxs(Box, { sx: { display: 'grid', gap: 2 }, children: [_jsx(Heading, { as: "h3", sx: { fontSize: 2 }, children: "Set up a client" }), _jsx(Box, { sx: {
104
+ display: 'grid',
105
+ gap: 3,
106
+ gridTemplateColumns: [
107
+ '1fr',
108
+ 'repeat(2, 1fr)',
109
+ 'repeat(3, 1fr)',
110
+ ],
111
+ }, children: MCP_CLIENTS.map(client => (_jsxs(Box, { sx: {
112
+ p: 3,
113
+ border: '1px solid',
114
+ borderColor: 'border.default',
115
+ borderRadius: 2,
116
+ display: 'grid',
117
+ gap: 2,
118
+ minWidth: 0,
119
+ }, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'semibold' }, children: client.name }), _jsx(Copyable, { text: mcpSetupCommand(client.setup) }), _jsx(Link, { href: `${clientDocsBase}/${client.setup}`, sx: { fontSize: 0, cursor: 'pointer', textAlign: 'left' }, onClick: event => {
120
+ // A modified click is the reader asking for a new tab or
121
+ // window, and `href` is real so it still leads to the
122
+ // full page — for that, for the status bar and for the
123
+ // context menu.
124
+ if (event.metaKey || event.ctrlKey || event.shiftKey) {
125
+ return;
126
+ }
127
+ event.preventDefault();
128
+ onOpenDocs(`${clientDocsBase}/${client.setup}`);
129
+ }, children: "Configuration and authorization" })] }, client.setup))) })] })] })), showSummaries && (_jsxs(Box, { sx: {
130
+ display: 'grid',
131
+ gap: 3,
132
+ gridTemplateColumns: ['1fr', 'repeat(2, 1fr)', 'repeat(3, 1fr)'],
133
+ }, children: [_jsx(Summary, { icon: PlugIcon, title: "Agents", action: {
134
+ label: 'Connected agents',
135
+ onClick: () => navigate(routes.agents),
136
+ }, children: connected.length === 0 ? (_jsx(Text, { children: "No agent has been authorized yet. Set up a client above and approve the scopes it asks for." })) : (_jsxs(_Fragment, { children: [_jsxs(Text, { children: [plural(connected.length, 'agent'), " authorized."] }), connected.slice(0, 3).map(agent => (_jsxs(Text, { children: [agent.clientName || agent.clientId, " \u2014", ' ', agent.lastUsedAt
137
+ ? `used ${timeAgo(agent.lastUsedAt)}`
138
+ : 'never used'] }, agent.uid)))] })) }), _jsx(Summary, { icon: PulseIcon, title: "Runs", action: { label: 'All runs', onClick: () => navigate(routes.runs) }, children: runs.length === 0 ? (_jsx(Text, { children: "Nothing has run yet. A tool call that outlives its request becomes a run you can watch and cancel." })) : (runs.map(task => (_jsxs(Text, { children: [task.tool, " \u2014 ", task.status, " ", timeAgo(task.lastUpdatedAt)] }, task.uid)))) }), _jsxs(Summary, { icon: TelescopeIcon, title: "Observability", action: {
139
+ label: 'Runs and metrics',
140
+ onClick: () => navigate(routes.observability),
141
+ }, children: [_jsx(Text, { children: metrics.data?.slis.samples.calls
142
+ ? `${plural(metrics.data.slis.samples.calls, 'call')} measured.`
143
+ : 'No call measured yet.' }), _jsx(Text, { children: metrics.data?.slis.p95CallDurationMs
144
+ ? `p95 ${Math.round(metrics.data.slis.p95CallDurationMs)}ms`
145
+ : 'Latency not measured yet.' }), _jsx(Text, { children: metrics.data?.slis.availability === null ||
146
+ metrics.data?.slis.availability === undefined
147
+ ? 'Error rate not measured yet.'
148
+ : `${((1 - metrics.data.slis.availability) * 100).toFixed(1)}% of calls failed.` })] }), _jsx(Summary, { icon: ToolsIcon, title: "Tools", children: _jsx(Text, { children: "The toolsets an agent may execute \u2014 the Contents sources you have enabled for it, their tools, their approval policy and their health \u2014 are managed here once toolset bindings ship." }) }), _jsx(Summary, { icon: ShareIcon, title: "Reach", children: _jsx(Text, { children: "Which notebooks and sources an agent can actually reach, as a list you can read at a glance, arrives with sharing to agents as principals." }) }), _jsx(Summary, { icon: KeyIcon, title: "Policies", action: {
149
+ label: 'What applies',
150
+ onClick: () => navigate(routes.policies),
151
+ }, children: _jsx(Text, { children: "What your agents are allowed to do, and which layer decided each rule." }) })] }))] }));
152
+ };
153
+ export default McpHome;
@@ -0,0 +1,50 @@
1
+ /**
2
+ * How a call ran, as opposed to whether it was allowed.
3
+ *
4
+ * Two panes over the Datalayer OTEL service, read directly with the
5
+ * caller's token: **Runs**, the span tree of one call across the gateway,
6
+ * the policy check and the worker, with the durations that matter called
7
+ * out; and **Metrics**, the four service level indicators and the metric
8
+ * catalog for the caller's agents or, for an owner, the organization.
9
+ *
10
+ * There is no gateway route behind this and no second store: the gateway
11
+ * exports spans, metrics and logs through the collector the platform
12
+ * already runs, and this page queries that. Which is exactly why the page
13
+ * says on itself that it is telemetry — short retention, sampled, no
14
+ * security claim. The audit log is the trail that answers "was this
15
+ * allowed", and every pane links to it.
16
+ *
17
+ * Milestone 1 draws the two panes over synchronous calls. The workflow
18
+ * steps and sandbox spans of a durable task, and the live stream of calls
19
+ * as they land, arrive with milestone 2.
20
+ *
21
+ * @module views/mcp/McpObservability
22
+ */
23
+ import type { JSX } from 'react';
24
+ import { type McpErrorStateFn, type McpRoutes } from './types';
25
+ export type McpObservabilityPane = 'runs' | 'metrics';
26
+ export interface McpObservabilityProps {
27
+ /** The application's words for a failed request. */
28
+ errorState: McpErrorStateFn;
29
+ /** Where this application puts the surfaces this view links to. */
30
+ routes: McpRoutes;
31
+ /** Which pane is open; the address owns it. */
32
+ pane: McpObservabilityPane;
33
+ onPaneChange: (pane: McpObservabilityPane) => void;
34
+ /** The run to open, when the address names one. */
35
+ taskUid?: string;
36
+ /** The trace to open — what a synchronous call leaves behind. */
37
+ traceId?: string;
38
+ /** Asked to write a new selection into the address. */
39
+ onSelect: (selection: {
40
+ task?: string;
41
+ trace?: string;
42
+ }) => void;
43
+ /** One agent's reading, rather than every agent of the caller. */
44
+ agent?: string;
45
+ /** An owner's reading of one organization. */
46
+ org?: string;
47
+ showTitle?: boolean;
48
+ }
49
+ export declare const McpObservability: ({ errorState, routes, pane, onPaneChange, taskUid, traceId, onSelect, agent, org, showTitle, }: McpObservabilityProps) => JSX.Element;
50
+ export default McpObservability;