@datalayer/core 1.2.12 → 1.2.14
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.
- package/README.md +4 -4
- package/lib/api/contents/datasets.d.ts +1 -32
- package/lib/api/contents/generated.d.ts +50 -2
- package/lib/api/iam/organizationPlugins.d.ts +8 -0
- package/lib/api/iam/organizationPlugins.js +41 -0
- package/lib/api/iam/servicePrincipals.d.ts +30 -0
- package/lib/api/iam/servicePrincipals.js +87 -0
- package/lib/components/avatars/UserAvatar.d.ts +2 -1
- package/lib/components/avatars/UserAvatar.js +2 -3
- package/lib/components/emoji/FluentEmoji.d.ts +33 -0
- package/lib/components/emoji/FluentEmoji.js +66 -0
- package/lib/components/emoji/faceEmojis.d.ts +24 -0
- package/lib/components/emoji/faceEmojis.js +178 -0
- package/lib/components/emoji/fluent/loaders.d.ts +12 -0
- package/lib/components/emoji/fluent/loaders.js +152 -0
- package/lib/components/emoji/fluent/svg/1f304.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f304.js +5 -0
- package/lib/components/emoji/fluent/svg/1f308.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f308.js +5 -0
- package/lib/components/emoji/fluent/svg/1f30d.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f30d.js +5 -0
- package/lib/components/emoji/fluent/svg/1f31f.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f31f.js +5 -0
- package/lib/components/emoji/fluent/svg/1f331.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f331.js +5 -0
- package/lib/components/emoji/fluent/svg/1f340.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f340.js +5 -0
- package/lib/components/emoji/fluent/svg/1f355.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f355.js +5 -0
- package/lib/components/emoji/fluent/svg/1f381.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f381.js +5 -0
- package/lib/components/emoji/fluent/svg/1f385.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f385.js +5 -0
- package/lib/components/emoji/fluent/svg/1f386.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f386.js +5 -0
- package/lib/components/emoji/fluent/svg/1f387.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f387.js +5 -0
- package/lib/components/emoji/fluent/svg/1f389.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f389.js +5 -0
- package/lib/components/emoji/fluent/svg/1f393.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f393.js +5 -0
- package/lib/components/emoji/fluent/svg/1f399.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f399.js +5 -0
- package/lib/components/emoji/fluent/svg/1f3a8.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f3a8.js +5 -0
- package/lib/components/emoji/fluent/svg/1f3ac.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f3ac.js +5 -0
- package/lib/components/emoji/fluent/svg/1f3af.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f3af.js +5 -0
- package/lib/components/emoji/fluent/svg/1f3b5.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f3b5.js +5 -0
- package/lib/components/emoji/fluent/svg/1f3c4.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f3c4.js +5 -0
- package/lib/components/emoji/fluent/svg/1f3c6.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f3c6.js +5 -0
- package/lib/components/emoji/fluent/svg/1f3ca.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f3ca.js +5 -0
- package/lib/components/emoji/fluent/svg/1f3d7.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f3d7.js +5 -0
- package/lib/components/emoji/fluent/svg/1f3db.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f3db.js +5 -0
- package/lib/components/emoji/fluent/svg/1f3e0.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f3e0.js +5 -0
- package/lib/components/emoji/fluent/svg/1f3e2.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f3e2.js +5 -0
- package/lib/components/emoji/fluent/svg/1f3e5.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f3e5.js +5 -0
- package/lib/components/emoji/fluent/svg/1f3e6.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f3e6.js +5 -0
- package/lib/components/emoji/fluent/svg/1f3f7.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f3f7.js +5 -0
- package/lib/components/emoji/fluent/svg/1f409.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f409.js +5 -0
- package/lib/components/emoji/fluent/svg/1f419.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f419.js +5 -0
- package/lib/components/emoji/fluent/svg/1f41d.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f41d.js +5 -0
- package/lib/components/emoji/fluent/svg/1f427.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f427.js +5 -0
- package/lib/components/emoji/fluent/svg/1f431.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f431.js +5 -0
- package/lib/components/emoji/fluent/svg/1f432.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f432.js +5 -0
- package/lib/components/emoji/fluent/svg/1f433.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f433.js +5 -0
- package/lib/components/emoji/fluent/svg/1f436.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f436.js +5 -0
- package/lib/components/emoji/fluent/svg/1f440.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f440.js +5 -0
- package/lib/components/emoji/fluent/svg/1f44b.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f44b.js +5 -0
- package/lib/components/emoji/fluent/svg/1f450.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f450.js +5 -0
- package/lib/components/emoji/fluent/svg/1f477.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f477.js +5 -0
- package/lib/components/emoji/fluent/svg/1f47d.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f47d.js +5 -0
- package/lib/components/emoji/fluent/svg/1f47e.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f47e.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4a1.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4a1.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4ac.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4ac.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4b0.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4b0.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4b3.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4b3.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4bc.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4bc.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4c5.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4c5.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4c8.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4c8.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4ca.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4ca.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4cb.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4cb.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4cc.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4cc.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4d1.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4d1.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4da.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4da.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4dd.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4dd.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4de.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4de.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4e3.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4e3.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4e6.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4e6.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4ec.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4ec.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4f0.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4f0.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4f7.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4f7.js +5 -0
- package/lib/components/emoji/fluent/svg/1f50d.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f50d.js +5 -0
- package/lib/components/emoji/fluent/svg/1f50e.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f50e.js +5 -0
- package/lib/components/emoji/fluent/svg/1f511.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f511.js +5 -0
- package/lib/components/emoji/fluent/svg/1f512.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f512.js +5 -0
- package/lib/components/emoji/fluent/svg/1f514.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f514.js +5 -0
- package/lib/components/emoji/fluent/svg/1f525.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f525.js +5 -0
- package/lib/components/emoji/fluent/svg/1f527.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f527.js +5 -0
- package/lib/components/emoji/fluent/svg/1f52c.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f52c.js +5 -0
- package/lib/components/emoji/fluent/svg/1f58a.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f58a.js +5 -0
- package/lib/components/emoji/fluent/svg/1f5bc.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f5bc.js +5 -0
- package/lib/components/emoji/fluent/svg/1f5c2.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f5c2.js +5 -0
- package/lib/components/emoji/fluent/svg/1f5d3.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f5d3.js +5 -0
- package/lib/components/emoji/fluent/svg/1f5fa.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f5fa.js +5 -0
- package/lib/components/emoji/fluent/svg/1f600.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f600.js +5 -0
- package/lib/components/emoji/fluent/svg/1f60e.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f60e.js +5 -0
- package/lib/components/emoji/fluent/svg/1f642.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f642.js +5 -0
- package/lib/components/emoji/fluent/svg/1f680.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f680.js +5 -0
- package/lib/components/emoji/fluent/svg/1f69a.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f69a.js +5 -0
- package/lib/components/emoji/fluent/svg/1f6a2.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f6a2.js +5 -0
- package/lib/components/emoji/fluent/svg/1f6a7.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f6a7.js +5 -0
- package/lib/components/emoji/fluent/svg/1f6b2.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f6b2.js +5 -0
- package/lib/components/emoji/fluent/svg/1f6d2.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f6d2.js +5 -0
- package/lib/components/emoji/fluent/svg/1f6df.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f6df.js +5 -0
- package/lib/components/emoji/fluent/svg/1f6e0.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f6e0.js +5 -0
- package/lib/components/emoji/fluent/svg/1f6e1.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f6e1.js +5 -0
- package/lib/components/emoji/fluent/svg/1f6eb.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f6eb.js +5 -0
- package/lib/components/emoji/fluent/svg/1f6f0.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f6f0.js +5 -0
- package/lib/components/emoji/fluent/svg/1f6f8.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f6f8.js +5 -0
- package/lib/components/emoji/fluent/svg/1f913.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f913.js +5 -0
- package/lib/components/emoji/fluent/svg/1f916.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f916.js +5 -0
- package/lib/components/emoji/fluent/svg/1f91d.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f91d.js +5 -0
- package/lib/components/emoji/fluent/svg/1f920.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f920.js +5 -0
- package/lib/components/emoji/fluent/svg/1f977.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f977.js +5 -0
- package/lib/components/emoji/fluent/svg/1f984.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f984.js +5 -0
- package/lib/components/emoji/fluent/svg/1f988.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f988.js +5 -0
- package/lib/components/emoji/fluent/svg/1f989.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f989.js +5 -0
- package/lib/components/emoji/fluent/svg/1f98a.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f98a.js +5 -0
- package/lib/components/emoji/fluent/svg/1f98e.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f98e.js +5 -0
- package/lib/components/emoji/fluent/svg/1f9d0.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f9d0.js +5 -0
- package/lib/components/emoji/fluent/svg/1f9d1-200d-1f33e.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f9d1-200d-1f33e.js +5 -0
- package/lib/components/emoji/fluent/svg/1f9d1-200d-1f373.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f9d1-200d-1f373.js +5 -0
- package/lib/components/emoji/fluent/svg/1f9d1-200d-1f393.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f9d1-200d-1f393.js +5 -0
- package/lib/components/emoji/fluent/svg/1f9d1-200d-1f3eb.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f9d1-200d-1f3eb.js +5 -0
- package/lib/components/emoji/fluent/svg/1f9d1-200d-1f4bb.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f9d1-200d-1f4bb.js +5 -0
- package/lib/components/emoji/fluent/svg/1f9d1-200d-1f4bc.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f9d1-200d-1f4bc.js +5 -0
- package/lib/components/emoji/fluent/svg/1f9d1-200d-1f52c.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f9d1-200d-1f52c.js +5 -0
- package/lib/components/emoji/fluent/svg/1f9d1-200d-1f680.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f9d1-200d-1f680.js +5 -0
- package/lib/components/emoji/fluent/svg/1f9d1-200d-2695.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f9d1-200d-2695.js +5 -0
- package/lib/components/emoji/fluent/svg/1f9dd.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f9dd.js +5 -0
- package/lib/components/emoji/fluent/svg/1f9e0.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f9e0.js +5 -0
- package/lib/components/emoji/fluent/svg/1f9e9.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f9e9.js +5 -0
- package/lib/components/emoji/fluent/svg/1f9ea.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f9ea.js +5 -0
- package/lib/components/emoji/fluent/svg/1f9ec.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f9ec.js +5 -0
- package/lib/components/emoji/fluent/svg/1f9ed.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f9ed.js +5 -0
- package/lib/components/emoji/fluent/svg/1f9ee.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f9ee.js +5 -0
- package/lib/components/emoji/fluent/svg/1f9f0.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f9f0.js +5 -0
- package/lib/components/emoji/fluent/svg/1f9f9.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f9f9.js +5 -0
- package/lib/components/emoji/fluent/svg/1f9fe.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f9fe.js +5 -0
- package/lib/components/emoji/fluent/svg/1fa84.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1fa84.js +5 -0
- package/lib/components/emoji/fluent/svg/1fa90.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1fa90.js +5 -0
- package/lib/components/emoji/fluent/svg/23f0.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/23f0.js +5 -0
- package/lib/components/emoji/fluent/svg/2600.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/2600.js +5 -0
- package/lib/components/emoji/fluent/svg/2601.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/2601.js +5 -0
- package/lib/components/emoji/fluent/svg/2603.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/2603.js +5 -0
- package/lib/components/emoji/fluent/svg/2615.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/2615.js +5 -0
- package/lib/components/emoji/fluent/svg/262f.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/262f.js +5 -0
- package/lib/components/emoji/fluent/svg/2696.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/2696.js +5 -0
- package/lib/components/emoji/fluent/svg/2699.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/2699.js +5 -0
- package/lib/components/emoji/fluent/svg/269b.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/269b.js +5 -0
- package/lib/components/emoji/fluent/svg/26a1.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/26a1.js +5 -0
- package/lib/components/emoji/fluent/svg/2705.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/2705.js +5 -0
- package/lib/components/emoji/fluent/svg/2709.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/2709.js +5 -0
- package/lib/components/emoji/fluent/svg/270d.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/270d.js +5 -0
- package/lib/components/emoji/fluent/svg/2712.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/2712.js +5 -0
- package/lib/components/emoji/fluent/svg/2764.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/2764.js +5 -0
- package/lib/components/emoji/fluent/svg/2b50.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/2b50.js +5 -0
- package/lib/components/emoji/index.d.ts +3 -0
- package/lib/components/emoji/index.js +7 -0
- package/lib/components/principal/PrincipalAppearance.d.ts +7 -1
- package/lib/components/principal/PrincipalAvatar.js +3 -1
- package/lib/components/principal/PrincipalDetailsOverlay.d.ts +2 -1
- package/lib/components/principal/PrincipalDetailsOverlay.js +4 -0
- package/lib/hooks/index.d.ts +1 -0
- package/lib/hooks/index.js +1 -0
- package/lib/hooks/useCache.d.ts +25 -0
- package/lib/hooks/useCache.js +147 -9
- package/lib/hooks/useContents.js +3 -0
- package/lib/hooks/useOrganizationPlugins.d.ts +4 -0
- package/lib/hooks/useOrganizationPlugins.js +37 -0
- package/lib/hooks/usePrincipalCacheStore.d.ts +1 -1
- package/lib/hooks/usePrincipalCacheStore.js +3 -1
- package/lib/models/URN.d.ts +37 -0
- package/lib/models/URN.js +59 -1
- package/lib/state/substates/NavigationState.d.ts +29 -2
- package/lib/state/substates/NavigationState.js +103 -12
- package/lib/utils/Handles.js +1 -1
- package/lib/views/mcp/McpDashboard.js +15 -10
- package/lib/views/mcp/McpHome.js +14 -6
- package/lib/views/mcp/types.d.ts +4 -0
- package/package.json +6 -6
- package/scripts/generate-fluent-emoji.py +188 -0
|
@@ -33,9 +33,14 @@ import { createStore } from 'zustand/vanilla';
|
|
|
33
33
|
import { registerSessionState } from '../sessionEnd.js';
|
|
34
34
|
/** The shells, and where each one opens when it has not been visited. */
|
|
35
35
|
export const NAVIGATION_VIEW_HOMES = {
|
|
36
|
-
|
|
36
|
+
studio: '/studio',
|
|
37
|
+
// Not `/`: the root is the Studio's, so the Power shell has an address of
|
|
38
|
+
// its own to be sent to.
|
|
39
|
+
home: '/power',
|
|
37
40
|
agentify: '/agentify',
|
|
38
41
|
admin: '/admin',
|
|
42
|
+
// The applications: what a builder opens LOOP for.
|
|
43
|
+
loop: '/loop/apps',
|
|
39
44
|
};
|
|
40
45
|
/** Well-known view identifiers for {@link NavigationState.tabsByView}. */
|
|
41
46
|
export const LIBRARY_VIEW = 'library';
|
|
@@ -50,7 +55,11 @@ const SHELL_COOKIE = 'datalayer-signed-in-view';
|
|
|
50
55
|
const FORMER_TABS_KEY = 'datalayer_view_tabs';
|
|
51
56
|
/** Days a remembered shell lives in the cookie. */
|
|
52
57
|
const COOKIE_MAX_AGE_DAYS = 365;
|
|
53
|
-
const isView = (value) => value === '
|
|
58
|
+
const isView = (value) => value === 'studio' ||
|
|
59
|
+
value === 'home' ||
|
|
60
|
+
value === 'agentify' ||
|
|
61
|
+
value === 'admin' ||
|
|
62
|
+
value === 'loop';
|
|
54
63
|
function readCookie(name) {
|
|
55
64
|
if (typeof document === 'undefined') {
|
|
56
65
|
return undefined;
|
|
@@ -90,7 +99,8 @@ function restore() {
|
|
|
90
99
|
const parsed = JSON.parse(stored);
|
|
91
100
|
// The landing kept this under the same key through zustand's
|
|
92
101
|
// `persist`, which wraps what it writes in `{ state, version }`.
|
|
93
|
-
|
|
102
|
+
const kept = parsed?.state ?? parsed;
|
|
103
|
+
persisted = kept && typeof kept === 'object' ? kept : {};
|
|
94
104
|
}
|
|
95
105
|
catch {
|
|
96
106
|
persisted = {};
|
|
@@ -112,8 +122,32 @@ function restore() {
|
|
|
112
122
|
if (isView(shell)) {
|
|
113
123
|
persisted.view = shell;
|
|
114
124
|
}
|
|
125
|
+
persisted.lastRouteByView = restoredRoutes(persisted.lastRouteByView);
|
|
115
126
|
return persisted;
|
|
116
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* The shells' pages as they were written down, less the ones no shell
|
|
130
|
+
* returns to.
|
|
131
|
+
*
|
|
132
|
+
* What is in storage was written by whichever version ran last, under that
|
|
133
|
+
* version's rules. Before the Power shell had an address of its own, its
|
|
134
|
+
* page could be the root — which is now the Studio's, and would send Power
|
|
135
|
+
* to the Studio — and an earlier version filed pages under the shell the
|
|
136
|
+
* toggle named. Such a page is dropped here rather than carried, so the next
|
|
137
|
+
* write does not put it back.
|
|
138
|
+
*/
|
|
139
|
+
function restoredRoutes(stored) {
|
|
140
|
+
const routes = {};
|
|
141
|
+
if (!stored || typeof stored !== 'object') {
|
|
142
|
+
return routes;
|
|
143
|
+
}
|
|
144
|
+
for (const [view, route] of Object.entries(stored)) {
|
|
145
|
+
if (isView(view) && isRouteOfView(route, view)) {
|
|
146
|
+
routes[view] = route;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return routes;
|
|
150
|
+
}
|
|
117
151
|
function persist(state) {
|
|
118
152
|
const written = {
|
|
119
153
|
view: state.view,
|
|
@@ -128,6 +162,18 @@ function persist(state) {
|
|
|
128
162
|
}
|
|
129
163
|
writeCookie(SHELL_COOKIE, state.view);
|
|
130
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* The path of a route: what is before its query and its fragment.
|
|
167
|
+
*
|
|
168
|
+
* A route is what the reader was at — `/settings/profile?tab=keys#tokens` —
|
|
169
|
+
* and the shell it belongs to is decided by its path alone. Cutting only at
|
|
170
|
+
* `?` left a fragment attached, so `/settings#profile` was not `/settings`:
|
|
171
|
+
* it read as a shell's own page and moved the shell.
|
|
172
|
+
*/
|
|
173
|
+
function pathOf(route) {
|
|
174
|
+
const end = route.search(/[?#]/);
|
|
175
|
+
return end === -1 ? route : route.slice(0, end);
|
|
176
|
+
}
|
|
131
177
|
/**
|
|
132
178
|
* Whether a page is worth remembering as a shell's.
|
|
133
179
|
*
|
|
@@ -139,17 +185,30 @@ export function isRememberableRoute(route) {
|
|
|
139
185
|
if (!route.startsWith('/')) {
|
|
140
186
|
return false;
|
|
141
187
|
}
|
|
142
|
-
const path = route
|
|
143
|
-
return ![
|
|
188
|
+
const path = pathOf(route);
|
|
189
|
+
return (![
|
|
144
190
|
'/signin',
|
|
145
191
|
'/signup',
|
|
146
192
|
'/login',
|
|
147
193
|
'/logout',
|
|
148
194
|
'/oauth2',
|
|
149
195
|
'/oauth',
|
|
150
|
-
'/docs',
|
|
151
196
|
'/join',
|
|
152
|
-
].some(prefix => path === prefix || path.startsWith(`${prefix}/`))
|
|
197
|
+
].some(prefix => path === prefix || path.startsWith(`${prefix}/`)) &&
|
|
198
|
+
!isShellNeutralRoute(route));
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Whether a page belongs to no shell: the settings, the documentation and
|
|
202
|
+
* the decks.
|
|
203
|
+
*
|
|
204
|
+
* They are read from whichever shell the reader is in — its sidebar stays
|
|
205
|
+
* beside them and the header's selector does not move — so they are never a
|
|
206
|
+
* shell's own page: opening one does not change the shell, and no shell
|
|
207
|
+
* returns to one.
|
|
208
|
+
*/
|
|
209
|
+
export function isShellNeutralRoute(route) {
|
|
210
|
+
const path = pathOf(route);
|
|
211
|
+
return ['/settings', '/docs', '/decks'].some(prefix => path === prefix || path.startsWith(`${prefix}/`));
|
|
153
212
|
}
|
|
154
213
|
/**
|
|
155
214
|
* The shell a route belongs to, read off its first segment.
|
|
@@ -159,20 +218,51 @@ export function isRememberableRoute(route) {
|
|
|
159
218
|
* reached Home through a sidebar link while the toggle still said Agentify
|
|
160
219
|
* had their Home pages filed under Agentify — and the toggle, seeing
|
|
161
220
|
* "Agentify" already chosen, did nothing when they clicked it.
|
|
221
|
+
*
|
|
222
|
+
* A shell-neutral page (the settings, the documentation) has no shell of its
|
|
223
|
+
* own: given the shell the reader is in (`current`), that is the answer, so
|
|
224
|
+
* the sidebar and the header stay where they were. Without it the settings
|
|
225
|
+
* read as the Studio's and the documentation as Power's, as they once were.
|
|
162
226
|
*/
|
|
163
|
-
export function viewForRoute(route) {
|
|
164
|
-
const path = route
|
|
227
|
+
export function viewForRoute(route, current) {
|
|
228
|
+
const path = pathOf(route);
|
|
229
|
+
if (current && isShellNeutralRoute(route)) {
|
|
230
|
+
return current;
|
|
231
|
+
}
|
|
232
|
+
// The root is the Studio: what a signed-in reader opens on. The settings
|
|
233
|
+
// are read from it too, with its sidebar beside them — and so is the
|
|
234
|
+
// agentspecs catalogue, the specs an app is composed from.
|
|
235
|
+
if (path === '/' ||
|
|
236
|
+
path === '/studio' ||
|
|
237
|
+
path.startsWith('/studio/') ||
|
|
238
|
+
path === '/settings' ||
|
|
239
|
+
path.startsWith('/settings/') ||
|
|
240
|
+
path === '/agentspecs' ||
|
|
241
|
+
path.startsWith('/agentspecs/')) {
|
|
242
|
+
return 'studio';
|
|
243
|
+
}
|
|
165
244
|
if (path === '/agentify' || path.startsWith('/agentify/')) {
|
|
166
245
|
return 'agentify';
|
|
167
246
|
}
|
|
168
247
|
if (path === '/admin' || path.startsWith('/admin/')) {
|
|
169
248
|
return 'admin';
|
|
170
249
|
}
|
|
250
|
+
if (path === '/loop' || path.startsWith('/loop/')) {
|
|
251
|
+
return 'loop';
|
|
252
|
+
}
|
|
171
253
|
return 'home';
|
|
172
254
|
}
|
|
255
|
+
/** Whether a page may be the one a shell returns to. */
|
|
256
|
+
function isRouteOfView(route, view) {
|
|
257
|
+
return (typeof route === 'string' &&
|
|
258
|
+
isRememberableRoute(route) &&
|
|
259
|
+
viewForRoute(route) === view);
|
|
260
|
+
}
|
|
173
261
|
const initial = restore();
|
|
174
262
|
export const navigationStore = createStore((set, get) => ({
|
|
175
|
-
|
|
263
|
+
// The Studio, for a reader who never chose: a cookie from before it
|
|
264
|
+
// existed says `home`, and is honoured.
|
|
265
|
+
view: initial.view ?? 'studio',
|
|
176
266
|
lastRouteByView: initial.lastRouteByView ?? {},
|
|
177
267
|
tabsByView: initial.tabsByView ?? {},
|
|
178
268
|
requestedRoute: undefined,
|
|
@@ -210,9 +300,10 @@ export const navigationStore = createStore((set, get) => ({
|
|
|
210
300
|
// Only a page of that shell: an earlier version filed pages under the
|
|
211
301
|
// shell the toggle named rather than the one the route belonged to, so a
|
|
212
302
|
// reader can still have `/items` written down as Agentify's page. Going
|
|
213
|
-
// "to Agentify" must never land on a Home page
|
|
303
|
+
// "to Agentify" must never land on a Home page — nor Power on the root,
|
|
304
|
+
// which was its page before it had `/power` and is now the Studio's.
|
|
214
305
|
const remembered = get().lastRouteByView[view];
|
|
215
|
-
return
|
|
306
|
+
return isRouteOfView(remembered, view)
|
|
216
307
|
? remembered
|
|
217
308
|
: NAVIGATION_VIEW_HOMES[view];
|
|
218
309
|
},
|
package/lib/utils/Handles.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
3
|
* Distributed under the terms of the Modified BSD License.
|
|
4
4
|
*/
|
|
5
|
-
|
|
5
|
+
import { IAM_PROVIDER_URN_PREFIX as EXT_URN_PREFIX } from '../models/URN.js';
|
|
6
6
|
export function isExternalUrnHandle(handle) {
|
|
7
7
|
const normalized = (handle || '').trim().toLowerCase();
|
|
8
8
|
return normalized.startsWith(EXT_URN_PREFIX);
|
|
@@ -3,7 +3,7 @@ import { useMemo, useRef, useState } from 'react';
|
|
|
3
3
|
import { ActionList, ActionMenu, Button, Heading, Label, Link, RelativeTime, Select, Spinner, Text, } from '@primer/react';
|
|
4
4
|
import { Blankslate, DataTable, Dialog, Table, } from '@primer/react/experimental';
|
|
5
5
|
import { Box } from '@datalayer/primer-addons';
|
|
6
|
-
import { ChecklistIcon, KebabHorizontalIcon, PlayIcon, PlugIcon, StackIcon,
|
|
6
|
+
import { ChecklistIcon, KebabHorizontalIcon, PlayIcon, PlugIcon, StackIcon, } from '@primer/octicons-react';
|
|
7
7
|
import { ShareAccessDialog, sandboxSharingUrl } from '../../components/sharing/index.js';
|
|
8
8
|
import { ClientBadge, McpErrorBlankslate } from '../../components/mcp/index.js';
|
|
9
9
|
import { useDisconnectAgent, useMcpActivity, useTerminateBinding, } from '../../hooks/useMcp.js';
|
|
@@ -54,7 +54,7 @@ const boundTo = (client) => {
|
|
|
54
54
|
return '';
|
|
55
55
|
};
|
|
56
56
|
const countLook = (tone) => tone === 'danger' ? 'danger.fg' : 'fg.default';
|
|
57
|
-
const Count = ({ label, value, tone = 'neutral', note, }) => (_jsxs(Box, { sx: {
|
|
57
|
+
const Count = ({ label, value, tone = 'neutral', note, to, onOpen, }) => (_jsxs(Box, { sx: {
|
|
58
58
|
p: 3,
|
|
59
59
|
border: '1px solid',
|
|
60
60
|
borderColor: 'border.default',
|
|
@@ -66,7 +66,14 @@ const Count = ({ label, value, tone = 'neutral', note, }) => (_jsxs(Box, { sx: {
|
|
|
66
66
|
fontSize: 4,
|
|
67
67
|
fontWeight: 'bold',
|
|
68
68
|
color: countLook(tone),
|
|
69
|
-
}, children: value }),
|
|
69
|
+
}, children: value }), to ? (_jsx(Link, { href: to, onClick: (event) => {
|
|
70
|
+
// A modified click asks for a new tab; `href` is real, so let it.
|
|
71
|
+
if (event.metaKey || event.ctrlKey || event.shiftKey) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
event.preventDefault();
|
|
75
|
+
onOpen?.(to);
|
|
76
|
+
}, sx: { display: 'block', fontSize: 0 }, children: label })) : (_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 }))] }));
|
|
70
77
|
/** A panel that has nothing to show, and the step that would fill it. */
|
|
71
78
|
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 }))] }));
|
|
72
79
|
export const McpDashboard = ({ errorState, routes, org, showTitle = true, section, }) => {
|
|
@@ -379,7 +386,10 @@ export const McpDashboard = ({ errorState, routes, org, showTitle = true, sectio
|
|
|
379
386
|
'repeat(3, 1fr)',
|
|
380
387
|
'repeat(6, 1fr)',
|
|
381
388
|
],
|
|
382
|
-
}, 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"
|
|
389
|
+
}, children: [_jsx(Count, { label: "Clients connected", value: clients.length, to: routes.agents, onOpen: navigate }), _jsx(Count, { label: "Sandboxes bound", to: routes.sandboxes, onOpen: navigate, value: sandboxes.filter(binding => (binding.state ?? 'active') === 'active').length }), _jsx(Count, { label: "Tasks running", value: data?.tasks.length ?? 0, to: routes.runs, onOpen: navigate }), _jsx(Count, { label: "Calls today", value: data?.today.calls ?? 0, to: routes.calls, onOpen: navigate }), _jsx(Count, { label: "Refusals today", value: data?.today.refusals ?? 0, to: routes.audit, onOpen: navigate, tone: (data?.today.refusals ?? 0) > 0 ? 'danger' : 'neutral' }), _jsx(Count, { label: "Credits by agents", value: data?.today.credits ?? 0, note: "today",
|
|
390
|
+
// Credits are summed from the day's calls, which the Calls tab
|
|
391
|
+
// lists.
|
|
392
|
+
to: routes.calls, onOpen: navigate })] }))), draws('agents') &&
|
|
383
393
|
!loading &&
|
|
384
394
|
(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: {
|
|
385
395
|
label: 'Set up a client',
|
|
@@ -396,12 +406,7 @@ export const McpDashboard = ({ errorState, routes, org, showTitle = true, sectio
|
|
|
396
406
|
}, 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: {
|
|
397
407
|
label: 'Open the audit log',
|
|
398
408
|
onClick: () => navigate(routes.audit),
|
|
399
|
-
} }))),
|
|
400
|
-
display: 'flex',
|
|
401
|
-
gap: 3,
|
|
402
|
-
alignItems: 'center',
|
|
403
|
-
flexWrap: 'wrap',
|
|
404
|
-
}, 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: [
|
|
409
|
+
} }))), disconnecting && (_jsx(Dialog, { title: "Disconnect this client?", onClose: () => setDisconnecting(null), returnFocusRef: returnFocusRef, footerButtons: [
|
|
405
410
|
{
|
|
406
411
|
buttonType: 'default',
|
|
407
412
|
content: 'Keep it',
|
package/lib/views/mcp/McpHome.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from 'react';
|
|
3
|
+
import { AiAgentIcon } from '@datalayer/icons-react';
|
|
3
4
|
import { Button, Heading, IconButton, Link, Text } from '@primer/react';
|
|
4
5
|
import { Box } from '@datalayer/primer-addons';
|
|
5
|
-
import { CheckIcon, CopyIcon, KeyIcon,
|
|
6
|
+
import { CheckIcon, CopyIcon, KeyIcon, PulseIcon, RssIcon, ShieldCheckIcon, TelescopeIcon, ToolsIcon, } from '@primer/octicons-react';
|
|
6
7
|
import { useConnectedAgents, useMcpActivity, useMcpMetrics, useTasks, } from '../../hooks/useMcp.js';
|
|
7
8
|
import { useNavigate } from '../../hooks/index.js';
|
|
8
9
|
import { useCoreStore, useIAMStore } from '../../state/index.js';
|
|
@@ -63,7 +64,7 @@ export const Copyable = ({ text }) => {
|
|
|
63
64
|
} })] }));
|
|
64
65
|
};
|
|
65
66
|
/** 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
|
+
const Summary = ({ icon: Icon, title, children, action, to, onOpen, }) => (_jsxs(Box, { sx: {
|
|
67
68
|
p: 3,
|
|
68
69
|
border: '1px solid',
|
|
69
70
|
borderColor: 'border.default',
|
|
@@ -72,7 +73,14 @@ const Summary = ({ icon: Icon, title, children, action, }) => (_jsxs(Box, { sx:
|
|
|
72
73
|
gap: 2,
|
|
73
74
|
alignContent: 'start',
|
|
74
75
|
minWidth: 0,
|
|
75
|
-
}, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Icon, { size: 16 }),
|
|
76
|
+
}, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Icon, { size: 16 }), to ? (_jsx(Link, { href: to, onClick: event => {
|
|
77
|
+
// A modified click asks for a new tab; `href` is real, so let it.
|
|
78
|
+
if (event.metaKey || event.ctrlKey || event.shiftKey) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
event.preventDefault();
|
|
82
|
+
onOpen?.(to);
|
|
83
|
+
}, sx: { fontSize: 1, fontWeight: 'semibold' }, children: title })) : (_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
84
|
export const McpHome = ({ routes, clientDocsBase = '/docs/mcp-clients', showTitle = true, showSummaries = true, showSetup = true, onOpenDocs, }) => {
|
|
77
85
|
const navigate = useNavigate();
|
|
78
86
|
const endpoint = useCoreStore(state => state.configuration.datalayerMcpServerUrl);
|
|
@@ -130,12 +138,12 @@ export const McpHome = ({ routes, clientDocsBase = '/docs/mcp-clients', showTitl
|
|
|
130
138
|
display: 'grid',
|
|
131
139
|
gap: 3,
|
|
132
140
|
gridTemplateColumns: ['1fr', 'repeat(2, 1fr)', 'repeat(3, 1fr)'],
|
|
133
|
-
}, children: [_jsx(Summary, { icon:
|
|
141
|
+
}, children: [_jsx(Summary, { icon: AiAgentIcon, title: "Agents", to: routes.agents, onOpen: navigate, action: {
|
|
134
142
|
label: 'Connected agents',
|
|
135
143
|
onClick: () => navigate(routes.agents),
|
|
136
144
|
}, 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
145
|
? `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: {
|
|
146
|
+
: 'never used'] }, agent.uid)))] })) }), _jsx(Summary, { icon: PulseIcon, title: "Runs", to: routes.runs, onOpen: navigate, 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", to: routes.observability, onOpen: navigate, action: {
|
|
139
147
|
label: 'Runs and metrics',
|
|
140
148
|
onClick: () => navigate(routes.observability),
|
|
141
149
|
}, children: [_jsx(Text, { children: metrics.data?.slis.samples.calls
|
|
@@ -145,7 +153,7 @@ export const McpHome = ({ routes, clientDocsBase = '/docs/mcp-clients', showTitl
|
|
|
145
153
|
: 'Latency not measured yet.' }), _jsx(Text, { children: metrics.data?.slis.availability === null ||
|
|
146
154
|
metrics.data?.slis.availability === undefined
|
|
147
155
|
? '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:
|
|
156
|
+
: `${((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: RssIcon, 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: ShieldCheckIcon, title: "Policies", to: routes.policies, onOpen: navigate, action: {
|
|
149
157
|
label: 'What applies',
|
|
150
158
|
onClick: () => navigate(routes.policies),
|
|
151
159
|
}, children: _jsx(Text, { children: "What your agents are allowed to do, and which layer decided each rule." }) })] }))] }));
|
package/lib/views/mcp/types.d.ts
CHANGED
|
@@ -63,4 +63,8 @@ export interface McpRoutes {
|
|
|
63
63
|
agents: string;
|
|
64
64
|
/** The effective policy. */
|
|
65
65
|
policies: string;
|
|
66
|
+
/** The calls list, where an Overview count of calls or credits leads. */
|
|
67
|
+
calls?: string;
|
|
68
|
+
/** The bound code sandboxes, where the Overview's sandbox count leads. */
|
|
69
|
+
sandboxes?: string;
|
|
66
70
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datalayer/core",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.14",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"workspaces": [
|
|
6
6
|
".",
|
|
@@ -109,11 +109,11 @@
|
|
|
109
109
|
"rebuild:fresh": "npm run create:patches && npm install && npm run build && npm run clean:cache"
|
|
110
110
|
},
|
|
111
111
|
"dependencies": {
|
|
112
|
-
"@datalayer/design": "^1.0.
|
|
113
|
-
"@datalayer/icons-react": "^1.0.
|
|
114
|
-
"@datalayer/jupyter-lexical": "^
|
|
115
|
-
"@datalayer/jupyter-react": "^2.0.
|
|
116
|
-
"@datalayer/primer-addons": "^1.0.
|
|
112
|
+
"@datalayer/design": "^1.0.3",
|
|
113
|
+
"@datalayer/icons-react": "^1.0.14",
|
|
114
|
+
"@datalayer/jupyter-lexical": "^2.0.18",
|
|
115
|
+
"@datalayer/jupyter-react": "^2.0.18",
|
|
116
|
+
"@datalayer/primer-addons": "^1.0.23",
|
|
117
117
|
"@datalayer/primer-rjsf": "^1.0.3",
|
|
118
118
|
"@fluentui/react": "^8.125.3",
|
|
119
119
|
"@jupyter-widgets/base-manager": "^1.0.12",
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
|
+
# Distributed under the terms of the Modified BSD License.
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
Write the Fluent Emoji drawings of the faces Datalayer offers (LOOP T-20).
|
|
7
|
+
|
|
8
|
+
Reads the emojis between the ``fluent-emoji:start`` and ``fluent-emoji:end``
|
|
9
|
+
markers of ``src/components/emoji/faceEmojis.ts``, finds each in Microsoft's
|
|
10
|
+
Fluent Emoji (MIT) at a pinned commit by the unicode its metadata gives, and
|
|
11
|
+
writes its *Flat* drawing as a module of its own under
|
|
12
|
+
``src/components/emoji/fluent/svg/`` -- fetched on first draw, from
|
|
13
|
+
Datalayer's own bundle -- with ``loaders.ts`` naming them all and the licence
|
|
14
|
+
beside them. An emoji Fluent does not draw stops the script.
|
|
15
|
+
|
|
16
|
+
Run from the repository's root::
|
|
17
|
+
|
|
18
|
+
python scripts/generate-fluent-emoji.py [--cache DIR]
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
import argparse
|
|
24
|
+
import concurrent.futures
|
|
25
|
+
import json
|
|
26
|
+
import re
|
|
27
|
+
import urllib.parse
|
|
28
|
+
import urllib.request
|
|
29
|
+
from pathlib import Path
|
|
30
|
+
|
|
31
|
+
REPO = "microsoft/fluentui-emoji"
|
|
32
|
+
COMMIT = "1ffb34c752ecf5d402f04cfb4b392c77f57c54bc"
|
|
33
|
+
RAW = f"https://raw.githubusercontent.com/{REPO}/{COMMIT}/"
|
|
34
|
+
TREE = f"https://api.github.com/repos/{REPO}/git/trees/{COMMIT}?recursive=1"
|
|
35
|
+
|
|
36
|
+
ROOT = Path(__file__).resolve().parent.parent
|
|
37
|
+
LIST = ROOT / "src/components/emoji/faceEmojis.ts"
|
|
38
|
+
OUT = ROOT / "src/components/emoji/fluent"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def fetch(url: str) -> bytes:
|
|
42
|
+
"""
|
|
43
|
+
Fetch a URL of GitHub's.
|
|
44
|
+
|
|
45
|
+
Parameters
|
|
46
|
+
----------
|
|
47
|
+
url : str
|
|
48
|
+
The URL, at the pinned commit.
|
|
49
|
+
|
|
50
|
+
Returns
|
|
51
|
+
-------
|
|
52
|
+
bytes
|
|
53
|
+
Its body.
|
|
54
|
+
"""
|
|
55
|
+
with urllib.request.urlopen(url, timeout=60) as response: # nosec B310
|
|
56
|
+
return response.read()
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def cached(cache: Path | None, name: str, url: str) -> bytes:
|
|
60
|
+
"""
|
|
61
|
+
Fetch a URL once, keeping it under ``cache`` when one is given.
|
|
62
|
+
|
|
63
|
+
Parameters
|
|
64
|
+
----------
|
|
65
|
+
cache : Path or None
|
|
66
|
+
Where to keep what was fetched.
|
|
67
|
+
name : str
|
|
68
|
+
The file it is kept as.
|
|
69
|
+
url : str
|
|
70
|
+
The URL.
|
|
71
|
+
|
|
72
|
+
Returns
|
|
73
|
+
-------
|
|
74
|
+
bytes
|
|
75
|
+
Its body.
|
|
76
|
+
"""
|
|
77
|
+
if cache is None:
|
|
78
|
+
return fetch(url)
|
|
79
|
+
path = cache / name
|
|
80
|
+
if not path.exists():
|
|
81
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
82
|
+
path.write_bytes(fetch(url))
|
|
83
|
+
return path.read_bytes()
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def key_of(codes: list[int]) -> str:
|
|
87
|
+
"""
|
|
88
|
+
Name a drawing as ``emojiKey`` does in ``faceEmojis.ts``.
|
|
89
|
+
|
|
90
|
+
Parameters
|
|
91
|
+
----------
|
|
92
|
+
codes : list of int
|
|
93
|
+
The emoji's code points.
|
|
94
|
+
|
|
95
|
+
Returns
|
|
96
|
+
-------
|
|
97
|
+
str
|
|
98
|
+
Lower-case hexadecimal code points joined by ``-``, without U+FE0F.
|
|
99
|
+
"""
|
|
100
|
+
return "-".join(f"{code:x}" for code in codes if code != 0xFE0F)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def main() -> None:
|
|
104
|
+
"""Write the drawings, their loaders and the licence."""
|
|
105
|
+
parser = argparse.ArgumentParser(description=__doc__.splitlines()[1])
|
|
106
|
+
parser.add_argument("--cache", type=Path, help="keep what is fetched here")
|
|
107
|
+
args = parser.parse_args()
|
|
108
|
+
|
|
109
|
+
text = LIST.read_text(encoding="utf-8")
|
|
110
|
+
block = text.split("// fluent-emoji:start", 1)[1].split("// fluent-emoji:end", 1)[0]
|
|
111
|
+
emojis = re.findall(r"^\s*'([^']+)',", block, flags=re.M)
|
|
112
|
+
keys = list(dict.fromkeys(key_of([ord(c) for c in emoji]) for emoji in emojis))
|
|
113
|
+
|
|
114
|
+
tree = json.loads(cached(args.cache, "tree.json", TREE))["tree"]
|
|
115
|
+
paths = [item["path"] for item in tree if item["type"] == "blob"]
|
|
116
|
+
metadata = [p for p in paths if p.count("/") == 2 and p.endswith("/metadata.json")]
|
|
117
|
+
|
|
118
|
+
def read(path: str) -> tuple[str, dict]:
|
|
119
|
+
name = "meta/" + path.split("/")[1] + ".json"
|
|
120
|
+
return path.split("/")[1], json.loads(cached(args.cache, name, RAW + urllib.parse.quote(path)))
|
|
121
|
+
|
|
122
|
+
with concurrent.futures.ThreadPoolExecutor(16) as pool:
|
|
123
|
+
folders = dict(pool.map(read, metadata))
|
|
124
|
+
by_key = {
|
|
125
|
+
key_of([int(code, 16) for code in meta.get("unicode", "").split()]): (folder, meta)
|
|
126
|
+
for folder, meta in folders.items()
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
missing = [key for key in keys if key not in by_key]
|
|
130
|
+
if missing:
|
|
131
|
+
raise SystemExit(f"Fluent Emoji draws none of: {', '.join(missing)}")
|
|
132
|
+
|
|
133
|
+
(OUT / "svg").mkdir(parents=True, exist_ok=True)
|
|
134
|
+
for stale in (OUT / "svg").glob("*.ts"):
|
|
135
|
+
stale.unlink()
|
|
136
|
+
(OUT / "LICENSE").write_bytes(cached(args.cache, "LICENSE", RAW + "LICENSE"))
|
|
137
|
+
|
|
138
|
+
loaders = []
|
|
139
|
+
for key in keys:
|
|
140
|
+
folder, meta = by_key[key]
|
|
141
|
+
# The one drawing, or, for an emoji with skin tones, the default's.
|
|
142
|
+
flat = [
|
|
143
|
+
p
|
|
144
|
+
for p in paths
|
|
145
|
+
if p.startswith(f"assets/{folder}/Flat/")
|
|
146
|
+
or p.startswith(f"assets/{folder}/Default/Flat/")
|
|
147
|
+
]
|
|
148
|
+
flat = [p for p in flat if p.endswith(".svg")]
|
|
149
|
+
if len(flat) != 1:
|
|
150
|
+
raise SystemExit(f"{folder}: {len(flat)} Flat drawings, not one")
|
|
151
|
+
svg = cached(args.cache, f"svg/{key}.svg", RAW + urllib.parse.quote(flat[0])).decode("utf-8")
|
|
152
|
+
svg = re.sub(r"\s*\n\s*", " ", svg.strip())
|
|
153
|
+
# In single quotes, as prettier writes a string with no quote of its own.
|
|
154
|
+
quoted = "'" + svg.replace("\\", "\\\\").replace("'", "\\'") + "'"
|
|
155
|
+
(OUT / "svg" / f"{key}.ts").write_text(
|
|
156
|
+
"/*\n"
|
|
157
|
+
f" * {meta['glyph']} {meta.get('cldr', folder)} — Fluent Emoji, Flat, by Microsoft (MIT,\n"
|
|
158
|
+
" * see ../LICENSE). Written by scripts/generate-fluent-emoji.py: do not edit.\n"
|
|
159
|
+
" */\n\n"
|
|
160
|
+
f"export default {quoted};\n",
|
|
161
|
+
encoding="utf-8",
|
|
162
|
+
)
|
|
163
|
+
loaders.append(f" '{key}': () => import('./svg/{key}'),")
|
|
164
|
+
|
|
165
|
+
(OUT / "loaders.ts").write_text(
|
|
166
|
+
"/*\n"
|
|
167
|
+
" * Copyright (c) 2023-2025 Datalayer, Inc.\n"
|
|
168
|
+
" * Distributed under the terms of the Modified BSD License.\n"
|
|
169
|
+
" */\n\n"
|
|
170
|
+
"/**\n"
|
|
171
|
+
" * The Fluent Emoji drawings Datalayer ships, by `emojiKey`, each a module\n"
|
|
172
|
+
" * of its own, fetched the first time it is drawn. The drawings are\n"
|
|
173
|
+
f" * Microsoft's Fluent Emoji (MIT, see ./LICENSE), at {REPO}@{COMMIT[:12]}.\n"
|
|
174
|
+
" * Written by scripts/generate-fluent-emoji.py: do not edit.\n"
|
|
175
|
+
" *\n"
|
|
176
|
+
" * @module components/emoji/fluent/loaders\n"
|
|
177
|
+
" */\n\n"
|
|
178
|
+
f"export const FLUENT_EMOJI_COMMIT = '{COMMIT}';\n\n"
|
|
179
|
+
"export const FLUENT_EMOJI_LOADERS: Readonly<\n"
|
|
180
|
+
" Record<string, () => Promise<{ default: string }>>\n"
|
|
181
|
+
"> = {\n" + "\n".join(loaders) + "\n};\n",
|
|
182
|
+
encoding="utf-8",
|
|
183
|
+
)
|
|
184
|
+
print(f"{len(keys)} drawings written to {OUT.relative_to(ROOT)}")
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
if __name__ == "__main__":
|
|
188
|
+
main()
|