@creatornader/agent-bridge 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +51 -1
- package/README.md +37 -32
- package/ROADMAP.md +56 -15
- package/SECURITY.md +6 -5
- package/dist/archive.d.ts +2 -2
- package/dist/{bridge-service-CNBKdYXh.d.ts → bridge-service-DjSYfjKt.d.ts} +4 -2
- package/dist/{bridge-store-ByJ6CaJk.d.ts → bridge-store-Bi_LCX8e.d.ts} +5 -1
- package/dist/bridge.d.ts +9 -37
- package/dist/bridge.js +7 -11
- package/dist/chunk-23UDQZMT.js +54 -0
- package/dist/chunk-23UDQZMT.js.map +1 -0
- package/dist/{chunk-AWE3DFZV.js → chunk-4V2PFJEF.js} +11 -4
- package/dist/chunk-4V2PFJEF.js.map +1 -0
- package/dist/{chunk-E4OWHGUE.js → chunk-62C63PIE.js} +8 -8
- package/dist/chunk-62C63PIE.js.map +1 -0
- package/dist/{chunk-HUHG7XTB.js → chunk-AIALYLGQ.js} +30 -193
- package/dist/chunk-AIALYLGQ.js.map +1 -0
- package/dist/{chunk-XDNT6ZNZ.js → chunk-CVZAJ7TP.js} +2 -2
- package/dist/chunk-CVZAJ7TP.js.map +1 -0
- package/dist/{chunk-P635FAN4.js → chunk-FGERNG4X.js} +7 -3
- package/dist/chunk-FGERNG4X.js.map +1 -0
- package/dist/{chunk-7VJI2MXI.js → chunk-IF5OKPBK.js} +32 -14
- package/dist/chunk-IF5OKPBK.js.map +1 -0
- package/dist/{chunk-QPC6JHA3.js → chunk-IMJ47WO4.js} +12 -16
- package/dist/chunk-IMJ47WO4.js.map +1 -0
- package/dist/{chunk-2EVLG3YA.js → chunk-UKFRCP6X.js} +10 -7
- package/dist/chunk-UKFRCP6X.js.map +1 -0
- package/dist/chunk-WQ4I5XGF.js +242 -0
- package/dist/chunk-WQ4I5XGF.js.map +1 -0
- package/dist/{chunk-SN7PIVDF.js → chunk-ZUZ7TCIH.js} +13 -1
- package/dist/{chunk-SN7PIVDF.js.map → chunk-ZUZ7TCIH.js.map} +1 -1
- package/dist/cli.js +41 -34
- package/dist/cli.js.map +1 -1
- package/dist/client-config.d.ts +1 -1
- package/dist/client-config.js +1 -1
- package/dist/client-runtime.d.ts +3 -3
- package/dist/client-runtime.js +5 -5
- package/dist/contracts/generate.js +2 -3
- package/dist/contracts/generate.js.map +1 -1
- package/dist/dr.d.ts +8 -0
- package/dist/dr.js +1 -1
- package/dist/{gateway-CW-61lvs.d.ts → gateway-BqmcKam8.d.ts} +2 -2
- package/dist/gateway-main.js +4 -4
- package/dist/gateway.d.ts +3 -3
- package/dist/gateway.js +3 -3
- package/dist/index.js +8 -7
- package/dist/index.js.map +1 -1
- package/dist/{postgres-bridge-store-C9KG9Z69.d.ts → postgres-bridge-store-ChoOuFEY.d.ts} +1 -1
- package/dist/server.d.ts +0 -2
- package/dist/server.js +8 -7
- package/dist/{sqlite-edge-store-CdMIOrho.d.ts → sqlite-edge-store-BAFUeysk.d.ts} +1 -1
- package/dist/sqlite.d.ts +7 -3
- package/dist/sqlite.js +1 -1
- package/docs/architecture-v2.md +29 -15
- package/docs/decisions/0001-protocol-layers-and-acknowledgment-semantics.md +2 -1
- package/docs/decisions/0002-canonical-operation-contract-registry.md +6 -1
- package/docs/decisions/0005-retire-direct-supabase-runtime.md +52 -0
- package/docs/deployment.md +17 -12
- package/docs/ecosystem.md +6 -4
- package/docs/troubleshooting.md +15 -0
- package/llms.txt +3 -3
- package/openapi/agent-bridge-v2.openapi.json +3 -6
- package/package.json +3 -3
- package/schemas/agent-bridge-v2.capabilities.json +4 -5
- package/schemas/agent-bridge-v2.mcp.json +6 -12
- package/schemas/agent-bridge-v2.schema.json +12 -24
- package/dist/chunk-2EVLG3YA.js.map +0 -1
- package/dist/chunk-7VJI2MXI.js.map +0 -1
- package/dist/chunk-AWE3DFZV.js.map +0 -1
- package/dist/chunk-E4OWHGUE.js.map +0 -1
- package/dist/chunk-HUHG7XTB.js.map +0 -1
- package/dist/chunk-P635FAN4.js.map +0 -1
- package/dist/chunk-QPC6JHA3.js.map +0 -1
- package/dist/chunk-XDNT6ZNZ.js.map +0 -1
- package/dist/chunk-Z6JP6MYD.js +0 -584
- package/dist/chunk-Z6JP6MYD.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server.ts","../src/message-envelope.ts","../src/source-identity.ts"],"sourcesContent":["import { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ErrorCode,\n ListToolsRequestSchema,\n McpError,\n} from \"@modelcontextprotocol/sdk/types.js\";\n\nimport { normalizeReceiptId } from \"./atrib-receipt.js\";\nimport {\n buildMessageEnvelope,\n mergeEnvelopeMetadata,\n} from \"./message-envelope.js\";\nimport { resolveAgentIdentity, resolvePostSource } from \"./source-identity.js\";\nimport { BridgeService } from \"./bridge-service.js\";\nimport {\n BridgePrincipalMismatchError,\n BridgeValidationError,\n validateProject,\n validateMessageDraft,\n type BridgePrincipal,\n type MessageDraft,\n} from \"./bridge-domain.js\";\nimport { createStore } from \"./client-runtime.js\";\nimport { legacyContextMetadata, legacyNumericMessageId } from \"./legacy-compat.js\";\nimport {\n resolveClientConfig,\n type ClientConfig,\n type ClientEnvironment,\n type ClientProvider,\n} from \"./client-config.js\";\nimport {\n availableOperations,\n capabilityDocument,\n ContractValidationError,\n parseResponse,\n validateRequest,\n} from \"./contracts/registry.js\";\n\nexport interface AgentBridgeServerConfig {\n agent?: string;\n provider?: ClientProvider;\n workspace?: string;\n instance?: string;\n databasePath?: string;\n edgeDatabasePath?: string;\n cursorPath?: string;\n gatewayUrl?: string;\n gatewayToken?: string;\n}\n\nexport const MCP_IMPLEMENTATION_VERSION = \"2.0.0\";\n\nexport interface AgentBridgeServerEnv {\n AGENT_BRIDGE_URL?: string;\n AGENT_BRIDGE_KEY?: string;\n AGENT_BRIDGE_AGENT?: string;\n AGENT_BRIDGE_CONFIG?: string;\n HOME?: string;\n AGENT_BRIDGE_PROVIDER?: string;\n AGENT_BRIDGE_TOKEN?: string;\n AGENT_BRIDGE_WORKSPACE?: string;\n AGENT_BRIDGE_INSTANCE?: string;\n AGENT_BRIDGE_DB?: string;\n}\n\nexport function configFromEnv(\n env: AgentBridgeServerEnv = process.env,\n): AgentBridgeServerConfig {\n const client = resolveClientConfig(env as ClientEnvironment);\n return {\n provider: client.provider,\n agent: client.principal.agent,\n workspace: client.principal.workspace,\n instance: client.principal.instance,\n databasePath: client.databasePath,\n edgeDatabasePath: client.edgeDatabasePath,\n cursorPath: client.cursorPath,\n gatewayUrl: client.provider === \"gateway\" ? client.url : undefined,\n gatewayToken: client.provider === \"gateway\" ? client.credential : undefined,\n };\n}\n\nexport function createAgentBridgeServer(\n config: AgentBridgeServerConfig,\n): Server {\n const provider = config.provider ?? (config.gatewayToken ? \"gateway\" : \"local\");\n const principal: BridgePrincipal | undefined = config.agent ? {\n workspace: config.workspace ?? \"default\",\n agent: config.agent,\n instance: config.instance,\n } : undefined;\n const clientConfig: ClientConfig | undefined = principal ? {\n provider, principal,\n url: config.gatewayUrl, credential: config.gatewayToken,\n databasePath: config.databasePath ?? \":memory:\", edgeDatabasePath: config.edgeDatabasePath ?? config.databasePath ?? \":memory:\", cursorPath: config.cursorPath ?? \"\", configPath: \"\",\n } : undefined;\n const store = clientConfig ? createStore(clientConfig) : undefined;\n const service = store ? new BridgeService(store) : undefined;\n const server = new Server(\n { name: \"agent-bridge\", version: MCP_IMPLEMENTATION_VERSION },\n { capabilities: { tools: {} } },\n );\n\n server.setRequestHandler(ListToolsRequestSchema, async () => {\n const legacyTools = [\n {\n name: \"post_context\",\n description:\n \"Post a shared context entry visible to all agents. Categories: operational, config-change, goal-update, flag, bridge-meta (for suggesting improvements to the Agent Bridge itself).\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n source: {\n type: \"string\",\n description:\n \"Optional posting agent. Defaults to AGENT_BRIDGE_AGENT when configured; an explicit value must match it.\",\n },\n category: {\n type: \"string\",\n description:\n \"Entry type: operational | config-change | goal-update | flag | bridge-meta\",\n },\n content: {\n type: \"string\",\n description: \"The context message\",\n },\n priority: {\n type: \"string\",\n description: \"info (default) | high | urgent\",\n },\n project: {\n type: \"string\",\n description:\n \"Optional immutable message label. Omit for an unlabeled message.\",\n },\n metadata: {\n type: \"object\",\n description: \"Arbitrary structured data\",\n },\n message_id: {\n type: \"string\",\n description:\n \"Stable message id. Generated by the bridge when omitted.\",\n },\n target_agents: {\n type: \"array\",\n items: { type: \"string\" },\n description:\n \"Optional target agent names. Empty or omitted means broadcast.\",\n },\n thread_id: {\n type: \"string\",\n description: \"Optional conversation/thread id.\",\n },\n reply_to_id: {\n type: \"string\",\n description: \"Optional parent message id for reply threading.\",\n },\n kind: {\n type: \"string\",\n description:\n \"Message kind: operational | config-change | goal-update | flag | bridge-meta | handoff | request | result\",\n },\n payload_mime: {\n type: \"string\",\n description:\n \"Payload MIME type. Defaults to text/plain for the content column.\",\n },\n payload: {\n anyOf: [\n { type: \"object\" },\n { type: \"array\" },\n { type: \"string\" },\n { type: \"number\" },\n { type: \"boolean\" },\n { type: \"null\" },\n ],\n description:\n \"Optional structured payload stored in metadata.message_envelope.\",\n },\n payload_ref: {\n type: \"string\",\n description: \"Optional external blob pointer for large payloads.\",\n },\n payload_ciphertext: {\n type: \"string\",\n description:\n \"Optional inline encrypted payload for small encrypted messages.\",\n },\n informed_by: {\n type: \"array\",\n items: { type: \"string\" },\n description:\n \"Optional atrib record hashes (sha256:<64-hex>) this message depends on.\",\n },\n expires_at: {\n type: \"string\",\n description: \"Optional ISO timestamp retention boundary.\",\n },\n atrib_receipt_id: {\n type: \"string\",\n description:\n \"Optional. Signed atrib record receipt_id for the wrapper that signed this post_context call. Set automatically by an atrib-signing wrapper; consumers reading the row use this as the informed_by anchor for cross-process causal edges.\",\n },\n },\n required: [\"category\", \"content\"],\n },\n },\n {\n name: \"get_context\",\n description:\n \"Read shared context entries, newest first. Filter by source, category, project, or unacknowledged entries.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n since: {\n type: \"string\",\n description: \"ISO timestamp. Only entries after this time\",\n },\n source: {\n type: \"string\",\n description: \"Filter by posting agent\",\n },\n category: {\n type: \"string\",\n description: \"Filter by category\",\n },\n project: {\n type: \"string\",\n description: \"Filter by an exact project label\",\n },\n unacked_by: {\n type: \"string\",\n description:\n \"Only entries NOT yet acknowledged by this agent name. Defaults to AGENT_BRIDGE_AGENT when configured.\",\n },\n limit: {\n type: \"number\",\n description: \"Max entries to return (default 20)\",\n minimum: 1,\n maximum: 200,\n },\n target_agent: {\n type: \"string\",\n description:\n \"Return broadcast entries plus entries targeted to this agent.\",\n },\n thread_id: {\n type: \"string\",\n description: \"Filter by metadata.message_envelope.thread_id.\",\n },\n kind: {\n type: \"string\",\n description: \"Filter by metadata.message_envelope.kind.\",\n },\n },\n },\n outputSchema: {\n type: \"object\" as const,\n properties: {\n entries: { type: \"array\", items: { type: \"object\", additionalProperties: true } },\n source: { type: \"string\", enum: [\"remote\", \"cache\"] },\n stale: { type: \"boolean\" }, degraded: { type: \"boolean\" },\n acknowledgements: { type: \"string\", enum: [\"authoritative\", \"unknown\"] },\n lastSyncedAt: { type: [\"string\", \"null\"] },\n },\n required: [\"entries\"],\n additionalProperties: false,\n },\n },\n {\n name: \"ack_context\",\n description:\n \"Acknowledge context entries so they won't appear in unacked queries for this agent.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n ids: {\n type: \"array\",\n items: { anyOf: [{ type: \"number\" }, { type: \"string\" }] },\n description: \"Legacy numeric entry IDs or v2 UUID message IDs to acknowledge\",\n },\n agent: {\n type: \"string\",\n description:\n \"Optional acknowledging agent. Defaults to AGENT_BRIDGE_AGENT when configured; an explicit value must match it.\",\n },\n },\n required: [\"ids\"],\n },\n },\n ];\n const canonical = service ? availableOperations({ surface: \"mcp\", provider }).map((operation) => ({\n name: operation.mcp!.name,\n description: operation.summary,\n inputSchema: operation.request,\n outputSchema: operation.response,\n })) : [];\n return { tools: [...legacyTools, ...canonical] as any };\n });\n\n server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {\n const { name, arguments: args } = request.params;\n const canonicalResult = (operationId: string, value: unknown) => {\n const parsed = parseResponse(operationId, value);\n return {\n content: [{ type: \"text\" as const, text: JSON.stringify(parsed) }],\n ...(parsed !== null && typeof parsed === \"object\"\n ? { structuredContent: parsed as Record<string, unknown> }\n : {}),\n };\n };\n\n try {\n switch (name) {\n case \"capabilities\": {\n validateRequest(\"capabilities\", args ?? {});\n return canonicalResult(\"capabilities\", capabilityDocument({ surface: \"mcp\", provider }));\n }\n case \"post_context\": {\n let source: string | undefined;\n try {\n source = resolvePostSource(args?.source, config.agent);\n if (!source) {\n throw new Error(\n \"source is required when AGENT_BRIDGE_AGENT is not configured\",\n );\n }\n } catch (e) {\n throw new McpError(\n ErrorCode.InvalidParams,\n e instanceof Error ? e.message : \"source identity mismatch\",\n );\n }\n const project = validateProject(args?.project);\n const postArgs = { ...(args ?? {}), source, project };\n const receiptId = normalizeReceiptId(args?.atrib_receipt_id);\n const envelope = buildMessageEnvelope(postArgs, receiptId);\n const draft = validateMessageDraft({\n id: String(envelope.message_id),\n project,\n type: String(args?.kind ?? args?.category),\n content: String(args?.content ?? \"\"),\n contentType: String(args?.payload_mime ?? \"text/plain\"),\n data: args?.payload as MessageDraft[\"data\"],\n targets: Array.isArray(args?.target_agents) ? args.target_agents.map(String) : [],\n threadId: args?.thread_id as string | undefined,\n replyToId: args?.reply_to_id as string | undefined,\n priority: (args?.priority ?? \"info\") as MessageDraft[\"priority\"],\n expiresAt: args?.expires_at as string | undefined,\n atribReceiptId: receiptId,\n informedBy: Array.isArray(args?.informed_by) ? args.informed_by.map(String) : [],\n metadata: mergeEnvelopeMetadata(args?.metadata, envelope) as MessageDraft[\"metadata\"],\n });\n if (!service || !principal) throw new McpError(ErrorCode.InternalError, \"bridge provider is not configured\");\n const result = await service.publish(principal, draft);\n return { content: [{ type: \"text\", text: JSON.stringify(result) }], structuredContent: result as unknown as Record<string, unknown> };\n }\n\n case \"get_context\": {\n const project = validateProject(args?.project);\n const rawLimit = args?.limit;\n if (\n rawLimit !== undefined &&\n (typeof rawLimit !== \"number\" || !Number.isSafeInteger(rawLimit) || rawLimit < 1 || rawLimit > 200)\n ) {\n throw new McpError(ErrorCode.InvalidParams, \"limit must be between 1 and 200\");\n }\n const requestedLimit = rawLimit ?? 20;\n if (args?.unacked_by !== undefined && String(args.unacked_by) !== config.agent) {\n throw new McpError(ErrorCode.InvalidParams, \"unacked_by must equal the configured principal\");\n }\n if (service && principal) {\n if (!service || !principal) throw new McpError(ErrorCode.InternalError, \"bridge provider is not configured\");\n if (args?.target_agent && String(args.target_agent) !== principal.agent) {\n return { content: [{ type: \"text\", text: \"[]\" }], structuredContent: { entries: [] } };\n }\n const result = await service.history(principal, {\n limit: requestedLimit,\n types: args?.kind ? [String(args.kind)] : args?.category ? [String(args.category)] : undefined,\n source: args?.source ? String(args.source) : undefined,\n project,\n since: args?.since ? String(args.since) : undefined,\n receiptState: \"unread\",\n threadId: args?.thread_id ? String(args.thread_id) : undefined,\n latest: true,\n });\n const entries = result.messages\n .slice(0, requestedLimit)\n .map((message) => ({\n id: message.id,\n source: message.source,\n category: message.type,\n content: message.content,\n priority: message.priority,\n project: message.project ?? null,\n metadata: legacyContextMetadata(message),\n atrib_receipt_id: message.atribReceiptId ?? null,\n created_at: message.createdAt,\n }));\n const cachedResult = result as typeof result & {\n source?: \"remote\" | \"cache\";\n stale?: boolean;\n degraded?: boolean;\n acknowledgements?: \"authoritative\" | \"unknown\";\n lastSyncedAt?: string;\n };\n const cacheMetadata = cachedResult.source\n ? {\n source: cachedResult.source,\n stale: Boolean(cachedResult.stale),\n degraded: Boolean(cachedResult.degraded),\n acknowledgements: cachedResult.acknowledgements ?? \"authoritative\",\n lastSyncedAt: cachedResult.lastSyncedAt ?? null,\n }\n : {};\n return {\n content: [\n { type: \"text\", text: JSON.stringify(entries, null, 2) },\n ...(cachedResult.stale || cachedResult.degraded ? [{\n type: \"text\" as const,\n text: `WARNING: cached Agent Bridge context is ${cachedResult.stale ? \"stale\" : \"degraded\"}; acknowledgement authority is ${cachedResult.acknowledgements ?? \"unknown\"}.`,\n }] : []),\n ],\n structuredContent: { entries, ...cacheMetadata },\n };\n }\n throw new McpError(ErrorCode.InternalError, \"bridge provider is not configured\");\n }\n\n case \"ack_context\": {\n const ids = args?.ids as unknown[];\n let agent: string | undefined;\n try {\n agent = resolveAgentIdentity(args?.agent, config.agent);\n } catch (e) {\n throw new McpError(\n ErrorCode.InvalidParams,\n e instanceof Error ? e.message : \"agent identity mismatch\",\n );\n }\n if (!ids?.length || !agent) {\n throw new McpError(\n ErrorCode.InvalidParams,\n \"ids are required; agent is required when AGENT_BRIDGE_AGENT is not configured\",\n );\n }\n if (service && principal) {\n if (!service || !principal) throw new McpError(ErrorCode.InternalError, \"bridge provider is not configured\");\n const acknowledged = await service.acknowledge(\n principal,\n ids.map((id) => legacyNumericMessageId(id as string | number)),\n );\n return { content: [{ type: \"text\", text: JSON.stringify({ acknowledged, agent }) }], structuredContent: { acknowledged, agent } };\n }\n throw new McpError(ErrorCode.InternalError, \"bridge provider is not configured\");\n }\n\n case \"send\": {\n if (!service || !principal) throw new McpError(ErrorCode.InvalidParams, \"AGENT_BRIDGE_AGENT is required\");\n const input = validateRequest(\"publish_message\", args ?? {});\n try { resolvePostSource(input.source, principal.agent); } catch (error) { throw new McpError(ErrorCode.InvalidParams, error instanceof Error ? error.message : \"source identity mismatch\"); }\n const { source: _source, ...draft } = input;\n return canonicalResult(\"publish_message\", await service.publish(principal, draft as unknown as MessageDraft));\n }\n case \"history\": {\n if (!service || !principal) throw new McpError(ErrorCode.InvalidParams, \"AGENT_BRIDGE_AGENT is required\");\n const input = validateRequest(\"history\", args ?? {});\n return canonicalResult(\"history\", await service.history(principal, input));\n }\n case \"sync\": {\n if (!store?.sync) throw new McpError(ErrorCode.InvalidParams, \"sync is available only with the gateway provider\");\n const input = validateRequest(\"sync\", args ?? {});\n const result = await store.sync({\n maxPush: input.maxPush as number | undefined,\n maxPages: input.maxPages as number | undefined,\n signal: extra.signal,\n });\n return canonicalResult(\"sync\", result);\n }\n case \"claim\": {\n if (!service || !principal) throw new McpError(ErrorCode.InvalidParams, \"AGENT_BRIDGE_AGENT is required\");\n const input = validateRequest(\"claim_delivery\", args ?? {});\n const result = await service.claim(principal, {\n leaseMs: input.leaseMs as number | undefined,\n messageId: input.messageId as string | undefined,\n maxAttempts: input.maxAttempts as number | undefined,\n });\n return canonicalResult(\"claim_delivery\", result ?? { delivery: null });\n }\n case \"list_deliveries\": case \"list_delivery_events\": case \"cancel_delivery\": case \"requeue_delivery\": {\n if(!service||!principal) throw new McpError(ErrorCode.InvalidParams,\"AGENT_BRIDGE_AGENT is required\");\n const operationId = name === \"list_deliveries\" ? \"list_deliveries\" : name === \"list_delivery_events\" ? \"list_delivery_events\" : name === \"cancel_delivery\" ? \"cancel_delivery\" : \"requeue_delivery\";\n const input = validateRequest(operationId, args ?? {});\n const result=name===\"list_deliveries\"?await service.deliveries(principal,input as any):name===\"list_delivery_events\"?await service.deliveryEvents(principal,String(input.deliveryId),input as any):name===\"cancel_delivery\"?await service.cancel(principal,String(input.deliveryId)):await service.requeue(principal,String(input.deliveryId));\n return canonicalResult(operationId, name === \"list_deliveries\" || name === \"list_delivery_events\" ? result : { delivery: result });\n }\n case \"extend\": case \"acknowledge\": case \"negative_acknowledge\": {\n if (!service || !principal) throw new McpError(ErrorCode.InvalidParams, \"AGENT_BRIDGE_AGENT is required\");\n const operationId = name === \"extend\" ? \"extend_delivery\" : name === \"acknowledge\" ? \"acknowledge_delivery\" : \"negative_acknowledge_delivery\";\n const input = validateRequest(operationId, args ?? {});\n const id = String(input.deliveryId), token = String(input.leaseToken);\n const result = name === \"extend\" ? await service.extend(principal, id, token, input.leaseMs as number | undefined)\n : name === \"acknowledge\" ? await service.ack(principal, id, token)\n : await service.nack(\n principal,\n id,\n token,\n input.error as string,\n (input.disposition ?? input.dead ?? \"retry\") as \"retry\" | \"dead\" | boolean,\n input.retryPolicy,\n );\n return canonicalResult(operationId, { delivery: result });\n }\n case \"heartbeat\": {\n if (!service || !principal) throw new McpError(ErrorCode.InvalidParams, \"AGENT_BRIDGE_AGENT is required\");\n const input = validateRequest(\"heartbeat\", args ?? {});\n const result = await service.heartbeat(principal, {\n leaseMs: input.leaseMs as number | undefined,\n runtimeType: input.runtimeType as string | undefined,\n capabilities: input.capabilities as string[] | undefined,\n });\n return canonicalResult(\"heartbeat\", result);\n }\n case \"presence\": {\n if (!service || !principal) throw new McpError(ErrorCode.InvalidParams, \"AGENT_BRIDGE_AGENT is required\");\n validateRequest(\"presence\", args ?? {});\n const result = { agents: await service.presence(principal) };\n return canonicalResult(\"presence\", result);\n }\n\n default:\n throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);\n }\n } catch (error) {\n if (error instanceof McpError) throw error;\n if (error instanceof ContractValidationError || error instanceof BridgeValidationError || error instanceof BridgePrincipalMismatchError) {\n throw new McpError(ErrorCode.InvalidParams, error.message);\n }\n throw error;\n }\n });\n\n let initialization: Promise<void> | undefined;\n const initializeStore = () => initialization ??= clientConfig?.provider === \"gateway\"\n ? store?.initialize() ?? Promise.resolve()\n : Promise.resolve();\n let closure: Promise<void> | undefined;\n const closeStore = () => closure ??= store?.close?.() ?? Promise.resolve();\n const connect = server.connect.bind(server);\n server.connect = async (transport) => {\n await initializeStore();\n await connect(transport);\n };\n const close = server.close.bind(server);\n server.close = async () => {\n let transportError: unknown;\n try { await close(); } catch (error) { transportError = error; }\n try { await closeStore(); } catch (error) {\n if (transportError) throw Object.assign(new Error(\"failed to close Agent Bridge server\"), {\n errors: [transportError, error],\n });\n throw error;\n }\n if (transportError) throw transportError;\n };\n server.onclose = () => {\n void closeStore().catch((error) => server.onerror?.(error instanceof Error ? error : new Error(String(error))));\n };\n\n return server;\n}\n\nexport async function startServer(\n config: AgentBridgeServerConfig = configFromEnv(),\n) {\n const server = createAgentBridgeServer(config);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n","import { uuidv7 } from \"./bridge-domain.js\";\n\nexport const MESSAGE_ENVELOPE_SCHEMA = \"agent-bridge.message-envelope.v1\";\n\nconst RECORD_HASH_RE = /^sha256:[a-f0-9]{64}$/i;\n\ntype JsonRecord = Record<string, unknown>;\n\nfunction isRecord(value: unknown): value is JsonRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction normalizeString(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed ? trimmed : undefined;\n}\n\nfunction normalizeStringList(value: unknown): string[] | undefined {\n const raw = Array.isArray(value)\n ? value\n : typeof value === \"string\"\n ? value.split(\",\")\n : [];\n const seen = new Set<string>();\n for (const item of raw) {\n const normalized = normalizeString(item);\n if (normalized) seen.add(normalized);\n }\n return seen.size ? [...seen] : undefined;\n}\n\nfunction normalizeRecordHashes(value: unknown): string[] | undefined {\n const raw = Array.isArray(value)\n ? value\n : typeof value === \"string\"\n ? value.split(\",\")\n : [];\n const seen = new Set<string>();\n for (const item of raw) {\n const normalized = normalizeString(item);\n if (normalized && RECORD_HASH_RE.test(normalized)) {\n seen.add(normalized.toLowerCase());\n }\n }\n return seen.size ? [...seen] : undefined;\n}\n\nfunction normalizeIsoTimestamp(value: unknown): string | undefined {\n const text = normalizeString(value);\n if (!text) return undefined;\n const parsed = Date.parse(text);\n if (Number.isNaN(parsed)) return undefined;\n return new Date(parsed).toISOString();\n}\n\nexport function normalizeMetadata(value: unknown): JsonRecord {\n return isRecord(value) ? { ...value } : {};\n}\n\nexport function buildMessageEnvelope(\n args: JsonRecord | undefined,\n receiptId?: string\n): JsonRecord {\n const source = normalizeString(args?.source) ?? \"unknown\";\n const category = normalizeString(args?.category);\n const kind = normalizeString(args?.kind) ?? category ?? \"operational\";\n const messageId = normalizeString(args?.message_id) ?? uuidv7();\n\n const envelope: JsonRecord = {\n schema: MESSAGE_ENVELOPE_SCHEMA,\n message_id: messageId,\n source_agent: source,\n kind,\n priority: normalizeString(args?.priority) ?? \"info\",\n payload_mime: normalizeString(args?.payload_mime) ?? \"text/plain\",\n };\n\n const targetAgents = normalizeStringList(args?.target_agents);\n if (targetAgents) envelope.target_agents = targetAgents;\n\n const project = normalizeString(args?.project);\n if (project) envelope.project = project;\n\n const threadId = normalizeString(args?.thread_id);\n if (threadId) envelope.thread_id = threadId;\n\n const replyToId = normalizeString(args?.reply_to_id);\n if (replyToId) envelope.reply_to_id = replyToId;\n\n if (Object.prototype.hasOwnProperty.call(args ?? {}, \"payload\")) {\n envelope.payload = args?.payload;\n }\n\n const payloadRef = normalizeString(args?.payload_ref);\n if (payloadRef) envelope.payload_ref = payloadRef;\n\n const payloadCiphertext = normalizeString(args?.payload_ciphertext);\n if (payloadCiphertext) envelope.payload_ciphertext = payloadCiphertext;\n\n if (receiptId) envelope.atrib_receipt_id = receiptId;\n\n const informedBy = normalizeRecordHashes(args?.informed_by);\n if (informedBy) envelope.informed_by = informedBy;\n\n const expiresAt = normalizeIsoTimestamp(args?.expires_at);\n if (expiresAt) envelope.expires_at = expiresAt;\n\n return envelope;\n}\n\nexport function mergeEnvelopeMetadata(\n metadataInput: unknown,\n envelope: JsonRecord\n): JsonRecord {\n return {\n ...normalizeMetadata(metadataInput),\n message_envelope: envelope,\n };\n}\n\nfunction getEnvelope(row: unknown): JsonRecord | undefined {\n if (!isRecord(row)) return undefined;\n const metadata = row.metadata;\n if (!isRecord(metadata)) return undefined;\n const envelope = metadata.message_envelope;\n return isRecord(envelope) ? envelope : undefined;\n}\n\nexport function rowMatchesMessageFilters(\n row: unknown,\n filters: JsonRecord | undefined\n): boolean {\n const targetAgent = normalizeString(filters?.target_agent);\n const threadId = normalizeString(filters?.thread_id);\n const kind = normalizeString(filters?.kind);\n\n if (!targetAgent && !threadId && !kind) return true;\n\n const envelope = getEnvelope(row);\n if (!envelope) {\n return !threadId && !kind;\n }\n\n if (targetAgent) {\n const targets = normalizeStringList(envelope.target_agents);\n if (targets && !targets.includes(targetAgent)) return false;\n }\n\n if (threadId && normalizeString(envelope.thread_id) !== threadId) {\n return false;\n }\n\n if (kind && normalizeString(envelope.kind) !== kind) {\n return false;\n }\n\n return true;\n}\n\nexport function filterContextRows(\n rows: unknown,\n filters: JsonRecord | undefined,\n limit: number\n): unknown {\n if (!Array.isArray(rows)) return rows;\n return rows.filter((row) => rowMatchesMessageFilters(row, filters)).slice(0, limit);\n}\n","function normalizeSource(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed ? trimmed : undefined;\n}\n\nexport function resolveAgentIdentity(\n requestedAgent: unknown,\n configuredAgent: unknown,\n field = \"agent\",\n): string | undefined {\n const requested = normalizeSource(requestedAgent);\n const configured = normalizeSource(configuredAgent);\n\n if (requested && configured && requested !== configured) {\n throw new Error(\n `${field} must match AGENT_BRIDGE_AGENT (${configured}); got ${requested}`,\n );\n }\n\n return requested ?? configured;\n}\n\nexport function resolvePostSource(\n requestedSource: unknown,\n configuredAgent: unknown,\n): string | undefined {\n return resolveAgentIdentity(requestedSource, configuredAgent, \"source\");\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,cAAc;AACvB,SAAS,4BAA4B;AACrC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACLA,IAAM,0BAA0B;AAEvC,IAAM,iBAAiB;AAIvB,SAAS,SAAS,OAAqC;AACrD,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,gBAAgB,OAAoC;AAC3D,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,UAAU,MAAM,KAAK;AAC3B,SAAO,UAAU,UAAU;AAC7B;AAEA,SAAS,oBAAoB,OAAsC;AACjE,QAAM,MAAM,MAAM,QAAQ,KAAK,IAC3B,QACA,OAAO,UAAU,WACf,MAAM,MAAM,GAAG,IACf,CAAC;AACP,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,QAAQ,KAAK;AACtB,UAAM,aAAa,gBAAgB,IAAI;AACvC,QAAI,WAAY,MAAK,IAAI,UAAU;AAAA,EACrC;AACA,SAAO,KAAK,OAAO,CAAC,GAAG,IAAI,IAAI;AACjC;AAEA,SAAS,sBAAsB,OAAsC;AACnE,QAAM,MAAM,MAAM,QAAQ,KAAK,IAC3B,QACA,OAAO,UAAU,WACf,MAAM,MAAM,GAAG,IACf,CAAC;AACP,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,QAAQ,KAAK;AACtB,UAAM,aAAa,gBAAgB,IAAI;AACvC,QAAI,cAAc,eAAe,KAAK,UAAU,GAAG;AACjD,WAAK,IAAI,WAAW,YAAY,CAAC;AAAA,IACnC;AAAA,EACF;AACA,SAAO,KAAK,OAAO,CAAC,GAAG,IAAI,IAAI;AACjC;AAEA,SAAS,sBAAsB,OAAoC;AACjE,QAAM,OAAO,gBAAgB,KAAK;AAClC,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,MAAI,OAAO,MAAM,MAAM,EAAG,QAAO;AACjC,SAAO,IAAI,KAAK,MAAM,EAAE,YAAY;AACtC;AAEO,SAAS,kBAAkB,OAA4B;AAC5D,SAAO,SAAS,KAAK,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC;AAC3C;AAEO,SAAS,qBACd,MACA,WACY;AACZ,QAAM,SAAS,gBAAgB,MAAM,MAAM,KAAK;AAChD,QAAM,WAAW,gBAAgB,MAAM,QAAQ;AAC/C,QAAM,OAAO,gBAAgB,MAAM,IAAI,KAAK,YAAY;AACxD,QAAM,YAAY,gBAAgB,MAAM,UAAU,KAAK,OAAO;AAE9D,QAAM,WAAuB;AAAA,IAC3B,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,cAAc;AAAA,IACd;AAAA,IACA,UAAU,gBAAgB,MAAM,QAAQ,KAAK;AAAA,IAC7C,cAAc,gBAAgB,MAAM,YAAY,KAAK;AAAA,EACvD;AAEA,QAAM,eAAe,oBAAoB,MAAM,aAAa;AAC5D,MAAI,aAAc,UAAS,gBAAgB;AAE3C,QAAM,UAAU,gBAAgB,MAAM,OAAO;AAC7C,MAAI,QAAS,UAAS,UAAU;AAEhC,QAAM,WAAW,gBAAgB,MAAM,SAAS;AAChD,MAAI,SAAU,UAAS,YAAY;AAEnC,QAAM,YAAY,gBAAgB,MAAM,WAAW;AACnD,MAAI,UAAW,UAAS,cAAc;AAEtC,MAAI,OAAO,UAAU,eAAe,KAAK,QAAQ,CAAC,GAAG,SAAS,GAAG;AAC/D,aAAS,UAAU,MAAM;AAAA,EAC3B;AAEA,QAAM,aAAa,gBAAgB,MAAM,WAAW;AACpD,MAAI,WAAY,UAAS,cAAc;AAEvC,QAAM,oBAAoB,gBAAgB,MAAM,kBAAkB;AAClE,MAAI,kBAAmB,UAAS,qBAAqB;AAErD,MAAI,UAAW,UAAS,mBAAmB;AAE3C,QAAM,aAAa,sBAAsB,MAAM,WAAW;AAC1D,MAAI,WAAY,UAAS,cAAc;AAEvC,QAAM,YAAY,sBAAsB,MAAM,UAAU;AACxD,MAAI,UAAW,UAAS,aAAa;AAErC,SAAO;AACT;AAEO,SAAS,sBACd,eACA,UACY;AACZ,SAAO;AAAA,IACL,GAAG,kBAAkB,aAAa;AAAA,IAClC,kBAAkB;AAAA,EACpB;AACF;;;ACvHA,SAAS,gBAAgB,OAAoC;AAC3D,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,UAAU,MAAM,KAAK;AAC3B,SAAO,UAAU,UAAU;AAC7B;AAEO,SAAS,qBACd,gBACA,iBACA,QAAQ,SACY;AACpB,QAAM,YAAY,gBAAgB,cAAc;AAChD,QAAM,aAAa,gBAAgB,eAAe;AAElD,MAAI,aAAa,cAAc,cAAc,YAAY;AACvD,UAAM,IAAI;AAAA,MACR,GAAG,KAAK,mCAAmC,UAAU,UAAU,SAAS;AAAA,IAC1E;AAAA,EACF;AAEA,SAAO,aAAa;AACtB;AAEO,SAAS,kBACd,iBACA,iBACoB;AACpB,SAAO,qBAAqB,iBAAiB,iBAAiB,QAAQ;AACxE;;;AFwBO,IAAM,6BAA6B;AAenC,SAAS,cACd,MAA4B,QAAQ,KACX;AACzB,QAAM,SAAS,oBAAoB,GAAwB;AAC3D,SAAO;AAAA,IACL,UAAU,OAAO;AAAA,IACjB,OAAO,OAAO,UAAU;AAAA,IACxB,WAAW,OAAO,UAAU;AAAA,IAC5B,UAAU,OAAO,UAAU;AAAA,IAC3B,cAAc,OAAO;AAAA,IACrB,kBAAkB,OAAO;AAAA,IACzB,YAAY,OAAO;AAAA,IACnB,YAAY,OAAO,aAAa,YAAY,OAAO,MAAM;AAAA,IACzD,cAAc,OAAO,aAAa,YAAY,OAAO,aAAa;AAAA,EACpE;AACF;AAEO,SAAS,wBACd,QACQ;AACR,QAAM,WAAW,OAAO,aAAa,OAAO,eAAe,YAAY;AACvE,QAAM,YAAyC,OAAO,QAAQ;AAAA,IAC5D,WAAW,OAAO,aAAa;AAAA,IAC/B,OAAO,OAAO;AAAA,IACd,UAAU,OAAO;AAAA,EACnB,IAAI;AACJ,QAAM,eAAyC,YAAY;AAAA,IACzD;AAAA,IAAU;AAAA,IACV,KAAK,OAAO;AAAA,IAAY,YAAY,OAAO;AAAA,IAC3C,cAAc,OAAO,gBAAgB;AAAA,IAAY,kBAAkB,OAAO,oBAAoB,OAAO,gBAAgB;AAAA,IAAY,YAAY,OAAO,cAAc;AAAA,IAAI,YAAY;AAAA,EACpL,IAAI;AACJ,QAAM,QAAQ,eAAe,YAAY,YAAY,IAAI;AACzD,QAAM,UAAU,QAAQ,IAAI,cAAc,KAAK,IAAI;AACnD,QAAM,SAAS,IAAI;AAAA,IACjB,EAAE,MAAM,gBAAgB,SAAS,2BAA2B;AAAA,IAC5D,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,EAAE;AAAA,EAChC;AAEA,SAAO,kBAAkB,wBAAwB,YAAY;AAC3D,UAAM,cAAc;AAAA,MAClB;AAAA,QACE,MAAM;AAAA,QACN,aACE;AAAA,QACF,aAAa;AAAA,UACX,MAAM;AAAA,UACN,YAAY;AAAA,YACV,QAAQ;AAAA,cACN,MAAM;AAAA,cACN,aACE;AAAA,YACJ;AAAA,YACA,UAAU;AAAA,cACR,MAAM;AAAA,cACN,aACE;AAAA,YACJ;AAAA,YACA,SAAS;AAAA,cACP,MAAM;AAAA,cACN,aAAa;AAAA,YACf;AAAA,YACA,UAAU;AAAA,cACR,MAAM;AAAA,cACN,aAAa;AAAA,YACf;AAAA,YACA,SAAS;AAAA,cACP,MAAM;AAAA,cACN,aACE;AAAA,YACJ;AAAA,YACA,UAAU;AAAA,cACR,MAAM;AAAA,cACN,aAAa;AAAA,YACf;AAAA,YACA,YAAY;AAAA,cACV,MAAM;AAAA,cACN,aACE;AAAA,YACJ;AAAA,YACA,eAAe;AAAA,cACb,MAAM;AAAA,cACN,OAAO,EAAE,MAAM,SAAS;AAAA,cACxB,aACE;AAAA,YACJ;AAAA,YACA,WAAW;AAAA,cACT,MAAM;AAAA,cACN,aAAa;AAAA,YACf;AAAA,YACA,aAAa;AAAA,cACX,MAAM;AAAA,cACN,aAAa;AAAA,YACf;AAAA,YACA,MAAM;AAAA,cACJ,MAAM;AAAA,cACN,aACE;AAAA,YACJ;AAAA,YACA,cAAc;AAAA,cACZ,MAAM;AAAA,cACN,aACE;AAAA,YACJ;AAAA,YACA,SAAS;AAAA,cACP,OAAO;AAAA,gBACL,EAAE,MAAM,SAAS;AAAA,gBACjB,EAAE,MAAM,QAAQ;AAAA,gBAChB,EAAE,MAAM,SAAS;AAAA,gBACjB,EAAE,MAAM,SAAS;AAAA,gBACjB,EAAE,MAAM,UAAU;AAAA,gBAClB,EAAE,MAAM,OAAO;AAAA,cACjB;AAAA,cACA,aACE;AAAA,YACJ;AAAA,YACA,aAAa;AAAA,cACX,MAAM;AAAA,cACN,aAAa;AAAA,YACf;AAAA,YACA,oBAAoB;AAAA,cAClB,MAAM;AAAA,cACN,aACE;AAAA,YACJ;AAAA,YACA,aAAa;AAAA,cACX,MAAM;AAAA,cACN,OAAO,EAAE,MAAM,SAAS;AAAA,cACxB,aACE;AAAA,YACJ;AAAA,YACA,YAAY;AAAA,cACV,MAAM;AAAA,cACN,aAAa;AAAA,YACf;AAAA,YACA,kBAAkB;AAAA,cAChB,MAAM;AAAA,cACN,aACE;AAAA,YACJ;AAAA,UACF;AAAA,UACA,UAAU,CAAC,YAAY,SAAS;AAAA,QAClC;AAAA,MACF;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,aACE;AAAA,QACF,aAAa;AAAA,UACX,MAAM;AAAA,UACN,YAAY;AAAA,YACV,OAAO;AAAA,cACL,MAAM;AAAA,cACN,aAAa;AAAA,YACf;AAAA,YACA,QAAQ;AAAA,cACN,MAAM;AAAA,cACN,aAAa;AAAA,YACf;AAAA,YACA,UAAU;AAAA,cACR,MAAM;AAAA,cACN,aAAa;AAAA,YACf;AAAA,YACA,SAAS;AAAA,cACP,MAAM;AAAA,cACN,aAAa;AAAA,YACf;AAAA,YACA,YAAY;AAAA,cACV,MAAM;AAAA,cACN,aACE;AAAA,YACJ;AAAA,YACA,OAAO;AAAA,cACL,MAAM;AAAA,cACN,aAAa;AAAA,cACb,SAAS;AAAA,cACT,SAAS;AAAA,YACX;AAAA,YACA,cAAc;AAAA,cACZ,MAAM;AAAA,cACN,aACE;AAAA,YACJ;AAAA,YACA,WAAW;AAAA,cACT,MAAM;AAAA,cACN,aAAa;AAAA,YACf;AAAA,YACA,MAAM;AAAA,cACJ,MAAM;AAAA,cACN,aAAa;AAAA,YACf;AAAA,UACF;AAAA,QACF;AAAA,QACA,cAAc;AAAA,UACZ,MAAM;AAAA,UACN,YAAY;AAAA,YACV,SAAS,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,UAAU,sBAAsB,KAAK,EAAE;AAAA,YAChF,QAAQ,EAAE,MAAM,UAAU,MAAM,CAAC,UAAU,OAAO,EAAE;AAAA,YACpD,OAAO,EAAE,MAAM,UAAU;AAAA,YAAG,UAAU,EAAE,MAAM,UAAU;AAAA,YACxD,kBAAkB,EAAE,MAAM,UAAU,MAAM,CAAC,iBAAiB,SAAS,EAAE;AAAA,YACvE,cAAc,EAAE,MAAM,CAAC,UAAU,MAAM,EAAE;AAAA,UAC3C;AAAA,UACA,UAAU,CAAC,SAAS;AAAA,UACpB,sBAAsB;AAAA,QACxB;AAAA,MACF;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,aACE;AAAA,QACF,aAAa;AAAA,UACX,MAAM;AAAA,UACN,YAAY;AAAA,YACV,KAAK;AAAA,cACH,MAAM;AAAA,cACN,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,SAAS,GAAG,EAAE,MAAM,SAAS,CAAC,EAAE;AAAA,cACzD,aAAa;AAAA,YACf;AAAA,YACA,OAAO;AAAA,cACL,MAAM;AAAA,cACN,aACE;AAAA,YACJ;AAAA,UACF;AAAA,UACA,UAAU,CAAC,KAAK;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AACA,UAAM,YAAY,UAAU,oBAAoB,EAAE,SAAS,OAAO,SAAS,CAAC,EAAE,IAAI,CAAC,eAAe;AAAA,MAChG,MAAM,UAAU,IAAK;AAAA,MACrB,aAAa,UAAU;AAAA,MACvB,aAAa,UAAU;AAAA,MACvB,cAAc,UAAU;AAAA,IAC1B,EAAE,IAAI,CAAC;AACP,WAAO,EAAE,OAAO,CAAC,GAAG,aAAa,GAAG,SAAS,EAAS;AAAA,EACxD,CAAC;AAED,SAAO,kBAAkB,uBAAuB,OAAO,SAAS,UAAU;AACxE,UAAM,EAAE,MAAM,WAAW,KAAK,IAAI,QAAQ;AAC1C,UAAM,kBAAkB,CAAC,aAAqB,UAAmB;AAC/D,YAAM,SAAS,cAAc,aAAa,KAAK;AAC/C,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,MAAM,EAAE,CAAC;AAAA,QACjE,GAAI,WAAW,QAAQ,OAAO,WAAW,WACrC,EAAE,mBAAmB,OAAkC,IACvD,CAAC;AAAA,MACP;AAAA,IACF;AAEA,QAAI;AACF,cAAQ,MAAM;AAAA,QACd,KAAK,gBAAgB;AACnB,0BAAgB,gBAAgB,QAAQ,CAAC,CAAC;AAC1C,iBAAO,gBAAgB,gBAAgB,mBAAmB,EAAE,SAAS,OAAO,SAAS,CAAC,CAAC;AAAA,QACzF;AAAA,QACA,KAAK,gBAAgB;AACnB,cAAI;AACJ,cAAI;AACF,qBAAS,kBAAkB,MAAM,QAAQ,OAAO,KAAK;AACrD,gBAAI,CAAC,QAAQ;AACX,oBAAM,IAAI;AAAA,gBACR;AAAA,cACF;AAAA,YACF;AAAA,UACF,SAAS,GAAG;AACV,kBAAM,IAAI;AAAA,cACR,UAAU;AAAA,cACV,aAAa,QAAQ,EAAE,UAAU;AAAA,YACnC;AAAA,UACF;AACA,gBAAM,UAAU,gBAAgB,MAAM,OAAO;AAC7C,gBAAM,WAAW,EAAE,GAAI,QAAQ,CAAC,GAAI,QAAQ,QAAQ;AACpD,gBAAM,YAAY,mBAAmB,MAAM,gBAAgB;AAC3D,gBAAM,WAAW,qBAAqB,UAAU,SAAS;AACzD,gBAAM,QAAQ,qBAAqB;AAAA,YACjC,IAAI,OAAO,SAAS,UAAU;AAAA,YAC9B;AAAA,YACA,MAAM,OAAO,MAAM,QAAQ,MAAM,QAAQ;AAAA,YACzC,SAAS,OAAO,MAAM,WAAW,EAAE;AAAA,YACnC,aAAa,OAAO,MAAM,gBAAgB,YAAY;AAAA,YACtD,MAAM,MAAM;AAAA,YACZ,SAAS,MAAM,QAAQ,MAAM,aAAa,IAAI,KAAK,cAAc,IAAI,MAAM,IAAI,CAAC;AAAA,YAChF,UAAU,MAAM;AAAA,YAChB,WAAW,MAAM;AAAA,YACjB,UAAW,MAAM,YAAY;AAAA,YAC7B,WAAW,MAAM;AAAA,YACjB,gBAAgB;AAAA,YAChB,YAAY,MAAM,QAAQ,MAAM,WAAW,IAAI,KAAK,YAAY,IAAI,MAAM,IAAI,CAAC;AAAA,YAC/E,UAAU,sBAAsB,MAAM,UAAU,QAAQ;AAAA,UAC1D,CAAC;AACD,cAAI,CAAC,WAAW,CAAC,UAAW,OAAM,IAAI,SAAS,UAAU,eAAe,mCAAmC;AAC3G,gBAAM,SAAS,MAAM,QAAQ,QAAQ,WAAW,KAAK;AACrD,iBAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,MAAM,EAAE,CAAC,GAAG,mBAAmB,OAA6C;AAAA,QACtI;AAAA,QAEA,KAAK,eAAe;AAClB,gBAAM,UAAU,gBAAgB,MAAM,OAAO;AAC7C,gBAAM,WAAW,MAAM;AACvB,cACE,aAAa,WACZ,OAAO,aAAa,YAAY,CAAC,OAAO,cAAc,QAAQ,KAAK,WAAW,KAAK,WAAW,MAC/F;AACA,kBAAM,IAAI,SAAS,UAAU,eAAe,iCAAiC;AAAA,UAC/E;AACA,gBAAM,iBAAiB,YAAY;AACnC,cAAI,MAAM,eAAe,UAAa,OAAO,KAAK,UAAU,MAAM,OAAO,OAAO;AAC9E,kBAAM,IAAI,SAAS,UAAU,eAAe,gDAAgD;AAAA,UAC9F;AACA,cAAI,WAAW,WAAW;AACxB,gBAAI,CAAC,WAAW,CAAC,UAAW,OAAM,IAAI,SAAS,UAAU,eAAe,mCAAmC;AAC3G,gBAAI,MAAM,gBAAgB,OAAO,KAAK,YAAY,MAAM,UAAU,OAAO;AACvE,qBAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,CAAC,GAAG,mBAAmB,EAAE,SAAS,CAAC,EAAE,EAAE;AAAA,YACvF;AACA,kBAAM,SAAS,MAAM,QAAQ,QAAQ,WAAW;AAAA,cAC9C,OAAO;AAAA,cACP,OAAO,MAAM,OAAO,CAAC,OAAO,KAAK,IAAI,CAAC,IAAI,MAAM,WAAW,CAAC,OAAO,KAAK,QAAQ,CAAC,IAAI;AAAA,cACrF,QAAQ,MAAM,SAAS,OAAO,KAAK,MAAM,IAAI;AAAA,cAC7C;AAAA,cACA,OAAO,MAAM,QAAQ,OAAO,KAAK,KAAK,IAAI;AAAA,cAC1C,cAAc;AAAA,cACd,UAAU,MAAM,YAAY,OAAO,KAAK,SAAS,IAAI;AAAA,cACrD,QAAQ;AAAA,YACV,CAAC;AACD,kBAAM,UAAU,OAAO,SACpB,MAAM,GAAG,cAAc,EACvB,IAAI,CAAC,aAAa;AAAA,cACjB,IAAI,QAAQ;AAAA,cACZ,QAAQ,QAAQ;AAAA,cAChB,UAAU,QAAQ;AAAA,cAClB,SAAS,QAAQ;AAAA,cACjB,UAAU,QAAQ;AAAA,cAClB,SAAS,QAAQ,WAAW;AAAA,cAC5B,UAAU,sBAAsB,OAAO;AAAA,cACvC,kBAAkB,QAAQ,kBAAkB;AAAA,cAC5C,YAAY,QAAQ;AAAA,YACtB,EAAE;AACJ,kBAAM,eAAe;AAOrB,kBAAM,gBAAgB,aAAa,SAC/B;AAAA,cACE,QAAQ,aAAa;AAAA,cACrB,OAAO,QAAQ,aAAa,KAAK;AAAA,cACjC,UAAU,QAAQ,aAAa,QAAQ;AAAA,cACvC,kBAAkB,aAAa,oBAAoB;AAAA,cACnD,cAAc,aAAa,gBAAgB;AAAA,YAC7C,IACA,CAAC;AACL,mBAAO;AAAA,cACL,SAAS;AAAA,gBACP,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,SAAS,MAAM,CAAC,EAAE;AAAA,gBACvD,GAAI,aAAa,SAAS,aAAa,WAAW,CAAC;AAAA,kBACjD,MAAM;AAAA,kBACN,MAAM,2CAA2C,aAAa,QAAQ,UAAU,UAAU,kCAAkC,aAAa,oBAAoB,SAAS;AAAA,gBACxK,CAAC,IAAI,CAAC;AAAA,cACR;AAAA,cACA,mBAAmB,EAAE,SAAS,GAAG,cAAc;AAAA,YACjD;AAAA,UACF;AACA,gBAAM,IAAI,SAAS,UAAU,eAAe,mCAAmC;AAAA,QACjF;AAAA,QAEA,KAAK,eAAe;AAClB,gBAAM,MAAM,MAAM;AAClB,cAAI;AACJ,cAAI;AACF,oBAAQ,qBAAqB,MAAM,OAAO,OAAO,KAAK;AAAA,UACxD,SAAS,GAAG;AACV,kBAAM,IAAI;AAAA,cACR,UAAU;AAAA,cACV,aAAa,QAAQ,EAAE,UAAU;AAAA,YACnC;AAAA,UACF;AACA,cAAI,CAAC,KAAK,UAAU,CAAC,OAAO;AAC1B,kBAAM,IAAI;AAAA,cACR,UAAU;AAAA,cACV;AAAA,YACF;AAAA,UACF;AACA,cAAI,WAAW,WAAW;AACxB,gBAAI,CAAC,WAAW,CAAC,UAAW,OAAM,IAAI,SAAS,UAAU,eAAe,mCAAmC;AAC3G,kBAAM,eAAe,MAAM,QAAQ;AAAA,cACjC;AAAA,cACA,IAAI,IAAI,CAAC,OAAO,uBAAuB,EAAqB,CAAC;AAAA,YAC/D;AACA,mBAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,EAAE,cAAc,MAAM,CAAC,EAAE,CAAC,GAAG,mBAAmB,EAAE,cAAc,MAAM,EAAE;AAAA,UAClI;AACA,gBAAM,IAAI,SAAS,UAAU,eAAe,mCAAmC;AAAA,QACjF;AAAA,QAEA,KAAK,QAAQ;AACX,cAAI,CAAC,WAAW,CAAC,UAAW,OAAM,IAAI,SAAS,UAAU,eAAe,gCAAgC;AACxG,gBAAM,QAAQ,gBAAgB,mBAAmB,QAAQ,CAAC,CAAC;AAC3D,cAAI;AAAE,8BAAkB,MAAM,QAAQ,UAAU,KAAK;AAAA,UAAG,SAAS,OAAO;AAAE,kBAAM,IAAI,SAAS,UAAU,eAAe,iBAAiB,QAAQ,MAAM,UAAU,0BAA0B;AAAA,UAAG;AAC5L,gBAAM,EAAE,QAAQ,SAAS,GAAG,MAAM,IAAI;AACtC,iBAAO,gBAAgB,mBAAmB,MAAM,QAAQ,QAAQ,WAAW,KAAgC,CAAC;AAAA,QAC9G;AAAA,QACA,KAAK,WAAW;AACd,cAAI,CAAC,WAAW,CAAC,UAAW,OAAM,IAAI,SAAS,UAAU,eAAe,gCAAgC;AACxG,gBAAM,QAAQ,gBAAgB,WAAW,QAAQ,CAAC,CAAC;AACnD,iBAAO,gBAAgB,WAAW,MAAM,QAAQ,QAAQ,WAAW,KAAK,CAAC;AAAA,QAC3E;AAAA,QACA,KAAK,QAAQ;AACX,cAAI,CAAC,OAAO,KAAM,OAAM,IAAI,SAAS,UAAU,eAAe,kDAAkD;AAChH,gBAAM,QAAQ,gBAAgB,QAAQ,QAAQ,CAAC,CAAC;AAChD,gBAAM,SAAS,MAAM,MAAM,KAAK;AAAA,YAC9B,SAAS,MAAM;AAAA,YACf,UAAU,MAAM;AAAA,YAChB,QAAQ,MAAM;AAAA,UAChB,CAAC;AACD,iBAAO,gBAAgB,QAAQ,MAAM;AAAA,QACvC;AAAA,QACA,KAAK,SAAS;AACZ,cAAI,CAAC,WAAW,CAAC,UAAW,OAAM,IAAI,SAAS,UAAU,eAAe,gCAAgC;AACxG,gBAAM,QAAQ,gBAAgB,kBAAkB,QAAQ,CAAC,CAAC;AAC1D,gBAAM,SAAS,MAAM,QAAQ,MAAM,WAAW;AAAA,YAC5C,SAAS,MAAM;AAAA,YACf,WAAW,MAAM;AAAA,YACjB,aAAa,MAAM;AAAA,UACrB,CAAC;AACD,iBAAO,gBAAgB,kBAAkB,UAAU,EAAE,UAAU,KAAK,CAAC;AAAA,QACvE;AAAA,QACA,KAAK;AAAA,QAAmB,KAAK;AAAA,QAAwB,KAAK;AAAA,QAAmB,KAAK,oBAAoB;AACpG,cAAG,CAAC,WAAS,CAAC,UAAW,OAAM,IAAI,SAAS,UAAU,eAAc,gCAAgC;AACpG,gBAAM,cAAc,SAAS,oBAAoB,oBAAoB,SAAS,yBAAyB,yBAAyB,SAAS,oBAAoB,oBAAoB;AACjL,gBAAM,QAAQ,gBAAgB,aAAa,QAAQ,CAAC,CAAC;AACrD,gBAAM,SAAO,SAAO,oBAAkB,MAAM,QAAQ,WAAW,WAAU,KAAY,IAAE,SAAO,yBAAuB,MAAM,QAAQ,eAAe,WAAU,OAAO,MAAM,UAAU,GAAE,KAAY,IAAE,SAAO,oBAAkB,MAAM,QAAQ,OAAO,WAAU,OAAO,MAAM,UAAU,CAAC,IAAE,MAAM,QAAQ,QAAQ,WAAU,OAAO,MAAM,UAAU,CAAC;AAC7U,iBAAO,gBAAgB,aAAa,SAAS,qBAAqB,SAAS,yBAAyB,SAAS,EAAE,UAAU,OAAO,CAAC;AAAA,QACnI;AAAA,QACA,KAAK;AAAA,QAAU,KAAK;AAAA,QAAe,KAAK,wBAAwB;AAC9D,cAAI,CAAC,WAAW,CAAC,UAAW,OAAM,IAAI,SAAS,UAAU,eAAe,gCAAgC;AACxG,gBAAM,cAAc,SAAS,WAAW,oBAAoB,SAAS,gBAAgB,yBAAyB;AAC9G,gBAAM,QAAQ,gBAAgB,aAAa,QAAQ,CAAC,CAAC;AACrD,gBAAM,KAAK,OAAO,MAAM,UAAU,GAAG,QAAQ,OAAO,MAAM,UAAU;AACpE,gBAAM,SAAS,SAAS,WAAW,MAAM,QAAQ,OAAO,WAAW,IAAI,OAAO,MAAM,OAA6B,IAC7G,SAAS,gBAAgB,MAAM,QAAQ,IAAI,WAAW,IAAI,KAAK,IAC/D,MAAM,QAAQ;AAAA,YACd;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACL,MAAM,eAAe,MAAM,QAAQ;AAAA,YACpC,MAAM;AAAA,UACR;AACF,iBAAO,gBAAgB,aAAa,EAAE,UAAU,OAAO,CAAC;AAAA,QAC1D;AAAA,QACA,KAAK,aAAa;AAChB,cAAI,CAAC,WAAW,CAAC,UAAW,OAAM,IAAI,SAAS,UAAU,eAAe,gCAAgC;AACxG,gBAAM,QAAQ,gBAAgB,aAAa,QAAQ,CAAC,CAAC;AACrD,gBAAM,SAAS,MAAM,QAAQ,UAAU,WAAW;AAAA,YAChD,SAAS,MAAM;AAAA,YACf,aAAa,MAAM;AAAA,YACnB,cAAc,MAAM;AAAA,UACtB,CAAC;AACD,iBAAO,gBAAgB,aAAa,MAAM;AAAA,QAC5C;AAAA,QACA,KAAK,YAAY;AACf,cAAI,CAAC,WAAW,CAAC,UAAW,OAAM,IAAI,SAAS,UAAU,eAAe,gCAAgC;AACxG,0BAAgB,YAAY,QAAQ,CAAC,CAAC;AACtC,gBAAM,SAAS,EAAE,QAAQ,MAAM,QAAQ,SAAS,SAAS,EAAE;AAC3D,iBAAO,gBAAgB,YAAY,MAAM;AAAA,QAC3C;AAAA,QAEA;AACE,gBAAM,IAAI,SAAS,UAAU,gBAAgB,iBAAiB,IAAI,EAAE;AAAA,MACtE;AAAA,IACF,SAAS,OAAO;AACd,UAAI,iBAAiB,SAAU,OAAM;AACrC,UAAI,iBAAiB,2BAA2B,iBAAiB,yBAAyB,iBAAiB,8BAA8B;AACvI,cAAM,IAAI,SAAS,UAAU,eAAe,MAAM,OAAO;AAAA,MAC3D;AACA,YAAM;AAAA,IACR;AAAA,EACF,CAAC;AAED,MAAI;AACJ,QAAM,kBAAkB,MAAM,oCAAmB,cAAc,aAAa,YACxE,OAAO,WAAW,KAAK,QAAQ,QAAQ,IACvC,QAAQ,QAAQ;AACpB,MAAI;AACJ,QAAM,aAAa,MAAM,sBAAY,OAAO,QAAQ,KAAK,QAAQ,QAAQ;AACzE,QAAM,UAAU,OAAO,QAAQ,KAAK,MAAM;AAC1C,SAAO,UAAU,OAAO,cAAc;AACpC,UAAM,gBAAgB;AACtB,UAAM,QAAQ,SAAS;AAAA,EACzB;AACA,QAAM,QAAQ,OAAO,MAAM,KAAK,MAAM;AACtC,SAAO,QAAQ,YAAY;AACzB,QAAI;AACJ,QAAI;AAAE,YAAM,MAAM;AAAA,IAAG,SAAS,OAAO;AAAE,uBAAiB;AAAA,IAAO;AAC/D,QAAI;AAAE,YAAM,WAAW;AAAA,IAAG,SAAS,OAAO;AACxC,UAAI,eAAgB,OAAM,OAAO,OAAO,IAAI,MAAM,qCAAqC,GAAG;AAAA,QACxF,QAAQ,CAAC,gBAAgB,KAAK;AAAA,MAChC,CAAC;AACD,YAAM;AAAA,IACR;AACA,QAAI,eAAgB,OAAM;AAAA,EAC5B;AACA,SAAO,UAAU,MAAM;AACrB,SAAK,WAAW,EAAE,MAAM,CAAC,UAAU,OAAO,UAAU,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC,CAAC;AAAA,EAChH;AAEA,SAAO;AACT;AAEA,eAAsB,YACpB,SAAkC,cAAc,GAChD;AACA,QAAM,SAAS,wBAAwB,MAAM;AAC7C,QAAM,YAAY,IAAI,qBAAqB;AAC3C,QAAM,OAAO,QAAQ,SAAS;AAChC;","names":[]}
|
|
@@ -55,7 +55,7 @@ function asMessage(row) {
|
|
|
55
55
|
expiresAt: asTimestamp(row.expires_at),
|
|
56
56
|
idempotencyKey: row.idempotency_key ?? void 0,
|
|
57
57
|
atribReceiptId: row.atrib_receipt_id ?? void 0,
|
|
58
|
-
informedBy: parse(row.informed_by),
|
|
58
|
+
informedBy: parse(row.informed_by) ?? void 0,
|
|
59
59
|
metadata: parse(row.metadata),
|
|
60
60
|
deliveryPolicy,
|
|
61
61
|
createdAt: asTimestamp(row.created_at) ?? ""
|
|
@@ -618,4 +618,4 @@ var PostgresBridgeStore = class {
|
|
|
618
618
|
export {
|
|
619
619
|
PostgresBridgeStore
|
|
620
620
|
};
|
|
621
|
-
//# sourceMappingURL=chunk-
|
|
621
|
+
//# sourceMappingURL=chunk-CVZAJ7TP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/postgres-bridge-store.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport {\n DeliveryStateConflictError,\n decodeCursor,\n decodeScopedCursor,\n encodeCursor,\n encodeScopedCursor,\n cursorScope,\n scopedCursorScope,\n validateDeliveryCursorPosition,\n validateEventCursorPosition,\n type AgentPresence,\n type BridgeDelivery,\n type BridgeDeliveryEvent,\n type BridgeMessage,\n type BridgePrincipal,\n type DeliveryPolicy,\n} from \"./bridge-domain.js\";\nimport type {\n BridgeStore,\n BridgeDiagnostics,\n ClaimOptions,\n InsertMessageResult,\n MessagePage,\n MessageQuery,\n DeliveryQuery,\n} from \"./bridge-store.js\";\nimport { assertIdempotentReplay } from \"./idempotency.js\";\n\nexport interface PgQueryable {\n query<T extends Record<string, unknown> = Record<string, unknown>>(\n sql: string,\n values?: unknown[],\n ): Promise<{ rows: T[]; rowCount: number | null }>;\n connect?(): Promise<PgTransactionClient>;\n release?(): void;\n /** True when the queryable is already owned by an explicit request transaction. */\n inTransaction?: boolean;\n}\nexport interface PgTransactionClient {\n query<T extends Record<string, unknown> = Record<string, unknown>>(\n sql: string,\n values?: unknown[],\n ): Promise<{ rows: T[]; rowCount: number | null }>;\n release(error?: Error | boolean): void;\n}\n\ntype Row = Record<string, any>;\n\nfunction json(value: unknown): string | null {\n return value === undefined ? null : JSON.stringify(value);\n}\n\nfunction parse(value: unknown): any {\n return typeof value === \"string\" ? JSON.parse(value) : value;\n}\n\nfunction asTimestamp(value: unknown): string | undefined {\n if (value === undefined || value === null) return undefined;\n if (value instanceof Date) return value.toISOString();\n return String(value);\n}\n\nfunction asMessage(row: Row): BridgeMessage {\n const deliveryPolicy: DeliveryPolicy = row.delivery_mode === \"mailbox\"\n ? { mode: \"mailbox\" }\n : {\n mode: \"leased\",\n maxAttempts: Number(row.delivery_max_attempts),\n retryBaseDelayMs: Number(row.delivery_retry_base_delay_ms),\n retryMaxDelayMs: Number(row.delivery_retry_max_delay_ms),\n retryJitterRatio: Number(row.delivery_retry_jitter_ratio),\n ...(row.delivery_not_before ? { notBefore: asTimestamp(row.delivery_not_before) } : {}),\n };\n return {\n id: String(row.id),\n workspace: String(row.workspace),\n project: row.project ?? undefined,\n source: String(row.source),\n sequence: String(row.sequence),\n type: String(row.type),\n content: String(row.content),\n contentType: String(row.content_type),\n data: parse(row.data),\n targets: parse(row.targets) ?? [],\n threadId: row.thread_id ?? undefined,\n replyToId: row.reply_to_id ?? undefined,\n correlationId: row.correlation_id ?? undefined,\n causationId: row.causation_id ?? undefined,\n priority: row.priority,\n expiresAt: asTimestamp(row.expires_at),\n idempotencyKey: row.idempotency_key ?? undefined,\n atribReceiptId: row.atrib_receipt_id ?? undefined,\n informedBy: parse(row.informed_by) ?? undefined,\n metadata: parse(row.metadata),\n deliveryPolicy,\n createdAt: asTimestamp(row.created_at) ?? \"\",\n };\n}\n\nfunction asDelivery(row: Row): BridgeDelivery {\n return {\n id: String(row.id),\n messageId: String(row.message_id),\n workspace: String(row.workspace),\n recipient: String(row.recipient),\n state: row.state,\n attempt: Number(row.attempt),\n cycleAttempt: Number(row.cycle_attempt ?? row.attempt),\n requeueCount: Number(row.requeue_count ?? 0),\n createdAt: asTimestamp(row.created_at) ?? \"\",\n priorityRank: Number(row.priority_rank),\n availableAt: asTimestamp(row.available_at) ?? \"\",\n leaseToken: row.lease_token ?? undefined,\n leaseOwner: row.lease_owner ?? undefined,\n leaseExpiresAt: asTimestamp(row.lease_expires_at),\n lastError: row.last_error ?? undefined,\n lastActor: row.last_actor ?? undefined,\n lastAction: row.last_action,\n };\n}\n\nfunction asPresence(row: Row): AgentPresence {\n return {\n workspace: String(row.workspace), agent: String(row.agent), instance: String(row.instance),\n runtimeType: row.runtime_type ?? undefined, capabilities: parse(row.capabilities) ?? [],\n leaseExpiresAt: asTimestamp(row.lease_expires_at) ?? \"\", lastSeenAt: asTimestamp(row.last_seen_at) ?? \"\",\n };\n}\n\nfunction asDeliveryEvent(row: Row): BridgeDeliveryEvent {\n return {\n sequence: String(row.sequence), deliveryId: String(row.delivery_id),\n messageId: String(row.message_id), workspace: String(row.workspace),\n recipient: String(row.recipient),\n fromState: row.from_state == null ? undefined : row.from_state as BridgeDeliveryEvent[\"fromState\"],\n toState: row.to_state as BridgeDeliveryEvent[\"toState\"], attempt: Number(row.attempt),\n cycleAttempt: Number(row.cycle_attempt), requeueCount: Number(row.requeue_count),\n leaseOwner: row.lease_owner ?? undefined, error: row.error ?? undefined,\n actor: String(row.actor), action: row.action,\n createdAt: asTimestamp(row.created_at) ?? \"\",\n };\n}\n\nasync function transaction<T>(db: PgQueryable, work: (client: PgQueryable) => Promise<T>): Promise<T> {\n if (db.inTransaction) return work(db);\n const borrowed = !db.release && Boolean(db.connect);\n const client = borrowed ? await db.connect!() : db;\n try {\n await client.query(\"BEGIN\");\n const result = await work(client);\n await client.query(\"COMMIT\");\n return result;\n } catch (error) {\n await client.query(\"ROLLBACK\").catch(() => undefined);\n throw error;\n } finally {\n if (borrowed && \"release\" in client && typeof client.release === \"function\") client.release();\n }\n}\n\nexport class PostgresBridgeStore implements BridgeStore {\n constructor(private readonly db: PgQueryable) {}\n\n async initialize(): Promise<void> {\n // Deployments apply ordered migrations before starting the service.\n }\n\n async insertMessage(\n input: Omit<BridgeMessage, \"sequence\" | \"createdAt\">,\n ): Promise<InsertMessageResult> {\n const values = [\n input.id,\n input.workspace,\n input.project ?? null,\n input.source,\n input.type,\n input.content,\n input.contentType,\n json(input.data),\n json(input.targets),\n input.threadId ?? null,\n input.replyToId ?? null,\n input.correlationId ?? null,\n input.causationId ?? null,\n input.priority,\n input.expiresAt ?? null,\n input.idempotencyKey ?? null,\n input.atribReceiptId ?? null,\n json(input.informedBy),\n json(input.metadata),\n input.deliveryPolicy.mode,\n input.deliveryPolicy.mode === \"leased\" ? input.deliveryPolicy.maxAttempts : null,\n input.deliveryPolicy.mode === \"leased\" ? input.deliveryPolicy.retryBaseDelayMs : null,\n input.deliveryPolicy.mode === \"leased\" ? input.deliveryPolicy.retryMaxDelayMs : null,\n input.deliveryPolicy.mode === \"leased\" ? input.deliveryPolicy.retryJitterRatio : null,\n input.deliveryPolicy.mode === \"leased\" ? input.deliveryPolicy.notBefore ?? null : null,\n ];\n\n const result = await this.db.query<Row>(\n `WITH inserted AS (\n INSERT INTO agent_bridge.messages (\n id, workspace, project, source, type, content, content_type, data, targets,\n thread_id, reply_to_id, correlation_id, causation_id, priority,\n expires_at, idempotency_key, atrib_receipt_id, informed_by, metadata,\n delivery_mode, delivery_max_attempts, delivery_retry_base_delay_ms,\n delivery_retry_max_delay_ms, delivery_retry_jitter_ratio, delivery_not_before\n )\n VALUES (\n $1, $2, $3, $4, $5, $6, $7, $8::jsonb, $9::jsonb,\n $10, $11, $12, $13, $14, $15, $16, $17, $18::jsonb, $19::jsonb,\n $20, $21, $22, $23, $24, $25\n )\n ON CONFLICT (workspace, source, idempotency_key)\n WHERE idempotency_key IS NOT NULL\n DO NOTHING\n RETURNING *, true AS created\n ), selected AS (\n SELECT * FROM inserted\n UNION ALL\n SELECT existing.*, false AS created\n FROM agent_bridge.messages existing\n WHERE $16::text IS NOT NULL\n AND existing.workspace = $2\n AND existing.source = $4\n AND existing.idempotency_key = $16\n AND NOT EXISTS (SELECT 1 FROM inserted)\n LIMIT 1\n ), delivery_rows AS (\n INSERT INTO agent_bridge.deliveries (\n id, message_id, workspace, publisher, recipient, state, available_at,\n created_at, priority_rank, last_actor, last_action\n )\n SELECT gen_random_uuid(), inserted.id, inserted.workspace, inserted.source, target, 'pending',\n greatest(now(), coalesce(inserted.delivery_not_before, now())),\n inserted.created_at,\n case inserted.priority when 'urgent' then 0 when 'high' then 1 else 2 end,\n inserted.source, 'created'\n FROM inserted\n CROSS JOIN LATERAL jsonb_array_elements_text(inserted.targets) AS target\n WHERE inserted.delivery_mode = 'leased'\n ON CONFLICT (message_id, recipient) DO NOTHING\n )\n SELECT * FROM selected`,\n values,\n );\n\n let row = result.rows[0];\n if (!row && input.idempotencyKey) {\n const existing = await this.db.query<Row>(\n `SELECT *, false AS created\n FROM agent_bridge.messages\n WHERE workspace=$1 AND source=$2 AND idempotency_key=$3`,\n [input.workspace, input.source, input.idempotencyKey],\n );\n row = existing.rows[0];\n }\n if (!row) throw new Error(\"message insert did not return a row\");\n const message = asMessage(row);\n if (row.created !== true) assertIdempotentReplay(message, input);\n return { message, created: row.created === true };\n }\n\n async listMessages(\n principal: BridgePrincipal,\n query: MessageQuery = {},\n ): Promise<MessagePage> {\n const scope = cursorScope(principal, query);\n const cursor = decodeCursor(query.cursor, scope) ?? \"0\";\n const limit = Math.min(Math.max(Math.trunc(query.limit ?? 50), 1), 200);\n const boundary = query.latest ? undefined : await this.db.query<{ sequence: string | null }>(\n \"SELECT max(sequence)::text AS sequence FROM agent_bridge.messages WHERE workspace=$1\",\n [principal.workspace],\n );\n const highWater = boundary?.rows[0]?.sequence;\n const values: unknown[] = query.latest\n ? [principal.workspace, principal.agent]\n : [principal.workspace, cursor, principal.agent];\n const mailbox = query.mailbox ?? \"inbox\";\n const agentParam = query.latest ? 2 : 3;\n const visibility = mailbox === \"sent\" ? `source=$${agentParam}`\n : mailbox === \"all\" ? `(source=$${agentParam} OR targets='[]'::jsonb OR targets ? $${agentParam})`\n : `(targets='[]'::jsonb OR targets ? $${agentParam})`;\n let sql = `SELECT * FROM agent_bridge.messages WHERE workspace=$1 ${query.latest ? \"\" : \"AND sequence>$2::bigint \"}AND ${visibility}`;\n\n if (highWater) {\n values.push(highWater);\n sql += ` AND sequence <= $${values.length}::bigint`;\n }\n\n if (!query.includeExpired) {\n sql += \" AND (expires_at IS NULL OR expires_at > now())\";\n }\n if (query.types?.length) {\n values.push(query.types);\n sql += ` AND type = ANY($${values.length})`;\n }\n if (query.source) {\n values.push(query.source);\n sql += ` AND source = $${values.length}`;\n }\n if (query.project) {\n values.push(query.project);\n sql += ` AND project = $${values.length}`;\n }\n if (query.since) {\n values.push(query.since);\n sql += ` AND created_at >= $${values.length}::timestamptz`;\n }\n if (query.receiptState && query.receiptState !== \"any\") {\n sql += ` AND ${query.receiptState === \"unread\" ? \"NOT \" : \"\"}EXISTS (\n SELECT 1 FROM agent_bridge.receipts receipt\n WHERE receipt.workspace=agent_bridge.messages.workspace\n AND receipt.message_id=agent_bridge.messages.id\n AND receipt.principal=$${agentParam}\n )`;\n }\n if (query.threadId) {\n values.push(query.threadId);\n sql += ` AND thread_id = $${values.length}`;\n }\n\n values.push(limit);\n const result = await this.db.query<Row>(\n `${sql} ORDER BY sequence ${query.latest ? \"DESC\" : \"ASC\"} LIMIT $${values.length}`,\n values,\n );\n const messages = result.rows.map(asMessage);\n const last = messages[messages.length - 1];\n if (query.latest) return { messages, cursor: messages[0] ? encodeCursor(messages[0].sequence, scope) : query.cursor };\n if (messages.length === limit) return { messages, cursor: encodeCursor(last!.sequence, scope) };\n return { messages, cursor: highWater ? encodeCursor(highWater, scope) : query.cursor };\n }\n\n async recordReceipt(\n principal: BridgePrincipal,\n ids: string[],\n readAt = new Date(),\n ): Promise<number> {\n const result = await this.db.query(\n `INSERT INTO agent_bridge.receipts (workspace, message_id, principal, read_at)\n SELECT message.workspace, message.id, $3, $4\n FROM agent_bridge.messages message\n WHERE message.workspace = $1 AND message.id = ANY($2::uuid[])\n AND (message.targets='[]'::jsonb OR message.targets ? $3)\n ON CONFLICT DO NOTHING`,\n [principal.workspace, ids, principal.agent, readAt],\n );\n return result.rowCount ?? 0;\n }\n\n async claimDelivery(\n principal: BridgePrincipal,\n options: ClaimOptions,\n ): Promise<BridgeDelivery | null> {\n return transaction(this.db, async (db) => {\n await db.query(\n `UPDATE agent_bridge.deliveries delivery\n SET state='dead', last_error='message expired', lease_token=NULL,\n lease_owner=NULL, lease_expires_at=NULL,\n last_actor='agent-bridge', last_action='message_expired'\n FROM agent_bridge.messages message\n WHERE delivery.workspace=$1 AND delivery.recipient=$2\n AND ($3::uuid IS NULL OR delivery.message_id=$3)\n AND delivery.state IN ('pending','retrying','claimed')\n AND message.workspace=delivery.workspace AND message.id=delivery.message_id\n AND message.expires_at IS NOT NULL AND message.expires_at<=now()`,\n [principal.workspace, principal.agent, options.messageId ?? null],\n );\n await db.query(\n `UPDATE agent_bridge.deliveries delivery\n SET state='dead', last_error='maximum attempts reached', lease_token=NULL,\n lease_owner=NULL, lease_expires_at=NULL,\n last_actor='agent-bridge', last_action='attempts_exhausted'\n FROM agent_bridge.messages message\n WHERE delivery.workspace=$1 AND delivery.recipient=$2\n AND ($3::uuid IS NULL OR delivery.message_id=$3)\n AND message.workspace=delivery.workspace AND message.id=delivery.message_id\n AND delivery.cycle_attempt>=message.delivery_max_attempts\n AND (delivery.state IN ('pending','retrying')\n OR (delivery.state='claimed' AND delivery.lease_expires_at<=now()))`,\n [principal.workspace, principal.agent, options.messageId ?? null],\n );\n await db.query(\n `UPDATE agent_bridge.deliveries delivery\n SET state='retrying', available_at=now(), lease_token=NULL,\n lease_owner=NULL, lease_expires_at=NULL,\n last_error='lease expired', last_actor='agent-bridge', last_action='lease_expired'\n FROM agent_bridge.messages message\n WHERE delivery.workspace=$1 AND delivery.recipient=$2\n AND ($3::uuid IS NULL OR delivery.message_id=$3)\n AND message.workspace=delivery.workspace AND message.id=delivery.message_id\n AND delivery.state='claimed' AND delivery.lease_expires_at<=now()\n AND delivery.cycle_attempt<message.delivery_max_attempts`,\n [principal.workspace, principal.agent, options.messageId ?? null],\n );\n const candidate = await db.query<Row>(\n `SELECT delivery.id\n FROM agent_bridge.deliveries delivery\n JOIN agent_bridge.messages message\n ON message.workspace=delivery.workspace AND message.id=delivery.message_id\n WHERE delivery.workspace=$1 AND delivery.recipient=$2 AND ($3::uuid IS NULL OR delivery.message_id=$3)\n AND delivery.state IN ('pending','retrying')\n AND delivery.available_at<=now()\n AND delivery.cycle_attempt<message.delivery_max_attempts\n AND (message.expires_at IS NULL OR message.expires_at>now())\n ORDER BY delivery.priority_rank, delivery.available_at, delivery.created_at, delivery.id\n FOR UPDATE OF delivery SKIP LOCKED\n LIMIT 1`,\n [principal.workspace, principal.agent, options.messageId ?? null],\n );\n if (!candidate.rows[0]) return null;\n const token = randomUUID();\n const owner = principal.instance ?? principal.agent;\n const claimed = await db.query<Row>(\n `UPDATE agent_bridge.deliveries\n SET state='claimed', attempt=attempt+1, cycle_attempt=cycle_attempt+1,\n lease_token=$1, lease_owner=$2,\n lease_expires_at=now()+($3*interval '1 millisecond'),\n last_error=NULL, last_actor=$4, last_action='claim'\n WHERE id=$5\n RETURNING *`,\n [token, owner, options.leaseMs, principal.agent, candidate.rows[0].id],\n );\n return asDelivery(claimed.rows[0]!);\n });\n }\n\n async renewDelivery(\n principal: BridgePrincipal,\n id: string,\n token: string,\n leaseMs: number,\n ): Promise<BridgeDelivery | null> {\n const result = await this.db.query<Row>(\n `UPDATE agent_bridge.deliveries\n SET lease_expires_at=now() + ($1 * interval '1 millisecond')\n WHERE workspace=$2 AND recipient=$3 AND lease_owner=$4 AND id=$5 AND lease_token=$6\n AND state='claimed' AND lease_expires_at>now()\n RETURNING *`,\n [leaseMs, principal.workspace, principal.agent, principal.instance ?? principal.agent, id, token],\n );\n return result.rows[0] ? asDelivery(result.rows[0]) : null;\n }\n\n async settleDelivery(\n principal: BridgePrincipal,\n id: string,\n token: string,\n state: \"acked\" | \"retrying\" | \"dead\",\n error?: string,\n _retryPolicy?: import(\"./bridge-domain.js\").RetryPolicy,\n ): Promise<BridgeDelivery | null> {\n const result = await this.db.query<Row>(\n `UPDATE agent_bridge.deliveries delivery\n SET state=CASE\n WHEN $1='retrying' AND cycle_attempt>=message.delivery_max_attempts THEN 'dead'\n ELSE $1\n END,\n available_at=CASE\n WHEN $1='retrying' AND cycle_attempt<message.delivery_max_attempts THEN\n now() + (\n LEAST(message.delivery_retry_max_delay_ms::double precision,\n message.delivery_retry_base_delay_ms::double precision * power(2, GREATEST(cycle_attempt - 1, 0)))\n * (1 + ((random() * 2) - 1) * message.delivery_retry_jitter_ratio)\n * interval '1 millisecond'\n )\n ELSE available_at\n END,\n last_error=$2, lease_token=NULL, lease_owner=NULL, lease_expires_at=NULL,\n last_actor=$4,\n last_action=CASE\n WHEN $1='acked' THEN 'ack'\n WHEN $1='dead' THEN 'nack_dead'\n WHEN cycle_attempt>=message.delivery_max_attempts THEN 'attempts_exhausted'\n ELSE 'nack_retry'\n END\n FROM agent_bridge.messages message\n WHERE delivery.workspace=$3 AND delivery.recipient=$4 AND delivery.lease_owner=$5\n AND message.workspace=delivery.workspace AND message.id=delivery.message_id\n AND delivery.id=$6 AND delivery.lease_token=$7 AND delivery.state='claimed' AND delivery.lease_expires_at>now()\n RETURNING delivery.*`,\n [\n state,\n error?.slice(0, 1024) ?? null,\n principal.workspace,\n principal.agent,\n principal.instance ?? principal.agent,\n id,\n token,\n ],\n );\n return result.rows[0] ? asDelivery(result.rows[0]) : null;\n }\n\n async listDeliveries(principal: BridgePrincipal, query: DeliveryQuery = {}) {\n const filters = {\n role: query.role ?? \"all\",\n states: [...(query.states ?? [])].sort(),\n messageId: query.messageId ?? null,\n recipient: query.recipient ?? null,\n };\n const scope = scopedCursorScope(\"deliveries\", principal, filters);\n const boundary = validateDeliveryCursorPosition(decodeScopedCursor(query.cursor, scope));\n const createdAt = boundary?.createdAt;\n const id = boundary?.id;\n const limit = query.limit ?? 50;\n const values: unknown[] = [principal.workspace, principal.agent];\n const clauses = [\"delivery.workspace=$1\"];\n const role = query.role ?? \"all\";\n clauses.push(role === \"recipient\" ? \"delivery.recipient=$2\" : role === \"publisher\" ? \"message.source=$2\" : \"(delivery.recipient=$2 OR message.source=$2)\");\n if (createdAt && id) {\n values.push(createdAt, id);\n clauses.push(`(delivery.created_at,delivery.id)>($${values.length - 1}::timestamptz,$${values.length}::uuid)`);\n }\n if (query.messageId) { values.push(query.messageId); clauses.push(`delivery.message_id=$${values.length}`); }\n if (query.recipient) { values.push(query.recipient); clauses.push(`delivery.recipient=$${values.length}`); }\n if (query.states?.length) { values.push(query.states); clauses.push(`delivery.state=ANY($${values.length}::text[])`); }\n values.push(limit);\n const result = await this.db.query<Row>(\n `SELECT delivery.* FROM agent_bridge.deliveries delivery\n JOIN agent_bridge.messages message ON message.workspace=delivery.workspace AND message.id=delivery.message_id\n WHERE ${clauses.join(\" AND \")}\n ORDER BY delivery.created_at,delivery.id LIMIT $${values.length}`,\n values,\n );\n const deliveries = result.rows.map(asDelivery);\n const last = deliveries[deliveries.length - 1];\n return { deliveries, cursor: deliveries.length === limit && last ? encodeScopedCursor(scope, { createdAt: last.createdAt, id: last.id }) : undefined };\n }\n\n async listDeliveryEvents(principal: BridgePrincipal, id: string, query: { cursor?: string; limit?: number } = {}) {\n const limit = Math.min(Math.max(query.limit ?? 50, 1), 200);\n const scope = scopedCursorScope(\"delivery-events\", principal, { deliveryId: id });\n const position = validateEventCursorPosition(decodeScopedCursor(query.cursor, scope));\n const result = await this.db.query<Row>(\n `SELECT event.* FROM agent_bridge.delivery_events event\n JOIN agent_bridge.messages message ON message.workspace=event.workspace AND message.id=event.message_id\n WHERE event.workspace=$1 AND event.delivery_id=$2 AND event.sequence>$3::bigint\n AND (event.recipient=$4 OR message.source=$4)\n ORDER BY event.sequence LIMIT $5`,\n [principal.workspace, id, position ?? \"0\", principal.agent, limit],\n );\n const events = result.rows.map(asDeliveryEvent);\n const last = events[events.length - 1];\n return { events, cursor: events.length === limit && last ? encodeScopedCursor(scope, last.sequence) : undefined };\n }\n\n async cancelDelivery(principal: BridgePrincipal, id: string) {\n return transaction(this.db, async (db) => {\n const visible = await db.query<Row>(\n `SELECT delivery.* FROM agent_bridge.deliveries delivery\n JOIN agent_bridge.messages message ON message.workspace=delivery.workspace AND message.id=delivery.message_id\n WHERE delivery.id=$1 AND delivery.workspace=$2 AND message.source=$3 FOR UPDATE OF delivery`,\n [id, principal.workspace, principal.agent],\n );\n const current = visible.rows[0];\n if (!current) return null;\n if (current.state === \"cancelled\") return asDelivery(current);\n if (![\"pending\", \"retrying\", \"claimed\"].includes(current.state)) {\n throw new DeliveryStateConflictError(`cannot cancel a ${current.state} delivery`);\n }\n const result = await db.query<Row>(\n `UPDATE agent_bridge.deliveries SET state='cancelled', lease_token=NULL,\n lease_owner=NULL, lease_expires_at=NULL, last_error=NULL,\n last_actor=$1, last_action='cancel' WHERE id=$2 RETURNING *`,\n [principal.agent, id],\n );\n return asDelivery(result.rows[0]!);\n });\n }\n\n async requeueDelivery(principal: BridgePrincipal, id: string) {\n return transaction(this.db, async (db) => {\n const visible = await db.query<Row>(\n `SELECT delivery.*,message.expires_at,message.delivery_not_before\n FROM agent_bridge.deliveries delivery\n JOIN agent_bridge.messages message ON message.workspace=delivery.workspace AND message.id=delivery.message_id\n WHERE delivery.id=$1 AND delivery.workspace=$2 AND message.source=$3 FOR UPDATE OF delivery`,\n [id, principal.workspace, principal.agent],\n );\n const current = visible.rows[0];\n if (!current) return null;\n if (![\"dead\", \"cancelled\"].includes(current.state)) {\n throw new DeliveryStateConflictError(`cannot requeue a ${current.state} delivery`);\n }\n if (current.expires_at && new Date(current.expires_at).getTime() <= Date.now()) {\n throw new DeliveryStateConflictError(\"cannot requeue an expired message\");\n }\n const result = await db.query<Row>(\n `UPDATE agent_bridge.deliveries SET state='pending',\n available_at=greatest(now(),coalesce($1::timestamptz,now())),\n cycle_attempt=0,requeue_count=requeue_count+1,\n lease_token=NULL,lease_owner=NULL,lease_expires_at=NULL,last_error=NULL,\n last_actor=$2,last_action='requeue' WHERE id=$3 RETURNING *`,\n [current.delivery_not_before, principal.agent, id],\n );\n return asDelivery(result.rows[0]!);\n });\n }\n\n async diagnostics(principal: BridgePrincipal): Promise<BridgeDiagnostics> {\n const result = await this.db.query<Row>(\n `SELECT\n count(*) FILTER (WHERE state='pending')::integer AS pending,\n count(*) FILTER (WHERE state='claimed')::integer AS claimed,\n count(*) FILTER (WHERE state='retrying')::integer AS retrying,\n count(*) FILTER (WHERE state='dead')::integer AS dead,\n count(*) FILTER (WHERE state='cancelled')::integer AS cancelled,\n min(available_at) FILTER (WHERE state IN ('pending','retrying')) AS oldest_available,\n count(*) FILTER (WHERE state IN ('pending','retrying') AND available_at<=now())::integer AS due,\n count(*) FILTER (WHERE state IN ('pending','retrying') AND available_at>now())::integer AS scheduled,\n count(*) FILTER (WHERE state='claimed' AND lease_expires_at<=now())::integer AS expired_leases,\n min(available_at) FILTER (WHERE state IN ('pending','retrying') AND available_at<=now()) AS oldest_due,\n coalesce(greatest(0,extract(epoch FROM (now()-min(available_at) FILTER (WHERE state IN ('pending','retrying') AND available_at<=now())))*1000),0)::bigint AS queue_lag_ms\n FROM agent_bridge.deliveries WHERE workspace=$1 AND recipient=$2`,\n [principal.workspace, principal.agent],\n );\n const queue = result.rows[0] ?? {};\n return {\n schemaVersion: \"postgres-v2\",\n deliverySupported: true,\n pending: Number(queue.pending ?? 0),\n claimed: Number(queue.claimed ?? 0),\n retrying: Number(queue.retrying ?? 0),\n dead: Number(queue.dead ?? 0),\n cancelled: Number(queue.cancelled ?? 0),\n oldestAvailableAt: asTimestamp(queue.oldest_available),\n due: Number(queue.due ?? 0),\n scheduled: Number(queue.scheduled ?? 0),\n expiredLeases: Number(queue.expired_leases ?? 0),\n oldestDueAt: asTimestamp(queue.oldest_due),\n queueLagMs: Number(queue.queue_lag_ms ?? 0),\n };\n }\n\n async heartbeat(principal: BridgePrincipal, leaseMs: number, runtimeType?: string, capabilities: string[] = []): Promise<AgentPresence> {\n await this.db.query(\n \"DELETE FROM agent_bridge.agent_instances WHERE workspace=$1 AND lease_expires_at<=now()\",\n [principal.workspace],\n );\n const result = await this.db.query<Row>(\n `WITH locked AS (\n SELECT pg_advisory_xact_lock(hashtextextended($1, 0))\n )\n INSERT INTO agent_bridge.agent_instances (workspace,agent,instance,runtime_type,capabilities,lease_expires_at,last_seen_at)\n SELECT $1,$2,$3,$4,$5::jsonb,now() + ($6 * interval '1 millisecond'),now()\n FROM locked\n WHERE EXISTS (\n SELECT 1 FROM agent_bridge.agent_instances\n WHERE workspace=$1 AND agent=$2 AND instance=$3\n ) OR ((\n SELECT count(*) < 128 FROM agent_bridge.agent_instances\n WHERE workspace=$1 AND agent=$2\n ) AND (\n SELECT count(*) < 4096 FROM agent_bridge.agent_instances\n WHERE workspace=$1\n )\n )\n ON CONFLICT (workspace,agent,instance) DO UPDATE SET runtime_type=excluded.runtime_type,capabilities=excluded.capabilities,lease_expires_at=excluded.lease_expires_at,last_seen_at=excluded.last_seen_at\n RETURNING *`,\n [principal.workspace, principal.agent, principal.instance, runtimeType ?? null, JSON.stringify(capabilities), leaseMs],\n );\n if (!result.rows[0]) {\n throw Object.assign(new Error(\"active instance limit reached\"), {\n status: 429,\n code: \"presence_limit\",\n });\n }\n return asPresence(result.rows[0]!);\n }\n\n async listPresence(principal: BridgePrincipal): Promise<AgentPresence[]> {\n await this.db.query(\n \"DELETE FROM agent_bridge.agent_instances WHERE workspace=$1 AND lease_expires_at<=now()\",\n [principal.workspace],\n );\n const result = await this.db.query<Row>(\n \"SELECT * FROM agent_bridge.agent_instances WHERE workspace=$1 ORDER BY agent,instance\",\n [principal.workspace],\n );\n return result.rows.map(asPresence);\n }\n\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
BridgeService
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-4V2PFJEF.js";
|
|
5
5
|
import {
|
|
6
6
|
ContractResponseError,
|
|
7
7
|
ContractValidationError,
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
parseResponse,
|
|
17
17
|
validateRequest,
|
|
18
18
|
validateRequestForProtocol
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-62C63PIE.js";
|
|
20
20
|
import {
|
|
21
21
|
BridgePrincipalMismatchError,
|
|
22
22
|
BridgeValidationError
|
|
@@ -259,6 +259,10 @@ function createGateway(options) {
|
|
|
259
259
|
const requestBody = () => parsedBody ?? (parsedBody = jsonBody(req, limit, abort.signal));
|
|
260
260
|
const dispatch = async (authority, response = res) => {
|
|
261
261
|
const url = new URL(req.url ?? "/", "http://gateway.invalid");
|
|
262
|
+
if (req.method === "GET" && url.pathname === "/healthz") {
|
|
263
|
+
send(response, 200, { status: "alive" }, requestId);
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
262
266
|
if (req.method === "GET" && url.pathname === "/readyz") {
|
|
263
267
|
let ready = false;
|
|
264
268
|
try {
|
|
@@ -594,4 +598,4 @@ export {
|
|
|
594
598
|
safeTokenHashEqual,
|
|
595
599
|
createGateway
|
|
596
600
|
};
|
|
597
|
-
//# sourceMappingURL=chunk-
|
|
601
|
+
//# sourceMappingURL=chunk-FGERNG4X.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/gateway.ts","../src/gateway-auth.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport { BridgePrincipalMismatchError, BridgeValidationError, type MessageDraft } from \"./bridge-domain.js\";\nimport { BridgeService } from \"./bridge-service.js\";\nimport type { BridgeStore } from \"./bridge-store.js\";\nimport { bearerToken, hashCredential, type CredentialResolver } from \"./gateway-auth.js\";\nimport type { GatewaySecurity } from \"./gateway-security.js\";\nimport type { RequestAuthority, RequestAuthorityContext } from \"./postgres-request-authority.js\";\nimport {\n capabilityDocument,\n ContractResponseError,\n ContractValidationError,\n LEGACY_PROTOCOL_VERSION,\n negotiateProtocolVersion,\n operationContract,\n parseResponse,\n PROTOCOL_HEADER,\n PROTOCOL_VERSION,\n SUPPORTED_PROTOCOL_HEADER,\n SUPPORTED_PROTOCOL_VERSIONS,\n type OperationId,\n validateRequest,\n validateRequestForProtocol,\n} from \"./contracts/registry.js\";\n\nexport interface GatewayOptions {\n store: BridgeStore;\n credentials: CredentialResolver;\n security: GatewaySecurity;\n allowedOrigins?: string[];\n bodyLimitBytes?: number;\n requestDeadlineMs?: number;\n ready?: () => Promise<boolean>;\n /** Reports whether the configured database has verified row isolation. */\n rowIsolationReady?: () => Promise<boolean>;\n /** Production PostgreSQL request authority. Other providers omit this. */\n requestAuthority?: RequestAuthority;\n}\n\ntype Metrics = { requests: number; errors: number; timeouts: number; authFailures: number };\nconst jsonHeaders = { \"content-type\": \"application/json; charset=utf-8\", \"cache-control\": \"no-store\" };\n\ninterface ResponseWriter {\n readonly writableEnded: boolean;\n getHeader(name: string): string | number | readonly string[] | undefined;\n setHeader(name: string, value: string | number | readonly string[]): unknown;\n writeHead(status: number, headers?: any): unknown;\n end(chunk?: any): unknown;\n}\n\nclass BufferedResponse implements ResponseWriter {\n private readonly headers = new Map<string, string | number | readonly string[]>();\n private status: number | undefined;\n private headHeaders: any;\n private body: any;\n\n constructor(private readonly target: ServerResponse) {}\n get writableEnded(): boolean { return this.body !== undefined; }\n getHeader(name: string) { return this.headers.get(name.toLowerCase()) ?? this.target.getHeader(name); }\n setHeader(name: string, value: string | number | readonly string[]) { this.headers.set(name.toLowerCase(), value); return this; }\n writeHead(status: number, headers?: any) {\n this.status = status;\n this.headHeaders = headers;\n return this;\n }\n end(chunk?: any) { this.body = chunk ?? null; return this; }\n flush(): void {\n if (this.target.writableEnded) return;\n for (const [name, value] of this.headers) this.target.setHeader(name, value);\n if (this.status !== undefined) this.target.writeHead(this.status, this.headHeaders);\n if (this.body !== undefined) this.target.end(this.body);\n }\n}\n\nfunction send(res: ResponseWriter, status: number, value: unknown, requestId: string): void {\n if (res.writableEnded) return;\n res.writeHead(status, {\n ...jsonHeaders,\n \"x-request-id\": requestId,\n });\n res.end(JSON.stringify(value));\n}\n\nfunction sendOperation(res: ResponseWriter, status: number, operation: string, value: unknown, requestId: string): void {\n const canonical = parseResponse(operation, value) as Record<string, unknown>;\n const protocolVersion = String(res.getHeader(PROTOCOL_HEADER) ?? PROTOCOL_VERSION);\n if (protocolVersion !== LEGACY_PROTOCOL_VERSION) {\n send(res, status, canonical, requestId);\n return;\n }\n if (operation === \"claim_delivery\") {\n send(res, status, canonical.delivery === null ? null : canonical, requestId);\n return;\n }\n if ([\"cancel_delivery\", \"requeue_delivery\", \"extend_delivery\", \"acknowledge_delivery\", \"negative_acknowledge_delivery\"].includes(operation)) {\n send(res, status, canonical.delivery, requestId);\n return;\n }\n send(res, status, canonical, requestId);\n}\n\nfunction failure(\n res: ResponseWriter,\n status: number,\n code: string,\n requestId: string,\n details: Record<string, unknown> = {},\n): void {\n send(res, status, { error: { code, requestId, ...details } }, requestId);\n}\n\nasync function body(\n req: IncomingMessage,\n limit: number,\n signal: AbortSignal,\n): Promise<Record<string, any>> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n let size = 0;\n const cleanup = () => {\n req.off(\"data\", onData);\n req.off(\"end\", onEnd);\n req.off(\"error\", onError);\n signal.removeEventListener(\"abort\", onAbort);\n };\n const finish = (callback: () => void) => {\n cleanup();\n callback();\n };\n const onData = (chunk: Buffer | string) => {\n const buffer = Buffer.from(chunk);\n size += buffer.length;\n if (size > limit) {\n finish(() => reject(Object.assign(new Error(\"body too large\"), {\n status: 413,\n code: \"body_too_large\",\n })));\n req.resume();\n return;\n }\n chunks.push(buffer);\n };\n const onEnd = () => finish(() => {\n if (!size) {\n resolve({});\n return;\n }\n try {\n const parsed = JSON.parse(Buffer.concat(chunks).toString(\"utf8\"));\n if (!parsed || Array.isArray(parsed) || typeof parsed !== \"object\") throw new Error();\n resolve(parsed);\n } catch {\n reject(Object.assign(new Error(\"invalid JSON\"), { status: 400, code: \"malformed_json\" }));\n }\n });\n const onError = (error: Error) => finish(() => reject(error));\n const onAbort = () => {\n finish(() => reject(signal.reason));\n req.resume();\n };\n req.on(\"data\", onData);\n req.on(\"end\", onEnd);\n req.on(\"error\", onError);\n signal.addEventListener(\"abort\", onAbort, { once: true });\n if (signal.aborted) onAbort();\n });\n}\n\nasync function jsonBody(\n req: IncomingMessage,\n limit: number,\n signal: AbortSignal,\n): Promise<Record<string, any>> {\n if (hasRequestBody(req) && req.headers[\"content-type\"]?.split(\";\", 1)[0] !== \"application/json\") {\n throw Object.assign(new Error(\"unsupported media type\"), {\n status: 415,\n code: \"unsupported_media_type\",\n });\n }\n return body(req, limit, signal);\n}\n\nfunction numberParam(value: string | null, name: string): number | undefined {\n if (value === null) return undefined;\n const result = Number(value);\n if (!Number.isSafeInteger(result)) throw new BridgeValidationError(`${name} is invalid`);\n return result;\n}\n\nfunction booleanParam(value: string | null, name: string): boolean | undefined {\n if (value === null) return undefined;\n if (value === \"true\") return true;\n if (value === \"false\") return false;\n throw new BridgeValidationError(`${name} must be true or false`);\n}\n\nfunction hasRequestBody(req: IncomingMessage): boolean {\n const length = req.headers[\"content-length\"];\n return req.headers[\"transfer-encoding\"] !== undefined || (length !== undefined && length !== \"0\");\n}\n\nfunction pathBoundInput(\n operation: string,\n deliveryId: string,\n rawInput: Record<string, unknown>,\n protocolVersion?: string,\n): Record<string, unknown> {\n if (Object.prototype.hasOwnProperty.call(rawInput, \"deliveryId\")) {\n throw new ContractValidationError(operation, [{ path: \"/deliveryId\", message: \"deliveryId is supplied by the request path\" }]);\n }\n const value = { ...rawInput, deliveryId };\n return protocolVersion\n ? validateRequestForProtocol(operation, value, protocolVersion)\n : validateRequest(operation, value);\n}\n\nfunction active(signal: AbortSignal): void {\n if (signal.aborted) throw signal.reason;\n}\n\nfunction closedQuery(url: URL, operation: string, allowed: readonly string[]): void {\n const unknown = [...url.searchParams.keys()].find((key) => !allowed.includes(key));\n if (unknown) throw new ContractValidationError(operation, [{ path: `/${unknown}`, message: \"Unexpected query parameter\" }]);\n}\n\nfunction selectedProtocol(res: ResponseWriter): string {\n return String(res.getHeader(PROTOCOL_HEADER) ?? PROTOCOL_VERSION);\n}\n\nfunction requireCurrentProtocol(res: ResponseWriter): void {\n if (selectedProtocol(res) === LEGACY_PROTOCOL_VERSION) {\n const error = new Error(\"Operation is not available in protocol 2.0\") as Error & { status: number; code: string };\n error.status = 404;\n error.code = \"not_found\";\n throw error;\n }\n}\n\nexport function createGateway(options: GatewayOptions) {\n const metrics: Metrics = { requests: 0, errors: 0, timeouts: 0, authFailures: 0 };\n const limit = options.bodyLimitBytes ?? 128 * 1024;\n const deadline = options.requestDeadlineMs ?? 10_000;\n const origins = new Set(options.allowedOrigins ?? []);\n\n return createServer((req, res) => {\n const requestId = randomUUID();\n const abort = new AbortController();\n let mutationStarted = false;\n metrics.requests += 1;\n const requestedProtocol = req.headers[PROTOCOL_HEADER];\n const rawRequestedProtocol = Array.isArray(requestedProtocol) ? requestedProtocol[0] : requestedProtocol;\n const initialProtocol = rawRequestedProtocol === undefined || rawRequestedProtocol.trim() === \"\"\n ? LEGACY_PROTOCOL_VERSION\n : (SUPPORTED_PROTOCOL_VERSIONS as readonly string[]).includes(rawRequestedProtocol.trim())\n ? rawRequestedProtocol.trim()\n : PROTOCOL_VERSION;\n res.setHeader(PROTOCOL_HEADER, initialProtocol);\n res.setHeader(SUPPORTED_PROTOCOL_HEADER, SUPPORTED_PROTOCOL_VERSIONS.join(\",\"));\n const timer = setTimeout(() => {\n abort.abort(new Error(\"request deadline exceeded\"));\n metrics.timeouts += 1; metrics.errors += 1;\n res.once(\"finish\", () => {\n if (!req.complete) req.destroy();\n });\n failure(\n res,\n 504,\n mutationStarted ? \"mutation_outcome_unknown\" : \"request_timeout\",\n requestId,\n );\n }, deadline);\n let parsedBody: Promise<Record<string, any>> | undefined;\n const requestBody = () => parsedBody ??= jsonBody(req, limit, abort.signal);\n\n const dispatch = async (authority?: RequestAuthorityContext, response: ResponseWriter = res): Promise<void> => {\n const url = new URL(req.url ?? \"/\", \"http://gateway.invalid\");\n if (req.method === \"GET\" && url.pathname === \"/healthz\") {\n send(response, 200, { status: \"alive\" }, requestId);\n return;\n }\n if (req.method === \"GET\" && url.pathname === \"/readyz\") {\n let ready = false;\n try {\n ready = await (options.ready?.() ?? options.store.initialize().then(() => true));\n } catch {\n ready = false;\n }\n send(response, ready ? 200 : 503, { status: ready ? \"ready\" : \"not_ready\" }, requestId);\n return;\n }\n const origin = req.headers.origin;\n if (origin && !origins.has(origin)) {\n failure(response, 403, \"origin_forbidden\", requestId); return;\n }\n const token = bearerToken(req.headers.authorization);\n if (options.requestAuthority && !authority) {\n if (!token) {\n metrics.authFailures += 1;\n failure(response, 401, \"unauthorized\", requestId); return;\n }\n const preflight = await options.credentials.resolve(token, abort.signal);\n active(abort.signal);\n if (!preflight) {\n metrics.authFailures += 1;\n failure(response, 401, \"unauthorized\", requestId); return;\n }\n if (hasRequestBody(req)) await requestBody();\n active(abort.signal);\n const buffered = new BufferedResponse(res);\n await options.requestAuthority!.run(\n preflight.id,\n hashCredential(token),\n requestId,\n abort.signal,\n (context) => dispatch(context, buffered),\n );\n active(abort.signal);\n buffered.flush();\n return;\n }\n const credential = authority?.credential ?? (token ? await options.credentials.resolve(token, abort.signal) : null);\n active(abort.signal);\n if (!credential) {\n metrics.authFailures += 1;\n failure(response, 401, \"unauthorized\", requestId); return;\n }\n if (!Array.isArray(credential.scopes)) {\n failure(response, 503, \"security_unavailable\", requestId); return;\n }\n const service = new BridgeService(authority?.store ?? options.store);\n const security = authority?.security ?? options.security;\n if (url.pathname.startsWith(\"/v2/\") || url.pathname === \"/metrics\") {\n response.setHeader(PROTOCOL_HEADER, negotiateProtocolVersion(req.headers[PROTOCOL_HEADER]));\n }\n const authorize = async (operationId: OperationId): Promise<void> => {\n const requiredScopes = operationContract(operationId).scopes;\n if (requiredScopes.some((scope) => !credential.scopes.includes(scope))) {\n try {\n await security.recordScopeDenial(credential.id, operationId, requestId, abort.signal);\n } catch {\n throw Object.assign(new Error(\"Scope denial could not be audited\"), {\n status: 503,\n code: \"security_unavailable\",\n });\n }\n throw Object.assign(new Error(\"Credential lacks a required scope\"), {\n status: 403, code: \"insufficient_scope\", requiredScopes,\n });\n }\n let decision;\n try {\n decision = await security.consume(credential.id, operationId, requestId, abort.signal);\n } catch {\n throw Object.assign(new Error(\"Rate limit state is unavailable\"), {\n status: 503,\n code: \"security_unavailable\",\n });\n }\n if (!decision.allowed) {\n const retryAfter = Math.max(1, Math.ceil(decision.retryAfterSeconds));\n response.setHeader(\"retry-after\", String(retryAfter));\n throw Object.assign(new Error(\"Credential rate limit exceeded\"), {\n status: 429, code: \"rate_limited\", retryAfterSeconds: retryAfter,\n });\n }\n };\n if (req.method === \"GET\" && url.pathname === \"/metrics\") {\n await authorize(\"gateway_metrics\");\n validateRequest(\"gateway_metrics\", {});\n const result = Object.entries(metrics).map(([key, value]) => `agent_bridge_gateway_${key}_total ${value}`).join(\"\\n\") + \"\\n\";\n parseResponse(\"gateway_metrics\", result);\n response.writeHead(200, {\n ...jsonHeaders,\n \"content-type\": \"text/plain; version=0.0.4\",\n \"x-request-id\": requestId,\n });\n response.end(result);\n return;\n }\n const instanceHeader = req.headers[\"x-agent-bridge-instance\"];\n const principal = {\n ...credential.principal,\n instance: Array.isArray(instanceHeader) ? instanceHeader[0] : instanceHeader,\n };\n\n if (req.method === \"GET\" && url.pathname === \"/v2/capabilities\") {\n requireCurrentProtocol(response);\n await authorize(\"capabilities\");\n closedQuery(url, \"capabilities\", []);\n validateRequest(\"capabilities\", {});\n let rowIsolation = false;\n if (options.requestAuthority && options.rowIsolationReady) {\n try {\n rowIsolation = await options.rowIsolationReady();\n } catch {\n rowIsolation = false;\n }\n }\n sendOperation(response, 200, \"capabilities\", {\n ...capabilityDocument({\n surface: \"http\",\n provider: \"gateway\",\n selectedProtocolVersion: String(response.getHeader(PROTOCOL_HEADER)),\n requestAuthority: Boolean(options.requestAuthority),\n rowIsolation,\n }),\n grantedScopes: [...credential.scopes],\n }, requestId); return;\n }\n\n if (req.method === \"GET\" && url.pathname === \"/v2/status\") {\n await authorize(\"status\");\n closedQuery(url, \"status\", []);\n validateRequest(\"status\", {});\n const activeStore = authority?.store ?? options.store;\n const authorityBinding = authority && response.getHeader(PROTOCOL_HEADER) === PROTOCOL_VERSION ? {\n gatewayAuthorityId: authority.gatewayAuthorityId,\n credentialId: authority.credential.id,\n } : {};\n if (!activeStore.diagnostics) {\n sendOperation(response, 200, \"status\", { schemaVersion: \"postgres-v2\", deliverySupported: false, pending: null, claimed: null, retrying: null, dead: null, ...authorityBinding, principal: credential.principal }, requestId);\n } else {\n sendOperation(response, 200, \"status\", { ...await activeStore.diagnostics(principal), ...authorityBinding, principal: credential.principal }, requestId);\n }\n return;\n }\n\n if (req.method === \"POST\" && url.pathname === \"/v2/endpoint-migration-challenges\") {\n requireCurrentProtocol(response);\n await authorize(\"issue_endpoint_migration_challenge\");\n const input = validateRequestForProtocol(\"issue_endpoint_migration_challenge\", await requestBody(), selectedProtocol(response));\n if (!authority?.endpointMigrationChallenges) throw Object.assign(new Error(\"endpoint migration challenges require request authority\"), { status: 503, code: \"security_unavailable\" });\n active(abort.signal);\n await authority.beginDomainWork(); mutationStarted = true;\n sendOperation(response, 200, \"issue_endpoint_migration_challenge\", await authority.endpointMigrationChallenges.issue({\n challenge: String(input.challenge),\n expectedGatewayAuthorityId: String(input.expectedGatewayAuthorityId),\n verifierCredentialId: String(input.verifierCredentialId),\n }), requestId); return;\n }\n\n if (req.method === \"POST\" && url.pathname === \"/v2/endpoint-migration-challenges/consume\") {\n requireCurrentProtocol(response);\n await authorize(\"consume_endpoint_migration_challenge\");\n const input = validateRequestForProtocol(\"consume_endpoint_migration_challenge\", await requestBody(), selectedProtocol(response));\n if (!authority?.endpointMigrationChallenges) throw Object.assign(new Error(\"endpoint migration challenges require request authority\"), { status: 503, code: \"security_unavailable\" });\n active(abort.signal);\n await authority.beginDomainWork(); mutationStarted = true;\n sendOperation(response, 200, \"consume_endpoint_migration_challenge\", await authority.endpointMigrationChallenges.consume({\n challenge: String(input.challenge),\n expectedGatewayAuthorityId: String(input.expectedGatewayAuthorityId),\n issuerCredentialId: String(input.issuerCredentialId),\n }), requestId); return;\n }\n\n if (req.method === \"POST\" && url.pathname === \"/v2/messages\") {\n await authorize(\"publish_message\");\n const input = validateRequestForProtocol(\"publish_message\", await requestBody(), String(response.getHeader(PROTOCOL_HEADER)));\n if (input.source !== undefined && input.source !== principal.agent) {\n throw new BridgePrincipalMismatchError(\"source must match the authenticated principal\");\n }\n const { source: _source, ...draft } = input;\n active(abort.signal);\n await authority?.beginDomainWork(); mutationStarted = true;\n sendOperation(response, 201, \"publish_message\", await service.publish(principal, draft as unknown as MessageDraft), requestId); return;\n }\n if (req.method === \"GET\" && url.pathname === \"/v2/history\") {\n await authorize(\"history\");\n closedQuery(url, \"history\", [\"cursor\", \"mailbox\", \"receiptState\", \"limit\", \"type\", \"includeExpired\", \"source\", \"project\", \"since\", \"unacknowledgedBy\", \"unacked_by\", \"threadId\", \"latest\"]);\n const types = url.searchParams.getAll(\"type\");\n const input = validateRequestForProtocol(\"history\", {\n cursor: url.searchParams.get(\"cursor\") ?? undefined,\n mailbox: url.searchParams.get(\"mailbox\") ?? undefined as any,\n receiptState: url.searchParams.get(\"receiptState\") ?? undefined as any,\n limit: numberParam(url.searchParams.get(\"limit\"), \"limit\"),\n types: types.length ? types : undefined,\n includeExpired: booleanParam(url.searchParams.get(\"includeExpired\"), \"includeExpired\"),\n source: url.searchParams.get(\"source\") ?? undefined,\n project: url.searchParams.get(\"project\") ?? undefined,\n since: url.searchParams.get(\"since\") ?? undefined,\n unacknowledgedBy: url.searchParams.get(\"unacknowledgedBy\") ?? url.searchParams.get(\"unacked_by\") ?? undefined,\n threadId: url.searchParams.get(\"threadId\") ?? undefined,\n latest: booleanParam(url.searchParams.get(\"latest\"), \"latest\"),\n }, String(response.getHeader(PROTOCOL_HEADER)));\n sendOperation(response, 200, \"history\", await service.history(principal, input), requestId); return;\n }\n if (req.method === \"POST\" && url.pathname === \"/v2/receipts\") {\n await authorize(\"record_receipt\");\n const input = validateRequest(\"record_receipt\", await requestBody());\n active(abort.signal);\n await authority?.beginDomainWork(); mutationStarted = true;\n sendOperation(response, 200, \"record_receipt\", { recorded: await service.acknowledge(principal, input.messageIds as string[]) }, requestId); return;\n }\n if (req.method === \"POST\" && url.pathname === \"/v2/deliveries/claim\") {\n await authorize(\"claim_delivery\");\n const input = validateRequestForProtocol(\"claim_delivery\", await requestBody(), selectedProtocol(response));\n active(abort.signal);\n await authority?.beginDomainWork(); mutationStarted = true;\n sendOperation(response, 200, \"claim_delivery\", await service.claim(principal, input) ?? { delivery: null }, requestId); return;\n }\n if (req.method === \"GET\" && url.pathname === \"/v2/deliveries\") {\n requireCurrentProtocol(response);\n await authorize(\"list_deliveries\");\n closedQuery(url, \"list_deliveries\", [\"cursor\", \"limit\", \"role\", \"messageId\", \"recipient\", \"state\"]);\n const input = validateRequest(\"list_deliveries\", {cursor:url.searchParams.get(\"cursor\")??undefined,limit:numberParam(url.searchParams.get(\"limit\"),\"limit\"),role:url.searchParams.get(\"role\")??undefined,messageId:url.searchParams.get(\"messageId\")??undefined,recipient:url.searchParams.get(\"recipient\")??undefined,states:url.searchParams.getAll(\"state\")});\n sendOperation(response,200,\"list_deliveries\",await service.deliveries(principal,input as any),requestId);return;\n }\n const eventsMatch=url.pathname.match(/^\\/v2\\/deliveries\\/([^/]+)\\/events$/);\n if(req.method===\"GET\"&&eventsMatch){requireCurrentProtocol(response);await authorize(\"list_delivery_events\");closedQuery(url,\"list_delivery_events\",[\"cursor\",\"limit\"]);const input=validateRequest(\"list_delivery_events\",{deliveryId:eventsMatch[1],cursor:url.searchParams.get(\"cursor\")??undefined,limit:numberParam(url.searchParams.get(\"limit\"),\"limit\")});sendOperation(response,200,\"list_delivery_events\",await service.deliveryEvents(principal,eventsMatch[1]!,input as any),requestId);return;}\n const controlMatch=url.pathname.match(/^\\/v2\\/deliveries\\/([^/]+)\\/(cancel|requeue)$/);\n if(req.method===\"POST\"&&controlMatch){requireCurrentProtocol(response);const operation=controlMatch[2]===\"cancel\"?\"cancel_delivery\":\"requeue_delivery\";await authorize(operation);pathBoundInput(operation,controlMatch[1]!,await requestBody());await authority?.beginDomainWork();mutationStarted=true;const result=controlMatch[2]===\"cancel\"?await service.cancel(principal,controlMatch[1]!):await service.requeue(principal,controlMatch[1]!);if(!result)failure(response,404,\"not_found\",requestId);else sendOperation(response,200,operation,{delivery:result},requestId);return;}\n if (req.method === \"POST\" && url.pathname === \"/v2/presence/heartbeat\") {\n await authorize(\"heartbeat\");\n const input = validateRequest(\"heartbeat\", await requestBody());\n active(abort.signal);\n await authority?.beginDomainWork(); mutationStarted = true;\n sendOperation(response, 200, \"heartbeat\", await service.heartbeat(principal, input), requestId); return;\n }\n if (req.method === \"GET\" && url.pathname === \"/v2/presence\") {\n await authorize(\"presence\");\n closedQuery(url, \"presence\", []);\n validateRequest(\"presence\", {});\n sendOperation(response, 200, \"presence\", { agents: await service.presence(principal) }, requestId); return;\n }\n const match = url.pathname.match(/^\\/v2\\/deliveries\\/([^/]+)\\/(extend|ack|nack)$/);\n if (req.method === \"POST\" && match) {\n const operationId = match[2] === \"extend\" ? \"extend_delivery\" : match[2] === \"ack\" ? \"acknowledge_delivery\" : \"negative_acknowledge_delivery\";\n await authorize(operationId);\n const rawInput = await requestBody();\n const protocolVersion = String(response.getHeader(PROTOCOL_HEADER) ?? PROTOCOL_VERSION);\n const input = pathBoundInput(operationId, match[1]!, rawInput, protocolVersion);\n active(abort.signal);\n await authority?.beginDomainWork(); mutationStarted = true;\n const [, id, action] = match;\n const result = action === \"extend\"\n ? await service.extend(principal, id, input.leaseToken as string, input.leaseMs as number)\n : action === \"ack\"\n ? await service.ack(principal, id, input.leaseToken as string)\n : await service.nack(\n principal,\n id,\n input.leaseToken as string,\n (input.error as string | undefined) ?? \"negative acknowledgment\",\n (input.disposition ?? input.dead ?? \"retry\") as \"retry\" | \"dead\" | boolean,\n input.retryPolicy,\n );\n if (!result) failure(response, 409, \"lease_conflict\", requestId);\n else sendOperation(response, 200, operationId, { delivery: result }, requestId);\n return;\n }\n failure(response, 404, \"not_found\", requestId);\n };\n void dispatch().catch((error: any) => {\n if (res.writableEnded) return;\n metrics.errors += 1;\n if (error instanceof ContractValidationError || error instanceof ContractResponseError) {\n failure(res, error.status, error.code, requestId, { operation: error.operation, issues: error.issues });\n } else if (error?.status === 426) {\n failure(res, 426, error.code, requestId, { supportedProtocolVersions: [...SUPPORTED_PROTOCOL_VERSIONS] });\n } else if (error?.code === \"insufficient_scope\") {\n failure(res, 403, error.code, requestId, { details: { requiredScopes: [...error.requiredScopes] } });\n } else if (error?.code === \"rate_limited\") {\n res.setHeader(\"retry-after\", String(error.retryAfterSeconds));\n failure(res, 429, error.code, requestId, { details: { retryAfterSeconds: error.retryAfterSeconds } });\n } else if (error instanceof BridgeValidationError || error instanceof BridgePrincipalMismatchError) {\n failure(res, \"status\" in error ? error.status : 400, error.code, requestId, { message: error.message });\n } else {\n failure(res, error?.status ?? 500, error?.code ?? \"internal_error\", requestId);\n }\n }).finally(() => clearTimeout(timer));\n });\n}\n","import { createHash, timingSafeEqual } from \"node:crypto\";\nimport type { BridgePrincipal } from \"./bridge-domain.js\";\nimport type { AuthorizationScope } from \"./contracts/registry.js\";\nimport type { PgQueryable } from \"./postgres-bridge-store.js\";\n\nexport interface AuthenticatedCredential {\n id: string;\n principal: BridgePrincipal;\n /** Canonical authorization scopes granted to this credential. */\n scopes: readonly AuthorizationScope[];\n}\n\nexport interface CredentialResolver {\n resolve(token: string, signal?: AbortSignal): Promise<AuthenticatedCredential | null>;\n}\n\nexport function hashCredential(token: string): string {\n return createHash(\"sha256\").update(token, \"utf8\").digest(\"hex\");\n}\n\nexport class PostgresCredentialResolver implements CredentialResolver {\n constructor(private readonly db: PgQueryable) {}\n\n async resolve(token: string, signal?: AbortSignal): Promise<AuthenticatedCredential | null> {\n if (signal?.aborted) throw signal.reason;\n const result = await this.db.query<{\n credential_id: string; workspace_id: string; principal: string; scopes: AuthorizationScope[];\n }>(\n `SELECT credential_id,workspace_id,principal,scopes\n FROM agent_bridge.resolve_credential_hash($1::text)`,\n [hashCredential(token)],\n );\n const row = result.rows[0];\n if (signal?.aborted) throw signal.reason;\n return row ? {\n id: row.credential_id,\n principal: { workspace: row.workspace_id, agent: row.principal },\n scopes: row.scopes,\n } : null;\n }\n}\n\nexport function bearerToken(value: string | undefined): string | null {\n if (!value?.startsWith(\"Bearer \")) return null;\n const token = value.slice(7);\n if (!token || token.length > 4096 || /\\s/.test(token)) return null;\n return token;\n}\n\nexport function safeTokenHashEqual(token: string, expectedHash: string): boolean {\n const actual = Buffer.from(hashCredential(token));\n const expected = Buffer.from(expectedHash);\n return actual.length === expected.length && timingSafeEqual(actual, expected);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1301,21 +1301,24 @@ async function collectPostgresRoleInventory(client, databaseName) {
|
|
|
1301
1301
|
CROSS JOIN LATERAL pg_catalog.aclexplode(type.typacl) acl WHERE namespace.nspname='agent_bridge' AND acl.grantee<>0
|
|
1302
1302
|
UNION SELECT defaults.defaclrole, 'object-role' FROM pg_catalog.pg_default_acl defaults
|
|
1303
1303
|
LEFT JOIN pg_catalog.pg_namespace namespace ON namespace.oid=defaults.defaclnamespace
|
|
1304
|
-
WHERE namespace.nspname='agent_bridge' OR
|
|
1305
|
-
|
|
1304
|
+
WHERE namespace.nspname='agent_bridge' OR (
|
|
1305
|
+
defaults.defaclnamespace=0 AND defaults.defaclrole=(
|
|
1306
|
+
SELECT nspowner FROM pg_catalog.pg_namespace WHERE nspname='agent_bridge'))
|
|
1306
1307
|
OR (defaults.defaclnamespace=0 AND defaults.defaclrole=(SELECT oid FROM pg_catalog.pg_roles
|
|
1307
1308
|
WHERE rolname='agent_bridge_control_owner_'||substr(pg_catalog.md5(pg_catalog.current_database()),1,16)))
|
|
1308
1309
|
UNION SELECT acl.grantor, 'object-role' FROM pg_catalog.pg_default_acl defaults
|
|
1309
1310
|
LEFT JOIN pg_catalog.pg_namespace namespace ON namespace.oid=defaults.defaclnamespace
|
|
1310
1311
|
CROSS JOIN LATERAL pg_catalog.aclexplode(defaults.defaclacl) acl WHERE namespace.nspname='agent_bridge'
|
|
1311
|
-
OR defaults.
|
|
1312
|
+
OR (defaults.defaclnamespace=0 AND defaults.defaclrole=(
|
|
1313
|
+
SELECT nspowner FROM pg_catalog.pg_namespace WHERE nspname='agent_bridge'))
|
|
1312
1314
|
OR (defaults.defaclnamespace=0 AND defaults.defaclrole=(SELECT oid FROM pg_catalog.pg_roles
|
|
1313
1315
|
WHERE rolname='agent_bridge_control_owner_'||substr(pg_catalog.md5(pg_catalog.current_database()),1,16)))
|
|
1314
1316
|
UNION SELECT acl.grantee, 'object-role' FROM pg_catalog.pg_default_acl defaults
|
|
1315
1317
|
LEFT JOIN pg_catalog.pg_namespace namespace ON namespace.oid=defaults.defaclnamespace
|
|
1316
1318
|
CROSS JOIN LATERAL pg_catalog.aclexplode(defaults.defaclacl) acl WHERE acl.grantee<>0 AND (
|
|
1317
|
-
namespace.nspname='agent_bridge' OR
|
|
1318
|
-
|
|
1319
|
+
namespace.nspname='agent_bridge' OR (
|
|
1320
|
+
defaults.defaclnamespace=0 AND defaults.defaclrole=(
|
|
1321
|
+
SELECT nspowner FROM pg_catalog.pg_namespace WHERE nspname='agent_bridge'))
|
|
1319
1322
|
OR (defaults.defaclnamespace=0 AND defaults.defaclrole=(SELECT oid FROM pg_catalog.pg_roles
|
|
1320
1323
|
WHERE rolname='agent_bridge_control_owner_'||substr(pg_catalog.md5(pg_catalog.current_database()),1,16))))
|
|
1321
1324
|
), base_roles AS (
|
|
@@ -1325,12 +1328,19 @@ async function collectPostgresRoleInventory(client, databaseName) {
|
|
|
1325
1328
|
UNION
|
|
1326
1329
|
SELECT role.oid, 'derived' FROM pg_catalog.pg_roles role
|
|
1327
1330
|
WHERE role.rolname IN (SELECT name FROM derived_names)
|
|
1331
|
+
), canonical_base_roles AS (
|
|
1332
|
+
SELECT oid, CASE WHEN bool_or(kind='schema-owner') THEN 'schema-owner'
|
|
1333
|
+
WHEN bool_or(kind='derived') THEN 'derived'
|
|
1334
|
+
ELSE 'object-role' END AS kind
|
|
1335
|
+
FROM base_roles GROUP BY oid
|
|
1328
1336
|
), related_roles AS (
|
|
1329
|
-
SELECT oid, kind FROM
|
|
1337
|
+
SELECT oid, kind FROM canonical_base_roles
|
|
1330
1338
|
UNION SELECT membership.roleid, 'external-principal' FROM pg_catalog.pg_auth_members membership
|
|
1331
|
-
WHERE membership.member IN (
|
|
1339
|
+
WHERE membership.member IN (
|
|
1340
|
+
SELECT oid FROM canonical_base_roles WHERE kind<>'schema-owner')
|
|
1332
1341
|
UNION SELECT membership.member, 'external-principal' FROM pg_catalog.pg_auth_members membership
|
|
1333
|
-
WHERE membership.roleid IN (
|
|
1342
|
+
WHERE membership.roleid IN (
|
|
1343
|
+
SELECT oid FROM canonical_base_roles WHERE kind<>'schema-owner')
|
|
1334
1344
|
)
|
|
1335
1345
|
SELECT role.rolname AS name,
|
|
1336
1346
|
CASE WHEN bool_or(related.kind='schema-owner') THEN 'schema-owner'
|
|
@@ -1340,6 +1350,7 @@ async function collectPostgresRoleInventory(client, databaseName) {
|
|
|
1340
1350
|
FROM related_roles related JOIN pg_catalog.pg_roles role ON role.oid=related.oid
|
|
1341
1351
|
GROUP BY role.rolname ORDER BY role.rolname`);
|
|
1342
1352
|
const names = roleRows.rows.map((row) => row.name);
|
|
1353
|
+
const schemaOwnerNames = roleRows.rows.filter((row) => row.kind === "schema-owner").map((row) => row.name);
|
|
1343
1354
|
const membershipRows = names.length === 0 ? { rows: [], rowCount: 0 } : await client.query(`
|
|
1344
1355
|
SELECT granted.rolname AS role, member.rolname AS member,
|
|
1345
1356
|
bool_or(membership.admin_option) AS "adminOption",
|
|
@@ -1353,15 +1364,21 @@ async function collectPostgresRoleInventory(client, databaseName) {
|
|
|
1353
1364
|
ORDER BY granted.rolname,member.rolname`, [names]);
|
|
1354
1365
|
if (names.length > 0) {
|
|
1355
1366
|
const boundary = await client.query(`
|
|
1356
|
-
SELECT
|
|
1367
|
+
SELECT granted.rolname AS role, member.rolname AS member
|
|
1368
|
+
FROM pg_catalog.pg_auth_members membership
|
|
1357
1369
|
JOIN pg_catalog.pg_roles granted ON granted.oid=membership.roleid
|
|
1358
1370
|
JOIN pg_catalog.pg_roles member ON member.oid=membership.member
|
|
1359
1371
|
WHERE (granted.rolname=ANY($1::text[])) <> (member.rolname=ANY($1::text[]))
|
|
1360
|
-
|
|
1372
|
+
AND NOT (
|
|
1373
|
+
granted.rolname=ANY($1::text[]) AND granted.rolname=ANY($2::text[])
|
|
1374
|
+
OR member.rolname=ANY($1::text[]) AND member.rolname=ANY($2::text[])
|
|
1375
|
+
)
|
|
1376
|
+
ORDER BY granted.rolname,member.rolname LIMIT 10`, [names, schemaOwnerNames]);
|
|
1361
1377
|
if (boundary.rows.length > 0) {
|
|
1362
1378
|
throw new PostgresNativeDrError(
|
|
1363
1379
|
"TRANSITIVE_ROLE_MEMBERSHIP_UNSUPPORTED",
|
|
1364
|
-
"PostgreSQL role inventory has a transitive external membership outside the bounded restore graph"
|
|
1380
|
+
"PostgreSQL role inventory has a transitive external membership outside the bounded restore graph",
|
|
1381
|
+
{ roleMemberships: boundary.rows }
|
|
1365
1382
|
);
|
|
1366
1383
|
}
|
|
1367
1384
|
}
|
|
@@ -1380,8 +1397,9 @@ async function collectPostgresRoleInventory(client, databaseName) {
|
|
|
1380
1397
|
LEFT JOIN LATERAL pg_catalog.aclexplode(defaults.defaclacl) acl ON true
|
|
1381
1398
|
LEFT JOIN pg_catalog.pg_roles grantor ON grantor.oid=acl.grantor
|
|
1382
1399
|
LEFT JOIN pg_catalog.pg_roles grantee ON grantee.oid=acl.grantee
|
|
1383
|
-
WHERE namespace.nspname='agent_bridge' OR
|
|
1384
|
-
|
|
1400
|
+
WHERE namespace.nspname='agent_bridge' OR (
|
|
1401
|
+
defaults.defaclnamespace=0 AND defaults.defaclrole=(
|
|
1402
|
+
SELECT nspowner FROM pg_catalog.pg_namespace WHERE nspname='agent_bridge'))
|
|
1385
1403
|
OR (defaults.defaclnamespace=0 AND defaults.defaclrole=(SELECT oid FROM pg_catalog.pg_roles
|
|
1386
1404
|
WHERE rolname='agent_bridge_control_owner_'||substr(pg_catalog.md5(pg_catalog.current_database()),1,16)))
|
|
1387
1405
|
ORDER BY owner.rolname,namespace.nspname NULLS FIRST,defaults.defaclobjtype,
|
|
@@ -2668,4 +2686,4 @@ export {
|
|
|
2668
2686
|
restoreLocalSqlite,
|
|
2669
2687
|
SQLITE_EDGE_APPLICATION_ID
|
|
2670
2688
|
};
|
|
2671
|
-
//# sourceMappingURL=chunk-
|
|
2689
|
+
//# sourceMappingURL=chunk-IF5OKPBK.js.map
|