import type { DaemonGatewayRestRouteHandlers } from './context.js'; /** * gateway-rest-routes.ts * * Explicit REST route table for the handler-backed gateway verb families that * ALSO advertise an `http` binding in the operator method catalog (skills.*, * principals.*, profile.*, occasions.*, checkin.*, ci.*, channels.profiles.*, the session-scoped * sessions.permissionMode.get/set + sessions.contextUsage.get, stepup.* (the * relay step-up ceremony), and runtime.metrics.get). Those verbs are * served in-process through `invokeGatewayMethodCall`'s registered-handler * branch, reachable over the wire via the generic * `POST /api/control/gateway-methods/:methodId/invoke` endpoint. But each one * also promises a plain-REST path (`GET /api/skills`, …) in its descriptor's * http binding, and no route ever served those paths, a caller trusting the * advertisement and hitting `GET /api/skills` got a bare 404. That is the exact * advertise-without-route defect the capability-route reconcile * (method-catalog-route-reconcile.ts) exists to catch. * * This module closes that gap with genuine route parity rather than by muting * the gate: it maps each advertised REST path to its gateway methodId and * dispatches through `handlers.invokeGatewayRestVerb`, which the daemon wires * back to the SAME `invokeGatewayMethodCall` the methodId-invoke endpoint uses. * No verb logic is duplicated, the REST path and the methodId-invoke endpoint * now resolve to the identical in-process handler, with the identical * access/scope gate. Path parameters ({name}, {sessionId}, …) are folded into * the invocation query so the handler's `readInvocationParams` view sees them. * * Drift guard: the reconcile gate reddens whenever a handler-backed family * gains an http binding without a matching entry here (its advertised path * would resolve to no route), so a new family's REST paths must be added to * GATEWAY_REST_ROUTES in the same change. */ interface GatewayRestRoute { readonly method: string; readonly regex: RegExp; readonly paramNames: readonly string[]; readonly methodId: string; } /** * The explicit REST route table. Every entry is a path a gateway verb * descriptor advertises in its http binding; keep this in lockstep with those * bindings (the reconcile gate enforces it). */ export declare const GATEWAY_REST_ROUTES: readonly GatewayRestRoute[]; /** * Dispatch a request against the gateway REST route table. * * Returns the handler's `Response` when a path+method entry matches, or `null` * when nothing matches (so the caller falls through to the rest of the route * chain / a 404). When the daemon has not wired `invokeGatewayRestVerb` (e.g. a * minimal embed), a matching path returns `null` rather than throwing, it * degrades to the same 404 the caller saw before these routes existed. */ /** * Header carrying how many synthesized dispatches a request is already deep. * * Lives here rather than beside the guard that reads it because this module * owns the table that made a cycle possible: these rows map an advertised path * back to its own methodId, so a verb reaching the synthesizing arm of * `invokeGatewayMethodCall` lands right back here. Absent on a request from a * real client; `1` on the first synthesis. */ export declare const SYNTHESIZED_DISPATCH_HEADER = "x-goodvibes-synthesized-dispatch"; /** Read the synthesized-dispatch depth off a request. 0 when unmarked. */ export declare function readSynthesizedDispatchDepth(req: Request): number; export declare function dispatchGatewayRestRoutes(req: Request, handlers: Partial): Promise; export {}; //# sourceMappingURL=gateway-rest-routes.d.ts.map