@opengeni/api-router 0.30.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-grant-rls.d.ts +3 -0
- package/dist/admission-trace.d.ts +8 -0
- package/dist/api-websocket.d.ts +18 -0
- package/dist/app.d.ts +50 -2
- package/dist/app.js +12 -1
- package/dist/artifact-catalog-cursor.d.ts +27 -0
- package/dist/auth/managed-auth-attempt-context.d.ts +10 -0
- package/dist/auth/managed-auth-rate-limits.d.ts +167 -0
- package/dist/auth/managed-auth-session-adapter.d.ts +6 -0
- package/dist/auth/managed-auth.d.ts +102 -3
- package/dist/auth/managed-email.d.ts +29 -0
- package/dist/auth/managed-sign-in-notifications.d.ts +4 -0
- package/dist/auth/new-signups-gate.d.ts +23 -0
- package/dist/auth/organization-user-setup.d.ts +80 -0
- package/dist/auth/signup-funnel-metrics.d.ts +44 -0
- package/dist/browser-controller-authority.d.ts +1 -61
- package/dist/browser-ephemeral.d.ts +5 -0
- package/dist/browser-state-authority.d.ts +1 -27
- package/dist/chunk-6TZ5LG3O.js +123948 -0
- package/dist/chunk-6TZ5LG3O.js.map +1 -0
- package/dist/chunk-OGQDXVXY.js +18 -0
- package/dist/chunk-OGQDXVXY.js.map +1 -0
- package/dist/claude-subscription-account-conflicts.d.ts +1 -0
- package/dist/claude-subscription-account-usage.d.ts +39 -0
- package/dist/claude-subscription-oauth.d.ts +25 -0
- package/dist/claude-subscription-profile.d.ts +9 -0
- package/dist/claude-subscription-usage.d.ts +44 -0
- package/dist/claude-workspace-connection.d.ts +15 -0
- package/dist/codemode.d.ts +32 -1
- package/dist/company-brain-okf.d.ts +24 -0
- package/dist/connected-machine-computer-access.d.ts +11 -0
- package/dist/connection-ownership.d.ts +54 -0
- package/dist/controller-data-plane.d.ts +32 -0
- package/dist/editable-artifact-office-import.d.ts +7 -4
- package/dist/editable-artifact-source-session.d.ts +3 -0
- package/dist/editable-artifact-websocket.d.ts +10 -18
- package/dist/editable-artifact-workspace-files.d.ts +1 -1
- package/dist/fatal-process-boundary.d.ts +25 -0
- package/dist/github-access.d.ts +31 -2
- package/dist/http/acting-person.d.ts +24 -0
- package/dist/http/api-contract-compat.d.ts +19 -0
- package/dist/http/api-error.d.ts +27 -1
- package/dist/http/cors.d.ts +17 -0
- package/dist/http/deprecation.d.ts +42 -0
- package/dist/http/interaction-control-error.d.ts +13 -0
- package/dist/http/keyed-admission.d.ts +12 -0
- package/dist/http/local-browser-boundary.d.ts +72 -0
- package/dist/http/metrics-listener.d.ts +22 -0
- package/dist/http/path-identifier.d.ts +17 -0
- package/dist/http/registered-route-label.d.ts +16 -0
- package/dist/http/request-body.d.ts +27 -0
- package/dist/http/request-source.d.ts +52 -0
- package/dist/http/sse.d.ts +17 -6
- package/dist/http/unmatched-route.d.ts +18 -0
- package/dist/http/user-content.d.ts +36 -0
- package/dist/http/websocket-upgrade-dispatch.d.ts +18 -0
- package/dist/index.d.ts +10 -3
- package/dist/index.js +1129 -166
- package/dist/index.js.map +1 -1
- package/dist/integration-endpoint-test.d.ts +20 -0
- package/dist/integrations/api-integrations.d.ts +2 -2
- package/dist/integrations/atlassian.d.ts +29 -3
- package/dist/integrations/connect-authority.d.ts +1 -0
- package/dist/integrations/connect-callback-return.d.ts +6 -0
- package/dist/integrations/fiken.d.ts +16 -2
- package/dist/integrations/github-app-connect.d.ts +47 -0
- package/dist/integrations/github-installation-proof.d.ts +3 -0
- package/dist/integrations/github-lens-connect.d.ts +116 -0
- package/dist/integrations/github-skill-source.d.ts +1 -5
- package/dist/integrations/google-drive.d.ts +25 -0
- package/dist/integrations/integration-commit-authority.d.ts +13 -0
- package/dist/integrations/marketplace-plugin.d.ts +2691 -0
- package/dist/integrations/oauth-client.d.ts +178 -18
- package/dist/integrations/oauth-profiles.d.ts +222 -0
- package/dist/integrations/oauth-return-path.d.ts +1 -0
- package/dist/integrations/personal-github-repositories.d.ts +84 -0
- package/dist/integrations/personal-github.d.ts +42 -0
- package/dist/integrations/pr-review-provider.d.ts +22 -0
- package/dist/integrations/provider-oauth.d.ts +19 -1
- package/dist/integrations/slack-app-home.d.ts +24 -0
- package/dist/integrations/slack-bot.d.ts +367 -12
- package/dist/integrations/slack-file-upload-flow.d.ts +62 -0
- package/dist/integrations/slack-install.d.ts +20 -0
- package/dist/integrations/slack-interactions.d.ts +113 -10
- package/dist/integrations/slack-mrkdwn.d.ts +41 -0
- package/dist/integrations/slack-routing.d.ts +120 -0
- package/dist/integrations/slack-session-defaults.d.ts +58 -0
- package/dist/integrations/slack-task-file-upload.d.ts +36 -0
- package/dist/integrations/social-oauth.d.ts +7 -0
- package/dist/interaction-agent-access.d.ts +15 -0
- package/dist/interaction-frame-proxy.d.ts +68 -0
- package/dist/interaction-metrics.d.ts +2 -0
- package/dist/mcp/action-catalog-types.d.ts +9 -0
- package/dist/mcp/action-catalog.gen.d.ts +2 -0
- package/dist/mcp/capability-account-readiness.d.ts +7 -0
- package/dist/mcp/child-read-evidence.d.ts +9 -0
- package/dist/mcp/command-read.d.ts +24 -0
- package/dist/mcp/company-profile-agent-admin.d.ts +44 -0
- package/dist/mcp/contract-input.d.ts +11 -0
- package/dist/mcp/documents.d.ts +7 -5
- package/dist/mcp/files.d.ts +2 -2
- package/dist/mcp/first-party-tool-permissions.d.ts +650 -0
- package/dist/mcp/knowledge-entries.d.ts +5 -0
- package/dist/mcp/orchestration-failure-diagnostic.d.ts +43 -0
- package/dist/mcp/receipts.d.ts +9 -0
- package/dist/mcp/request-abort.d.ts +19 -0
- package/dist/mcp/scheduled-task-input.d.ts +1189 -0
- package/dist/mcp/scheduled-task-view.d.ts +22 -4
- package/dist/mcp/server.d.ts +255 -3
- package/dist/mcp/session-event-view.d.ts +94 -0
- package/dist/mcp/session-view.d.ts +66 -2
- package/dist/mcp/session-wait.d.ts +174 -0
- package/dist/mcp-oauth.d.ts +52 -0
- package/dist/model-catalog.d.ts +11 -31
- package/dist/observability.d.ts +3 -1
- package/dist/organization-mcp.d.ts +52 -0
- package/dist/organization-recovery-notifications.d.ts +41 -0
- package/dist/routes/analytics-consent.d.ts +26 -0
- package/dist/routes/api-integrations.d.ts +25 -0
- package/dist/routes/api-keys.d.ts +17 -0
- package/dist/routes/artifact-catalog.d.ts +6 -0
- package/dist/routes/automations.d.ts +19 -0
- package/dist/routes/billing.d.ts +49 -0
- package/dist/routes/browser-sessions.d.ts +71 -3
- package/dist/routes/claude-subscription-accounts.d.ts +3 -0
- package/dist/routes/claude-subscription-oauth.d.ts +3 -0
- package/dist/routes/client-errors.d.ts +146 -0
- package/dist/routes/codex.d.ts +76 -2
- package/dist/routes/company-brain.d.ts +3 -0
- package/dist/routes/company-profile.d.ts +2 -1
- package/dist/routes/computer-sessions.d.ts +14 -0
- package/dist/routes/connect.d.ts +5 -0
- package/dist/routes/editable-artifacts.d.ts +2 -0
- package/dist/routes/external-identity-links.d.ts +6 -0
- package/dist/routes/feedback.d.ts +3 -0
- package/dist/routes/files.d.ts +4 -0
- package/dist/routes/github-browser-pages.d.ts +12 -0
- package/dist/routes/github.d.ts +2 -0
- package/dist/routes/insights-response-cache.d.ts +10 -0
- package/dist/routes/insights-usage.d.ts +12 -0
- package/dist/routes/insights.d.ts +30 -1
- package/dist/routes/knowledge.d.ts +3 -0
- package/dist/routes/managed-auth-session-sets.d.ts +26 -0
- package/dist/routes/managed-onboarding.d.ts +29 -0
- package/dist/routes/managed-sign-in-methods.d.ts +6 -0
- package/dist/routes/model-connection-access.d.ts +3 -0
- package/dist/routes/organization-integration-policy.d.ts +3 -0
- package/dist/routes/organization-integrations.d.ts +6 -0
- package/dist/routes/organization-mcp-connections.d.ts +3 -0
- package/dist/routes/organization-model-providers.d.ts +3 -0
- package/dist/routes/organization-recovery.d.ts +19 -0
- package/dist/routes/organization-service-accounts.d.ts +3 -0
- package/dist/routes/organization-sessions.d.ts +26 -0
- package/dist/routes/personal-github-git-broker.d.ts +29 -0
- package/dist/routes/personal-github.d.ts +3 -0
- package/dist/routes/pr-review-github.d.ts +3 -0
- package/dist/routes/pr-review.d.ts +3 -0
- package/dist/routes/session-artifact-associations.d.ts +4 -0
- package/dist/routes/session-history-imports.d.ts +9 -0
- package/dist/routes/sessions.d.ts +44 -6
- package/dist/routes/skill-content.d.ts +4 -0
- package/dist/routes/skill-install-authority.d.ts +6 -0
- package/dist/routes/subscription-account-pools.d.ts +34 -0
- package/dist/routes/subscription-pool-access.d.ts +16 -0
- package/dist/routes/supergrok.d.ts +6 -1
- package/dist/routes/usage-allowances.d.ts +12 -0
- package/dist/routes/user-resource-authorities.d.ts +3 -0
- package/dist/routes/workspace-artifacts.d.ts +2 -1
- package/dist/routes/workspace-capture.d.ts +10 -2
- package/dist/routes/workspace-integrations.d.ts +35 -0
- package/dist/routes/workspace-learning.d.ts +3 -0
- package/dist/routes/workspace-model-providers.d.ts +4 -0
- package/dist/routes/workspaces.d.ts +29 -0
- package/dist/sandbox/auth-callout.d.ts +8 -0
- package/dist/sandbox/channel-a.d.ts +19 -1
- package/dist/sandbox/connection-authority.d.ts +3 -0
- package/dist/sandbox/enrollment.d.ts +9 -1
- package/dist/sandbox/machines.d.ts +5 -2
- package/dist/sandbox/metrics-ingestion.d.ts +28 -20
- package/dist/sandbox/rematerialize.d.ts +2 -0
- package/dist/sandbox/session-attach-variable-sets.d.ts +30 -0
- package/dist/sandbox/viewer.d.ts +26 -1
- package/dist/sandbox-file-artifacts.d.ts +50 -0
- package/dist/scheduled-task-deletion.d.ts +13 -0
- package/dist/session-create-observability.d.ts +5 -0
- package/dist/session-event-view-MPS2OZD3.js +292 -0
- package/dist/session-event-view-MPS2OZD3.js.map +1 -0
- package/dist/site-session-origin.d.ts +13 -0
- package/dist/site-uploads.d.ts +41 -0
- package/dist/slack-reaction-files.d.ts +1 -1
- package/dist/temporal-schedule-cleanup.d.ts +1 -0
- package/dist/temporal-schedule-sync.d.ts +26 -0
- package/dist/transcription/providers/xai-subscription.d.ts +1 -0
- package/dist/transcription/service.d.ts +2 -1
- package/dist/work-discovery-observability.d.ts +33 -0
- package/dist/workspace-artifact-content.d.ts +28 -0
- package/dist/workspace-artifact-provenance.d.ts +7 -0
- package/dist/workspace-delete-observability.d.ts +10 -0
- package/dist/workspace-deletion.d.ts +6 -0
- package/dist/workspace-state-projection.d.ts +3 -5
- package/dist/workspace-tool-gateway-observability.d.ts +17 -0
- package/dist/workspace-tool-gateway.d.ts +123 -0
- package/dist/workspace-webhook-dispatch.d.ts +26 -0
- package/package.json +23 -19
- package/src/access-grant-rls.ts +75 -0
- package/src/admission-trace.ts +14 -0
- package/src/api-websocket.ts +23 -0
- package/src/app.ts +1974 -256
- package/src/artifact-catalog-cursor.ts +60 -0
- package/src/auth/managed-auth-attempt-context.ts +70 -0
- package/src/auth/managed-auth-rate-limits.ts +252 -0
- package/src/auth/managed-auth-session-adapter.ts +222 -0
- package/src/auth/managed-auth.ts +536 -60
- package/src/auth/managed-email.ts +174 -0
- package/src/auth/managed-sign-in-notifications.ts +81 -0
- package/src/auth/new-signups-gate.ts +49 -0
- package/src/auth/organization-user-setup.ts +307 -0
- package/src/auth/signup-funnel-metrics.ts +164 -0
- package/src/browser-controller-authority.ts +1 -186
- package/src/browser-ephemeral.ts +39 -0
- package/src/browser-state-authority.ts +1 -236
- package/src/claude-subscription-account-conflicts.ts +12 -0
- package/src/claude-subscription-account-usage.ts +48 -0
- package/src/claude-subscription-oauth.ts +362 -0
- package/src/claude-subscription-profile.ts +73 -0
- package/src/claude-subscription-usage.ts +97 -0
- package/src/claude-workspace-connection.ts +82 -0
- package/src/codemode.ts +194 -30
- package/src/codex-realtime.ts +8 -2
- package/src/company-brain-okf.ts +340 -0
- package/src/connected-machine-computer-access.ts +33 -0
- package/src/connection-ownership.ts +199 -0
- package/src/controller-data-plane.ts +81 -0
- package/src/editable-artifact-native-kernel.ts +26 -15
- package/src/editable-artifact-office-import.ts +77 -9
- package/src/editable-artifact-production.ts +23 -7
- package/src/editable-artifact-source-session.ts +123 -0
- package/src/editable-artifact-websocket.ts +27 -21
- package/src/editable-artifact-workspace-files.ts +31 -6
- package/src/fatal-process-boundary.ts +246 -0
- package/src/gateway-realtime.ts +1 -1
- package/src/github-access.ts +147 -5
- package/src/http/acting-person.ts +71 -0
- package/src/http/api-contract-compat.ts +49 -0
- package/src/http/api-error.ts +115 -1
- package/src/http/auth.ts +48 -0
- package/src/http/cors.ts +67 -0
- package/src/http/deprecation.ts +118 -0
- package/src/http/interaction-control-error.ts +164 -0
- package/src/http/keyed-admission.ts +29 -0
- package/src/http/local-browser-boundary.ts +343 -0
- package/src/http/metrics-listener.ts +57 -0
- package/src/http/path-identifier.ts +54 -0
- package/src/http/registered-route-label.ts +34 -0
- package/src/http/request-body.ts +127 -0
- package/src/http/request-source.ts +178 -0
- package/src/http/sse.ts +486 -132
- package/src/http/unmatched-route.ts +60 -0
- package/src/http/user-content.ts +158 -0
- package/src/http/websocket-upgrade-dispatch.ts +29 -0
- package/src/index.ts +157 -52
- package/src/integration-endpoint-test.ts +291 -0
- package/src/integrations/api-integrations.ts +98 -11
- package/src/integrations/atlassian.ts +474 -136
- package/src/integrations/connect-authority.ts +2 -0
- package/src/integrations/connect-callback-return.ts +86 -0
- package/src/integrations/fiken.ts +354 -64
- package/src/integrations/github-app-connect.ts +435 -0
- package/src/integrations/github-installation-proof.ts +60 -0
- package/src/integrations/github-lens-connect.ts +76 -0
- package/src/integrations/github-skill-source.ts +2 -142
- package/src/integrations/google-drive.ts +820 -222
- package/src/integrations/integration-commit-authority.ts +69 -0
- package/src/integrations/marketplace-plugin.ts +48 -0
- package/src/integrations/oauth-client.ts +1356 -459
- package/src/integrations/oauth-profiles.ts +537 -0
- package/src/integrations/oauth-return-path.ts +18 -0
- package/src/integrations/personal-github-repositories.ts +674 -0
- package/src/integrations/personal-github.ts +825 -0
- package/src/integrations/pr-review-provider.ts +246 -0
- package/src/integrations/provider-oauth.ts +250 -22
- package/src/integrations/slack-app-home.ts +300 -0
- package/src/integrations/slack-bot.ts +963 -239
- package/src/integrations/slack-file-upload-flow.ts +147 -0
- package/src/integrations/slack-install.ts +83 -0
- package/src/integrations/slack-interactions.ts +3170 -474
- package/src/integrations/slack-mrkdwn.ts +193 -0
- package/src/integrations/slack-routing.ts +337 -0
- package/src/integrations/slack-session-defaults.ts +224 -0
- package/src/integrations/slack-task-file-upload.ts +323 -0
- package/src/integrations/social-oauth.ts +213 -15
- package/src/interaction-agent-access.ts +48 -0
- package/src/interaction-frame-proxy.ts +409 -0
- package/src/interaction-metrics.ts +30 -0
- package/src/mcp/action-catalog-types.ts +9 -0
- package/src/mcp/action-catalog.gen.ts +6696 -0
- package/src/mcp/capability-account-readiness.ts +17 -0
- package/src/mcp/child-read-evidence.ts +19 -0
- package/src/mcp/command-read.ts +109 -0
- package/src/mcp/company-profile-agent-admin.ts +198 -0
- package/src/mcp/contract-input.ts +141 -0
- package/src/mcp/documents.ts +65 -377
- package/src/mcp/editable-artifacts.ts +12 -6
- package/src/mcp/files.ts +80 -38
- package/src/mcp/first-party-tool-permissions.ts +305 -0
- package/src/mcp/knowledge-entries.ts +322 -0
- package/src/mcp/orchestration-failure-diagnostic.ts +43 -0
- package/src/mcp/receipts.ts +34 -0
- package/src/mcp/request-abort.ts +44 -0
- package/src/mcp/scheduled-task-input.ts +76 -0
- package/src/mcp/scheduled-task-view.ts +44 -3
- package/src/mcp/server.ts +3030 -1267
- package/src/mcp/session-event-view.ts +383 -0
- package/src/mcp/session-view.ts +84 -3
- package/src/mcp/session-wait.ts +665 -0
- package/src/mcp-oauth.ts +1123 -0
- package/src/model-catalog.ts +91 -333
- package/src/observability.ts +15 -1
- package/src/organization-mcp.ts +397 -0
- package/src/organization-recovery-notifications.ts +103 -0
- package/src/routes/analytics-consent.ts +123 -0
- package/src/routes/api-integrations.ts +364 -74
- package/src/routes/api-keys.ts +336 -10
- package/src/routes/artifact-catalog.ts +279 -0
- package/src/routes/automations.ts +768 -0
- package/src/routes/billing.ts +461 -46
- package/src/routes/browser-sessions.ts +839 -131
- package/src/routes/canonical-human-identities.ts +90 -14
- package/src/routes/capabilities.ts +107 -6
- package/src/routes/channels.ts +20 -3
- package/src/routes/claude-subscription-accounts.ts +334 -0
- package/src/routes/claude-subscription-oauth.ts +142 -0
- package/src/routes/client-errors.ts +362 -0
- package/src/routes/codex.ts +833 -116
- package/src/routes/company-brain.ts +322 -0
- package/src/routes/company-profile.ts +65 -1
- package/src/routes/computer-sessions.ts +557 -106
- package/src/routes/connect.ts +1938 -0
- package/src/routes/connections.ts +1040 -349
- package/src/routes/documents.ts +488 -287
- package/src/routes/editable-artifacts.ts +79 -9
- package/src/routes/enrollments.ts +135 -39
- package/src/routes/environments.ts +154 -58
- package/src/routes/external-identity-links.ts +201 -0
- package/src/routes/feedback.ts +113 -0
- package/src/routes/files.ts +337 -39
- package/src/routes/github-browser-pages.ts +162 -0
- package/src/routes/github.ts +446 -144
- package/src/routes/insights-response-cache.ts +83 -0
- package/src/routes/insights-usage.ts +345 -0
- package/src/routes/insights.ts +153 -19
- package/src/routes/install.ts +133 -38
- package/src/routes/integration-facets.ts +107 -33
- package/src/routes/interaction-resources.ts +30 -3
- package/src/routes/knowledge.ts +488 -0
- package/src/routes/machines.ts +313 -15
- package/src/routes/managed-auth-session-sets.ts +1218 -0
- package/src/routes/managed-onboarding.ts +337 -0
- package/src/routes/managed-sign-in-methods.ts +433 -0
- package/src/routes/memory-slack-publications.ts +3 -2
- package/src/routes/model-connection-access.ts +208 -0
- package/src/routes/organization-integration-policy.ts +116 -0
- package/src/routes/organization-integrations.ts +326 -0
- package/src/routes/organization-mcp-connections.ts +178 -0
- package/src/routes/organization-memberships.ts +1019 -27
- package/src/routes/organization-model-providers.ts +293 -0
- package/src/routes/organization-recovery.ts +325 -0
- package/src/routes/organization-service-accounts.ts +128 -0
- package/src/routes/organization-sessions.ts +350 -0
- package/src/routes/personal-github-git-broker.ts +785 -0
- package/src/routes/personal-github.ts +370 -0
- package/src/routes/plugins.ts +251 -22
- package/src/routes/pr-review-github.ts +881 -0
- package/src/routes/pr-review.ts +622 -0
- package/src/routes/preference-registry.ts +12 -93
- package/src/routes/rigs.ts +167 -50
- package/src/routes/scheduled-tasks.ts +346 -41
- package/src/routes/session-artifact-associations.ts +87 -0
- package/src/routes/session-history-imports.ts +280 -0
- package/src/routes/sessions.ts +2306 -264
- package/src/routes/skill-content.ts +297 -0
- package/src/routes/skill-install-authority.ts +64 -0
- package/src/routes/skills.ts +62 -9
- package/src/routes/social.ts +46 -18
- package/src/routes/subscription-account-pools.ts +436 -0
- package/src/routes/subscription-pool-access.ts +126 -0
- package/src/routes/supergrok.ts +219 -303
- package/src/routes/transcription-recordings.ts +38 -3
- package/src/routes/transcriptions.ts +4 -0
- package/src/routes/usage-allowances.ts +378 -0
- package/src/routes/user-resource-authorities.ts +138 -0
- package/src/routes/video-generation.ts +14 -10
- package/src/routes/workspace-artifacts.ts +275 -69
- package/src/routes/workspace-capture.ts +21 -0
- package/src/routes/workspace-integrations.ts +576 -0
- package/src/routes/workspace-learning.ts +159 -0
- package/src/routes/workspace-model-providers.ts +148 -0
- package/src/routes/workspace-state.ts +38 -25
- package/src/routes/workspaces.ts +1004 -127
- package/src/sandbox/auth-callout.ts +96 -19
- package/src/sandbox/channel-a.ts +323 -24
- package/src/sandbox/connection-authority.ts +3 -0
- package/src/sandbox/enrollment.ts +81 -6
- package/src/sandbox/machines.ts +218 -76
- package/src/sandbox/metrics-ingestion.ts +411 -62
- package/src/sandbox/rematerialize.ts +121 -19
- package/src/sandbox/session-attach-variable-sets.ts +131 -0
- package/src/sandbox/viewer.ts +280 -25
- package/src/sandbox-file-artifacts.ts +413 -0
- package/src/scheduled-task-deletion.ts +138 -0
- package/src/session-create-observability.ts +46 -0
- package/src/session-realtime-context.ts +6 -3
- package/src/site-session-origin.ts +48 -0
- package/src/site-uploads.ts +224 -0
- package/src/slack-reaction-files.ts +16 -5
- package/src/temporal-schedule-cleanup.ts +13 -0
- package/src/temporal-schedule-sync.ts +74 -0
- package/src/transcription/providers/codex-subscription.ts +2 -0
- package/src/transcription/providers/openai.ts +1 -0
- package/src/transcription/providers/xai-subscription.ts +49 -3
- package/src/transcription/segmenter.ts +8 -2
- package/src/transcription/service.ts +43 -6
- package/src/work-discovery-observability.ts +121 -0
- package/src/workspace-artifact-content.ts +144 -0
- package/src/workspace-artifact-provenance.ts +104 -0
- package/src/workspace-delete-observability.ts +75 -0
- package/src/workspace-deletion.ts +73 -0
- package/src/workspace-state-projection.ts +18 -148
- package/src/workspace-tool-gateway-observability.ts +100 -0
- package/src/workspace-tool-gateway.ts +870 -0
- package/src/workspace-webhook-dispatch.ts +190 -0
- package/src/xai-subscription-auth.ts +9 -2
- package/dist/chunk-2PQMSRCB.js +0 -49759
- package/dist/chunk-2PQMSRCB.js.map +0 -1
- package/dist/routes/packs.d.ts +0 -3
- package/src/routes/packs.ts +0 -729
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
// FLAG GATE: the whole feature is behind sandboxSelfhostedEnabled (default OFF) —
|
|
29
29
|
// when off the routes 404 (the surface is invisible) and boot is unaffected.
|
|
30
30
|
|
|
31
|
-
import { randomBytes } from "node:crypto";
|
|
31
|
+
import { createPublicKey, randomBytes, verify } from "node:crypto";
|
|
32
32
|
import {
|
|
33
33
|
resolveEnrollmentSigningSecret,
|
|
34
34
|
resolveRelayTokenSecret,
|
|
@@ -36,10 +36,13 @@ import {
|
|
|
36
36
|
} from "@opengeni/config";
|
|
37
37
|
import {
|
|
38
38
|
DeviceEnrollmentState,
|
|
39
|
+
enrollmentRenewalProof,
|
|
39
40
|
signEnrollmentBearer,
|
|
40
41
|
signEnrollToken,
|
|
41
42
|
signRelayToken,
|
|
42
43
|
verifyEnrollToken,
|
|
44
|
+
verifyEnrollmentBearer,
|
|
45
|
+
type RenewEnrollmentRequest,
|
|
43
46
|
type DeviceEnrollmentLookupResponse,
|
|
44
47
|
type DeviceEnrollmentPollResponse,
|
|
45
48
|
type DeviceEnrollmentStartResponse,
|
|
@@ -71,7 +74,8 @@ export const DEVICE_POLL_INTERVAL_SECONDS = 5;
|
|
|
71
74
|
// The bearer the agent presents to the NATS auth-callout. A bring-your-own-compute
|
|
72
75
|
// machine is PERSISTENT (unlike an ephemeral Modal box, whose lifetime ~= an agent
|
|
73
76
|
// token's hour), so this is long-lived — 30 days, matching the relay token below —
|
|
74
|
-
// and re-minted on
|
|
77
|
+
// and renewed automatically by install-key proof, or re-minted on poll/re-enroll.
|
|
78
|
+
// The old 1-hour value (sized for a Modal
|
|
75
79
|
// box) caused a self-hosted agent to drop PERMANENTLY one hour after connecting: the
|
|
76
80
|
// bearer expired and the auth-callout rejected every reconnect ("re-enroll may be
|
|
77
81
|
// required"). A long-lived bearer is safe because the auth-callout RE-CHECKS the
|
|
@@ -83,10 +87,69 @@ export const ENROLLMENT_BEARER_TTL_SECONDS = 30 * 24 * 3600;
|
|
|
83
87
|
// NOT per-stream: the agent presents it on every channel registration for the life
|
|
84
88
|
// of its run, and the producer side has no per-viewer epoch fence (that is the
|
|
85
89
|
// VIEWER's `ogs_` token's job). So it is long-lived — 30 days — re-minted on every
|
|
86
|
-
// poll/re-enroll. The relay re-verifies it (authenticity + the channel-key ws+agent
|
|
90
|
+
// renewal/poll/re-enroll. The relay re-verifies it (authenticity + the channel-key ws+agent
|
|
87
91
|
// scope) on every StreamOpen; a revoked enrollment's machine goes offline at the
|
|
88
92
|
// control plane regardless, so a long-lived relay token cannot reach a dead agent.
|
|
89
93
|
export const RELAY_TOKEN_TTL_SECONDS = 30 * 24 * 3600;
|
|
94
|
+
|
|
95
|
+
/** Renew an existing grant, including after a long offline interval. The expired
|
|
96
|
+
* bearer is only an authenticated enrollment/generation locator here: current
|
|
97
|
+
* install-key possession and live enrollment authority are both required. Normal
|
|
98
|
+
* NATS/relay authentication continues to reject expired transport credentials.
|
|
99
|
+
* Nothing creates/reactivates an enrollment or changes its consent or scope. */
|
|
100
|
+
export async function renewEnrollmentCredentials(
|
|
101
|
+
services: EnrollmentServices,
|
|
102
|
+
input: RenewEnrollmentRequest,
|
|
103
|
+
nowSeconds = Math.floor(Date.now() / 1000),
|
|
104
|
+
): Promise<EnrollmentCredentialsResponse | null> {
|
|
105
|
+
if (Math.abs(nowSeconds - input.signedAt) > 120) return null;
|
|
106
|
+
const secret = resolveEnrollmentSigningSecret(services.settings);
|
|
107
|
+
if (!secret) return null;
|
|
108
|
+
const claims = await verifyEnrollmentBearer(secret, input.bearer, 0);
|
|
109
|
+
if (
|
|
110
|
+
!claims ||
|
|
111
|
+
claims.agentId !== claims.enrollmentId ||
|
|
112
|
+
claims.subjectPrefix !== `agent.${claims.workspaceId}.${claims.agentId}`
|
|
113
|
+
)
|
|
114
|
+
return null;
|
|
115
|
+
const enrollment = await getEnrollment(services.db, claims.workspaceId, claims.enrollmentId);
|
|
116
|
+
if (
|
|
117
|
+
!enrollment ||
|
|
118
|
+
enrollment.status !== "active" ||
|
|
119
|
+
enrollment.credentialGeneration !== claims.credentialGeneration
|
|
120
|
+
)
|
|
121
|
+
return null;
|
|
122
|
+
try {
|
|
123
|
+
const rawKey = Buffer.from(enrollment.pubkey, "base64");
|
|
124
|
+
const signature = Buffer.from(input.signature, "base64");
|
|
125
|
+
if (rawKey.length !== 32 || signature.length !== 64) return null;
|
|
126
|
+
const key = createPublicKey({
|
|
127
|
+
key: Buffer.concat([Buffer.from("302a300506032b6570032100", "hex"), rawKey]),
|
|
128
|
+
format: "der",
|
|
129
|
+
type: "spki",
|
|
130
|
+
});
|
|
131
|
+
if (
|
|
132
|
+
!verify(
|
|
133
|
+
null,
|
|
134
|
+
Buffer.from(enrollmentRenewalProof(input.bearer, input.signedAt)),
|
|
135
|
+
key,
|
|
136
|
+
signature,
|
|
137
|
+
)
|
|
138
|
+
)
|
|
139
|
+
return null;
|
|
140
|
+
} catch {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
// A concurrent revoke/re-enrollment still wins: issued credentials retain the
|
|
144
|
+
// captured generation, which the control-plane claim rechecks transactionally.
|
|
145
|
+
return buildEnrollmentCredentials(services, {
|
|
146
|
+
secret,
|
|
147
|
+
workspaceId: enrollment.workspaceId,
|
|
148
|
+
agentId: enrollment.id,
|
|
149
|
+
credentialGeneration: enrollment.credentialGeneration,
|
|
150
|
+
consentedScreenControl: enrollment.allowScreenControl,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
90
153
|
// The headless enroll token (`oget_`; design 11 §A2.1) TTL. 1h: long enough to
|
|
91
154
|
// script a fleet rollout, short enough to bound exposure of a workspace-scoped
|
|
92
155
|
// secret that IS the grant (no human approve). Re-mintable by an authorized user.
|
|
@@ -172,7 +235,7 @@ export async function startDeviceEnrollment(
|
|
|
172
235
|
throw lastError instanceof Error ? lastError : new Error("failed to start device enrollment");
|
|
173
236
|
}
|
|
174
237
|
|
|
175
|
-
const base = input.verificationOrigin.replace(
|
|
238
|
+
const base = input.verificationOrigin.replace(/\/+$/, "");
|
|
176
239
|
const verificationUri = `${base}/device`;
|
|
177
240
|
const verificationUriComplete = `${verificationUri}?user_code=${encodeURIComponent(request.userCode)}`;
|
|
178
241
|
return {
|
|
@@ -193,12 +256,18 @@ export async function approveDeviceEnrollment(
|
|
|
193
256
|
input: {
|
|
194
257
|
accountId: string;
|
|
195
258
|
workspaceId: string;
|
|
259
|
+
scope?: "organization" | "workspace" | "user";
|
|
260
|
+
allowOrganization?: boolean;
|
|
196
261
|
userCode: string;
|
|
197
262
|
allowScreenControl: boolean;
|
|
198
263
|
approvedBySubjectId: string;
|
|
199
264
|
approvedBySubjectLabel?: string | null;
|
|
200
265
|
},
|
|
201
|
-
): Promise<{
|
|
266
|
+
): Promise<{
|
|
267
|
+
enrollmentId: string;
|
|
268
|
+
sandboxId: string;
|
|
269
|
+
allowScreenControl: boolean;
|
|
270
|
+
} | null> {
|
|
202
271
|
const { db } = services;
|
|
203
272
|
const pending = await getPendingDeviceEnrollmentRequestByUserCode(
|
|
204
273
|
db,
|
|
@@ -213,6 +282,8 @@ export async function approveDeviceEnrollment(
|
|
|
213
282
|
const result = await approveDeviceEnrollmentRequest(db, {
|
|
214
283
|
accountId: input.accountId,
|
|
215
284
|
workspaceId: input.workspaceId,
|
|
285
|
+
...(input.scope ? { scope: input.scope } : {}),
|
|
286
|
+
allowOrganization: input.allowOrganization === true,
|
|
216
287
|
requestId: pending.id,
|
|
217
288
|
allowScreenControl: input.allowScreenControl,
|
|
218
289
|
approvedBySubjectId: input.approvedBySubjectId,
|
|
@@ -291,7 +362,11 @@ export async function denyDeviceEnrollment(
|
|
|
291
362
|
* mirror poll's "disabled" handling. The token value is NEVER logged. */
|
|
292
363
|
export async function mintEnrollToken(
|
|
293
364
|
services: EnrollmentServices,
|
|
294
|
-
input: {
|
|
365
|
+
input: {
|
|
366
|
+
accountId: string;
|
|
367
|
+
workspaceId: string;
|
|
368
|
+
allowScreenControl: boolean;
|
|
369
|
+
},
|
|
295
370
|
): Promise<MintEnrollTokenResponse | null> {
|
|
296
371
|
const { settings } = services;
|
|
297
372
|
const secret = resolveEnrollmentSigningSecret(settings);
|
package/src/sandbox/machines.ts
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
// apps/api/src/sandbox/machines.ts — the M10 Machines-DASHBOARD service (design
|
|
2
2
|
// §10.7). Builds the `MachinesResponse` the dashboard renders: the workspace's
|
|
3
3
|
// enrolled selfhosted machines, each enriched with
|
|
4
|
-
// * STATE —
|
|
5
|
-
// enrollment-derived
|
|
6
|
-
//
|
|
7
|
-
//
|
|
4
|
+
// * STATE — heartbeat + goodbye liveness (online/offline) overlaid with the
|
|
5
|
+
// enrollment-derived display reason (display_unavailable). This list does
|
|
6
|
+
// not ControlRpc-ping; attach, capability negotiation, and fleet tools
|
|
7
|
+
// still probe when they need a live responder.
|
|
8
8
|
// * METRICS — the latest machine_metrics_latest row (or null before a first
|
|
9
9
|
// heartbeat), projected to the contract's MetricSample;
|
|
10
10
|
// * sharedSessionCount — the lease refcount (how many sessions share this one
|
|
11
11
|
// whole machine, the maxSandboxes:1 disclosure).
|
|
12
|
-
// PLUS, when a session context is supplied, the session's synthetic
|
|
13
|
-
// box (isSessionGroup:true) + the active-sandbox pointer
|
|
12
|
+
// PLUS, when a session context is supplied, the session's synthetic managed
|
|
13
|
+
// group box (isSessionGroup:true) + the active-sandbox pointer
|
|
14
|
+
// (activeSandboxId/Epoch).
|
|
14
15
|
//
|
|
15
16
|
// This is workspace-scoped (perm enrollments:read) and flag-gated upstream
|
|
16
17
|
// (sandboxSelfhostedEnabled). It deliberately does NOT depend on a FleetContext
|
|
@@ -21,6 +22,7 @@
|
|
|
21
22
|
import type { Settings } from "@opengeni/config";
|
|
22
23
|
import {
|
|
23
24
|
getSession,
|
|
25
|
+
getLiveEnrollmentConnection,
|
|
24
26
|
listEnrollments,
|
|
25
27
|
listSandboxes,
|
|
26
28
|
readActiveSandbox,
|
|
@@ -30,32 +32,129 @@ import {
|
|
|
30
32
|
type EnrollmentRecord,
|
|
31
33
|
type MachineMetricsRow,
|
|
32
34
|
} from "@opengeni/db";
|
|
33
|
-
import type { EventBus } from "@opengeni/events";
|
|
34
35
|
import { MachineView, MetricSample, type MachinesResponse } from "@opengeni/contracts";
|
|
35
|
-
import {
|
|
36
|
-
|
|
37
|
-
selfhostedLiveness,
|
|
38
|
-
SelfhostedSession,
|
|
39
|
-
type ControlRpc,
|
|
40
|
-
type NatsRequestConnection,
|
|
41
|
-
} from "@opengeni/runtime/sandbox";
|
|
42
|
-
import { relayConfigFromSettings } from "@opengeni/core";
|
|
36
|
+
import { managedSessionGroupBackend, sessionGroupMachinePresentation } from "@opengeni/core";
|
|
37
|
+
import { selfhostedHeartbeatLiveness } from "@opengeni/runtime/sandbox";
|
|
43
38
|
|
|
44
39
|
export type MachinesServices = {
|
|
45
40
|
db: Database;
|
|
46
41
|
settings: Settings;
|
|
47
|
-
bus?: EventBus;
|
|
48
42
|
};
|
|
49
43
|
|
|
50
|
-
const
|
|
44
|
+
const ACTIVE_UPDATE_STATUSES = new Set([
|
|
45
|
+
"requested",
|
|
46
|
+
"accepted",
|
|
47
|
+
"waiting_for_idle",
|
|
48
|
+
"downloading",
|
|
49
|
+
"verifying",
|
|
50
|
+
"applying",
|
|
51
|
+
"restarting",
|
|
52
|
+
]);
|
|
51
53
|
|
|
52
|
-
function
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
function compareAgentVersions(left: string, right: string): number | null {
|
|
55
|
+
const parse = (value: string): { core: number[]; prerelease: string | null } | null => {
|
|
56
|
+
const match = /^(?:v)?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/.exec(value.trim());
|
|
57
|
+
if (!match) return null;
|
|
58
|
+
return {
|
|
59
|
+
core: [Number(match[1]), Number(match[2]), Number(match[3])],
|
|
60
|
+
prerelease: match[4] ?? null,
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
const a = parse(left);
|
|
64
|
+
const b = parse(right);
|
|
65
|
+
if (!a || !b) return null;
|
|
66
|
+
for (let index = 0; index < 3; index += 1) {
|
|
67
|
+
const delta = a.core[index]! - b.core[index]!;
|
|
68
|
+
if (delta !== 0) return Math.sign(delta);
|
|
69
|
+
}
|
|
70
|
+
if (a.prerelease === b.prerelease) return 0;
|
|
71
|
+
if (a.prerelease === null) return 1;
|
|
72
|
+
if (b.prerelease === null) return -1;
|
|
73
|
+
return a.prerelease.localeCompare(b.prerelease);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Older Mac updaters replace a single file inside a sealed app. They must
|
|
77
|
+
* bootstrap once through the official whole-app installer, never an RPC swap. */
|
|
78
|
+
export function machineUpdateBlockedReason(os: string, version: string | null): string | null {
|
|
79
|
+
if (os !== "macos") return null;
|
|
80
|
+
const order = version ? compareAgentVersions(version, "0.1.29") : null;
|
|
81
|
+
return order !== null && order >= 0
|
|
82
|
+
? null
|
|
83
|
+
: "Install Opengeni Agent 0.1.29 or newer with the official Mac installer first. This older updater cannot preserve the signed application.";
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function runtimeFor(settings: Settings, enrollment: EnrollmentRecord): MachineView["runtime"] {
|
|
87
|
+
const desiredVersion =
|
|
88
|
+
enrollment.agentUpdateChannel === "beta"
|
|
89
|
+
? (settings.agentBetaVersion ?? settings.agentStableVersion)
|
|
90
|
+
: settings.agentStableVersion;
|
|
91
|
+
const update = enrollment.agentUpdate;
|
|
92
|
+
const activeUpdate = update ? ACTIVE_UPDATE_STATUSES.has(update.status) : false;
|
|
93
|
+
const order =
|
|
94
|
+
enrollment.agentVersion && desiredVersion
|
|
95
|
+
? compareAgentVersions(enrollment.agentVersion, desiredVersion)
|
|
96
|
+
: null;
|
|
97
|
+
const versionState = activeUpdate
|
|
98
|
+
? "updating"
|
|
99
|
+
: update?.status === "failed"
|
|
100
|
+
? "update_failed"
|
|
101
|
+
: order === null
|
|
102
|
+
? "unknown"
|
|
103
|
+
: order === 0
|
|
104
|
+
? "current"
|
|
105
|
+
: order < 0
|
|
106
|
+
? "outdated"
|
|
107
|
+
: "ahead";
|
|
108
|
+
const capability = (name: string): boolean => enrollment.agentCapabilities[name] === true;
|
|
109
|
+
return {
|
|
110
|
+
installedVersion: enrollment.agentVersion,
|
|
111
|
+
binarySha256: enrollment.agentBinarySha256,
|
|
112
|
+
updateChannel: enrollment.agentUpdateChannel,
|
|
113
|
+
desiredVersion,
|
|
114
|
+
versionState,
|
|
115
|
+
updateBlockedReason: machineUpdateBlockedReason(enrollment.os, enrollment.agentVersion),
|
|
116
|
+
capabilities: {
|
|
117
|
+
exec: capability("exec"),
|
|
118
|
+
filesystem: capability("filesystem"),
|
|
119
|
+
git: capability("git"),
|
|
120
|
+
pty: capability("pty"),
|
|
121
|
+
desktop: capability("desktop"),
|
|
122
|
+
opStream: capability("opStream"),
|
|
123
|
+
browserBridge: capability("browserBridge"),
|
|
124
|
+
operationResourcePolicy: capability("operationResourcePolicy"),
|
|
125
|
+
operationCpuQuota: capability("operationCpuQuota"),
|
|
126
|
+
transactionalFsWrite: capability("transactionalFsWrite"),
|
|
127
|
+
},
|
|
128
|
+
update,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function connectionAuthorityFor(
|
|
133
|
+
enrollment: EnrollmentRecord | null,
|
|
134
|
+
liveConnection: EnrollmentRecord | null,
|
|
135
|
+
): MachineView["connectionAuthority"] {
|
|
136
|
+
if (!enrollment) {
|
|
137
|
+
return {
|
|
138
|
+
state: "not_applicable",
|
|
139
|
+
generation: 0,
|
|
140
|
+
supersededCount: 0,
|
|
141
|
+
leaseExpiresAt: null,
|
|
142
|
+
duplicateRunnerDeniedCount: 0,
|
|
143
|
+
duplicateRunnerDeniedAt: null,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
state: liveConnection
|
|
148
|
+
? "active"
|
|
149
|
+
: enrollment.connectionInstanceId && enrollment.connectionLeaseExpiresAt
|
|
150
|
+
? "expired"
|
|
151
|
+
: "unclaimed",
|
|
152
|
+
generation: enrollment.connectionGeneration,
|
|
153
|
+
supersededCount: Math.max(0, enrollment.connectionGeneration - 1),
|
|
154
|
+
leaseExpiresAt: enrollment.connectionLeaseExpiresAt,
|
|
155
|
+
duplicateRunnerDeniedCount: enrollment.connectionDuplicateDeniedCount,
|
|
156
|
+
duplicateRunnerDeniedAt: enrollment.connectionDuplicateDeniedAt,
|
|
157
|
+
};
|
|
59
158
|
}
|
|
60
159
|
|
|
61
160
|
/**
|
|
@@ -83,36 +182,8 @@ export function metricRowToSample(row: MachineMetricsRow): MetricSample {
|
|
|
83
182
|
});
|
|
84
183
|
}
|
|
85
184
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
* disambiguate a probe-miss into reconnecting vs offline). Mirrors the M7 fleet
|
|
89
|
-
* probe. A non-active enrollment is offline without a probe. */
|
|
90
|
-
async function probeEnrollment(
|
|
91
|
-
services: MachinesServices,
|
|
92
|
-
workspaceId: string,
|
|
93
|
-
enrollment: EnrollmentRecord,
|
|
94
|
-
): Promise<{
|
|
95
|
-
state: "online" | "reconnecting" | "offline";
|
|
96
|
-
consented: boolean;
|
|
97
|
-
hasDisplay: boolean;
|
|
98
|
-
}> {
|
|
99
|
-
const { settings, bus } = services;
|
|
100
|
-
let probeResponded = false;
|
|
101
|
-
if (enrollment.status === "active") {
|
|
102
|
-
const session = new SelfhostedSession({
|
|
103
|
-
workspaceId,
|
|
104
|
-
agentId: enrollment.id,
|
|
105
|
-
controlRpc: controlRpc(bus),
|
|
106
|
-
relay: relayConfigFromSettings(settings),
|
|
107
|
-
timeoutMs: PROBE_TIMEOUT_MS,
|
|
108
|
-
});
|
|
109
|
-
try {
|
|
110
|
-
probeResponded = await session.ping();
|
|
111
|
-
} catch {
|
|
112
|
-
probeResponded = false;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
const derived = selfhostedLiveness({
|
|
185
|
+
function enrollmentLiveness(enrollment: EnrollmentRecord) {
|
|
186
|
+
return selfhostedHeartbeatLiveness({
|
|
116
187
|
enrollment: {
|
|
117
188
|
status: enrollment.status,
|
|
118
189
|
exposure: enrollment.exposure,
|
|
@@ -122,16 +193,15 @@ async function probeEnrollment(
|
|
|
122
193
|
wentOfflineAt: enrollment.wentOfflineAt,
|
|
123
194
|
wentOfflineReason: enrollment.wentOfflineReason,
|
|
124
195
|
},
|
|
125
|
-
probeResponded,
|
|
126
196
|
});
|
|
127
|
-
return { state: derived.state, consented: derived.consented, hasDisplay: derived.hasDisplay };
|
|
128
197
|
}
|
|
129
198
|
|
|
130
199
|
/**
|
|
131
200
|
* Resolve the dashboard STATE of a machine. State reflects REACHABILITY + the
|
|
132
201
|
* VIEW plane only: an online machine with no display → `display_unavailable` (no
|
|
133
202
|
* desktop stream, but compute — exec/fs/git/terminal — still works); otherwise
|
|
134
|
-
* the liveness state (online/
|
|
203
|
+
* the liveness state (online/offline; list heartbeat never yields reconnecting).
|
|
204
|
+
* It deliberately does NOT fold
|
|
135
205
|
* in screen-control consent: a displayed machine can be VIEWED (read-only) and
|
|
136
206
|
* used for compute regardless of `allowScreenControl` — only INPUT (ComputerUse /
|
|
137
207
|
* an interactive stream) needs that consent, which is a per-capability concern
|
|
@@ -163,7 +233,12 @@ function machineStateFor(
|
|
|
163
233
|
*/
|
|
164
234
|
export async function listMachines(
|
|
165
235
|
services: MachinesServices,
|
|
166
|
-
input: {
|
|
236
|
+
input: {
|
|
237
|
+
accountId?: string;
|
|
238
|
+
workspaceId: string;
|
|
239
|
+
subjectId?: string;
|
|
240
|
+
sessionId?: string | null;
|
|
241
|
+
},
|
|
167
242
|
): Promise<MachinesResponse> {
|
|
168
243
|
const { db } = services;
|
|
169
244
|
const { workspaceId } = input;
|
|
@@ -183,45 +258,92 @@ export async function listMachines(
|
|
|
183
258
|
}
|
|
184
259
|
|
|
185
260
|
const machines: MachineView[] = [];
|
|
261
|
+
const groupBackend = session
|
|
262
|
+
? managedSessionGroupBackend(services.settings.sandboxBackend, session.sandboxBackend)
|
|
263
|
+
: null;
|
|
186
264
|
|
|
187
|
-
// The session's own group box (synthetic): the
|
|
188
|
-
//
|
|
189
|
-
|
|
265
|
+
// The session's own managed group box (synthetic): the sandbox a null active
|
|
266
|
+
// pointer routes to. A machine-home session uses the deployment's managed
|
|
267
|
+
// backend only after an explicit switch; none/selfhosted-only deployments do
|
|
268
|
+
// not invent a group they cannot establish.
|
|
269
|
+
if (session && groupBackend) {
|
|
190
270
|
const groupActive = activeSandboxId === null;
|
|
191
271
|
const groupLease = await readLease(db, workspaceId, session.sandboxGroupId);
|
|
272
|
+
const presentation = sessionGroupMachinePresentation(groupBackend);
|
|
273
|
+
const localHost = groupBackend === "local";
|
|
192
274
|
machines.push(
|
|
193
275
|
MachineView.parse({
|
|
194
276
|
sandboxId: session.sandboxGroupId,
|
|
195
277
|
enrollmentId: null,
|
|
196
|
-
name:
|
|
197
|
-
kind:
|
|
278
|
+
name: presentation.name,
|
|
279
|
+
kind: presentation.kind,
|
|
198
280
|
state: "online",
|
|
199
281
|
active: groupActive,
|
|
200
282
|
isSessionGroup: true,
|
|
201
283
|
workspaceGeneration: groupLease?.workspaceGeneration ?? null,
|
|
202
284
|
archiveGeneration: groupLease?.archiveGeneration ?? null,
|
|
203
285
|
archiveComplete: groupLease?.archiveComplete ?? false,
|
|
204
|
-
//
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
hasDisplay: false,
|
|
286
|
+
// A local sandbox is this machine. Other managed providers run a Linux box.
|
|
287
|
+
os: localHost ? process.platform : "linux",
|
|
288
|
+
arch: localHost ? process.arch : "x86_64",
|
|
289
|
+
hasDisplay: localHost,
|
|
209
290
|
desktopUnavailableReason: null,
|
|
210
291
|
allowScreenControl: false,
|
|
211
292
|
sharedSessionCount: 1,
|
|
212
293
|
lastSeenAt: null,
|
|
294
|
+
connectionAuthority: connectionAuthorityFor(null, null),
|
|
295
|
+
runtime: null,
|
|
296
|
+
operationPolicy: null,
|
|
213
297
|
metrics: null,
|
|
214
298
|
}),
|
|
215
299
|
);
|
|
216
300
|
}
|
|
217
301
|
|
|
218
302
|
// The workspace's enrolled selfhosted machines. One bulk metrics read joined
|
|
219
|
-
// onto the machines (no N+1).
|
|
220
|
-
const [
|
|
303
|
+
// onto the machines (no N+1). Liveness is the durable heartbeat cursor.
|
|
304
|
+
const [legacySandboxes, enrollments] = await Promise.all([
|
|
221
305
|
listSandboxes(db, workspaceId),
|
|
222
|
-
listEnrollments(
|
|
223
|
-
|
|
306
|
+
listEnrollments(
|
|
307
|
+
db,
|
|
308
|
+
input.accountId && input.subjectId
|
|
309
|
+
? {
|
|
310
|
+
accountId: input.accountId,
|
|
311
|
+
workspaceId,
|
|
312
|
+
subjectId: input.subjectId,
|
|
313
|
+
}
|
|
314
|
+
: workspaceId,
|
|
315
|
+
{ status: "active" },
|
|
316
|
+
),
|
|
224
317
|
]);
|
|
318
|
+
const metricsByEnrollment = new Map<string, MachineMetricsRow>();
|
|
319
|
+
for (const originWorkspaceId of new Set(enrollments.map((entry) => entry.workspaceId))) {
|
|
320
|
+
const originMetrics = await readMachineMetricsLatestForWorkspace(db, originWorkspaceId);
|
|
321
|
+
for (const [enrollmentId, metrics] of originMetrics) {
|
|
322
|
+
metricsByEnrollment.set(enrollmentId, metrics);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
const scopedSandboxes = enrollments.flatMap((enrollment) =>
|
|
326
|
+
enrollment.sandboxId
|
|
327
|
+
? [
|
|
328
|
+
{
|
|
329
|
+
id: enrollment.sandboxId,
|
|
330
|
+
accountId: enrollment.accountId,
|
|
331
|
+
workspaceId: enrollment.workspaceId,
|
|
332
|
+
kind: "selfhosted" as const,
|
|
333
|
+
name: enrollment.sandboxName ?? `${enrollment.os} machine`,
|
|
334
|
+
enrollmentId: enrollment.id,
|
|
335
|
+
createdAt: enrollment.createdAt,
|
|
336
|
+
updatedAt: enrollment.updatedAt,
|
|
337
|
+
},
|
|
338
|
+
]
|
|
339
|
+
: [],
|
|
340
|
+
);
|
|
341
|
+
const sandboxes = [
|
|
342
|
+
...legacySandboxes.filter(
|
|
343
|
+
(sandbox) => !scopedSandboxes.some((scoped) => scoped.id === sandbox.id),
|
|
344
|
+
),
|
|
345
|
+
...scopedSandboxes,
|
|
346
|
+
];
|
|
225
347
|
const enrollmentById = new Map(enrollments.map((e) => [e.id, e]));
|
|
226
348
|
|
|
227
349
|
const machineViews = await Promise.all(
|
|
@@ -233,11 +355,26 @@ export async function listMachines(
|
|
|
233
355
|
if (!enrollment) {
|
|
234
356
|
return null;
|
|
235
357
|
}
|
|
236
|
-
const [
|
|
237
|
-
|
|
238
|
-
|
|
358
|
+
const [liveConnection, lease] = await Promise.all([
|
|
359
|
+
enrollment.connectionInstanceId &&
|
|
360
|
+
enrollment.connectionLeaseExpiresAt &&
|
|
361
|
+
Date.parse(enrollment.connectionLeaseExpiresAt) > Date.now()
|
|
362
|
+
? Promise.resolve(enrollment)
|
|
363
|
+
: getLiveEnrollmentConnection(
|
|
364
|
+
db,
|
|
365
|
+
input.accountId && input.subjectId
|
|
366
|
+
? {
|
|
367
|
+
accountId: input.accountId,
|
|
368
|
+
workspaceId,
|
|
369
|
+
subjectId: input.subjectId,
|
|
370
|
+
}
|
|
371
|
+
: enrollment.workspaceId,
|
|
372
|
+
enrollment.id,
|
|
373
|
+
),
|
|
374
|
+
readLease(db, enrollment.workspaceId, sandbox.id),
|
|
239
375
|
]);
|
|
240
|
-
const
|
|
376
|
+
const liveness = enrollmentLiveness(enrollment);
|
|
377
|
+
const state = machineStateFor(liveness.state, liveness.hasDisplay);
|
|
241
378
|
|
|
242
379
|
// sharedSessionCount = the lease refcount for this machine's group. The
|
|
243
380
|
// selfhosted sandbox id IS the lease group key (maxSandboxes:1, N sessions
|
|
@@ -248,6 +385,8 @@ export async function listMachines(
|
|
|
248
385
|
return MachineView.parse({
|
|
249
386
|
sandboxId: sandbox.id,
|
|
250
387
|
enrollmentId: enrollment.id,
|
|
388
|
+
scope: enrollment.scope,
|
|
389
|
+
generation: enrollment.generation,
|
|
251
390
|
name: sandbox.name,
|
|
252
391
|
kind: "selfhosted",
|
|
253
392
|
state,
|
|
@@ -263,6 +402,9 @@ export async function listMachines(
|
|
|
263
402
|
allowScreenControl: enrollment.allowScreenControl,
|
|
264
403
|
sharedSessionCount,
|
|
265
404
|
lastSeenAt: enrollment.lastSeenAt,
|
|
405
|
+
connectionAuthority: connectionAuthorityFor(enrollment, liveConnection),
|
|
406
|
+
runtime: runtimeFor(services.settings, enrollment),
|
|
407
|
+
operationPolicy: enrollment.operationPolicy,
|
|
266
408
|
metrics: metricsRow ? metricRowToSample(metricsRow) : null,
|
|
267
409
|
});
|
|
268
410
|
}),
|