@opengeni/api-router 0.30.3 → 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-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 +1091 -162
- 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 +24 -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 +107 -9
- 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 +59 -2
- 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/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 +1967 -252
- 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 +28 -3
- 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 +717 -225
- 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 +3167 -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 -43
- 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 +780 -112
- 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 +1039 -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 +267 -33
- 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-WCXHI3FF.js +0 -49920
- package/dist/chunk-WCXHI3FF.js.map +0 -1
- package/dist/routes/packs.d.ts +0 -3
- package/src/routes/packs.ts +0 -729
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
} from "@opengeni/contracts";
|
|
7
7
|
import {
|
|
8
8
|
getVideoGenerationOperationSummary,
|
|
9
|
+
withSessionRlsActorContext,
|
|
9
10
|
getWorkspaceVercelAiGatewayConnectionMetadata,
|
|
10
11
|
getWorkspaceVideoGenerationPolicy,
|
|
11
12
|
updateWorkspaceVideoGenerationPolicy,
|
|
@@ -14,6 +15,9 @@ import {
|
|
|
14
15
|
} from "@opengeni/db";
|
|
15
16
|
import {
|
|
16
17
|
requireAccessGrant,
|
|
18
|
+
requireAccessGrantAuthorization,
|
|
19
|
+
fileOwnerContextForAccess,
|
|
20
|
+
requireWorkspaceSettingsGrant,
|
|
17
21
|
VIDEO_GENERATION_MODEL_CATALOG,
|
|
18
22
|
videoGenerationModelSupportsFundingSource,
|
|
19
23
|
videoGenerationCapabilitiesForPolicy,
|
|
@@ -21,6 +25,7 @@ import {
|
|
|
21
25
|
} from "@opengeni/core";
|
|
22
26
|
import type { Hono } from "hono";
|
|
23
27
|
import { HTTPException } from "hono/http-exception";
|
|
28
|
+
import { parseRequestJson } from "../http/request-body";
|
|
24
29
|
|
|
25
30
|
export function registerVideoGenerationRoutes(app: Hono, deps: ApiRouteDeps): void {
|
|
26
31
|
app.get("/v1/workspaces/:workspaceId/video-generation", async (c) => {
|
|
@@ -58,8 +63,8 @@ export function registerVideoGenerationRoutes(app: Hono, deps: ApiRouteDeps): vo
|
|
|
58
63
|
|
|
59
64
|
app.put("/v1/workspaces/:workspaceId/video-generation/policy", async (c) => {
|
|
60
65
|
const workspaceId = c.req.param("workspaceId");
|
|
61
|
-
const grant = await
|
|
62
|
-
const payload =
|
|
66
|
+
const grant = await requireWorkspaceSettingsGrant(c, deps, workspaceId);
|
|
67
|
+
const payload = await parseRequestJson(c, UpdateVideoGenerationPolicyRequest);
|
|
63
68
|
const [connection, supergrokConfigured] = await Promise.all([
|
|
64
69
|
getWorkspaceVercelAiGatewayConnectionMetadata(deps.db, workspaceId),
|
|
65
70
|
workspaceXaiSubscriptionActive(deps.db, deps.settings, workspaceId, grant.subjectId),
|
|
@@ -107,11 +112,10 @@ export function registerVideoGenerationRoutes(app: Hono, deps: ApiRouteDeps): vo
|
|
|
107
112
|
|
|
108
113
|
app.get("/v1/workspaces/:workspaceId/video-generation/operations/:operationId", async (c) => {
|
|
109
114
|
const workspaceId = c.req.param("workspaceId");
|
|
110
|
-
await
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
workspaceId,
|
|
114
|
-
c.req.param("operationId"),
|
|
115
|
+
const access = await requireAccessGrantAuthorization(c, deps, workspaceId, "workspace:read");
|
|
116
|
+
const actor = await fileOwnerContextForAccess(deps, access, "workspace:read");
|
|
117
|
+
const summary = await withSessionRlsActorContext(actor, () =>
|
|
118
|
+
getVideoGenerationOperationSummary(deps.db, workspaceId, c.req.param("operationId")),
|
|
115
119
|
);
|
|
116
120
|
if (!summary)
|
|
117
121
|
throw new HTTPException(404, {
|
|
@@ -133,12 +137,12 @@ function videoGenerationFundingOptions(input: {
|
|
|
133
137
|
return [
|
|
134
138
|
{
|
|
135
139
|
source: "opengeni_credits" as const,
|
|
136
|
-
label: "
|
|
137
|
-
description: "Uses
|
|
140
|
+
label: "Opengeni",
|
|
141
|
+
description: "Uses Opengeni credits through the managed Gateway route.",
|
|
138
142
|
available: input.managedConfigured,
|
|
139
143
|
unavailableReason: input.managedConfigured
|
|
140
144
|
? null
|
|
141
|
-
: "
|
|
145
|
+
: "Opengeni-managed video generation is not configured.",
|
|
142
146
|
},
|
|
143
147
|
{
|
|
144
148
|
source: "supergrok_subscription" as const,
|
|
@@ -3,21 +3,32 @@ import {
|
|
|
3
3
|
CreateWorkspaceArtifactRequest,
|
|
4
4
|
PublishWorkspaceArtifactVersionRequest,
|
|
5
5
|
RollbackWorkspaceArtifactRequest,
|
|
6
|
+
SetWorkspaceArtifactStatusRequest,
|
|
6
7
|
WorkspaceArtifactContentResponse,
|
|
7
8
|
WorkspaceArtifactDetailResponse,
|
|
8
9
|
WorkspaceArtifactListQuery,
|
|
9
10
|
WorkspaceArtifactListResponse,
|
|
10
11
|
WorkspaceArtifactMutationResponse,
|
|
11
12
|
normalizeWorkspaceArtifactSlug,
|
|
13
|
+
type AccessGrant,
|
|
12
14
|
} from "@opengeni/contracts";
|
|
13
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
requireAccessGrant,
|
|
17
|
+
requireAccessGrantAuthorization,
|
|
18
|
+
requireSessionAuthorization,
|
|
19
|
+
SessionAuthorizationDeniedError,
|
|
20
|
+
SessionAuthorizationUnavailableError,
|
|
21
|
+
type ApiRouteDeps,
|
|
22
|
+
} from "@opengeni/core";
|
|
14
23
|
import {
|
|
15
24
|
createWorkspaceArtifact,
|
|
16
25
|
getWorkspaceArtifact,
|
|
17
26
|
getWorkspaceArtifactContentRef,
|
|
18
27
|
listWorkspaceArtifacts,
|
|
28
|
+
nestedPostgresSqlState,
|
|
19
29
|
publishWorkspaceArtifactVersion,
|
|
20
30
|
rollbackWorkspaceArtifact,
|
|
31
|
+
setWorkspaceArtifactStatus,
|
|
21
32
|
WorkspaceArtifactConflictError,
|
|
22
33
|
WorkspaceArtifactNotFoundError,
|
|
23
34
|
WorkspaceArtifactOperationError,
|
|
@@ -25,10 +36,22 @@ import {
|
|
|
25
36
|
import type { Context, Hono } from "hono";
|
|
26
37
|
import { HTTPException } from "hono/http-exception";
|
|
27
38
|
import { z } from "zod";
|
|
39
|
+
import { readWorkspaceArtifactContent } from "../workspace-artifact-content";
|
|
40
|
+
import { userContentDispositionHeaders } from "../http/user-content";
|
|
41
|
+
import {
|
|
42
|
+
projectWorkspaceArtifactDetailProvenance,
|
|
43
|
+
projectWorkspaceArtifactMutationProvenance,
|
|
44
|
+
redactWorkspaceArtifactListProvenance,
|
|
45
|
+
} from "../workspace-artifact-provenance";
|
|
46
|
+
|
|
47
|
+
import {
|
|
48
|
+
prepareWorkspaceArtifactPublication,
|
|
49
|
+
prepareWorkspaceArtifactUpload,
|
|
50
|
+
workspaceArtifactDownloads,
|
|
51
|
+
readArtifactObject,
|
|
52
|
+
} from "../site-uploads";
|
|
28
53
|
|
|
29
54
|
const ArtifactId = z.string().uuid();
|
|
30
|
-
const encoder = new TextEncoder();
|
|
31
|
-
const decoder = new TextDecoder("utf-8", { fatal: true });
|
|
32
55
|
|
|
33
56
|
async function body<S extends z.ZodType>(context: Context, schema: S): Promise<z.infer<S>> {
|
|
34
57
|
const parsed = schema.safeParse(await context.req.json().catch(() => null));
|
|
@@ -36,13 +59,20 @@ async function body<S extends z.ZodType>(context: Context, schema: S): Promise<z
|
|
|
36
59
|
return parsed.data;
|
|
37
60
|
}
|
|
38
61
|
|
|
62
|
+
function parseVersionId(value: string | undefined): string | undefined {
|
|
63
|
+
if (value !== undefined && !ArtifactId.safeParse(value).success) {
|
|
64
|
+
throw new HTTPException(422, { message: "Invalid artifact version id" });
|
|
65
|
+
}
|
|
66
|
+
return value;
|
|
67
|
+
}
|
|
68
|
+
|
|
39
69
|
function artifactId(context: Context): string {
|
|
40
70
|
const parsed = ArtifactId.safeParse(context.req.param("artifactId"));
|
|
41
71
|
if (!parsed.success) throw new HTTPException(422, { message: "Invalid artifact id" });
|
|
42
72
|
return parsed.data;
|
|
43
73
|
}
|
|
44
74
|
|
|
45
|
-
function
|
|
75
|
+
export function workspaceArtifactErrorResponse(context: Context, error: unknown): Response {
|
|
46
76
|
if (error instanceof WorkspaceArtifactNotFoundError) {
|
|
47
77
|
return context.json({ code: "WORKSPACE_ARTIFACT_NOT_FOUND", message: error.message }, 404);
|
|
48
78
|
}
|
|
@@ -62,41 +92,28 @@ function errorResponse(context: Context, error: unknown): Response {
|
|
|
62
92
|
422,
|
|
63
93
|
);
|
|
64
94
|
}
|
|
65
|
-
if (
|
|
95
|
+
if (nestedPostgresSqlState(error) === "23505") {
|
|
66
96
|
return context.json(
|
|
67
|
-
{
|
|
97
|
+
{
|
|
98
|
+
code: "WORKSPACE_ARTIFACT_CONFLICT",
|
|
99
|
+
message: "Artifact slug or operation already exists",
|
|
100
|
+
},
|
|
68
101
|
409,
|
|
69
102
|
);
|
|
70
103
|
}
|
|
71
104
|
throw error;
|
|
72
105
|
}
|
|
73
106
|
|
|
74
|
-
function
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
contentSha256: sha256,
|
|
80
|
-
sizeBytes: bytes.byteLength,
|
|
81
|
-
contentKey: `workspaces/${workspaceId}/workspace-artifacts/blobs/${sha256}.html`,
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function prepareHtml(deps: ApiRouteDeps, workspaceId: string, html: string) {
|
|
107
|
+
function prepareContent(
|
|
108
|
+
deps: ApiRouteDeps,
|
|
109
|
+
grant: AccessGrant,
|
|
110
|
+
input: Parameters<typeof prepareWorkspaceArtifactPublication>[2],
|
|
111
|
+
) {
|
|
86
112
|
if (!deps.objectStorage)
|
|
87
|
-
throw new HTTPException(503, {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
persistContent: async () => {
|
|
92
|
-
await deps.objectStorage!.putObject({
|
|
93
|
-
key: content.contentKey,
|
|
94
|
-
contentType: "text/html; charset=utf-8",
|
|
95
|
-
body: content.bytes,
|
|
96
|
-
sha256: content.contentSha256,
|
|
97
|
-
});
|
|
98
|
-
},
|
|
99
|
-
};
|
|
113
|
+
throw new HTTPException(503, {
|
|
114
|
+
message: "Object storage is not configured",
|
|
115
|
+
});
|
|
116
|
+
return prepareWorkspaceArtifactPublication(deps, grant, input);
|
|
100
117
|
}
|
|
101
118
|
|
|
102
119
|
function provenance(subjectId: string, idempotencyKey: string) {
|
|
@@ -111,49 +128,138 @@ function provenance(subjectId: string, idempotencyKey: string) {
|
|
|
111
128
|
};
|
|
112
129
|
}
|
|
113
130
|
|
|
131
|
+
async function canReadProvenanceSession(
|
|
132
|
+
deps: ApiRouteDeps,
|
|
133
|
+
grant: AccessGrant,
|
|
134
|
+
sessionId: string,
|
|
135
|
+
): Promise<boolean> {
|
|
136
|
+
try {
|
|
137
|
+
await requireSessionAuthorization(deps, grant, {
|
|
138
|
+
sessionId,
|
|
139
|
+
operation: "session.read",
|
|
140
|
+
surface: "http",
|
|
141
|
+
});
|
|
142
|
+
return true;
|
|
143
|
+
} catch (error) {
|
|
144
|
+
if (error instanceof SessionAuthorizationDeniedError) return false;
|
|
145
|
+
if (error instanceof SessionAuthorizationUnavailableError) {
|
|
146
|
+
throw new HTTPException(503, {
|
|
147
|
+
message: "Session authorization is unavailable",
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
throw error;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async function mutationResponse(
|
|
155
|
+
deps: ApiRouteDeps,
|
|
156
|
+
grant: AccessGrant,
|
|
157
|
+
response: WorkspaceArtifactMutationResponse,
|
|
158
|
+
): Promise<WorkspaceArtifactMutationResponse> {
|
|
159
|
+
return WorkspaceArtifactMutationResponse.parse(
|
|
160
|
+
await projectWorkspaceArtifactMutationProvenance(response, (sessionId) =>
|
|
161
|
+
canReadProvenanceSession(deps, grant, sessionId),
|
|
162
|
+
),
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
114
166
|
export function registerWorkspaceArtifactRoutes(app: Hono, deps: ApiRouteDeps): void {
|
|
115
167
|
// `published-artifacts` deliberately avoids the existing `/artifacts/:id`
|
|
116
168
|
// retained-output API. The product route remains simply `/artifacts`.
|
|
117
169
|
const base = "/v1/workspaces/:workspaceId/published-artifacts";
|
|
118
170
|
|
|
119
|
-
app.
|
|
171
|
+
app.post(`${base}/uploads`, async (context) => {
|
|
172
|
+
const grant = await requireAccessGrant(
|
|
173
|
+
context,
|
|
174
|
+
deps,
|
|
175
|
+
context.req.param("workspaceId"),
|
|
176
|
+
"artifacts:publish",
|
|
177
|
+
);
|
|
178
|
+
return context.json(await prepareWorkspaceArtifactUpload(deps, grant));
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
app.get(`${base}/:artifactId/downloads`, async (context) => {
|
|
120
182
|
const workspaceId = context.req.param("workspaceId");
|
|
121
183
|
await requireAccessGrant(context, deps, workspaceId, "artifacts:read");
|
|
184
|
+
if (!deps.objectStorage)
|
|
185
|
+
throw new HTTPException(503, {
|
|
186
|
+
message: "Object storage is not configured",
|
|
187
|
+
});
|
|
188
|
+
const ref = await getWorkspaceArtifactContentRef(
|
|
189
|
+
deps.db,
|
|
190
|
+
workspaceId,
|
|
191
|
+
artifactId(context),
|
|
192
|
+
parseVersionId(context.req.query("versionId")),
|
|
193
|
+
);
|
|
194
|
+
return context.json(await workspaceArtifactDownloads(deps.objectStorage, ref, "public"));
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
app.get(base, async (context) => {
|
|
198
|
+
const workspaceId = context.req.param("workspaceId");
|
|
199
|
+
const grant = await requireAccessGrant(context, deps, workspaceId, "artifacts:read");
|
|
122
200
|
const query = WorkspaceArtifactListQuery.safeParse({
|
|
123
201
|
limit: context.req.query("limit"),
|
|
124
202
|
cursor: context.req.query("cursor"),
|
|
203
|
+
status: context.req.query("status"),
|
|
204
|
+
sourceSessionId: context.req.query("sourceSessionId"),
|
|
125
205
|
});
|
|
126
206
|
if (!query.success) throw new HTTPException(422, { message: "Invalid artifact list query" });
|
|
207
|
+
if (
|
|
208
|
+
query.data.sourceSessionId &&
|
|
209
|
+
!(await canReadProvenanceSession(deps, grant, query.data.sourceSessionId))
|
|
210
|
+
) {
|
|
211
|
+
throw new HTTPException(404, { message: "Session not found" });
|
|
212
|
+
}
|
|
127
213
|
try {
|
|
128
214
|
return context.json(
|
|
129
215
|
WorkspaceArtifactListResponse.parse(
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
216
|
+
redactWorkspaceArtifactListProvenance(
|
|
217
|
+
await listWorkspaceArtifacts(deps.db, workspaceId, {
|
|
218
|
+
limit: query.data.limit,
|
|
219
|
+
...(query.data.cursor ? { cursor: query.data.cursor } : {}),
|
|
220
|
+
...(query.data.status ? { status: query.data.status } : {}),
|
|
221
|
+
...(query.data.sourceSessionId
|
|
222
|
+
? { sourceSessionId: query.data.sourceSessionId }
|
|
223
|
+
: {}),
|
|
224
|
+
}),
|
|
225
|
+
),
|
|
134
226
|
),
|
|
135
227
|
);
|
|
136
228
|
} catch (error) {
|
|
137
|
-
return
|
|
229
|
+
return workspaceArtifactErrorResponse(context, error);
|
|
138
230
|
}
|
|
139
231
|
});
|
|
140
232
|
|
|
141
233
|
app.post(base, async (context) => {
|
|
142
234
|
const workspaceId = context.req.param("workspaceId");
|
|
143
|
-
const
|
|
235
|
+
const authorization = await requireAccessGrantAuthorization(
|
|
236
|
+
context,
|
|
237
|
+
deps,
|
|
238
|
+
workspaceId,
|
|
239
|
+
"artifacts:publish",
|
|
240
|
+
);
|
|
241
|
+
const grant = authorization.grant;
|
|
144
242
|
const request = await body(context, CreateWorkspaceArtifactRequest);
|
|
145
243
|
const id = crypto.randomUUID();
|
|
146
244
|
const slugBase = request.slug ?? (normalizeWorkspaceArtifactSlug(request.title) || "artifact");
|
|
147
245
|
const slug = request.slug ?? `${slugBase.slice(0, 87)}-${id.slice(0, 8)}`;
|
|
148
|
-
const content = prepareHtml(deps, workspaceId, request.html);
|
|
149
246
|
try {
|
|
247
|
+
const content = await prepareContent(deps, grant, {
|
|
248
|
+
...(request.html !== undefined ? { html: request.html } : {}),
|
|
249
|
+
...(request.uploadId ? { uploadId: request.uploadId } : {}),
|
|
250
|
+
...(request.source ? { source: request.source } : {}),
|
|
251
|
+
...(request.requestedTools ? { requestedTools: request.requestedTools } : {}),
|
|
252
|
+
});
|
|
150
253
|
return context.json(
|
|
151
|
-
|
|
254
|
+
await mutationResponse(
|
|
255
|
+
deps,
|
|
256
|
+
grant,
|
|
152
257
|
await createWorkspaceArtifact(deps.db, {
|
|
153
258
|
accountId: grant.accountId,
|
|
154
259
|
workspaceId,
|
|
155
260
|
artifactId: id,
|
|
156
261
|
slug,
|
|
262
|
+
requestedSlug: request.slug ?? null,
|
|
157
263
|
title: request.title,
|
|
158
264
|
description: request.description ?? null,
|
|
159
265
|
...content,
|
|
@@ -163,33 +269,82 @@ export function registerWorkspaceArtifactRoutes(app: Hono, deps: ApiRouteDeps):
|
|
|
163
269
|
201,
|
|
164
270
|
);
|
|
165
271
|
} catch (error) {
|
|
166
|
-
return
|
|
272
|
+
return workspaceArtifactErrorResponse(context, error);
|
|
167
273
|
}
|
|
168
274
|
});
|
|
169
275
|
|
|
170
276
|
app.get(`${base}/:artifactId`, async (context) => {
|
|
171
277
|
const workspaceId = context.req.param("workspaceId");
|
|
172
|
-
await requireAccessGrant(context, deps, workspaceId, "artifacts:read");
|
|
278
|
+
const grant = await requireAccessGrant(context, deps, workspaceId, "artifacts:read");
|
|
173
279
|
try {
|
|
280
|
+
const detail = await getWorkspaceArtifact(deps.db, workspaceId, artifactId(context));
|
|
174
281
|
return context.json(
|
|
175
282
|
WorkspaceArtifactDetailResponse.parse(
|
|
176
|
-
await
|
|
283
|
+
await projectWorkspaceArtifactDetailProvenance(detail, (sessionId) =>
|
|
284
|
+
canReadProvenanceSession(deps, grant, sessionId),
|
|
285
|
+
),
|
|
177
286
|
),
|
|
178
287
|
);
|
|
179
288
|
} catch (error) {
|
|
180
|
-
return
|
|
289
|
+
return workspaceArtifactErrorResponse(context, error);
|
|
181
290
|
}
|
|
182
291
|
});
|
|
183
292
|
|
|
293
|
+
app.get(`${base}/:artifactId/html`, async (context) => {
|
|
294
|
+
const workspaceId = context.req.param("workspaceId");
|
|
295
|
+
await requireAccessGrant(context, deps, workspaceId, "artifacts:read");
|
|
296
|
+
if (!deps.objectStorage)
|
|
297
|
+
throw new HTTPException(503, {
|
|
298
|
+
message: "Object storage is not configured",
|
|
299
|
+
});
|
|
300
|
+
const ref = await getWorkspaceArtifactContentRef(
|
|
301
|
+
deps.db,
|
|
302
|
+
workspaceId,
|
|
303
|
+
artifactId(context),
|
|
304
|
+
parseVersionId(context.req.query("versionId")),
|
|
305
|
+
);
|
|
306
|
+
const iterator = readArtifactObject(deps.objectStorage, ref.contentKey);
|
|
307
|
+
return new Response(
|
|
308
|
+
new ReadableStream({
|
|
309
|
+
async pull(controller) {
|
|
310
|
+
try {
|
|
311
|
+
const item = await iterator.next();
|
|
312
|
+
if (item.done) controller.close();
|
|
313
|
+
else controller.enqueue(item.value);
|
|
314
|
+
} catch (error) {
|
|
315
|
+
controller.error(error);
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
async cancel() {
|
|
319
|
+
await iterator.return();
|
|
320
|
+
},
|
|
321
|
+
}),
|
|
322
|
+
{
|
|
323
|
+
headers: {
|
|
324
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
325
|
+
"Cache-Control": "private, no-store",
|
|
326
|
+
// A Site runs its own scripts, but only inside an opaque origin: no
|
|
327
|
+
// same-origin access to the console, and no cross-site embedding.
|
|
328
|
+
"Content-Security-Policy": "sandbox allow-scripts",
|
|
329
|
+
"Cross-Origin-Resource-Policy": "same-origin",
|
|
330
|
+
"X-Content-Type-Options": "nosniff",
|
|
331
|
+
// Clients read this HTML with fetch and render it in their own frame
|
|
332
|
+
// (the console uses srcdoc). Opening the raw URL downloads it rather
|
|
333
|
+
// than running a publisher-authored page at an app-origin URL.
|
|
334
|
+
...userContentDispositionHeaders("text/html", "site.html"),
|
|
335
|
+
},
|
|
336
|
+
},
|
|
337
|
+
);
|
|
338
|
+
});
|
|
339
|
+
|
|
184
340
|
app.get(`${base}/:artifactId/content`, async (context) => {
|
|
185
341
|
const workspaceId = context.req.param("workspaceId");
|
|
186
342
|
await requireAccessGrant(context, deps, workspaceId, "artifacts:read");
|
|
187
343
|
if (!deps.objectStorage)
|
|
188
|
-
throw new HTTPException(503, {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
}
|
|
344
|
+
throw new HTTPException(503, {
|
|
345
|
+
message: "Object storage is not configured",
|
|
346
|
+
});
|
|
347
|
+
const parsedVersion = parseVersionId(context.req.query("versionId"));
|
|
193
348
|
try {
|
|
194
349
|
const ref = await getWorkspaceArtifactContentRef(
|
|
195
350
|
deps.db,
|
|
@@ -197,17 +352,14 @@ export function registerWorkspaceArtifactRoutes(app: Hono, deps: ApiRouteDeps):
|
|
|
197
352
|
artifactId(context),
|
|
198
353
|
parsedVersion,
|
|
199
354
|
);
|
|
200
|
-
|
|
201
|
-
if (!object) throw new HTTPException(503, { message: "Artifact content is unavailable" });
|
|
202
|
-
const actualHash = createHash("sha256").update(object.bytes).digest("hex");
|
|
203
|
-
if (actualHash !== ref.version.contentSha256) {
|
|
204
|
-
throw new HTTPException(503, { message: "Artifact content failed integrity verification" });
|
|
205
|
-
}
|
|
206
|
-
let html: string;
|
|
355
|
+
let content: Awaited<ReturnType<typeof readWorkspaceArtifactContent>>;
|
|
207
356
|
try {
|
|
208
|
-
|
|
209
|
-
} catch {
|
|
210
|
-
throw new HTTPException(503, {
|
|
357
|
+
content = await readWorkspaceArtifactContent(deps.objectStorage, ref);
|
|
358
|
+
} catch (error) {
|
|
359
|
+
throw new HTTPException(503, {
|
|
360
|
+
message: error instanceof Error ? error.message : "Artifact content is unavailable",
|
|
361
|
+
cause: error,
|
|
362
|
+
});
|
|
211
363
|
}
|
|
212
364
|
return context.json(
|
|
213
365
|
WorkspaceArtifactContentResponse.parse({
|
|
@@ -215,23 +367,36 @@ export function registerWorkspaceArtifactRoutes(app: Hono, deps: ApiRouteDeps):
|
|
|
215
367
|
versionId: ref.version.id,
|
|
216
368
|
contentType: "text/html",
|
|
217
369
|
contentSha256: ref.version.contentSha256,
|
|
218
|
-
|
|
370
|
+
...content,
|
|
219
371
|
}),
|
|
220
372
|
);
|
|
221
373
|
} catch (error) {
|
|
222
|
-
return
|
|
374
|
+
return workspaceArtifactErrorResponse(context, error);
|
|
223
375
|
}
|
|
224
376
|
});
|
|
225
377
|
|
|
226
378
|
app.post(`${base}/:artifactId/versions`, async (context) => {
|
|
227
379
|
const workspaceId = context.req.param("workspaceId");
|
|
228
|
-
const
|
|
380
|
+
const authorization = await requireAccessGrantAuthorization(
|
|
381
|
+
context,
|
|
382
|
+
deps,
|
|
383
|
+
workspaceId,
|
|
384
|
+
"artifacts:publish",
|
|
385
|
+
);
|
|
386
|
+
const grant = authorization.grant;
|
|
229
387
|
const request = await body(context, PublishWorkspaceArtifactVersionRequest);
|
|
230
388
|
const id = artifactId(context);
|
|
231
|
-
const content = prepareHtml(deps, workspaceId, request.html);
|
|
232
389
|
try {
|
|
390
|
+
const content = await prepareContent(deps, grant, {
|
|
391
|
+
...(request.html !== undefined ? { html: request.html } : {}),
|
|
392
|
+
...(request.uploadId ? { uploadId: request.uploadId } : {}),
|
|
393
|
+
...(request.source ? { source: request.source } : {}),
|
|
394
|
+
...(request.requestedTools ? { requestedTools: request.requestedTools } : {}),
|
|
395
|
+
});
|
|
233
396
|
return context.json(
|
|
234
|
-
|
|
397
|
+
await mutationResponse(
|
|
398
|
+
deps,
|
|
399
|
+
grant,
|
|
235
400
|
await publishWorkspaceArtifactVersion(deps.db, {
|
|
236
401
|
accountId: grant.accountId,
|
|
237
402
|
workspaceId,
|
|
@@ -245,21 +410,30 @@ export function registerWorkspaceArtifactRoutes(app: Hono, deps: ApiRouteDeps):
|
|
|
245
410
|
),
|
|
246
411
|
);
|
|
247
412
|
} catch (error) {
|
|
248
|
-
return
|
|
413
|
+
return workspaceArtifactErrorResponse(context, error);
|
|
249
414
|
}
|
|
250
415
|
});
|
|
251
416
|
|
|
252
417
|
app.post(`${base}/:artifactId/rollback`, async (context) => {
|
|
253
418
|
const workspaceId = context.req.param("workspaceId");
|
|
254
|
-
const
|
|
419
|
+
const authorization = await requireAccessGrantAuthorization(
|
|
420
|
+
context,
|
|
421
|
+
deps,
|
|
422
|
+
workspaceId,
|
|
423
|
+
"artifacts:publish",
|
|
424
|
+
);
|
|
425
|
+
const grant = authorization.grant;
|
|
255
426
|
const request = await body(context, RollbackWorkspaceArtifactRequest);
|
|
427
|
+
const id = artifactId(context);
|
|
256
428
|
try {
|
|
257
429
|
return context.json(
|
|
258
|
-
|
|
430
|
+
await mutationResponse(
|
|
431
|
+
deps,
|
|
432
|
+
grant,
|
|
259
433
|
await rollbackWorkspaceArtifact(deps.db, {
|
|
260
434
|
accountId: grant.accountId,
|
|
261
435
|
workspaceId,
|
|
262
|
-
artifactId:
|
|
436
|
+
artifactId: id,
|
|
263
437
|
versionId: request.versionId,
|
|
264
438
|
expectedCurrentVersionId: request.expectedCurrentVersionId,
|
|
265
439
|
reason: request.reason,
|
|
@@ -268,7 +442,39 @@ export function registerWorkspaceArtifactRoutes(app: Hono, deps: ApiRouteDeps):
|
|
|
268
442
|
),
|
|
269
443
|
);
|
|
270
444
|
} catch (error) {
|
|
271
|
-
return
|
|
445
|
+
return workspaceArtifactErrorResponse(context, error);
|
|
446
|
+
}
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
app.patch(`${base}/:artifactId/status`, async (context) => {
|
|
450
|
+
const workspaceId = context.req.param("workspaceId");
|
|
451
|
+
const authorization = await requireAccessGrantAuthorization(
|
|
452
|
+
context,
|
|
453
|
+
deps,
|
|
454
|
+
workspaceId,
|
|
455
|
+
"artifacts:publish",
|
|
456
|
+
);
|
|
457
|
+
const grant = authorization.grant;
|
|
458
|
+
const request = await body(context, SetWorkspaceArtifactStatusRequest);
|
|
459
|
+
const id = artifactId(context);
|
|
460
|
+
try {
|
|
461
|
+
return context.json(
|
|
462
|
+
await mutationResponse(
|
|
463
|
+
deps,
|
|
464
|
+
grant,
|
|
465
|
+
await setWorkspaceArtifactStatus(deps.db, {
|
|
466
|
+
accountId: grant.accountId,
|
|
467
|
+
workspaceId,
|
|
468
|
+
artifactId: id,
|
|
469
|
+
status: request.status,
|
|
470
|
+
expectedCurrentVersionId: request.expectedCurrentVersionId,
|
|
471
|
+
reason: request.reason,
|
|
472
|
+
...provenance(grant.subjectId, request.idempotencyKey),
|
|
473
|
+
}),
|
|
474
|
+
),
|
|
475
|
+
);
|
|
476
|
+
} catch (error) {
|
|
477
|
+
return workspaceArtifactErrorResponse(context, error);
|
|
272
478
|
}
|
|
273
479
|
});
|
|
274
480
|
}
|
|
@@ -215,10 +215,20 @@ async function loadManifest(
|
|
|
215
215
|
* manifest blob has been GC'd (all graceful cold-fallback states — never errors).
|
|
216
216
|
* Inline manifest for ≤2MB, signed URL above.
|
|
217
217
|
*/
|
|
218
|
+
/** Awaited before a signed capture URL is returned to the caller: the route
|
|
219
|
+
* records the metadata-only issuance audit fact. A throwing recorder fails
|
|
220
|
+
* the serve closed - no recorded fact, no bearer capability. */
|
|
221
|
+
export type CaptureSignedUrlIssuanceRecorder = (fact: {
|
|
222
|
+
kind: "capture_manifest" | "capture_file";
|
|
223
|
+
revision: number;
|
|
224
|
+
expiresAt: string;
|
|
225
|
+
}) => Promise<void>;
|
|
226
|
+
|
|
218
227
|
export async function serveWorkspaceCapture(
|
|
219
228
|
row: WorkspaceCaptureRow | null,
|
|
220
229
|
storage: CaptureStoragePort,
|
|
221
230
|
cache?: WorkspaceCaptureManifestCache,
|
|
231
|
+
onSignedUrlIssued?: CaptureSignedUrlIssuanceRecorder,
|
|
222
232
|
): Promise<GetWorkspaceCaptureResponse> {
|
|
223
233
|
if (!row) {
|
|
224
234
|
return { available: false };
|
|
@@ -274,6 +284,11 @@ export async function serveWorkspaceCapture(
|
|
|
274
284
|
key: row.manifestKey,
|
|
275
285
|
expiresInSeconds: CAPTURE_SIGNED_URL_TTL_SECONDS,
|
|
276
286
|
});
|
|
287
|
+
await onSignedUrlIssued?.({
|
|
288
|
+
kind: "capture_manifest",
|
|
289
|
+
revision: row.revision,
|
|
290
|
+
expiresAt: signed.expiresAt.toISOString(),
|
|
291
|
+
});
|
|
277
292
|
return GetWorkspaceCaptureResponse.parse({
|
|
278
293
|
...meta,
|
|
279
294
|
manifest: null,
|
|
@@ -293,6 +308,7 @@ export async function serveWorkspaceCaptureFile(
|
|
|
293
308
|
row: WorkspaceCaptureRow | null,
|
|
294
309
|
path: string,
|
|
295
310
|
storage: CaptureStoragePort,
|
|
311
|
+
onSignedUrlIssued?: CaptureSignedUrlIssuanceRecorder,
|
|
296
312
|
): Promise<GetWorkspaceCaptureFileResponse> {
|
|
297
313
|
const loaded = row ? await loadManifest(row, storage) : null;
|
|
298
314
|
if (!loaded) {
|
|
@@ -347,6 +363,11 @@ export async function serveWorkspaceCaptureFile(
|
|
|
347
363
|
key: file.contentRef,
|
|
348
364
|
expiresInSeconds: CAPTURE_SIGNED_URL_TTL_SECONDS,
|
|
349
365
|
});
|
|
366
|
+
await onSignedUrlIssued?.({
|
|
367
|
+
kind: "capture_file",
|
|
368
|
+
revision: row!.revision,
|
|
369
|
+
expiresAt: signed.expiresAt.toISOString(),
|
|
370
|
+
});
|
|
350
371
|
return GetWorkspaceCaptureFileResponse.parse({
|
|
351
372
|
...base,
|
|
352
373
|
encoding: null,
|