@datalayer/core 1.1.66 → 1.2.10

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 (210) hide show
  1. package/README.md +41 -18
  2. package/lib/api/constants.d.ts +1 -1
  3. package/lib/api/constants.js +1 -1
  4. package/lib/api/contents/attachments.js +3 -7
  5. package/lib/api/contents/datasets.d.ts +48 -0
  6. package/lib/api/contents/datasets.js +44 -7
  7. package/lib/api/contents/runtimeMounts.js +1 -1
  8. package/lib/api/contents/sandboxUid.d.ts +13 -45
  9. package/lib/api/contents/sandboxUid.js +14 -65
  10. package/lib/api/evals/client.d.ts +402 -0
  11. package/lib/api/evals/client.js +359 -0
  12. package/lib/api/evals/index.d.ts +10 -0
  13. package/lib/api/evals/index.js +18 -0
  14. package/lib/api/evals/request.d.ts +43 -0
  15. package/lib/api/evals/request.js +67 -0
  16. package/lib/api/evals/status.d.ts +27 -0
  17. package/lib/api/evals/status.js +122 -0
  18. package/lib/api/evals/types.d.ts +1335 -0
  19. package/lib/api/evals/types.js +5 -0
  20. package/lib/api/iam/connectedAgents.d.ts +29 -0
  21. package/lib/api/iam/connectedAgents.js +35 -0
  22. package/lib/api/iam/identityProviders.d.ts +76 -0
  23. package/lib/api/iam/identityProviders.js +187 -0
  24. package/lib/api/iam/index.d.ts +1 -0
  25. package/lib/api/iam/index.js +1 -0
  26. package/lib/api/iam/mcpPolicy.d.ts +102 -1
  27. package/lib/api/iam/mcpPolicy.js +38 -2
  28. package/lib/api/iam/profile.d.ts +17 -1
  29. package/lib/api/iam/profile.js +27 -0
  30. package/lib/api/iam/scimTokens.d.ts +79 -0
  31. package/lib/api/iam/scimTokens.js +141 -0
  32. package/lib/api/iam/secrets.js +9 -21
  33. package/lib/api/iam/trials.d.ts +38 -0
  34. package/lib/api/iam/trials.js +66 -0
  35. package/lib/api/index.d.ts +4 -0
  36. package/lib/api/index.js +4 -0
  37. package/lib/api/mcp/observability.d.ts +25 -9
  38. package/lib/api/mcp/observability.js +63 -50
  39. package/lib/api/orchestration/client.d.ts +53 -0
  40. package/lib/api/orchestration/client.js +105 -0
  41. package/lib/api/orchestration/events.d.ts +88 -0
  42. package/lib/api/orchestration/events.js +245 -0
  43. package/lib/api/orchestration/generated.d.ts +693 -0
  44. package/lib/api/orchestration/generated.js +687 -0
  45. package/lib/api/orchestration/index.d.ts +30 -0
  46. package/lib/api/orchestration/index.js +34 -0
  47. package/lib/api/orchestration/lifecycle.d.ts +39 -0
  48. package/lib/api/orchestration/lifecycle.js +57 -0
  49. package/lib/api/orchestration/measures.d.ts +55 -0
  50. package/lib/api/orchestration/measures.js +99 -0
  51. package/lib/api/otel/dashboards.d.ts +56 -0
  52. package/lib/api/otel/dashboards.js +50 -0
  53. package/lib/api/otel/index.d.ts +1 -0
  54. package/lib/api/otel/index.js +1 -0
  55. package/lib/api/otel/metrics.d.ts +16 -0
  56. package/lib/api/otel/metrics.js +15 -0
  57. package/lib/api/scheduler/client.d.ts +32 -0
  58. package/lib/api/scheduler/client.js +42 -0
  59. package/lib/api/scheduler/index.d.ts +8 -0
  60. package/lib/api/scheduler/index.js +16 -0
  61. package/lib/api/scheduler/request.d.ts +28 -0
  62. package/lib/api/scheduler/request.js +50 -0
  63. package/lib/api/scheduler/types.d.ts +88 -0
  64. package/lib/api/scheduler/types.js +5 -0
  65. package/lib/api/spacer/comments.d.ts +97 -0
  66. package/lib/api/spacer/comments.js +45 -0
  67. package/lib/api/spacer/index.d.ts +9 -0
  68. package/lib/api/spacer/index.js +17 -0
  69. package/lib/api/spacer/notebooks.d.ts +33 -0
  70. package/lib/api/spacer/notebooks.js +39 -0
  71. package/lib/api/spacer/request.d.ts +25 -0
  72. package/lib/api/spacer/request.js +46 -0
  73. package/lib/api/spacer/spaces.d.ts +68 -0
  74. package/lib/api/spacer/spaces.js +45 -0
  75. package/lib/api/utils/validation.d.ts +4 -4
  76. package/lib/api/utils/validation.js +10 -7
  77. package/lib/client/constants.d.ts +1 -0
  78. package/lib/client/constants.js +1 -0
  79. package/lib/components/animation/AnimatedText.d.ts +1 -44
  80. package/lib/components/animation/AnimatedText.js +6 -122
  81. package/lib/components/anonymous/AnonymousKeyExpired.d.ts +56 -0
  82. package/lib/components/anonymous/AnonymousKeyExpired.js +96 -0
  83. package/lib/components/anonymous/AnonymousKeyTimer.d.ts +63 -0
  84. package/lib/components/anonymous/AnonymousKeyTimer.js +140 -0
  85. package/lib/components/anonymous/index.d.ts +7 -0
  86. package/lib/components/anonymous/index.js +15 -0
  87. package/lib/components/avatars/UserAvatar.d.ts +7 -1
  88. package/lib/components/avatars/UserAvatar.js +15 -1
  89. package/lib/components/billing/BillingEntitySelect.d.ts +6 -0
  90. package/lib/components/billing/BillingEntitySelect.js +49 -10
  91. package/lib/components/billing/eligibility.d.ts +22 -0
  92. package/lib/components/billing/eligibility.js +27 -0
  93. package/lib/components/billing/index.d.ts +1 -0
  94. package/lib/components/billing/index.js +1 -0
  95. package/lib/components/collaboration/LiveEditorCollaborators.d.ts +5 -0
  96. package/lib/components/collaboration/LiveEditorCollaborators.js +3 -1
  97. package/lib/components/display/DatalayerBox.d.ts +2 -3
  98. package/lib/components/display/DatalayerBox.js +1 -1
  99. package/lib/components/display/NavLink.js +3 -2
  100. package/lib/components/labels/StatusLabels.d.ts +2 -10
  101. package/lib/components/labels/StatusLabels.js +2 -26
  102. package/lib/components/principal/PrincipalAppearance.d.ts +21 -42
  103. package/lib/components/principal/PrincipalAppearance.js +232 -174
  104. package/lib/components/principal/PrincipalAvatar.d.ts +8 -1
  105. package/lib/components/principal/PrincipalAvatar.js +2 -2
  106. package/lib/components/principal/PrincipalDetailsOverlay.d.ts +8 -1
  107. package/lib/components/principal/PrincipalDetailsOverlay.js +2 -2
  108. package/lib/components/screencapture/Screencapture.js +46 -3
  109. package/lib/components/sharing/ShareAccessComponent.d.ts +45 -4
  110. package/lib/components/sharing/ShareAccessComponent.js +110 -78
  111. package/lib/components/sharing/SharingEditor.d.ts +5 -1
  112. package/lib/components/sharing/SharingEditor.js +9 -4
  113. package/lib/components/sharing/index.d.ts +1 -0
  114. package/lib/components/sharing/index.js +1 -0
  115. package/lib/components/sharing/sandboxSharing.d.ts +26 -0
  116. package/lib/components/sharing/sandboxSharing.js +41 -0
  117. package/lib/components/spaces/SpaceDetailsOverlay.d.ts +39 -0
  118. package/lib/components/spaces/SpaceDetailsOverlay.js +80 -0
  119. package/lib/components/spaces/SpaceDisplay.d.ts +38 -0
  120. package/lib/components/spaces/SpaceDisplay.js +92 -0
  121. package/lib/components/spaces/index.d.ts +4 -0
  122. package/lib/components/spaces/index.js +7 -0
  123. package/lib/components/spaces/spaceDisplayModel.d.ts +93 -0
  124. package/lib/components/spaces/spaceDisplayModel.js +170 -0
  125. package/lib/hooks/cacheConverters.d.ts +0 -7
  126. package/lib/hooks/cacheConverters.js +0 -25
  127. package/lib/hooks/index.d.ts +1 -0
  128. package/lib/hooks/index.js +1 -0
  129. package/lib/hooks/useBillingEntityStore.js +3 -0
  130. package/lib/hooks/useCache.d.ts +168 -25
  131. package/lib/hooks/useCache.js +1424 -307
  132. package/lib/hooks/useContents.d.ts +22 -1
  133. package/lib/hooks/useContents.js +90 -21
  134. package/lib/hooks/useMcp.d.ts +87 -1
  135. package/lib/hooks/useMcp.js +247 -12
  136. package/lib/hooks/useNavigate.d.ts +41 -3
  137. package/lib/hooks/useNavigate.js +106 -52
  138. package/lib/hooks/usePrincipalCacheStore.js +3 -0
  139. package/lib/hooks/usePrincipalStore.js +3 -0
  140. package/lib/hooks/useSpaceCacheStore.d.ts +50 -0
  141. package/lib/hooks/useSpaceCacheStore.js +85 -0
  142. package/lib/models/CreditsDTO.d.ts +6 -5
  143. package/lib/models/CreditsDTO.js +7 -5
  144. package/lib/models/McpBinding.d.ts +6 -0
  145. package/lib/models/Organization.d.ts +69 -0
  146. package/lib/models/Organization.js +96 -0
  147. package/lib/models/Secret.d.ts +1 -2
  148. package/lib/models/Secret.js +2 -18
  149. package/lib/models/StartedBy.d.ts +34 -0
  150. package/lib/models/StartedBy.js +36 -0
  151. package/lib/models/Team.d.ts +2 -0
  152. package/lib/models/Team.js +2 -0
  153. package/lib/models/User.d.ts +4 -0
  154. package/lib/models/User.js +3 -0
  155. package/lib/models/UserSettings.d.ts +13 -0
  156. package/lib/models/UserSettings.js +9 -0
  157. package/lib/models/contents/__fixtures__/v1-contracts.json +158 -30
  158. package/lib/navigation/components.js +2 -3
  159. package/lib/routes/publicPaths.js +4 -0
  160. package/lib/state/index.d.ts +1 -0
  161. package/lib/state/index.js +1 -0
  162. package/lib/state/sessionEnd.d.ts +55 -0
  163. package/lib/state/sessionEnd.js +162 -0
  164. package/lib/state/substates/CoreState.js +3 -3
  165. package/lib/state/substates/IAMState.js +7 -0
  166. package/lib/state/substates/LayoutState.js +12 -0
  167. package/lib/state/substates/ProfileState.d.ts +1 -0
  168. package/lib/state/substates/ProfileState.js +1 -0
  169. package/lib/utils/Lazy.d.ts +20 -0
  170. package/lib/utils/Lazy.js +32 -6
  171. package/lib/utils/Screencapture.js +3 -0
  172. package/lib/utils/WithSuspense.d.ts +11 -1
  173. package/lib/utils/WithSuspense.js +11 -1
  174. package/lib/views/mcp/AdmittedClients.d.ts +44 -0
  175. package/lib/views/mcp/AdmittedClients.js +59 -0
  176. package/lib/views/mcp/ApprovalQueue.d.ts +66 -0
  177. package/lib/views/mcp/ApprovalQueue.js +95 -0
  178. package/lib/views/mcp/ConnectedAgents.js +38 -3
  179. package/lib/views/mcp/EnterpriseConsole.d.ts +1 -1
  180. package/lib/views/mcp/EnterpriseConsole.js +23 -1
  181. package/lib/views/mcp/IdentityProviders.d.ts +33 -0
  182. package/lib/views/mcp/IdentityProviders.js +299 -0
  183. package/lib/views/mcp/McpDashboard.js +90 -7
  184. package/lib/views/mcp/McpObservability.d.ts +30 -1
  185. package/lib/views/mcp/McpObservability.js +105 -19
  186. package/lib/views/mcp/NotebookRuns.d.ts +39 -0
  187. package/lib/views/mcp/NotebookRuns.js +44 -0
  188. package/lib/views/mcp/OrganizationPolicy.js +2 -1
  189. package/lib/views/mcp/PersonalPolicy.js +2 -1
  190. package/lib/views/mcp/PolicyForm.d.ts +17 -1
  191. package/lib/views/mcp/PolicyForm.js +25 -3
  192. package/lib/views/mcp/PolicyHistory.d.ts +13 -0
  193. package/lib/views/mcp/PolicyHistory.js +14 -1
  194. package/lib/views/mcp/RunDetail.d.ts +87 -0
  195. package/lib/views/mcp/RunDetail.js +186 -0
  196. package/lib/views/mcp/ScimProvisioning.d.ts +54 -0
  197. package/lib/views/mcp/ScimProvisioning.js +173 -0
  198. package/lib/views/mcp/TeamPolicies.js +66 -5
  199. package/lib/views/mcp/ToolAccess.d.ts +60 -0
  200. package/lib/views/mcp/ToolAccess.js +101 -0
  201. package/lib/views/mcp/TraceTimeline.d.ts +81 -0
  202. package/lib/views/mcp/TraceTimeline.js +132 -0
  203. package/lib/views/mcp/index.d.ts +5 -0
  204. package/lib/views/mcp/index.js +5 -0
  205. package/lib/views/otel/simpleAuthStore.js +3 -0
  206. package/lib/views/secrets/SecretEdit.js +3 -2
  207. package/lib/views/secrets/SecretNew.js +5 -1
  208. package/package.json +269 -264
  209. package/scripts/generate-mcp-types.py +1 -1
  210. package/scripts/generate-orchestration-types.py +920 -0
@@ -0,0 +1,5 @@
1
+ /*
2
+ * Copyright (c) 2023-2025 Datalayer, Inc.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ export {};
@@ -37,3 +37,32 @@ export declare const disconnectAgent: (token: string, grantUid: string, baseUrl?
37
37
  success: boolean;
38
38
  message?: string;
39
39
  }>;
40
+ /**
41
+ * Disconnect every agent this person has connected — sign out everywhere.
42
+ *
43
+ * **This is also how a forced re-consent is done.** A grant *is* the consent,
44
+ * so ending them all sends the next authorization through the consent screen
45
+ * rather than letting it be answered from what was agreed before; there is no
46
+ * separate "ask again" flag to keep in step with this one.
47
+ *
48
+ * Always the caller's own. A person cannot end somebody else's sessions here
49
+ * — an organization taking back what it granted is deprovisioning, which runs
50
+ * when a membership ends.
51
+ */
52
+ export declare const disconnectEveryAgent: (token: string, baseUrl?: string) => Promise<{
53
+ success: boolean;
54
+ revoked: number;
55
+ message?: string;
56
+ }>;
57
+ /**
58
+ * Disconnect every agent connected while acting for one team.
59
+ *
60
+ * For the people who may manage that team: ending a team's sessions is the
61
+ * same kind of authority as removing somebody from it. It never touches a
62
+ * personal agent or another team's — the same narrowness deprovisioning has.
63
+ */
64
+ export declare const disconnectEveryAgentInTeam: (token: string, teamUid: string, baseUrl?: string) => Promise<{
65
+ success: boolean;
66
+ revoked: number;
67
+ message?: string;
68
+ }>;
@@ -50,3 +50,38 @@ export const disconnectAgent = async (token, grantUid, baseUrl = DEFAULT_SERVICE
50
50
  method: 'DELETE',
51
51
  token,
52
52
  });
53
+ /**
54
+ * Disconnect every agent this person has connected — sign out everywhere.
55
+ *
56
+ * **This is also how a forced re-consent is done.** A grant *is* the consent,
57
+ * so ending them all sends the next authorization through the consent screen
58
+ * rather than letting it be answered from what was agreed before; there is no
59
+ * separate "ask again" flag to keep in step with this one.
60
+ *
61
+ * Always the caller's own. A person cannot end somebody else's sessions here
62
+ * — an organization taking back what it granted is deprovisioning, which runs
63
+ * when a membership ends.
64
+ */
65
+ export const disconnectEveryAgent = async (token, baseUrl = DEFAULT_SERVICE_URLS.IAM) => {
66
+ const response = await requestDatalayerAPI({
67
+ url: connectedAgentsUrl(baseUrl),
68
+ method: 'DELETE',
69
+ token,
70
+ });
71
+ return { ...response, revoked: response.revoked ?? 0 };
72
+ };
73
+ /**
74
+ * Disconnect every agent connected while acting for one team.
75
+ *
76
+ * For the people who may manage that team: ending a team's sessions is the
77
+ * same kind of authority as removing somebody from it. It never touches a
78
+ * personal agent or another team's — the same narrowness deprovisioning has.
79
+ */
80
+ export const disconnectEveryAgentInTeam = async (token, teamUid, baseUrl = DEFAULT_SERVICE_URLS.IAM) => {
81
+ const response = await requestDatalayerAPI({
82
+ url: `${baseUrl}${API_BASE_PATHS.IAM}/oauth/teams/${encodeURIComponent(teamUid)}/connected-agents`,
83
+ method: 'DELETE',
84
+ token,
85
+ });
86
+ return { ...response, revoked: response.revoked ?? 0 };
87
+ };
@@ -0,0 +1,76 @@
1
+ /** A role a group mapping may grant, at the organization or at a team. */
2
+ export declare const ORGANIZATION_ROLES: readonly ["organization_owner", "organization_security_auditor", "organization_user_reviewer", "organization_member"];
3
+ export declare const TEAM_ROLES: readonly ["team_owner", "team_member"];
4
+ export type OrganizationRole = (typeof ORGANIZATION_ROLES)[number];
5
+ export type TeamRole = (typeof TEAM_ROLES)[number];
6
+ /** One `groups` claim mapped onto one role, at the organization or a team. */
7
+ export interface RoleMapping {
8
+ /** The group, exactly as the token names it. */
9
+ group: string;
10
+ role: OrganizationRole | TeamRole;
11
+ /** Which team, when `role` is a team role; empty for an organization role. */
12
+ teamUid: string;
13
+ }
14
+ export interface IdentityProvider {
15
+ uid: string;
16
+ orgUid: string;
17
+ name: string;
18
+ protocol: 'oidc';
19
+ issuer: string;
20
+ clientId: string;
21
+ /** The *name* of a secret in this organization's store — never the secret. */
22
+ clientSecretRef: string;
23
+ /** Domains this provider claims. Claiming is free; see `verifiedDomains`. */
24
+ domains: string[];
25
+ /** The claimed domains proved by DNS. Only these route a sign-in. */
26
+ verifiedDomains: string[];
27
+ groupClaim: string;
28
+ /** Whether a sign-in may adopt a Datalayer account that already exists
29
+ * with the asserted address, rather than being refused. Off by default:
30
+ * see the module and provisioning notes for why. */
31
+ allowEmailLinking: boolean;
32
+ roleMappings: RoleMapping[];
33
+ enabled: boolean;
34
+ createdBy?: string;
35
+ createdAt?: string;
36
+ updatedAt?: string;
37
+ version?: number;
38
+ }
39
+ /**
40
+ * A provider as it is written. Everything but what the route already names
41
+ * and `verifiedDomains` — which is never sent, only ever read: it is set
42
+ * exclusively by `verifyDomain` checking DNS, and a draft that could set it
43
+ * directly would be a way to claim verification without proving anything.
44
+ */
45
+ export type IdentityProviderDraft = Omit<IdentityProvider, 'uid' | 'orgUid' | 'verifiedDomains' | 'createdBy' | 'createdAt' | 'updatedAt' | 'version'>;
46
+ export interface DomainVerification {
47
+ host: string;
48
+ type: 'TXT';
49
+ value: string;
50
+ }
51
+ /** Raised when the registry refused a provider as written — a bad issuer, an
52
+ * unowned domain, an unknown role in a mapping. The message is IAM's own. */
53
+ export declare class IdentityProviderInvalid extends Error {
54
+ constructor(message: string);
55
+ }
56
+ export declare const listIdentityProviders: (token: string, orgUid: string, baseUrl?: string) => Promise<IdentityProvider[]>;
57
+ export declare const getIdentityProvider: (token: string, orgUid: string, uid: string, baseUrl?: string) => Promise<IdentityProvider>;
58
+ export declare const createIdentityProvider: (token: string, orgUid: string, provider: IdentityProviderDraft, baseUrl?: string) => Promise<IdentityProvider>;
59
+ export declare const updateIdentityProvider: (token: string, orgUid: string, uid: string, provider: IdentityProviderDraft, baseUrl?: string) => Promise<IdentityProvider>;
60
+ export declare const enableIdentityProvider: (token: string, orgUid: string, uid: string, baseUrl?: string) => Promise<IdentityProvider>;
61
+ export declare const disableIdentityProvider: (token: string, orgUid: string, uid: string, baseUrl?: string) => Promise<IdentityProvider>;
62
+ /** Remove a registration outright. Prefer disabling one that has been used:
63
+ * this keeps no trace for the sign-in rows that name it. */
64
+ export declare const deleteIdentityProvider: (token: string, orgUid: string, uid: string, baseUrl?: string) => Promise<void>;
65
+ /** What to publish in DNS to prove this organization holds `domain`. */
66
+ export declare const getDomainVerification: (token: string, orgUid: string, uid: string, domain: string, baseUrl?: string) => Promise<{
67
+ verification: DomainVerification;
68
+ verified: boolean;
69
+ }>;
70
+ /**
71
+ * Check DNS now and, if the record is there, make the domain route sign-in.
72
+ *
73
+ * Until this succeeds the domain routes nothing at all, whatever was typed
74
+ * when the provider was registered.
75
+ */
76
+ export declare const verifyDomain: (token: string, orgUid: string, uid: string, domain: string, baseUrl?: string) => Promise<IdentityProvider>;
@@ -0,0 +1,187 @@
1
+ /*
2
+ * Copyright (c) 2023-2025 Datalayer, Inc.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ /*
6
+ * Copyright (c) 2023-2026 Datalayer, Inc.
7
+ * Distributed under the terms of the Modified BSD License.
8
+ */
9
+ /**
10
+ * An organization's own identity provider.
11
+ *
12
+ * Enterprise sign-in used to be one Okta for the whole deployment. This is
13
+ * the registry that replaces it: an organization registers an OIDC provider
14
+ * — issuer, client id, the email domains it claims — and a sign-in is routed
15
+ * to it by domain.
16
+ *
17
+ * **A claim is not proof.** Registering a domain here does not route
18
+ * anything: only a domain proved by a DNS TXT record does, because a domain
19
+ * that only had to be typed would let one organization receive another's
20
+ * sign-ins. `getDomainVerification` reads what to publish; `verifyDomain`
21
+ * checks it and is the only call that turns a claim into a route.
22
+ *
23
+ * **The client secret never appears here.** The record names a secret in the
24
+ * organization's own secret store (`clientSecretRef`); this client never
25
+ * reads or writes a secret's value.
26
+ *
27
+ * @module api/iam/identityProviders
28
+ */
29
+ import { requestDatalayerAPI } from '../DatalayerApi.js';
30
+ import { API_BASE_PATHS, DEFAULT_SERVICE_URLS } from '../constants.js';
31
+ /** A role a group mapping may grant, at the organization or at a team. */
32
+ export const ORGANIZATION_ROLES = [
33
+ 'organization_owner',
34
+ 'organization_security_auditor',
35
+ 'organization_user_reviewer',
36
+ 'organization_member',
37
+ ];
38
+ export const TEAM_ROLES = ['team_owner', 'team_member'];
39
+ const roleMappingFromWire = (mapping) => ({
40
+ group: mapping.group ?? '',
41
+ role: mapping.role ?? 'organization_member',
42
+ teamUid: mapping.team_uid ?? '',
43
+ });
44
+ const roleMappingToWire = (mapping) => ({
45
+ group: mapping.group,
46
+ role: mapping.role,
47
+ team_uid: mapping.teamUid,
48
+ });
49
+ const fromWire = (provider) => ({
50
+ uid: provider.uid,
51
+ orgUid: provider.org_uid ?? '',
52
+ name: provider.name ?? '',
53
+ protocol: 'oidc',
54
+ issuer: provider.issuer ?? '',
55
+ clientId: provider.client_id ?? '',
56
+ clientSecretRef: provider.client_secret_ref ?? '',
57
+ domains: provider.domains ?? [],
58
+ verifiedDomains: provider.verified_domains ?? [],
59
+ groupClaim: provider.group_claim ?? 'groups',
60
+ allowEmailLinking: provider.allow_email_linking ?? false,
61
+ roleMappings: (provider.role_mappings ?? []).map(roleMappingFromWire),
62
+ enabled: provider.enabled ?? true,
63
+ createdBy: provider.created_by ?? undefined,
64
+ createdAt: provider.created_at ?? undefined,
65
+ updatedAt: provider.updated_at ?? undefined,
66
+ version: provider.version ?? undefined,
67
+ });
68
+ const toWire = (provider) => ({
69
+ name: provider.name,
70
+ protocol: provider.protocol,
71
+ issuer: provider.issuer,
72
+ client_id: provider.clientId,
73
+ client_secret_ref: provider.clientSecretRef,
74
+ domains: provider.domains,
75
+ group_claim: provider.groupClaim,
76
+ allow_email_linking: provider.allowEmailLinking,
77
+ role_mappings: provider.roleMappings.map(roleMappingToWire),
78
+ enabled: provider.enabled,
79
+ });
80
+ /** Raised when the registry refused a provider as written — a bad issuer, an
81
+ * unowned domain, an unknown role in a mapping. The message is IAM's own. */
82
+ export class IdentityProviderInvalid extends Error {
83
+ constructor(message) {
84
+ super(message);
85
+ this.name = 'IdentityProviderInvalid';
86
+ }
87
+ }
88
+ const providersUrl = (baseUrl, orgUid, suffix = '') => `${baseUrl}${API_BASE_PATHS.IAM}/organizations/${encodeURIComponent(orgUid)}/identity-providers${suffix}`;
89
+ export const listIdentityProviders = async (token, orgUid, baseUrl = DEFAULT_SERVICE_URLS.IAM) => {
90
+ const response = await requestDatalayerAPI({
91
+ url: providersUrl(baseUrl, orgUid),
92
+ method: 'GET',
93
+ token,
94
+ });
95
+ return (response.providers ?? []).map(fromWire);
96
+ };
97
+ export const getIdentityProvider = async (token, orgUid, uid, baseUrl = DEFAULT_SERVICE_URLS.IAM) => {
98
+ const response = await requestDatalayerAPI({
99
+ url: providersUrl(baseUrl, orgUid, `/${encodeURIComponent(uid)}`),
100
+ method: 'GET',
101
+ token,
102
+ });
103
+ return fromWire(response.provider ?? { uid });
104
+ };
105
+ export const createIdentityProvider = async (token, orgUid, provider, baseUrl = DEFAULT_SERVICE_URLS.IAM) => {
106
+ const response = await withRefusal(() => requestDatalayerAPI({
107
+ url: providersUrl(baseUrl, orgUid),
108
+ method: 'POST',
109
+ token,
110
+ body: toWire(provider),
111
+ }));
112
+ return fromWire(response.provider ?? { uid: '' });
113
+ };
114
+ export const updateIdentityProvider = async (token, orgUid, uid, provider, baseUrl = DEFAULT_SERVICE_URLS.IAM) => {
115
+ const response = await withRefusal(() => requestDatalayerAPI({
116
+ url: providersUrl(baseUrl, orgUid, `/${encodeURIComponent(uid)}`),
117
+ method: 'PUT',
118
+ token,
119
+ body: toWire(provider),
120
+ }));
121
+ return fromWire(response.provider ?? { uid });
122
+ };
123
+ const setEnabled = async (token, orgUid, uid, enabled, baseUrl) => {
124
+ const response = await requestDatalayerAPI({
125
+ url: providersUrl(baseUrl, orgUid, `/${encodeURIComponent(uid)}/${enabled ? 'enable' : 'disable'}`),
126
+ method: 'POST',
127
+ token,
128
+ });
129
+ return fromWire(response.provider ?? { uid });
130
+ };
131
+ export const enableIdentityProvider = (token, orgUid, uid, baseUrl = DEFAULT_SERVICE_URLS.IAM) => setEnabled(token, orgUid, uid, true, baseUrl);
132
+ export const disableIdentityProvider = (token, orgUid, uid, baseUrl = DEFAULT_SERVICE_URLS.IAM) => setEnabled(token, orgUid, uid, false, baseUrl);
133
+ /** Remove a registration outright. Prefer disabling one that has been used:
134
+ * this keeps no trace for the sign-in rows that name it. */
135
+ export const deleteIdentityProvider = async (token, orgUid, uid, baseUrl = DEFAULT_SERVICE_URLS.IAM) => {
136
+ await requestDatalayerAPI({
137
+ url: providersUrl(baseUrl, orgUid, `/${encodeURIComponent(uid)}`),
138
+ method: 'DELETE',
139
+ token,
140
+ });
141
+ };
142
+ /** What to publish in DNS to prove this organization holds `domain`. */
143
+ export const getDomainVerification = async (token, orgUid, uid, domain, baseUrl = DEFAULT_SERVICE_URLS.IAM) => {
144
+ const response = await requestDatalayerAPI({
145
+ url: providersUrl(baseUrl, orgUid, `/${encodeURIComponent(uid)}/domains/${encodeURIComponent(domain)}/verification`),
146
+ method: 'GET',
147
+ token,
148
+ });
149
+ return {
150
+ verification: response.verification ?? { host: '', type: 'TXT', value: '' },
151
+ verified: response.verified ?? false,
152
+ };
153
+ };
154
+ /**
155
+ * Check DNS now and, if the record is there, make the domain route sign-in.
156
+ *
157
+ * Until this succeeds the domain routes nothing at all, whatever was typed
158
+ * when the provider was registered.
159
+ */
160
+ export const verifyDomain = async (token, orgUid, uid, domain, baseUrl = DEFAULT_SERVICE_URLS.IAM) => {
161
+ const response = await withRefusal(() => requestDatalayerAPI({
162
+ url: providersUrl(baseUrl, orgUid, `/${encodeURIComponent(uid)}/domains/${encodeURIComponent(domain)}/verify`),
163
+ method: 'POST',
164
+ token,
165
+ }));
166
+ return fromWire(response.provider ?? { uid });
167
+ };
168
+ /**
169
+ * Turn IAM's `400` into one the form can show beside the field.
170
+ *
171
+ * A `400` here is never a bug in the client: it is the registry saying it
172
+ * refused what was written, and its message names why — an `http` issuer, a
173
+ * domain somebody else already verified, an unknown role in a mapping.
174
+ */
175
+ const withRefusal = async (call) => {
176
+ try {
177
+ return await call();
178
+ }
179
+ catch (error) {
180
+ const candidate = error;
181
+ const status = candidate?.status ?? candidate?.response?.status;
182
+ if (status === 400) {
183
+ throw new IdentityProviderInvalid(candidate.message || 'This identity provider was refused.');
184
+ }
185
+ throw error;
186
+ }
187
+ };
@@ -12,6 +12,7 @@ export * as healthz from './healthz';
12
12
  export * as usage from './usage';
13
13
  export * as secrets from './secrets';
14
14
  export * as connectedAgents from './connectedAgents';
15
+ export * as trials from './trials';
15
16
  export { login, logout, checkAuth } from './authentication';
16
17
  export { getOAuth2AuthzUrl, getOAuth2AuthzUrlForLink, handleGitHubOAuth2Callback, handleLinkedInOAuth2Callback, handleOktaOAuth2Callback, type OAuth2Provider, type OAuth2AuthzUrlResponse, type OAuth2CallbackParams, type OAuth2CallbackResponse, } from './oauth2';
17
18
  export { me, whoami } from './profile';
@@ -16,6 +16,7 @@ export * as healthz from './healthz.js';
16
16
  export * as usage from './usage.js';
17
17
  export * as secrets from './secrets.js';
18
18
  export * as connectedAgents from './connectedAgents.js';
19
+ export * as trials from './trials.js';
19
20
  // For backward compatibility, export the old API structure
20
21
  export { login, logout, checkAuth } from './authentication.js';
21
22
  export { getOAuth2AuthzUrl, getOAuth2AuthzUrlForLink, handleGitHubOAuth2Callback, handleLinkedInOAuth2Callback, handleOktaOAuth2Callback, } from './oauth2.js';
@@ -34,6 +34,55 @@ export interface McpPolicyRules {
34
34
  maxCreditsPerDay?: number;
35
35
  /** Sandboxes at once. Counted per scope — a team's counts the team's. */
36
36
  maxConcurrentSandboxes?: number;
37
+ /**
38
+ * GPU-hours over the last 30 days. Refuses a launch on a **GPU**
39
+ * environment; a CPU sandbox is unaffected.
40
+ *
41
+ * Not expressible as credits: the credits a GPU hour costs differ per
42
+ * environment, so neither number can be derived from the other.
43
+ *
44
+ * A trailing 30 days, not a calendar month — a limit that resets on the
45
+ * 1st can be spent twice inside 48 hours, once each side of the reset.
46
+ * And it counts **every** GPU-hour billed to the scope, agents' or not:
47
+ * the agent dimension lives on a child document in the ledger and cannot
48
+ * be a clause of the sum. A form must say both.
49
+ */
50
+ gpuHoursPerMonth?: number;
51
+ /**
52
+ * Bytes stored. Refuses **every** launch when reached, not only one that
53
+ * attaches content — every sandbox can write, so unlike the GPU-hour limit
54
+ * there is nothing to condition on.
55
+ *
56
+ * In **bytes**, not gigabytes. A number whose unit is implied is one
57
+ * somebody eventually reads as the other, and this is compared against a
58
+ * figure Contents reports in bytes; a form converts for the reader.
59
+ *
60
+ * Counted over every live object *version* rather than every object: an
61
+ * object's recorded size is its current version's, and a scope keeping a
62
+ * hundred versions of a one-gigabyte file stores a hundred gigabytes.
63
+ */
64
+ storageBytes?: number;
65
+ /**
66
+ * How long a connection may go on being refreshed before the person signs
67
+ * in and consents again. Hours, because that is the unit it is set in.
68
+ *
69
+ * Enforced by **IAM**, at its token endpoint, rather than by the gateway:
70
+ * a session's age is a fact about the grant, and the grant is IAM's. The
71
+ * gateway never sees it.
72
+ */
73
+ sessionMaxHours?: number;
74
+ /**
75
+ * Whether this organization's own identity provider may stand in for the
76
+ * consent screen, for a client it already admits.
77
+ *
78
+ * Narrow by construction, and off unless turned on: it applies only to a
79
+ * session that came through one of this organization's own enabled
80
+ * providers, only for a client named on `allowedClients`, and only when
81
+ * that list is not empty. Every other session still sees the screen.
82
+ *
83
+ * Not "require SSO": it does not stop anybody signing in another way.
84
+ */
85
+ ssoAdmitsWithoutConsent?: boolean;
37
86
  }
38
87
  /** A stored layer, with the version a write must carry back. */
39
88
  export interface McpPolicy extends McpPolicyRules {
@@ -52,7 +101,7 @@ export interface McpPolicy extends McpPolicyRules {
52
101
  * rendered here and unknown to IAM is refused at the write, which reads to
53
102
  * the person filling it in as the page being broken.
54
103
  */
55
- export declare const MCP_POLICY_RULES: readonly ["toolDenylist", "toolAllowlist", "allowedClients", "maxCallsPerMinute", "maxCreditsPerDay", "maxConcurrentSandboxes"];
104
+ export declare const MCP_POLICY_RULES: readonly ["toolDenylist", "toolAllowlist", "allowedClients", "maxCallsPerMinute", "maxCreditsPerDay", "maxConcurrentSandboxes", "gpuHoursPerMonth", "storageBytes", "sessionMaxHours", "ssoAdmitsWithoutConsent"];
56
105
  /** Raised when the policy changed between the read and the write. */
57
106
  export declare class McpPolicyConflict extends Error {
58
107
  constructor(message: string);
@@ -78,3 +127,55 @@ export declare const setMcpPolicy: (token: string, scope: McpPolicyScope, subjec
78
127
  }, baseUrl?: string) => Promise<McpPolicy>;
79
128
  /** Remove one layer, so it narrows nothing again. */
80
129
  export declare const deleteMcpPolicy: (token: string, scope: McpPolicyScope, subjectUid: string, baseUrl?: string) => Promise<void>;
130
+ /**
131
+ * One `allowedClients` entry, as the server can describe it.
132
+ *
133
+ * Three states, kept apart deliberately — collapsing any two of them is the
134
+ * mistake this shape exists to prevent.
135
+ */
136
+ export interface AdmittedClient {
137
+ /** Exactly as it is stored, so somebody can find the line they typed. */
138
+ entry: string;
139
+ /**
140
+ * `hostname` admits every client that host publishes and has no document
141
+ * to read. `url` names one client document. `unusable` matches nothing —
142
+ * almost always a URL pasted without its scheme.
143
+ */
144
+ kind: 'hostname' | 'url' | 'unusable';
145
+ hostname?: string;
146
+ /**
147
+ * Only for `url`. `false` means the document could not be read, which is
148
+ * an entry that silently admits nobody — and reads to the vendor whose
149
+ * agent is refused as a deliberate decision.
150
+ */
151
+ resolved?: boolean;
152
+ clientName?: string;
153
+ clientHostname?: string;
154
+ clientUri?: string;
155
+ /** Every redirect goes to the reader's own machine. */
156
+ localhostOnly?: boolean;
157
+ /** Why it cannot be read, or what a hostname entry admits. */
158
+ detail?: string;
159
+ }
160
+ export interface AdmittedClients {
161
+ /**
162
+ * Whether this layer names an allowlist **at all**.
163
+ *
164
+ * `false` for an absent or empty list, and it is not a detail: an empty
165
+ * list is not an allowlist, and the gateway admits every client through a
166
+ * layer that has not filled one in. A page rendering "0 clients admitted"
167
+ * over `false` would state the opposite of what is enforced.
168
+ */
169
+ allowlisted: boolean;
170
+ clients: AdmittedClient[];
171
+ detail?: string;
172
+ }
173
+ /**
174
+ * What this layer's admitted-client entries actually name.
175
+ *
176
+ * Its own call rather than part of `getMcpPolicy`, because that one is what
177
+ * the gateway reads on every uncached tool call and this may fetch a client
178
+ * document per entry — which is exactly what must never happen on the
179
+ * enforcement path.
180
+ */
181
+ export declare const getAdmittedClients: (token: string, scope: McpPolicyScope, subjectUid: string, baseUrl?: string) => Promise<AdmittedClients>;
@@ -52,6 +52,10 @@ export const MCP_POLICY_RULES = [
52
52
  'maxCallsPerMinute',
53
53
  'maxCreditsPerDay',
54
54
  'maxConcurrentSandboxes',
55
+ 'gpuHoursPerMonth',
56
+ 'storageBytes',
57
+ 'sessionMaxHours',
58
+ 'ssoAdmitsWithoutConsent',
55
59
  ];
56
60
  /** Raised when the policy changed between the read and the write. */
57
61
  export class McpPolicyConflict extends Error {
@@ -60,8 +64,9 @@ export class McpPolicyConflict extends Error {
60
64
  this.name = 'McpPolicyConflict';
61
65
  }
62
66
  }
63
- const policyUrl = (baseUrl, scope, subjectUid, query = '') => `${baseUrl}${API_BASE_PATHS.IAM}/mcp-policies/${encodeURIComponent(scope)}` +
64
- `/${encodeURIComponent(subjectUid)}${query}`;
67
+ /** `suffix` is appended verbatim: a query string, or a further path segment. */
68
+ const policyUrl = (baseUrl, scope, subjectUid, suffix = '') => `${baseUrl}${API_BASE_PATHS.IAM}/mcp-policies/${encodeURIComponent(scope)}` +
69
+ `/${encodeURIComponent(subjectUid)}${suffix}`;
65
70
  /**
66
71
  * One layer's rules, or `null` where nobody has written it.
67
72
  *
@@ -130,3 +135,34 @@ const statusOf = (error) => {
130
135
  };
131
136
  const isNotFound = (error) => statusOf(error) === 404;
132
137
  const isConflict = (error) => statusOf(error) === 409;
138
+ const admittedFromWire = (wire) => ({
139
+ entry: wire.entry ?? '',
140
+ kind: wire.kind === 'hostname' || wire.kind === 'url' ? wire.kind : 'unusable',
141
+ hostname: wire.hostname || undefined,
142
+ resolved: wire.resolved,
143
+ clientName: wire.client_name || undefined,
144
+ clientHostname: wire.client_hostname || undefined,
145
+ clientUri: wire.client_uri || undefined,
146
+ localhostOnly: wire.localhost_only,
147
+ detail: wire.detail || undefined,
148
+ });
149
+ /**
150
+ * What this layer's admitted-client entries actually name.
151
+ *
152
+ * Its own call rather than part of `getMcpPolicy`, because that one is what
153
+ * the gateway reads on every uncached tool call and this may fetch a client
154
+ * document per entry — which is exactly what must never happen on the
155
+ * enforcement path.
156
+ */
157
+ export const getAdmittedClients = async (token, scope, subjectUid, baseUrl = DEFAULT_SERVICE_URLS.IAM) => {
158
+ const response = await requestDatalayerAPI({
159
+ url: policyUrl(baseUrl, scope, subjectUid, '/admitted-clients'),
160
+ method: 'GET',
161
+ token,
162
+ });
163
+ return {
164
+ allowlisted: response.allowlisted === true,
165
+ clients: (response.clients ?? []).map(admittedFromWire),
166
+ detail: response.detail || undefined,
167
+ };
168
+ };
@@ -1,4 +1,4 @@
1
- import { MembershipsResponse, ShareablePrincipalsResponse, UserMeResponse, WhoAmIResponse } from '../../models/IAM';
1
+ import { MembershipsResponse, PrincipalSearchResponse, PrincipalSearchUser, ShareablePrincipalsResponse, UserMeResponse, WhoAmIResponse } from '../../models/IAM';
2
2
  /**
3
3
  * Get current authenticated user profile
4
4
  * @param token - Authentication token (required)
@@ -28,3 +28,19 @@ export declare const memberships: (token: string, baseUrl?: string) => Promise<M
28
28
  * @param baseUrl - Base URL for the API (defaults to production IAM URL)
29
29
  */
30
30
  export declare const principalsShareable: (token: string, baseUrl?: string) => Promise<ShareablePrincipalsResponse>;
31
+ /**
32
+ * Search the people, teams and organizations the caller may name: what the
33
+ * sharing dialogs search, and whom a comment mentions or assigns (B4-02).
34
+ *
35
+ * @param token - Authentication token (required)
36
+ * @param query - What is typed: part of a handle or of a name
37
+ * @param principalTypes - What to search; people only by default
38
+ * @param baseUrl - Base URL for the API (defaults to production IAM URL)
39
+ */
40
+ export declare const searchPrincipals: (token: string, query: string, principalTypes?: Array<"user" | "team" | "organization">, baseUrl?: string) => Promise<PrincipalSearchResponse>;
41
+ /** A person `searchPrincipals` found, as a comment or a report names them. */
42
+ export declare const personOfPrincipalUser: (user: PrincipalSearchUser) => {
43
+ uid: string;
44
+ handle: string;
45
+ name: string | null;
46
+ };
@@ -69,3 +69,30 @@ export const principalsShareable = async (token, baseUrl = DEFAULT_SERVICE_URLS.
69
69
  token,
70
70
  });
71
71
  };
72
+ /**
73
+ * Search the people, teams and organizations the caller may name: what the
74
+ * sharing dialogs search, and whom a comment mentions or assigns (B4-02).
75
+ *
76
+ * @param token - Authentication token (required)
77
+ * @param query - What is typed: part of a handle or of a name
78
+ * @param principalTypes - What to search; people only by default
79
+ * @param baseUrl - Base URL for the API (defaults to production IAM URL)
80
+ */
81
+ export const searchPrincipals = async (token, query, principalTypes = ['user'], baseUrl = DEFAULT_SERVICE_URLS.IAM) => {
82
+ validateToken(token);
83
+ return requestDatalayerAPI({
84
+ url: `${baseUrl}${API_BASE_PATHS.IAM}/principals/search`,
85
+ method: 'POST',
86
+ body: { query, principalTypes },
87
+ token,
88
+ });
89
+ };
90
+ /** A person `searchPrincipals` found, as a comment or a report names them. */
91
+ export const personOfPrincipalUser = (user) => ({
92
+ uid: user.uid,
93
+ handle: user.handle_s,
94
+ name: `${user.first_name_t ?? ''} ${user.last_name_t ?? ''}`.trim() ||
95
+ user.display_name_t ||
96
+ user.display_name ||
97
+ null,
98
+ });