import { registerConnectCallbackReturns } from "./integrations/connect-callback-return"; import { registerFeedbackRoutes } from "./routes/feedback"; import { codemodeSessionRequest } from "./codemode"; import { SiteSessionPathError } from "@opengeni/contracts"; import { registerModelConnectionAccessRoutes } from "./routes/model-connection-access"; import { canonicalizeConfiguredModelId, configuredAllowedModels, configuredAllowedReasoningEfforts, configuredModels, resolveFirstPartyMcpToolPolicy, resolveVoiceInputProviderRegistry, withCodexCatalogProvider, withXaiSubscriptionCatalogProvider, } from "@opengeni/config"; import { ClientConfig, CodemodeCallRequest, ErrorEnvelope, OPENGENI_API_CONTRACT_HEADER, OPENGENI_API_CONTRACT_REVISION, OPENGENI_CORRELATION_HEADER, resolveWorkspaceMemoryEnabled, resolveWorkspaceMemoryPromptMode, VOICE_INPUT_ACCEPTED_MIME_TYPES, TRANSCRIPTION_RECORDING_PROVIDER_SEGMENT_SECONDS, ToolGatewayApprovalRequest, ToolGatewayCallRequest, type AccessGrant, type ErrorCode, } from "@opengeni/contracts"; import { createDocumentServices, getDocumentForIndexing, indexDocumentNow, type DocumentServices, } from "@opengeni/documents"; import { CodemodeOperationConflictError, CodemodeOperationNotExecutableError, CodemodePayloadTooLargeError, CodemodeToolApprovalRequiredError, CodemodeToolNotInCatalogError, ConnectAttemptConflictError, ConnectAttemptNotFoundError, configureChildLifecycleNotices, configureWorkspaceControlRequestLockTimeoutMs, dbSql, getManagedAuthSessionSetSnapshot, getWorkspace, reapManagedAuthIsolatedSessions, reapExpiredManagedAuthSessionSets, resolveSessionMemoryAgentScope, rlsContextForWorkspace, } from "@opengeni/db"; import { requireSessionEventDurableFanoutCapability } from "@opengeni/events"; import { githubAppBotIdentityWarnings } from "@opengeni/github"; import { createObservability } from "@opengeni/observability"; import { createObjectStorage } from "@opengeni/storage"; import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js"; import { handleMcpRequestWithClientAbort } from "./mcp/request-abort"; import { Hono } from "hono"; import { bodyLimit } from "hono/body-limit"; import { compress } from "hono/compress"; import { cors } from "hono/cors"; import { getCookie } from "hono/cookie"; import { HTTPException } from "hono/http-exception"; import { ApiHttpError, workspaceControlBusyHttpError } from "./http/api-error"; import type { ContentfulStatusCode } from "hono/utils/http-status"; import type { ApiRouteDeps, AppDependencies } from "@opengeni/core"; import { CodexCompactionV2ProviderLockedError, ManagedAuthActorLeaseOutcomeUnknownError, hasPermission, requireAccessGrant, requireAccessGrantAuthorization, requirePermission, releaseManagedAuthRequestActorLease, resolveCatalogSettings, resolveWorkspaceCatalogSettings, validateManagedAuthRequestActorLease, requireSessionAuthorization, SessionAuthorizationDeniedError, SessionAuthorizationUnavailableError, } from "@opengeni/core"; import { createManagedAuth, isolatedManagedAuthOAuthCallbackRequest, managedAuthOAuthReturnMatches, resolveManagedAuthOAuthAttempt, } from "./auth/managed-auth"; import { adoptManagedAuthSession, MANAGED_AUTH_SESSION_SET_COOKIE, ManagedAuthActorChangeError, managedAuthCsrfHash, managedAuthDerivedUuid, managedAuthSecretRequestDigest, managedAuthSha256, } from "@opengeni/core/managed-auth-session-sets"; import { createBetterAuthSessionAdapter } from "./auth/managed-auth-session-adapter"; import { currentManagedAuthCreatedSessionId, runManagedAuthAttempt, runManagedAuthDiscardedProviderSession, runManagedAuthProvider, } from "./auth/managed-auth-attempt-context"; import { createManagedEmailTransport } from "./auth/managed-email"; import { assertManagedEmailTransportMetadata, assertOrganizationUserSetupQueryTransportConfigured, } from "./auth/organization-user-setup"; import { createApiSandboxClient, makeResumeBoxById } from "./sandbox/access"; import { buildOpenGeniMcpServer } from "./mcp/server"; import { buildWorkspaceToolGatewayMcpServer, approveWorkspaceToolGatewayCall, callWorkspaceToolGateway, grantUsesAttemptScopedMcp, prepareMcpOAuthWorkspaceToolGateway, prepareWorkspaceToolGateway, workspaceToolGatewayDeclarations, } from "./workspace-tool-gateway"; import { isMcpOAuthResourcePath, mcpOAuthAuthenticateHeader, mcpOAuthBearerToken, registerMcpOAuthRoutes, resolveMcpOAuthRouteAccess, } from "./mcp-oauth"; import { CodemodeAuthorityError, CodemodeCatalogNotReadyError, CodemodeCatalogStaleError, isCodemodeGrant, readCodemodeOperation, requireActiveCodemodeCatalog, submitAndDispatchCodemodeCall, } from "./codemode"; import { boundedMcpRequest, McpPayloadTooLargeError } from "@opengeni/runtime/mcp-network"; import { BrowserControlProtocolError, BrowserControlTransportError, } from "@opengeni/runtime/sandbox"; import { requireAccessKey } from "./http/auth"; import { allowedCorsOrigin } from "./http/cors"; import { withAccessGrantSessionRlsContext } from "./access-grant-rls"; import { registerCapabilityRoutes } from "./routes/capabilities"; import { registerCatalogAssetRoutes } from "./routes/catalog-assets"; import { registerCodexRoutes } from "./routes/codex"; import { registerOrganizationModelProviderRoutes } from "./routes/organization-model-providers"; import { registerSuperGrokRoutes } from "./routes/supergrok"; import { registerConnectionRoutes } from "./routes/connections"; import { registerConnectRoutes } from "./routes/connect"; import { registerHostMcpBindingRoutes } from "./routes/host-mcp-bindings"; import { registerHostMcpResolverRoutes } from "./routes/host-mcp-resolvers"; import { registerExternalIdentityLinkRoutes } from "./routes/external-identity-links"; import { registerDocumentRoutes } from "./routes/documents"; import { registerKnowledgeRoutes } from "./routes/knowledge"; import { registerEnrollmentRoutes } from "./routes/enrollments"; import { registerMachineRoutes } from "./routes/machines"; import { registerMemorySlackPublicationRoutes } from "./routes/memory-slack-publications"; import { registerEnvironmentRoutes } from "./routes/environments"; import { registerFileRoutes } from "./routes/files"; import { registerApiKeyRoutes } from "./routes/api-keys"; import { registerBillingRoutes } from "./routes/billing"; import { registerBrowserIdentityRoutes } from "./routes/browser-identities"; import { registerBrowserSessionRoutes } from "./routes/browser-sessions"; import { registerComputerSessionRoutes } from "./routes/computer-sessions"; import { registerGitHubRoutes } from "./routes/github"; import { registerPersonalGitHubRoutes } from "./routes/personal-github"; import { isPersonalGitHubGitBrokerRequest, registerPersonalGitHubGitBrokerRoutes, } from "./routes/personal-github-git-broker"; import { registerInstallRoutes } from "./routes/install"; import { registerApiIntegrationRoutes } from "./routes/api-integrations"; import { registerIntegrationFacetRoutes } from "./routes/integration-facets"; import { registerInteractionResourceRoutes } from "./routes/interaction-resources"; import { registerPrReviewRoutes } from "./routes/pr-review"; import { registerPackRoutes } from "./routes/packs"; import { registerAutomationRoutes } from "./routes/automations"; import { registerPluginRoutes } from "./routes/plugins"; import { registerSkillRoutes } from "./routes/skills"; import { registerChannelRoutes } from "./routes/channels"; import { registerRigRoutes } from "./routes/rigs"; import { registerScheduledTaskRoutes } from "./routes/scheduled-tasks"; import { registerSessionRoutes } from "./routes/sessions"; import { registerSocialRoutes } from "./routes/social"; import { registerWorkspaceRoutes } from "./routes/workspaces"; import { registerWorkspaceInstructionPolicyRoutes } from "./routes/workspace-instruction-policies"; import { registerWorkspaceLearningRoutes } from "./routes/workspace-learning"; import { registerCompanyProfileRoutes } from "./routes/company-profile"; import { registerCompanyBrainRoutes } from "./routes/company-brain"; import { registerSlackTaskPolicyRoutes } from "./routes/slack-task-policy"; import { registerWorkspaceStateRoutes } from "./routes/workspace-state"; import { registerWorkspaceArtifactRoutes } from "./routes/workspace-artifacts"; import { registerArtifactCatalogRoutes } from "./routes/artifact-catalog"; import { registerPreferenceRegistryRoutes } from "./routes/preference-registry"; import { registerInsightsRoutes } from "./routes/insights"; import { registerTranscriptionRoutes } from "./routes/transcriptions"; import { registerEditableArtifactRoutes } from "./routes/editable-artifacts"; import { registerVideoGenerationRoutes } from "./routes/video-generation"; import { registerCanonicalHumanIdentityRoutes } from "./routes/canonical-human-identities"; import { registerOrganizationMembershipRoutes } from "./routes/organization-memberships"; import { registerOrganizationSessionRoutes } from "./routes/organization-sessions"; import { registerOrganizationRecoveryRoutes } from "./routes/organization-recovery"; import { registerManagedOnboardingRoutes } from "./routes/managed-onboarding"; import { registerManagedAuthSessionSetRoutes, requireManagedAuthProviderRouteAllowed, scrubManagedAuthProviderResponse, } from "./routes/managed-auth-session-sets"; import { registerUserResourceAuthorityRoutes } from "./routes/user-resource-authorities"; import { registerConnectionAuthorityRoutes } from "./routes/connection-authorities"; import { projectClientModel } from "./model-catalog"; import { createTranscriptionService } from "./transcription/service"; import { createFfmpegTranscriptionSegmenter } from "./transcription/segmenter"; import { registerSlackInteractionRoutes } from "./integrations/slack-interactions"; export { allowedCorsOrigin } from "./http/cors"; export type { ApiRouteDeps, AppDependencies, DocumentIndexClient, ObjectStorageDependency, SessionWorkflowClient, } from "@opengeni/core"; export { mergeResourceRefs, mergeToolRefs, normalizeResources, validateFileResources, validateGitHubRepositorySelection, validateGitHubRepositorySelectionShape, validateGitHubRepositorySelectionShapes, validateToolRefs, withDefaultEnabledCapabilityMcpTools, } from "@opengeni/core"; export { workflowIdForSession } from "@opengeni/core"; export { replaySessionEvents, sseSessionStream, sseWorkspaceControlStream } from "./http/sse"; export const API_MAX_REQUEST_BODY_BYTES = 32 * 1024 * 1024; const managedAuthReaperDatabases = new WeakSet(); const MANAGED_AUTH_REAPER_INTERVAL_MS = 60_000; /** Effective Hono bodyLimit — API JSON ceiling or voice multipart + multipart overhead. */ export function apiRequestBodyLimitBytes(settings: { voiceInputMaxSizeBytes: number; voiceInputResumableMaxChunkSizeBytes?: number; }): number { return Math.max( API_MAX_REQUEST_BODY_BYTES, settings.voiceInputMaxSizeBytes + 64 * 1024, (settings.voiceInputResumableMaxChunkSizeBytes ?? 0) + 64 * 1024, ); } const API_PUBLIC_ERROR_MESSAGE_MAX_BYTES = 512; export function createApp(deps: AppDependencies): Hono { return createAppComposition(deps).app; } export async function resolveWorkspaceMcpRouteDeps( routeDeps: ApiRouteDeps, grant: AccessGrant, ): Promise { const catalogSourceSettings = routeDeps.catalogSourceSettings ?? routeDeps.settings; const resolvedCatalog = await resolveWorkspaceCatalogSettings( routeDeps.db, catalogSourceSettings, { accountId: grant.accountId, workspaceId: grant.workspaceId, }, ); return { ...routeDeps, catalogSourceSettings, settings: resolvedCatalog.settings }; } export function createAppComposition(deps: AppDependencies): { app: Hono; routeDeps: ApiRouteDeps; } { assertOrganizationUserSetupQueryTransportConfigured(deps.settings); // The request-scoped workspace control-prefix budget is validated once by // @opengeni/config at boot; install it for every request-scoped db command // (Send/Steer/control/queue/settings/delete) built by this app. configureWorkspaceControlRequestLockTimeoutMs(deps.settings.workspaceControlLockTimeoutMs); // Child lifecycle notice producers (human-input/approval resolutions, direct // Pause) run inside API-originated db commands; install the boot-validated // rollout flag once for this process. configureChildLifecycleNotices({ enabled: deps.settings.childLifecycleNoticesEnabled }); const managedEmailTransport = deps.managedEmailTransport ?? createManagedEmailTransport(deps.settings); assertManagedEmailTransportMetadata(managedEmailTransport); const managedAuth = deps.managedAuth ?? createManagedAuth(deps.settings, deps.db, managedEmailTransport); const managedAuthSessionAdapter = deps.managedAuthSessionAdapter ?? (managedAuth ? createBetterAuthSessionAdapter(managedAuth, deps.db) : null); const objectStorage = deps.objectStorage === undefined ? createObjectStorage(deps.settings) : deps.objectStorage; let documentServices: DocumentServices | null = deps.documentServices ?? null; const getDocumentServices = () => { documentServices ??= createDocumentServices(deps.settings); return documentServices; }; const documentIndexer = deps.documentIndexer ?? { indexDocument: async ({ accountId, workspaceId, documentId, authorityKind, authorityWorkspaceId, authoritySubjectId, }: { accountId: string; workspaceId: string; documentId: string; authorityKind: import("@opengeni/contracts").DocumentAuthorityKind; authorityWorkspaceId: string | null; authoritySubjectId: string | null; }) => { if (!objectStorage) { throw new HTTPException(503, { message: "object storage is not configured", }); } const context = await rlsContextForWorkspace(deps.db, workspaceId); if (context.accountId !== accountId) { throw new Error("document account/workspace authority mismatch"); } // This is a metadata-only authority-tuple fence. Workspace and // organization documents intentionally have no authority subject, so a // viewer-scoped public read cannot supply the immutable human needed for // Drive ACL evaluation. The byte boundary below reconstructs that // subject from the stored document through indexDocumentNow. const claimedDocument = await getDocumentForIndexing(deps.db, workspaceId, documentId); if ( !claimedDocument || claimedDocument.authorityKind !== authorityKind || claimedDocument.authorityWorkspaceId !== authorityWorkspaceId || claimedDocument.authoritySubjectId !== authoritySubjectId ) { throw new Error("document authority changed before indexing"); } const document = await indexDocumentNow( deps.db, objectStorage, workspaceId, documentId, getDocumentServices(), { viewerSubjectId: authoritySubjectId }, ); if ( document.authorityKind !== authorityKind || document.authorityWorkspaceId !== authorityWorkspaceId || document.authoritySubjectId !== authoritySubjectId ) { throw new Error("document authority changed before indexing"); } return document; }, }; // The API process's own agent-loop-free sandbox client — the API-direct // control-plane seam. Constructed from settings (resumes boxes by id // in-process) unless a client was injected (tests). resumeBoxById is always // concrete for routes; it throws SandboxResumeError when sandboxBackend=none. const sandboxClient = deps.sandboxClient ?? createApiSandboxClient(deps.settings); const resumeBoxById = deps.resumeBoxById ?? makeResumeBoxById(sandboxClient); const observability = deps.observability ?? createObservability(deps.settings, { component: "api" }); if ( managedAuth && deps.settings.managedAuthSessionSetMode !== "legacy" && !managedAuthReaperDatabases.has(deps.db as object) ) { managedAuthReaperDatabases.add(deps.db as object); const timer = setInterval(() => { void Promise.all([ reapManagedAuthIsolatedSessions(deps.db, 100), reapExpiredManagedAuthSessionSets(deps.db, 100), ]).catch((error) => { observability.error("Managed isolated-auth orphan reap failed", { errorClass: error instanceof Error ? error.name : "UnknownError", }); }); }, MANAGED_AUTH_REAPER_INTERVAL_MS); (timer as ReturnType & { unref?: () => void }).unref?.(); } const transcription = deps.transcription === undefined ? createTranscriptionService({ settings: deps.settings, db: deps.db, ...(deps.codexFetch ? { codexFetch: deps.codexFetch } : {}), }) : deps.transcription; const transcriptionSegmenter = deps.transcriptionSegmenter === undefined ? createFfmpegTranscriptionSegmenter({ ffmpegPath: deps.settings.voiceInputFfmpegPath, }) : deps.transcriptionSegmenter; const routeDeps: ApiRouteDeps = { ...deps, resolveCatalogSettings: () => resolveCatalogSettings(deps.db, deps.settings), observability, githubStateSecret: deps.githubStateSecret ?? deps.settings.githubAppManifestStateSecret ?? crypto.randomUUID(), managedAuth, managedAuthSessionAdapter, managedEmailTransport, objectStorage, documentIndexer, getDocumentServices, transcription, transcriptionSegmenter, ...(sandboxClient ? { sandboxClient } : {}), resumeBoxById, }; const app = new Hono(); const correlationIds = new WeakMap(); app.use("*", async (c, next) => { const correlationId = boundedCorrelationId(c.req.header(OPENGENI_CORRELATION_HEADER)) ?? crypto.randomUUID(); correlationIds.set(c.req.raw, correlationId); c.header(OPENGENI_CORRELATION_HEADER, correlationId); await next(); }); app.use("*", async (c, next) => { const oauthToken = mcpOAuthBearerToken(c.req.raw); if ( oauthToken && (!deps.settings.mcpOauthEnabled || !isMcpOAuthResourcePath(new URL(c.req.url).pathname)) ) { c.header("www-authenticate", 'Bearer error="invalid_token"'); return c.json({ error: "invalid_token" }, 401); } await next(); }); const corsHeaders = { allowHeaders: [ "Accept", "Authorization", "Content-Type", "Range", "X-OpenGeni-Access-Key", "X-OpenGeni-Api-Contract", "X-OpenGeni-Actor-Epoch", "X-OpenGeni-Correlation-Id", "X-OpenGeni-Session-Csrf", "X-OpenGeni-Site-Id", "X-OpenGeni-Site-Version", "X-OpenGeni-Subject", ], exposeHeaders: [ "Accept-Ranges", "Content-Range", "X-OpenGeni-Api-Contract", "X-OpenGeni-Actor-Epoch", "X-OpenGeni-Actor-State", "X-OpenGeni-Correlation-Id", "X-OpenGeni-Covered-First", "X-OpenGeni-Covered-Last", "X-OpenGeni-Event-Direction", "X-OpenGeni-Event-Mode", "X-OpenGeni-Event-Result", "X-OpenGeni-Event-Result-Mode", "X-OpenGeni-Forensic-Exact", "X-OpenGeni-Has-More", "X-OpenGeni-Next-After", "X-OpenGeni-Next-Before", "X-OpenGeni-Page-Bytes", "X-OpenGeni-Page-Max-Bytes", "X-OpenGeni-Page-Truncated", "X-OpenGeni-Payload-Mode", "X-OpenGeni-Truncated-By", ], }; const publicApiCors = cors({ ...corsHeaders, credentials: false, origin: "*", }); const credentialedCors = cors({ ...corsHeaders, credentials: true, origin: (origin) => allowedCorsOrigin(deps.settings.corsAllowOriginRegex, origin) ? origin : null, }); app.use("*", (c, next) => { const origin = c.req.header("origin"); const middleware = origin && allowedCorsOrigin(deps.settings.corsAllowOriginRegex, origin) ? credentialedCors : publicApiCors; return middleware(c, next); }); const standardRequestBodyLimit = bodyLimit({ maxSize: apiRequestBodyLimitBytes(deps.settings), onError: (c) => c.json({ code: "PAYLOAD_TOO_LARGE", message: "Request body is too large." }, 413), }); app.use("*", async (c, next) => { // Git packfiles must stay streaming and can legitimately exceed the JSON // request ceiling. The exact closed broker routes apply their own method, // content-type, authority, and idle-deadline checks. if (isPersonalGitHubGitBrokerRequest(c.req.method, new URL(c.req.url).pathname)) { await next(); return; } return await standardRequestBodyLimit(c, next); }); // Large catalog, capture, and session-list responses are on the browser's // critical path. Compress JSON at the API boundary while leaving SSE and // other streaming transports byte-for-byte unchanged. const compressJson = compress({ encoding: "gzip", contentTypeFilter: /^application\/json(?:;|$)/i, }); app.use("/v1/*", async (c, next) => { await compressJson(c, next); if (/^application\/json(?:;|$)/i.test(c.res.headers.get("content-type") ?? "")) { c.res.headers.set("vary", appendVary(c.res.headers.get("vary"), "Accept-Encoding")); } }); app.use("*", async (c, next) => { const url = new URL(c.req.url); const route = routeLabel(url.pathname); const correlationId = correlationIds.get(c.req.raw) ?? crypto.randomUUID(); const start = performance.now(); const span = observability.startSpan(`HTTP ${c.req.method} ${route}`, { "http.request.method": c.req.method, "opengeni.route": route, }); try { await next(); const status = c.res.status || 200; const durationSeconds = (performance.now() - start) / 1000; observability.recordHttpRequest({ method: c.req.method, route, status, durationSeconds, }); span.end({ attributes: { "http.response.status_code": status, "opengeni.duration_ms": Math.round(durationSeconds * 1000), }, }); observability.info("HTTP request completed", { method: c.req.method, route, status, durationMs: Math.round(durationSeconds * 1000), traceId: span.traceId, spanId: span.spanId, correlationId, }); } catch (error) { const status = httpStatusForError(error); const errorCode = errorCodeForStatus(status); const durationSeconds = (performance.now() - start) / 1000; observability.recordHttpRequest({ method: c.req.method, route, status, durationSeconds, }); observability.incrementCounter({ name: "opengeni_http_errors_total", help: "Total OpenGeni HTTP request failures by bounded route, status, and stable code.", labels: { route, status: String(status), code: errorCode }, }); span.end({ attributes: { "http.response.status_code": status, "opengeni.duration_ms": Math.round(durationSeconds * 1000), }, error, }); observability.error("HTTP request failed", { method: c.req.method, route, status, durationMs: Math.round(durationSeconds * 1000), traceId: span.traceId, spanId: span.spanId, correlationId, errorCode, errorClass: "HttpOperationError", }); throw error; } }); const accessKeyBoundary = requireAccessKey(deps.settings); app.use("*", async (c, next) => { // Git's credential helper supplies the exact encrypted broker bearer in // Authorization. It cannot also supply the deployment access key, and the // route performs its own attempt-bound authorization before every use. if (isPersonalGitHubGitBrokerRequest(c.req.method, new URL(c.req.url).pathname)) { await next(); return; } return await accessKeyBoundary(c, next); }); app.use("/v1/*", async (c, next) => { c.header(OPENGENI_API_CONTRACT_HEADER, OPENGENI_API_CONTRACT_REVISION); if ( deps.settings.environment !== "test" && isApiContractProtectedMutation(c.req.method, new URL(c.req.url).pathname) && c.req.header(OPENGENI_API_CONTRACT_HEADER) !== OPENGENI_API_CONTRACT_REVISION ) { return c.json( { code: "API_CONTRACT_CHANGED", message: "OpenGeni updated. Reload this client before changing state.", apiContractRevision: OPENGENI_API_CONTRACT_REVISION, }, 409, ); } await next(); }); app.use("/v1/*", async (c, next) => { try { await next(); try { await validateManagedAuthRequestActorLease(c.req.raw); } catch (error) { if (error instanceof ManagedAuthActorChangeError) { c.header("x-opengeni-actor-state", "changed"); throw new HTTPException(409, { message: error.code, cause: error }); } if (error instanceof ManagedAuthActorLeaseOutcomeUnknownError) { throw new ApiHttpError(503, { code: "upstream_unavailable", message: error.code, retryable: true, outcomeUnknown: true, details: { managedAuthCode: error.code }, }); } throw error; } } finally { await releaseManagedAuthRequestActorLease(c.req.raw).catch((error) => { observability.error("Managed actor mutation lease release failed", { errorClass: error instanceof Error ? error.name : "UnknownError", }); }); } }); // These product-owned auth routes must be registered before Better Auth's // wildcard handler or the provider returns its own 404 first. registerManagedOnboardingRoutes(app, routeDeps); registerManagedAuthSessionSetRoutes(app, routeDeps); if (managedAuth) { app.on(["GET", "POST"], "/v1/auth/*", async (c) => { const pathname = new URL(c.req.url).pathname; const oauthCallbackProvider = managedAuthOAuthCallbackProvider(pathname); if (deps.settings.managedAuthSessionSetMode === "legacy") { return oauthCallbackProvider ? await runManagedAuthProvider( oauthCallbackProvider, async () => await managedAuth.handler(c.req.raw), ) : await managedAuth.handler(c.req.raw); } requireManagedAuthProviderRouteAllowed(c.req.method, pathname); // Provider authentication/recovery is isolated from whichever actor the // browser currently renders. Selected-session capabilities are all // product-owned above this wildcard and generation/epoch fenced. const authority = getCookie(c, MANAGED_AUTH_SESSION_SET_COOKIE); let providerResponse: Response; let preserveCookieNames: readonly string[] | undefined; if (oauthCallbackProvider) { const attempt = await resolveManagedAuthOAuthAttempt( managedAuth, c.req.raw, oauthCallbackProvider, deps.settings.publicBaseUrl!, ); if (!attempt || !authority || attempt.authorityHash !== managedAuthSha256(authority)) { throw new HTTPException(409, { message: "provider_route_blocked" }); } const isolated = await isolatedManagedAuthOAuthCallbackRequest(managedAuth, c.req.raw); preserveCookieNames = [isolated.stateCookieName]; const handled = await runManagedAuthAttempt( attempt.transactionId, oauthCallbackProvider, async () => { const response = await managedAuth.handler(isolated.request); return { response, authSessionId: currentManagedAuthCreatedSessionId(), }; }, ); providerResponse = handled.response; if ( !handled.authSessionId && managedAuthOAuthReturnMatches( providerResponse.headers.get("location") ?? "", new URL(deps.settings.publicBaseUrl!).origin, attempt.transactionId, "complete", ) ) { const location = new URL("/account-auth", deps.settings.publicBaseUrl!); location.searchParams.set("transaction", attempt.transactionId); location.searchParams.set("social", "error"); providerResponse = Response.redirect(location, 302); } else if (handled.authSessionId) { try { await adoptManagedAuthSession({ db: deps.db, adapter: managedAuthSessionAdapter!, authority, authorityHash: attempt.authorityHash, csrfHash: managedAuthCsrfHash(authority), operationId: managedAuthDerivedUuid( "opengeni:managed-auth:social-completion", `${attempt.transactionId}:${attempt.provider}`, ), requestDigest: managedAuthSecretRequestDigest(deps.settings.betterAuthSecret!, { operation: "social_completion", transactionId: attempt.transactionId, provider: attempt.provider, expectedGeneration: attempt.expectedGeneration, expectedActorEpoch: attempt.expectedActorEpoch, }), expectedGeneration: attempt.expectedGeneration, expectedActorEpoch: attempt.expectedActorEpoch, transactionId: attempt.transactionId, transactionSecretHash: attempt.transactionSecretHash, authSessionId: handled.authSessionId, mode: deps.settings.managedAuthSessionSetMode, }); } catch { // adoptManagedAuthSession revokes only when durable reconciliation // proves that completion did not commit. An uncertain outcome may // already point the selected slot at this session, so the callback // must not independently revoke it. const location = new URL("/account-auth", deps.settings.publicBaseUrl!); location.searchParams.set("transaction", attempt.transactionId); location.searchParams.set("social", "error"); providerResponse = Response.redirect(location, 302); } } } else { const headers = new Headers(c.req.raw.headers); headers.delete("cookie"); headers.delete("authorization"); headers.delete("x-forwarded-user"); const providerRequest = new Request(c.req.raw, { headers }); const discardProviderSession = deps.settings.managedAuthSessionSetMode === "broker" || authority !== undefined; providerResponse = discardProviderSession ? await runManagedAuthDiscardedProviderSession( async () => await managedAuth.handler(providerRequest), ) : await managedAuth.handler(providerRequest); } let replacementCookies: readonly string[] | undefined; if (deps.settings.managedAuthSessionSetMode === "broker") { replacementCookies = await managedAuthSessionAdapter!.createLegacySelectedSessionCookies( null, c.req.header("cookie") ?? null, ); } else { if (authority !== undefined) { const snapshot = await getManagedAuthSessionSetSnapshot(deps.db, { authorityHash: managedAuthSha256(authority), mode: "dual", includeInternal: true, readOnly: true, }); if (snapshot) { replacementCookies = await managedAuthSessionAdapter!.createLegacySelectedSessionCookies( snapshot.selected, c.req.header("cookie") ?? null, ); } else { replacementCookies = await managedAuthSessionAdapter!.createLegacySelectedSessionCookies( null, c.req.header("cookie") ?? null, ); } } } return await scrubManagedAuthProviderResponse(providerResponse, { replacementCookies, preserveCookieNames, }); }); } app.get("/healthz", (c) => { const warnings = githubAppBotIdentityWarnings(deps.settings); return c.json({ service: deps.settings.serviceName, environment: deps.settings.environment, deploymentRevision: deps.settings.deploymentRevision, ...(deps.settings.serverVersion ? { serverVersion: deps.settings.serverVersion } : {}), ...(warnings.length > 0 ? { warnings } : {}), ok: true, }); }); app.get("/readyz", async (c) => { const result = await runReadinessChecks(readinessChecks(deps), 2_000); return c.json(result, result.ok ? 200 : 503); }); app.get("/traffic-readyz", async (c) => { const { db } = readinessChecks(deps); const result = await runReadinessChecks({ db }, 2_000); return c.json(result, result.ok ? 200 : 503); }); app.get("/metrics", async (c) => c.text(await observability.prometheusMetrics(), 200, { "content-type": "text/plain; version=0.0.4; charset=utf-8", }), ); registerMcpOAuthRoutes(app, routeDeps); app.get("/v1/config/client", async (c) => { c.header("cache-control", "no-store"); const resolvedCatalog = await resolveCatalogSettings(deps.db, deps.settings); const baseCatalogSettings = resolvedCatalog.settings; const codexCatalogSettings = baseCatalogSettings.codexSubscriptionEnabled ? withCodexCatalogProvider(baseCatalogSettings) : baseCatalogSettings; const catalogSettings = baseCatalogSettings.supergrokSubscriptionEnabled ? withXaiSubscriptionCatalogProvider(codexCatalogSettings) : codexCatalogSettings; return c.json( ClientConfig.parse({ deploymentRevision: deps.settings.deploymentRevision, apiContractRevision: OPENGENI_API_CONTRACT_REVISION, ...(deps.settings.serverVersion ? { serverVersion: deps.settings.serverVersion } : {}), defaultModel: canonicalizeConfiguredModelId(catalogSettings, catalogSettings.openaiModel), allowedModels: configuredAllowedModels(catalogSettings), // Provider-grouped model list for the picker. configuredModels() carries the // union of the built-in allow-list and every registry provider's models, in // selection order (default model first); project each to the client-safe // provider-blind ClientModel shape (execution topology remains server-side). models: configuredModels(catalogSettings).map(projectClientModel), defaultReasoningEffort: deps.settings.openaiReasoningEffort, allowedReasoningEfforts: configuredAllowedReasoningEfforts(deps.settings), defaultSandboxBackend: deps.settings.sandboxBackend, mcpServers: deps.settings.mcpServers.map((server) => ({ id: server.id, name: server.name ?? server.id, })), firstPartyMcpTools: resolveFirstPartyMcpToolPolicy(deps.settings), fileUploads: { enabled: objectStorage !== null, maxSizeBytes: objectStorage?.maxSinglePutSizeBytes ?? 5_000_000_000, }, voiceInput: { providers: resolveVoiceInputProviderRegistry(deps.settings).map( (provider) => provider.id, ), available: (await transcription?.available()) ?? false, maxDurationSeconds: deps.settings.voiceInputMaxDurationSeconds, maxSizeBytes: deps.settings.voiceInputMaxSizeBytes, acceptedMimeTypes: [...VOICE_INPUT_ACCEPTED_MIME_TYPES], ...(deps.settings.voiceInputResumableEnabled && objectStorage && transcription && transcriptionSegmenter && (await transcription.available()) && (await transcriptionSegmenter.available()) ? { resumable: { maxDurationSeconds: deps.settings.voiceInputResumableMaxDurationSeconds, maxSizeBytes: deps.settings.voiceInputResumableMaxSizeBytes, maxChunkSizeBytes: deps.settings.voiceInputResumableMaxChunkSizeBytes, providerSegmentSeconds: Math.min( TRANSCRIPTION_RECORDING_PROVIDER_SEGMENT_SECONDS, deps.settings.voiceInputMaxDurationSeconds, ), }, } : {}), }, productAccessMode: deps.settings.productAccessMode, billingMode: deps.settings.billingMode, managedAuthSessionSetMode: deps.settings.managedAuthSessionSetMode, auth: clientAuthConfig(deps.settings), analytics: clientAnalyticsConfig(deps.settings), // Channel-A structured services (P4.4) ride exec/readFile/createEditor, // available on every real backend; `none` has no box so they are all off. // Per-session availability is still negotiated on /stream-capabilities. structuredServices: structuredServicesHint(deps.settings.sandboxBackend), }), ); }); app.use("/v1/workspaces/:workspaceId/*", async (c, next) => { const workspaceId = c.req.param("workspaceId"); if (workspaceRequestRequiresCodexAccountPrevalidation(c.req.raw)) { const grant = await requireAccessGrant(c, routeDeps, workspaceId); await validateCodexAccountTarget(c.req.raw); await withAccessGrantSessionRlsContext(routeDeps, grant, next); return; } if (workspaceActorContextExempt(c.req.method, new URL(c.req.url).pathname)) { await next(); return; } const grant = await requireAccessGrant(c, routeDeps, workspaceId); await withAccessGrantSessionRlsContext(routeDeps, grant, next); }); app.all("/v1/workspaces/:workspaceId/mcp", async (c) => { const workspaceId = c.req.param("workspaceId"); let boundedRequest: Request; try { boundedRequest = await boundedMcpRequest(c.req.raw); } catch (error) { if (error instanceof McpPayloadTooLargeError) { throw new HTTPException(413, { message: "MCP request body exceeds the safety limit", }); } throw error; } let oauthAccess: Awaited>; try { oauthAccess = await resolveMcpOAuthRouteAccess(routeDeps, c.req.raw, workspaceId); } catch (error) { if (error instanceof HTTPException && error.status === 401) { c.header( "www-authenticate", mcpOAuthAuthenticateHeader(routeDeps, new URL(c.req.url).pathname), ); } throw error; } if (oauthAccess) { return await withAccessGrantSessionRlsContext(routeDeps, oauthAccess.grant, async () => { const prepared = await prepareMcpOAuthWorkspaceToolGateway( routeDeps, oauthAccess.grant, oauthAccess.allowedToolIdentities, ); const transport = new WebStandardStreamableHTTPServerTransport({ enableJsonResponse: true, }); const mcp = buildWorkspaceToolGatewayMcpServer( prepared, oauthAccess.grant, routeDeps.observability, ); try { await mcp.connect(transport); return await handleMcpRequestWithClientAbort(transport, boundedRequest, c.req.raw.signal); } finally { await Promise.allSettled([mcp.close(), prepared.close()]); } }); } let authorization: Awaited>; try { authorization = await requireMcpAccessGrantAuthorization(c, routeDeps, workspaceId); } catch (error) { if (deps.settings.mcpOauthEnabled && error instanceof HTTPException && error.status === 401) { c.header( "www-authenticate", mcpOAuthAuthenticateHeader(routeDeps, new URL(c.req.url).pathname), ); } throw error; } const grant = authorization.grant; return await withAccessGrantSessionRlsContext(routeDeps, grant, async () => { const boundSessionId = grant.metadata?.sessionId; if (typeof boundSessionId === "string") { try { await requireSessionAuthorization(routeDeps, grant, { sessionId: boundSessionId, operation: "session.first_party_mcp.call", surface: "first_party_mcp", }); } catch (error) { if (error instanceof SessionAuthorizationDeniedError) { throw new HTTPException(404, { message: "session not found" }); } if (error instanceof SessionAuthorizationUnavailableError) { throw new HTTPException(503, { message: "session authorization is unavailable", }); } throw error; } } const workspace = await getWorkspace(routeDeps.db, workspaceId); const workspaceMemoryEnabled = resolveWorkspaceMemoryEnabled(workspace?.settings); const workspaceMemoryPromptMode = resolveWorkspaceMemoryPromptMode(); const transport = new WebStandardStreamableHTTPServerTransport({ enableJsonResponse: true, }); if (!grantUsesAttemptScopedMcp(grant)) { const prepared = await prepareWorkspaceToolGateway(routeDeps, authorization); const mcp = buildWorkspaceToolGatewayMcpServer(prepared, grant, routeDeps.observability); try { await mcp.connect(transport); return await handleMcpRequestWithClientAbort(transport, boundedRequest, c.req.raw.signal); } finally { await Promise.allSettled([mcp.close(), prepared.close()]); } } const mcpDeps = await resolveWorkspaceMcpRouteDeps(routeDeps, grant); // The bound session's frozen Memory selector (migration 0427) decides // which Memory tools the attempt receives and which typed layers they // read and write. A missing row resolves to no Memory tools. const sessionMemory = typeof boundSessionId === "string" ? ((await resolveSessionMemoryAgentScope( routeDeps.db, workspaceId, boundSessionId, grant.metadata, )) ?? { mode: "off" as const, userSubjectId: null, rootSessionId: null, }) : null; const mcp = buildOpenGeniMcpServer(mcpDeps, grant, { requestOrigin: new URL(c.req.url).origin, workspaceMemoryEnabled, workspaceMemoryPromptMode, sessionMemory, }); await mcp.connect(transport); // Bind tool handlers' `extra.signal` to the HTTP client's connection: a // worker that drops the call (Steer/Pause) aborts a blocking tool here. return await handleMcpRequestWithClientAbort(transport, boundedRequest, c.req.raw.signal); }); }); app.get("/v1/workspaces/:workspaceId/tools/catalog", async (c) => { const workspaceId = c.req.param("workspaceId"); const authorization = await requireAccessGrantAuthorization( c, routeDeps, workspaceId, "workspace:read", ); const prepared = await prepareWorkspaceToolGateway(routeDeps, authorization); try { c.header("cache-control", "no-store"); return c.json(prepared.toolGatewayCatalog); } finally { await prepared.close(); } }); app.post("/v1/workspaces/:workspaceId/tools/calls", async (c) => { const workspaceId = c.req.param("workspaceId"); const authorization = await requireAccessGrantAuthorization( c, routeDeps, workspaceId, "workspace:read", ); const grant = authorization.grant; const parsed = ToolGatewayCallRequest.safeParse(await c.req.json().catch(() => null)); if (!parsed.success) { throw new HTTPException(400, { message: "Invalid tool gateway call" }); } const prepared = await prepareWorkspaceToolGateway(routeDeps, authorization); try { return c.json( await callWorkspaceToolGateway( prepared, grant, parsed.data, routeDeps.db, undefined, routeDeps.observability, ), ); } finally { await prepared.close(); } }); app.post("/v1/workspaces/:workspaceId/tools/approvals", async (c) => { const workspaceId = c.req.param("workspaceId"); const authorization = await requireAccessGrantAuthorization( c, routeDeps, workspaceId, "workspace:read", ); const parsed = ToolGatewayApprovalRequest.safeParse(await c.req.json().catch(() => null)); if (!parsed.success) { throw new HTTPException(400, { message: "Invalid tool gateway approval" }); } const prepared = await prepareWorkspaceToolGateway(routeDeps, authorization); try { return c.json( await approveWorkspaceToolGatewayCall( prepared, authorization.grant, routeDeps.db, parsed.data, undefined, routeDeps.observability, ), 201, ); } finally { await prepared.close(); } }); app.get("/v1/workspaces/:workspaceId/tools/declarations", async (c) => { const workspaceId = c.req.param("workspaceId"); const authorization = await requireAccessGrantAuthorization( c, routeDeps, workspaceId, "workspace:read", ); const prepared = await prepareWorkspaceToolGateway(routeDeps, authorization); try { c.header("cache-control", "no-store"); return c.json(workspaceToolGatewayDeclarations(prepared)); } finally { await prepared.close(); } }); app.all("/v1/workspaces/:workspaceId/codemode/sdk/*", async (c) => { const workspaceId = c.req.param("workspaceId"); const grant = await requireAccessGrant(c, routeDeps, workspaceId); const url = new URL(c.req.url); const prefix = `/v1/workspaces/${workspaceId}/codemode/sdk`; let forwarded: Request; try { forwarded = await codemodeSessionRequest( routeDeps, grant, c.req.raw, url.pathname.slice(prefix.length) + url.search, ); } catch (error) { throw codemodeHttpError(error); } return app.fetch(forwarded); }); app.get("/v1/workspaces/:workspaceId/codemode/catalog", async (c) => { const workspaceId = c.req.param("workspaceId"); const grant = await requireAccessGrant(c, routeDeps, workspaceId); if (!isCodemodeGrant(grant)) { throw new HTTPException(403, { message: "Codemode access denied" }); } try { return c.json((await requireActiveCodemodeCatalog(routeDeps, grant)).catalog); } catch (error) { throw codemodeHttpError(error); } }); app.post("/v1/workspaces/:workspaceId/codemode/calls", async (c) => { const workspaceId = c.req.param("workspaceId"); const grant = await requireAccessGrant(c, routeDeps, workspaceId); if (!isCodemodeGrant(grant)) { throw new HTTPException(403, { message: "Codemode access denied" }); } const parsed = CodemodeCallRequest.safeParse(await c.req.json().catch(() => null)); if (!parsed.success) { throw new HTTPException(400, { message: "Invalid Codemode call" }); } try { const submission = await submitAndDispatchCodemodeCall(routeDeps, grant, parsed.data); const terminal = ["completed", "failed", "outcome_unknown", "cancelled"].includes( submission.operation.state, ); return c.json(submission, terminal ? 200 : 202); } catch (error) { throw codemodeHttpError(error); } }); app.get("/v1/workspaces/:workspaceId/codemode/calls/:operationId", async (c) => { const workspaceId = c.req.param("workspaceId"); const grant = await requireAccessGrant(c, routeDeps, workspaceId); if (!isCodemodeGrant(grant)) { throw new HTTPException(403, { message: "Codemode access denied" }); } try { const operation = await readCodemodeOperation(routeDeps, grant, c.req.param("operationId")); if (!operation) throw new HTTPException(404, { message: "Codemode operation not found", }); return c.json(operation); } catch (error) { if (error instanceof HTTPException) throw error; throw codemodeHttpError(error); } }); registerConnectCallbackReturns(app, routeDeps); registerFileRoutes(app, routeDeps); registerApiKeyRoutes(app, routeDeps); registerBillingRoutes(app, routeDeps); registerBrowserIdentityRoutes(app, routeDeps); registerBrowserSessionRoutes(app, routeDeps); registerComputerSessionRoutes(app, routeDeps); registerDocumentRoutes(app, routeDeps); registerKnowledgeRoutes(app, routeDeps); registerGitHubRoutes(app, routeDeps); registerInstallRoutes(app, routeDeps); registerInteractionResourceRoutes(app, routeDeps); registerWorkspaceRoutes(app, routeDeps); registerInsightsRoutes(app, routeDeps); registerWorkspaceInstructionPolicyRoutes(app, routeDeps); registerWorkspaceLearningRoutes(app, routeDeps); registerCompanyProfileRoutes(app, routeDeps); registerCompanyBrainRoutes(app, routeDeps); registerSlackTaskPolicyRoutes(app, routeDeps); registerWorkspaceStateRoutes(app, routeDeps); registerMemorySlackPublicationRoutes(app, routeDeps); registerWorkspaceArtifactRoutes(app, routeDeps); registerArtifactCatalogRoutes(app, routeDeps); registerPreferenceRegistryRoutes(app, routeDeps); registerSocialRoutes(app, routeDeps); registerPersonalGitHubRoutes(app, routeDeps); registerPersonalGitHubGitBrokerRoutes(app, routeDeps); registerConnectionRoutes(app, routeDeps); registerConnectRoutes(app, routeDeps); registerHostMcpBindingRoutes(app, routeDeps); registerHostMcpResolverRoutes(app, routeDeps); registerExternalIdentityLinkRoutes(app, routeDeps); registerCapabilityRoutes(app, routeDeps); registerApiIntegrationRoutes(app, routeDeps); registerIntegrationFacetRoutes(app, routeDeps); registerCatalogAssetRoutes(app, routeDeps); registerEnrollmentRoutes(app, routeDeps); registerMachineRoutes(app, routeDeps); registerEnvironmentRoutes(app, routeDeps); registerChannelRoutes(app, routeDeps); registerRigRoutes(app, routeDeps); registerPackRoutes(app, routeDeps); registerAutomationRoutes(app, routeDeps); registerPrReviewRoutes(app, routeDeps); registerPluginRoutes(app, routeDeps); registerSkillRoutes(app, routeDeps); registerSessionRoutes(app, routeDeps); registerFeedbackRoutes(app, routeDeps); registerScheduledTaskRoutes(app, routeDeps); registerCodexRoutes(app, routeDeps); registerOrganizationModelProviderRoutes(app, routeDeps); registerModelConnectionAccessRoutes(app, routeDeps); registerSuperGrokRoutes(app, routeDeps); registerTranscriptionRoutes(app, routeDeps); registerEditableArtifactRoutes(app, routeDeps); registerVideoGenerationRoutes(app, routeDeps); registerCanonicalHumanIdentityRoutes(app, routeDeps); registerOrganizationMembershipRoutes(app, routeDeps); registerOrganizationSessionRoutes(app, routeDeps); registerOrganizationRecoveryRoutes(app, routeDeps); registerUserResourceAuthorityRoutes(app, routeDeps); registerConnectionAuthorityRoutes(app, routeDeps); registerSlackInteractionRoutes(app, routeDeps); app.notFound((c) => { if (!new URL(c.req.url).pathname.startsWith("/v1/")) return c.text("Not Found", 404); const requestId = correlationIds.get(c.req.raw) ?? crypto.randomUUID(); return c.json( ErrorEnvelope.parse({ error: { status: 404, code: "not_found", message: "Resource not found.", retryable: false, requestId, }, }), 404, ); }); app.onError((rawError, c) => { // One central mapping for every Send/Steer/control route: a bounded // control-prefix wait that expired is a known, retryable, not-applied 503. const error = workspaceControlBusyHttpError(rawError) ?? rawError; const compactionLock = codexCompactionV2ProviderLockedError(error); const apiError = error instanceof ApiHttpError ? error : null; const status = compactionLock ? 422 : httpStatusForError(error); const code: ErrorCode = compactionLock ? compactionLock.code : (apiError?.code ?? errorCodeForStatus(status)); const requestId = correlationIds.get(c.req.raw) ?? crypto.randomUUID(); c.header(OPENGENI_CORRELATION_HEADER, requestId); if (new URL(c.req.url).pathname.startsWith("/v1/")) { c.header(OPENGENI_API_CONTRACT_HEADER, OPENGENI_API_CONTRACT_REVISION); } const envelope = ErrorEnvelope.parse({ error: { status, code, message: compactionLock ? (boundedPublicMessage(compactionLock.message) ?? "Request failed.") : apiError ? (boundedPublicMessage(apiError.message) ?? "Request failed.") : publicErrorMessage(error, status), retryable: apiError?.retryable ?? retryableHttpStatus(status), ...((apiError?.outcomeUnknown ?? mutationOutcomeUnknown(error, c.req.method)) ? { outcomeUnknown: true } : {}), requestId, ...(apiError?.details ? { details: apiError.details } : {}), }, }); return c.json(envelope, status as ContentfulStatusCode); }); return { app, routeDeps }; } function managedAuthOAuthCallbackProvider(pathname: string): "google" | "github" | null { const match = pathname.match(/^\/v1\/auth\/callback\/(google|github)$/u); return match?.[1] === "google" || match?.[1] === "github" ? match[1] : null; } function mutationOutcomeUnknown(error: unknown, method: string): boolean { if (method === "GET" || method === "HEAD" || method === "OPTIONS") return false; const cause = error instanceof HTTPException ? error.cause : error; return ( cause instanceof BrowserControlTransportError || cause instanceof BrowserControlProtocolError ); } export function appendVary(current: string | null, value: string): string { const values = (current ?? "") .split(",") .map((entry) => entry.trim()) .filter(Boolean); if (!values.some((entry) => entry.toLowerCase() === value.toLowerCase())) { values.push(value); } return values.join(", "); } const publicWorkspaceBrowserRoutePatterns = [ /^\/v1\/workspaces\/[^/]+\/github\/connect$/, /^\/v1\/workspaces\/[^/]+\/github\/installations\/[^/]+\/configure$/, /^\/v1\/workspaces\/[^/]+\/github\/installations\/select$/, ] as const; export function workspaceActorContextExempt(method: string, pathname: string): boolean { // The account-scoped provisioning route shares the workspace collection prefix. // Hono's trailing wildcard also matches it, but "external" is not a workspace UUID; // the route performs its own organization API-key authorization. if (method === "PUT" && pathname === "/v1/workspaces/external") return true; if (/^\/v1\/workspaces\/[^/]+\/mcp(?:\/(?:docs|files))?$/.test(pathname)) return true; if ( method === "GET" && publicWorkspaceBrowserRoutePatterns.some((route) => route.test(pathname)) ) { return true; } return method === "POST" && /^\/v1\/workspaces\/[^/]+\/github\/installations$/.test(pathname); } function workspaceRequestRequiresCodexAccountPrevalidation(request: Request): boolean { return ( request.method === "POST" && /^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+\/codex-account$/.test(new URL(request.url).pathname) ); } async function validateCodexAccountTarget(request: Request): Promise { const body = (await request .clone() .json() .catch(() => null)) as { target?: unknown } | null; if (typeof body?.target !== "string" || body.target.length === 0) { throw new HTTPException(400, { message: 'target is required ("auto" or an account id)', }); } } async function requireMcpAccessGrantAuthorization( c: Parameters[0], deps: ApiRouteDeps, workspaceId: string, ): Promise>> { const authorization = await requireAccessGrantAuthorization(c, deps, workspaceId); const grant = authorization.grant; if (hasPermission(grant.permissions, "workspace:read")) { return authorization; } if (isCodemodeGrant(grant)) { requirePermission(grant, "workspace:read"); } // A worker-signed session-bound grant is allowed to reach the transport // without inheriting broad workspace read access. The exact session // authorization seam runs immediately after this gate, and tool registration // still exposes only capabilities permitted by the delegated grant. if (grant.metadata?.delegated === true && typeof grant.metadata.sessionId === "string") { return authorization; } requirePermission(grant, "workspace:read"); return authorization; } function clientAuthConfig(settings: AppDependencies["settings"]) { if (settings.productAccessMode === "managed") { return { mode: "managedSession" as const, session: "cookie" as const, emailVerificationRequired: settings.environment !== "local", socialProviders: [ ...(settings.managedAuthGoogleClientId && settings.managedAuthGoogleClientSecret ? (["google"] as const) : []), ...(settings.managedAuthGithubClientId && settings.managedAuthGithubClientSecret ? (["github"] as const) : []), ], }; } if (settings.productAccessMode === "configured") { return { mode: "configuredToken" as const, headerName: "authorization" as const, scheme: "bearer" as const, }; } if (settings.authRequired) { return { mode: "deploymentKey" as const, headerName: "x-opengeni-access-key" as const, }; } return { mode: "none" as const }; } function codemodeHttpError(error: unknown): HTTPException { if (error instanceof SiteSessionPathError) { // The proxied Site/SDK surface is an explicit allowlist; a route outside // it (tool policy, visibility, forks, Steer, control, ...) does not exist // for this caller rather than being a server fault. return new HTTPException(404, { message: error.message, cause: error }); } if (error instanceof SessionAuthorizationDeniedError) { return new HTTPException(404, { message: "session not found", cause: error, }); } if (error instanceof SessionAuthorizationUnavailableError) { return new HTTPException(503, { message: "session authorization is unavailable", cause: error, }); } if (error instanceof CodemodeCatalogNotReadyError) { return new ApiHttpError(409, { code: "conflict", message: error.message, retryable: true, outcomeUnknown: false, details: { code: error.code }, }); } if (error instanceof CodemodeCatalogStaleError) { return new ApiHttpError(409, { code: "conflict", message: error.message, retryable: true, outcomeUnknown: false, details: { code: error.code }, }); } if (error instanceof CodemodeAuthorityError) { return new ApiHttpError(error.reason === "invalid_grant" ? 403 : 409, { code: error.reason === "invalid_grant" ? "forbidden" : "conflict", message: error.message, retryable: false, outcomeUnknown: false, details: { code: error.code }, }); } if (error instanceof CodemodeOperationNotExecutableError) { return new HTTPException(409, { message: error.message, cause: error }); } if (error instanceof CodemodeOperationConflictError) { return new HTTPException(409, { message: error.message, cause: error }); } if (error instanceof CodemodeToolNotInCatalogError) { return new HTTPException(404, { message: error.message, cause: error }); } if (error instanceof CodemodeToolApprovalRequiredError) { return new HTTPException(409, { message: error.message, cause: error }); } if (error instanceof CodemodePayloadTooLargeError) { return new HTTPException(413, { message: error.message, cause: error }); } return error instanceof HTTPException ? error : new HTTPException(500, { message: "Codemode request failed", cause: error, }); } function clientAnalyticsConfig(settings: AppDependencies["settings"]) { if (!settings.analyticsEnabled) { return { consentRequired: true, providers: {} }; } return { consentRequired: settings.analyticsConsentRequired, providers: { ...(settings.analyticsReoClientId ? { reo: { clientId: settings.analyticsReoClientId } } : {}), ...(settings.analyticsPosthogProjectKey && settings.analyticsPosthogHost ? { posthog: { projectKey: settings.analyticsPosthogProjectKey, host: settings.analyticsPosthogHost, }, } : {}), ...(settings.analyticsGa4MeasurementId ? { ga4: { measurementId: settings.analyticsGa4MeasurementId } } : {}), }, }; } function structuredServicesHint(backend: string): { fileSystem: boolean; git: boolean; terminalEvents: boolean; } { const hasBox = backend !== "none"; return { fileSystem: hasBox, git: hasBox, terminalEvents: hasBox }; } function codexCompactionV2ProviderLockedError( error: unknown, ): CodexCompactionV2ProviderLockedError | null { if (error instanceof CodexCompactionV2ProviderLockedError) return error; if ( error instanceof HTTPException && error.cause instanceof CodexCompactionV2ProviderLockedError ) { return error.cause; } return null; } export function httpStatusForError(error: unknown): number { if (error instanceof ConnectAttemptConflictError) return 409; if (error instanceof ConnectAttemptNotFoundError) return 404; if (codexCompactionV2ProviderLockedError(error)) { return 422; } if (workspaceControlBusyHttpError(error)) { return 503; } if (error instanceof HTTPException) { return error.status; } if (error instanceof McpPayloadTooLargeError) { return 413; } return 500; } export function errorCodeForStatus(status: number): ErrorCode { if (status === 401) return "unauthenticated"; if (status === 402) return "payment_required"; if (status === 403) return "forbidden"; if (status === 404) return "not_found"; if (status === 409) return "conflict"; if (status === 413 || status === 422 || status === 400) return "validation_failed"; if (status === 429) return "limit_exceeded"; if (status === 502 || status === 503 || status === 504) return "upstream_unavailable"; return "internal_error"; } function retryableHttpStatus(status: number): boolean { return status === 408 || status === 425 || status === 429 || status >= 500; } function publicErrorMessage(error: unknown, status: number): string { if (error instanceof ConnectAttemptConflictError) return "Connection setup changed or is still in progress. Reload its current status before retrying."; if (error instanceof ConnectAttemptNotFoundError) return "Connection setup not found."; if (status === 502 || status === 503 || status === 504) { return "OpenGeni is temporarily unavailable — retry."; } if (status >= 500) { return "OpenGeni could not complete the request."; } if (error instanceof HTTPException) { return boundedPublicMessage(error.message) ?? "Request failed."; } if (error instanceof McpPayloadTooLargeError) { return "Request payload is too large."; } return "Request failed."; } function boundedPublicMessage(value: string): string | null { const normalized = value.replace(/[\u0000-\u001f\u007f]+/g, " ").trim(); if (!normalized) return null; const bytes = new TextEncoder().encode(normalized); if (bytes.byteLength <= API_PUBLIC_ERROR_MESSAGE_MAX_BYTES) return normalized; return new TextDecoder().decode(bytes.slice(0, API_PUBLIC_ERROR_MESSAGE_MAX_BYTES)).trim(); } function boundedCorrelationId(value: string | undefined): string | null { if (!value || value.length > 128 || !/^[A-Za-z0-9._:-]+$/.test(value)) return null; return value; } type ReadinessCheckName = "db" | "nats" | "temporal"; type ReadinessCheck = () => Promise | void; type ReadinessChecks = Record; type ReadinessCheckResult = { ok: boolean; error?: string }; function readinessChecks(deps: AppDependencies): ReadinessChecks { const configuredNatsCheck = deps.readinessChecks?.nats; return { db: async () => { if (deps.readinessChecks?.db) { await deps.readinessChecks.db(); } else { await deps.db.execute(dbSql`select 1`); } await resolveCatalogSettings(deps.db, deps.settings); }, nats: async () => { requireSessionEventDurableFanoutCapability(deps.bus); if (configuredNatsCheck) { await configuredNatsCheck(); } else { if (deps.bus.isConnected && !deps.bus.isConnected()) { throw new Error("NATS is not connected"); } } }, temporal: deps.readinessChecks?.temporal ?? deps.workflowClient.check ?? (() => { throw new Error("Temporal readiness check unavailable"); }), }; } async function runReadinessChecks>>( checks: Checks, timeoutMs: number, ): Promise<{ ok: boolean; checks: { [Name in keyof Checks]: ReadinessCheckResult }; }> { const entries = await Promise.all( (Object.entries(checks) as Array<[keyof Checks, ReadinessCheck]>).map(async ([name, check]) => { try { await withTimeout(Promise.resolve().then(check), timeoutMs); return [name, { ok: true }] as const; } catch { return [ name, { ok: false, error: "dependency_unavailable", }, ] as const; } }), ); const result = Object.fromEntries(entries) as { [Name in keyof Checks]: ReadinessCheckResult; }; return { ok: Object.values(result).every((check) => check.ok), checks: result, }; } async function withTimeout(promise: Promise, timeoutMs: number): Promise { let timer: ReturnType | undefined; try { return await Promise.race([ promise, new Promise((_, reject) => { timer = setTimeout( () => reject(new Error(`readiness check timed out after ${timeoutMs}ms`)), timeoutMs, ); }), ]); } finally { if (timer) { clearTimeout(timer); } } } const routeLabelPatterns: Array<{ pattern: RegExp; label: string | ((match: RegExpMatchArray) => string); }> = [ { pattern: /^\/\.well-known\/oauth-authorization-server$/, label: "/.well-known/oauth-authorization-server", }, { pattern: /^\/\.well-known\/oauth-protected-resource\/v1\/workspaces\/[^/]+\/mcp(?:\/(docs|files))?$/, label: (match) => `/.well-known/oauth-protected-resource/v1/workspaces/:workspaceId/mcp${match[1] ? `/${match[1]}` : ""}`, }, { pattern: /^\/oauth\/(register|authorize|token)$/, label: (match) => `/oauth/${match[1]}`, }, { pattern: /^\/healthz$/, label: "/healthz" }, { pattern: /^\/readyz$/, label: "/readyz" }, { pattern: /^\/traffic-readyz$/, label: "/traffic-readyz" }, { pattern: /^\/v1\/workspaces\/[^/]+\/codex\/connect\/start$/, label: "/v1/workspaces/:workspaceId/codex/connect/start", }, { pattern: /^\/v1\/workspaces\/[^/]+\/codex\/connect\/poll$/, label: "/v1/workspaces/:workspaceId/codex/connect/poll", }, { pattern: /^\/v1\/workspaces\/[^/]+\/codex\/status$/, label: "/v1/workspaces/:workspaceId/codex/status", }, { pattern: /^\/v1\/workspaces\/[^/]+\/codex\/source$/, label: "/v1/workspaces/:workspaceId/codex/source", }, { pattern: /^\/v1\/organizations\/[^/]+\/codex\/(accounts|settings)$/, label: (match) => `/v1/organizations/:organizationId/codex/${match[1]}`, }, { pattern: /^\/v1\/organizations\/[^/]+\/codex\/connect\/(start|poll)$/, label: (match) => `/v1/organizations/:organizationId/codex/connect/${match[1]}`, }, { pattern: /^\/v1\/organizations\/[^/]+\/codex\/accounts\/[^/]+(?:\/activate)?$/, label: "/v1/organizations/:organizationId/codex/accounts/:accountId", }, { pattern: /^\/v1\/workspaces\/[^/]+\/supergrok\/connect\/(start|poll)$/, label: (match) => `/v1/workspaces/:workspaceId/supergrok/connect/${match[1]}`, }, { pattern: /^\/v1\/workspaces\/[^/]+\/supergrok\/(status|accounts|settings)$/, label: (match) => `/v1/workspaces/:workspaceId/supergrok/${match[1]}`, }, { pattern: /^\/v1\/workspaces\/[^/]+\/supergrok\/accounts\/[^/]+\/(activate|allocator)$/, label: (match) => `/v1/workspaces/:workspaceId/supergrok/accounts/:accountId/${match[1]}`, }, { pattern: /^\/v1\/workspaces\/[^/]+\/supergrok\/accounts\/[^/]+$/, label: "/v1/workspaces/:workspaceId/supergrok/accounts/:accountId", }, { pattern: /^\/v1\/workspaces\/[^/]+\/codex\/usage$/, label: "/v1/workspaces/:workspaceId/codex/usage", }, { pattern: /^\/v1\/workspaces\/[^/]+\/codex$/, label: "/v1/workspaces/:workspaceId/codex", }, { pattern: /^\/metrics$/, label: "/metrics" }, { pattern: /^\/v1\/config\/client$/, label: "/v1/config/client" }, { pattern: /^\/v1\/billing$/, label: "/v1/billing" }, { pattern: /^\/v1\/billing\/checkout$/, label: "/v1/billing/checkout" }, { pattern: /^\/v1\/billing\/usage$/, label: "/v1/billing/usage" }, { pattern: /^\/v1\/workspaces\/[^/]+\/insights$/, label: "/v1/workspaces/:workspaceId/insights", }, { pattern: /^\/v1\/billing\/entitlements$/, label: "/v1/billing/entitlements", }, { pattern: /^\/v1\/webhooks\/stripe$/, label: "/v1/webhooks/stripe" }, { pattern: /^\/v1\/workspaces\/[^/]+\/pr-review\/(registrations|repositories)(?:\/[^/]+)?$/, label: (match) => `/v1/workspaces/:workspaceId/pr-review/${match[1]}`, }, { pattern: /^\/v1\/workspaces\/[^/]+\/mcp$/, label: "/v1/workspaces/:workspaceId/mcp", }, { pattern: /^\/v1\/workspaces\/[^/]+\/mcp\/docs$/, label: "/v1/workspaces/:workspaceId/mcp/docs", }, { pattern: /^\/v1\/workspaces\/[^/]+\/mcp\/files$/, label: "/v1/workspaces/:workspaceId/mcp/files", }, { pattern: /^\/v1\/workspaces\/[^/]+\/tools\/catalog$/, label: "/v1/workspaces/:workspaceId/tools/catalog", }, { pattern: /^\/v1\/workspaces\/[^/]+\/tools\/calls$/, label: "/v1/workspaces/:workspaceId/tools/calls", }, { pattern: /^\/v1\/workspaces\/[^/]+\/tools\/approvals$/, label: "/v1/workspaces/:workspaceId/tools/approvals", }, { pattern: /^\/v1\/workspaces\/[^/]+\/tools\/declarations$/, label: "/v1/workspaces/:workspaceId/tools/declarations", }, { pattern: /^\/v1\/workspaces\/[^/]+\/default-rig$/, label: "/v1/workspaces/:workspaceId/default-rig", }, { pattern: /^\/v1\/workspaces\/[^/]+\/sessions$/, label: "/v1/workspaces/:workspaceId/sessions", }, { pattern: /^\/v1\/workspaces\/[^/]+\/control-events\/stream$/, label: "/v1/workspaces/:workspaceId/control-events/stream", }, { pattern: /^\/v1\/workspaces\/[^/]+\/live-events\/stream$/, label: "/v1/workspaces/:workspaceId/live-events/stream", }, { pattern: /^\/v1\/workspaces\/[^/]+\/interaction-events\/stream$/, label: "/v1/workspaces/:workspaceId/interaction-events/stream", }, { pattern: /^\/v1\/workspaces\/[^/]+\/attached-browsers\/[^/]+$/, label: "/v1/workspaces/:workspaceId/attached-browsers/:deviceId", }, { pattern: /^\/v1\/workspaces\/[^/]+\/attached-browsers$/, label: "/v1/workspaces/:workspaceId/attached-browsers", }, { pattern: /^\/v1\/workspaces\/[^/]+\/browser-identities\/[^/]+\/revisions$/, label: "/v1/workspaces/:workspaceId/browser-identities/:identityId/revisions", }, { pattern: /^\/v1\/workspaces\/[^/]+\/browser-identities\/[^/]+$/, label: "/v1/workspaces/:workspaceId/browser-identities/:identityId", }, { pattern: /^\/v1\/workspaces\/[^/]+\/browser-identities$/, label: "/v1/workspaces/:workspaceId/browser-identities", }, { pattern: /^\/v1\/workspaces\/[^/]+\/browser-sessions\/[^/]+\/downloads\/[^/]+\/save$/, label: "/v1/workspaces/:workspaceId/browser-sessions/:browserSessionId/downloads/:downloadId/save", }, { pattern: /^\/v1\/workspaces\/[^/]+\/browser-sessions\/[^/]+\/downloads\/[^/]+$/, label: "/v1/workspaces/:workspaceId/browser-sessions/:browserSessionId/downloads/:downloadId", }, { pattern: /^\/v1\/workspaces\/[^/]+\/browser-sessions\/[^/]+\/downloads$/, label: "/v1/workspaces/:workspaceId/browser-sessions/:browserSessionId/downloads", }, { pattern: /^\/v1\/workspaces\/[^/]+\/browser-sessions\/[^/]+\/auth-runs\/[^/]+\/external-auth\/interactive$/, label: "/v1/workspaces/:workspaceId/browser-sessions/:browserSessionId/auth-runs/:authRunId/external-auth/interactive", }, { pattern: /^\/v1\/workspaces\/[^/]+\/browser-sessions\/[^/]+\/auth-runs\/[^/]+\/(external-auth|protected-fill|report|verify)$/, label: (match) => `/v1/workspaces/:workspaceId/browser-sessions/:browserSessionId/auth-runs/:authRunId/${match[1]}`, }, { pattern: /^\/v1\/workspaces\/[^/]+\/browser-sessions\/[^/]+\/auth-runs\/[^/]+$/, label: "/v1/workspaces/:workspaceId/browser-sessions/:browserSessionId/auth-runs/:authRunId", }, { pattern: /^\/v1\/workspaces\/[^/]+\/browser-sessions\/[^/]+\/auth-runs$/, label: "/v1/workspaces/:workspaceId/browser-sessions/:browserSessionId/auth-runs", }, { pattern: /^\/v1\/workspaces\/[^/]+\/browser-sessions\/[^/]+\/targets\/[^/]+\/(diagnostics|observation|select)$/, label: (match) => `/v1/workspaces/:workspaceId/browser-sessions/:browserSessionId/targets/:targetId/${match[1]}`, }, { pattern: /^\/v1\/workspaces\/[^/]+\/browser-sessions\/[^/]+\/targets\/[^/]+$/, label: "/v1/workspaces/:workspaceId/browser-sessions/:browserSessionId/targets/:targetId", }, { pattern: /^\/v1\/workspaces\/[^/]+\/browser-sessions\/[^/]+\/operations\/[^/]+$/, label: "/v1/workspaces/:workspaceId/browser-sessions/:browserSessionId/operations/:operationId", }, { pattern: /^\/v1\/workspaces\/[^/]+\/browser-sessions\/[^/]+\/(actions|attachments|clipboard|end|heartbeat|resume|revisions|suspend|targets)$/, label: (match) => `/v1/workspaces/:workspaceId/browser-sessions/:browserSessionId/${match[1]}`, }, { pattern: /^\/v1\/workspaces\/[^/]+\/browser-sessions\/[^/]+$/, label: "/v1/workspaces/:workspaceId/browser-sessions/:browserSessionId", }, { pattern: /^\/v1\/workspaces\/[^/]+\/browser-sessions$/, label: "/v1/workspaces/:workspaceId/browser-sessions", }, { pattern: /^\/v1\/workspaces\/[^/]+\/computer-sessions\/[^/]+\/targets\/[^/]+\/observation$/, label: "/v1/workspaces/:workspaceId/computer-sessions/:computerSessionId/targets/:targetId/observation", }, { pattern: /^\/v1\/workspaces\/[^/]+\/computer-sessions\/[^/]+\/targets\/[^/]+\/screenshot$/, label: "/v1/workspaces/:workspaceId/computer-sessions/:computerSessionId/targets/:targetId/screenshot", }, { pattern: /^\/v1\/workspaces\/[^/]+\/computer-sessions\/[^/]+\/operations\/[^/]+$/, label: "/v1/workspaces/:workspaceId/computer-sessions/:computerSessionId/operations/:operationId", }, { pattern: /^\/v1\/workspaces\/[^/]+\/computer-sessions\/[^/]+\/(actions|attachments|clipboard|end|heartbeat|targets)$/, label: (match) => `/v1/workspaces/:workspaceId/computer-sessions/:computerSessionId/${match[1]}`, }, { pattern: /^\/v1\/workspaces\/[^/]+\/computer-sessions\/[^/]+$/, label: "/v1/workspaces/:workspaceId/computer-sessions/:computerSessionId", }, { pattern: /^\/v1\/workspaces\/[^/]+\/computer-sessions$/, label: "/v1/workspaces/:workspaceId/computer-sessions", }, { pattern: /^\/v1\/workspaces\/[^/]+\/network-routes\/[^/]+$/, label: "/v1/workspaces/:workspaceId/network-routes/:networkRouteId", }, { pattern: /^\/v1\/workspaces\/[^/]+\/network-routes$/, label: "/v1/workspaces/:workspaceId/network-routes", }, { pattern: /^\/v1\/workspaces\/[^/]+\/site-auth-connections\/[^/]+$/, label: "/v1/workspaces/:workspaceId/site-auth-connections/:siteAuthConnectionId", }, { pattern: /^\/v1\/workspaces\/[^/]+\/site-auth-connections$/, label: "/v1/workspaces/:workspaceId/site-auth-connections", }, { pattern: /^\/v1\/workspaces\/[^/]+\/auth-runs\/[^/]+$/, label: "/v1/workspaces/:workspaceId/auth-runs/:authRunId", }, { pattern: /^\/v1\/workspaces\/[^/]+\/auth-runs$/, label: "/v1/workspaces/:workspaceId/auth-runs", }, { pattern: /^\/v1\/workspaces\/[^/]+\/interaction-interventions\/[^/]+\/resolve$/, label: "/v1/workspaces/:workspaceId/interaction-interventions/:interventionId/resolve", }, { pattern: /^\/v1\/workspaces\/[^/]+\/interaction-interventions\/[^/]+$/, label: "/v1/workspaces/:workspaceId/interaction-interventions/:interventionId", }, { pattern: /^\/v1\/workspaces\/[^/]+\/interaction-interventions$/, label: "/v1/workspaces/:workspaceId/interaction-interventions", }, { pattern: /^\/v1\/workspaces\/[^/]+\/control-events$/, label: "/v1/workspaces/:workspaceId/control-events", }, { pattern: /^\/v1\/workspaces\/[^/]+\/inference-control$/, label: "/v1/workspaces/:workspaceId/inference-control", }, { pattern: /^\/v1\/workspaces\/[^/]+\/pause-timer$/, label: "/v1/workspaces/:workspaceId/pause-timer", }, { pattern: /^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+\/fs\/(list|list-batch|read|write|delete|move|mkdir)$/, label: "/v1/workspaces/:workspaceId/sessions/:id/fs/:operation", }, { pattern: /^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+\/git\/(status|diff|read-batch|log|show)$/, label: "/v1/workspaces/:workspaceId/sessions/:id/git/:operation", }, { pattern: /^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+\/terminal\/(exec|pty)$/, label: "/v1/workspaces/:workspaceId/sessions/:id/terminal/:operation", }, { pattern: /^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+\/terminal\/pty\/(write|resize|close)$/, label: "/v1/workspaces/:workspaceId/sessions/:id/terminal/pty/:action", }, { pattern: /^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+\/events\/stream$/, label: "/v1/workspaces/:workspaceId/sessions/:id/events/stream", }, { pattern: /^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+\/(visibility|forks)$/, label: (match) => `/v1/workspaces/:workspaceId/sessions/:id/${match[1]}`, }, { pattern: /^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+\/lineage$/, label: "/v1/workspaces/:workspaceId/sessions/:id/lineage", }, { pattern: /^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+\/events$/, label: "/v1/workspaces/:workspaceId/sessions/:id/events", }, { pattern: /^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+\/turns$/, label: "/v1/workspaces/:workspaceId/sessions/:id/turns", }, { pattern: /^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+\/queue\/[^/]+\/(move|edit|steer|delete)$/, label: "/v1/workspaces/:workspaceId/sessions/:id/queue/:turnId/:action", }, { pattern: /^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+\/queue$/, label: "/v1/workspaces/:workspaceId/sessions/:id/queue", }, { pattern: /^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+\/composer-draft\/submit$/, label: "/v1/workspaces/:workspaceId/sessions/:id/composer-draft/submit", }, { pattern: /^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+\/composer-draft$/, label: "/v1/workspaces/:workspaceId/sessions/:id/composer-draft", }, { pattern: /^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+\/(control|steer)$/, label: "/v1/workspaces/:workspaceId/sessions/:id/:controlAction", }, { pattern: /^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+\/stream-capabilities$/, label: "/v1/workspaces/:workspaceId/sessions/:id/stream-capabilities", }, { pattern: /^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+\/viewers\/[^/]+\/heartbeat$/, label: "/v1/workspaces/:workspaceId/sessions/:id/viewers/:viewerId/heartbeat", }, { pattern: /^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+\/viewers\/[^/]+$/, label: "/v1/workspaces/:workspaceId/sessions/:id/viewers/:viewerId", }, { pattern: /^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+\/viewers$/, label: "/v1/workspaces/:workspaceId/sessions/:id/viewers", }, { pattern: /^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+\/goal$/, label: "/v1/workspaces/:workspaceId/sessions/:id/goal", }, { pattern: /^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+$/, label: "/v1/workspaces/:workspaceId/sessions/:id", }, { pattern: /^\/v1\/workspaces\/[^/]+\/files\/uploads$/, label: "/v1/workspaces/:workspaceId/files/uploads", }, { pattern: /^\/v1\/workspaces\/[^/]+\/files\/uploads\/[^/]+\/complete$/, label: "/v1/workspaces/:workspaceId/files/uploads/:id/complete", }, { pattern: /^\/v1\/workspaces\/[^/]+\/files\/[^/]+\/download-url$/, label: "/v1/workspaces/:workspaceId/files/:id/download-url", }, { pattern: /^\/v1\/workspaces\/[^/]+\/files\/[^/]+$/, label: "/v1/workspaces/:workspaceId/files/:id", }, { pattern: /^\/v1\/workspaces\/[^/]+\/artifacts\/[^/]+\/content$/, label: "/v1/workspaces/:workspaceId/artifacts/:id/content", }, { pattern: /^\/v1\/workspaces\/[^/]+\/artifacts\/[^/]+$/, label: "/v1/workspaces/:workspaceId/artifacts/:id", }, { pattern: /^\/v1\/workspaces\/[^/]+\/api-keys$/, label: "/v1/workspaces/:workspaceId/api-keys", }, { pattern: /^\/v1\/workspaces\/[^/]+\/api-keys\/[^/]+$/, label: "/v1/workspaces/:workspaceId/api-keys/:id", }, { pattern: /^\/v1\/organizations\/[^/]+\/api-keys$/, label: "/v1/organizations/:organizationId/api-keys", }, { pattern: /^\/v1\/organizations\/[^/]+\/api-keys\/[^/]+$/, label: "/v1/organizations/:organizationId/api-keys/:id", }, { pattern: /^\/v1\/workspaces\/external$/, label: "/v1/workspaces/external", }, { pattern: /^\/v1\/workspaces\/[^/]+\/scheduled-tasks$/, label: "/v1/workspaces/:workspaceId/scheduled-tasks", }, { pattern: /^\/v1\/workspaces\/[^/]+\/scheduled-tasks\/[^/]+\/pause$/, label: "/v1/workspaces/:workspaceId/scheduled-tasks/:id/pause", }, { pattern: /^\/v1\/workspaces\/[^/]+\/scheduled-tasks\/[^/]+\/resume$/, label: "/v1/workspaces/:workspaceId/scheduled-tasks/:id/resume", }, { pattern: /^\/v1\/workspaces\/[^/]+\/scheduled-tasks\/[^/]+\/trigger$/, label: "/v1/workspaces/:workspaceId/scheduled-tasks/:id/trigger", }, { pattern: /^\/v1\/workspaces\/[^/]+\/scheduled-tasks\/[^/]+\/runs$/, label: "/v1/workspaces/:workspaceId/scheduled-tasks/:id/runs", }, { pattern: /^\/v1\/workspaces\/[^/]+\/scheduled-tasks\/[^/]+$/, label: "/v1/workspaces/:workspaceId/scheduled-tasks/:id", }, { pattern: /^\/v1\/workspaces\/[^/]+\/document-bases$/, label: "/v1/workspaces/:workspaceId/document-bases", }, { pattern: /^\/v1\/workspaces\/[^/]+\/document-bases\/[^/]+\/documents\/[^/]+\/reindex$/, label: "/v1/workspaces/:workspaceId/document-bases/:id/documents/:documentId/reindex", }, { pattern: /^\/v1\/workspaces\/[^/]+\/document-bases\/[^/]+\/documents\/[^/]+$/, label: "/v1/workspaces/:workspaceId/document-bases/:id/documents/:documentId", }, { pattern: /^\/v1\/workspaces\/[^/]+\/document-bases\/[^/]+\/documents$/, label: "/v1/workspaces/:workspaceId/document-bases/:id/documents", }, { pattern: /^\/v1\/workspaces\/[^/]+\/document-bases\/[^/]+\/search$/, label: "/v1/workspaces/:workspaceId/document-bases/:id/search", }, { pattern: /^\/v1\/workspaces\/[^/]+\/document-bases\/[^/]+$/, label: "/v1/workspaces/:workspaceId/document-bases/:id", }, { pattern: /^\/v1\/workspaces\/[^/]+\/knowledge\/search$/, label: "/v1/workspaces/:workspaceId/knowledge/search", }, { pattern: /^\/v1\/workspaces\/[^/]+\/knowledge\/memories\/[^/]+$/, label: "/v1/workspaces/:workspaceId/knowledge/memories/:id", }, { pattern: /^\/v1\/workspaces\/[^/]+\/knowledge\/memories$/, label: "/v1/workspaces/:workspaceId/knowledge/memories", }, { pattern: /^\/v1\/workspaces\/[^/]+\/github\/app$/, label: "/v1/workspaces/:workspaceId/github/app", }, { pattern: /^\/v1\/workspaces\/[^/]+\/github\/action-policies$/, label: "/v1/workspaces/:workspaceId/github/action-policies", }, { pattern: /^\/v1\/workspaces\/[^/]+\/github\/repositories$/, label: "/v1/workspaces/:workspaceId/github/repositories", }, { pattern: /^\/v1\/workspaces\/[^/]+\/github\/repositories\/sync$/, label: "/v1/workspaces/:workspaceId/github/repositories/sync", }, { pattern: /^\/v1\/workspaces\/[^/]+\/github\/connect$/, label: "/v1/workspaces/:workspaceId/github/connect", }, { pattern: /^\/v1\/workspaces\/[^/]+\/github\/installations\/select$/, label: "/v1/workspaces/:workspaceId/github/installations/select", }, { pattern: /^\/v1\/workspaces\/[^/]+\/github\/installations\/[^/]+\/configure$/, label: "/v1/workspaces/:workspaceId/github/installations/:installationId/configure", }, { pattern: /^\/v1\/workspaces\/[^/]+\/github\/installations$/, label: "/v1/workspaces/:workspaceId/github/installations", }, { pattern: /^\/v1\/workspaces\/[^/]+\/github\/installations\/[^/]+$/, label: "/v1/workspaces/:workspaceId/github/installations/:installationId", }, { pattern: /^\/v1\/workspaces\/[^/]+\/github\/app-manifest$/, label: "/v1/workspaces/:workspaceId/github/app-manifest", }, { pattern: /^\/v1\/workspaces\/[^/]+\/pr-review\/github$/, label: "/v1/workspaces/:workspaceId/pr-review/github", }, { pattern: /^\/v1\/workspaces\/[^/]+\/pr-review\/github\/connect$/, label: "/v1/workspaces/:workspaceId/pr-review/github/connect", }, { pattern: /^\/v1\/workspaces\/[^/]+\/pr-review\/github\/installations\/select$/, label: "/v1/workspaces/:workspaceId/pr-review/github/installations/select", }, { pattern: /^\/v1\/workspaces\/[^/]+\/pr-review\/github\/installations\/[^/]+\/configure$/, label: "/v1/workspaces/:workspaceId/pr-review/github/installations/:installationId/configure", }, { pattern: /^\/v1\/workspaces\/[^/]+\/capabilities$/, label: "/v1/workspaces/:workspaceId/capabilities", }, { pattern: /^\/v1\/workspaces\/[^/]+\/capabilities\/discovery\/mcp-registry$/, label: "/v1/workspaces/:workspaceId/capabilities/discovery/mcp-registry", }, { pattern: /^\/v1\/workspaces\/[^/]+\/capabilities\/[^/]+\/enable$/, label: "/v1/workspaces/:workspaceId/capabilities/:id/enable", }, { pattern: /^\/v1\/workspaces\/[^/]+\/capabilities\/[^/]+\/disable$/, label: "/v1/workspaces/:workspaceId/capabilities/:id/disable", }, { pattern: /^\/v1\/workspaces\/[^/]+\/integrations\/preview$/, label: "/v1/workspaces/:workspaceId/integrations/preview", }, { pattern: /^\/v1\/workspaces\/[^/]+\/integrations\/install$/, label: "/v1/workspaces/:workspaceId/integrations/install", }, { pattern: /^\/v1\/workspaces\/[^/]+\/integrations\/definitions$/, label: "/v1/workspaces/:workspaceId/integrations/definitions", }, { pattern: /^\/v1\/workspaces\/[^/]+\/integrations\/[^/]+\/instances\/[^/]+\/uninstall-preview$/, label: "/v1/workspaces/:workspaceId/integrations/:capabilityId/instances/:instanceKey/uninstall-preview", }, { pattern: /^\/v1\/workspaces\/[^/]+\/integrations\/[^/]+\/instances\/[^/]+\/facets\/[^/]+\/browse$/, label: "/v1/workspaces/:workspaceId/integrations/:capabilityId/instances/:instanceKey/facets/:facetKey/browse", }, { pattern: /^\/v1\/workspaces\/[^/]+\/integrations\/[^/]+\/instances\/[^/]+\/facets\/[^/]+\/source$/, label: "/v1/workspaces/:workspaceId/integrations/:capabilityId/instances/:instanceKey/facets/:facetKey/source", }, { pattern: /^\/v1\/workspaces\/[^/]+\/integrations\/[^/]+\/instances\/[^/]+\/facets\/[^/]+\/pause$/, label: "/v1/workspaces/:workspaceId/integrations/:capabilityId/instances/:instanceKey/facets/:facetKey/pause", }, { pattern: /^\/v1\/workspaces\/[^/]+\/integrations\/[^/]+\/instances\/[^/]+\/facets\/[^/]+\/resume$/, label: "/v1/workspaces/:workspaceId/integrations/:capabilityId/instances/:instanceKey/facets/:facetKey/resume", }, { pattern: /^\/v1\/workspaces\/[^/]+\/integrations\/[^/]+\/instances\/[^/]+\/facets\/[^/]+$/, label: "/v1/workspaces/:workspaceId/integrations/:capabilityId/instances/:instanceKey/facets/:facetKey", }, { pattern: /^\/v1\/workspaces\/[^/]+\/integrations\/[^/]+\/instances\/[^/]+\/facets$/, label: "/v1/workspaces/:workspaceId/integrations/:capabilityId/instances/:instanceKey/facets", }, { pattern: /^\/v1\/workspaces\/[^/]+\/integrations\/[^/]+\/instances\/[^/]+$/, label: "/v1/workspaces/:workspaceId/integrations/:capabilityId/instances/:instanceKey", }, { pattern: /^\/v1\/workspaces\/[^/]+\/integrations$/, label: "/v1/workspaces/:workspaceId/integrations", }, { pattern: /^\/v1\/workspaces\/[^/]+\/skills\/preview$/, label: "/v1/workspaces/:workspaceId/skills/preview", }, { pattern: /^\/v1\/workspaces\/[^/]+\/skills\/install$/, label: "/v1/workspaces/:workspaceId/skills/install", }, { pattern: /^\/v1\/workspaces\/[^/]+\/skills\/[^/]+\/uninstall-preview$/, label: "/v1/workspaces/:workspaceId/skills/:id/uninstall-preview", }, { pattern: /^\/v1\/workspaces\/[^/]+\/skills\/[^/]+$/, label: "/v1/workspaces/:workspaceId/skills/:id", }, { pattern: /^\/v1\/workspaces\/[^/]+\/environments$/, label: "/v1/workspaces/:workspaceId/environments", }, { pattern: /^\/v1\/workspaces\/[^/]+\/environments\/[^/]+\/variables\/[^/]+$/, label: "/v1/workspaces/:workspaceId/environments/:id/variables/:name", }, { pattern: /^\/v1\/workspaces\/[^/]+\/environments\/[^/]+$/, label: "/v1/workspaces/:workspaceId/environments/:id", }, { pattern: /^\/v1\/workspaces\/[^/]+\/packs$/, label: "/v1/workspaces/:workspaceId/packs", }, { pattern: /^\/v1\/workspaces\/[^/]+\/packs\/installations$/, label: "/v1/workspaces/:workspaceId/packs/installations", }, { pattern: /^\/v1\/workspaces\/[^/]+\/packs\/marketing-social-daily-analysis\/scheduled-tasks$/, label: "/v1/workspaces/:workspaceId/packs/marketing-social-daily-analysis/scheduled-tasks", }, { pattern: /^\/v1\/workspaces\/[^/]+\/packs\/[^/]+\/enable$/, label: "/v1/workspaces/:workspaceId/packs/:id/enable", }, { pattern: /^\/v1\/workspaces\/[^/]+\/packs\/[^/]+$/, label: "/v1/workspaces/:workspaceId/packs/:id", }, { pattern: /^\/v1\/workspaces\/[^/]+\/plugins\/preview$/, label: "/v1/workspaces/:workspaceId/plugins/preview", }, { pattern: /^\/v1\/workspaces\/[^/]+\/plugins$/, label: "/v1/workspaces/:workspaceId/plugins", }, { pattern: /^\/v1\/workspaces\/[^/]+\/plugins\/install$/, label: "/v1/workspaces/:workspaceId/plugins/install", }, { pattern: /^\/v1\/workspaces\/[^/]+\/plugins\/[^/]+\/uninstall-preview$/, label: "/v1/workspaces/:workspaceId/plugins/:pluginKey/uninstall-preview", }, { pattern: /^\/v1\/workspaces\/[^/]+\/plugins\/[^/]+$/, label: "/v1/workspaces/:workspaceId/plugins/:pluginKey", }, { pattern: /^\/v1\/workspaces\/[^/]+\/social\/connections$/, label: "/v1/workspaces/:workspaceId/social/connections", }, { pattern: /^\/v1\/workspaces\/[^/]+\/social\/posts$/, label: "/v1/workspaces/:workspaceId/social/posts", }, { pattern: /^\/v1\/workspaces\/[^/]+\/connections$/, label: "/v1/workspaces/:workspaceId/connections", }, { pattern: /^\/v1\/workspaces\/[^/]+\/connections\/oauth\/start$/, label: "/v1/workspaces/:workspaceId/connections/oauth/start", }, { pattern: /^\/v1\/workspaces\/[^/]+\/connections\/github$/, label: "/v1/workspaces/:workspaceId/connections/github", }, { pattern: /^\/v1\/workspaces\/[^/]+\/connections\/github\/oauth\/start$/, label: "/v1/workspaces/:workspaceId/connections/github/oauth/start", }, { pattern: /^\/v1\/workspaces\/[^/]+\/connections\/[^/]+\/github\/reconnect$/, label: "/v1/workspaces/:workspaceId/connections/:connectionId/github/reconnect", }, { pattern: /^\/v1\/workspaces\/[^/]+\/connections\/[^/]+\/github\/repositories\/verify$/, label: "/v1/workspaces/:workspaceId/connections/:connectionId/github/repositories/verify", }, { pattern: /^\/v1\/workspaces\/[^/]+\/connections\/[^/]+\/github\/repositories$/, label: "/v1/workspaces/:workspaceId/connections/:connectionId/github/repositories", }, { pattern: /^\/v1\/workspaces\/[^/]+\/integrations\/oauth\/start$/, label: "/v1/workspaces/:workspaceId/integrations/oauth/start", }, { pattern: /^\/v1\/workspaces\/[^/]+\/connections\/slack-bot\/install$/, label: "/v1/workspaces/:workspaceId/connections/slack-bot/install", }, { pattern: /^\/v1\/workspaces\/[^/]+\/connections\/fiken\/install$/, label: "/v1/workspaces/:workspaceId/connections/fiken/install", }, { pattern: /^\/v1\/workspaces\/[^/]+\/connections\/fiken\/oauth\/start$/, label: "/v1/workspaces/:workspaceId/connections/fiken/oauth/start", }, { pattern: /^\/v1\/integrations\/fiken\/callback$/, label: "/v1/integrations/fiken/callback", }, { pattern: /^\/v1\/workspaces\/[^/]+\/connections\/[^/]+$/, label: "/v1/workspaces/:workspaceId/connections/:connectionId", }, { pattern: /^\/v1\/git\/personal\/[^/]+\/info\/refs$/, label: "/v1/git/personal/:routeId/info/refs", }, { pattern: /^\/v1\/git\/personal\/[^/]+\/git-upload-pack$/, label: "/v1/git/personal/:routeId/git-upload-pack", }, { pattern: /^\/v1\/git\/personal\/[^/]+\/git-receive-pack$/, label: "/v1/git/personal/:routeId/git-receive-pack", }, { pattern: /^\/v1\/catalog-assets\/.+$/, label: "/v1/catalog-assets/*" }, { pattern: /^\/v1\/integrations\/oauth\/callback$/, label: "/v1/integrations/oauth/callback", }, { pattern: /^\/v1\/integrations\/provider-oauth\/callback$/, label: "/v1/integrations/provider-oauth/callback", }, { pattern: /^\/v1\/integrations\/github-personal\/oauth\/callback$/, label: "/v1/integrations/github-personal/oauth/callback", }, { pattern: /^\/v1\/integrations\/google-drive\/callback$/, label: "/v1/integrations/google-drive/callback", }, { pattern: /^\/v1\/integrations\/oauth\/client-metadata\.json$/, label: "/v1/integrations/oauth/client-metadata.json", }, { pattern: /^\/v1\/integrations\/slack\/callback$/, label: "/v1/integrations/slack/callback", }, { pattern: /^\/v1\/social\/oauth\/callback$/, label: "/v1/social/oauth/callback", }, { pattern: /^\/v1\/enrollments\/device\/start$/, label: "/v1/enrollments/device/start", }, { pattern: /^\/v1\/enrollments\/device\/poll$/, label: "/v1/enrollments/device/poll", }, { pattern: /^\/v1\/workspaces\/[^/]+\/enrollments\/device\/approve$/, label: "/v1/workspaces/:workspaceId/enrollments/device/approve", }, { pattern: /^\/v1\/workspaces\/[^/]+\/enrollments\/[^/]+\/revoke$/, label: "/v1/workspaces/:workspaceId/enrollments/:id/revoke", }, { pattern: /^\/v1\/workspaces\/[^/]+\/enrollments$/, label: "/v1/workspaces/:workspaceId/enrollments", }, { pattern: /^\/v1\/workspaces\/[^/]+\/machines\/[^/]+\/metrics\/series$/, label: "/v1/workspaces/:workspaceId/machines/:enrollmentId/metrics/series", }, { pattern: /^\/v1\/workspaces\/[^/]+\/machines\/[^/]+\/operation-policy$/, label: "/v1/workspaces/:workspaceId/machines/:enrollmentId/operation-policy", }, { pattern: /^\/v1\/workspaces\/[^/]+\/machines\/[^/]+\/update$/, label: "/v1/workspaces/:workspaceId/machines/:enrollmentId/update", }, { pattern: /^\/v1\/workspaces\/[^/]+\/machines$/, label: "/v1/workspaces/:workspaceId/machines", }, { pattern: /^\/v1\/github\/app-manifest\/callback$/, label: "/v1/github/app-manifest/callback", }, { pattern: /^\/v1\/github\/setup$/, label: "/v1/github/setup" }, { pattern: /^\/v1\/github\/install\/callback$/, label: "/v1/github/install/callback", }, { pattern: /^\/v1\/github\/oauth\/callback$/, label: "/v1/github/oauth/callback", }, { pattern: /^\/v1\/pr-review\/github\/setup$/, label: "/v1/pr-review/github/setup" }, { pattern: /^\/v1\/pr-review\/github\/install\/callback$/, label: "/v1/pr-review/github/install/callback", }, { pattern: /^\/v1\/pr-review\/github\/oauth\/callback$/, label: "/v1/pr-review/github/oauth/callback", }, { pattern: /^\/v1\/webhooks\/pr-review\/github$/, label: "/v1/webhooks/pr-review/github", }, { pattern: /^\/v1\/workspaces\/[^/]+$/, label: "/v1/workspaces/:workspaceId", }, ]; export function routeLabel(pathname: string): string { if (/^\/v1\/workspaces\/[^/]+\/transcriptions$/.test(pathname)) return "/v1/workspaces/:workspaceId/transcriptions"; const transcription = pathname.match( /^\/v1\/workspaces\/[^/]+\/transcription-recordings(?:\/[^/]+(\/(?:finalize|process-next)|\/chunks\/\d+)?)?$/, ); if (transcription) { const base = "/v1/workspaces/:workspaceId/transcription-recordings"; if (pathname.split("/").length === 5) return base; return ( base + "/:recordingId" + (transcription[1]?.startsWith("/chunks/") ? "/chunks/:chunkNumber" : (transcription[1] ?? "")) ); } for (const candidate of routeLabelPatterns) { const match = pathname.match(candidate.pattern); if (match) { return typeof candidate.label === "string" ? candidate.label : candidate.label(match); } } return pathname.startsWith("/v1/") ? "/v1/unknown" : "/unknown"; } /** * State-changing OpenGeni HTTP calls must never cross an incompatible rollout * boundary. Standard third-party protocols and externally initiated callbacks * are intentionally outside this product API contract. */ export function isApiContractProtectedMutation(method: string, pathname: string): boolean { if (!new Set(["POST", "PUT", "PATCH", "DELETE"]).has(method.toUpperCase())) { return false; } if (!pathname.startsWith("/v1/")) { return false; } if ( pathname === "/v1/auth/organization-onboarding" || pathname === "/v1/auth/organization-setup" ) { return true; } if ( pathname.startsWith("/v1/auth/") || pathname.startsWith("/v1/webhooks/") || pathname.startsWith("/v1/integrations/oauth/") || isPersonalGitHubGitBrokerRequest(method, pathname) || pathname === "/v1/integrations/slack/events" || pathname === "/v1/integrations/slack/commands" || pathname === "/v1/integrations/slack/interactions" || pathname.startsWith("/v1/github/") || pathname === "/v1/enrollments/device/start" || pathname === "/v1/enrollments/device/poll" || pathname === "/v1/enrollments/token/exchange" ) { return false; } const segments = pathname.split("/"); return !segments.includes("mcp") && !segments.includes("codemode"); }