@agimon-ai/doompi-core 0.0.1-alpha.117 → 0.0.1-alpha.119

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.
@@ -32,6 +32,9 @@ function describeResource(resource) {
32
32
  const query = [...parsed.searchParams.keys()].map((key) => `${key}=<redacted>`).join("&");
33
33
  return `${parsed.origin}${pathname}${query === "" ? "" : `?${query}`}${parsed.hash === "" ? "" : "#<redacted>"}`;
34
34
  }
35
+ function redactUrlCredentials(text) {
36
+ return text.replace(/([a-z][a-z0-9+.-]*:\/\/)[^\s/?#]*@/giu, "$1***@");
37
+ }
35
38
  const PROTECTED_RESOURCE_PATTERN = /^\/\.well-known\/oauth-protected-resource(\/api\/workspaces\/[^/]+\/sessions\/[^/]+\/mcp)$/u;
36
39
  function json(status, value) {
37
40
  return Response.json(value, {
@@ -312,6 +315,7 @@ function createSessionMcpRoutes(options) {
312
315
  return child;
313
316
  } catch (error) {
314
317
  if (error instanceof require_index.SessionMcpConversationError) throw error;
318
+ options.onNotice?.(`session MCP worktree provisioning failed for reservation ${record.id}: ${error instanceof Error ? redactUrlCredentials(error.message) : "Automatic worktree provisioning failed."}`);
315
319
  throw new require_index.SessionMcpConversationError("SESSION_WORKTREE_PROVISION_FAILED", "An automatic worktree could not be created for this conversation. Resolve the host Git setup, then retry.", record.id);
316
320
  }
317
321
  })();
@@ -1 +1 @@
1
- {"version":3,"file":"sessionMcpRoutes.cjs","names":["SessionMcpOAuthError","sessionMcpRouting","path","SessionMcpConversationError","fs","createSessionMcpAuthorizationService","createSessionMcpHttpHandler","SESSION_MCP_EXTRA_TOOLS"],"sources":["../../../src/server/sessionMcpRoutes.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport type { DoomHubSessionReservations, DoomHubSessionScope } from '../schemas/hubChannel';\nimport type { SessionMcpActivitySnapshot, SessionMcpAvailableTool } from '../schemas/sessionMcpActivity';\nimport type { SessionMcpActivityStore } from '../services/sessionMcpActivity';\nimport {\n createSessionMcpAuthorizationService,\n SessionMcpOAuthError,\n sessionMcpRouting,\n type SessionMcpAuthorizationBinding,\n type SessionMcpAuthorizationService,\n type SessionMcpClient,\n} from '../services/sessionMcpAuthorization';\nimport { SessionMcpConversationError, type SessionMcpConversationStore } from '../services/sessionMcpConversations';\nimport type { SessionMcpRegistrationStore } from '../services/sessionMcpRegistrationStore';\nimport type { HeadlessHub, HeadlessHubSession } from './headlessHub';\nimport {\n createSessionMcpHttpHandler,\n SESSION_MCP_EXTRA_TOOLS,\n type SessionMcpBaseline,\n type SessionMcpHttpHandler,\n type SessionMcpOperationRegistry,\n} from './sessionMcpHandler';\n\nconst AUTHORIZATION_SERVER_DISCOVERY = '/.well-known/oauth-authorization-server';\nconst AUTHORIZE_ROUTE = '/oauth/authorize';\nconst TOKEN_ROUTE = '/oauth/token';\nconst SESSION_MCP_PATTERN = /^\\/api\\/workspaces\\/([^/]+)\\/sessions\\/([^/]+)\\/mcp$/u;\nconst SESSION_MCP_URL_TOKEN_PATTERN =\n /^\\/api\\/workspaces\\/([^/]+)\\/sessions\\/([^/]+)\\/mcp\\/([A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+)$/u;\nconst SESSION_MCP_ACTIVITY_PATTERN = /^\\/api\\/workspaces\\/([^/]+)\\/sessions\\/([^/]+)\\/mcp\\/activity$/u;\nconst SESSION_MCP_CONFIG_PATTERN = /^\\/api\\/workspaces\\/([^/]+)\\/sessions\\/([^/]+)\\/mcp\\/config$/u;\nconst SESSION_MCP_CLIENTS_PATTERN = /^\\/api\\/workspaces\\/([^/]+)\\/sessions\\/([^/]+)\\/mcp\\/clients(?:\\/([^/]+))?$/u;\nconst SESSION_MCP_CONVERSATIONS_PATTERN =\n /^\\/api\\/workspaces\\/([^/]+)\\/sessions\\/([^/]+)\\/mcp\\/conversations(?:\\/([^/]+))?$/u;\n\n/**\n * An OAuth resource as it can be logged: the URL with any URL-token segment and every query value\n * redacted, so a mismatch in origin, path, trailing slash or query is visible without a secret.\n */\nfunction describeResource(resource: string): string {\n let parsed: URL;\n try {\n parsed = new URL(resource);\n } catch {\n return 'a resource that is not a URL';\n }\n const token = SESSION_MCP_URL_TOKEN_PATTERN.exec(parsed.pathname);\n const pathname = token === null ? parsed.pathname : parsed.pathname.slice(0, -token[3]!.length) + '<token>';\n const query = [...parsed.searchParams.keys()].map((key) => `${key}=<redacted>`).join('&');\n return `${parsed.origin}${pathname}${query === '' ? '' : `?${query}`}${parsed.hash === '' ? '' : '#<redacted>'}`;\n}\nconst PROTECTED_RESOURCE_PATTERN =\n /^\\/\\.well-known\\/oauth-protected-resource(\\/api\\/workspaces\\/[^/]+\\/sessions\\/[^/]+\\/mcp)$/u;\n\nexport interface SessionMcpRoutesOptions {\n readonly headlessHub: HeadlessHub;\n readonly publicOrigin: () => string | undefined;\n readonly publicOriginRevision?: () => number;\n readonly authorization?: SessionMcpAuthorizationService;\n readonly registrationStore?: SessionMcpRegistrationStore;\n readonly conversationStore?: SessionMcpConversationStore;\n readonly activityStore?: SessionMcpActivityStore;\n readonly isSessionPersisted?: (sessionId: string, cwd: string) => boolean;\n readonly onNotice?: (message: string) => void;\n}\n\nexport interface SessionMcpRoutes {\n handlePublic(request: Request): Promise<Response | undefined>;\n handleHost(request: Request): Promise<Response | undefined>;\n readonly reservations: DoomHubSessionReservations;\n closeSessionBinding(sessionId: string): void;\n close(): void;\n}\n\nfunction json(status: number, value: unknown): Response {\n return Response.json(value, { status, headers: { 'cache-control': 'no-store' } });\n}\n\nfunction oauthError(error: unknown): Response {\n if (error instanceof SessionMcpOAuthError)\n return json(error.code === 'invalid_client' ? 401 : 400, {\n error: error.code,\n error_description: error.message,\n });\n return json(400, { error: 'invalid_request', error_description: 'The OAuth request was invalid.' });\n}\n\nfunction trustedOrigin(value: string | undefined): string | undefined {\n if (value === undefined) return undefined;\n try {\n const url = new URL(value);\n return url.protocol === 'https:' && url.pathname === '/' && url.search === '' && url.hash === ''\n ? url.origin\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction sessionPath(workspaceId: string, sessionId: string): string {\n return `/api/workspaces/${encodeURIComponent(workspaceId)}/sessions/${encodeURIComponent(sessionId)}/mcp`;\n}\n\nfunction parseStringArray(value: unknown): readonly string[] | undefined {\n return Array.isArray(value) && value.every((entry) => typeof entry === 'string') ? value : undefined;\n}\n\nfunction defaultClientName(origin: string): string {\n return `ChatGPT · ${new URL(origin).hostname}`;\n}\n\nfunction formString(form: FormData, name: string): string {\n const value = form.get(name);\n return typeof value === 'string' ? value : '';\n}\n\nfunction publicClient(client: SessionMcpClient, binding: SessionMcpAuthorizationBinding): Record<string, unknown> {\n return {\n clientId: client.clientId,\n name: client.name,\n redirectUri: client.redirectUri,\n tokenEndpointAuthMethod: client.tokenEndpointAuthMethod,\n createdAt: client.createdAt,\n scope: binding.scope,\n routing: sessionMcpRouting(binding.routing),\n tools: binding.tools,\n skills: binding.skills,\n audience: binding.audience,\n };\n}\n\n/** Canonicalizes an intended directory without creating it or accepting symlink aliases. */\nfunction executionDirectory(value: string): string {\n if (!path.isAbsolute(value) || value.includes('\\0') || value.length > 4096)\n throw new SessionMcpConversationError('INVALID_EXECUTION_DIRECTORY', 'Choose an absolute execution directory.');\n let ancestor = path.resolve(value);\n const suffix: string[] = [];\n for (;;) {\n try {\n return path.join(fs.realpathSync(ancestor), ...suffix);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT' || path.dirname(ancestor) === ancestor)\n throw new SessionMcpConversationError(\n 'INVALID_EXECUTION_DIRECTORY',\n 'The execution directory cannot be resolved.',\n );\n suffix.unshift(path.basename(ancestor));\n ancestor = path.dirname(ancestor);\n }\n }\n}\n\nfunction overlappingDirectories(left: string, right: string): boolean {\n const contained = (root: string, target: string): boolean => {\n const relative = path.relative(root, target);\n return (\n relative === '' || (!path.isAbsolute(relative) && relative !== '..' && !relative.startsWith(`..${path.sep}`))\n );\n };\n return contained(left, right) || contained(right, left);\n}\n\n/** Routes the process-local session MCP authority and revokes every grant with its live incarnation. */\nexport function createSessionMcpRoutes(options: SessionMcpRoutesOptions): SessionMcpRoutes {\n const authorization = options.authorization ?? createSessionMcpAuthorizationService();\n // ponytail: Catalog baselines last one parent incarnation; persist snapshots only if clients must avoid a refresh after restart.\n const incarnations = new Map<\n string,\n {\n host: HeadlessHubSession['host'];\n generation: number;\n handlers: Map<string, SessionMcpHttpHandler>;\n operations: SessionMcpOperationRegistry;\n baselines: Map<string, SessionMcpBaseline>;\n }\n >();\n let nextGeneration = 1;\n let publishPending = (): void => {};\n\n const revokeIncarnation = (sessionId: string, generation: number): void => {\n authorization.revokeSessionGeneration(sessionId, generation);\n };\n const abortOperations = (operations: SessionMcpOperationRegistry): void => {\n for (const operation of operations.values()) operation.controller.abort();\n operations.clear();\n };\n const register = (session: HeadlessHubSession): boolean => {\n const current = incarnations.get(session.id);\n if (current?.host === session.host) return false;\n if (current !== undefined) {\n revokeIncarnation(session.id, current.generation);\n abortOperations(current.operations);\n }\n incarnations.set(session.id, {\n host: session.host,\n generation: nextGeneration++,\n handlers: new Map(),\n baselines: new Map(),\n operations: new Map(),\n });\n return true;\n };\n for (const session of options.headlessHub.snapshot()) register(session);\n const unsubscribe = options.headlessHub.onEvent((event) => {\n if (event.kind === 'upsert' && register(event.session)) publishPending();\n if (event.kind === 'removed') {\n const current = incarnations.get(event.sessionId);\n if (current !== undefined) {\n revokeIncarnation(event.sessionId, current.generation);\n abortOperations(current.operations);\n }\n incarnations.delete(event.sessionId);\n }\n });\n\n let observedOrigin: string | undefined;\n let observedOriginRevision: number | undefined;\n let originObserved = false;\n const origin = (): string | undefined => {\n const current = trustedOrigin(options.publicOrigin());\n const revision = options.publicOriginRevision?.();\n if (\n (originObserved && current !== observedOrigin) ||\n (revision !== undefined && observedOriginRevision !== undefined && revision !== observedOriginRevision)\n ) {\n for (const client of authorization.listClients()) {\n authorization.revokeClient(client.clientId);\n options.registrationStore?.remove(client.clientId);\n }\n for (const incarnation of incarnations.values()) {\n incarnation.handlers.clear();\n incarnation.baselines.clear();\n abortOperations(incarnation.operations);\n }\n }\n observedOrigin = current;\n observedOriginRevision = revision;\n originObserved = true;\n restorePersistedRegistrations(current);\n return current;\n };\n const target = (workspaceId: string, sessionId: string) => {\n // Remote MCP clients cannot inherit a grant, including through conversation child routing.\n if (options.headlessHub.computerUse?.ownsSession?.(sessionId)) return undefined;\n const session = options.headlessHub.session(sessionId);\n const incarnation = incarnations.get(sessionId);\n return session !== undefined && session.workspaceId === workspaceId && incarnation?.host === session.host\n ? { session, generation: incarnation.generation }\n : undefined;\n };\n const restorePersistedRegistrations = (configuredOrigin: string | undefined): void => {\n if (configuredOrigin === undefined) return;\n for (const registration of options.registrationStore?.registrations() ?? []) {\n const audience = `${configuredOrigin}${sessionPath(registration.workspaceId, registration.binding.sessionId)}`;\n if (registration.binding.audience !== audience) {\n options.registrationStore?.remove(registration.client.clientId);\n continue;\n }\n const resolved = target(registration.workspaceId, registration.binding.sessionId);\n if (resolved !== undefined) authorization.restorePersistentRegistration(registration, resolved.generation);\n }\n };\n\n const requireStore = (): SessionMcpConversationStore => {\n if (!options.conversationStore)\n throw new SessionMcpConversationError(\n 'CONVERSATION_ROUTING_UNAVAILABLE',\n 'Persistent conversation routing is unavailable.',\n );\n return options.conversationStore;\n };\n publishPending = () => {\n if (!options.conversationStore) return;\n try {\n const records = options.conversationStore.list();\n for (const parent of options.headlessHub.snapshot())\n options.headlessHub.setPendingSessionSetups?.(\n parent.id,\n records\n .filter((record) => record.parentSessionId === parent.id && record.state === 'pending')\n .map((record) => ({\n id: record.id,\n name: `conversation ${record.id.slice(0, 8)}`,\n createdAt: record.createdAt,\n status:\n provision.has(record.id) || recoveries.has(record.id)\n ? ('provisioning' as const)\n : record.failureCode === undefined\n ? ('interrupted' as const)\n : ('failed' as const),\n ...(record.setupKind === undefined ? {} : { setupKind: record.setupKind }),\n ...(record.failureCode === undefined ? {} : { errorCode: record.failureCode }),\n ...(record.cwd === undefined ? {} : { cwd: record.cwd }),\n })),\n );\n } catch (error) {\n options.onNotice?.(error instanceof Error ? error.message : 'Conversation bindings are unavailable.');\n }\n };\n const readReservation = (id: string, parentSessionId: string) => {\n origin();\n const record = requireStore().get(id, parentSessionId);\n const binding = authorization.readAuthorizationBinding(record.clientId);\n const parent = target(record.parentWorkspaceId, parentSessionId);\n if (\n !parent ||\n binding?.routing !== 'conversation' ||\n binding.sessionId !== parentSessionId ||\n binding.sessionGeneration !== parent.generation\n )\n throw new SessionMcpConversationError(\n 'SESSION_UNAVAILABLE',\n 'The connection that owns this setup is no longer active.',\n id,\n );\n return { record, parent };\n };\n const reservations: DoomHubSessionReservations = {\n read(id, parentSessionId) {\n const { record } = readReservation(id, parentSessionId);\n return { sessionId: record.id, ...(record.cwd === undefined ? {} : { cwd: record.cwd }) };\n },\n async prepare(id, parentSessionId, suppliedDirectory) {\n const { record, parent } = readReservation(id, parentSessionId);\n const cwd = executionDirectory(suppliedDirectory);\n const parentRoot =\n options.headlessHub.workspaces().find((workspace) => workspace.id === parent.session.workspaceId)?.root ??\n parent.session.cwd;\n const occupied = [\n parentRoot,\n ...options.headlessHub\n .snapshot()\n .filter((session) => session.id !== id)\n .map((session) => session.cwd),\n ...requireStore()\n .list()\n .filter((entry) => entry.id !== id && entry.state !== 'closed' && entry.cwd !== undefined)\n .map((entry) => entry.cwd!),\n ];\n if (occupied.some((directory) => overlappingDirectories(cwd, executionDirectory(directory))))\n throw new SessionMcpConversationError(\n 'EXECUTION_DIRECTORY_SHARED',\n 'Choose a separate checkout, not a directory shared with another session.',\n id,\n );\n if (record.state === 'bound' && record.cwd !== cwd)\n throw new SessionMcpConversationError(\n 'SESSION_TARGET_FIXED',\n 'An initialized session cannot change its directory.',\n id,\n );\n requireStore().prepare(id, parentSessionId, cwd);\n publishPending();\n return { sessionId: id, cwd };\n },\n async complete(id, parentSessionId): Promise<DoomHubSessionScope> {\n const { record } = readReservation(id, parentSessionId);\n const child = options.headlessHub.session(id);\n if (\n !record.cwd ||\n !child?.workspaceId ||\n child.parentSessionId !== parentSessionId ||\n (record.setupKind === 'managed-worktree' && child.workspaceId !== record.parentWorkspaceId) ||\n executionDirectory(child.cwd) !== record.cwd ||\n options.isSessionPersisted?.(id, child.cwd) === false\n )\n throw new SessionMcpConversationError(\n 'SESSION_SETUP_INCOMPLETE',\n 'The reserved session is not durably ready. Recover the existing setup instead of creating another checkout.',\n id,\n );\n requireStore().bind(id, parentSessionId, child.workspaceId);\n publishPending();\n return { sessionId: id, workspaceId: child.workspaceId, cwd: child.cwd };\n },\n };\n const provision = new Map<string, Promise<DoomHubSessionScope>>();\n const recoveries = new Map<string, Promise<DoomHubSessionScope>>();\n const setupDirectory = async (\n id: string,\n parentSessionId: string,\n directory: string,\n ): Promise<DoomHubSessionScope> => {\n // A mistyped existing-directory choice must not permanently reserve a nonexistent path.\n const canonical = executionDirectory(directory);\n if (!fs.statSync(canonical).isDirectory()) throw new Error('The execution directory is not a directory.');\n const { record: current } = readReservation(id, parentSessionId);\n if (provision.has(id) && current.setupKind === 'managed-worktree')\n throw new SessionMcpConversationError('SESSION_TARGET_FIXED', 'This setup belongs to a managed worktree.', id);\n const selected = requireStore().selectSetup(id, parentSessionId, 'existing-directory');\n if (selected.setupKind !== 'existing-directory')\n throw new SessionMcpConversationError('SESSION_TARGET_FIXED', 'This setup belongs to a managed worktree.', id);\n const prepared = await reservations.prepare(id, parentSessionId, canonical);\n const pending = provision.get(id);\n if (pending) return pending;\n const setup = (async () => {\n if (!options.headlessHub.session(id)) {\n const record = requireStore().get(id, parentSessionId);\n if (record.state === 'bound' || options.isSessionPersisted?.(id, prepared.cwd))\n throw new SessionMcpConversationError(\n 'SESSION_UNAVAILABLE',\n 'Resume the existing session in DoomPi. It will not be recreated automatically.',\n id,\n );\n if (!fs.statSync(prepared.cwd).isDirectory()) throw new Error('The execution directory is not a directory.');\n await options.headlessHub.sessionService.create({\n cwd: prepared.cwd,\n name: `conversation ${id.slice(0, 8)}`,\n parentSessionId,\n sessionProvenance: 'remote-conversation',\n reservationId: id,\n });\n }\n return reservations.complete(id, parentSessionId);\n })();\n provision.set(id, setup);\n publishPending();\n try {\n return await setup;\n } catch (error) {\n requireStore().fail(id, parentSessionId, 'SESSION_UNAVAILABLE');\n throw error;\n } finally {\n if (provision.get(id) === setup) provision.delete(id);\n publishPending();\n }\n };\n const provisionConversationWorktree = async (\n record: ReturnType<SessionMcpConversationStore['reserve']>,\n signal?: AbortSignal,\n ): Promise<DoomHubSessionScope> => {\n const pending = provision.get(record.id);\n if (pending) return pending;\n readReservation(record.id, record.parentSessionId);\n requireStore().selectSetup(record.id, record.parentSessionId, 'managed-worktree');\n const setup = (async () => {\n try {\n const child = await options.headlessHub.sessionService.provisionReservedWorktree?.({\n reservationId: record.id,\n parentSessionId: record.parentSessionId,\n signal,\n });\n if (child === undefined || child.sessionId !== record.id)\n throw new Error('Automatic worktree provisioning did not create the reserved session.');\n return child;\n } catch (error) {\n if (error instanceof SessionMcpConversationError) throw error;\n throw new SessionMcpConversationError(\n 'SESSION_WORKTREE_PROVISION_FAILED',\n 'An automatic worktree could not be created for this conversation. Resolve the host Git setup, then retry.',\n record.id,\n );\n }\n })();\n provision.set(record.id, setup);\n publishPending();\n try {\n return await setup;\n } catch (error) {\n requireStore().fail(record.id, record.parentSessionId, 'SESSION_WORKTREE_PROVISION_FAILED');\n throw error;\n } finally {\n if (provision.get(record.id) === setup) provision.delete(record.id);\n publishPending();\n }\n };\n const publicRoutes = async (request: Request): Promise<Response | undefined> => {\n const url = new URL(request.url);\n const configuredOrigin = origin();\n const signedMcpMatch = SESSION_MCP_URL_TOKEN_PATTERN.exec(url.pathname);\n const mcpMatch = SESSION_MCP_PATTERN.exec(url.pathname) ?? signedMcpMatch;\n if (mcpMatch !== null) {\n if (configuredOrigin === undefined) return json(503, { error: 'Session MCP public origin is unavailable.' });\n const workspaceId = decodeURIComponent(mcpMatch[1]);\n const sessionId = decodeURIComponent(mcpMatch[2]);\n const pathToken = signedMcpMatch?.[3];\n const basePath = sessionPath(workspaceId, sessionId);\n const exactPath = pathToken === undefined ? basePath : `${basePath}/${pathToken}`;\n if (url.pathname !== exactPath || url.search !== '') return json(404, { error: 'Not found.' });\n const audience = `${configuredOrigin}${basePath}`;\n const resource = pathToken === undefined ? audience : `${audience}/${pathToken}`;\n const incarnation = target(workspaceId, sessionId) === undefined ? undefined : incarnations.get(sessionId);\n const handlers = incarnation?.handlers;\n const cachedHandler = pathToken === undefined ? handlers?.get(resource) : undefined;\n const handler =\n cachedHandler ??\n createSessionMcpHttpHandler({\n audience,\n baselines: incarnation?.baselines ?? new Map(),\n authorization,\n onNotice: options.onNotice,\n onInvocation: (invocation) => {\n if (invocation.sessionId === undefined || invocation.conversationDigest === undefined) return;\n const conversation = options.conversationStore?.find(\n invocation.clientId,\n invocation.parentSessionId,\n invocation.conversationDigest,\n );\n if (\n conversation?.state !== 'bound' ||\n conversation.id !== invocation.sessionId ||\n conversation.workspaceId === undefined\n )\n return;\n options.activityStore?.record(\n conversation.workspaceId,\n conversation.id,\n authorization.readClient(invocation.clientId)?.name ?? 'remote agent',\n invocation,\n );\n },\n ...(pathToken === undefined ? {} : { pathToken, operations: incarnation?.operations }),\n resolveConversation: async (grant, digest, reserve, signal) => {\n const store = requireStore();\n let record = reserve\n ? store.reserve(grant.clientId, sessionId, workspaceId, digest)\n : store.find(grant.clientId, sessionId, digest);\n if (!record)\n throw new SessionMcpConversationError(\n 'SESSION_UNAVAILABLE',\n 'This conversation binding is unavailable. It will not be recreated automatically.',\n );\n const restoring = recoveries.get(record.id);\n if (restoring) await restoring;\n else {\n const existing = record.workspaceId === undefined ? undefined : target(record.workspaceId, record.id);\n if (record.state === 'closed' || (record.state === 'bound' && !existing)) {\n if (\n options.headlessHub.session(record.id) ||\n !record.cwd ||\n options.isSessionPersisted?.(record.id, record.cwd) !== false\n )\n throw new SessionMcpConversationError(\n 'SESSION_UNAVAILABLE',\n 'The bound session is unavailable. Resume it in DoomPi; no other session will be used.',\n record.id,\n );\n if (record.setupKind === undefined && record.cwd !== undefined)\n throw new SessionMcpConversationError(\n 'SESSION_TARGET_FIXED',\n 'This existing setup has no verified provider. Recover it without changing its ownership.',\n record.id,\n );\n record = store.recover(record.id, sessionId);\n const recovery =\n record.setupKind === 'existing-directory' && record.cwd\n ? setupDirectory(record.id, sessionId, record.cwd)\n : provisionConversationWorktree(record, signal);\n recoveries.set(record.id, recovery);\n publishPending();\n try {\n await recovery;\n } finally {\n if (recoveries.get(record.id) === recovery) recoveries.delete(record.id);\n publishPending();\n }\n }\n }\n record = store.find(grant.clientId, sessionId, digest)!;\n if (record.state === 'pending') {\n publishPending();\n if (record.workspaceId !== undefined && options.isSessionPersisted?.(record.id, record.cwd!) !== false)\n throw new SessionMcpConversationError(\n 'SESSION_UNAVAILABLE',\n 'The bound session is unavailable. Resume it in DoomPi; no other session will be used.',\n record.id,\n );\n const pending = provision.get(record.id);\n if (pending) await pending;\n else if (record.setupKind === 'existing-directory' && record.cwd)\n await setupDirectory(record.id, sessionId, record.cwd);\n else await provisionConversationWorktree(record, signal);\n record = store.find(grant.clientId, sessionId, digest);\n if (!record || record.state !== 'bound')\n throw new SessionMcpConversationError(\n 'SESSION_WORKTREE_PROVISION_FAILED',\n 'The automatic worktree setup did not complete. Retry after resolving the host Git setup.',\n );\n }\n const child = record.workspaceId === undefined ? undefined : target(record.workspaceId, record.id);\n if (\n !child ||\n child.session.parentSessionId !== sessionId ||\n executionDirectory(child.session.cwd) !== record.cwd ||\n !fs.existsSync(child.session.cwd)\n )\n throw new SessionMcpConversationError(\n 'SESSION_UNAVAILABLE',\n 'The bound session is unavailable. Resume it in DoomPi; no other session will be used.',\n record.id,\n );\n return { sessionId: record.id, generation: child.generation, toolSurface: child.session.host.mcpSurface };\n },\n onVerified: (grant) => {\n if (options.registrationStore === undefined) return;\n const active = target(workspaceId, sessionId);\n if (active === undefined || grant.sessionGeneration !== active.generation || grant.clientId === '') {\n throw new Error('The session grant is no longer active.');\n }\n if (authorization.readClient(grant.clientId)?.tokenEndpointAuthMethod !== 'client_secret_post') return;\n const registration = authorization.persistentRegistration(grant.clientId, workspaceId, Date.now());\n if (registration === undefined || !options.registrationStore.save(registration)) {\n throw new Error('The verified Session MCP client could not be saved.');\n }\n },\n ...(pathToken === undefined\n ? { resourceMetadataUrl: `${configuredOrigin}/.well-known/oauth-protected-resource${basePath}` }\n : {}),\n resolveSession: (grantedSessionId) => {\n if (grantedSessionId !== sessionId) return undefined;\n const resolved = target(workspaceId, sessionId);\n return resolved === undefined\n ? undefined\n : { sessionId, generation: resolved.generation, toolSurface: resolved.session.host.mcpSurface };\n },\n });\n if (pathToken === undefined) handlers?.set(resource, handler);\n return handler(new Request(resource, request));\n }\n\n const protectedMatch = PROTECTED_RESOURCE_PATTERN.exec(url.pathname);\n if (protectedMatch !== null && request.method === 'GET') {\n if (configuredOrigin === undefined) return json(503, { error: 'Session MCP public origin is unavailable.' });\n return json(200, {\n resource: `${configuredOrigin}${protectedMatch[1]}`,\n authorization_servers: [configuredOrigin],\n bearer_methods_supported: ['header'],\n });\n }\n if (url.pathname === AUTHORIZATION_SERVER_DISCOVERY && request.method === 'GET') {\n if (configuredOrigin === undefined) return json(503, { error: 'Session MCP public origin is unavailable.' });\n return json(200, {\n issuer: configuredOrigin,\n authorization_endpoint: `${configuredOrigin}${AUTHORIZE_ROUTE}`,\n token_endpoint: `${configuredOrigin}${TOKEN_ROUTE}`,\n response_types_supported: ['code'],\n grant_types_supported: ['authorization_code', 'refresh_token'],\n code_challenge_methods_supported: ['S256'],\n token_endpoint_auth_methods_supported: ['client_secret_post'],\n });\n }\n if (url.pathname === AUTHORIZE_ROUTE && request.method === 'GET') {\n if (configuredOrigin === undefined) return json(503, { error: 'Session MCP public origin is unavailable.' });\n const clientId = url.searchParams.get('client_id') ?? '';\n const client = authorization.readClient(clientId);\n const binding = authorization.readAuthorizationBinding(clientId);\n const redirectUri = url.searchParams.get('redirect_uri') ?? '';\n if (\n client === undefined ||\n client.tokenEndpointAuthMethod !== 'client_secret_post' ||\n binding === undefined ||\n redirectUri !== client.redirectUri\n ) {\n return oauthError(new SessionMcpOAuthError('invalid_client', 'Unknown client or callback.'));\n }\n const callback = new URL(client.redirectUri);\n const state = url.searchParams.get('state');\n try {\n const boundSession = options.headlessHub.session(binding.sessionId);\n const boundIncarnation = incarnations.get(binding.sessionId);\n const expectedAudience =\n boundSession?.workspaceId === undefined\n ? undefined\n : `${configuredOrigin}${sessionPath(boundSession.workspaceId, binding.sessionId)}`;\n if (\n expectedAudience === undefined ||\n binding.audience !== expectedAudience ||\n boundIncarnation?.host !== boundSession?.host ||\n binding.sessionGeneration !== boundIncarnation?.generation\n ) {\n authorization.revokeClient(clientId);\n throw new SessionMcpOAuthError('invalid_grant', 'The preauthorized session is no longer active.');\n }\n if (url.searchParams.get('response_type') !== 'code')\n throw new SessionMcpOAuthError('invalid_request', 'Only the code response type is supported.');\n const resource = url.searchParams.get('resource');\n if (resource !== null && resource !== binding.audience) {\n // The requested URL can carry a URL token, which is redacted.\n options.onNotice?.(\n `session MCP authorize refused: client ${clientId} is bound to session ${binding.sessionId}, expecting ${binding.audience} but the connector asked for ${describeResource(resource)}`,\n );\n throw new SessionMcpOAuthError(\n 'invalid_request',\n \"The requested resource is not preauthorized. The connector's MCP URL must be the session URL this client was created for.\",\n );\n }\n const code = authorization.issueAuthorizationCode({\n clientId,\n redirectUri,\n codeChallenge: url.searchParams.get('code_challenge') ?? '',\n codeChallengeMethod: url.searchParams.get('code_challenge_method') as 'S256',\n });\n callback.searchParams.set('code', code.code);\n } catch (error) {\n callback.searchParams.set('error', error instanceof SessionMcpOAuthError ? error.code : 'invalid_request');\n callback.searchParams.set(\n 'error_description',\n error instanceof Error ? error.message : 'The OAuth request was invalid.',\n );\n }\n if (state !== null) callback.searchParams.set('state', state);\n return new Response(null, { status: 302, headers: { location: callback.href, 'cache-control': 'no-store' } });\n }\n if (url.pathname === TOKEN_ROUTE && request.method === 'POST') {\n try {\n const form = await request.formData();\n const grantType = formString(form, 'grant_type');\n const clientId = formString(form, 'client_id');\n const clientSecret = formString(form, 'client_secret');\n const result =\n grantType === 'authorization_code'\n ? authorization.exchangeToken({\n grantType,\n clientId,\n clientSecret,\n code: formString(form, 'code'),\n redirectUri: formString(form, 'redirect_uri'),\n codeVerifier: formString(form, 'code_verifier'),\n })\n : grantType === 'refresh_token'\n ? authorization.exchangeToken({\n grantType,\n clientId,\n clientSecret,\n refreshToken: formString(form, 'refresh_token'),\n })\n : (() => {\n throw new SessionMcpOAuthError('unsupported_grant_type', 'The grant type is not supported.');\n })();\n return json(200, {\n access_token: result.accessToken,\n refresh_token: result.refreshToken,\n token_type: result.tokenType,\n expires_in: result.expiresIn,\n });\n } catch (error) {\n return oauthError(error);\n }\n }\n return undefined;\n };\n\n publishPending();\n return {\n reservations,\n closeSessionBinding(sessionId) {\n options.conversationStore?.closeSession(sessionId);\n publishPending();\n },\n handlePublic: publicRoutes,\n async handleHost(request) {\n const url = new URL(request.url);\n origin();\n const configMatch = SESSION_MCP_CONFIG_PATTERN.exec(url.pathname);\n const match = SESSION_MCP_CLIENTS_PATTERN.exec(url.pathname);\n const conversationMatch = SESSION_MCP_CONVERSATIONS_PATTERN.exec(url.pathname);\n const activityMatch = SESSION_MCP_ACTIVITY_PATTERN.exec(url.pathname);\n if (configMatch === null && match === null && conversationMatch === null && activityMatch === null)\n return undefined;\n const routeMatch = configMatch ?? match ?? conversationMatch ?? activityMatch!;\n const workspaceId = decodeURIComponent(routeMatch[1]);\n const sessionId = decodeURIComponent(routeMatch[2]);\n const clientId = match?.[3] === undefined ? undefined : decodeURIComponent(match[3]);\n const resolved = target(workspaceId, sessionId);\n if (activityMatch !== null) {\n if (request.method !== 'GET') return json(405, { error: 'Method not allowed.' });\n const beforeText = url.searchParams.get('before');\n const before = beforeText === null ? undefined : Number(beforeText);\n if (\n [...url.searchParams.keys()].some((key) => key !== 'before') ||\n (before !== undefined && (!Number.isSafeInteger(before) || before <= 0))\n )\n return json(400, { error: 'Invalid history cursor.' });\n if (options.headlessHub.computerUse?.ownsSession?.(sessionId))\n return json(404, { error: 'Session not found.' });\n if (!options.activityStore) return json(503, { error: 'MCP call history is unavailable in this host.' });\n try {\n const conversation = options.conversationStore\n ?.list()\n .find((entry) => entry.id === sessionId && entry.state === 'bound' && entry.workspaceId === workspaceId);\n if (conversation === undefined)\n return json(200, {\n enabled: false,\n available: false,\n tools: [],\n calls: [],\n total: 0,\n } satisfies SessionMcpActivitySnapshot);\n const history = options.activityStore.read(workspaceId, sessionId, before);\n const parent = target(conversation.parentWorkspaceId, conversation.parentSessionId);\n const bindings = authorization.listClients().flatMap((client) => {\n const binding = authorization.readAuthorizationBinding(client.clientId);\n return binding !== undefined &&\n client.clientId === conversation.clientId &&\n binding.sessionId === conversation.parentSessionId &&\n binding.sessionGeneration === parent?.generation\n ? [{ client, binding }]\n : [];\n });\n let available = false;\n let tools: SessionMcpAvailableTool[] = [];\n if (resolved !== undefined && bindings.length > 0) {\n try {\n const surface = resolved.session.host.mcpSurface.readSurface();\n const candidates = [\n ...surface.tools.map((tool) => ({\n name: tool.name,\n label: tool.label,\n description: tool.description,\n inputSchema: tool.parameters,\n })),\n ...SESSION_MCP_EXTRA_TOOLS.map((tool) => ({\n name: tool.name,\n label: tool.title ?? tool.name,\n description: tool.description ?? '',\n inputSchema: tool.inputSchema,\n })),\n ];\n tools = candidates.flatMap((tool) => {\n const connections = bindings\n .filter(({ binding }) => binding.scope === 'session' || binding.tools.includes(tool.name))\n .map(({ client }) => client.name);\n return connections.length === 0 ? [] : [{ ...tool, connections }];\n });\n available = true;\n } catch {\n // Keep durable history visible while the child session's live capability surface is rebuilding.\n available = false;\n }\n }\n const snapshot: SessionMcpActivitySnapshot = {\n ...history,\n enabled: true,\n available,\n tools,\n };\n return json(200, snapshot);\n } catch {\n return json(503, { error: 'MCP call history could not be read. Check the host storage.' });\n }\n }\n if (resolved === undefined) return json(404, { error: 'Session not found.' });\n if (conversationMatch !== null) {\n const id = conversationMatch[3] === undefined ? undefined : decodeURIComponent(conversationMatch[3]);\n try {\n if (request.method === 'GET' && id === undefined)\n return json(200, {\n conversations: requireStore()\n .list()\n .filter((record) => record.parentSessionId === sessionId && record.state !== 'closed')\n .map(({ conversationDigest: _digest, clientId: _clientId, ...record }) => record),\n });\n if (id !== undefined && request.method === 'DELETE') {\n const record = requireStore().get(id, sessionId);\n if (record.state !== 'pending' || options.headlessHub.session(id))\n return json(409, { error: 'Remove the existing session instead.' });\n requireStore().closeSession(id);\n publishPending();\n return json(200, { ok: true });\n }\n if (id !== undefined && request.method === 'POST') {\n const body: unknown = await request.json();\n if (typeof body !== 'object' || body === null || !('cwd' in body) || typeof body.cwd !== 'string')\n return json(400, { error: 'An execution directory is required.' });\n return json(200, { session: await setupDirectory(id, sessionId, body.cwd) });\n }\n return json(405, { error: 'Method not allowed.' });\n } catch (error) {\n return json(409, {\n error:\n error instanceof SessionMcpConversationError\n ? error.message\n : 'Session setup failed. Recover the existing setup before retrying.',\n ...(error instanceof SessionMcpConversationError ? { code: error.code } : {}),\n });\n }\n }\n if (configMatch !== null) {\n if (request.method !== 'GET') return json(405, { error: 'Method not allowed.' });\n const configuredOrigin = origin();\n if (configuredOrigin === undefined) return json(503, { error: 'Session MCP public origin is unavailable.' });\n let surface;\n try {\n surface = resolved.session.host.mcpSurface.readSurface();\n } catch {\n return json(409, { error: 'The session capability surface is not ready.' });\n }\n if (surface.tools.some((tool) => SESSION_MCP_EXTRA_TOOLS.some((wrapper) => wrapper.name === tool.name)))\n return json(409, { error: 'The session capability surface contains a reserved remote tool name.' });\n return json(200, {\n audience: `${configuredOrigin}${sessionPath(workspaceId, sessionId)}`,\n authorizationEndpoint: `${configuredOrigin}${AUTHORIZE_ROUTE}`,\n tokenEndpoint: `${configuredOrigin}${TOKEN_ROUTE}`,\n tools: [\n ...surface.tools.map(({ name, label, description }) => ({ name, label, description })),\n ...SESSION_MCP_EXTRA_TOOLS.map(({ name, title, description }) => ({\n name,\n label: title ?? name,\n description,\n })),\n ],\n skills: surface.skills,\n });\n }\n if (clientId === undefined && request.method === 'GET') {\n return json(200, {\n clients: authorization.listClients().flatMap((client) => {\n const binding = authorization.readAuthorizationBinding(client.clientId);\n return binding?.sessionId === sessionId ? [publicClient(client, binding)] : [];\n }),\n });\n }\n if (clientId === undefined && request.method === 'POST') {\n const configuredOrigin = origin();\n if (configuredOrigin === undefined) return json(503, { error: 'Session MCP public origin is unavailable.' });\n let body: unknown;\n try {\n body = await request.json();\n } catch {\n return json(400, { error: 'Invalid client request.' });\n }\n if (typeof body !== 'object' || body === null) return json(400, { error: 'Invalid client request.' });\n const input = body as Record<string, unknown>;\n if (!options.conversationStore || !options.registrationStore)\n return json(503, { error: 'Mandatory conversation routing requires persistent host state.' });\n if (input.routing !== undefined && input.routing !== 'session' && input.routing !== 'conversation')\n return json(400, { error: 'Session MCP routing is not supported.' });\n const routing = sessionMcpRouting(input.routing);\n const requestedScope = input.scope;\n if (requestedScope !== undefined && requestedScope !== 'session' && requestedScope !== 'restricted') {\n return json(400, { error: 'Authorization scope is not supported.' });\n }\n const scope = requestedScope === 'session' ? 'session' : 'restricted';\n const hasTools = Object.hasOwn(input, 'tools');\n const hasSkills = Object.hasOwn(input, 'skills');\n const tools = parseStringArray(input.tools);\n const skills = parseStringArray(input.skills);\n const authMethod = input.authMethod;\n const apiKey = authMethod === 'api_key';\n const urlToken = authMethod === 'url_token';\n const nonOAuthCredential = apiKey || urlToken;\n if (authMethod !== undefined && authMethod !== 'oauth' && !nonOAuthCredential)\n return json(400, { error: 'Authentication method is not supported.' });\n if (nonOAuthCredential && (scope !== 'session' || Object.hasOwn(input, 'redirectUri')))\n return json(400, { error: 'Signed URLs and API keys require session scope and no redirectUri.' });\n if (!nonOAuthCredential && typeof input.redirectUri !== 'string')\n return json(400, { error: 'A redirectUri is required.' });\n if (scope === 'session' && (hasTools || hasSkills)) {\n return json(400, { error: 'Session scope cannot include capability grants.' });\n }\n if (scope === 'restricted' && (typeof input.name !== 'string' || !tools || !skills)) {\n return json(400, { error: 'Restricted scope requires a name, tools, and skills.' });\n }\n if (scope === 'restricted') {\n let surface;\n try {\n surface = resolved.session.host.mcpSurface.readSurface();\n } catch {\n return json(409, { error: 'The session capability surface is not ready.' });\n }\n if (surface.tools.some((tool) => SESSION_MCP_EXTRA_TOOLS.some((wrapper) => wrapper.name === tool.name)))\n return json(409, { error: 'The session capability surface contains a reserved remote tool name.' });\n const activeTools = new Set([\n ...surface.tools.map((tool) => tool.name),\n ...SESSION_MCP_EXTRA_TOOLS.map((tool) => tool.name),\n ]);\n const activeSkills = new Set(surface.skills.map((skill) => skill.name));\n if (tools!.some((name) => !activeTools.has(name)) || skills!.some((name) => !activeSkills.has(name)))\n return json(400, { error: 'Every requested grant must be active in the session.' });\n }\n try {\n const client = authorization.createClient(\n urlToken\n ? { name: defaultClientName(configuredOrigin), authMethod: 'url_token' }\n : apiKey\n ? { name: typeof input.name === 'string' ? input.name : 'API key', authMethod: 'api_key' }\n : {\n name: scope === 'session' ? defaultClientName(configuredOrigin) : (input.name as string),\n redirectUri: input.redirectUri as string,\n },\n );\n const audience = `${configuredOrigin}${sessionPath(workspaceId, sessionId)}`;\n try {\n const binding =\n scope === 'session'\n ? authorization.createAuthorizationBinding({\n clientId: client.clientId,\n sessionId,\n sessionGeneration: resolved.generation,\n audience,\n scope: 'session',\n routing,\n })\n : authorization.createAuthorizationBinding({\n clientId: client.clientId,\n sessionId,\n sessionGeneration: resolved.generation,\n audience,\n scope: 'restricted',\n routing,\n tools: [...new Set(tools!)],\n skills: [...new Set(skills!)],\n });\n const connectionUrl = urlToken ? `${audience}/${authorization.issueUrlToken(client.clientId)}` : undefined;\n if (nonOAuthCredential) {\n const registration = authorization.persistentRegistration(client.clientId, workspaceId, Date.now());\n if (registration === undefined || !options.registrationStore.save(registration)) {\n authorization.revokeClient(client.clientId);\n return json(500, { error: 'Session MCP credential could not be saved.' });\n }\n }\n return json(201, {\n client: {\n ...publicClient(client, binding),\n ...(connectionUrl === undefined ? { clientSecret: client.clientSecret } : { connectionUrl }),\n },\n });\n } catch (error) {\n authorization.revokeClient(client.clientId);\n throw error;\n }\n } catch (error) {\n return oauthError(error);\n }\n }\n if (clientId !== undefined && request.method === 'DELETE') {\n const binding = authorization.readAuthorizationBinding(clientId);\n if (binding?.sessionId !== sessionId) return json(404, { error: 'Client not found.' });\n if (options.registrationStore !== undefined && !options.registrationStore.remove(clientId)) {\n return json(500, { error: 'Client revocation could not be saved.' });\n }\n authorization.revokeClient(clientId);\n incarnations.get(sessionId)?.baselines.delete(clientId);\n options.conversationStore?.closeClient(clientId);\n publishPending();\n return json(200, { ok: true });\n }\n return json(405, { error: 'Method not allowed.' });\n },\n close() {\n unsubscribe();\n for (const [sessionId, incarnation] of incarnations) {\n revokeIncarnation(sessionId, incarnation.generation);\n abortOperations(incarnation.operations);\n }\n incarnations.clear();\n options.activityStore?.close();\n },\n };\n}\n\nexport function isPublicSessionMcpRoute(method: string, pathname: string): boolean {\n return (\n SESSION_MCP_PATTERN.test(pathname) ||\n SESSION_MCP_URL_TOKEN_PATTERN.test(pathname) ||\n (method === 'GET' && PROTECTED_RESOURCE_PATTERN.test(pathname)) ||\n (method === 'GET' && (pathname === AUTHORIZATION_SERVER_DISCOVERY || pathname === AUTHORIZE_ROUTE)) ||\n (method === 'POST' && pathname === TOKEN_ROUTE)\n );\n}\n\nexport function isSessionMcpHostRoute(pathname: string): boolean {\n return (\n SESSION_MCP_ACTIVITY_PATTERN.test(pathname) ||\n SESSION_MCP_CONFIG_PATTERN.test(pathname) ||\n SESSION_MCP_CLIENTS_PATTERN.test(pathname) ||\n SESSION_MCP_CONVERSATIONS_PATTERN.test(pathname)\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sessionMcpRoutes.cjs","names":["SessionMcpOAuthError","sessionMcpRouting","path","SessionMcpConversationError","fs","createSessionMcpAuthorizationService","createSessionMcpHttpHandler","SESSION_MCP_EXTRA_TOOLS"],"sources":["../../../src/server/sessionMcpRoutes.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport type { DoomHubSessionReservations, DoomHubSessionScope } from '../schemas/hubChannel';\nimport type { SessionMcpActivitySnapshot, SessionMcpAvailableTool } from '../schemas/sessionMcpActivity';\nimport type { SessionMcpActivityStore } from '../services/sessionMcpActivity';\nimport {\n createSessionMcpAuthorizationService,\n SessionMcpOAuthError,\n sessionMcpRouting,\n type SessionMcpAuthorizationBinding,\n type SessionMcpAuthorizationService,\n type SessionMcpClient,\n} from '../services/sessionMcpAuthorization';\nimport { SessionMcpConversationError, type SessionMcpConversationStore } from '../services/sessionMcpConversations';\nimport type { SessionMcpRegistrationStore } from '../services/sessionMcpRegistrationStore';\nimport type { HeadlessHub, HeadlessHubSession } from './headlessHub';\nimport {\n createSessionMcpHttpHandler,\n SESSION_MCP_EXTRA_TOOLS,\n type SessionMcpBaseline,\n type SessionMcpHttpHandler,\n type SessionMcpOperationRegistry,\n} from './sessionMcpHandler';\n\nconst AUTHORIZATION_SERVER_DISCOVERY = '/.well-known/oauth-authorization-server';\nconst AUTHORIZE_ROUTE = '/oauth/authorize';\nconst TOKEN_ROUTE = '/oauth/token';\nconst SESSION_MCP_PATTERN = /^\\/api\\/workspaces\\/([^/]+)\\/sessions\\/([^/]+)\\/mcp$/u;\nconst SESSION_MCP_URL_TOKEN_PATTERN =\n /^\\/api\\/workspaces\\/([^/]+)\\/sessions\\/([^/]+)\\/mcp\\/([A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+)$/u;\nconst SESSION_MCP_ACTIVITY_PATTERN = /^\\/api\\/workspaces\\/([^/]+)\\/sessions\\/([^/]+)\\/mcp\\/activity$/u;\nconst SESSION_MCP_CONFIG_PATTERN = /^\\/api\\/workspaces\\/([^/]+)\\/sessions\\/([^/]+)\\/mcp\\/config$/u;\nconst SESSION_MCP_CLIENTS_PATTERN = /^\\/api\\/workspaces\\/([^/]+)\\/sessions\\/([^/]+)\\/mcp\\/clients(?:\\/([^/]+))?$/u;\nconst SESSION_MCP_CONVERSATIONS_PATTERN =\n /^\\/api\\/workspaces\\/([^/]+)\\/sessions\\/([^/]+)\\/mcp\\/conversations(?:\\/([^/]+))?$/u;\n\n/**\n * An OAuth resource as it can be logged: the URL with any URL-token segment and every query value\n * redacted, so a mismatch in origin, path, trailing slash or query is visible without a secret.\n */\nfunction describeResource(resource: string): string {\n let parsed: URL;\n try {\n parsed = new URL(resource);\n } catch {\n return 'a resource that is not a URL';\n }\n const token = SESSION_MCP_URL_TOKEN_PATTERN.exec(parsed.pathname);\n const pathname = token === null ? parsed.pathname : parsed.pathname.slice(0, -token[3]!.length) + '<token>';\n const query = [...parsed.searchParams.keys()].map((key) => `${key}=<redacted>`).join('&');\n return `${parsed.origin}${pathname}${query === '' ? '' : `?${query}`}${parsed.hash === '' ? '' : '#<redacted>'}`;\n}\nfunction redactUrlCredentials(text: string): string {\n return text.replace(/([a-z][a-z0-9+.-]*:\\/\\/)[^\\s/?#]*@/giu, '$1***@');\n}\n\nconst PROTECTED_RESOURCE_PATTERN =\n /^\\/\\.well-known\\/oauth-protected-resource(\\/api\\/workspaces\\/[^/]+\\/sessions\\/[^/]+\\/mcp)$/u;\n\nexport interface SessionMcpRoutesOptions {\n readonly headlessHub: HeadlessHub;\n readonly publicOrigin: () => string | undefined;\n readonly publicOriginRevision?: () => number;\n readonly authorization?: SessionMcpAuthorizationService;\n readonly registrationStore?: SessionMcpRegistrationStore;\n readonly conversationStore?: SessionMcpConversationStore;\n readonly activityStore?: SessionMcpActivityStore;\n readonly isSessionPersisted?: (sessionId: string, cwd: string) => boolean;\n readonly onNotice?: (message: string) => void;\n}\n\nexport interface SessionMcpRoutes {\n handlePublic(request: Request): Promise<Response | undefined>;\n handleHost(request: Request): Promise<Response | undefined>;\n readonly reservations: DoomHubSessionReservations;\n closeSessionBinding(sessionId: string): void;\n close(): void;\n}\n\nfunction json(status: number, value: unknown): Response {\n return Response.json(value, { status, headers: { 'cache-control': 'no-store' } });\n}\n\nfunction oauthError(error: unknown): Response {\n if (error instanceof SessionMcpOAuthError)\n return json(error.code === 'invalid_client' ? 401 : 400, {\n error: error.code,\n error_description: error.message,\n });\n return json(400, { error: 'invalid_request', error_description: 'The OAuth request was invalid.' });\n}\n\nfunction trustedOrigin(value: string | undefined): string | undefined {\n if (value === undefined) return undefined;\n try {\n const url = new URL(value);\n return url.protocol === 'https:' && url.pathname === '/' && url.search === '' && url.hash === ''\n ? url.origin\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction sessionPath(workspaceId: string, sessionId: string): string {\n return `/api/workspaces/${encodeURIComponent(workspaceId)}/sessions/${encodeURIComponent(sessionId)}/mcp`;\n}\n\nfunction parseStringArray(value: unknown): readonly string[] | undefined {\n return Array.isArray(value) && value.every((entry) => typeof entry === 'string') ? value : undefined;\n}\n\nfunction defaultClientName(origin: string): string {\n return `ChatGPT · ${new URL(origin).hostname}`;\n}\n\nfunction formString(form: FormData, name: string): string {\n const value = form.get(name);\n return typeof value === 'string' ? value : '';\n}\n\nfunction publicClient(client: SessionMcpClient, binding: SessionMcpAuthorizationBinding): Record<string, unknown> {\n return {\n clientId: client.clientId,\n name: client.name,\n redirectUri: client.redirectUri,\n tokenEndpointAuthMethod: client.tokenEndpointAuthMethod,\n createdAt: client.createdAt,\n scope: binding.scope,\n routing: sessionMcpRouting(binding.routing),\n tools: binding.tools,\n skills: binding.skills,\n audience: binding.audience,\n };\n}\n\n/** Canonicalizes an intended directory without creating it or accepting symlink aliases. */\nfunction executionDirectory(value: string): string {\n if (!path.isAbsolute(value) || value.includes('\\0') || value.length > 4096)\n throw new SessionMcpConversationError('INVALID_EXECUTION_DIRECTORY', 'Choose an absolute execution directory.');\n let ancestor = path.resolve(value);\n const suffix: string[] = [];\n for (;;) {\n try {\n return path.join(fs.realpathSync(ancestor), ...suffix);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT' || path.dirname(ancestor) === ancestor)\n throw new SessionMcpConversationError(\n 'INVALID_EXECUTION_DIRECTORY',\n 'The execution directory cannot be resolved.',\n );\n suffix.unshift(path.basename(ancestor));\n ancestor = path.dirname(ancestor);\n }\n }\n}\n\nfunction overlappingDirectories(left: string, right: string): boolean {\n const contained = (root: string, target: string): boolean => {\n const relative = path.relative(root, target);\n return (\n relative === '' || (!path.isAbsolute(relative) && relative !== '..' && !relative.startsWith(`..${path.sep}`))\n );\n };\n return contained(left, right) || contained(right, left);\n}\n\n/** Routes the process-local session MCP authority and revokes every grant with its live incarnation. */\nexport function createSessionMcpRoutes(options: SessionMcpRoutesOptions): SessionMcpRoutes {\n const authorization = options.authorization ?? createSessionMcpAuthorizationService();\n // ponytail: Catalog baselines last one parent incarnation; persist snapshots only if clients must avoid a refresh after restart.\n const incarnations = new Map<\n string,\n {\n host: HeadlessHubSession['host'];\n generation: number;\n handlers: Map<string, SessionMcpHttpHandler>;\n operations: SessionMcpOperationRegistry;\n baselines: Map<string, SessionMcpBaseline>;\n }\n >();\n let nextGeneration = 1;\n let publishPending = (): void => {};\n\n const revokeIncarnation = (sessionId: string, generation: number): void => {\n authorization.revokeSessionGeneration(sessionId, generation);\n };\n const abortOperations = (operations: SessionMcpOperationRegistry): void => {\n for (const operation of operations.values()) operation.controller.abort();\n operations.clear();\n };\n const register = (session: HeadlessHubSession): boolean => {\n const current = incarnations.get(session.id);\n if (current?.host === session.host) return false;\n if (current !== undefined) {\n revokeIncarnation(session.id, current.generation);\n abortOperations(current.operations);\n }\n incarnations.set(session.id, {\n host: session.host,\n generation: nextGeneration++,\n handlers: new Map(),\n baselines: new Map(),\n operations: new Map(),\n });\n return true;\n };\n for (const session of options.headlessHub.snapshot()) register(session);\n const unsubscribe = options.headlessHub.onEvent((event) => {\n if (event.kind === 'upsert' && register(event.session)) publishPending();\n if (event.kind === 'removed') {\n const current = incarnations.get(event.sessionId);\n if (current !== undefined) {\n revokeIncarnation(event.sessionId, current.generation);\n abortOperations(current.operations);\n }\n incarnations.delete(event.sessionId);\n }\n });\n\n let observedOrigin: string | undefined;\n let observedOriginRevision: number | undefined;\n let originObserved = false;\n const origin = (): string | undefined => {\n const current = trustedOrigin(options.publicOrigin());\n const revision = options.publicOriginRevision?.();\n if (\n (originObserved && current !== observedOrigin) ||\n (revision !== undefined && observedOriginRevision !== undefined && revision !== observedOriginRevision)\n ) {\n for (const client of authorization.listClients()) {\n authorization.revokeClient(client.clientId);\n options.registrationStore?.remove(client.clientId);\n }\n for (const incarnation of incarnations.values()) {\n incarnation.handlers.clear();\n incarnation.baselines.clear();\n abortOperations(incarnation.operations);\n }\n }\n observedOrigin = current;\n observedOriginRevision = revision;\n originObserved = true;\n restorePersistedRegistrations(current);\n return current;\n };\n const target = (workspaceId: string, sessionId: string) => {\n // Remote MCP clients cannot inherit a grant, including through conversation child routing.\n if (options.headlessHub.computerUse?.ownsSession?.(sessionId)) return undefined;\n const session = options.headlessHub.session(sessionId);\n const incarnation = incarnations.get(sessionId);\n return session !== undefined && session.workspaceId === workspaceId && incarnation?.host === session.host\n ? { session, generation: incarnation.generation }\n : undefined;\n };\n const restorePersistedRegistrations = (configuredOrigin: string | undefined): void => {\n if (configuredOrigin === undefined) return;\n for (const registration of options.registrationStore?.registrations() ?? []) {\n const audience = `${configuredOrigin}${sessionPath(registration.workspaceId, registration.binding.sessionId)}`;\n if (registration.binding.audience !== audience) {\n options.registrationStore?.remove(registration.client.clientId);\n continue;\n }\n const resolved = target(registration.workspaceId, registration.binding.sessionId);\n if (resolved !== undefined) authorization.restorePersistentRegistration(registration, resolved.generation);\n }\n };\n\n const requireStore = (): SessionMcpConversationStore => {\n if (!options.conversationStore)\n throw new SessionMcpConversationError(\n 'CONVERSATION_ROUTING_UNAVAILABLE',\n 'Persistent conversation routing is unavailable.',\n );\n return options.conversationStore;\n };\n publishPending = () => {\n if (!options.conversationStore) return;\n try {\n const records = options.conversationStore.list();\n for (const parent of options.headlessHub.snapshot())\n options.headlessHub.setPendingSessionSetups?.(\n parent.id,\n records\n .filter((record) => record.parentSessionId === parent.id && record.state === 'pending')\n .map((record) => ({\n id: record.id,\n name: `conversation ${record.id.slice(0, 8)}`,\n createdAt: record.createdAt,\n status:\n provision.has(record.id) || recoveries.has(record.id)\n ? ('provisioning' as const)\n : record.failureCode === undefined\n ? ('interrupted' as const)\n : ('failed' as const),\n ...(record.setupKind === undefined ? {} : { setupKind: record.setupKind }),\n ...(record.failureCode === undefined ? {} : { errorCode: record.failureCode }),\n ...(record.cwd === undefined ? {} : { cwd: record.cwd }),\n })),\n );\n } catch (error) {\n options.onNotice?.(error instanceof Error ? error.message : 'Conversation bindings are unavailable.');\n }\n };\n const readReservation = (id: string, parentSessionId: string) => {\n origin();\n const record = requireStore().get(id, parentSessionId);\n const binding = authorization.readAuthorizationBinding(record.clientId);\n const parent = target(record.parentWorkspaceId, parentSessionId);\n if (\n !parent ||\n binding?.routing !== 'conversation' ||\n binding.sessionId !== parentSessionId ||\n binding.sessionGeneration !== parent.generation\n )\n throw new SessionMcpConversationError(\n 'SESSION_UNAVAILABLE',\n 'The connection that owns this setup is no longer active.',\n id,\n );\n return { record, parent };\n };\n const reservations: DoomHubSessionReservations = {\n read(id, parentSessionId) {\n const { record } = readReservation(id, parentSessionId);\n return { sessionId: record.id, ...(record.cwd === undefined ? {} : { cwd: record.cwd }) };\n },\n async prepare(id, parentSessionId, suppliedDirectory) {\n const { record, parent } = readReservation(id, parentSessionId);\n const cwd = executionDirectory(suppliedDirectory);\n const parentRoot =\n options.headlessHub.workspaces().find((workspace) => workspace.id === parent.session.workspaceId)?.root ??\n parent.session.cwd;\n const occupied = [\n parentRoot,\n ...options.headlessHub\n .snapshot()\n .filter((session) => session.id !== id)\n .map((session) => session.cwd),\n ...requireStore()\n .list()\n .filter((entry) => entry.id !== id && entry.state !== 'closed' && entry.cwd !== undefined)\n .map((entry) => entry.cwd!),\n ];\n if (occupied.some((directory) => overlappingDirectories(cwd, executionDirectory(directory))))\n throw new SessionMcpConversationError(\n 'EXECUTION_DIRECTORY_SHARED',\n 'Choose a separate checkout, not a directory shared with another session.',\n id,\n );\n if (record.state === 'bound' && record.cwd !== cwd)\n throw new SessionMcpConversationError(\n 'SESSION_TARGET_FIXED',\n 'An initialized session cannot change its directory.',\n id,\n );\n requireStore().prepare(id, parentSessionId, cwd);\n publishPending();\n return { sessionId: id, cwd };\n },\n async complete(id, parentSessionId): Promise<DoomHubSessionScope> {\n const { record } = readReservation(id, parentSessionId);\n const child = options.headlessHub.session(id);\n if (\n !record.cwd ||\n !child?.workspaceId ||\n child.parentSessionId !== parentSessionId ||\n (record.setupKind === 'managed-worktree' && child.workspaceId !== record.parentWorkspaceId) ||\n executionDirectory(child.cwd) !== record.cwd ||\n options.isSessionPersisted?.(id, child.cwd) === false\n )\n throw new SessionMcpConversationError(\n 'SESSION_SETUP_INCOMPLETE',\n 'The reserved session is not durably ready. Recover the existing setup instead of creating another checkout.',\n id,\n );\n requireStore().bind(id, parentSessionId, child.workspaceId);\n publishPending();\n return { sessionId: id, workspaceId: child.workspaceId, cwd: child.cwd };\n },\n };\n const provision = new Map<string, Promise<DoomHubSessionScope>>();\n const recoveries = new Map<string, Promise<DoomHubSessionScope>>();\n const setupDirectory = async (\n id: string,\n parentSessionId: string,\n directory: string,\n ): Promise<DoomHubSessionScope> => {\n // A mistyped existing-directory choice must not permanently reserve a nonexistent path.\n const canonical = executionDirectory(directory);\n if (!fs.statSync(canonical).isDirectory()) throw new Error('The execution directory is not a directory.');\n const { record: current } = readReservation(id, parentSessionId);\n if (provision.has(id) && current.setupKind === 'managed-worktree')\n throw new SessionMcpConversationError('SESSION_TARGET_FIXED', 'This setup belongs to a managed worktree.', id);\n const selected = requireStore().selectSetup(id, parentSessionId, 'existing-directory');\n if (selected.setupKind !== 'existing-directory')\n throw new SessionMcpConversationError('SESSION_TARGET_FIXED', 'This setup belongs to a managed worktree.', id);\n const prepared = await reservations.prepare(id, parentSessionId, canonical);\n const pending = provision.get(id);\n if (pending) return pending;\n const setup = (async () => {\n if (!options.headlessHub.session(id)) {\n const record = requireStore().get(id, parentSessionId);\n if (record.state === 'bound' || options.isSessionPersisted?.(id, prepared.cwd))\n throw new SessionMcpConversationError(\n 'SESSION_UNAVAILABLE',\n 'Resume the existing session in DoomPi. It will not be recreated automatically.',\n id,\n );\n if (!fs.statSync(prepared.cwd).isDirectory()) throw new Error('The execution directory is not a directory.');\n await options.headlessHub.sessionService.create({\n cwd: prepared.cwd,\n name: `conversation ${id.slice(0, 8)}`,\n parentSessionId,\n sessionProvenance: 'remote-conversation',\n reservationId: id,\n });\n }\n return reservations.complete(id, parentSessionId);\n })();\n provision.set(id, setup);\n publishPending();\n try {\n return await setup;\n } catch (error) {\n requireStore().fail(id, parentSessionId, 'SESSION_UNAVAILABLE');\n throw error;\n } finally {\n if (provision.get(id) === setup) provision.delete(id);\n publishPending();\n }\n };\n const provisionConversationWorktree = async (\n record: ReturnType<SessionMcpConversationStore['reserve']>,\n signal?: AbortSignal,\n ): Promise<DoomHubSessionScope> => {\n const pending = provision.get(record.id);\n if (pending) return pending;\n readReservation(record.id, record.parentSessionId);\n requireStore().selectSetup(record.id, record.parentSessionId, 'managed-worktree');\n const setup = (async () => {\n try {\n const child = await options.headlessHub.sessionService.provisionReservedWorktree?.({\n reservationId: record.id,\n parentSessionId: record.parentSessionId,\n signal,\n });\n if (child === undefined || child.sessionId !== record.id)\n throw new Error('Automatic worktree provisioning did not create the reserved session.');\n return child;\n } catch (error) {\n if (error instanceof SessionMcpConversationError) throw error;\n options.onNotice?.(\n `session MCP worktree provisioning failed for reservation ${record.id}: ${error instanceof Error ? redactUrlCredentials(error.message) : 'Automatic worktree provisioning failed.'}`,\n );\n throw new SessionMcpConversationError(\n 'SESSION_WORKTREE_PROVISION_FAILED',\n 'An automatic worktree could not be created for this conversation. Resolve the host Git setup, then retry.',\n record.id,\n );\n }\n })();\n provision.set(record.id, setup);\n publishPending();\n try {\n return await setup;\n } catch (error) {\n requireStore().fail(record.id, record.parentSessionId, 'SESSION_WORKTREE_PROVISION_FAILED');\n throw error;\n } finally {\n if (provision.get(record.id) === setup) provision.delete(record.id);\n publishPending();\n }\n };\n const publicRoutes = async (request: Request): Promise<Response | undefined> => {\n const url = new URL(request.url);\n const configuredOrigin = origin();\n const signedMcpMatch = SESSION_MCP_URL_TOKEN_PATTERN.exec(url.pathname);\n const mcpMatch = SESSION_MCP_PATTERN.exec(url.pathname) ?? signedMcpMatch;\n if (mcpMatch !== null) {\n if (configuredOrigin === undefined) return json(503, { error: 'Session MCP public origin is unavailable.' });\n const workspaceId = decodeURIComponent(mcpMatch[1]);\n const sessionId = decodeURIComponent(mcpMatch[2]);\n const pathToken = signedMcpMatch?.[3];\n const basePath = sessionPath(workspaceId, sessionId);\n const exactPath = pathToken === undefined ? basePath : `${basePath}/${pathToken}`;\n if (url.pathname !== exactPath || url.search !== '') return json(404, { error: 'Not found.' });\n const audience = `${configuredOrigin}${basePath}`;\n const resource = pathToken === undefined ? audience : `${audience}/${pathToken}`;\n const incarnation = target(workspaceId, sessionId) === undefined ? undefined : incarnations.get(sessionId);\n const handlers = incarnation?.handlers;\n const cachedHandler = pathToken === undefined ? handlers?.get(resource) : undefined;\n const handler =\n cachedHandler ??\n createSessionMcpHttpHandler({\n audience,\n baselines: incarnation?.baselines ?? new Map(),\n authorization,\n onNotice: options.onNotice,\n onInvocation: (invocation) => {\n if (invocation.sessionId === undefined || invocation.conversationDigest === undefined) return;\n const conversation = options.conversationStore?.find(\n invocation.clientId,\n invocation.parentSessionId,\n invocation.conversationDigest,\n );\n if (\n conversation?.state !== 'bound' ||\n conversation.id !== invocation.sessionId ||\n conversation.workspaceId === undefined\n )\n return;\n options.activityStore?.record(\n conversation.workspaceId,\n conversation.id,\n authorization.readClient(invocation.clientId)?.name ?? 'remote agent',\n invocation,\n );\n },\n ...(pathToken === undefined ? {} : { pathToken, operations: incarnation?.operations }),\n resolveConversation: async (grant, digest, reserve, signal) => {\n const store = requireStore();\n let record = reserve\n ? store.reserve(grant.clientId, sessionId, workspaceId, digest)\n : store.find(grant.clientId, sessionId, digest);\n if (!record)\n throw new SessionMcpConversationError(\n 'SESSION_UNAVAILABLE',\n 'This conversation binding is unavailable. It will not be recreated automatically.',\n );\n const restoring = recoveries.get(record.id);\n if (restoring) await restoring;\n else {\n const existing = record.workspaceId === undefined ? undefined : target(record.workspaceId, record.id);\n if (record.state === 'closed' || (record.state === 'bound' && !existing)) {\n if (\n options.headlessHub.session(record.id) ||\n !record.cwd ||\n options.isSessionPersisted?.(record.id, record.cwd) !== false\n )\n throw new SessionMcpConversationError(\n 'SESSION_UNAVAILABLE',\n 'The bound session is unavailable. Resume it in DoomPi; no other session will be used.',\n record.id,\n );\n if (record.setupKind === undefined && record.cwd !== undefined)\n throw new SessionMcpConversationError(\n 'SESSION_TARGET_FIXED',\n 'This existing setup has no verified provider. Recover it without changing its ownership.',\n record.id,\n );\n record = store.recover(record.id, sessionId);\n const recovery =\n record.setupKind === 'existing-directory' && record.cwd\n ? setupDirectory(record.id, sessionId, record.cwd)\n : provisionConversationWorktree(record, signal);\n recoveries.set(record.id, recovery);\n publishPending();\n try {\n await recovery;\n } finally {\n if (recoveries.get(record.id) === recovery) recoveries.delete(record.id);\n publishPending();\n }\n }\n }\n record = store.find(grant.clientId, sessionId, digest)!;\n if (record.state === 'pending') {\n publishPending();\n if (record.workspaceId !== undefined && options.isSessionPersisted?.(record.id, record.cwd!) !== false)\n throw new SessionMcpConversationError(\n 'SESSION_UNAVAILABLE',\n 'The bound session is unavailable. Resume it in DoomPi; no other session will be used.',\n record.id,\n );\n const pending = provision.get(record.id);\n if (pending) await pending;\n else if (record.setupKind === 'existing-directory' && record.cwd)\n await setupDirectory(record.id, sessionId, record.cwd);\n else await provisionConversationWorktree(record, signal);\n record = store.find(grant.clientId, sessionId, digest);\n if (!record || record.state !== 'bound')\n throw new SessionMcpConversationError(\n 'SESSION_WORKTREE_PROVISION_FAILED',\n 'The automatic worktree setup did not complete. Retry after resolving the host Git setup.',\n );\n }\n const child = record.workspaceId === undefined ? undefined : target(record.workspaceId, record.id);\n if (\n !child ||\n child.session.parentSessionId !== sessionId ||\n executionDirectory(child.session.cwd) !== record.cwd ||\n !fs.existsSync(child.session.cwd)\n )\n throw new SessionMcpConversationError(\n 'SESSION_UNAVAILABLE',\n 'The bound session is unavailable. Resume it in DoomPi; no other session will be used.',\n record.id,\n );\n return { sessionId: record.id, generation: child.generation, toolSurface: child.session.host.mcpSurface };\n },\n onVerified: (grant) => {\n if (options.registrationStore === undefined) return;\n const active = target(workspaceId, sessionId);\n if (active === undefined || grant.sessionGeneration !== active.generation || grant.clientId === '') {\n throw new Error('The session grant is no longer active.');\n }\n if (authorization.readClient(grant.clientId)?.tokenEndpointAuthMethod !== 'client_secret_post') return;\n const registration = authorization.persistentRegistration(grant.clientId, workspaceId, Date.now());\n if (registration === undefined || !options.registrationStore.save(registration)) {\n throw new Error('The verified Session MCP client could not be saved.');\n }\n },\n ...(pathToken === undefined\n ? { resourceMetadataUrl: `${configuredOrigin}/.well-known/oauth-protected-resource${basePath}` }\n : {}),\n resolveSession: (grantedSessionId) => {\n if (grantedSessionId !== sessionId) return undefined;\n const resolved = target(workspaceId, sessionId);\n return resolved === undefined\n ? undefined\n : { sessionId, generation: resolved.generation, toolSurface: resolved.session.host.mcpSurface };\n },\n });\n if (pathToken === undefined) handlers?.set(resource, handler);\n return handler(new Request(resource, request));\n }\n\n const protectedMatch = PROTECTED_RESOURCE_PATTERN.exec(url.pathname);\n if (protectedMatch !== null && request.method === 'GET') {\n if (configuredOrigin === undefined) return json(503, { error: 'Session MCP public origin is unavailable.' });\n return json(200, {\n resource: `${configuredOrigin}${protectedMatch[1]}`,\n authorization_servers: [configuredOrigin],\n bearer_methods_supported: ['header'],\n });\n }\n if (url.pathname === AUTHORIZATION_SERVER_DISCOVERY && request.method === 'GET') {\n if (configuredOrigin === undefined) return json(503, { error: 'Session MCP public origin is unavailable.' });\n return json(200, {\n issuer: configuredOrigin,\n authorization_endpoint: `${configuredOrigin}${AUTHORIZE_ROUTE}`,\n token_endpoint: `${configuredOrigin}${TOKEN_ROUTE}`,\n response_types_supported: ['code'],\n grant_types_supported: ['authorization_code', 'refresh_token'],\n code_challenge_methods_supported: ['S256'],\n token_endpoint_auth_methods_supported: ['client_secret_post'],\n });\n }\n if (url.pathname === AUTHORIZE_ROUTE && request.method === 'GET') {\n if (configuredOrigin === undefined) return json(503, { error: 'Session MCP public origin is unavailable.' });\n const clientId = url.searchParams.get('client_id') ?? '';\n const client = authorization.readClient(clientId);\n const binding = authorization.readAuthorizationBinding(clientId);\n const redirectUri = url.searchParams.get('redirect_uri') ?? '';\n if (\n client === undefined ||\n client.tokenEndpointAuthMethod !== 'client_secret_post' ||\n binding === undefined ||\n redirectUri !== client.redirectUri\n ) {\n return oauthError(new SessionMcpOAuthError('invalid_client', 'Unknown client or callback.'));\n }\n const callback = new URL(client.redirectUri);\n const state = url.searchParams.get('state');\n try {\n const boundSession = options.headlessHub.session(binding.sessionId);\n const boundIncarnation = incarnations.get(binding.sessionId);\n const expectedAudience =\n boundSession?.workspaceId === undefined\n ? undefined\n : `${configuredOrigin}${sessionPath(boundSession.workspaceId, binding.sessionId)}`;\n if (\n expectedAudience === undefined ||\n binding.audience !== expectedAudience ||\n boundIncarnation?.host !== boundSession?.host ||\n binding.sessionGeneration !== boundIncarnation?.generation\n ) {\n authorization.revokeClient(clientId);\n throw new SessionMcpOAuthError('invalid_grant', 'The preauthorized session is no longer active.');\n }\n if (url.searchParams.get('response_type') !== 'code')\n throw new SessionMcpOAuthError('invalid_request', 'Only the code response type is supported.');\n const resource = url.searchParams.get('resource');\n if (resource !== null && resource !== binding.audience) {\n // The requested URL can carry a URL token, which is redacted.\n options.onNotice?.(\n `session MCP authorize refused: client ${clientId} is bound to session ${binding.sessionId}, expecting ${binding.audience} but the connector asked for ${describeResource(resource)}`,\n );\n throw new SessionMcpOAuthError(\n 'invalid_request',\n \"The requested resource is not preauthorized. The connector's MCP URL must be the session URL this client was created for.\",\n );\n }\n const code = authorization.issueAuthorizationCode({\n clientId,\n redirectUri,\n codeChallenge: url.searchParams.get('code_challenge') ?? '',\n codeChallengeMethod: url.searchParams.get('code_challenge_method') as 'S256',\n });\n callback.searchParams.set('code', code.code);\n } catch (error) {\n callback.searchParams.set('error', error instanceof SessionMcpOAuthError ? error.code : 'invalid_request');\n callback.searchParams.set(\n 'error_description',\n error instanceof Error ? error.message : 'The OAuth request was invalid.',\n );\n }\n if (state !== null) callback.searchParams.set('state', state);\n return new Response(null, { status: 302, headers: { location: callback.href, 'cache-control': 'no-store' } });\n }\n if (url.pathname === TOKEN_ROUTE && request.method === 'POST') {\n try {\n const form = await request.formData();\n const grantType = formString(form, 'grant_type');\n const clientId = formString(form, 'client_id');\n const clientSecret = formString(form, 'client_secret');\n const result =\n grantType === 'authorization_code'\n ? authorization.exchangeToken({\n grantType,\n clientId,\n clientSecret,\n code: formString(form, 'code'),\n redirectUri: formString(form, 'redirect_uri'),\n codeVerifier: formString(form, 'code_verifier'),\n })\n : grantType === 'refresh_token'\n ? authorization.exchangeToken({\n grantType,\n clientId,\n clientSecret,\n refreshToken: formString(form, 'refresh_token'),\n })\n : (() => {\n throw new SessionMcpOAuthError('unsupported_grant_type', 'The grant type is not supported.');\n })();\n return json(200, {\n access_token: result.accessToken,\n refresh_token: result.refreshToken,\n token_type: result.tokenType,\n expires_in: result.expiresIn,\n });\n } catch (error) {\n return oauthError(error);\n }\n }\n return undefined;\n };\n\n publishPending();\n return {\n reservations,\n closeSessionBinding(sessionId) {\n options.conversationStore?.closeSession(sessionId);\n publishPending();\n },\n handlePublic: publicRoutes,\n async handleHost(request) {\n const url = new URL(request.url);\n origin();\n const configMatch = SESSION_MCP_CONFIG_PATTERN.exec(url.pathname);\n const match = SESSION_MCP_CLIENTS_PATTERN.exec(url.pathname);\n const conversationMatch = SESSION_MCP_CONVERSATIONS_PATTERN.exec(url.pathname);\n const activityMatch = SESSION_MCP_ACTIVITY_PATTERN.exec(url.pathname);\n if (configMatch === null && match === null && conversationMatch === null && activityMatch === null)\n return undefined;\n const routeMatch = configMatch ?? match ?? conversationMatch ?? activityMatch!;\n const workspaceId = decodeURIComponent(routeMatch[1]);\n const sessionId = decodeURIComponent(routeMatch[2]);\n const clientId = match?.[3] === undefined ? undefined : decodeURIComponent(match[3]);\n const resolved = target(workspaceId, sessionId);\n if (activityMatch !== null) {\n if (request.method !== 'GET') return json(405, { error: 'Method not allowed.' });\n const beforeText = url.searchParams.get('before');\n const before = beforeText === null ? undefined : Number(beforeText);\n if (\n [...url.searchParams.keys()].some((key) => key !== 'before') ||\n (before !== undefined && (!Number.isSafeInteger(before) || before <= 0))\n )\n return json(400, { error: 'Invalid history cursor.' });\n if (options.headlessHub.computerUse?.ownsSession?.(sessionId))\n return json(404, { error: 'Session not found.' });\n if (!options.activityStore) return json(503, { error: 'MCP call history is unavailable in this host.' });\n try {\n const conversation = options.conversationStore\n ?.list()\n .find((entry) => entry.id === sessionId && entry.state === 'bound' && entry.workspaceId === workspaceId);\n if (conversation === undefined)\n return json(200, {\n enabled: false,\n available: false,\n tools: [],\n calls: [],\n total: 0,\n } satisfies SessionMcpActivitySnapshot);\n const history = options.activityStore.read(workspaceId, sessionId, before);\n const parent = target(conversation.parentWorkspaceId, conversation.parentSessionId);\n const bindings = authorization.listClients().flatMap((client) => {\n const binding = authorization.readAuthorizationBinding(client.clientId);\n return binding !== undefined &&\n client.clientId === conversation.clientId &&\n binding.sessionId === conversation.parentSessionId &&\n binding.sessionGeneration === parent?.generation\n ? [{ client, binding }]\n : [];\n });\n let available = false;\n let tools: SessionMcpAvailableTool[] = [];\n if (resolved !== undefined && bindings.length > 0) {\n try {\n const surface = resolved.session.host.mcpSurface.readSurface();\n const candidates = [\n ...surface.tools.map((tool) => ({\n name: tool.name,\n label: tool.label,\n description: tool.description,\n inputSchema: tool.parameters,\n })),\n ...SESSION_MCP_EXTRA_TOOLS.map((tool) => ({\n name: tool.name,\n label: tool.title ?? tool.name,\n description: tool.description ?? '',\n inputSchema: tool.inputSchema,\n })),\n ];\n tools = candidates.flatMap((tool) => {\n const connections = bindings\n .filter(({ binding }) => binding.scope === 'session' || binding.tools.includes(tool.name))\n .map(({ client }) => client.name);\n return connections.length === 0 ? [] : [{ ...tool, connections }];\n });\n available = true;\n } catch {\n // Keep durable history visible while the child session's live capability surface is rebuilding.\n available = false;\n }\n }\n const snapshot: SessionMcpActivitySnapshot = {\n ...history,\n enabled: true,\n available,\n tools,\n };\n return json(200, snapshot);\n } catch {\n return json(503, { error: 'MCP call history could not be read. Check the host storage.' });\n }\n }\n if (resolved === undefined) return json(404, { error: 'Session not found.' });\n if (conversationMatch !== null) {\n const id = conversationMatch[3] === undefined ? undefined : decodeURIComponent(conversationMatch[3]);\n try {\n if (request.method === 'GET' && id === undefined)\n return json(200, {\n conversations: requireStore()\n .list()\n .filter((record) => record.parentSessionId === sessionId && record.state !== 'closed')\n .map(({ conversationDigest: _digest, clientId: _clientId, ...record }) => record),\n });\n if (id !== undefined && request.method === 'DELETE') {\n const record = requireStore().get(id, sessionId);\n if (record.state !== 'pending' || options.headlessHub.session(id))\n return json(409, { error: 'Remove the existing session instead.' });\n requireStore().closeSession(id);\n publishPending();\n return json(200, { ok: true });\n }\n if (id !== undefined && request.method === 'POST') {\n const body: unknown = await request.json();\n if (typeof body !== 'object' || body === null || !('cwd' in body) || typeof body.cwd !== 'string')\n return json(400, { error: 'An execution directory is required.' });\n return json(200, { session: await setupDirectory(id, sessionId, body.cwd) });\n }\n return json(405, { error: 'Method not allowed.' });\n } catch (error) {\n return json(409, {\n error:\n error instanceof SessionMcpConversationError\n ? error.message\n : 'Session setup failed. Recover the existing setup before retrying.',\n ...(error instanceof SessionMcpConversationError ? { code: error.code } : {}),\n });\n }\n }\n if (configMatch !== null) {\n if (request.method !== 'GET') return json(405, { error: 'Method not allowed.' });\n const configuredOrigin = origin();\n if (configuredOrigin === undefined) return json(503, { error: 'Session MCP public origin is unavailable.' });\n let surface;\n try {\n surface = resolved.session.host.mcpSurface.readSurface();\n } catch {\n return json(409, { error: 'The session capability surface is not ready.' });\n }\n if (surface.tools.some((tool) => SESSION_MCP_EXTRA_TOOLS.some((wrapper) => wrapper.name === tool.name)))\n return json(409, { error: 'The session capability surface contains a reserved remote tool name.' });\n return json(200, {\n audience: `${configuredOrigin}${sessionPath(workspaceId, sessionId)}`,\n authorizationEndpoint: `${configuredOrigin}${AUTHORIZE_ROUTE}`,\n tokenEndpoint: `${configuredOrigin}${TOKEN_ROUTE}`,\n tools: [\n ...surface.tools.map(({ name, label, description }) => ({ name, label, description })),\n ...SESSION_MCP_EXTRA_TOOLS.map(({ name, title, description }) => ({\n name,\n label: title ?? name,\n description,\n })),\n ],\n skills: surface.skills,\n });\n }\n if (clientId === undefined && request.method === 'GET') {\n return json(200, {\n clients: authorization.listClients().flatMap((client) => {\n const binding = authorization.readAuthorizationBinding(client.clientId);\n return binding?.sessionId === sessionId ? [publicClient(client, binding)] : [];\n }),\n });\n }\n if (clientId === undefined && request.method === 'POST') {\n const configuredOrigin = origin();\n if (configuredOrigin === undefined) return json(503, { error: 'Session MCP public origin is unavailable.' });\n let body: unknown;\n try {\n body = await request.json();\n } catch {\n return json(400, { error: 'Invalid client request.' });\n }\n if (typeof body !== 'object' || body === null) return json(400, { error: 'Invalid client request.' });\n const input = body as Record<string, unknown>;\n if (!options.conversationStore || !options.registrationStore)\n return json(503, { error: 'Mandatory conversation routing requires persistent host state.' });\n if (input.routing !== undefined && input.routing !== 'session' && input.routing !== 'conversation')\n return json(400, { error: 'Session MCP routing is not supported.' });\n const routing = sessionMcpRouting(input.routing);\n const requestedScope = input.scope;\n if (requestedScope !== undefined && requestedScope !== 'session' && requestedScope !== 'restricted') {\n return json(400, { error: 'Authorization scope is not supported.' });\n }\n const scope = requestedScope === 'session' ? 'session' : 'restricted';\n const hasTools = Object.hasOwn(input, 'tools');\n const hasSkills = Object.hasOwn(input, 'skills');\n const tools = parseStringArray(input.tools);\n const skills = parseStringArray(input.skills);\n const authMethod = input.authMethod;\n const apiKey = authMethod === 'api_key';\n const urlToken = authMethod === 'url_token';\n const nonOAuthCredential = apiKey || urlToken;\n if (authMethod !== undefined && authMethod !== 'oauth' && !nonOAuthCredential)\n return json(400, { error: 'Authentication method is not supported.' });\n if (nonOAuthCredential && (scope !== 'session' || Object.hasOwn(input, 'redirectUri')))\n return json(400, { error: 'Signed URLs and API keys require session scope and no redirectUri.' });\n if (!nonOAuthCredential && typeof input.redirectUri !== 'string')\n return json(400, { error: 'A redirectUri is required.' });\n if (scope === 'session' && (hasTools || hasSkills)) {\n return json(400, { error: 'Session scope cannot include capability grants.' });\n }\n if (scope === 'restricted' && (typeof input.name !== 'string' || !tools || !skills)) {\n return json(400, { error: 'Restricted scope requires a name, tools, and skills.' });\n }\n if (scope === 'restricted') {\n let surface;\n try {\n surface = resolved.session.host.mcpSurface.readSurface();\n } catch {\n return json(409, { error: 'The session capability surface is not ready.' });\n }\n if (surface.tools.some((tool) => SESSION_MCP_EXTRA_TOOLS.some((wrapper) => wrapper.name === tool.name)))\n return json(409, { error: 'The session capability surface contains a reserved remote tool name.' });\n const activeTools = new Set([\n ...surface.tools.map((tool) => tool.name),\n ...SESSION_MCP_EXTRA_TOOLS.map((tool) => tool.name),\n ]);\n const activeSkills = new Set(surface.skills.map((skill) => skill.name));\n if (tools!.some((name) => !activeTools.has(name)) || skills!.some((name) => !activeSkills.has(name)))\n return json(400, { error: 'Every requested grant must be active in the session.' });\n }\n try {\n const client = authorization.createClient(\n urlToken\n ? { name: defaultClientName(configuredOrigin), authMethod: 'url_token' }\n : apiKey\n ? { name: typeof input.name === 'string' ? input.name : 'API key', authMethod: 'api_key' }\n : {\n name: scope === 'session' ? defaultClientName(configuredOrigin) : (input.name as string),\n redirectUri: input.redirectUri as string,\n },\n );\n const audience = `${configuredOrigin}${sessionPath(workspaceId, sessionId)}`;\n try {\n const binding =\n scope === 'session'\n ? authorization.createAuthorizationBinding({\n clientId: client.clientId,\n sessionId,\n sessionGeneration: resolved.generation,\n audience,\n scope: 'session',\n routing,\n })\n : authorization.createAuthorizationBinding({\n clientId: client.clientId,\n sessionId,\n sessionGeneration: resolved.generation,\n audience,\n scope: 'restricted',\n routing,\n tools: [...new Set(tools!)],\n skills: [...new Set(skills!)],\n });\n const connectionUrl = urlToken ? `${audience}/${authorization.issueUrlToken(client.clientId)}` : undefined;\n if (nonOAuthCredential) {\n const registration = authorization.persistentRegistration(client.clientId, workspaceId, Date.now());\n if (registration === undefined || !options.registrationStore.save(registration)) {\n authorization.revokeClient(client.clientId);\n return json(500, { error: 'Session MCP credential could not be saved.' });\n }\n }\n return json(201, {\n client: {\n ...publicClient(client, binding),\n ...(connectionUrl === undefined ? { clientSecret: client.clientSecret } : { connectionUrl }),\n },\n });\n } catch (error) {\n authorization.revokeClient(client.clientId);\n throw error;\n }\n } catch (error) {\n return oauthError(error);\n }\n }\n if (clientId !== undefined && request.method === 'DELETE') {\n const binding = authorization.readAuthorizationBinding(clientId);\n if (binding?.sessionId !== sessionId) return json(404, { error: 'Client not found.' });\n if (options.registrationStore !== undefined && !options.registrationStore.remove(clientId)) {\n return json(500, { error: 'Client revocation could not be saved.' });\n }\n authorization.revokeClient(clientId);\n incarnations.get(sessionId)?.baselines.delete(clientId);\n options.conversationStore?.closeClient(clientId);\n publishPending();\n return json(200, { ok: true });\n }\n return json(405, { error: 'Method not allowed.' });\n },\n close() {\n unsubscribe();\n for (const [sessionId, incarnation] of incarnations) {\n revokeIncarnation(sessionId, incarnation.generation);\n abortOperations(incarnation.operations);\n }\n incarnations.clear();\n options.activityStore?.close();\n },\n };\n}\n\nexport function isPublicSessionMcpRoute(method: string, pathname: string): boolean {\n return (\n SESSION_MCP_PATTERN.test(pathname) ||\n SESSION_MCP_URL_TOKEN_PATTERN.test(pathname) ||\n (method === 'GET' && PROTECTED_RESOURCE_PATTERN.test(pathname)) ||\n (method === 'GET' && (pathname === AUTHORIZATION_SERVER_DISCOVERY || pathname === AUTHORIZE_ROUTE)) ||\n (method === 'POST' && pathname === TOKEN_ROUTE)\n );\n}\n\nexport function isSessionMcpHostRoute(pathname: string): boolean {\n return (\n SESSION_MCP_ACTIVITY_PATTERN.test(pathname) ||\n SESSION_MCP_CONFIG_PATTERN.test(pathname) ||\n SESSION_MCP_CLIENTS_PATTERN.test(pathname) ||\n SESSION_MCP_CONVERSATIONS_PATTERN.test(pathname)\n );\n}\n"],"mappings":"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"}
@@ -29,6 +29,9 @@ function describeResource(resource) {
29
29
  const query = [...parsed.searchParams.keys()].map((key) => `${key}=<redacted>`).join("&");
30
30
  return `${parsed.origin}${pathname}${query === "" ? "" : `?${query}`}${parsed.hash === "" ? "" : "#<redacted>"}`;
31
31
  }
32
+ function redactUrlCredentials(text) {
33
+ return text.replace(/([a-z][a-z0-9+.-]*:\/\/)[^\s/?#]*@/giu, "$1***@");
34
+ }
32
35
  const PROTECTED_RESOURCE_PATTERN = /^\/\.well-known\/oauth-protected-resource(\/api\/workspaces\/[^/]+\/sessions\/[^/]+\/mcp)$/u;
33
36
  function json(status, value) {
34
37
  return Response.json(value, {
@@ -309,6 +312,7 @@ function createSessionMcpRoutes(options) {
309
312
  return child;
310
313
  } catch (error) {
311
314
  if (error instanceof SessionMcpConversationError) throw error;
315
+ options.onNotice?.(`session MCP worktree provisioning failed for reservation ${record.id}: ${error instanceof Error ? redactUrlCredentials(error.message) : "Automatic worktree provisioning failed."}`);
312
316
  throw new SessionMcpConversationError("SESSION_WORKTREE_PROVISION_FAILED", "An automatic worktree could not be created for this conversation. Resolve the host Git setup, then retry.", record.id);
313
317
  }
314
318
  })();
@@ -1 +1 @@
1
- {"version":3,"file":"sessionMcpRoutes.mjs","names":[],"sources":["../../../src/server/sessionMcpRoutes.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport type { DoomHubSessionReservations, DoomHubSessionScope } from '../schemas/hubChannel';\nimport type { SessionMcpActivitySnapshot, SessionMcpAvailableTool } from '../schemas/sessionMcpActivity';\nimport type { SessionMcpActivityStore } from '../services/sessionMcpActivity';\nimport {\n createSessionMcpAuthorizationService,\n SessionMcpOAuthError,\n sessionMcpRouting,\n type SessionMcpAuthorizationBinding,\n type SessionMcpAuthorizationService,\n type SessionMcpClient,\n} from '../services/sessionMcpAuthorization';\nimport { SessionMcpConversationError, type SessionMcpConversationStore } from '../services/sessionMcpConversations';\nimport type { SessionMcpRegistrationStore } from '../services/sessionMcpRegistrationStore';\nimport type { HeadlessHub, HeadlessHubSession } from './headlessHub';\nimport {\n createSessionMcpHttpHandler,\n SESSION_MCP_EXTRA_TOOLS,\n type SessionMcpBaseline,\n type SessionMcpHttpHandler,\n type SessionMcpOperationRegistry,\n} from './sessionMcpHandler';\n\nconst AUTHORIZATION_SERVER_DISCOVERY = '/.well-known/oauth-authorization-server';\nconst AUTHORIZE_ROUTE = '/oauth/authorize';\nconst TOKEN_ROUTE = '/oauth/token';\nconst SESSION_MCP_PATTERN = /^\\/api\\/workspaces\\/([^/]+)\\/sessions\\/([^/]+)\\/mcp$/u;\nconst SESSION_MCP_URL_TOKEN_PATTERN =\n /^\\/api\\/workspaces\\/([^/]+)\\/sessions\\/([^/]+)\\/mcp\\/([A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+)$/u;\nconst SESSION_MCP_ACTIVITY_PATTERN = /^\\/api\\/workspaces\\/([^/]+)\\/sessions\\/([^/]+)\\/mcp\\/activity$/u;\nconst SESSION_MCP_CONFIG_PATTERN = /^\\/api\\/workspaces\\/([^/]+)\\/sessions\\/([^/]+)\\/mcp\\/config$/u;\nconst SESSION_MCP_CLIENTS_PATTERN = /^\\/api\\/workspaces\\/([^/]+)\\/sessions\\/([^/]+)\\/mcp\\/clients(?:\\/([^/]+))?$/u;\nconst SESSION_MCP_CONVERSATIONS_PATTERN =\n /^\\/api\\/workspaces\\/([^/]+)\\/sessions\\/([^/]+)\\/mcp\\/conversations(?:\\/([^/]+))?$/u;\n\n/**\n * An OAuth resource as it can be logged: the URL with any URL-token segment and every query value\n * redacted, so a mismatch in origin, path, trailing slash or query is visible without a secret.\n */\nfunction describeResource(resource: string): string {\n let parsed: URL;\n try {\n parsed = new URL(resource);\n } catch {\n return 'a resource that is not a URL';\n }\n const token = SESSION_MCP_URL_TOKEN_PATTERN.exec(parsed.pathname);\n const pathname = token === null ? parsed.pathname : parsed.pathname.slice(0, -token[3]!.length) + '<token>';\n const query = [...parsed.searchParams.keys()].map((key) => `${key}=<redacted>`).join('&');\n return `${parsed.origin}${pathname}${query === '' ? '' : `?${query}`}${parsed.hash === '' ? '' : '#<redacted>'}`;\n}\nconst PROTECTED_RESOURCE_PATTERN =\n /^\\/\\.well-known\\/oauth-protected-resource(\\/api\\/workspaces\\/[^/]+\\/sessions\\/[^/]+\\/mcp)$/u;\n\nexport interface SessionMcpRoutesOptions {\n readonly headlessHub: HeadlessHub;\n readonly publicOrigin: () => string | undefined;\n readonly publicOriginRevision?: () => number;\n readonly authorization?: SessionMcpAuthorizationService;\n readonly registrationStore?: SessionMcpRegistrationStore;\n readonly conversationStore?: SessionMcpConversationStore;\n readonly activityStore?: SessionMcpActivityStore;\n readonly isSessionPersisted?: (sessionId: string, cwd: string) => boolean;\n readonly onNotice?: (message: string) => void;\n}\n\nexport interface SessionMcpRoutes {\n handlePublic(request: Request): Promise<Response | undefined>;\n handleHost(request: Request): Promise<Response | undefined>;\n readonly reservations: DoomHubSessionReservations;\n closeSessionBinding(sessionId: string): void;\n close(): void;\n}\n\nfunction json(status: number, value: unknown): Response {\n return Response.json(value, { status, headers: { 'cache-control': 'no-store' } });\n}\n\nfunction oauthError(error: unknown): Response {\n if (error instanceof SessionMcpOAuthError)\n return json(error.code === 'invalid_client' ? 401 : 400, {\n error: error.code,\n error_description: error.message,\n });\n return json(400, { error: 'invalid_request', error_description: 'The OAuth request was invalid.' });\n}\n\nfunction trustedOrigin(value: string | undefined): string | undefined {\n if (value === undefined) return undefined;\n try {\n const url = new URL(value);\n return url.protocol === 'https:' && url.pathname === '/' && url.search === '' && url.hash === ''\n ? url.origin\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction sessionPath(workspaceId: string, sessionId: string): string {\n return `/api/workspaces/${encodeURIComponent(workspaceId)}/sessions/${encodeURIComponent(sessionId)}/mcp`;\n}\n\nfunction parseStringArray(value: unknown): readonly string[] | undefined {\n return Array.isArray(value) && value.every((entry) => typeof entry === 'string') ? value : undefined;\n}\n\nfunction defaultClientName(origin: string): string {\n return `ChatGPT · ${new URL(origin).hostname}`;\n}\n\nfunction formString(form: FormData, name: string): string {\n const value = form.get(name);\n return typeof value === 'string' ? value : '';\n}\n\nfunction publicClient(client: SessionMcpClient, binding: SessionMcpAuthorizationBinding): Record<string, unknown> {\n return {\n clientId: client.clientId,\n name: client.name,\n redirectUri: client.redirectUri,\n tokenEndpointAuthMethod: client.tokenEndpointAuthMethod,\n createdAt: client.createdAt,\n scope: binding.scope,\n routing: sessionMcpRouting(binding.routing),\n tools: binding.tools,\n skills: binding.skills,\n audience: binding.audience,\n };\n}\n\n/** Canonicalizes an intended directory without creating it or accepting symlink aliases. */\nfunction executionDirectory(value: string): string {\n if (!path.isAbsolute(value) || value.includes('\\0') || value.length > 4096)\n throw new SessionMcpConversationError('INVALID_EXECUTION_DIRECTORY', 'Choose an absolute execution directory.');\n let ancestor = path.resolve(value);\n const suffix: string[] = [];\n for (;;) {\n try {\n return path.join(fs.realpathSync(ancestor), ...suffix);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT' || path.dirname(ancestor) === ancestor)\n throw new SessionMcpConversationError(\n 'INVALID_EXECUTION_DIRECTORY',\n 'The execution directory cannot be resolved.',\n );\n suffix.unshift(path.basename(ancestor));\n ancestor = path.dirname(ancestor);\n }\n }\n}\n\nfunction overlappingDirectories(left: string, right: string): boolean {\n const contained = (root: string, target: string): boolean => {\n const relative = path.relative(root, target);\n return (\n relative === '' || (!path.isAbsolute(relative) && relative !== '..' && !relative.startsWith(`..${path.sep}`))\n );\n };\n return contained(left, right) || contained(right, left);\n}\n\n/** Routes the process-local session MCP authority and revokes every grant with its live incarnation. */\nexport function createSessionMcpRoutes(options: SessionMcpRoutesOptions): SessionMcpRoutes {\n const authorization = options.authorization ?? createSessionMcpAuthorizationService();\n // ponytail: Catalog baselines last one parent incarnation; persist snapshots only if clients must avoid a refresh after restart.\n const incarnations = new Map<\n string,\n {\n host: HeadlessHubSession['host'];\n generation: number;\n handlers: Map<string, SessionMcpHttpHandler>;\n operations: SessionMcpOperationRegistry;\n baselines: Map<string, SessionMcpBaseline>;\n }\n >();\n let nextGeneration = 1;\n let publishPending = (): void => {};\n\n const revokeIncarnation = (sessionId: string, generation: number): void => {\n authorization.revokeSessionGeneration(sessionId, generation);\n };\n const abortOperations = (operations: SessionMcpOperationRegistry): void => {\n for (const operation of operations.values()) operation.controller.abort();\n operations.clear();\n };\n const register = (session: HeadlessHubSession): boolean => {\n const current = incarnations.get(session.id);\n if (current?.host === session.host) return false;\n if (current !== undefined) {\n revokeIncarnation(session.id, current.generation);\n abortOperations(current.operations);\n }\n incarnations.set(session.id, {\n host: session.host,\n generation: nextGeneration++,\n handlers: new Map(),\n baselines: new Map(),\n operations: new Map(),\n });\n return true;\n };\n for (const session of options.headlessHub.snapshot()) register(session);\n const unsubscribe = options.headlessHub.onEvent((event) => {\n if (event.kind === 'upsert' && register(event.session)) publishPending();\n if (event.kind === 'removed') {\n const current = incarnations.get(event.sessionId);\n if (current !== undefined) {\n revokeIncarnation(event.sessionId, current.generation);\n abortOperations(current.operations);\n }\n incarnations.delete(event.sessionId);\n }\n });\n\n let observedOrigin: string | undefined;\n let observedOriginRevision: number | undefined;\n let originObserved = false;\n const origin = (): string | undefined => {\n const current = trustedOrigin(options.publicOrigin());\n const revision = options.publicOriginRevision?.();\n if (\n (originObserved && current !== observedOrigin) ||\n (revision !== undefined && observedOriginRevision !== undefined && revision !== observedOriginRevision)\n ) {\n for (const client of authorization.listClients()) {\n authorization.revokeClient(client.clientId);\n options.registrationStore?.remove(client.clientId);\n }\n for (const incarnation of incarnations.values()) {\n incarnation.handlers.clear();\n incarnation.baselines.clear();\n abortOperations(incarnation.operations);\n }\n }\n observedOrigin = current;\n observedOriginRevision = revision;\n originObserved = true;\n restorePersistedRegistrations(current);\n return current;\n };\n const target = (workspaceId: string, sessionId: string) => {\n // Remote MCP clients cannot inherit a grant, including through conversation child routing.\n if (options.headlessHub.computerUse?.ownsSession?.(sessionId)) return undefined;\n const session = options.headlessHub.session(sessionId);\n const incarnation = incarnations.get(sessionId);\n return session !== undefined && session.workspaceId === workspaceId && incarnation?.host === session.host\n ? { session, generation: incarnation.generation }\n : undefined;\n };\n const restorePersistedRegistrations = (configuredOrigin: string | undefined): void => {\n if (configuredOrigin === undefined) return;\n for (const registration of options.registrationStore?.registrations() ?? []) {\n const audience = `${configuredOrigin}${sessionPath(registration.workspaceId, registration.binding.sessionId)}`;\n if (registration.binding.audience !== audience) {\n options.registrationStore?.remove(registration.client.clientId);\n continue;\n }\n const resolved = target(registration.workspaceId, registration.binding.sessionId);\n if (resolved !== undefined) authorization.restorePersistentRegistration(registration, resolved.generation);\n }\n };\n\n const requireStore = (): SessionMcpConversationStore => {\n if (!options.conversationStore)\n throw new SessionMcpConversationError(\n 'CONVERSATION_ROUTING_UNAVAILABLE',\n 'Persistent conversation routing is unavailable.',\n );\n return options.conversationStore;\n };\n publishPending = () => {\n if (!options.conversationStore) return;\n try {\n const records = options.conversationStore.list();\n for (const parent of options.headlessHub.snapshot())\n options.headlessHub.setPendingSessionSetups?.(\n parent.id,\n records\n .filter((record) => record.parentSessionId === parent.id && record.state === 'pending')\n .map((record) => ({\n id: record.id,\n name: `conversation ${record.id.slice(0, 8)}`,\n createdAt: record.createdAt,\n status:\n provision.has(record.id) || recoveries.has(record.id)\n ? ('provisioning' as const)\n : record.failureCode === undefined\n ? ('interrupted' as const)\n : ('failed' as const),\n ...(record.setupKind === undefined ? {} : { setupKind: record.setupKind }),\n ...(record.failureCode === undefined ? {} : { errorCode: record.failureCode }),\n ...(record.cwd === undefined ? {} : { cwd: record.cwd }),\n })),\n );\n } catch (error) {\n options.onNotice?.(error instanceof Error ? error.message : 'Conversation bindings are unavailable.');\n }\n };\n const readReservation = (id: string, parentSessionId: string) => {\n origin();\n const record = requireStore().get(id, parentSessionId);\n const binding = authorization.readAuthorizationBinding(record.clientId);\n const parent = target(record.parentWorkspaceId, parentSessionId);\n if (\n !parent ||\n binding?.routing !== 'conversation' ||\n binding.sessionId !== parentSessionId ||\n binding.sessionGeneration !== parent.generation\n )\n throw new SessionMcpConversationError(\n 'SESSION_UNAVAILABLE',\n 'The connection that owns this setup is no longer active.',\n id,\n );\n return { record, parent };\n };\n const reservations: DoomHubSessionReservations = {\n read(id, parentSessionId) {\n const { record } = readReservation(id, parentSessionId);\n return { sessionId: record.id, ...(record.cwd === undefined ? {} : { cwd: record.cwd }) };\n },\n async prepare(id, parentSessionId, suppliedDirectory) {\n const { record, parent } = readReservation(id, parentSessionId);\n const cwd = executionDirectory(suppliedDirectory);\n const parentRoot =\n options.headlessHub.workspaces().find((workspace) => workspace.id === parent.session.workspaceId)?.root ??\n parent.session.cwd;\n const occupied = [\n parentRoot,\n ...options.headlessHub\n .snapshot()\n .filter((session) => session.id !== id)\n .map((session) => session.cwd),\n ...requireStore()\n .list()\n .filter((entry) => entry.id !== id && entry.state !== 'closed' && entry.cwd !== undefined)\n .map((entry) => entry.cwd!),\n ];\n if (occupied.some((directory) => overlappingDirectories(cwd, executionDirectory(directory))))\n throw new SessionMcpConversationError(\n 'EXECUTION_DIRECTORY_SHARED',\n 'Choose a separate checkout, not a directory shared with another session.',\n id,\n );\n if (record.state === 'bound' && record.cwd !== cwd)\n throw new SessionMcpConversationError(\n 'SESSION_TARGET_FIXED',\n 'An initialized session cannot change its directory.',\n id,\n );\n requireStore().prepare(id, parentSessionId, cwd);\n publishPending();\n return { sessionId: id, cwd };\n },\n async complete(id, parentSessionId): Promise<DoomHubSessionScope> {\n const { record } = readReservation(id, parentSessionId);\n const child = options.headlessHub.session(id);\n if (\n !record.cwd ||\n !child?.workspaceId ||\n child.parentSessionId !== parentSessionId ||\n (record.setupKind === 'managed-worktree' && child.workspaceId !== record.parentWorkspaceId) ||\n executionDirectory(child.cwd) !== record.cwd ||\n options.isSessionPersisted?.(id, child.cwd) === false\n )\n throw new SessionMcpConversationError(\n 'SESSION_SETUP_INCOMPLETE',\n 'The reserved session is not durably ready. Recover the existing setup instead of creating another checkout.',\n id,\n );\n requireStore().bind(id, parentSessionId, child.workspaceId);\n publishPending();\n return { sessionId: id, workspaceId: child.workspaceId, cwd: child.cwd };\n },\n };\n const provision = new Map<string, Promise<DoomHubSessionScope>>();\n const recoveries = new Map<string, Promise<DoomHubSessionScope>>();\n const setupDirectory = async (\n id: string,\n parentSessionId: string,\n directory: string,\n ): Promise<DoomHubSessionScope> => {\n // A mistyped existing-directory choice must not permanently reserve a nonexistent path.\n const canonical = executionDirectory(directory);\n if (!fs.statSync(canonical).isDirectory()) throw new Error('The execution directory is not a directory.');\n const { record: current } = readReservation(id, parentSessionId);\n if (provision.has(id) && current.setupKind === 'managed-worktree')\n throw new SessionMcpConversationError('SESSION_TARGET_FIXED', 'This setup belongs to a managed worktree.', id);\n const selected = requireStore().selectSetup(id, parentSessionId, 'existing-directory');\n if (selected.setupKind !== 'existing-directory')\n throw new SessionMcpConversationError('SESSION_TARGET_FIXED', 'This setup belongs to a managed worktree.', id);\n const prepared = await reservations.prepare(id, parentSessionId, canonical);\n const pending = provision.get(id);\n if (pending) return pending;\n const setup = (async () => {\n if (!options.headlessHub.session(id)) {\n const record = requireStore().get(id, parentSessionId);\n if (record.state === 'bound' || options.isSessionPersisted?.(id, prepared.cwd))\n throw new SessionMcpConversationError(\n 'SESSION_UNAVAILABLE',\n 'Resume the existing session in DoomPi. It will not be recreated automatically.',\n id,\n );\n if (!fs.statSync(prepared.cwd).isDirectory()) throw new Error('The execution directory is not a directory.');\n await options.headlessHub.sessionService.create({\n cwd: prepared.cwd,\n name: `conversation ${id.slice(0, 8)}`,\n parentSessionId,\n sessionProvenance: 'remote-conversation',\n reservationId: id,\n });\n }\n return reservations.complete(id, parentSessionId);\n })();\n provision.set(id, setup);\n publishPending();\n try {\n return await setup;\n } catch (error) {\n requireStore().fail(id, parentSessionId, 'SESSION_UNAVAILABLE');\n throw error;\n } finally {\n if (provision.get(id) === setup) provision.delete(id);\n publishPending();\n }\n };\n const provisionConversationWorktree = async (\n record: ReturnType<SessionMcpConversationStore['reserve']>,\n signal?: AbortSignal,\n ): Promise<DoomHubSessionScope> => {\n const pending = provision.get(record.id);\n if (pending) return pending;\n readReservation(record.id, record.parentSessionId);\n requireStore().selectSetup(record.id, record.parentSessionId, 'managed-worktree');\n const setup = (async () => {\n try {\n const child = await options.headlessHub.sessionService.provisionReservedWorktree?.({\n reservationId: record.id,\n parentSessionId: record.parentSessionId,\n signal,\n });\n if (child === undefined || child.sessionId !== record.id)\n throw new Error('Automatic worktree provisioning did not create the reserved session.');\n return child;\n } catch (error) {\n if (error instanceof SessionMcpConversationError) throw error;\n throw new SessionMcpConversationError(\n 'SESSION_WORKTREE_PROVISION_FAILED',\n 'An automatic worktree could not be created for this conversation. Resolve the host Git setup, then retry.',\n record.id,\n );\n }\n })();\n provision.set(record.id, setup);\n publishPending();\n try {\n return await setup;\n } catch (error) {\n requireStore().fail(record.id, record.parentSessionId, 'SESSION_WORKTREE_PROVISION_FAILED');\n throw error;\n } finally {\n if (provision.get(record.id) === setup) provision.delete(record.id);\n publishPending();\n }\n };\n const publicRoutes = async (request: Request): Promise<Response | undefined> => {\n const url = new URL(request.url);\n const configuredOrigin = origin();\n const signedMcpMatch = SESSION_MCP_URL_TOKEN_PATTERN.exec(url.pathname);\n const mcpMatch = SESSION_MCP_PATTERN.exec(url.pathname) ?? signedMcpMatch;\n if (mcpMatch !== null) {\n if (configuredOrigin === undefined) return json(503, { error: 'Session MCP public origin is unavailable.' });\n const workspaceId = decodeURIComponent(mcpMatch[1]);\n const sessionId = decodeURIComponent(mcpMatch[2]);\n const pathToken = signedMcpMatch?.[3];\n const basePath = sessionPath(workspaceId, sessionId);\n const exactPath = pathToken === undefined ? basePath : `${basePath}/${pathToken}`;\n if (url.pathname !== exactPath || url.search !== '') return json(404, { error: 'Not found.' });\n const audience = `${configuredOrigin}${basePath}`;\n const resource = pathToken === undefined ? audience : `${audience}/${pathToken}`;\n const incarnation = target(workspaceId, sessionId) === undefined ? undefined : incarnations.get(sessionId);\n const handlers = incarnation?.handlers;\n const cachedHandler = pathToken === undefined ? handlers?.get(resource) : undefined;\n const handler =\n cachedHandler ??\n createSessionMcpHttpHandler({\n audience,\n baselines: incarnation?.baselines ?? new Map(),\n authorization,\n onNotice: options.onNotice,\n onInvocation: (invocation) => {\n if (invocation.sessionId === undefined || invocation.conversationDigest === undefined) return;\n const conversation = options.conversationStore?.find(\n invocation.clientId,\n invocation.parentSessionId,\n invocation.conversationDigest,\n );\n if (\n conversation?.state !== 'bound' ||\n conversation.id !== invocation.sessionId ||\n conversation.workspaceId === undefined\n )\n return;\n options.activityStore?.record(\n conversation.workspaceId,\n conversation.id,\n authorization.readClient(invocation.clientId)?.name ?? 'remote agent',\n invocation,\n );\n },\n ...(pathToken === undefined ? {} : { pathToken, operations: incarnation?.operations }),\n resolveConversation: async (grant, digest, reserve, signal) => {\n const store = requireStore();\n let record = reserve\n ? store.reserve(grant.clientId, sessionId, workspaceId, digest)\n : store.find(grant.clientId, sessionId, digest);\n if (!record)\n throw new SessionMcpConversationError(\n 'SESSION_UNAVAILABLE',\n 'This conversation binding is unavailable. It will not be recreated automatically.',\n );\n const restoring = recoveries.get(record.id);\n if (restoring) await restoring;\n else {\n const existing = record.workspaceId === undefined ? undefined : target(record.workspaceId, record.id);\n if (record.state === 'closed' || (record.state === 'bound' && !existing)) {\n if (\n options.headlessHub.session(record.id) ||\n !record.cwd ||\n options.isSessionPersisted?.(record.id, record.cwd) !== false\n )\n throw new SessionMcpConversationError(\n 'SESSION_UNAVAILABLE',\n 'The bound session is unavailable. Resume it in DoomPi; no other session will be used.',\n record.id,\n );\n if (record.setupKind === undefined && record.cwd !== undefined)\n throw new SessionMcpConversationError(\n 'SESSION_TARGET_FIXED',\n 'This existing setup has no verified provider. Recover it without changing its ownership.',\n record.id,\n );\n record = store.recover(record.id, sessionId);\n const recovery =\n record.setupKind === 'existing-directory' && record.cwd\n ? setupDirectory(record.id, sessionId, record.cwd)\n : provisionConversationWorktree(record, signal);\n recoveries.set(record.id, recovery);\n publishPending();\n try {\n await recovery;\n } finally {\n if (recoveries.get(record.id) === recovery) recoveries.delete(record.id);\n publishPending();\n }\n }\n }\n record = store.find(grant.clientId, sessionId, digest)!;\n if (record.state === 'pending') {\n publishPending();\n if (record.workspaceId !== undefined && options.isSessionPersisted?.(record.id, record.cwd!) !== false)\n throw new SessionMcpConversationError(\n 'SESSION_UNAVAILABLE',\n 'The bound session is unavailable. Resume it in DoomPi; no other session will be used.',\n record.id,\n );\n const pending = provision.get(record.id);\n if (pending) await pending;\n else if (record.setupKind === 'existing-directory' && record.cwd)\n await setupDirectory(record.id, sessionId, record.cwd);\n else await provisionConversationWorktree(record, signal);\n record = store.find(grant.clientId, sessionId, digest);\n if (!record || record.state !== 'bound')\n throw new SessionMcpConversationError(\n 'SESSION_WORKTREE_PROVISION_FAILED',\n 'The automatic worktree setup did not complete. Retry after resolving the host Git setup.',\n );\n }\n const child = record.workspaceId === undefined ? undefined : target(record.workspaceId, record.id);\n if (\n !child ||\n child.session.parentSessionId !== sessionId ||\n executionDirectory(child.session.cwd) !== record.cwd ||\n !fs.existsSync(child.session.cwd)\n )\n throw new SessionMcpConversationError(\n 'SESSION_UNAVAILABLE',\n 'The bound session is unavailable. Resume it in DoomPi; no other session will be used.',\n record.id,\n );\n return { sessionId: record.id, generation: child.generation, toolSurface: child.session.host.mcpSurface };\n },\n onVerified: (grant) => {\n if (options.registrationStore === undefined) return;\n const active = target(workspaceId, sessionId);\n if (active === undefined || grant.sessionGeneration !== active.generation || grant.clientId === '') {\n throw new Error('The session grant is no longer active.');\n }\n if (authorization.readClient(grant.clientId)?.tokenEndpointAuthMethod !== 'client_secret_post') return;\n const registration = authorization.persistentRegistration(grant.clientId, workspaceId, Date.now());\n if (registration === undefined || !options.registrationStore.save(registration)) {\n throw new Error('The verified Session MCP client could not be saved.');\n }\n },\n ...(pathToken === undefined\n ? { resourceMetadataUrl: `${configuredOrigin}/.well-known/oauth-protected-resource${basePath}` }\n : {}),\n resolveSession: (grantedSessionId) => {\n if (grantedSessionId !== sessionId) return undefined;\n const resolved = target(workspaceId, sessionId);\n return resolved === undefined\n ? undefined\n : { sessionId, generation: resolved.generation, toolSurface: resolved.session.host.mcpSurface };\n },\n });\n if (pathToken === undefined) handlers?.set(resource, handler);\n return handler(new Request(resource, request));\n }\n\n const protectedMatch = PROTECTED_RESOURCE_PATTERN.exec(url.pathname);\n if (protectedMatch !== null && request.method === 'GET') {\n if (configuredOrigin === undefined) return json(503, { error: 'Session MCP public origin is unavailable.' });\n return json(200, {\n resource: `${configuredOrigin}${protectedMatch[1]}`,\n authorization_servers: [configuredOrigin],\n bearer_methods_supported: ['header'],\n });\n }\n if (url.pathname === AUTHORIZATION_SERVER_DISCOVERY && request.method === 'GET') {\n if (configuredOrigin === undefined) return json(503, { error: 'Session MCP public origin is unavailable.' });\n return json(200, {\n issuer: configuredOrigin,\n authorization_endpoint: `${configuredOrigin}${AUTHORIZE_ROUTE}`,\n token_endpoint: `${configuredOrigin}${TOKEN_ROUTE}`,\n response_types_supported: ['code'],\n grant_types_supported: ['authorization_code', 'refresh_token'],\n code_challenge_methods_supported: ['S256'],\n token_endpoint_auth_methods_supported: ['client_secret_post'],\n });\n }\n if (url.pathname === AUTHORIZE_ROUTE && request.method === 'GET') {\n if (configuredOrigin === undefined) return json(503, { error: 'Session MCP public origin is unavailable.' });\n const clientId = url.searchParams.get('client_id') ?? '';\n const client = authorization.readClient(clientId);\n const binding = authorization.readAuthorizationBinding(clientId);\n const redirectUri = url.searchParams.get('redirect_uri') ?? '';\n if (\n client === undefined ||\n client.tokenEndpointAuthMethod !== 'client_secret_post' ||\n binding === undefined ||\n redirectUri !== client.redirectUri\n ) {\n return oauthError(new SessionMcpOAuthError('invalid_client', 'Unknown client or callback.'));\n }\n const callback = new URL(client.redirectUri);\n const state = url.searchParams.get('state');\n try {\n const boundSession = options.headlessHub.session(binding.sessionId);\n const boundIncarnation = incarnations.get(binding.sessionId);\n const expectedAudience =\n boundSession?.workspaceId === undefined\n ? undefined\n : `${configuredOrigin}${sessionPath(boundSession.workspaceId, binding.sessionId)}`;\n if (\n expectedAudience === undefined ||\n binding.audience !== expectedAudience ||\n boundIncarnation?.host !== boundSession?.host ||\n binding.sessionGeneration !== boundIncarnation?.generation\n ) {\n authorization.revokeClient(clientId);\n throw new SessionMcpOAuthError('invalid_grant', 'The preauthorized session is no longer active.');\n }\n if (url.searchParams.get('response_type') !== 'code')\n throw new SessionMcpOAuthError('invalid_request', 'Only the code response type is supported.');\n const resource = url.searchParams.get('resource');\n if (resource !== null && resource !== binding.audience) {\n // The requested URL can carry a URL token, which is redacted.\n options.onNotice?.(\n `session MCP authorize refused: client ${clientId} is bound to session ${binding.sessionId}, expecting ${binding.audience} but the connector asked for ${describeResource(resource)}`,\n );\n throw new SessionMcpOAuthError(\n 'invalid_request',\n \"The requested resource is not preauthorized. The connector's MCP URL must be the session URL this client was created for.\",\n );\n }\n const code = authorization.issueAuthorizationCode({\n clientId,\n redirectUri,\n codeChallenge: url.searchParams.get('code_challenge') ?? '',\n codeChallengeMethod: url.searchParams.get('code_challenge_method') as 'S256',\n });\n callback.searchParams.set('code', code.code);\n } catch (error) {\n callback.searchParams.set('error', error instanceof SessionMcpOAuthError ? error.code : 'invalid_request');\n callback.searchParams.set(\n 'error_description',\n error instanceof Error ? error.message : 'The OAuth request was invalid.',\n );\n }\n if (state !== null) callback.searchParams.set('state', state);\n return new Response(null, { status: 302, headers: { location: callback.href, 'cache-control': 'no-store' } });\n }\n if (url.pathname === TOKEN_ROUTE && request.method === 'POST') {\n try {\n const form = await request.formData();\n const grantType = formString(form, 'grant_type');\n const clientId = formString(form, 'client_id');\n const clientSecret = formString(form, 'client_secret');\n const result =\n grantType === 'authorization_code'\n ? authorization.exchangeToken({\n grantType,\n clientId,\n clientSecret,\n code: formString(form, 'code'),\n redirectUri: formString(form, 'redirect_uri'),\n codeVerifier: formString(form, 'code_verifier'),\n })\n : grantType === 'refresh_token'\n ? authorization.exchangeToken({\n grantType,\n clientId,\n clientSecret,\n refreshToken: formString(form, 'refresh_token'),\n })\n : (() => {\n throw new SessionMcpOAuthError('unsupported_grant_type', 'The grant type is not supported.');\n })();\n return json(200, {\n access_token: result.accessToken,\n refresh_token: result.refreshToken,\n token_type: result.tokenType,\n expires_in: result.expiresIn,\n });\n } catch (error) {\n return oauthError(error);\n }\n }\n return undefined;\n };\n\n publishPending();\n return {\n reservations,\n closeSessionBinding(sessionId) {\n options.conversationStore?.closeSession(sessionId);\n publishPending();\n },\n handlePublic: publicRoutes,\n async handleHost(request) {\n const url = new URL(request.url);\n origin();\n const configMatch = SESSION_MCP_CONFIG_PATTERN.exec(url.pathname);\n const match = SESSION_MCP_CLIENTS_PATTERN.exec(url.pathname);\n const conversationMatch = SESSION_MCP_CONVERSATIONS_PATTERN.exec(url.pathname);\n const activityMatch = SESSION_MCP_ACTIVITY_PATTERN.exec(url.pathname);\n if (configMatch === null && match === null && conversationMatch === null && activityMatch === null)\n return undefined;\n const routeMatch = configMatch ?? match ?? conversationMatch ?? activityMatch!;\n const workspaceId = decodeURIComponent(routeMatch[1]);\n const sessionId = decodeURIComponent(routeMatch[2]);\n const clientId = match?.[3] === undefined ? undefined : decodeURIComponent(match[3]);\n const resolved = target(workspaceId, sessionId);\n if (activityMatch !== null) {\n if (request.method !== 'GET') return json(405, { error: 'Method not allowed.' });\n const beforeText = url.searchParams.get('before');\n const before = beforeText === null ? undefined : Number(beforeText);\n if (\n [...url.searchParams.keys()].some((key) => key !== 'before') ||\n (before !== undefined && (!Number.isSafeInteger(before) || before <= 0))\n )\n return json(400, { error: 'Invalid history cursor.' });\n if (options.headlessHub.computerUse?.ownsSession?.(sessionId))\n return json(404, { error: 'Session not found.' });\n if (!options.activityStore) return json(503, { error: 'MCP call history is unavailable in this host.' });\n try {\n const conversation = options.conversationStore\n ?.list()\n .find((entry) => entry.id === sessionId && entry.state === 'bound' && entry.workspaceId === workspaceId);\n if (conversation === undefined)\n return json(200, {\n enabled: false,\n available: false,\n tools: [],\n calls: [],\n total: 0,\n } satisfies SessionMcpActivitySnapshot);\n const history = options.activityStore.read(workspaceId, sessionId, before);\n const parent = target(conversation.parentWorkspaceId, conversation.parentSessionId);\n const bindings = authorization.listClients().flatMap((client) => {\n const binding = authorization.readAuthorizationBinding(client.clientId);\n return binding !== undefined &&\n client.clientId === conversation.clientId &&\n binding.sessionId === conversation.parentSessionId &&\n binding.sessionGeneration === parent?.generation\n ? [{ client, binding }]\n : [];\n });\n let available = false;\n let tools: SessionMcpAvailableTool[] = [];\n if (resolved !== undefined && bindings.length > 0) {\n try {\n const surface = resolved.session.host.mcpSurface.readSurface();\n const candidates = [\n ...surface.tools.map((tool) => ({\n name: tool.name,\n label: tool.label,\n description: tool.description,\n inputSchema: tool.parameters,\n })),\n ...SESSION_MCP_EXTRA_TOOLS.map((tool) => ({\n name: tool.name,\n label: tool.title ?? tool.name,\n description: tool.description ?? '',\n inputSchema: tool.inputSchema,\n })),\n ];\n tools = candidates.flatMap((tool) => {\n const connections = bindings\n .filter(({ binding }) => binding.scope === 'session' || binding.tools.includes(tool.name))\n .map(({ client }) => client.name);\n return connections.length === 0 ? [] : [{ ...tool, connections }];\n });\n available = true;\n } catch {\n // Keep durable history visible while the child session's live capability surface is rebuilding.\n available = false;\n }\n }\n const snapshot: SessionMcpActivitySnapshot = {\n ...history,\n enabled: true,\n available,\n tools,\n };\n return json(200, snapshot);\n } catch {\n return json(503, { error: 'MCP call history could not be read. Check the host storage.' });\n }\n }\n if (resolved === undefined) return json(404, { error: 'Session not found.' });\n if (conversationMatch !== null) {\n const id = conversationMatch[3] === undefined ? undefined : decodeURIComponent(conversationMatch[3]);\n try {\n if (request.method === 'GET' && id === undefined)\n return json(200, {\n conversations: requireStore()\n .list()\n .filter((record) => record.parentSessionId === sessionId && record.state !== 'closed')\n .map(({ conversationDigest: _digest, clientId: _clientId, ...record }) => record),\n });\n if (id !== undefined && request.method === 'DELETE') {\n const record = requireStore().get(id, sessionId);\n if (record.state !== 'pending' || options.headlessHub.session(id))\n return json(409, { error: 'Remove the existing session instead.' });\n requireStore().closeSession(id);\n publishPending();\n return json(200, { ok: true });\n }\n if (id !== undefined && request.method === 'POST') {\n const body: unknown = await request.json();\n if (typeof body !== 'object' || body === null || !('cwd' in body) || typeof body.cwd !== 'string')\n return json(400, { error: 'An execution directory is required.' });\n return json(200, { session: await setupDirectory(id, sessionId, body.cwd) });\n }\n return json(405, { error: 'Method not allowed.' });\n } catch (error) {\n return json(409, {\n error:\n error instanceof SessionMcpConversationError\n ? error.message\n : 'Session setup failed. Recover the existing setup before retrying.',\n ...(error instanceof SessionMcpConversationError ? { code: error.code } : {}),\n });\n }\n }\n if (configMatch !== null) {\n if (request.method !== 'GET') return json(405, { error: 'Method not allowed.' });\n const configuredOrigin = origin();\n if (configuredOrigin === undefined) return json(503, { error: 'Session MCP public origin is unavailable.' });\n let surface;\n try {\n surface = resolved.session.host.mcpSurface.readSurface();\n } catch {\n return json(409, { error: 'The session capability surface is not ready.' });\n }\n if (surface.tools.some((tool) => SESSION_MCP_EXTRA_TOOLS.some((wrapper) => wrapper.name === tool.name)))\n return json(409, { error: 'The session capability surface contains a reserved remote tool name.' });\n return json(200, {\n audience: `${configuredOrigin}${sessionPath(workspaceId, sessionId)}`,\n authorizationEndpoint: `${configuredOrigin}${AUTHORIZE_ROUTE}`,\n tokenEndpoint: `${configuredOrigin}${TOKEN_ROUTE}`,\n tools: [\n ...surface.tools.map(({ name, label, description }) => ({ name, label, description })),\n ...SESSION_MCP_EXTRA_TOOLS.map(({ name, title, description }) => ({\n name,\n label: title ?? name,\n description,\n })),\n ],\n skills: surface.skills,\n });\n }\n if (clientId === undefined && request.method === 'GET') {\n return json(200, {\n clients: authorization.listClients().flatMap((client) => {\n const binding = authorization.readAuthorizationBinding(client.clientId);\n return binding?.sessionId === sessionId ? [publicClient(client, binding)] : [];\n }),\n });\n }\n if (clientId === undefined && request.method === 'POST') {\n const configuredOrigin = origin();\n if (configuredOrigin === undefined) return json(503, { error: 'Session MCP public origin is unavailable.' });\n let body: unknown;\n try {\n body = await request.json();\n } catch {\n return json(400, { error: 'Invalid client request.' });\n }\n if (typeof body !== 'object' || body === null) return json(400, { error: 'Invalid client request.' });\n const input = body as Record<string, unknown>;\n if (!options.conversationStore || !options.registrationStore)\n return json(503, { error: 'Mandatory conversation routing requires persistent host state.' });\n if (input.routing !== undefined && input.routing !== 'session' && input.routing !== 'conversation')\n return json(400, { error: 'Session MCP routing is not supported.' });\n const routing = sessionMcpRouting(input.routing);\n const requestedScope = input.scope;\n if (requestedScope !== undefined && requestedScope !== 'session' && requestedScope !== 'restricted') {\n return json(400, { error: 'Authorization scope is not supported.' });\n }\n const scope = requestedScope === 'session' ? 'session' : 'restricted';\n const hasTools = Object.hasOwn(input, 'tools');\n const hasSkills = Object.hasOwn(input, 'skills');\n const tools = parseStringArray(input.tools);\n const skills = parseStringArray(input.skills);\n const authMethod = input.authMethod;\n const apiKey = authMethod === 'api_key';\n const urlToken = authMethod === 'url_token';\n const nonOAuthCredential = apiKey || urlToken;\n if (authMethod !== undefined && authMethod !== 'oauth' && !nonOAuthCredential)\n return json(400, { error: 'Authentication method is not supported.' });\n if (nonOAuthCredential && (scope !== 'session' || Object.hasOwn(input, 'redirectUri')))\n return json(400, { error: 'Signed URLs and API keys require session scope and no redirectUri.' });\n if (!nonOAuthCredential && typeof input.redirectUri !== 'string')\n return json(400, { error: 'A redirectUri is required.' });\n if (scope === 'session' && (hasTools || hasSkills)) {\n return json(400, { error: 'Session scope cannot include capability grants.' });\n }\n if (scope === 'restricted' && (typeof input.name !== 'string' || !tools || !skills)) {\n return json(400, { error: 'Restricted scope requires a name, tools, and skills.' });\n }\n if (scope === 'restricted') {\n let surface;\n try {\n surface = resolved.session.host.mcpSurface.readSurface();\n } catch {\n return json(409, { error: 'The session capability surface is not ready.' });\n }\n if (surface.tools.some((tool) => SESSION_MCP_EXTRA_TOOLS.some((wrapper) => wrapper.name === tool.name)))\n return json(409, { error: 'The session capability surface contains a reserved remote tool name.' });\n const activeTools = new Set([\n ...surface.tools.map((tool) => tool.name),\n ...SESSION_MCP_EXTRA_TOOLS.map((tool) => tool.name),\n ]);\n const activeSkills = new Set(surface.skills.map((skill) => skill.name));\n if (tools!.some((name) => !activeTools.has(name)) || skills!.some((name) => !activeSkills.has(name)))\n return json(400, { error: 'Every requested grant must be active in the session.' });\n }\n try {\n const client = authorization.createClient(\n urlToken\n ? { name: defaultClientName(configuredOrigin), authMethod: 'url_token' }\n : apiKey\n ? { name: typeof input.name === 'string' ? input.name : 'API key', authMethod: 'api_key' }\n : {\n name: scope === 'session' ? defaultClientName(configuredOrigin) : (input.name as string),\n redirectUri: input.redirectUri as string,\n },\n );\n const audience = `${configuredOrigin}${sessionPath(workspaceId, sessionId)}`;\n try {\n const binding =\n scope === 'session'\n ? authorization.createAuthorizationBinding({\n clientId: client.clientId,\n sessionId,\n sessionGeneration: resolved.generation,\n audience,\n scope: 'session',\n routing,\n })\n : authorization.createAuthorizationBinding({\n clientId: client.clientId,\n sessionId,\n sessionGeneration: resolved.generation,\n audience,\n scope: 'restricted',\n routing,\n tools: [...new Set(tools!)],\n skills: [...new Set(skills!)],\n });\n const connectionUrl = urlToken ? `${audience}/${authorization.issueUrlToken(client.clientId)}` : undefined;\n if (nonOAuthCredential) {\n const registration = authorization.persistentRegistration(client.clientId, workspaceId, Date.now());\n if (registration === undefined || !options.registrationStore.save(registration)) {\n authorization.revokeClient(client.clientId);\n return json(500, { error: 'Session MCP credential could not be saved.' });\n }\n }\n return json(201, {\n client: {\n ...publicClient(client, binding),\n ...(connectionUrl === undefined ? { clientSecret: client.clientSecret } : { connectionUrl }),\n },\n });\n } catch (error) {\n authorization.revokeClient(client.clientId);\n throw error;\n }\n } catch (error) {\n return oauthError(error);\n }\n }\n if (clientId !== undefined && request.method === 'DELETE') {\n const binding = authorization.readAuthorizationBinding(clientId);\n if (binding?.sessionId !== sessionId) return json(404, { error: 'Client not found.' });\n if (options.registrationStore !== undefined && !options.registrationStore.remove(clientId)) {\n return json(500, { error: 'Client revocation could not be saved.' });\n }\n authorization.revokeClient(clientId);\n incarnations.get(sessionId)?.baselines.delete(clientId);\n options.conversationStore?.closeClient(clientId);\n publishPending();\n return json(200, { ok: true });\n }\n return json(405, { error: 'Method not allowed.' });\n },\n close() {\n unsubscribe();\n for (const [sessionId, incarnation] of incarnations) {\n revokeIncarnation(sessionId, incarnation.generation);\n abortOperations(incarnation.operations);\n }\n incarnations.clear();\n options.activityStore?.close();\n },\n };\n}\n\nexport function isPublicSessionMcpRoute(method: string, pathname: string): boolean {\n return (\n SESSION_MCP_PATTERN.test(pathname) ||\n SESSION_MCP_URL_TOKEN_PATTERN.test(pathname) ||\n (method === 'GET' && PROTECTED_RESOURCE_PATTERN.test(pathname)) ||\n (method === 'GET' && (pathname === AUTHORIZATION_SERVER_DISCOVERY || pathname === AUTHORIZE_ROUTE)) ||\n (method === 'POST' && pathname === TOKEN_ROUTE)\n );\n}\n\nexport function isSessionMcpHostRoute(pathname: string): boolean {\n return (\n SESSION_MCP_ACTIVITY_PATTERN.test(pathname) ||\n SESSION_MCP_CONFIG_PATTERN.test(pathname) ||\n SESSION_MCP_CLIENTS_PATTERN.test(pathname) ||\n SESSION_MCP_CONVERSATIONS_PATTERN.test(pathname)\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sessionMcpRoutes.mjs","names":[],"sources":["../../../src/server/sessionMcpRoutes.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport type { DoomHubSessionReservations, DoomHubSessionScope } from '../schemas/hubChannel';\nimport type { SessionMcpActivitySnapshot, SessionMcpAvailableTool } from '../schemas/sessionMcpActivity';\nimport type { SessionMcpActivityStore } from '../services/sessionMcpActivity';\nimport {\n createSessionMcpAuthorizationService,\n SessionMcpOAuthError,\n sessionMcpRouting,\n type SessionMcpAuthorizationBinding,\n type SessionMcpAuthorizationService,\n type SessionMcpClient,\n} from '../services/sessionMcpAuthorization';\nimport { SessionMcpConversationError, type SessionMcpConversationStore } from '../services/sessionMcpConversations';\nimport type { SessionMcpRegistrationStore } from '../services/sessionMcpRegistrationStore';\nimport type { HeadlessHub, HeadlessHubSession } from './headlessHub';\nimport {\n createSessionMcpHttpHandler,\n SESSION_MCP_EXTRA_TOOLS,\n type SessionMcpBaseline,\n type SessionMcpHttpHandler,\n type SessionMcpOperationRegistry,\n} from './sessionMcpHandler';\n\nconst AUTHORIZATION_SERVER_DISCOVERY = '/.well-known/oauth-authorization-server';\nconst AUTHORIZE_ROUTE = '/oauth/authorize';\nconst TOKEN_ROUTE = '/oauth/token';\nconst SESSION_MCP_PATTERN = /^\\/api\\/workspaces\\/([^/]+)\\/sessions\\/([^/]+)\\/mcp$/u;\nconst SESSION_MCP_URL_TOKEN_PATTERN =\n /^\\/api\\/workspaces\\/([^/]+)\\/sessions\\/([^/]+)\\/mcp\\/([A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+)$/u;\nconst SESSION_MCP_ACTIVITY_PATTERN = /^\\/api\\/workspaces\\/([^/]+)\\/sessions\\/([^/]+)\\/mcp\\/activity$/u;\nconst SESSION_MCP_CONFIG_PATTERN = /^\\/api\\/workspaces\\/([^/]+)\\/sessions\\/([^/]+)\\/mcp\\/config$/u;\nconst SESSION_MCP_CLIENTS_PATTERN = /^\\/api\\/workspaces\\/([^/]+)\\/sessions\\/([^/]+)\\/mcp\\/clients(?:\\/([^/]+))?$/u;\nconst SESSION_MCP_CONVERSATIONS_PATTERN =\n /^\\/api\\/workspaces\\/([^/]+)\\/sessions\\/([^/]+)\\/mcp\\/conversations(?:\\/([^/]+))?$/u;\n\n/**\n * An OAuth resource as it can be logged: the URL with any URL-token segment and every query value\n * redacted, so a mismatch in origin, path, trailing slash or query is visible without a secret.\n */\nfunction describeResource(resource: string): string {\n let parsed: URL;\n try {\n parsed = new URL(resource);\n } catch {\n return 'a resource that is not a URL';\n }\n const token = SESSION_MCP_URL_TOKEN_PATTERN.exec(parsed.pathname);\n const pathname = token === null ? parsed.pathname : parsed.pathname.slice(0, -token[3]!.length) + '<token>';\n const query = [...parsed.searchParams.keys()].map((key) => `${key}=<redacted>`).join('&');\n return `${parsed.origin}${pathname}${query === '' ? '' : `?${query}`}${parsed.hash === '' ? '' : '#<redacted>'}`;\n}\nfunction redactUrlCredentials(text: string): string {\n return text.replace(/([a-z][a-z0-9+.-]*:\\/\\/)[^\\s/?#]*@/giu, '$1***@');\n}\n\nconst PROTECTED_RESOURCE_PATTERN =\n /^\\/\\.well-known\\/oauth-protected-resource(\\/api\\/workspaces\\/[^/]+\\/sessions\\/[^/]+\\/mcp)$/u;\n\nexport interface SessionMcpRoutesOptions {\n readonly headlessHub: HeadlessHub;\n readonly publicOrigin: () => string | undefined;\n readonly publicOriginRevision?: () => number;\n readonly authorization?: SessionMcpAuthorizationService;\n readonly registrationStore?: SessionMcpRegistrationStore;\n readonly conversationStore?: SessionMcpConversationStore;\n readonly activityStore?: SessionMcpActivityStore;\n readonly isSessionPersisted?: (sessionId: string, cwd: string) => boolean;\n readonly onNotice?: (message: string) => void;\n}\n\nexport interface SessionMcpRoutes {\n handlePublic(request: Request): Promise<Response | undefined>;\n handleHost(request: Request): Promise<Response | undefined>;\n readonly reservations: DoomHubSessionReservations;\n closeSessionBinding(sessionId: string): void;\n close(): void;\n}\n\nfunction json(status: number, value: unknown): Response {\n return Response.json(value, { status, headers: { 'cache-control': 'no-store' } });\n}\n\nfunction oauthError(error: unknown): Response {\n if (error instanceof SessionMcpOAuthError)\n return json(error.code === 'invalid_client' ? 401 : 400, {\n error: error.code,\n error_description: error.message,\n });\n return json(400, { error: 'invalid_request', error_description: 'The OAuth request was invalid.' });\n}\n\nfunction trustedOrigin(value: string | undefined): string | undefined {\n if (value === undefined) return undefined;\n try {\n const url = new URL(value);\n return url.protocol === 'https:' && url.pathname === '/' && url.search === '' && url.hash === ''\n ? url.origin\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction sessionPath(workspaceId: string, sessionId: string): string {\n return `/api/workspaces/${encodeURIComponent(workspaceId)}/sessions/${encodeURIComponent(sessionId)}/mcp`;\n}\n\nfunction parseStringArray(value: unknown): readonly string[] | undefined {\n return Array.isArray(value) && value.every((entry) => typeof entry === 'string') ? value : undefined;\n}\n\nfunction defaultClientName(origin: string): string {\n return `ChatGPT · ${new URL(origin).hostname}`;\n}\n\nfunction formString(form: FormData, name: string): string {\n const value = form.get(name);\n return typeof value === 'string' ? value : '';\n}\n\nfunction publicClient(client: SessionMcpClient, binding: SessionMcpAuthorizationBinding): Record<string, unknown> {\n return {\n clientId: client.clientId,\n name: client.name,\n redirectUri: client.redirectUri,\n tokenEndpointAuthMethod: client.tokenEndpointAuthMethod,\n createdAt: client.createdAt,\n scope: binding.scope,\n routing: sessionMcpRouting(binding.routing),\n tools: binding.tools,\n skills: binding.skills,\n audience: binding.audience,\n };\n}\n\n/** Canonicalizes an intended directory without creating it or accepting symlink aliases. */\nfunction executionDirectory(value: string): string {\n if (!path.isAbsolute(value) || value.includes('\\0') || value.length > 4096)\n throw new SessionMcpConversationError('INVALID_EXECUTION_DIRECTORY', 'Choose an absolute execution directory.');\n let ancestor = path.resolve(value);\n const suffix: string[] = [];\n for (;;) {\n try {\n return path.join(fs.realpathSync(ancestor), ...suffix);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT' || path.dirname(ancestor) === ancestor)\n throw new SessionMcpConversationError(\n 'INVALID_EXECUTION_DIRECTORY',\n 'The execution directory cannot be resolved.',\n );\n suffix.unshift(path.basename(ancestor));\n ancestor = path.dirname(ancestor);\n }\n }\n}\n\nfunction overlappingDirectories(left: string, right: string): boolean {\n const contained = (root: string, target: string): boolean => {\n const relative = path.relative(root, target);\n return (\n relative === '' || (!path.isAbsolute(relative) && relative !== '..' && !relative.startsWith(`..${path.sep}`))\n );\n };\n return contained(left, right) || contained(right, left);\n}\n\n/** Routes the process-local session MCP authority and revokes every grant with its live incarnation. */\nexport function createSessionMcpRoutes(options: SessionMcpRoutesOptions): SessionMcpRoutes {\n const authorization = options.authorization ?? createSessionMcpAuthorizationService();\n // ponytail: Catalog baselines last one parent incarnation; persist snapshots only if clients must avoid a refresh after restart.\n const incarnations = new Map<\n string,\n {\n host: HeadlessHubSession['host'];\n generation: number;\n handlers: Map<string, SessionMcpHttpHandler>;\n operations: SessionMcpOperationRegistry;\n baselines: Map<string, SessionMcpBaseline>;\n }\n >();\n let nextGeneration = 1;\n let publishPending = (): void => {};\n\n const revokeIncarnation = (sessionId: string, generation: number): void => {\n authorization.revokeSessionGeneration(sessionId, generation);\n };\n const abortOperations = (operations: SessionMcpOperationRegistry): void => {\n for (const operation of operations.values()) operation.controller.abort();\n operations.clear();\n };\n const register = (session: HeadlessHubSession): boolean => {\n const current = incarnations.get(session.id);\n if (current?.host === session.host) return false;\n if (current !== undefined) {\n revokeIncarnation(session.id, current.generation);\n abortOperations(current.operations);\n }\n incarnations.set(session.id, {\n host: session.host,\n generation: nextGeneration++,\n handlers: new Map(),\n baselines: new Map(),\n operations: new Map(),\n });\n return true;\n };\n for (const session of options.headlessHub.snapshot()) register(session);\n const unsubscribe = options.headlessHub.onEvent((event) => {\n if (event.kind === 'upsert' && register(event.session)) publishPending();\n if (event.kind === 'removed') {\n const current = incarnations.get(event.sessionId);\n if (current !== undefined) {\n revokeIncarnation(event.sessionId, current.generation);\n abortOperations(current.operations);\n }\n incarnations.delete(event.sessionId);\n }\n });\n\n let observedOrigin: string | undefined;\n let observedOriginRevision: number | undefined;\n let originObserved = false;\n const origin = (): string | undefined => {\n const current = trustedOrigin(options.publicOrigin());\n const revision = options.publicOriginRevision?.();\n if (\n (originObserved && current !== observedOrigin) ||\n (revision !== undefined && observedOriginRevision !== undefined && revision !== observedOriginRevision)\n ) {\n for (const client of authorization.listClients()) {\n authorization.revokeClient(client.clientId);\n options.registrationStore?.remove(client.clientId);\n }\n for (const incarnation of incarnations.values()) {\n incarnation.handlers.clear();\n incarnation.baselines.clear();\n abortOperations(incarnation.operations);\n }\n }\n observedOrigin = current;\n observedOriginRevision = revision;\n originObserved = true;\n restorePersistedRegistrations(current);\n return current;\n };\n const target = (workspaceId: string, sessionId: string) => {\n // Remote MCP clients cannot inherit a grant, including through conversation child routing.\n if (options.headlessHub.computerUse?.ownsSession?.(sessionId)) return undefined;\n const session = options.headlessHub.session(sessionId);\n const incarnation = incarnations.get(sessionId);\n return session !== undefined && session.workspaceId === workspaceId && incarnation?.host === session.host\n ? { session, generation: incarnation.generation }\n : undefined;\n };\n const restorePersistedRegistrations = (configuredOrigin: string | undefined): void => {\n if (configuredOrigin === undefined) return;\n for (const registration of options.registrationStore?.registrations() ?? []) {\n const audience = `${configuredOrigin}${sessionPath(registration.workspaceId, registration.binding.sessionId)}`;\n if (registration.binding.audience !== audience) {\n options.registrationStore?.remove(registration.client.clientId);\n continue;\n }\n const resolved = target(registration.workspaceId, registration.binding.sessionId);\n if (resolved !== undefined) authorization.restorePersistentRegistration(registration, resolved.generation);\n }\n };\n\n const requireStore = (): SessionMcpConversationStore => {\n if (!options.conversationStore)\n throw new SessionMcpConversationError(\n 'CONVERSATION_ROUTING_UNAVAILABLE',\n 'Persistent conversation routing is unavailable.',\n );\n return options.conversationStore;\n };\n publishPending = () => {\n if (!options.conversationStore) return;\n try {\n const records = options.conversationStore.list();\n for (const parent of options.headlessHub.snapshot())\n options.headlessHub.setPendingSessionSetups?.(\n parent.id,\n records\n .filter((record) => record.parentSessionId === parent.id && record.state === 'pending')\n .map((record) => ({\n id: record.id,\n name: `conversation ${record.id.slice(0, 8)}`,\n createdAt: record.createdAt,\n status:\n provision.has(record.id) || recoveries.has(record.id)\n ? ('provisioning' as const)\n : record.failureCode === undefined\n ? ('interrupted' as const)\n : ('failed' as const),\n ...(record.setupKind === undefined ? {} : { setupKind: record.setupKind }),\n ...(record.failureCode === undefined ? {} : { errorCode: record.failureCode }),\n ...(record.cwd === undefined ? {} : { cwd: record.cwd }),\n })),\n );\n } catch (error) {\n options.onNotice?.(error instanceof Error ? error.message : 'Conversation bindings are unavailable.');\n }\n };\n const readReservation = (id: string, parentSessionId: string) => {\n origin();\n const record = requireStore().get(id, parentSessionId);\n const binding = authorization.readAuthorizationBinding(record.clientId);\n const parent = target(record.parentWorkspaceId, parentSessionId);\n if (\n !parent ||\n binding?.routing !== 'conversation' ||\n binding.sessionId !== parentSessionId ||\n binding.sessionGeneration !== parent.generation\n )\n throw new SessionMcpConversationError(\n 'SESSION_UNAVAILABLE',\n 'The connection that owns this setup is no longer active.',\n id,\n );\n return { record, parent };\n };\n const reservations: DoomHubSessionReservations = {\n read(id, parentSessionId) {\n const { record } = readReservation(id, parentSessionId);\n return { sessionId: record.id, ...(record.cwd === undefined ? {} : { cwd: record.cwd }) };\n },\n async prepare(id, parentSessionId, suppliedDirectory) {\n const { record, parent } = readReservation(id, parentSessionId);\n const cwd = executionDirectory(suppliedDirectory);\n const parentRoot =\n options.headlessHub.workspaces().find((workspace) => workspace.id === parent.session.workspaceId)?.root ??\n parent.session.cwd;\n const occupied = [\n parentRoot,\n ...options.headlessHub\n .snapshot()\n .filter((session) => session.id !== id)\n .map((session) => session.cwd),\n ...requireStore()\n .list()\n .filter((entry) => entry.id !== id && entry.state !== 'closed' && entry.cwd !== undefined)\n .map((entry) => entry.cwd!),\n ];\n if (occupied.some((directory) => overlappingDirectories(cwd, executionDirectory(directory))))\n throw new SessionMcpConversationError(\n 'EXECUTION_DIRECTORY_SHARED',\n 'Choose a separate checkout, not a directory shared with another session.',\n id,\n );\n if (record.state === 'bound' && record.cwd !== cwd)\n throw new SessionMcpConversationError(\n 'SESSION_TARGET_FIXED',\n 'An initialized session cannot change its directory.',\n id,\n );\n requireStore().prepare(id, parentSessionId, cwd);\n publishPending();\n return { sessionId: id, cwd };\n },\n async complete(id, parentSessionId): Promise<DoomHubSessionScope> {\n const { record } = readReservation(id, parentSessionId);\n const child = options.headlessHub.session(id);\n if (\n !record.cwd ||\n !child?.workspaceId ||\n child.parentSessionId !== parentSessionId ||\n (record.setupKind === 'managed-worktree' && child.workspaceId !== record.parentWorkspaceId) ||\n executionDirectory(child.cwd) !== record.cwd ||\n options.isSessionPersisted?.(id, child.cwd) === false\n )\n throw new SessionMcpConversationError(\n 'SESSION_SETUP_INCOMPLETE',\n 'The reserved session is not durably ready. Recover the existing setup instead of creating another checkout.',\n id,\n );\n requireStore().bind(id, parentSessionId, child.workspaceId);\n publishPending();\n return { sessionId: id, workspaceId: child.workspaceId, cwd: child.cwd };\n },\n };\n const provision = new Map<string, Promise<DoomHubSessionScope>>();\n const recoveries = new Map<string, Promise<DoomHubSessionScope>>();\n const setupDirectory = async (\n id: string,\n parentSessionId: string,\n directory: string,\n ): Promise<DoomHubSessionScope> => {\n // A mistyped existing-directory choice must not permanently reserve a nonexistent path.\n const canonical = executionDirectory(directory);\n if (!fs.statSync(canonical).isDirectory()) throw new Error('The execution directory is not a directory.');\n const { record: current } = readReservation(id, parentSessionId);\n if (provision.has(id) && current.setupKind === 'managed-worktree')\n throw new SessionMcpConversationError('SESSION_TARGET_FIXED', 'This setup belongs to a managed worktree.', id);\n const selected = requireStore().selectSetup(id, parentSessionId, 'existing-directory');\n if (selected.setupKind !== 'existing-directory')\n throw new SessionMcpConversationError('SESSION_TARGET_FIXED', 'This setup belongs to a managed worktree.', id);\n const prepared = await reservations.prepare(id, parentSessionId, canonical);\n const pending = provision.get(id);\n if (pending) return pending;\n const setup = (async () => {\n if (!options.headlessHub.session(id)) {\n const record = requireStore().get(id, parentSessionId);\n if (record.state === 'bound' || options.isSessionPersisted?.(id, prepared.cwd))\n throw new SessionMcpConversationError(\n 'SESSION_UNAVAILABLE',\n 'Resume the existing session in DoomPi. It will not be recreated automatically.',\n id,\n );\n if (!fs.statSync(prepared.cwd).isDirectory()) throw new Error('The execution directory is not a directory.');\n await options.headlessHub.sessionService.create({\n cwd: prepared.cwd,\n name: `conversation ${id.slice(0, 8)}`,\n parentSessionId,\n sessionProvenance: 'remote-conversation',\n reservationId: id,\n });\n }\n return reservations.complete(id, parentSessionId);\n })();\n provision.set(id, setup);\n publishPending();\n try {\n return await setup;\n } catch (error) {\n requireStore().fail(id, parentSessionId, 'SESSION_UNAVAILABLE');\n throw error;\n } finally {\n if (provision.get(id) === setup) provision.delete(id);\n publishPending();\n }\n };\n const provisionConversationWorktree = async (\n record: ReturnType<SessionMcpConversationStore['reserve']>,\n signal?: AbortSignal,\n ): Promise<DoomHubSessionScope> => {\n const pending = provision.get(record.id);\n if (pending) return pending;\n readReservation(record.id, record.parentSessionId);\n requireStore().selectSetup(record.id, record.parentSessionId, 'managed-worktree');\n const setup = (async () => {\n try {\n const child = await options.headlessHub.sessionService.provisionReservedWorktree?.({\n reservationId: record.id,\n parentSessionId: record.parentSessionId,\n signal,\n });\n if (child === undefined || child.sessionId !== record.id)\n throw new Error('Automatic worktree provisioning did not create the reserved session.');\n return child;\n } catch (error) {\n if (error instanceof SessionMcpConversationError) throw error;\n options.onNotice?.(\n `session MCP worktree provisioning failed for reservation ${record.id}: ${error instanceof Error ? redactUrlCredentials(error.message) : 'Automatic worktree provisioning failed.'}`,\n );\n throw new SessionMcpConversationError(\n 'SESSION_WORKTREE_PROVISION_FAILED',\n 'An automatic worktree could not be created for this conversation. Resolve the host Git setup, then retry.',\n record.id,\n );\n }\n })();\n provision.set(record.id, setup);\n publishPending();\n try {\n return await setup;\n } catch (error) {\n requireStore().fail(record.id, record.parentSessionId, 'SESSION_WORKTREE_PROVISION_FAILED');\n throw error;\n } finally {\n if (provision.get(record.id) === setup) provision.delete(record.id);\n publishPending();\n }\n };\n const publicRoutes = async (request: Request): Promise<Response | undefined> => {\n const url = new URL(request.url);\n const configuredOrigin = origin();\n const signedMcpMatch = SESSION_MCP_URL_TOKEN_PATTERN.exec(url.pathname);\n const mcpMatch = SESSION_MCP_PATTERN.exec(url.pathname) ?? signedMcpMatch;\n if (mcpMatch !== null) {\n if (configuredOrigin === undefined) return json(503, { error: 'Session MCP public origin is unavailable.' });\n const workspaceId = decodeURIComponent(mcpMatch[1]);\n const sessionId = decodeURIComponent(mcpMatch[2]);\n const pathToken = signedMcpMatch?.[3];\n const basePath = sessionPath(workspaceId, sessionId);\n const exactPath = pathToken === undefined ? basePath : `${basePath}/${pathToken}`;\n if (url.pathname !== exactPath || url.search !== '') return json(404, { error: 'Not found.' });\n const audience = `${configuredOrigin}${basePath}`;\n const resource = pathToken === undefined ? audience : `${audience}/${pathToken}`;\n const incarnation = target(workspaceId, sessionId) === undefined ? undefined : incarnations.get(sessionId);\n const handlers = incarnation?.handlers;\n const cachedHandler = pathToken === undefined ? handlers?.get(resource) : undefined;\n const handler =\n cachedHandler ??\n createSessionMcpHttpHandler({\n audience,\n baselines: incarnation?.baselines ?? new Map(),\n authorization,\n onNotice: options.onNotice,\n onInvocation: (invocation) => {\n if (invocation.sessionId === undefined || invocation.conversationDigest === undefined) return;\n const conversation = options.conversationStore?.find(\n invocation.clientId,\n invocation.parentSessionId,\n invocation.conversationDigest,\n );\n if (\n conversation?.state !== 'bound' ||\n conversation.id !== invocation.sessionId ||\n conversation.workspaceId === undefined\n )\n return;\n options.activityStore?.record(\n conversation.workspaceId,\n conversation.id,\n authorization.readClient(invocation.clientId)?.name ?? 'remote agent',\n invocation,\n );\n },\n ...(pathToken === undefined ? {} : { pathToken, operations: incarnation?.operations }),\n resolveConversation: async (grant, digest, reserve, signal) => {\n const store = requireStore();\n let record = reserve\n ? store.reserve(grant.clientId, sessionId, workspaceId, digest)\n : store.find(grant.clientId, sessionId, digest);\n if (!record)\n throw new SessionMcpConversationError(\n 'SESSION_UNAVAILABLE',\n 'This conversation binding is unavailable. It will not be recreated automatically.',\n );\n const restoring = recoveries.get(record.id);\n if (restoring) await restoring;\n else {\n const existing = record.workspaceId === undefined ? undefined : target(record.workspaceId, record.id);\n if (record.state === 'closed' || (record.state === 'bound' && !existing)) {\n if (\n options.headlessHub.session(record.id) ||\n !record.cwd ||\n options.isSessionPersisted?.(record.id, record.cwd) !== false\n )\n throw new SessionMcpConversationError(\n 'SESSION_UNAVAILABLE',\n 'The bound session is unavailable. Resume it in DoomPi; no other session will be used.',\n record.id,\n );\n if (record.setupKind === undefined && record.cwd !== undefined)\n throw new SessionMcpConversationError(\n 'SESSION_TARGET_FIXED',\n 'This existing setup has no verified provider. Recover it without changing its ownership.',\n record.id,\n );\n record = store.recover(record.id, sessionId);\n const recovery =\n record.setupKind === 'existing-directory' && record.cwd\n ? setupDirectory(record.id, sessionId, record.cwd)\n : provisionConversationWorktree(record, signal);\n recoveries.set(record.id, recovery);\n publishPending();\n try {\n await recovery;\n } finally {\n if (recoveries.get(record.id) === recovery) recoveries.delete(record.id);\n publishPending();\n }\n }\n }\n record = store.find(grant.clientId, sessionId, digest)!;\n if (record.state === 'pending') {\n publishPending();\n if (record.workspaceId !== undefined && options.isSessionPersisted?.(record.id, record.cwd!) !== false)\n throw new SessionMcpConversationError(\n 'SESSION_UNAVAILABLE',\n 'The bound session is unavailable. Resume it in DoomPi; no other session will be used.',\n record.id,\n );\n const pending = provision.get(record.id);\n if (pending) await pending;\n else if (record.setupKind === 'existing-directory' && record.cwd)\n await setupDirectory(record.id, sessionId, record.cwd);\n else await provisionConversationWorktree(record, signal);\n record = store.find(grant.clientId, sessionId, digest);\n if (!record || record.state !== 'bound')\n throw new SessionMcpConversationError(\n 'SESSION_WORKTREE_PROVISION_FAILED',\n 'The automatic worktree setup did not complete. Retry after resolving the host Git setup.',\n );\n }\n const child = record.workspaceId === undefined ? undefined : target(record.workspaceId, record.id);\n if (\n !child ||\n child.session.parentSessionId !== sessionId ||\n executionDirectory(child.session.cwd) !== record.cwd ||\n !fs.existsSync(child.session.cwd)\n )\n throw new SessionMcpConversationError(\n 'SESSION_UNAVAILABLE',\n 'The bound session is unavailable. Resume it in DoomPi; no other session will be used.',\n record.id,\n );\n return { sessionId: record.id, generation: child.generation, toolSurface: child.session.host.mcpSurface };\n },\n onVerified: (grant) => {\n if (options.registrationStore === undefined) return;\n const active = target(workspaceId, sessionId);\n if (active === undefined || grant.sessionGeneration !== active.generation || grant.clientId === '') {\n throw new Error('The session grant is no longer active.');\n }\n if (authorization.readClient(grant.clientId)?.tokenEndpointAuthMethod !== 'client_secret_post') return;\n const registration = authorization.persistentRegistration(grant.clientId, workspaceId, Date.now());\n if (registration === undefined || !options.registrationStore.save(registration)) {\n throw new Error('The verified Session MCP client could not be saved.');\n }\n },\n ...(pathToken === undefined\n ? { resourceMetadataUrl: `${configuredOrigin}/.well-known/oauth-protected-resource${basePath}` }\n : {}),\n resolveSession: (grantedSessionId) => {\n if (grantedSessionId !== sessionId) return undefined;\n const resolved = target(workspaceId, sessionId);\n return resolved === undefined\n ? undefined\n : { sessionId, generation: resolved.generation, toolSurface: resolved.session.host.mcpSurface };\n },\n });\n if (pathToken === undefined) handlers?.set(resource, handler);\n return handler(new Request(resource, request));\n }\n\n const protectedMatch = PROTECTED_RESOURCE_PATTERN.exec(url.pathname);\n if (protectedMatch !== null && request.method === 'GET') {\n if (configuredOrigin === undefined) return json(503, { error: 'Session MCP public origin is unavailable.' });\n return json(200, {\n resource: `${configuredOrigin}${protectedMatch[1]}`,\n authorization_servers: [configuredOrigin],\n bearer_methods_supported: ['header'],\n });\n }\n if (url.pathname === AUTHORIZATION_SERVER_DISCOVERY && request.method === 'GET') {\n if (configuredOrigin === undefined) return json(503, { error: 'Session MCP public origin is unavailable.' });\n return json(200, {\n issuer: configuredOrigin,\n authorization_endpoint: `${configuredOrigin}${AUTHORIZE_ROUTE}`,\n token_endpoint: `${configuredOrigin}${TOKEN_ROUTE}`,\n response_types_supported: ['code'],\n grant_types_supported: ['authorization_code', 'refresh_token'],\n code_challenge_methods_supported: ['S256'],\n token_endpoint_auth_methods_supported: ['client_secret_post'],\n });\n }\n if (url.pathname === AUTHORIZE_ROUTE && request.method === 'GET') {\n if (configuredOrigin === undefined) return json(503, { error: 'Session MCP public origin is unavailable.' });\n const clientId = url.searchParams.get('client_id') ?? '';\n const client = authorization.readClient(clientId);\n const binding = authorization.readAuthorizationBinding(clientId);\n const redirectUri = url.searchParams.get('redirect_uri') ?? '';\n if (\n client === undefined ||\n client.tokenEndpointAuthMethod !== 'client_secret_post' ||\n binding === undefined ||\n redirectUri !== client.redirectUri\n ) {\n return oauthError(new SessionMcpOAuthError('invalid_client', 'Unknown client or callback.'));\n }\n const callback = new URL(client.redirectUri);\n const state = url.searchParams.get('state');\n try {\n const boundSession = options.headlessHub.session(binding.sessionId);\n const boundIncarnation = incarnations.get(binding.sessionId);\n const expectedAudience =\n boundSession?.workspaceId === undefined\n ? undefined\n : `${configuredOrigin}${sessionPath(boundSession.workspaceId, binding.sessionId)}`;\n if (\n expectedAudience === undefined ||\n binding.audience !== expectedAudience ||\n boundIncarnation?.host !== boundSession?.host ||\n binding.sessionGeneration !== boundIncarnation?.generation\n ) {\n authorization.revokeClient(clientId);\n throw new SessionMcpOAuthError('invalid_grant', 'The preauthorized session is no longer active.');\n }\n if (url.searchParams.get('response_type') !== 'code')\n throw new SessionMcpOAuthError('invalid_request', 'Only the code response type is supported.');\n const resource = url.searchParams.get('resource');\n if (resource !== null && resource !== binding.audience) {\n // The requested URL can carry a URL token, which is redacted.\n options.onNotice?.(\n `session MCP authorize refused: client ${clientId} is bound to session ${binding.sessionId}, expecting ${binding.audience} but the connector asked for ${describeResource(resource)}`,\n );\n throw new SessionMcpOAuthError(\n 'invalid_request',\n \"The requested resource is not preauthorized. The connector's MCP URL must be the session URL this client was created for.\",\n );\n }\n const code = authorization.issueAuthorizationCode({\n clientId,\n redirectUri,\n codeChallenge: url.searchParams.get('code_challenge') ?? '',\n codeChallengeMethod: url.searchParams.get('code_challenge_method') as 'S256',\n });\n callback.searchParams.set('code', code.code);\n } catch (error) {\n callback.searchParams.set('error', error instanceof SessionMcpOAuthError ? error.code : 'invalid_request');\n callback.searchParams.set(\n 'error_description',\n error instanceof Error ? error.message : 'The OAuth request was invalid.',\n );\n }\n if (state !== null) callback.searchParams.set('state', state);\n return new Response(null, { status: 302, headers: { location: callback.href, 'cache-control': 'no-store' } });\n }\n if (url.pathname === TOKEN_ROUTE && request.method === 'POST') {\n try {\n const form = await request.formData();\n const grantType = formString(form, 'grant_type');\n const clientId = formString(form, 'client_id');\n const clientSecret = formString(form, 'client_secret');\n const result =\n grantType === 'authorization_code'\n ? authorization.exchangeToken({\n grantType,\n clientId,\n clientSecret,\n code: formString(form, 'code'),\n redirectUri: formString(form, 'redirect_uri'),\n codeVerifier: formString(form, 'code_verifier'),\n })\n : grantType === 'refresh_token'\n ? authorization.exchangeToken({\n grantType,\n clientId,\n clientSecret,\n refreshToken: formString(form, 'refresh_token'),\n })\n : (() => {\n throw new SessionMcpOAuthError('unsupported_grant_type', 'The grant type is not supported.');\n })();\n return json(200, {\n access_token: result.accessToken,\n refresh_token: result.refreshToken,\n token_type: result.tokenType,\n expires_in: result.expiresIn,\n });\n } catch (error) {\n return oauthError(error);\n }\n }\n return undefined;\n };\n\n publishPending();\n return {\n reservations,\n closeSessionBinding(sessionId) {\n options.conversationStore?.closeSession(sessionId);\n publishPending();\n },\n handlePublic: publicRoutes,\n async handleHost(request) {\n const url = new URL(request.url);\n origin();\n const configMatch = SESSION_MCP_CONFIG_PATTERN.exec(url.pathname);\n const match = SESSION_MCP_CLIENTS_PATTERN.exec(url.pathname);\n const conversationMatch = SESSION_MCP_CONVERSATIONS_PATTERN.exec(url.pathname);\n const activityMatch = SESSION_MCP_ACTIVITY_PATTERN.exec(url.pathname);\n if (configMatch === null && match === null && conversationMatch === null && activityMatch === null)\n return undefined;\n const routeMatch = configMatch ?? match ?? conversationMatch ?? activityMatch!;\n const workspaceId = decodeURIComponent(routeMatch[1]);\n const sessionId = decodeURIComponent(routeMatch[2]);\n const clientId = match?.[3] === undefined ? undefined : decodeURIComponent(match[3]);\n const resolved = target(workspaceId, sessionId);\n if (activityMatch !== null) {\n if (request.method !== 'GET') return json(405, { error: 'Method not allowed.' });\n const beforeText = url.searchParams.get('before');\n const before = beforeText === null ? undefined : Number(beforeText);\n if (\n [...url.searchParams.keys()].some((key) => key !== 'before') ||\n (before !== undefined && (!Number.isSafeInteger(before) || before <= 0))\n )\n return json(400, { error: 'Invalid history cursor.' });\n if (options.headlessHub.computerUse?.ownsSession?.(sessionId))\n return json(404, { error: 'Session not found.' });\n if (!options.activityStore) return json(503, { error: 'MCP call history is unavailable in this host.' });\n try {\n const conversation = options.conversationStore\n ?.list()\n .find((entry) => entry.id === sessionId && entry.state === 'bound' && entry.workspaceId === workspaceId);\n if (conversation === undefined)\n return json(200, {\n enabled: false,\n available: false,\n tools: [],\n calls: [],\n total: 0,\n } satisfies SessionMcpActivitySnapshot);\n const history = options.activityStore.read(workspaceId, sessionId, before);\n const parent = target(conversation.parentWorkspaceId, conversation.parentSessionId);\n const bindings = authorization.listClients().flatMap((client) => {\n const binding = authorization.readAuthorizationBinding(client.clientId);\n return binding !== undefined &&\n client.clientId === conversation.clientId &&\n binding.sessionId === conversation.parentSessionId &&\n binding.sessionGeneration === parent?.generation\n ? [{ client, binding }]\n : [];\n });\n let available = false;\n let tools: SessionMcpAvailableTool[] = [];\n if (resolved !== undefined && bindings.length > 0) {\n try {\n const surface = resolved.session.host.mcpSurface.readSurface();\n const candidates = [\n ...surface.tools.map((tool) => ({\n name: tool.name,\n label: tool.label,\n description: tool.description,\n inputSchema: tool.parameters,\n })),\n ...SESSION_MCP_EXTRA_TOOLS.map((tool) => ({\n name: tool.name,\n label: tool.title ?? tool.name,\n description: tool.description ?? '',\n inputSchema: tool.inputSchema,\n })),\n ];\n tools = candidates.flatMap((tool) => {\n const connections = bindings\n .filter(({ binding }) => binding.scope === 'session' || binding.tools.includes(tool.name))\n .map(({ client }) => client.name);\n return connections.length === 0 ? [] : [{ ...tool, connections }];\n });\n available = true;\n } catch {\n // Keep durable history visible while the child session's live capability surface is rebuilding.\n available = false;\n }\n }\n const snapshot: SessionMcpActivitySnapshot = {\n ...history,\n enabled: true,\n available,\n tools,\n };\n return json(200, snapshot);\n } catch {\n return json(503, { error: 'MCP call history could not be read. Check the host storage.' });\n }\n }\n if (resolved === undefined) return json(404, { error: 'Session not found.' });\n if (conversationMatch !== null) {\n const id = conversationMatch[3] === undefined ? undefined : decodeURIComponent(conversationMatch[3]);\n try {\n if (request.method === 'GET' && id === undefined)\n return json(200, {\n conversations: requireStore()\n .list()\n .filter((record) => record.parentSessionId === sessionId && record.state !== 'closed')\n .map(({ conversationDigest: _digest, clientId: _clientId, ...record }) => record),\n });\n if (id !== undefined && request.method === 'DELETE') {\n const record = requireStore().get(id, sessionId);\n if (record.state !== 'pending' || options.headlessHub.session(id))\n return json(409, { error: 'Remove the existing session instead.' });\n requireStore().closeSession(id);\n publishPending();\n return json(200, { ok: true });\n }\n if (id !== undefined && request.method === 'POST') {\n const body: unknown = await request.json();\n if (typeof body !== 'object' || body === null || !('cwd' in body) || typeof body.cwd !== 'string')\n return json(400, { error: 'An execution directory is required.' });\n return json(200, { session: await setupDirectory(id, sessionId, body.cwd) });\n }\n return json(405, { error: 'Method not allowed.' });\n } catch (error) {\n return json(409, {\n error:\n error instanceof SessionMcpConversationError\n ? error.message\n : 'Session setup failed. Recover the existing setup before retrying.',\n ...(error instanceof SessionMcpConversationError ? { code: error.code } : {}),\n });\n }\n }\n if (configMatch !== null) {\n if (request.method !== 'GET') return json(405, { error: 'Method not allowed.' });\n const configuredOrigin = origin();\n if (configuredOrigin === undefined) return json(503, { error: 'Session MCP public origin is unavailable.' });\n let surface;\n try {\n surface = resolved.session.host.mcpSurface.readSurface();\n } catch {\n return json(409, { error: 'The session capability surface is not ready.' });\n }\n if (surface.tools.some((tool) => SESSION_MCP_EXTRA_TOOLS.some((wrapper) => wrapper.name === tool.name)))\n return json(409, { error: 'The session capability surface contains a reserved remote tool name.' });\n return json(200, {\n audience: `${configuredOrigin}${sessionPath(workspaceId, sessionId)}`,\n authorizationEndpoint: `${configuredOrigin}${AUTHORIZE_ROUTE}`,\n tokenEndpoint: `${configuredOrigin}${TOKEN_ROUTE}`,\n tools: [\n ...surface.tools.map(({ name, label, description }) => ({ name, label, description })),\n ...SESSION_MCP_EXTRA_TOOLS.map(({ name, title, description }) => ({\n name,\n label: title ?? name,\n description,\n })),\n ],\n skills: surface.skills,\n });\n }\n if (clientId === undefined && request.method === 'GET') {\n return json(200, {\n clients: authorization.listClients().flatMap((client) => {\n const binding = authorization.readAuthorizationBinding(client.clientId);\n return binding?.sessionId === sessionId ? [publicClient(client, binding)] : [];\n }),\n });\n }\n if (clientId === undefined && request.method === 'POST') {\n const configuredOrigin = origin();\n if (configuredOrigin === undefined) return json(503, { error: 'Session MCP public origin is unavailable.' });\n let body: unknown;\n try {\n body = await request.json();\n } catch {\n return json(400, { error: 'Invalid client request.' });\n }\n if (typeof body !== 'object' || body === null) return json(400, { error: 'Invalid client request.' });\n const input = body as Record<string, unknown>;\n if (!options.conversationStore || !options.registrationStore)\n return json(503, { error: 'Mandatory conversation routing requires persistent host state.' });\n if (input.routing !== undefined && input.routing !== 'session' && input.routing !== 'conversation')\n return json(400, { error: 'Session MCP routing is not supported.' });\n const routing = sessionMcpRouting(input.routing);\n const requestedScope = input.scope;\n if (requestedScope !== undefined && requestedScope !== 'session' && requestedScope !== 'restricted') {\n return json(400, { error: 'Authorization scope is not supported.' });\n }\n const scope = requestedScope === 'session' ? 'session' : 'restricted';\n const hasTools = Object.hasOwn(input, 'tools');\n const hasSkills = Object.hasOwn(input, 'skills');\n const tools = parseStringArray(input.tools);\n const skills = parseStringArray(input.skills);\n const authMethod = input.authMethod;\n const apiKey = authMethod === 'api_key';\n const urlToken = authMethod === 'url_token';\n const nonOAuthCredential = apiKey || urlToken;\n if (authMethod !== undefined && authMethod !== 'oauth' && !nonOAuthCredential)\n return json(400, { error: 'Authentication method is not supported.' });\n if (nonOAuthCredential && (scope !== 'session' || Object.hasOwn(input, 'redirectUri')))\n return json(400, { error: 'Signed URLs and API keys require session scope and no redirectUri.' });\n if (!nonOAuthCredential && typeof input.redirectUri !== 'string')\n return json(400, { error: 'A redirectUri is required.' });\n if (scope === 'session' && (hasTools || hasSkills)) {\n return json(400, { error: 'Session scope cannot include capability grants.' });\n }\n if (scope === 'restricted' && (typeof input.name !== 'string' || !tools || !skills)) {\n return json(400, { error: 'Restricted scope requires a name, tools, and skills.' });\n }\n if (scope === 'restricted') {\n let surface;\n try {\n surface = resolved.session.host.mcpSurface.readSurface();\n } catch {\n return json(409, { error: 'The session capability surface is not ready.' });\n }\n if (surface.tools.some((tool) => SESSION_MCP_EXTRA_TOOLS.some((wrapper) => wrapper.name === tool.name)))\n return json(409, { error: 'The session capability surface contains a reserved remote tool name.' });\n const activeTools = new Set([\n ...surface.tools.map((tool) => tool.name),\n ...SESSION_MCP_EXTRA_TOOLS.map((tool) => tool.name),\n ]);\n const activeSkills = new Set(surface.skills.map((skill) => skill.name));\n if (tools!.some((name) => !activeTools.has(name)) || skills!.some((name) => !activeSkills.has(name)))\n return json(400, { error: 'Every requested grant must be active in the session.' });\n }\n try {\n const client = authorization.createClient(\n urlToken\n ? { name: defaultClientName(configuredOrigin), authMethod: 'url_token' }\n : apiKey\n ? { name: typeof input.name === 'string' ? input.name : 'API key', authMethod: 'api_key' }\n : {\n name: scope === 'session' ? defaultClientName(configuredOrigin) : (input.name as string),\n redirectUri: input.redirectUri as string,\n },\n );\n const audience = `${configuredOrigin}${sessionPath(workspaceId, sessionId)}`;\n try {\n const binding =\n scope === 'session'\n ? authorization.createAuthorizationBinding({\n clientId: client.clientId,\n sessionId,\n sessionGeneration: resolved.generation,\n audience,\n scope: 'session',\n routing,\n })\n : authorization.createAuthorizationBinding({\n clientId: client.clientId,\n sessionId,\n sessionGeneration: resolved.generation,\n audience,\n scope: 'restricted',\n routing,\n tools: [...new Set(tools!)],\n skills: [...new Set(skills!)],\n });\n const connectionUrl = urlToken ? `${audience}/${authorization.issueUrlToken(client.clientId)}` : undefined;\n if (nonOAuthCredential) {\n const registration = authorization.persistentRegistration(client.clientId, workspaceId, Date.now());\n if (registration === undefined || !options.registrationStore.save(registration)) {\n authorization.revokeClient(client.clientId);\n return json(500, { error: 'Session MCP credential could not be saved.' });\n }\n }\n return json(201, {\n client: {\n ...publicClient(client, binding),\n ...(connectionUrl === undefined ? { clientSecret: client.clientSecret } : { connectionUrl }),\n },\n });\n } catch (error) {\n authorization.revokeClient(client.clientId);\n throw error;\n }\n } catch (error) {\n return oauthError(error);\n }\n }\n if (clientId !== undefined && request.method === 'DELETE') {\n const binding = authorization.readAuthorizationBinding(clientId);\n if (binding?.sessionId !== sessionId) return json(404, { error: 'Client not found.' });\n if (options.registrationStore !== undefined && !options.registrationStore.remove(clientId)) {\n return json(500, { error: 'Client revocation could not be saved.' });\n }\n authorization.revokeClient(clientId);\n incarnations.get(sessionId)?.baselines.delete(clientId);\n options.conversationStore?.closeClient(clientId);\n publishPending();\n return json(200, { ok: true });\n }\n return json(405, { error: 'Method not allowed.' });\n },\n close() {\n unsubscribe();\n for (const [sessionId, incarnation] of incarnations) {\n revokeIncarnation(sessionId, incarnation.generation);\n abortOperations(incarnation.operations);\n }\n incarnations.clear();\n options.activityStore?.close();\n },\n };\n}\n\nexport function isPublicSessionMcpRoute(method: string, pathname: string): boolean {\n return (\n SESSION_MCP_PATTERN.test(pathname) ||\n SESSION_MCP_URL_TOKEN_PATTERN.test(pathname) ||\n (method === 'GET' && PROTECTED_RESOURCE_PATTERN.test(pathname)) ||\n (method === 'GET' && (pathname === AUTHORIZATION_SERVER_DISCOVERY || pathname === AUTHORIZE_ROUTE)) ||\n (method === 'POST' && pathname === TOKEN_ROUTE)\n );\n}\n\nexport function isSessionMcpHostRoute(pathname: string): boolean {\n return (\n SESSION_MCP_ACTIVITY_PATTERN.test(pathname) ||\n SESSION_MCP_CONFIG_PATTERN.test(pathname) ||\n SESSION_MCP_CLIENTS_PATTERN.test(pathname) ||\n SESSION_MCP_CONVERSATIONS_PATTERN.test(pathname)\n );\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agimon-ai/doompi-core",
3
- "version": "0.0.1-alpha.117",
3
+ "version": "0.0.1-alpha.119",
4
4
  "description": "Doompi runtime systems and reusable core services.",
5
5
  "keywords": [
6
6
  "ai",
@@ -547,8 +547,8 @@
547
547
  "registry": "https://registry.npmjs.org/"
548
548
  },
549
549
  "dependencies": {
550
- "@agimon-ai/doompi-telemetry": "0.0.1-alpha.100",
551
- "@agimon-ai/doompi-web-security": "0.0.1-alpha.63",
550
+ "@agimon-ai/doompi-telemetry": "0.0.1-alpha.102",
551
+ "@agimon-ai/doompi-web-security": "0.0.1-alpha.65",
552
552
  "@deepseek-ai/cordis": "4.0.4",
553
553
  "@earendil-works/chord": "1.0.2",
554
554
  "@earendil-works/pi-agent-core": "1.0.2",
@@ -572,7 +572,7 @@
572
572
  "yaml": "2.9.1"
573
573
  },
574
574
  "devDependencies": {
575
- "@agimon-ai/vibe-lint-plugin-doom-core": "0.0.1-alpha.34",
575
+ "@agimon-ai/vibe-lint-plugin-doom-core": "0.0.1-alpha.36",
576
576
  "@apidevtools/swagger-parser": "^13.1.0",
577
577
  "@asyncapi/parser": "^3.6.3",
578
578
  "@earendil-works/pi-ai": "1.0.2",