@cleocode/runtime 2026.10.4 → 2026.10.5-rc.ci.672
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-L5BLVQDA.js → chunk-4PUSKGDO.js} +2 -2
- package/dist/chunk-4PUSKGDO.js.map +1 -0
- package/dist/{chunk-KQBVXGOL.js → chunk-GULKX44R.js} +5 -3
- package/dist/chunk-GULKX44R.js.map +1 -0
- package/dist/{chunk-7Q7BEWM7.js → chunk-HXTRXEFI.js} +7 -9
- package/dist/chunk-HXTRXEFI.js.map +1 -0
- package/dist/{chunk-U2ESNIJ5.js → chunk-NOPLC5WS.js} +4 -2
- package/dist/chunk-NOPLC5WS.js.map +1 -0
- package/dist/chunk-PDZ5T4LO.js +597 -0
- package/dist/chunk-PDZ5T4LO.js.map +1 -0
- package/dist/{chunk-XJOMQIXL.js → chunk-WO6LJMDC.js} +4 -2
- package/dist/chunk-WO6LJMDC.js.map +1 -0
- package/dist/daemon/index.js +1 -1
- package/dist/dispatch-BWjVeeMg.d.ts +290 -0
- package/dist/gateway/dispatch.d.ts +5 -0
- package/dist/gateway/dispatch.js +53 -0
- package/dist/gateway/dispatch.js.map +1 -0
- package/dist/gateway/http/index.d.ts +897 -11
- package/dist/gateway/http/index.js +2 -2
- package/dist/gateway/index.d.ts +549 -4
- package/dist/gateway/index.js +26 -581
- package/dist/gateway/index.js.map +1 -1
- package/dist/gateway/mcp/index.d.ts +232 -10
- package/dist/gateway/mcp/index.js +2 -2
- package/dist/gateway/rpc/index.d.ts +5 -2036
- package/dist/gateway/rpc/index.js +1 -1
- package/dist/gateway-handler-DCU6E0a2.d.ts +80 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.js +9 -6
- package/dist/index.js.map +1 -1
- package/package.json +7 -3
- package/dist/chunk-7Q7BEWM7.js.map +0 -1
- package/dist/chunk-KQBVXGOL.js.map +0 -1
- package/dist/chunk-L5BLVQDA.js.map +0 -1
- package/dist/chunk-U2ESNIJ5.js.map +0 -1
- package/dist/chunk-XJOMQIXL.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/gateway/dispatcher.ts","../../src/gateway/meta.ts","../../src/gateway/pipeline.ts","../../src/gateway/background-jobs.ts","../../src/gateway/daemon-subsystem.ts","../../src/gateway/engine.ts","../../src/gateway/template-parser.ts","../../src/gateway/engine-error.ts","../../src/gateway/exit-codes.ts","../../src/gateway/job-manager-accessor.ts","../../src/gateway/nexus-decorator.ts","../../src/gateway/paths.ts","../../src/gateway/serve.ts","../../src/gateway/index.ts"],"sourcesContent":["/**\n * Central Dispatcher -- Routes requests through middleware to domain handlers.\n *\n * The dispatcher is the single entry point for the CLI adapter.\n * It resolves operations, validates parameters, runs the middleware pipeline,\n * and delegates to the appropriate domain handler.\n *\n * Flow: DispatchRequest → resolve → param validation → middleware → handler\n *\n * ## T1088 — Dialectic Evaluator Hook (PSYCHE Wave 3)\n *\n * After each successful mutate operation, the dispatcher fires a background\n * `evaluateDialectic` call via `setImmediate` if all of the following apply:\n *\n * 1. The response indicates `success: true`.\n * 2. The request gateway is `\"mutate\"` (state-modifying user-facing commands).\n * 3. A `sessionId` is present on the request (identifies conversation context).\n * 4. The in-memory rate limiter allows the evaluation (1 per 10s per session).\n *\n * Errors from the background evaluation are caught and logged at `warn` level\n * so they never affect the caller.\n *\n * ## T12024 — Bounded deadline for background LLM calls\n *\n * The dialectic evaluation makes an HTTP call to an LLM backend (Ollama,\n * Anthropic, etc.) which keeps the Node.js event loop alive. After the CLI\n * success-path `finally` tears down workers and databases via\n * `shutdownCliRuntime`, the pending HTTP connection is the sole remaining\n * reference — preventing the process from draining the loop and exiting rc:0.\n *\n * Each evaluation now runs against an unrefed deadline so the deadline\n * timer itself never holds the loop open, while the abort signal cancels the\n * underlying HTTP request when the deadline fires, releasing the connection\n * and allowing natural exit. The timeout is generous enough for normal\n * responses but prevents hung connections from blocking shutdown.\n *\n * @epic T4820\n * @task T1088\n * @task T12024\n */\n\nimport { randomUUID } from 'node:crypto';\nimport type {\n DispatchRequest,\n DispatchResponse,\n DomainHandler,\n Middleware,\n} from '@cleocode/contracts/gateway';\nimport { getLogger, getProjectRoot } from '@cleocode/core';\n// Deep import, not the barrel: this is a small dependency-free module, and\n// pulling it through the core barrel would load the full core module graph for\n// one function. Spelled WITHOUT `.js` because core's `./*` export maps to\n// `./dist/*.js`, so the extension is supplied by the pattern — adding it here\n// resolves to `dist/teardown-signal.js.js` and fails.\nimport { registerTeardownAbort } from '@cleocode/core/teardown-signal';\nimport { createDispatchMeta } from './meta.js';\nimport { compose } from './pipeline.js';\nimport { resolve, validateRequiredParams } from './registry.js';\n\n// ============================================================================\n// T1088: In-memory rate limiter for dialectic evaluation\n// ============================================================================\n\n/** Rate limit window in milliseconds (1 evaluation per 10 seconds per session). */\nconst DIALECTIC_RATE_LIMIT_MS = 10_000;\n\n/**\n * Maximum time the dialectic LLM call is allowed to run before aborting.\n *\n * The deadline uses an unrefed timer so it never blocks process exit by\n * itself. When triggered, the abort signal cancels the underlying HTTP\n * request, allowing the event loop to drain and the CLI process to exit.\n *\n * @task T12024\n */\nconst DIALECTIC_DEADLINE_MS = 10_000;\n\n/** In-memory last-evaluation timestamp per session ID. */\nconst _dialecticLastEvalMs = new Map<string, number>();\n\nfunction ensureRequestSessionLineage(request: DispatchRequest): void {\n request.executionSessionId ??=\n process.env.CLEO_EXECUTION_SESSION_ID ?? process.env.CLEO_SESSION_EXECUTION_ID ?? randomUUID();\n request.originSessionId ??=\n process.env.CLEO_ORIGIN_SESSION_ID ??\n process.env.CLEO_SESSION_ORIGIN_ID ??\n request.sessionId ??\n request.executionSessionId;\n}\n\n/**\n * Check whether a new dialectic evaluation is allowed for a session.\n *\n * Rate limit: 1 evaluation per `DIALECTIC_RATE_LIMIT_MS` per session.\n * Records the timestamp when allowed.\n *\n * @param sessionId - The session to check.\n * @returns `true` when the evaluation is allowed.\n */\nfunction isDialecticEvalAllowed(sessionId: string): boolean {\n const last = _dialecticLastEvalMs.get(sessionId) ?? 0;\n const now = Date.now();\n if (now - last < DIALECTIC_RATE_LIMIT_MS) {\n return false;\n }\n _dialecticLastEvalMs.set(sessionId, now);\n return true;\n}\n\n// ============================================================================\n// Dispatcher\n// ============================================================================\n\nexport interface DispatcherConfig {\n handlers: Map<string, DomainHandler>;\n middlewares?: Middleware[];\n}\n\nexport class Dispatcher {\n private handlers: Map<string, DomainHandler>;\n private pipeline: Middleware;\n\n constructor(config: DispatcherConfig) {\n this.handlers = config.handlers;\n this.pipeline = config.middlewares?.length\n ? compose(config.middlewares)\n : (_req, next) => next();\n }\n\n async dispatch(request: DispatchRequest): Promise<DispatchResponse> {\n const startTime = Date.now();\n ensureRequestSessionLineage(request);\n\n // 1. Resolve operation from registry\n const resolved = resolve(request.gateway, request.domain, request.operation);\n if (!resolved) {\n return {\n meta: createDispatchMeta(\n request.gateway,\n request.domain,\n request.operation,\n startTime,\n request.source,\n request.requestId,\n request.sessionId,\n request.originSessionId,\n request.executionSessionId,\n ),\n success: false,\n error: {\n code: 'E_INVALID_OPERATION',\n message: `Unknown operation: ${request.gateway}:${request.domain}.${request.operation}`,\n },\n };\n }\n\n // 2. Validate required params\n const missing = validateRequiredParams(resolved.def, request.params);\n if (missing.length > 0) {\n return {\n meta: createDispatchMeta(\n request.gateway,\n resolved.domain,\n resolved.operation,\n startTime,\n request.source,\n request.requestId,\n request.sessionId,\n request.originSessionId,\n request.executionSessionId,\n ),\n success: false,\n error: {\n code: 'E_MISSING_PARAMS',\n message: `Missing required parameters: ${missing.join(', ')}`,\n details: { missing },\n },\n };\n }\n\n // 3. Look up domain handler\n const handler = this.handlers.get(resolved.domain);\n if (!handler) {\n return {\n meta: createDispatchMeta(\n request.gateway,\n resolved.domain,\n resolved.operation,\n startTime,\n request.source,\n request.requestId,\n request.sessionId,\n request.originSessionId,\n request.executionSessionId,\n ),\n success: false,\n error: {\n code: 'E_NO_HANDLER',\n message: `No handler for domain: ${resolved.domain}`,\n },\n };\n }\n\n // 4. Run middleware pipeline with terminal handler\n const terminal = async (): Promise<DispatchResponse> => {\n if (request.gateway === 'query') {\n return handler.query(resolved.operation, request.params);\n } else {\n return handler.mutate(resolved.operation, request.params);\n }\n };\n\n const response = await this.pipeline(request, terminal);\n\n // 5. Stamp timing and tracing metadata\n response.meta.duration_ms = Date.now() - startTime;\n response.meta.requestId = request.requestId;\n response.meta.source = request.source;\n\n // 6. Stamp session identity and lineage (T4959/T10620)\n if (request.sessionId) {\n response.meta.sessionId = request.sessionId;\n }\n if (request.originSessionId) {\n response.meta.originSessionId = request.originSessionId;\n }\n if (request.executionSessionId) {\n response.meta.executionSessionId = request.executionSessionId;\n }\n\n // 7. T1088: Background dialectic evaluation hook\n //\n // Fires asynchronously via setImmediate so the response is returned to the\n // caller immediately. Conditions:\n // a) Response was successful\n // b) This was a mutate (state-modifying, user-facing) operation\n // c) A session ID is present (needed for narrative + source tagging)\n // d) Rate limiter allows this session to be evaluated right now\n //\n // The userMessage is synthesised from the operation + params since the\n // raw CLI string is not available at this layer. Future Wave 4 work can\n // thread the original raw command string through DispatchRequest.\n if (\n response.success &&\n request.gateway === 'mutate' &&\n request.sessionId &&\n isDialecticEvalAllowed(request.sessionId)\n ) {\n const capturedRequest = request;\n const capturedSessionId = request.sessionId;\n\n setImmediate(() => {\n // Lazy import to avoid loading the evaluator at startup (it pulls in\n // the Vercel AI SDK and zod which add ~50ms to cold start).\n //\n // T10351: ALL brain.db row inserts from this hook now flow through\n // the single-writer chokepoint (`enqueueBrainWrite`). The hook still\n // opens a brain handle for the evaluator's reads (RCA confirms WAL\n // reads are not the race vector), and `applyInsights` internally\n // calls `observeBrain` — which now auto-routes every write through\n // the writer queue. Global traits go to nexus.db which is out of\n // scope for the brain chokepoint.\n //\n // T12024: bound the LLM call with an AbortController whose timer is\n // unrefed so the deadline never extends CLI lifetime. The signal\n // cascades through evaluateDialectic → generateObject → the AI-SDK\n // HTTP request; when the signal fires, the fetch is cancelled and\n // the event loop can drain after shutdownCliRuntime.\n const controller = new AbortController();\n const deadline = setTimeout(\n () => controller.abort(new DOMException('DIALECTIC_DEADLINE', 'AbortError')),\n DIALECTIC_DEADLINE_MS,\n );\n deadline.unref();\n\n // T12239: the deadline above is 10s and the exit backstop is 3s, so a\n // dialectic in flight at teardown holds its TCPSocketWrap for up to\n // seven seconds PAST the \"event loop still alive\" warning. Unrefing the\n // TIMER does not unref the SOCKET. Register the controller so\n // shutdownCliRuntime can cancel the fetch itself; if teardown has\n // already begun this aborts immediately.\n const unregisterAbort = registerTeardownAbort(controller);\n\n Promise.all([\n import('@cleocode/core/memory/dialectic-evaluator.js'),\n import('@cleocode/core/store/nexus-sqlite.js'),\n import('@cleocode/core/store/memory-sqlite.js'),\n ])\n .then(async ([{ evaluateDialectic, applyInsights }, { getNexusDb }, { getBrainDb }]) => {\n const projectRoot = getProjectRoot();\n const turn = {\n userMessage: `cleo ${capturedRequest.domain} ${capturedRequest.operation} ${JSON.stringify(capturedRequest.params ?? {})}`,\n systemResponse: `Operation succeeded in domain \"${capturedRequest.domain}\".`,\n activePeerId: (capturedRequest.params?.['peerId'] as string | undefined) ?? 'global',\n sessionId: capturedSessionId,\n // T12543: this turn is an operation and its result envelope,\n // not a user utterance — the evaluator must never mint user\n // traits from it.\n origin: 'operation-envelope' as const,\n };\n\n const insights = await evaluateDialectic(turn, {\n abortSignal: controller.signal,\n });\n\n // applyInsights routes peer-insight writes through\n // `observeBrain → enqueueBrainWrite` automatically. Narrative\n // delta still uses the direct INSERT path (not in the high-volume\n // race surface that the T10301 RCA identified — plasticity_events\n // and weight_history dominate by ~94%). Tracked as a follow-up\n // refinement; out of scope for T10351 chokepoint.\n const [nexusDb, brainDb] = await Promise.all([getNexusDb(), getBrainDb()]);\n await applyInsights(insights, nexusDb, brainDb, {\n sessionId: capturedSessionId,\n activePeerId: turn.activePeerId,\n projectRoot,\n });\n })\n .catch((err: unknown) => {\n const log = getLogger('dialectic-hook');\n log.warn({ err }, 'dialectic-evaluator failed');\n })\n .finally(() => {\n clearTimeout(deadline);\n unregisterAbort();\n });\n });\n }\n\n return response;\n }\n}\n","/**\n * Dispatch-local metadata factory.\n *\n * Generates LAFS-conformant metadata for dispatch layer responses.\n * Generates LAFS-conformant metadata for dispatch responses.\n *\n * @task T4772\n */\n\nimport { randomUUID } from 'node:crypto';\nimport type { DispatchResponse, Source } from '@cleocode/contracts/gateway';\n\n/**\n * Create metadata for a dispatch response.\n *\n * @param gateway - Gateway name (e.g., 'query', 'mutate')\n * @param domain - Domain name (e.g., 'tasks', 'session')\n * @param operation - Operation name (e.g., 'show', 'list')\n * @param startTime - Timestamp from Date.now() at start of request\n * @param source - Where the request originated\n * @param requestId - Optional pre-generated request ID\n * @param sessionId - Optional session ID to include in metadata\n * @param originSessionId - Optional root workflow/saga session ID\n * @param executionSessionId - Optional execution-attempt session ID\n * @returns Metadata conforming to DispatchResponse['meta']\n *\n * @task T4772\n * @task T4959\n */\nexport function createDispatchMeta(\n gateway: string,\n domain: string,\n operation: string,\n startTime: number,\n source: Source = 'cli',\n requestId?: string,\n sessionId?: string | null,\n originSessionId?: string | null,\n executionSessionId?: string | null,\n): DispatchResponse['meta'] {\n return {\n gateway: gateway as DispatchResponse['meta']['gateway'],\n domain,\n operation,\n timestamp: new Date().toISOString(),\n duration_ms: Date.now() - startTime,\n source,\n requestId: requestId ?? randomUUID(),\n ...(sessionId != null && { sessionId }),\n ...(originSessionId != null && { originSessionId }),\n ...(executionSessionId != null && { executionSessionId }),\n };\n}\n","/**\n * Unified CQRS Dispatch Layer -- Middleware Pipeline\n *\n * Provides compose() to chain multiple Middleware functions together\n * into a single executable pipeline.\n *\n * @epic T4820\n * @task T4815\n */\n\nimport type {\n DispatchNext,\n DispatchRequest,\n DispatchResponse,\n Middleware,\n} from '@cleocode/contracts/gateway';\n\n/**\n * Composes an array of Middleware functions into a single Middleware function.\n * Execution flows through the array from first to last, and returns bubble\n * back up from last to first.\n *\n * @remarks\n * Uses an index-tracked dispatch function to prevent `next()` from being\n * called multiple times within a single middleware. If the array is empty,\n * a passthrough middleware that immediately calls `next()` is returned.\n *\n * @param middlewares - Array of middleware functions to chain\n * @returns A single composed Middleware function\n *\n * @example\n * ```typescript\n * import { compose } from './pipeline.js';\n *\n * const pipeline = compose([sanitizer, rateLimiter, protocolEnforcement]);\n * const response = await pipeline(request, handler);\n * ```\n */\nexport function compose(middlewares: Middleware[]): Middleware {\n if (middlewares.length === 0) {\n return async (_req: DispatchRequest, next: DispatchNext) => next();\n }\n\n return async (request: DispatchRequest, next: DispatchNext): Promise<DispatchResponse> => {\n let index = -1;\n\n async function dispatch(i: number): Promise<DispatchResponse> {\n if (i <= index) {\n throw new Error('next() called multiple times in middleware');\n }\n index = i;\n\n let fn: Middleware | undefined = middlewares[i];\n if (i === middlewares.length) {\n // We've reached the end of the middleware chain; call the final handler\n fn = async (_req, nxt) => nxt();\n }\n\n if (!fn) {\n return next();\n }\n\n return fn(request, async () => {\n if (i === middlewares.length) {\n return next();\n }\n return dispatch(i + 1);\n });\n }\n\n return dispatch(0);\n };\n}\n","/**\n * Background Job Manager — gateway re-export.\n *\n * @remarks\n * The Drizzle-backed background-job manager lives in `@cleocode/core/store`\n * (R3-K1 · T11455 · SG-RUNTIME-UNIFICATION) — that is the package which owns the\n * consolidated SQLite schema and the SINGLE `drizzle-orm` instance, so the query\n * builders type-check against one instance (no dual peer-hashed `SQL<unknown>`\n * mismatch under `tsc -b`). This module re-exports that surface so the gateway\n * (and the `@cleocode/runtime/gateway` barrel) expose `BackgroundJobManager` etc.\n * WITHOUT `@cleocode/runtime` taking its own `drizzle-orm` dependency.\n *\n * @task T641\n * @task T11455\n */\n\nexport {\n type BackgroundJob,\n BackgroundJobManager,\n type BackgroundJobManagerConfig,\n type BackgroundJobStatus,\n DurableJobStore,\n} from '@cleocode/core/store/background-jobs.js';\n","/**\n * The gateway as a supervised **daemon subsystem**.\n *\n * R3-T7 (this task) closes the loop between the two R-track halves: the R3\n * gateway (dispatcher + the four transport adapters) and the R2 daemon\n * (`defineSubsystem` + the `SubsystemRegistry`). It expresses the\n * external-facing gateway as a uniform {@link Subsystem} so the R2 daemon\n * registry drives its `start → healthProbe → shutdown` lifecycle exactly like\n * every other long-running concern (Studio supervision, the GC cron, …). One\n * gateway subsystem is registered per scope (project / global) → one\n * external-facing gateway process per scope.\n *\n * Which transports the daemon hosts:\n * - the **RPC unix socket** (`@cleocode/runtime/gateway/rpc`) — the canonical\n * local-client wire: the `cleo` CLI, Studio's server process, and test\n * harnesses open it to dispatch without paying a cold `cleo` spawn.\n * - the **HTTP server** (`@cleocode/runtime/gateway/http` via the daemon-local\n * `startHttpServer` embedder) — for external clients that speak HTTP rather\n * than the unix-socket NDJSON wire.\n *\n * The CLI and MCP adapters are intentionally NOT hosted by the daemon: the CLI\n * adapter is in-process to the `cleo` binary, and the MCP adapter is a stdio\n * server an MCP client spawns and owns — neither is a long-lived,\n * daemon-supervised listener. The two external-facing listeners (RPC + HTTP)\n * are the ones the daemon owns.\n *\n * This subsystem adds NO behavior to the adapters themselves — it only wires\n * their existing `start*Server` / `close()` lifecycle (and their already-merged\n * routing) into the daemon registry's uniform lifecycle. It carries NO\n * `@cleocode/cleo` dependency and NO drizzle-orm (the runtime invariant): the\n * caller injects the assembled {@link GatewayHandler} and the resolved bind\n * coordinates; this module only orchestrates listeners.\n *\n * @packageDocumentation\n * @module @cleocode/runtime/gateway\n *\n * @task T11451 (R3-T7)\n * @epic T11254\n * @saga T11243 SG-RUNTIME-UNIFICATION\n */\n\nimport type { Subsystem, SubsystemHealth, SubsystemState } from '@cleocode/contracts';\nimport { getLogger } from '@cleocode/core';\nimport { defineSubsystem } from '../daemon/index.js';\nimport { type HttpServerHandle, type HttpServerOptions, startHttpServer } from './http/listen.js';\nimport type { GatewayHandler } from './index.js';\nimport { type RpcServerHandle, type RpcServerOptions, startRpcServer } from './rpc/index.js';\n\n/** The scope a single gateway process serves — one external-facing process per scope. */\nexport type GatewayScope = 'project' | 'global';\n\n/**\n * Configuration for one scoped gateway subsystem.\n *\n * The caller injects the assembled, transport-neutral {@link GatewayHandler}\n * (built with `createGatewayHandler` from its domain handlers + middleware) and\n * the resolved bind coordinates for each hosted transport. The runtime never\n * resolves paths/ports itself — that keeps it free of `@cleocode/paths` and of\n * any policy decision about where a scope's socket/port lives.\n */\nexport interface GatewaySubsystemOptions {\n /** The scope this gateway process serves (`project` | `global`). */\n scope: GatewayScope;\n /** The transport-neutral gateway handler every hosted transport routes through. */\n handler: GatewayHandler;\n /**\n * RPC unix-socket transport options. When omitted, the RPC transport is not\n * hosted (a deployment that only wants HTTP). At least one transport MUST be\n * configured.\n */\n rpc?: RpcServerOptions;\n /**\n * HTTP transport options. When omitted, the HTTP transport is not hosted (a\n * deployment that only wants the local RPC socket). At least one transport\n * MUST be configured.\n */\n http?: HttpServerOptions;\n}\n\n/**\n * The live context a started gateway subsystem threads from `start` into\n * `healthProbe`/`shutdown`: the bound transport handles plus the owning pid.\n *\n * `void`-typed contexts are common for subsystems, but the gateway needs to\n * carry its bound handles so `shutdown` can close exactly what `start` opened\n * (and `healthProbe` can report the bound coordinates).\n */\nexport interface GatewaySubsystemContext {\n /** The OS pid hosting the listeners (this daemon process). */\n readonly pid: number;\n /** The bound RPC server handle, when the RPC transport is hosted. */\n readonly rpc?: RpcServerHandle;\n /** The bound HTTP server handle, when the HTTP transport is hosted. */\n readonly http?: HttpServerHandle;\n}\n\n/**\n * The stable subsystem name (and supervised `child_id`) of a scoped gateway.\n *\n * Suffixed with the scope so a single daemon process supervising both scopes\n * (project + global) registers two distinct, non-colliding subsystems. The\n * `child_id` matches the id the Rust supervisor tracks the listener under.\n *\n * @param scope - The gateway scope.\n * @returns The subsystem name, e.g. `gateway-project`.\n */\nexport function gatewaySubsystemName(scope: GatewayScope): string {\n return `gateway-${scope}`;\n}\n\n/**\n * Declare the external-facing gateway as a supervised daemon {@link Subsystem}.\n *\n * The returned subsystem (frozen by {@link defineSubsystem}) is registered with\n * a `SubsystemRegistry`, which then drives its lifecycle uniformly:\n *\n * - `start()` — binds the configured transports (RPC unix socket and/or\n * HTTP server) over the injected handler, in a fixed order (RPC then HTTP).\n * If the second listener fails to bind, the first is rolled back so a failed\n * start leaves no half-open listener — then the error is re-thrown for the\n * registry's `onError` sink.\n * - `healthProbe()` — reports a single {@link SubsystemHealth} row keyed on the\n * scoped `child_id`, `running` while the configured listeners are live, with\n * a `detail` summarizing the bound coordinates. Projects losslessly onto the\n * supervisor's `ChildStatus`.\n * - `shutdown()` — closes every bound listener (best-effort, idempotent) in\n * reverse bind order (HTTP then RPC).\n *\n * One subsystem instance is declared per scope, so registering the project and\n * global gateways yields two supervised listeners → one external-facing gateway\n * process surface per scope (AC1).\n *\n * @param opts - The scoped gateway configuration (handler + per-transport bind\n * coordinates).\n * @returns A frozen {@link Subsystem} ready to `register()` with a\n * `SubsystemRegistry`.\n * @throws {TypeError} When neither the RPC nor the HTTP transport is configured\n * (a gateway with no hosted transport serves nothing).\n *\n * @example\n * ```ts\n * const registry = new SubsystemRegistry();\n * registry.register(\n * defineGatewaySubsystem({\n * scope: 'project',\n * handler: createGatewayHandler(dispatcherConfig),\n * rpc: { socketPath: '/run/cleo/cleo-gateway-rpc-project.sock' },\n * http: { port: 7777 },\n * }),\n * );\n * await registry.startAll(); // binds the RPC socket + HTTP server\n * const health = await registry.aggregateHealth();\n * await registry.shutdownAll(); // closes both listeners\n * ```\n */\nexport function defineGatewaySubsystem(\n opts: GatewaySubsystemOptions,\n): Subsystem<GatewaySubsystemContext> {\n if (opts.rpc === undefined && opts.http === undefined) {\n throw new TypeError(\n 'defineGatewaySubsystem: at least one transport (rpc and/or http) must be configured',\n );\n }\n\n const name = gatewaySubsystemName(opts.scope);\n const log = getLogger(name);\n\n // The `Subsystem.healthProbe` contract takes NO arguments — the registry only\n // threads the start→shutdown context, not into the probe. We therefore hold\n // the live context in a closure so `healthProbe()` can read the bound handles\n // (and report `stopped` before `start()`/after `shutdown()`).\n let live: GatewaySubsystemContext | undefined;\n\n return defineSubsystem<GatewaySubsystemContext>({\n name,\n\n async start(): Promise<GatewaySubsystemContext> {\n // Bind RPC first, then HTTP, so the unix socket is available before the\n // HTTP listener (the canonical local wire comes up first). On an HTTP\n // bind failure, roll back the RPC socket so start() never leaves a\n // half-open listener for the registry's onError to clean up after.\n let rpc: RpcServerHandle | undefined;\n try {\n if (opts.rpc !== undefined) {\n rpc = await startRpcServer(opts.handler, opts.rpc);\n }\n let http: HttpServerHandle | undefined;\n if (opts.http !== undefined) {\n http = await startHttpServer(opts.handler, opts.http);\n }\n const context: GatewaySubsystemContext = { pid: process.pid, rpc, http };\n live = context;\n log.info(\n { scope: opts.scope, rpc: rpc?.socketPath, httpPort: http?.port },\n 'gateway subsystem started',\n );\n return context;\n } catch (cause) {\n // Roll back any listener already bound before re-throwing.\n if (rpc !== undefined) {\n await rpc.close().catch(() => undefined);\n }\n live = undefined;\n throw cause;\n }\n },\n\n healthProbe(): SubsystemHealth {\n // Not started (or already shut down) → report a stopped row so the\n // aggregate `allHealthy` cannot be falsely true.\n if (live === undefined) {\n const stopped: SubsystemState = 'stopped';\n return {\n child_id: name,\n pid: 0,\n state: stopped,\n restart_count: 0,\n detail: `scope=${opts.scope} not started`,\n };\n }\n const transports: string[] = [];\n if (live.rpc !== undefined) transports.push(`rpc=${live.rpc.socketPath}`);\n if (live.http !== undefined) {\n transports.push(`http=${live.http.host}:${live.http.port}`);\n }\n const running: SubsystemState = 'running';\n return {\n child_id: name,\n pid: live.pid,\n state: running,\n restart_count: 0,\n detail: `scope=${opts.scope} ${transports.join(' ')}`.trim(),\n };\n },\n\n async shutdown(context: GatewaySubsystemContext): Promise<void> {\n // Reverse bind order: close HTTP before the RPC socket. Both close()\n // calls are idempotent and best-effort — one failure must not block the\n // other listener's teardown.\n if (context.http !== undefined) {\n await context.http.close().catch((err: unknown) => {\n log.warn({ err }, 'gateway http close failed');\n });\n }\n if (context.rpc !== undefined) {\n await context.rpc.close().catch((err: unknown) => {\n log.warn({ err }, 'gateway rpc close failed');\n });\n }\n live = undefined;\n log.info({ scope: opts.scope }, 'gateway subsystem stopped');\n },\n });\n}\n","/**\n * Engine Re-exports for Gateway Domain Handlers\n *\n * Centralizes the engine imports consumed by the domain handlers into a single\n * barrel. Every symbol re-exported here ultimately resolves to\n * `@cleocode/core/internal` (the canonical business-logic SSoT) or core's\n * template parser — this file adds NO logic of its own.\n *\n * @remarks\n * Relocated from `packages/cleo/src/dispatch/lib/engine.ts` into\n * `@cleocode/runtime/gateway` (R3-K1 · T11455 · SG-RUNTIME-UNIFICATION) so the\n * runtime can assemble the handler map without importing `@cleocode/cleo`.\n * Mirrors the `meta` / `registry` / `dispatcher` relocations (R3-T3 · T11447).\n * A thin re-export shim remains at the old `lib/engine.ts` path so the\n * in-package import sites compile unchanged (zero behavior change).\n *\n * @epic T4820\n * @task T4815\n * @task T11455\n */\n\nexport type { MinimalTaskRecord, Session as SessionRecord, TaskRecord } from '@cleocode/contracts';\nexport type { OrchestratePlanResult } from '@cleocode/contracts/operations/orchestrate';\n// Task operations — re-exported from @cleocode/core/internal (T1568 / ADR-057 / ADR-058)\n// task-engine.ts was deleted in Wave 5; all symbols now live in core/tasks/.\n// Orchestrate — types and functions from @cleocode/core/internal (T1570 ADR-057)\n// System — type aliases for backward compat (T1571: system-engine.ts deleted, canonical sources = @cleocode/core/internal)\nexport type {\n ArchiveStatsResult as ArchiveStatsData,\n AuditResult as AuditData,\n BackupEntry as BackupEntryData,\n BackupResult as BackupData,\n CleanupResult as CleanupData,\n CompactTask,\n ComplianceData,\n ContextData,\n DashboardData,\n DiagnosticsResult as DiagnosticsData,\n FileRestoreResult,\n HealthResult as HealthData,\n HelpData,\n InjectGenerateResult as InjectGenerateData,\n IvtrHistoryEntry,\n LabelsResult as LabelsData,\n LifecycleStageEntry,\n LogQueryData,\n MigrateResult as MigrateData,\n OrchestratePlanInput,\n PathsData,\n PlanWarning,\n PlanWave,\n PlanWorkerEntry,\n RestoreResult as RestoreData,\n RuntimeDiagnostics as RuntimeData,\n SafestopResult as SafestopData,\n ScaffoldHubData,\n StatsData,\n SyncData,\n SystemMetricsResult as MetricsData,\n UncancelResult as UncancelData,\n} from '@cleocode/core/internal';\n// Pipeline manifest functions (moved from memory domain in T5241)\n// Release engine (T1572 — ENG-MIG-5: migrated to @cleocode/core/internal)\n// Session engine (T1573 — ENG-MIG-6: migrated to @cleocode/core/internal)\n// Lifecycle engine ops — re-exported from @cleocode/core/internal (T1576 / ENG-MIG-9 / ADR-057)\n// lifecycle-engine.ts shrunk to a shim; all symbols now live in core/lifecycle/engine-ops.ts.\n// Hooks engine (ENG-MIG-12 / T1579 — logic in @cleocode/core/internal)\n// Init engine-ops — migrated to @cleocode/core/internal (ENG-MIG-14 / T1581 / ADR-057)\n// Config engine-ops — migrated to @cleocode/core/internal (ENG-MIG-15 / T1582 / ADR-057)\n// config-engine.ts shrunk to a shim; all symbols now live in core/config/engine-ops.ts.\n// Codebase map — re-exported from core (engine shim deleted, T1584)\n// Memory engine — brain.db cognitive memory (T5241 cutover)\n// Validate engine — direct from core (was a rename shim, now inlined here)\nexport {\n addTaskWithSessionScope,\n completeTaskStrict,\n configGet,\n configListPresets,\n configSet,\n configSetPreset,\n coreBatchValidate as validateBatchValidate,\n coreCoherenceCheck as validateCoherenceCheck,\n coreComplianceRecord as validateComplianceRecord,\n coreComplianceSummary as validateComplianceSummary,\n coreComplianceViolations as validateComplianceViolations,\n coreTestCoverage as validateTestCoverage,\n coreTestRun as validateTestRun,\n coreTestStatus as validateTestStatus,\n coreValidateManifest as validateManifestOp,\n coreValidateOutput as validateOutput,\n coreValidateProtocol as validateProtocol,\n coreValidateSchema as validateSchemaOp,\n coreValidateTask as validateTaskOp,\n type DecisionRecord,\n ensureInitialized,\n filterEntries as filterManifestEntries,\n getVersion,\n type HookMatrixResult,\n initProject,\n isAutoInitEnabled,\n lifecycleCheck,\n lifecycleGateFail,\n lifecycleGatePass,\n lifecycleGates,\n lifecycleHistory,\n lifecyclePrerequisites,\n lifecycleProgress,\n lifecycleReset,\n lifecycleSkip,\n lifecycleStatus,\n type ManifestEntry as ResearchManifestEntry,\n mapCodebase,\n memoryBrainStats,\n memoryContradictions,\n memoryDecisionFind,\n memoryDecisionStore,\n memoryFetch,\n memoryFind,\n memoryGraphAdd,\n memoryGraphContext,\n memoryGraphNeighbors,\n memoryGraphRelated,\n memoryGraphRemove,\n memoryGraphShow,\n memoryGraphStatsFull,\n memoryGraphTrace,\n memoryLearningFind,\n memoryLearningStats,\n memoryLearningStore,\n memoryLink,\n memoryObserve,\n memoryPatternFind,\n memoryPatternStats,\n memoryPatternStore,\n memoryQualityReport,\n memoryReasonSimilar,\n memoryReasonWhy,\n memorySearchHybrid,\n memoryShow,\n memorySuperseded,\n memoryTimeline,\n memoryUnlink,\n orchestrateAnalyze,\n orchestrateBootstrap,\n orchestrateCheck,\n orchestrateContext,\n orchestrateCriticalPath,\n orchestrateHandoff,\n orchestrateNext,\n orchestrateParallelEnd,\n orchestrateParallelStart,\n orchestratePlan,\n orchestrateReady,\n orchestrateReport,\n orchestrateSkillInject,\n orchestrateSpawn,\n orchestrateSpawnExecute,\n orchestrateStartup,\n orchestrateStatus,\n orchestrateUnblockOpportunities,\n orchestrateValidate,\n orchestrateWaves,\n type ProviderMatrixEntry,\n // Pipeline engine-ops (ENG-MIG-11 / T1578 — migrated to @cleocode/core/internal)\n // pipeline-engine.ts shrunk to a shim; all symbols now live in core/pipeline/engine-ops.ts.\n phaseAdvance,\n phaseComplete,\n phaseDelete,\n phaseList,\n phaseRename,\n phaseSet,\n phaseShow,\n phaseStart,\n pipelineManifestAppend,\n pipelineManifestArchive,\n pipelineManifestFind,\n pipelineManifestList,\n pipelineManifestPending,\n pipelineManifestShow,\n pipelineManifestStats,\n queryCommonHooks,\n queryHookProviders,\n readManifestEntries,\n releaseCancel,\n releaseCommit,\n releaseGateCheck,\n releaseGatesRun,\n releaseIvtrAutoSuggest,\n releaseList,\n releaseOpen,\n releasePlan,\n releasePrepare,\n releasePrStatus,\n releasePush,\n releaseReconcileV2,\n releaseRollback,\n releaseRollbackFull,\n releaseShow,\n releaseTag,\n sessionAdopt,\n sessionArchive,\n sessionBriefing,\n sessionChainShow,\n sessionCleanup,\n // T4959: Rich debrief + chain\n sessionComputeDebrief,\n sessionComputeHandoff,\n sessionContextDrift,\n sessionContextInject,\n sessionDebriefShow,\n sessionDecisionLog,\n sessionEnd,\n // T5119: Lightweight session discovery\n sessionFind,\n sessionGc,\n sessionHandoff,\n sessionHistory,\n sessionList,\n sessionRecordAssumption,\n sessionRecordDecision,\n sessionResume,\n sessionShow,\n sessionStart,\n sessionStats,\n sessionStatus,\n sessionSuspend,\n sessionSwitch,\n systemHooksMatrix,\n taskAnalyze,\n taskArchive,\n // T11786 (epic T11556) — first-class assignee set/clear (distinct from claim).\n taskAssignee,\n taskBatchValidate,\n taskBlockers,\n // T11786 (epic T11556) — atomic multi-task status/stage move.\n taskBulkMove,\n taskCancel,\n taskClaim,\n taskComplete,\n taskComplexityEstimate,\n taskCurrentGet,\n taskDecompose,\n taskDelete,\n taskDepends,\n taskDeps,\n taskDepsCycles,\n taskDepsOverview,\n taskDepsTree,\n taskDepsValidate,\n taskExists,\n taskExport,\n taskFind,\n taskHistory,\n taskImpact,\n taskImport,\n taskLabelList,\n taskLabelShow,\n taskLint,\n taskList,\n taskNext,\n taskPlan,\n taskPromote,\n taskRankingHistory,\n taskRankingRevert,\n taskReconcileScope,\n taskRelates,\n taskRelatesAdd,\n taskRelatesAddBatch,\n taskRelatesFind,\n taskRelatesRemove,\n taskReopen,\n taskReorder,\n // T11786 (epic T11556) — explicit within-column re-rank from an ID order.\n taskReorderRank,\n taskReparent,\n taskRestore,\n taskShow,\n taskShowIvtrHistory,\n taskShowOperation,\n taskShowWithHistory,\n taskSlice,\n taskStart,\n taskStats,\n taskStop,\n taskSyncLinks,\n taskSyncLinksRemove,\n taskSyncReconcile,\n tasksAddBatchOp,\n taskTree,\n taskUnarchive,\n taskUnclaim,\n taskUpdate,\n taskWorkHistory,\n // T9937 — validate-changelog verb (Saga T9862)\n validateChangelog,\n validateGateVerify,\n // T5327 + T260: Protocol validation operations (12 protocols)\n validateProtocolArchitectureDecision,\n validateProtocolArtifactPublish,\n validateProtocolConsensus,\n validateProtocolContribution,\n validateProtocolDecomposition,\n validateProtocolImplementation,\n validateProtocolProvenance,\n validateProtocolRelease,\n validateProtocolResearch,\n validateProtocolSpecification,\n validateProtocolTesting,\n validateProtocolValidation,\n} from '@cleocode/core/internal';\n// Template parser engine\nexport {\n generateTemplateConfig,\n getTemplateForSubcommand,\n type IssueTemplate,\n parseIssueTemplates,\n type TemplateConfig,\n type TemplateSection,\n validateLabels,\n} from './template-parser.js';\n","/**\n * Template Parser Engine (Re-export Adapter)\n *\n * Thin re-export from core's templates/parser, adapting the core\n * TemplateResult type to the gateway EngineResult type.\n *\n * All business logic lives in `@cleocode/core/internal`.\n * This file preserves backward compatibility for existing importers.\n *\n * @remarks\n * Relocated from `packages/cleo/src/dispatch/engines/template-parser.ts` into\n * `@cleocode/runtime/gateway` (R3-K1 · T11455 · SG-RUNTIME-UNIFICATION) as a\n * dependency of the relocated engine barrel.\n *\n * @task T5705\n * @task T11455\n * @epic T5701\n */\n\nimport {\n generateTemplateConfig as coreGenerateTemplateConfig,\n getTemplateForSubcommand as coreGetTemplateForSubcommand,\n parseIssueTemplates as coreParseIssueTemplates,\n templates,\n} from '@cleocode/core/internal';\nimport type { EngineResult } from './engine-error.js';\n\n// Re-export types directly from core\nexport type {\n IssueTemplate,\n TemplateConfig,\n TemplateSection,\n} from '@cleocode/core/internal';\n\n/**\n * Adapt a core TemplateResult to an EngineResult.\n * The shapes are compatible -- TemplateResult is a subset of EngineResult.\n */\nfunction adaptResult<T>(result: {\n success: boolean;\n data?: T;\n error?: { code: string; message: string; details?: Record<string, unknown> };\n}): EngineResult<T> {\n if (result.success) {\n if (result.data === undefined) {\n return {\n success: false,\n error: { code: 'E_INTERNAL', message: 'Template parser succeeded with no data' },\n };\n }\n return { success: true, data: result.data };\n }\n return {\n success: false,\n error: result.error\n ? {\n code: result.error.code,\n message: result.error.message,\n ...(result.error.details ? { details: result.error.details } : {}),\n }\n : { code: 'E_INTERNAL', message: 'Unknown error' },\n };\n}\n\n/**\n * Parse all templates from the repo's .github/ISSUE_TEMPLATE/ directory.\n *\n * @remarks\n * Delegates to the core template parser and adapts the result to the\n * dispatch EngineResult type.\n *\n * @param projectRoot - Absolute path to the project root\n * @returns EngineResult containing the parsed template configuration\n *\n * @example\n * ```typescript\n * const result = parseIssueTemplates('/path/to/project');\n * if (result.success) {\n * console.log(result.data.templates);\n * }\n * ```\n */\nexport function parseIssueTemplates(\n projectRoot: string,\n): EngineResult<import('@cleocode/core/internal').TemplateConfig> {\n return adaptResult(coreParseIssueTemplates(projectRoot));\n}\n\n/**\n * Get template config for a specific subcommand (bug/feature/help).\n *\n * @remarks\n * Looks up a specific template by subcommand name from the project's\n * issue template directory.\n *\n * @param projectRoot - Absolute path to the project root\n * @param subcommand - Template subcommand identifier (e.g. \"bug\", \"feature\")\n * @returns EngineResult containing the matched issue template\n *\n * @example\n * ```typescript\n * const result = getTemplateForSubcommand('/path/to/project', 'bug');\n * ```\n */\nexport function getTemplateForSubcommand(\n projectRoot: string,\n subcommand: string,\n): EngineResult<import('@cleocode/core/internal').IssueTemplate> {\n return adaptResult(coreGetTemplateForSubcommand(projectRoot, subcommand));\n}\n\n/**\n * Generate and cache the config as .cleo/issue-templates.json.\n *\n * @remarks\n * Parses all templates and writes the resulting config to disk for caching.\n *\n * @param projectRoot - Absolute path to the project root\n * @returns EngineResult containing the generated template configuration\n *\n * @example\n * ```typescript\n * const result = await generateTemplateConfig('/path/to/project');\n * ```\n */\nexport async function generateTemplateConfig(\n projectRoot: string,\n): Promise<EngineResult<import('@cleocode/core/internal').TemplateConfig>> {\n return adaptResult(await coreGenerateTemplateConfig(projectRoot));\n}\n\n/**\n * Validate that labels exist on a GitHub repo.\n *\n * @remarks\n * Compares a set of required labels against the labels found on the repo.\n *\n * @param labels - Labels required by the template\n * @param repoLabels - Labels that exist on the GitHub repo\n * @returns EngineResult with existing and missing label lists\n *\n * @example\n * ```typescript\n * const result = validateLabels(['bug', 'enhancement'], repoLabels);\n * ```\n */\nexport function validateLabels(\n labels: string[],\n repoLabels: string[],\n): EngineResult<{ existing: string[]; missing: string[] }> {\n return adaptResult(templates.validateLabels(labels, repoLabels));\n}\n","/**\n * Centralized engine error helper for the transport-agnostic gateway.\n *\n * Every domain handler (and the engine barrel) imports `engineError()` /\n * `engineSuccess()` from this module to produce consistently typed error\n * results with correct exit codes and pino logging.\n *\n * The STRING_TO_EXIT map is the canonical mapping from string error codes\n * to numeric exit codes. It mirrors ERROR_CODE_TO_EXIT in cli.ts.\n *\n * @remarks\n * Relocated from `packages/cleo/src/dispatch/engines/_error.ts` into\n * `@cleocode/runtime/gateway` (R3-K1 · T11455 · SG-RUNTIME-UNIFICATION) so the\n * runtime owns the shared handler dependencies and can assemble the handler map\n * without importing `@cleocode/cleo`. A thin re-export shim remains at the old\n * `engines/_error.ts` path so in-package import sites compile unchanged.\n *\n * Error codes are organized into numeric ranges:\n * - 1-9: General errors (invalid input, file, dependency, validation)\n * - 10-19: Hierarchy errors (parent, depth, siblings, circular deps)\n * - 20-29: Concurrency errors (checksum, modification, collision)\n * - 30-39: Session errors (scope, claims, active task)\n * - 40-47: Verification errors (gates, agents, rounds)\n * - 50-54: Context safeguard (warning through emergency)\n * - 60-67: Orchestrator / protocol errors\n * - 70-79: Nexus errors\n * - 80-94: Lifecycle, artifact, provenance errors\n * - 95-99: Adapter errors\n * - 100+: Special informational codes (not errors)\n */\n\nimport {\n engineError as coreEngineError,\n type EngineResult,\n getLogger,\n type ProblemDetails,\n} from '@cleocode/core';\nimport { mapNumericExitCodeToString } from './exit-codes.js';\n\n// Re-export EngineResult from core (canonical location)\nexport type { EngineResult } from '@cleocode/core';\n\n/**\n * Canonical mapping from string error codes to numeric exit codes.\n *\n * Source of truth: src/types/exit-codes.ts (ExitCode enum).\n * Must stay in sync with ERROR_CODE_TO_EXIT in src/dispatch/adapters/cli.ts.\n */\nexport const STRING_TO_EXIT: Record<string, number> = {\n // General Errors (1-9)\n E_GENERAL: 1,\n E_GENERAL_ERROR: 1,\n E_INVALID_INPUT: 2,\n E_MISSING_PARAMS: 2,\n E_INVALID_OPERATION: 2,\n E_FILE_ERROR: 3,\n E_NOT_FOUND: 4,\n E_DEPENDENCY: 5,\n E_DEPENDENCY_ERROR: 5,\n E_VALIDATION: 6,\n E_VALIDATION_FAILED: 6,\n E_VALIDATION_ERROR: 6,\n E_RETRYABLE: 7,\n E_LOCK_TIMEOUT: 7,\n E_CONFIG_ERROR: 8,\n E_PROJECT_MOVED: 9,\n\n // Hierarchy Errors (10-19)\n E_PARENT_NOT_FOUND: 10,\n E_DEPTH_EXCEEDED: 11,\n E_SIBLING_LIMIT: 12,\n E_INVALID_PARENT_TYPE: 13,\n E_INVALID_PARENT: 13,\n E_CIRCULAR_DEP: 14,\n E_CIRCULAR_REFERENCE: 14,\n E_ORPHAN_DETECTED: 15,\n E_HAS_CHILDREN: 16,\n E_TASK_COMPLETED: 17, // ExitCode.TASK_COMPLETED — canonical value from @cleocode/contracts\n E_CASCADE_FAILED: 18,\n E_HAS_DEPENDENTS: 19,\n\n // Concurrency Errors (20-29)\n E_CHECKSUM_MISMATCH: 20,\n E_CONCURRENT_MODIFICATION: 21,\n E_ID_COLLISION: 22,\n E_CONFLICT: 23,\n E_SESSION_UNBOUND: 24,\n E_WORKTREE_LOCKED: 25,\n E_TASK_RENAMED: 26,\n\n // Session Errors (30-39)\n E_SESSION_EXISTS: 30,\n E_SESSION_CONFLICT: 30,\n E_SESSION_NOT_FOUND: 31,\n E_SCOPE_CONFLICT: 32,\n E_SCOPE_INVALID: 33,\n E_TASK_NOT_IN_SCOPE: 34,\n E_TASK_CLAIMED: 35,\n E_SESSION_REQUIRED: 36,\n E_SESSION_CLOSE_BLOCKED: 37,\n E_ACTIVE_TASK_REQUIRED: 38,\n E_NOTES_REQUIRED: 39,\n\n // Verification Errors (40-47)\n E_VERIFICATION_INIT_FAILED: 40,\n E_GATE_UPDATE_FAILED: 41,\n E_INVALID_GATE: 42,\n E_INVALID_AGENT: 43,\n E_MAX_ROUNDS_EXCEEDED: 44,\n E_GATE_DEPENDENCY: 45,\n E_VERIFICATION_LOCKED: 46,\n E_ROUND_MISMATCH: 47,\n // T1590 — Acceptance-criteria immutability after implementation stage\n E_AC_LOCKED: 48,\n\n // Context Safeguard (50-54)\n E_CONTEXT_WARNING: 50,\n E_CONTEXT_CAUTION: 51,\n E_CONTEXT_CRITICAL: 52,\n E_CONTEXT_EMERGENCY: 53,\n E_CONTEXT_STALE: 54,\n\n // Orchestrator / Protocol Errors (60-67)\n E_PROTOCOL_MISSING: 60,\n E_PROTOCOL_RESEARCH: 60,\n E_INVALID_RETURN_MESSAGE: 61,\n E_PROTOCOL_CONSENSUS: 61,\n E_MANIFEST_ENTRY_MISSING: 62,\n E_PROTOCOL_SPECIFICATION: 62,\n E_SPAWN_VALIDATION_FAILED: 63,\n E_PROTOCOL_DECOMPOSITION: 63,\n E_AUTONOMOUS_BOUNDARY: 64,\n E_PROTOCOL_IMPLEMENTATION: 64,\n E_HANDOFF_REQUIRED: 65,\n E_PROTOCOL_CONTRIBUTION: 65,\n E_RESUME_FAILED: 66,\n E_PROTOCOL_RELEASE: 66,\n E_CONCURRENT_SESSION: 67,\n E_PROTOCOL_GENERIC: 67,\n\n // Nexus Errors (70-79)\n E_NEXUS_NOT_INITIALIZED: 70,\n E_NEXUS_PROJECT_NOT_FOUND: 71,\n E_NEXUS_PERMISSION_DENIED: 72,\n E_NEXUS_INVALID_SYNTAX: 73,\n E_NEXUS_SYNC_FAILED: 74,\n E_NEXUS_REGISTRY_CORRUPT: 75,\n // T12512: the registry could not be read (unreadable, locked, missing table).\n // Shares 75 with E_NEXUS_REGISTRY_CORRUPT: both mean \"registry unusable\".\n E_NEXUS_REGISTRY_READ: 75,\n // T12513: a fleet `--device` filter named no known device.\n E_NEXUS_DEVICE_NOT_FOUND: 4,\n E_NEXUS_PROJECT_EXISTS: 76,\n E_NEXUS_QUERY_FAILED: 77,\n E_NEXUS_GRAPH_ERROR: 78,\n\n // Lifecycle Enforcement (80-84)\n E_LIFECYCLE_GATE_FAILED: 80,\n E_AUDIT_MISSING: 81,\n E_CIRCULAR_VALIDATION: 82,\n E_LIFECYCLE_TRANSITION_INVALID: 83,\n E_IVTR_INCOMPLETE: 83,\n E_PROVENANCE_REQUIRED: 84,\n // T1162: lifecycle scope guard — maps to ExitCode.TASK_NOT_IN_SCOPE (34)\n // because a subagent attempting to mutate a parent epic's lifecycle is\n // operating outside the scope granted by its session.\n E_LIFECYCLE_SCOPE_DENIED: 34,\n\n // Artifact Publish (85-89)\n E_ARTIFACT_TYPE_UNKNOWN: 85,\n E_ARTIFACT_VALIDATION_FAILED: 86,\n E_ARTIFACT_BUILD_FAILED: 87,\n E_ARTIFACT_PUBLISH_FAILED: 88,\n E_ARTIFACT_ROLLBACK_FAILED: 89,\n\n // Provenance (90-94)\n E_PROVENANCE_CONFIG_INVALID: 90,\n E_SIGNING_KEY_MISSING: 91,\n E_SIGNATURE_INVALID: 92,\n E_DIGEST_MISMATCH: 93,\n E_ATTESTATION_INVALID: 94,\n\n // Special Codes (100+) - NOT errors\n E_NO_DATA: 100,\n E_ALREADY_EXISTS: 101,\n E_NO_CHANGE: 102,\n E_TESTS_SKIPPED: 103,\n\n // Adapter Errors (95-99)\n E_ADAPTER_NOT_FOUND: 95,\n E_ADAPTER_INIT_FAILED: 96,\n E_ADAPTER_HOOK_FAILED: 97,\n E_ADAPTER_SPAWN_FAILED: 98,\n E_ADAPTER_INSTALL_FAILED: 99,\n\n // Common engine-specific aliases\n E_NOT_INITIALIZED: 3,\n E_NO_HANDLER: 1,\n E_INTERNAL: 1,\n E_LIST_FAILED: 3,\n E_READ_FAILED: 3,\n E_WRITE_FAILED: 3,\n E_PARSE_ERROR: 2,\n E_TEMPLATE_ERROR: 2,\n};\n\n/**\n * Derive pino log level from exit code.\n *\n * - 100+: special/informational -> 'debug'\n * - 1-9 internal errors (1, 3): -> 'error'\n * - 10-99 user/domain errors: -> 'warn'\n * - 0: success (should not be called for errors) -> 'debug'\n */\nfunction logLevel(exitCode: number): 'error' | 'warn' | 'debug' {\n if (exitCode === 0 || exitCode >= 100) return 'debug';\n // Internal errors: general (1), file (3) — these indicate bugs or system issues\n if (exitCode === 1 || exitCode === 3) return 'error';\n // Everything else is a user/domain error\n return 'warn';\n}\n\n/**\n * Create a typed engine error result with pino logging and correct exit code.\n *\n * @remarks\n * The exit code is derived from the {@link STRING_TO_EXIT} mapping. If the\n * code is not found in the map, exit code 1 (general error) is used.\n * Pino logging is automatically triggered at the appropriate level\n * (error for internal issues, warn for user/domain errors, debug for\n * informational codes). Logging is suppressed under Vitest to keep\n * test output clean.\n *\n * @param code - String error code (e.g., 'E_NOT_FOUND')\n * @param message - Human-readable error message\n * @param options - Optional details, fix command, and alternatives\n * @returns EngineResult with success=false and properly structured error\n *\n * @example\n * ```typescript\n * import { engineError } from './_error.js';\n *\n * return engineError('E_NOT_FOUND', `Task ${id} not found`, {\n * fix: `cleo show ${id}`,\n * details: { taskId: id },\n * });\n * ```\n */\nexport function engineError<T>(\n code: string,\n message: string,\n options?: {\n exitCode?: number;\n details?: Record<string, unknown>;\n fix?: string;\n alternatives?: Array<{ action: string; command: string }>;\n problemDetails?: ProblemDetails;\n },\n): EngineResult<T> {\n const resolvedExitCode = options?.exitCode ?? STRING_TO_EXIT[code] ?? 1;\n const level = logLevel(resolvedExitCode);\n\n // Keep test output clean: skip engine logging under Vitest.\n const isVitest = process.env['VITEST'] === 'true';\n if (!isVitest) {\n // Lazy logger acquisition: avoids capturing the stderr fallback logger\n // at module load time (before CLI's preAction hook calls initLogger()).\n // This prevents the double-output envelope bug (T5148).\n const logger = getLogger('engine');\n logger[level](\n { code, exitCode: resolvedExitCode, ...(options?.details && { details: options.details }) },\n message,\n );\n }\n\n // Delegate construction to canonical core helper (DRY).\n // The dispatch-layer wrapper adds: numeric exitCode resolution + structured logging.\n return coreEngineError<T>(code, message, { ...options, exitCode: resolvedExitCode });\n}\n\n/**\n * Create an engine success result (re-export of canonical core helper).\n *\n * @see {@link import('@cleocode/core').engineSuccess}\n *\n * @example\n * ```typescript\n * import { engineSuccess } from './_error.js';\n *\n * return engineSuccess({ tasks: filteredTasks, total: count });\n * ```\n */\nexport { engineSuccess } from '@cleocode/core';\n\n/**\n * Minimal meta shape carrying the request ID for RFC 7807 `instance` population.\n *\n * Callers may pass the dispatch-layer `DispatchRequest.requestId` (or any\n * other correlation identifier) so that the resulting `problemDetails.instance`\n * URI uniquely identifies the specific error occurrence.\n */\nexport interface ErrorMeta {\n /** Unique request identifier (used as the RFC 7807 `instance` field). */\n requestId?: string;\n}\n\n/**\n * Shape of a caught value that may be a `CleoError` instance.\n *\n * We cannot import `CleoError` from `@cleocode/core` here without risking a\n * circular dependency (core → engine → core), so we use a structural type.\n */\ninterface CaughtCleoErrorShape {\n code?: number;\n message?: string;\n fix?: string;\n details?: Record<string, unknown>;\n alternatives?: Array<{ action: string; command: string }>;\n}\n\n/**\n * Convert any caught value into an {@link EngineResult}, forwarding the rich\n * `fix`, `details`, and `alternatives` fields when the caught value is a\n * `CleoError` (or structurally compatible object).\n *\n * @remarks\n * This is the canonical catch-block helper for all dispatch engines. It\n * replaces the previous pattern of:\n * ```typescript\n * const code = (err as { code?: number })?.code;\n * if (code === 4) return engineError('E_NOT_FOUND', …);\n * …\n * ```\n * with a single call that preserves every field the core layer attached.\n *\n * The `fallbackCode` is used when the numeric `err.code` is not present in\n * the {@link STRING_TO_EXIT} mapping (e.g. unknown exit codes, plain `Error`\n * instances, or values thrown by non-CLEO code).\n *\n * RFC 7807 `problemDetails` is always populated from the resolved code, message,\n * and exit code. The optional `meta.requestId` is forwarded to the `instance`\n * field so every error occurrence is uniquely identifiable.\n *\n * @param err - The caught value (unknown type)\n * @param fallbackCode - String error code to use when mapping fails\n * @param fallbackMessage - Human-readable message when `err.message` is absent\n * @param meta - Optional dispatch meta carrying `requestId` for RFC 7807 `instance`\n * @returns EngineResult with all available rich fields propagated\n *\n * @example\n * ```typescript\n * import { cleoErrorToEngineError } from './_error.js';\n *\n * } catch (err: unknown) {\n * return cleoErrorToEngineError(err, 'E_NOT_INITIALIZED', 'Task database not initialized');\n * }\n * ```\n *\n * @example With requestId for RFC 7807 instance field:\n * ```typescript\n * } catch (err: unknown) {\n * return cleoErrorToEngineError(err, 'E_NOT_FOUND', 'Not found', { requestId });\n * }\n * ```\n */\nexport function cleoErrorToEngineError<T>(\n err: unknown,\n fallbackCode: string,\n fallbackMessage: string,\n meta?: ErrorMeta,\n): EngineResult<T> {\n // Non-Error thrown values: a raw string is its own message; other primitives\n // coerce to their String() form. Structured CleoError-like objects are\n // handled in the branch below via `CaughtCleoErrorShape`.\n if (typeof err === 'string') {\n const exitCode = STRING_TO_EXIT[fallbackCode] ?? 1;\n return engineError<T>(fallbackCode, err, {\n exitCode,\n problemDetails: {\n type: `https://cleocode.dev/errors/${fallbackCode}`,\n title: fallbackCode,\n status: exitCode,\n detail: err,\n ...(meta?.requestId !== undefined ? { instance: meta.requestId } : {}),\n },\n });\n }\n if (err !== null && typeof err !== 'object') {\n const exitCode = STRING_TO_EXIT[fallbackCode] ?? 1;\n const message = String(err);\n return engineError<T>(fallbackCode, message, {\n exitCode,\n problemDetails: {\n type: `https://cleocode.dev/errors/${fallbackCode}`,\n title: fallbackCode,\n status: exitCode,\n detail: message,\n ...(meta?.requestId !== undefined ? { instance: meta.requestId } : {}),\n },\n });\n }\n\n const e = err as CaughtCleoErrorShape;\n const code = mapNumericExitCodeToString(e.code) ?? fallbackCode;\n const message = e.message ?? fallbackMessage;\n const exitCode = STRING_TO_EXIT[code] ?? 1;\n\n return engineError<T>(code, message, {\n exitCode,\n ...(e.fix !== undefined && { fix: e.fix }),\n ...(e.details !== undefined && { details: e.details }),\n ...(e.alternatives !== undefined && { alternatives: e.alternatives }),\n problemDetails: {\n type: `https://cleocode.dev/errors/${code}`,\n title: code,\n status: exitCode,\n detail: message,\n ...(meta?.requestId !== undefined ? { instance: meta.requestId } : {}),\n },\n });\n}\n","/**\n * Shared exit-code mapping utilities for the transport-agnostic gateway.\n *\n * Provides a canonical reverse lookup from numeric exit code to string error code,\n * shared between the gateway engine helpers and every transport adapter (CLI,\n * MCP, RPC, HTTP).\n *\n * @remarks\n * Relocated from `packages/cleo/src/dispatch/lib/exit-codes.ts` into\n * `@cleocode/runtime/gateway` (R3-K1 · T11455 · SG-RUNTIME-UNIFICATION) so the\n * runtime can host the shared handler dependencies without importing\n * `@cleocode/cleo`. A thin re-export shim remains at the old path.\n *\n * The forward mapping (string → number) lives in `engine-error.ts` as\n * `STRING_TO_EXIT`. This module derives the inverse on first call and memoises\n * it so engines can resolve a caught `CleoError.code` (numeric) to the\n * string code expected by `engineError()`.\n *\n * @task T374\n * @task T11455\n * @epic T335\n */\n\nimport { STRING_TO_EXIT } from './engine-error.js';\n\n/** Lazily built inverse of STRING_TO_EXIT (number → string). */\nlet _inverseCache: Map<number, string> | null = null;\n\n/**\n * Build and memoize the inverse of STRING_TO_EXIT.\n *\n * When multiple string codes map to the same exit number (e.g. E_GENERAL\n * and E_GENERAL_ERROR both map to 1), the first occurrence wins.\n */\nfunction getInverseMap(): Map<number, string> {\n if (_inverseCache) return _inverseCache;\n\n const map = new Map<number, string>();\n for (const [key, value] of Object.entries(STRING_TO_EXIT)) {\n if (!map.has(value)) {\n map.set(value, key);\n }\n }\n _inverseCache = map;\n return map;\n}\n\n/**\n * Map a numeric CleoError exit code to the canonical string engine error code.\n *\n * @remarks\n * Returns `undefined` when the numeric code is not present in the\n * `STRING_TO_EXIT` map, allowing callers to fall back to their own default.\n *\n * @param numericCode - Numeric exit code from a caught `CleoError.code`\n * @returns Canonical string error code (e.g. `'E_NOT_FOUND'`), or `undefined`\n *\n * @example\n * ```typescript\n * import { mapNumericExitCodeToString } from '../lib/exit-codes.js';\n *\n * const code = mapNumericExitCodeToString(4) ?? 'E_NOT_INITIALIZED';\n * // → 'E_NOT_FOUND'\n * ```\n */\nexport function mapNumericExitCodeToString(numericCode: number | undefined): string | undefined {\n if (numericCode === undefined) return undefined;\n return getInverseMap().get(numericCode);\n}\n","/**\n * Singleton accessor for the gateway {@link BackgroundJobManager}.\n *\n * @remarks\n * Relocated from `packages/cleo/src/dispatch/lib/job-manager-accessor.ts` into\n * `@cleocode/runtime/gateway` (R3-K1 · T11455 · SG-RUNTIME-UNIFICATION) so the\n * `admin` domain handler resolves the job-manager singleton from the runtime\n * layer rather than a cleo-internal path. A thin re-export shim remains at the\n * old path so any existing import site compiles unchanged.\n *\n * Long-lived hosts (e.g. the daemon) call {@link setJobManager} once at startup;\n * short-lived CLI invocations leave the singleton `null`, and consumers handle\n * the absence gracefully.\n *\n * @task T4820\n * @task T11455\n */\n\nimport type { BackgroundJobManager } from '@cleocode/core/store/background-jobs.js';\n\n/** Process-wide singleton instance, or `null` when no host has registered one. */\nlet _instance: BackgroundJobManager | null = null;\n\n/**\n * Register the process-wide {@link BackgroundJobManager} singleton.\n *\n * @param manager - The manager to expose, or null to unregister a stopped host.\n * @remarks Hosts unregister before closing their store; absence is reported explicitly.\n */\nexport function setJobManager(manager: BackgroundJobManager | null): void {\n _instance = manager;\n}\n\n/**\n * Retrieve the registered {@link BackgroundJobManager} singleton.\n *\n * @returns The registered manager, or `null` when running in a short-lived\n * host (e.g. a one-shot CLI invocation) that never called {@link setJobManager}.\n */\nexport function getJobManager(): BackgroundJobManager | null {\n return _instance;\n}\n","/**\n * nexus-decorator — stamps `meta._nexus` on every nexus-domain dispatch response.\n *\n * Wave 2 of the Nexus Restructure (T9146). Reads `getNexusDescriptor(opId)` from\n * the W1 SSoT (`NEXUS_SCOPE_MAP`) and injects the namespaced `_nexus` block into\n * `DispatchResponse['meta']`.\n *\n * Usage:\n * ```ts\n * const decorated = stampNexusMeta(response, operation, params);\n * ```\n *\n * The `suggestedNext` field uses a structured form (not literal display strings).\n * Display strings are derived by `formatSuggestedNext()` for human/markdown renderers.\n *\n * Typed-registry gate: `validateSuggestedNext()` fails the build (throws at import-time\n * in test mode) if any `suggestedNext.op` is absent from `NEXUS_SCOPE_MAP`.\n *\n * @remarks\n * Relocated from `packages/cleo/src/dispatch/nexus-decorator.ts` into\n * `@cleocode/runtime/gateway` (R3-K1 · T11455 · SG-RUNTIME-UNIFICATION) so the\n * nexus domain handler can import it from the runtime layer rather than a\n * cleo-internal path. The module is pure (`@cleocode/contracts` only). A thin\n * re-export shim remains at the old path for the renderer / CLI import sites.\n *\n * @task T9146\n * @task T11455\n * @module runtime/gateway/nexus-decorator\n */\n\nimport type {\n NexusBindingSource,\n NexusOps,\n NexusScopeMeta,\n SuggestedNextOp,\n} from '@cleocode/contracts';\nimport { getNexusDescriptor, NEXUS_SCOPE_MAP } from '@cleocode/contracts';\nimport type { DispatchResponse, DispatchResponseMeta } from '@cleocode/contracts/gateway';\n\n// ---------------------------------------------------------------------------\n// Binding-source resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve how the `projectId` was bound for a given operation call.\n *\n * Priority: explicit `--project-id` arg > `--path` arg > cwd resolution >\n * registry lookup > none (for global/living-brain scope ops).\n */\nfunction resolveBindingSource(\n descriptor: ReturnType<typeof getNexusDescriptor>,\n params: Record<string, unknown>,\n): NexusBindingSource {\n if (!descriptor.requiresProject) return 'none';\n if (typeof params['projectId'] === 'string' && params['projectId']) {\n return 'arg-project-id';\n }\n if (typeof params['path'] === 'string' && params['path']) {\n return 'arg-path';\n }\n // Distinguish cwd vs registry: if a projectId was resolved (e.g. by the\n // engine from cwd) it comes through as projectId in params; absence means\n // the registry was consulted.\n if (typeof params['_resolvedFrom'] === 'string') {\n return params['_resolvedFrom'] === 'cwd' ? 'cwd' : 'registry';\n }\n return 'cwd';\n}\n\n// ---------------------------------------------------------------------------\n// indexFreshness\n// ---------------------------------------------------------------------------\n\n/**\n * Determine index freshness for `indexSensitive` operations.\n *\n * Only called for top-level CLI invocations (sub-calls inherit via\n * `meta.requestId` lineage to avoid per-call git-status shell-outs).\n * Returns `'unknown'` when freshness cannot be determined cheaply.\n */\nfunction resolveIndexFreshness(params: Record<string, unknown>): NexusScopeMeta['indexFreshness'] {\n // If the engine already stamped freshness on the response params, use it.\n const fromParams = params['_indexFreshness'];\n if (fromParams === 'fresh' || fromParams === 'stale') return fromParams;\n return 'unknown';\n}\n\n// ---------------------------------------------------------------------------\n// Canonical command\n// ---------------------------------------------------------------------------\n\n/** Derive the canonical CLI command string from the operation key. */\nfunction canonicalCommandFor(op: string): string {\n return `cleo nexus ${op}`;\n}\n\n// ---------------------------------------------------------------------------\n// Typed-registry gate\n// ---------------------------------------------------------------------------\n\n/**\n * Assert that every `suggestedNext.op` in a list resolves to a known\n * NEXUS_SCOPE_MAP entry.\n *\n * Throws `TypeError` at runtime (caught by tests and CI) if an unknown op\n * is referenced — acting as a build-time gate when imported in test suites.\n *\n * @throws {TypeError} if any `op` is absent from `NEXUS_SCOPE_MAP`\n * @task T9146\n */\nexport function validateSuggestedNext(suggestions: ReadonlyArray<SuggestedNextOp>): void {\n for (const s of suggestions) {\n if (!(s.op in NEXUS_SCOPE_MAP)) {\n throw new TypeError(\n `[nexus-decorator] suggestedNext.op \"${s.op}\" is not a known NEXUS_SCOPE_MAP entry. ` +\n `Add it to packages/contracts/src/operations/nexus-scope-map.ts first.`,\n );\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Display formatter\n// ---------------------------------------------------------------------------\n\n/**\n * Derive a human-readable display string from a {@link SuggestedNextOp}.\n *\n * Example: `\"cleo nexus context --project-id myproj (read-only, no confirmation needed)\"`\n */\nexport function formatSuggestedNext(s: SuggestedNextOp): string {\n const argParts = Object.entries(s.args)\n .map(([k, v]) => `--${k} ${String(v)}`)\n .join(' ');\n const cmd = `cleo nexus ${s.op}${argParts ? ` ${argParts}` : ''}`;\n const confirm = s.requiresConfirmation ? 'confirm before running' : 'no confirmation needed';\n return `${cmd} (${s.effect}, ${confirm}) — ${s.reason}`;\n}\n\n// ---------------------------------------------------------------------------\n// stampNexusMeta — core decorator\n// ---------------------------------------------------------------------------\n\n/**\n * Stamp `meta._nexus` onto a nexus-domain {@link DispatchResponse}.\n *\n * Call this after every nexus handler produces its `DispatchResponse`. The\n * function is a pure transformer — it returns a new object with `meta._nexus`\n * merged in.\n *\n * @param response - The original dispatch response from the nexus handler.\n * @param operation - The nexus operation key (must be a `keyof NexusOps`).\n * @param params - Raw params passed to the handler (used for binding-source resolution).\n * @param isTopLevel - Whether this is a top-level CLI invocation (not a sub-call).\n * @returns A new `DispatchResponse` with `meta._nexus` populated.\n *\n * @task T9146\n */\nexport function stampNexusMeta(\n response: DispatchResponse,\n operation: string,\n params: Record<string, unknown>,\n isTopLevel = true,\n): DispatchResponse {\n // Unknown ops (not in NEXUS_SCOPE_MAP) fall through without decoration —\n // the handler already returned an unsupported-op error.\n if (!(operation in NEXUS_SCOPE_MAP)) {\n return response;\n }\n\n const descriptor = getNexusDescriptor(operation as keyof NexusOps);\n const bindingSource = resolveBindingSource(descriptor, params);\n\n const projectId = typeof params['projectId'] === 'string' ? params['projectId'] : undefined;\n const projectName =\n typeof params['_projectName'] === 'string' ? params['_projectName'] : undefined;\n const projectPath =\n typeof params['_projectPath'] === 'string' ? params['_projectPath'] : undefined;\n const registryPath =\n typeof params['_registryPath'] === 'string' ? params['_registryPath'] : undefined;\n const counterpartProjectId =\n descriptor.scope === 'cross' || descriptor.scope === 'hybrid'\n ? typeof params['counterpartProjectId'] === 'string'\n ? params['counterpartProjectId']\n : undefined\n : undefined;\n\n const indexFreshness =\n descriptor.indexSensitive && isTopLevel ? resolveIndexFreshness(params) : undefined;\n\n const legacyAliasFor =\n typeof params['_legacyAliasFor'] === 'string' ? params['_legacyAliasFor'] : undefined;\n\n const nexusMeta: NexusScopeMeta = {\n scope: descriptor.scope,\n effect: descriptor.effect,\n ...(projectId !== undefined && { projectId }),\n ...(projectName !== undefined && { projectName }),\n ...(projectPath !== undefined && { projectPath }),\n ...(registryPath !== undefined && { registryPath }),\n bindingSource,\n ...(counterpartProjectId !== undefined && { counterpartProjectId }),\n ...(indexFreshness !== undefined && { indexFreshness }),\n canonicalCommand: canonicalCommandFor(operation),\n ...(legacyAliasFor !== undefined && { legacyAliasFor }),\n };\n\n return {\n ...response,\n meta: {\n ...response.meta,\n _nexus: nexusMeta,\n // Stamp top-level deprecated field for alias shims (T9147)\n ...(legacyAliasFor !== undefined && {\n deprecated: {\n since: 'v2026.6.5',\n removeIn: 'v2026.8.0',\n replacement: `cleo graph ${operation}`,\n },\n }),\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// pickDecoratorMetaExtensions — forward decorator fields into CLI envelope\n// ---------------------------------------------------------------------------\n\n/**\n * Pick the decorator-stamped fields (`_nexus`, `deprecated`) from a dispatch\n * response's `meta` so they can be forwarded via `cliOutput`'s `extensions`\n * option into the emitted LAFS envelope.\n *\n * Without this, `cliOutput(response.data, ...)` discards `response.meta._nexus`\n * + `response.meta.deprecated` (T9393 defect). Canonical CLI meta fields\n * (`operation`, `requestId`, `timestamp`) are intentionally NOT forwarded —\n * those are produced by {@link createCliMeta} on the CLI side.\n *\n * @task T9393\n */\nexport function pickDecoratorMetaExtensions(\n responseMeta: DispatchResponseMeta | undefined,\n): Record<string, unknown> {\n if (!responseMeta) return {};\n const out: Record<string, unknown> = {};\n if (responseMeta['_nexus'] !== undefined) out['_nexus'] = responseMeta['_nexus'];\n if (responseMeta['deprecated'] !== undefined) out['deprecated'] = responseMeta['deprecated'];\n if (responseMeta.sessionId !== undefined) out['sessionId'] = responseMeta.sessionId;\n if (responseMeta.originSessionId !== undefined) {\n out['originSessionId'] = responseMeta.originSessionId;\n }\n if (responseMeta.executionSessionId !== undefined) {\n out['executionSessionId'] = responseMeta.executionSessionId;\n }\n // T9921\n if (responseMeta['suggestedNext'] !== undefined) {\n out['suggestedNext'] = responseMeta['suggestedNext'];\n }\n return out;\n}\n\n/**\n * Build CLI envelope extensions for nexus commands that bypass the dispatcher\n * (e.g. `cleo nexus status` SSoT-EXEMPT path). Runs the same {@link stampNexusMeta}\n * logic against a synthetic response so the resulting envelope still carries\n * `meta._nexus` (and `meta.deprecated` for alias shims).\n *\n * Use this only where the command does NOT call `dispatchRaw`. When you have a\n * real dispatch response, use {@link pickDecoratorMetaExtensions} on\n * `response.meta` instead — that path already ran the decorator.\n *\n * @task T9393\n */\nexport function buildNexusMetaExtensions(\n operation: string,\n params: Record<string, unknown> = {},\n): Record<string, unknown> {\n const synthetic: DispatchResponse = {\n success: true,\n data: undefined,\n meta: {\n gateway: 'query',\n domain: 'nexus',\n operation,\n timestamp: new Date().toISOString(),\n duration_ms: 0,\n source: 'cli',\n requestId: '',\n },\n } as DispatchResponse;\n const stamped = stampNexusMeta(synthetic, operation, params);\n return pickDecoratorMetaExtensions(stamped.meta);\n}\n","/**\n * Gateway-level path constants shared by domain handlers.\n *\n * @remarks\n * The `orchestrate` and `admin` (smoke-provider) domain handlers join a handful\n * of well-known `.cleo/` path segments when locating workflow definitions and\n * the BRAIN database. Those constants were previously defined in\n * `packages/cleo/src/cli/paths.ts` (a CLI-internal leaf), which coupled the\n * handler subgraph to `@cleocode/cleo`.\n *\n * To let `@cleocode/runtime` assemble the handler map WITHOUT importing\n * `@cleocode/cleo` (R3-K1 · T11455 · SG-RUNTIME-UNIFICATION), the constants the\n * handlers actually consume are hosted here as the canonical source. The\n * CLI-side `cli/paths.ts` re-exports them so the rest of the CLI (backup /\n * restore / doctor) keeps importing from its established surface — there is a\n * single definition, no drift.\n *\n * @task T090\n * @task T11455\n */\n\n/** Name of the project-local CLEO data directory (`.cleo`). */\nexport const CLEO_DIR_NAME = '.cleo' as const;\n\n/** Subdirectory under `.cleo/` that stores CANT workflow definitions. */\nexport const WORKFLOWS_SUBDIR = 'workflows' as const;\n\n/** Project-local SQLite database filename for cognitive memory (BRAIN). */\nexport const BRAIN_DB_FILENAME = 'brain.db' as const;\n","/**\n * Daemon-side gateway server bootstrap — the call-site `cleo daemon serve`\n * drives (T11919).\n *\n * The HTTP gateway adapter (`./http/listen.ts`, T11254) and the supervised\n * `defineGatewaySubsystem` unit (`./daemon-subsystem.ts`, T11451) both already\n * exist, but nothing started them: the daemon had no `serve` call-site. This\n * module is that thin bootstrap — it assembles a {@link SubsystemRegistry} with\n * one scoped gateway subsystem hosting the HTTP transport (loopback by default)\n * over an INJECTED {@link GatewayHandler}, starts it, and returns a live handle\n * with the bound port + an idempotent `close()`.\n *\n * It carries NO `@cleocode/cleo` dependency and NO drizzle (the runtime\n * invariant): the caller (`cleo daemon serve`) injects the assembled CLI gateway\n * handler and the resolved bind coordinates. Secrets never touch the wire —\n * sealed-handle resolution happens server-side inside the dispatched handler,\n * exactly as it does for an in-process CLI call. The HTTP listener binds\n * `127.0.0.1` by default (loopback only); exposing it on a public interface is\n * an explicit caller decision.\n *\n * The streaming transports (SSE — T11921, WS — T11922) extend the SAME\n * subsystem: when their listeners land they bind alongside the unary HTTP server\n * here, so this bootstrap deliberately owns only transport assembly + lifecycle,\n * leaving the per-route seam to the adapter (`parseHttpRoute`).\n *\n * @packageDocumentation\n * @module @cleocode/runtime/gateway\n *\n * @task T11919\n * @epic T11769\n * @saga T10400\n */\n\nimport { defineGatewaySubsystem, type GatewayScope } from './daemon-subsystem.js';\nimport type { GatewayHandler } from './index.js';\n\n/** Default loopback host for the HTTP gateway — local-process-facing only. */\nconst DEFAULT_HOST = '127.0.0.1';\n\n/**\n * Options for {@link serveGateway}.\n *\n * The caller injects the assembled {@link GatewayHandler} and resolves the bind\n * coordinates so the runtime stays free of `@cleocode/paths`/`@cleocode/cleo`.\n */\nexport interface ServeGatewayOptions {\n /** The transport-neutral gateway handler every hosted transport routes through. */\n handler: GatewayHandler;\n /** TCP port to bind. `0` selects an ephemeral port (readable from the handle). */\n port: number;\n /** Host/interface to bind. Defaults to `127.0.0.1` (loopback only). */\n host?: string;\n /** The scope this gateway process serves. Defaults to `'global'`. */\n scope?: GatewayScope;\n /**\n * Absolute path to the Studio static asset directory (T11979).\n *\n * When set, the HTTP server serves the bundled CLEO Web Studio at `/studio`\n * using the `build/client/` static assets from an `adapter-node` Studio build.\n * When `undefined`, `/studio` routes return a clean 503 \"bundle absent\" JSON\n * envelope. The caller resolves this path (typically via\n * `resolveStudioStaticDir` from `@cleocode/cleo`) so the runtime stays free of\n * any path-resolution policy.\n */\n studioStaticDir?: string;\n}\n\n/**\n * A live gateway server handle returned by {@link serveGateway}.\n *\n * Exposes the actually-bound `port`/`host` (resolved even when `0` was\n * requested) and an idempotent {@link close} for deterministic teardown\n * (daemon shutdown, tests). Mirrors the lower-level\n * {@link import('./http/listen.js').HttpServerHandle} so a test can boot, probe,\n * and tear down on an ephemeral port.\n */\nexport interface ServeGatewayHandle {\n /** The actually-bound HTTP port (resolved when `0` was requested). */\n port: number;\n /** Host/interface the HTTP listener is bound to. */\n host: string;\n /** The scope the gateway process serves. */\n scope: GatewayScope;\n /** Stop every bound listener (best-effort, idempotent); resolves once closed. */\n close(): Promise<void>;\n}\n\n/**\n * Boot the HTTP gateway as a supervised subsystem and return a live handle.\n *\n * Declares one scoped gateway subsystem hosting the HTTP transport (loopback\n * default) over the injected handler via {@link defineGatewaySubsystem}, starts\n * it, and reads the actually-bound port from the start context (so the caller —\n * and tests — learn the ephemeral port when `0` was requested). The returned\n * `close()` drives the subsystem's `shutdown(context)` so teardown is the same\n * lifecycle the daemon registry uses for every other supervised concern.\n *\n * Using `defineGatewaySubsystem` directly (rather than a full\n * `SubsystemRegistry`) keeps the bound HTTP handle in reach for the port\n * resolution while still routing through the canonical start→shutdown contract.\n *\n * @param opts - The injected handler + resolved bind coordinates.\n * @returns A promise resolving to the live {@link ServeGatewayHandle}.\n *\n * @example\n * ```ts\n * const handle = await serveGateway({\n * handler: createCliGatewayHandler(),\n * port: 0, // ephemeral\n * });\n * // POST http://127.0.0.1:${handle.port}/v1/tasks/show\n * await handle.close();\n * ```\n */\nexport async function serveGateway(opts: ServeGatewayOptions): Promise<ServeGatewayHandle> {\n const host = opts.host ?? DEFAULT_HOST;\n const scope: GatewayScope = opts.scope ?? 'global';\n\n const subsystem = defineGatewaySubsystem({\n scope,\n handler: opts.handler,\n http: { port: opts.port, host, studioStaticDir: opts.studioStaticDir },\n });\n\n const context = await subsystem.start();\n // The HTTP transport is configured, so `start()` always binds it.\n const boundPort = context.http?.port ?? opts.port;\n\n let closed = false;\n return {\n port: boundPort,\n host,\n scope,\n async close(): Promise<void> {\n if (closed) return;\n closed = true;\n await subsystem.shutdown(context);\n },\n };\n}\n","/**\n * `@cleocode/runtime/gateway` — the transport-agnostic CQRS dispatch core.\n *\n * Relocated from `packages/cleo/src/dispatch` (R3-T3 · T11447 ·\n * SG-RUNTIME-UNIFICATION) so the dispatcher is owned by the runtime layer and\n * can be driven by ANY transport adapter — CLI, MCP, RPC, HTTP — not just the\n * CLI. Mirrors the `@cleocode/runtime/daemon` subpath (R2).\n *\n * The CLI adapter (`packages/cleo/src/dispatch/adapters/cli.ts`) and the\n * domain handlers + transport-specific middleware stay in `packages/cleo`; they\n * are INJECTED into the {@link Dispatcher} via {@link DispatcherConfig}. The\n * gateway contract itself lives in `@cleocode/contracts/gateway` (R3-T2).\n *\n * `packages/cleo/src/dispatch/{dispatcher,registry,lib/meta,middleware/pipeline}.ts`\n * remain as thin re-export shims pointing here, so the in-package import sites\n * (cli adapter, ~18 registry consumers, getCliDispatcher) compile unchanged.\n *\n * @epic T4820\n * @task T11447\n * @saga T11243\n */\n\nimport type { DispatchRequest, DispatchResponse } from '@cleocode/contracts/gateway';\nimport { Dispatcher, type DispatcherConfig } from './dispatcher.js';\n\nexport {\n type BackgroundJob,\n BackgroundJobManager,\n type BackgroundJobManagerConfig,\n type BackgroundJobStatus,\n DurableJobStore,\n} from './background-jobs.js';\n// Gateway-as-daemon-subsystem (R3-T7 · T11451) — declare the external-facing\n// gateway (RPC unix socket + HTTP server) as a supervised `defineSubsystem`\n// unit so the R2 daemon registry drives its start/health/shutdown lifecycle.\nexport {\n defineGatewaySubsystem,\n type GatewayScope,\n type GatewaySubsystemContext,\n type GatewaySubsystemOptions,\n gatewaySubsystemName,\n} from './daemon-subsystem.js';\nexport type { DispatcherConfig } from './dispatcher.js';\nexport { Dispatcher } from './dispatcher.js';\n// Shared handler dependencies (R3-K1 · T11455) — relocated here so the runtime\n// can assemble the domain-handler map without importing `@cleocode/cleo`.\n// The domain handlers + cli adapter import these from `@cleocode/runtime/gateway`\n// instead of cleo-internal `engines/` / `lib/` / `cli/paths` / `nexus-decorator`.\nexport * from './engine.js';\nexport {\n cleoErrorToEngineError,\n type EngineResult,\n type ErrorMeta,\n engineError,\n engineSuccess,\n STRING_TO_EXIT,\n} from './engine-error.js';\nexport { mapNumericExitCodeToString } from './exit-codes.js';\n// HTTP transport adapter (R3-T6 · T11450) — framework-agnostic unary + SSE over\n// the gateway. Also reachable via the `@cleocode/runtime/gateway/http` subpath.\n// `startHttpServer` (R3-T7 · T11451) is the daemon-hostable `node:http` binding.\nexport {\n createSseStream,\n encodeSseFrame,\n encodeStreamEvent,\n type GatewayStreamSource,\n type HttpServerHandle,\n type HttpServerOptions,\n type HttpUnaryRequest,\n type HttpUnaryResult,\n isStudioPath,\n mimeType,\n parseHttpRoute,\n registerStreamSource,\n resolveStreamSource,\n resolveStudioAssetPath,\n resolveStudioStaticDir,\n routeUnary,\n SSE_HEADERS,\n type SseEmitter,\n type SseFrame,\n type SseSource,\n STUDIO_PREFIX,\n type StreamSourceContext,\n type StreamSourceTeardown,\n type StudioStaticOptions,\n serveStudioStatic,\n startHttpServer,\n statusForResponse,\n tickStreamSource,\n writeBundleAbsentError,\n} from './http/index.js';\nexport { getJobManager, setJobManager } from './job-manager-accessor.js';\n// MCP transport adapter (R3-T4 · T11448) — thin stdio JSON-RPC over the\n// gateway. Also reachable via the `@cleocode/runtime/gateway/mcp` subpath.\nexport {\n buildToolsList,\n callTool,\n exposedOperations,\n type GatewayOperationKey,\n MCP_TOOL_PREFIX,\n type McpContent,\n type McpInputProperty,\n type McpServerOptions,\n type McpTool,\n type McpToolResult,\n operationToMcpTool,\n operationToToolName,\n startMcpServer,\n toolNameToOperationKey,\n} from './mcp/index.js';\nexport { createDispatchMeta } from './meta.js';\nexport {\n buildNexusMetaExtensions,\n formatSuggestedNext,\n pickDecoratorMetaExtensions,\n stampNexusMeta,\n validateSuggestedNext,\n} from './nexus-decorator.js';\nexport { BRAIN_DB_FILENAME, CLEO_DIR_NAME, WORKFLOWS_SUBDIR } from './paths.js';\nexport { compose } from './pipeline.js';\nexport type { OperationDef, Resolution } from './registry.js';\nexport {\n deriveGatewayMatrix,\n getActiveDomains,\n getByDomain,\n getByGateway,\n getByTier,\n getCounts,\n getGatewayDomains,\n inferGateway,\n OPERATIONS,\n resolve,\n resolveStreamRoute,\n type StreamResolution,\n validateRequiredParams,\n} from './registry.js';\n// CLI-RPC transport adapter (R3-T5 · T11449) — thin NDJSON-over-unix-socket\n// server over the gateway. Also reachable via the `@cleocode/runtime/gateway/rpc`\n// subpath. Reuses the FROZEN supervisor-ipc NDJSON framing discipline.\nexport {\n buildErrorFrame,\n type DecodeResult,\n decodeLine,\n encodeFrame,\n LineBuffer,\n type RpcServerHandle,\n type RpcServerOptions,\n routeFrame,\n startRpcServer,\n} from './rpc/index.js';\n// Daemon-side gateway server bootstrap (T11919) — the call-site `cleo daemon\n// serve` drives to start the HTTP transport over an injected handler.\nexport { type ServeGatewayHandle, type ServeGatewayOptions, serveGateway } from './serve.js';\n\n/**\n * Transport-agnostic gateway entrypoint. Wraps a configured {@link Dispatcher}\n * (`compose(middlewares) → DomainHandler`) behind a single `handle()` call that\n * every transport adapter (CLI/MCP/RPC/HTTP) invokes uniformly. The adapter\n * owns wire concerns (error-render, `process.exit`, serialization); the handler\n * only resolves, validates, runs middleware, and returns a {@link DispatchResponse}.\n */\nexport interface GatewayHandler {\n /** Route one gateway request through the dispatch pipeline. */\n handle(req: DispatchRequest): Promise<DispatchResponse>;\n}\n\n/**\n * Build a {@link GatewayHandler} from a {@link DispatcherConfig} (injected\n * domain handlers + middleware). The returned handler is transport-neutral.\n */\nexport function createGatewayHandler(config: DispatcherConfig): GatewayHandler {\n const dispatcher = new Dispatcher(config);\n return { handle: (req: DispatchRequest): Promise<DispatchResponse> => dispatcher.dispatch(req) };\n}\n"],"mappings":"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CA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OA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","names":["randomUUID","randomUUID","getLogger","getLogger","getLogger","getLogger","exitCode","message"]}
|
|
1
|
+
{"version":3,"sources":["../../src/gateway/background-jobs.ts","../../src/gateway/daemon-subsystem.ts","../../src/gateway/engine.ts","../../src/gateway/template-parser.ts","../../src/gateway/job-manager-accessor.ts","../../src/gateway/serve.ts"],"sourcesContent":["/**\n * Background Job Manager — gateway re-export.\n *\n * @remarks\n * The Drizzle-backed background-job manager lives in `@cleocode/core/store`\n * (R3-K1 · T11455 · SG-RUNTIME-UNIFICATION) — that is the package which owns the\n * consolidated SQLite schema and the SINGLE `drizzle-orm` instance, so the query\n * builders type-check against one instance (no dual peer-hashed `SQL<unknown>`\n * mismatch under `tsc -b`). This module re-exports that surface so the gateway\n * (and the `@cleocode/runtime/gateway` barrel) expose `BackgroundJobManager` etc.\n * WITHOUT `@cleocode/runtime` taking its own `drizzle-orm` dependency.\n *\n * @task T641\n * @task T11455\n */\n\nexport {\n type BackgroundJob,\n BackgroundJobManager,\n type BackgroundJobManagerConfig,\n type BackgroundJobStatus,\n DurableJobStore,\n} from '@cleocode/core/store/background-jobs.js';\n","/**\n * The gateway as a supervised **daemon subsystem**.\n *\n * R3-T7 (this task) closes the loop between the two R-track halves: the R3\n * gateway (dispatcher + the four transport adapters) and the R2 daemon\n * (`defineSubsystem` + the `SubsystemRegistry`). It expresses the\n * external-facing gateway as a uniform {@link Subsystem} so the R2 daemon\n * registry drives its `start → healthProbe → shutdown` lifecycle exactly like\n * every other long-running concern (Studio supervision, the GC cron, …). One\n * gateway subsystem is registered per scope (project / global) → one\n * external-facing gateway process per scope.\n *\n * Which transports the daemon hosts:\n * - the **RPC unix socket** (`@cleocode/runtime/gateway/rpc`) — the canonical\n * local-client wire: the `cleo` CLI, Studio's server process, and test\n * harnesses open it to dispatch without paying a cold `cleo` spawn.\n * - the **HTTP server** (`@cleocode/runtime/gateway/http` via the daemon-local\n * `startHttpServer` embedder) — for external clients that speak HTTP rather\n * than the unix-socket NDJSON wire.\n *\n * The CLI and MCP adapters are intentionally NOT hosted by the daemon: the CLI\n * adapter is in-process to the `cleo` binary, and the MCP adapter is a stdio\n * server an MCP client spawns and owns — neither is a long-lived,\n * daemon-supervised listener. The two external-facing listeners (RPC + HTTP)\n * are the ones the daemon owns.\n *\n * This subsystem adds NO behavior to the adapters themselves — it only wires\n * their existing `start*Server` / `close()` lifecycle (and their already-merged\n * routing) into the daemon registry's uniform lifecycle. It carries NO\n * `@cleocode/cleo` dependency and NO drizzle-orm (the runtime invariant): the\n * caller injects the assembled {@link GatewayHandler} and the resolved bind\n * coordinates; this module only orchestrates listeners.\n *\n * @packageDocumentation\n * @module @cleocode/runtime/gateway\n *\n * @task T11451 (R3-T7)\n * @epic T11254\n * @saga T11243 SG-RUNTIME-UNIFICATION\n */\n\nimport type { Subsystem, SubsystemHealth, SubsystemState } from '@cleocode/contracts';\nimport { getLogger } from '@cleocode/core';\nimport { defineSubsystem } from '../daemon/index.js';\nimport { type HttpServerHandle, type HttpServerOptions, startHttpServer } from './http/listen.js';\nimport type { GatewayHandler } from './index.js';\nimport { type RpcServerHandle, type RpcServerOptions, startRpcServer } from './rpc/index.js';\n\n/** The scope a single gateway process serves — one external-facing process per scope. */\nexport type GatewayScope = 'project' | 'global';\n\n/**\n * Configuration for one scoped gateway subsystem.\n *\n * The caller injects the assembled, transport-neutral {@link GatewayHandler}\n * (built with `createGatewayHandler` from its domain handlers + middleware) and\n * the resolved bind coordinates for each hosted transport. The runtime never\n * resolves paths/ports itself — that keeps it free of `@cleocode/paths` and of\n * any policy decision about where a scope's socket/port lives.\n */\nexport interface GatewaySubsystemOptions {\n /** The scope this gateway process serves (`project` | `global`). */\n scope: GatewayScope;\n /** The transport-neutral gateway handler every hosted transport routes through. */\n handler: GatewayHandler;\n /**\n * RPC unix-socket transport options. When omitted, the RPC transport is not\n * hosted (a deployment that only wants HTTP). At least one transport MUST be\n * configured.\n */\n rpc?: RpcServerOptions;\n /**\n * HTTP transport options. When omitted, the HTTP transport is not hosted (a\n * deployment that only wants the local RPC socket). At least one transport\n * MUST be configured.\n */\n http?: HttpServerOptions;\n}\n\n/**\n * The live context a started gateway subsystem threads from `start` into\n * `healthProbe`/`shutdown`: the bound transport handles plus the owning pid.\n *\n * `void`-typed contexts are common for subsystems, but the gateway needs to\n * carry its bound handles so `shutdown` can close exactly what `start` opened\n * (and `healthProbe` can report the bound coordinates).\n */\nexport interface GatewaySubsystemContext {\n /** The OS pid hosting the listeners (this daemon process). */\n readonly pid: number;\n /** The bound RPC server handle, when the RPC transport is hosted. */\n readonly rpc?: RpcServerHandle;\n /** The bound HTTP server handle, when the HTTP transport is hosted. */\n readonly http?: HttpServerHandle;\n}\n\n/**\n * The stable subsystem name (and supervised `child_id`) of a scoped gateway.\n *\n * Suffixed with the scope so a single daemon process supervising both scopes\n * (project + global) registers two distinct, non-colliding subsystems. The\n * `child_id` matches the id the Rust supervisor tracks the listener under.\n *\n * @param scope - The gateway scope.\n * @returns The subsystem name, e.g. `gateway-project`.\n */\nexport function gatewaySubsystemName(scope: GatewayScope): string {\n return `gateway-${scope}`;\n}\n\n/**\n * Declare the external-facing gateway as a supervised daemon {@link Subsystem}.\n *\n * The returned subsystem (frozen by {@link defineSubsystem}) is registered with\n * a `SubsystemRegistry`, which then drives its lifecycle uniformly:\n *\n * - `start()` — binds the configured transports (RPC unix socket and/or\n * HTTP server) over the injected handler, in a fixed order (RPC then HTTP).\n * If the second listener fails to bind, the first is rolled back so a failed\n * start leaves no half-open listener — then the error is re-thrown for the\n * registry's `onError` sink.\n * - `healthProbe()` — reports a single {@link SubsystemHealth} row keyed on the\n * scoped `child_id`, `running` while the configured listeners are live, with\n * a `detail` summarizing the bound coordinates. Projects losslessly onto the\n * supervisor's `ChildStatus`.\n * - `shutdown()` — closes every bound listener (best-effort, idempotent) in\n * reverse bind order (HTTP then RPC).\n *\n * One subsystem instance is declared per scope, so registering the project and\n * global gateways yields two supervised listeners → one external-facing gateway\n * process surface per scope (AC1).\n *\n * @param opts - The scoped gateway configuration (handler + per-transport bind\n * coordinates).\n * @returns A frozen {@link Subsystem} ready to `register()` with a\n * `SubsystemRegistry`.\n * @throws {TypeError} When neither the RPC nor the HTTP transport is configured\n * (a gateway with no hosted transport serves nothing).\n *\n * @example\n * ```ts\n * const registry = new SubsystemRegistry();\n * registry.register(\n * defineGatewaySubsystem({\n * scope: 'project',\n * handler: createGatewayHandler(dispatcherConfig),\n * rpc: { socketPath: '/run/cleo/cleo-gateway-rpc-project.sock' },\n * http: { port: 7777 },\n * }),\n * );\n * await registry.startAll(); // binds the RPC socket + HTTP server\n * const health = await registry.aggregateHealth();\n * await registry.shutdownAll(); // closes both listeners\n * ```\n */\nexport function defineGatewaySubsystem(\n opts: GatewaySubsystemOptions,\n): Subsystem<GatewaySubsystemContext> {\n if (opts.rpc === undefined && opts.http === undefined) {\n throw new TypeError(\n 'defineGatewaySubsystem: at least one transport (rpc and/or http) must be configured',\n );\n }\n\n const name = gatewaySubsystemName(opts.scope);\n const log = getLogger(name);\n\n // The `Subsystem.healthProbe` contract takes NO arguments — the registry only\n // threads the start→shutdown context, not into the probe. We therefore hold\n // the live context in a closure so `healthProbe()` can read the bound handles\n // (and report `stopped` before `start()`/after `shutdown()`).\n let live: GatewaySubsystemContext | undefined;\n\n return defineSubsystem<GatewaySubsystemContext>({\n name,\n\n async start(): Promise<GatewaySubsystemContext> {\n // Bind RPC first, then HTTP, so the unix socket is available before the\n // HTTP listener (the canonical local wire comes up first). On an HTTP\n // bind failure, roll back the RPC socket so start() never leaves a\n // half-open listener for the registry's onError to clean up after.\n let rpc: RpcServerHandle | undefined;\n try {\n if (opts.rpc !== undefined) {\n rpc = await startRpcServer(opts.handler, opts.rpc);\n }\n let http: HttpServerHandle | undefined;\n if (opts.http !== undefined) {\n http = await startHttpServer(opts.handler, opts.http);\n }\n const context: GatewaySubsystemContext = { pid: process.pid, rpc, http };\n live = context;\n log.info(\n { scope: opts.scope, rpc: rpc?.socketPath, httpPort: http?.port },\n 'gateway subsystem started',\n );\n return context;\n } catch (cause) {\n // Roll back any listener already bound before re-throwing.\n if (rpc !== undefined) {\n await rpc.close().catch(() => undefined);\n }\n live = undefined;\n throw cause;\n }\n },\n\n healthProbe(): SubsystemHealth {\n // Not started (or already shut down) → report a stopped row so the\n // aggregate `allHealthy` cannot be falsely true.\n if (live === undefined) {\n const stopped: SubsystemState = 'stopped';\n return {\n child_id: name,\n pid: 0,\n state: stopped,\n restart_count: 0,\n detail: `scope=${opts.scope} not started`,\n };\n }\n const transports: string[] = [];\n if (live.rpc !== undefined) transports.push(`rpc=${live.rpc.socketPath}`);\n if (live.http !== undefined) {\n transports.push(`http=${live.http.host}:${live.http.port}`);\n }\n const running: SubsystemState = 'running';\n return {\n child_id: name,\n pid: live.pid,\n state: running,\n restart_count: 0,\n detail: `scope=${opts.scope} ${transports.join(' ')}`.trim(),\n };\n },\n\n async shutdown(context: GatewaySubsystemContext): Promise<void> {\n // Reverse bind order: close HTTP before the RPC socket. Both close()\n // calls are idempotent and best-effort — one failure must not block the\n // other listener's teardown.\n if (context.http !== undefined) {\n await context.http.close().catch((err: unknown) => {\n log.warn({ err }, 'gateway http close failed');\n });\n }\n if (context.rpc !== undefined) {\n await context.rpc.close().catch((err: unknown) => {\n log.warn({ err }, 'gateway rpc close failed');\n });\n }\n live = undefined;\n log.info({ scope: opts.scope }, 'gateway subsystem stopped');\n },\n });\n}\n","/**\n * Engine Re-exports for Gateway Domain Handlers\n *\n * Centralizes the engine imports consumed by the domain handlers into a single\n * barrel. Every symbol re-exported here ultimately resolves to\n * `@cleocode/core/internal` (the canonical business-logic SSoT) or core's\n * template parser — this file adds NO logic of its own.\n *\n * @remarks\n * Relocated from `packages/cleo/src/dispatch/lib/engine.ts` into\n * `@cleocode/runtime/gateway` (R3-K1 · T11455 · SG-RUNTIME-UNIFICATION) so the\n * runtime can assemble the handler map without importing `@cleocode/cleo`.\n * Mirrors the `meta` / `registry` / `dispatcher` relocations (R3-T3 · T11447).\n * A thin re-export shim remains at the old `lib/engine.ts` path so the\n * in-package import sites compile unchanged (zero behavior change).\n *\n * @epic T4820\n * @task T4815\n * @task T11455\n */\n\nexport type { MinimalTaskRecord, Session as SessionRecord, TaskRecord } from '@cleocode/contracts';\nexport type { OrchestratePlanResult } from '@cleocode/contracts/operations/orchestrate';\n// Task operations — re-exported from @cleocode/core/internal (T1568 / ADR-057 / ADR-058)\n// task-engine.ts was deleted in Wave 5; all symbols now live in core/tasks/.\n// Orchestrate — types and functions from @cleocode/core/internal (T1570 ADR-057)\n// System — type aliases for backward compat (T1571: system-engine.ts deleted, canonical sources = @cleocode/core/internal)\nexport type {\n ArchiveStatsResult as ArchiveStatsData,\n AuditResult as AuditData,\n BackupEntry as BackupEntryData,\n BackupResult as BackupData,\n CleanupResult as CleanupData,\n CompactTask,\n ComplianceData,\n ContextData,\n DashboardData,\n DiagnosticsResult as DiagnosticsData,\n FileRestoreResult,\n HealthResult as HealthData,\n HelpData,\n InjectGenerateResult as InjectGenerateData,\n IvtrHistoryEntry,\n LabelsResult as LabelsData,\n LifecycleStageEntry,\n LogQueryData,\n MigrateResult as MigrateData,\n OrchestratePlanInput,\n PathsData,\n PlanWarning,\n PlanWave,\n PlanWorkerEntry,\n RestoreResult as RestoreData,\n RuntimeDiagnostics as RuntimeData,\n SafestopResult as SafestopData,\n ScaffoldHubData,\n StatsData,\n SyncData,\n SystemMetricsResult as MetricsData,\n UncancelResult as UncancelData,\n} from '@cleocode/core/internal';\n// Pipeline manifest functions (moved from memory domain in T5241)\n// Release engine (T1572 — ENG-MIG-5: migrated to @cleocode/core/internal)\n// Session engine (T1573 — ENG-MIG-6: migrated to @cleocode/core/internal)\n// Lifecycle engine ops — re-exported from @cleocode/core/internal (T1576 / ENG-MIG-9 / ADR-057)\n// lifecycle-engine.ts shrunk to a shim; all symbols now live in core/lifecycle/engine-ops.ts.\n// Hooks engine (ENG-MIG-12 / T1579 — logic in @cleocode/core/internal)\n// Init engine-ops — migrated to @cleocode/core/internal (ENG-MIG-14 / T1581 / ADR-057)\n// Config engine-ops — migrated to @cleocode/core/internal (ENG-MIG-15 / T1582 / ADR-057)\n// config-engine.ts shrunk to a shim; all symbols now live in core/config/engine-ops.ts.\n// Codebase map — re-exported from core (engine shim deleted, T1584)\n// Memory engine — brain.db cognitive memory (T5241 cutover)\n// Validate engine — direct from core (was a rename shim, now inlined here)\nexport {\n addTaskWithSessionScope,\n completeTaskStrict,\n configGet,\n configListPresets,\n configSet,\n configSetPreset,\n coreBatchValidate as validateBatchValidate,\n coreCoherenceCheck as validateCoherenceCheck,\n coreComplianceRecord as validateComplianceRecord,\n coreComplianceSummary as validateComplianceSummary,\n coreComplianceViolations as validateComplianceViolations,\n coreTestCoverage as validateTestCoverage,\n coreTestRun as validateTestRun,\n coreTestStatus as validateTestStatus,\n coreValidateManifest as validateManifestOp,\n coreValidateOutput as validateOutput,\n coreValidateProtocol as validateProtocol,\n coreValidateSchema as validateSchemaOp,\n coreValidateTask as validateTaskOp,\n type DecisionRecord,\n ensureInitialized,\n filterEntries as filterManifestEntries,\n getVersion,\n type HookMatrixResult,\n initProject,\n isAutoInitEnabled,\n lifecycleCheck,\n lifecycleGateFail,\n lifecycleGatePass,\n lifecycleGates,\n lifecycleHistory,\n lifecyclePrerequisites,\n lifecycleProgress,\n lifecycleReset,\n lifecycleSkip,\n lifecycleStatus,\n type ManifestEntry as ResearchManifestEntry,\n mapCodebase,\n memoryBrainStats,\n memoryContradictions,\n memoryDecisionFind,\n memoryDecisionStore,\n memoryFetch,\n memoryFind,\n memoryGraphAdd,\n memoryGraphContext,\n memoryGraphNeighbors,\n memoryGraphRelated,\n memoryGraphRemove,\n memoryGraphShow,\n memoryGraphStatsFull,\n memoryGraphTrace,\n memoryLearningFind,\n memoryLearningStats,\n memoryLearningStore,\n memoryLink,\n memoryObserve,\n memoryPatternFind,\n memoryPatternStats,\n memoryPatternStore,\n memoryQualityReport,\n memoryReasonSimilar,\n memoryReasonWhy,\n memorySearchHybrid,\n memoryShow,\n memorySuperseded,\n memoryTimeline,\n memoryUnlink,\n orchestrateAnalyze,\n orchestrateBootstrap,\n orchestrateCheck,\n orchestrateContext,\n orchestrateCriticalPath,\n orchestrateHandoff,\n orchestrateNext,\n orchestrateParallelEnd,\n orchestrateParallelStart,\n orchestratePlan,\n orchestrateReady,\n orchestrateReport,\n orchestrateSkillInject,\n orchestrateSpawn,\n orchestrateSpawnExecute,\n orchestrateStartup,\n orchestrateStatus,\n orchestrateUnblockOpportunities,\n orchestrateValidate,\n orchestrateWaves,\n type ProviderMatrixEntry,\n // Pipeline engine-ops (ENG-MIG-11 / T1578 — migrated to @cleocode/core/internal)\n // pipeline-engine.ts shrunk to a shim; all symbols now live in core/pipeline/engine-ops.ts.\n phaseAdvance,\n phaseComplete,\n phaseDelete,\n phaseList,\n phaseRename,\n phaseSet,\n phaseShow,\n phaseStart,\n pipelineManifestAppend,\n pipelineManifestArchive,\n pipelineManifestFind,\n pipelineManifestList,\n pipelineManifestPending,\n pipelineManifestShow,\n pipelineManifestStats,\n queryCommonHooks,\n queryHookProviders,\n readManifestEntries,\n releaseCancel,\n releaseCommit,\n releaseGateCheck,\n releaseGatesRun,\n releaseIvtrAutoSuggest,\n releaseList,\n releaseOpen,\n releasePlan,\n releasePrepare,\n releasePrStatus,\n releasePush,\n releaseReconcileV2,\n releaseRollback,\n releaseRollbackFull,\n releaseShow,\n releaseTag,\n sessionAdopt,\n sessionArchive,\n sessionBriefing,\n sessionChainShow,\n sessionCleanup,\n // T4959: Rich debrief + chain\n sessionComputeDebrief,\n sessionComputeHandoff,\n sessionContextDrift,\n sessionContextInject,\n sessionDebriefShow,\n sessionDecisionLog,\n sessionEnd,\n // T5119: Lightweight session discovery\n sessionFind,\n sessionGc,\n sessionHandoff,\n sessionHistory,\n sessionList,\n sessionRecordAssumption,\n sessionRecordDecision,\n sessionResume,\n sessionShow,\n sessionStart,\n sessionStats,\n sessionStatus,\n sessionSuspend,\n sessionSwitch,\n systemHooksMatrix,\n taskAnalyze,\n taskArchive,\n // T11786 (epic T11556) — first-class assignee set/clear (distinct from claim).\n taskAssignee,\n taskBatchValidate,\n taskBlockers,\n // T11786 (epic T11556) — atomic multi-task status/stage move.\n taskBulkMove,\n taskCancel,\n taskClaim,\n taskComplete,\n taskComplexityEstimate,\n taskCurrentGet,\n taskDecompose,\n taskDelete,\n taskDepends,\n taskDeps,\n taskDepsCycles,\n taskDepsOverview,\n taskDepsTree,\n taskDepsValidate,\n taskExists,\n taskExport,\n taskFind,\n taskHistory,\n taskImpact,\n taskImport,\n taskLabelList,\n taskLabelShow,\n taskLint,\n taskList,\n taskNext,\n taskPlan,\n taskPromote,\n taskRankingHistory,\n taskRankingRevert,\n taskReconcileScope,\n taskRelates,\n taskRelatesAdd,\n taskRelatesAddBatch,\n taskRelatesFind,\n taskRelatesRemove,\n taskReopen,\n taskReorder,\n // T11786 (epic T11556) — explicit within-column re-rank from an ID order.\n taskReorderRank,\n taskReparent,\n taskRestore,\n taskShow,\n taskShowIvtrHistory,\n taskShowOperation,\n taskShowWithHistory,\n taskSlice,\n taskStart,\n taskStats,\n taskStop,\n taskSyncLinks,\n taskSyncLinksRemove,\n taskSyncReconcile,\n tasksAddBatchOp,\n taskTree,\n taskUnarchive,\n taskUnclaim,\n taskUpdate,\n taskWorkHistory,\n // T9937 — validate-changelog verb (Saga T9862)\n validateChangelog,\n validateGateVerify,\n // T5327 + T260: Protocol validation operations (12 protocols)\n validateProtocolArchitectureDecision,\n validateProtocolArtifactPublish,\n validateProtocolConsensus,\n validateProtocolContribution,\n validateProtocolDecomposition,\n validateProtocolImplementation,\n validateProtocolProvenance,\n validateProtocolRelease,\n validateProtocolResearch,\n validateProtocolSpecification,\n validateProtocolTesting,\n validateProtocolValidation,\n} from '@cleocode/core/internal';\n// Template parser engine\nexport {\n generateTemplateConfig,\n getTemplateForSubcommand,\n type IssueTemplate,\n parseIssueTemplates,\n type TemplateConfig,\n type TemplateSection,\n validateLabels,\n} from './template-parser.js';\n","/**\n * Template Parser Engine (Re-export Adapter)\n *\n * Thin re-export from core's templates/parser, adapting the core\n * TemplateResult type to the gateway EngineResult type.\n *\n * All business logic lives in `@cleocode/core/internal`.\n * This file preserves backward compatibility for existing importers.\n *\n * @remarks\n * Relocated from `packages/cleo/src/dispatch/engines/template-parser.ts` into\n * `@cleocode/runtime/gateway` (R3-K1 · T11455 · SG-RUNTIME-UNIFICATION) as a\n * dependency of the relocated engine barrel.\n *\n * @task T5705\n * @task T11455\n * @epic T5701\n */\n\nimport {\n generateTemplateConfig as coreGenerateTemplateConfig,\n getTemplateForSubcommand as coreGetTemplateForSubcommand,\n parseIssueTemplates as coreParseIssueTemplates,\n templates,\n} from '@cleocode/core/internal';\nimport type { EngineResult } from './engine-error.js';\n\n// Re-export types directly from core\nexport type {\n IssueTemplate,\n TemplateConfig,\n TemplateSection,\n} from '@cleocode/core/internal';\n\n/**\n * Adapt a core TemplateResult to an EngineResult.\n * The shapes are compatible -- TemplateResult is a subset of EngineResult.\n */\nfunction adaptResult<T>(result: {\n success: boolean;\n data?: T;\n error?: { code: string; message: string; details?: Record<string, unknown> };\n}): EngineResult<T> {\n if (result.success) {\n if (result.data === undefined) {\n return {\n success: false,\n error: { code: 'E_INTERNAL', message: 'Template parser succeeded with no data' },\n };\n }\n return { success: true, data: result.data };\n }\n return {\n success: false,\n error: result.error\n ? {\n code: result.error.code,\n message: result.error.message,\n ...(result.error.details ? { details: result.error.details } : {}),\n }\n : { code: 'E_INTERNAL', message: 'Unknown error' },\n };\n}\n\n/**\n * Parse all templates from the repo's .github/ISSUE_TEMPLATE/ directory.\n *\n * @remarks\n * Delegates to the core template parser and adapts the result to the\n * dispatch EngineResult type.\n *\n * @param projectRoot - Absolute path to the project root\n * @returns EngineResult containing the parsed template configuration\n *\n * @example\n * ```typescript\n * const result = parseIssueTemplates('/path/to/project');\n * if (result.success) {\n * console.log(result.data.templates);\n * }\n * ```\n */\nexport function parseIssueTemplates(\n projectRoot: string,\n): EngineResult<import('@cleocode/core/internal').TemplateConfig> {\n return adaptResult(coreParseIssueTemplates(projectRoot));\n}\n\n/**\n * Get template config for a specific subcommand (bug/feature/help).\n *\n * @remarks\n * Looks up a specific template by subcommand name from the project's\n * issue template directory.\n *\n * @param projectRoot - Absolute path to the project root\n * @param subcommand - Template subcommand identifier (e.g. \"bug\", \"feature\")\n * @returns EngineResult containing the matched issue template\n *\n * @example\n * ```typescript\n * const result = getTemplateForSubcommand('/path/to/project', 'bug');\n * ```\n */\nexport function getTemplateForSubcommand(\n projectRoot: string,\n subcommand: string,\n): EngineResult<import('@cleocode/core/internal').IssueTemplate> {\n return adaptResult(coreGetTemplateForSubcommand(projectRoot, subcommand));\n}\n\n/**\n * Generate and cache the config as .cleo/issue-templates.json.\n *\n * @remarks\n * Parses all templates and writes the resulting config to disk for caching.\n *\n * @param projectRoot - Absolute path to the project root\n * @returns EngineResult containing the generated template configuration\n *\n * @example\n * ```typescript\n * const result = await generateTemplateConfig('/path/to/project');\n * ```\n */\nexport async function generateTemplateConfig(\n projectRoot: string,\n): Promise<EngineResult<import('@cleocode/core/internal').TemplateConfig>> {\n return adaptResult(await coreGenerateTemplateConfig(projectRoot));\n}\n\n/**\n * Validate that labels exist on a GitHub repo.\n *\n * @remarks\n * Compares a set of required labels against the labels found on the repo.\n *\n * @param labels - Labels required by the template\n * @param repoLabels - Labels that exist on the GitHub repo\n * @returns EngineResult with existing and missing label lists\n *\n * @example\n * ```typescript\n * const result = validateLabels(['bug', 'enhancement'], repoLabels);\n * ```\n */\nexport function validateLabels(\n labels: string[],\n repoLabels: string[],\n): EngineResult<{ existing: string[]; missing: string[] }> {\n return adaptResult(templates.validateLabels(labels, repoLabels));\n}\n","/**\n * Singleton accessor for the gateway {@link BackgroundJobManager}.\n *\n * @remarks\n * Relocated from `packages/cleo/src/dispatch/lib/job-manager-accessor.ts` into\n * `@cleocode/runtime/gateway` (R3-K1 · T11455 · SG-RUNTIME-UNIFICATION) so the\n * `admin` domain handler resolves the job-manager singleton from the runtime\n * layer rather than a cleo-internal path. A thin re-export shim remains at the\n * old path so any existing import site compiles unchanged.\n *\n * Long-lived hosts (e.g. the daemon) call {@link setJobManager} once at startup;\n * short-lived CLI invocations leave the singleton `null`, and consumers handle\n * the absence gracefully.\n *\n * @task T4820\n * @task T11455\n */\n\nimport type { BackgroundJobManager } from '@cleocode/core/store/background-jobs.js';\n\n/** Process-wide singleton instance, or `null` when no host has registered one. */\nlet _instance: BackgroundJobManager | null = null;\n\n/**\n * Register the process-wide {@link BackgroundJobManager} singleton.\n *\n * @param manager - The manager to expose, or null to unregister a stopped host.\n * @remarks Hosts unregister before closing their store; absence is reported explicitly.\n */\nexport function setJobManager(manager: BackgroundJobManager | null): void {\n _instance = manager;\n}\n\n/**\n * Retrieve the registered {@link BackgroundJobManager} singleton.\n *\n * @returns The registered manager, or `null` when running in a short-lived\n * host (e.g. a one-shot CLI invocation) that never called {@link setJobManager}.\n */\nexport function getJobManager(): BackgroundJobManager | null {\n return _instance;\n}\n","/**\n * Daemon-side gateway server bootstrap — the call-site `cleo daemon serve`\n * drives (T11919).\n *\n * The HTTP gateway adapter (`./http/listen.ts`, T11254) and the supervised\n * `defineGatewaySubsystem` unit (`./daemon-subsystem.ts`, T11451) both already\n * exist, but nothing started them: the daemon had no `serve` call-site. This\n * module is that thin bootstrap — it assembles a {@link SubsystemRegistry} with\n * one scoped gateway subsystem hosting the HTTP transport (loopback by default)\n * over an INJECTED {@link GatewayHandler}, starts it, and returns a live handle\n * with the bound port + an idempotent `close()`.\n *\n * It carries NO `@cleocode/cleo` dependency and NO drizzle (the runtime\n * invariant): the caller (`cleo daemon serve`) injects the assembled CLI gateway\n * handler and the resolved bind coordinates. Secrets never touch the wire —\n * sealed-handle resolution happens server-side inside the dispatched handler,\n * exactly as it does for an in-process CLI call. The HTTP listener binds\n * `127.0.0.1` by default (loopback only); exposing it on a public interface is\n * an explicit caller decision.\n *\n * The streaming transports (SSE — T11921, WS — T11922) extend the SAME\n * subsystem: when their listeners land they bind alongside the unary HTTP server\n * here, so this bootstrap deliberately owns only transport assembly + lifecycle,\n * leaving the per-route seam to the adapter (`parseHttpRoute`).\n *\n * @packageDocumentation\n * @module @cleocode/runtime/gateway\n *\n * @task T11919\n * @epic T11769\n * @saga T10400\n */\n\nimport { defineGatewaySubsystem, type GatewayScope } from './daemon-subsystem.js';\nimport type { GatewayHandler } from './index.js';\n\n/** Default loopback host for the HTTP gateway — local-process-facing only. */\nconst DEFAULT_HOST = '127.0.0.1';\n\n/**\n * Options for {@link serveGateway}.\n *\n * The caller injects the assembled {@link GatewayHandler} and resolves the bind\n * coordinates so the runtime stays free of `@cleocode/paths`/`@cleocode/cleo`.\n */\nexport interface ServeGatewayOptions {\n /** The transport-neutral gateway handler every hosted transport routes through. */\n handler: GatewayHandler;\n /** TCP port to bind. `0` selects an ephemeral port (readable from the handle). */\n port: number;\n /** Host/interface to bind. Defaults to `127.0.0.1` (loopback only). */\n host?: string;\n /** The scope this gateway process serves. Defaults to `'global'`. */\n scope?: GatewayScope;\n /**\n * Absolute path to the Studio static asset directory (T11979).\n *\n * When set, the HTTP server serves the bundled CLEO Web Studio at `/studio`\n * using the `build/client/` static assets from an `adapter-node` Studio build.\n * When `undefined`, `/studio` routes return a clean 503 \"bundle absent\" JSON\n * envelope. The caller resolves this path (typically via\n * `resolveStudioStaticDir` from `@cleocode/cleo`) so the runtime stays free of\n * any path-resolution policy.\n */\n studioStaticDir?: string;\n}\n\n/**\n * A live gateway server handle returned by {@link serveGateway}.\n *\n * Exposes the actually-bound `port`/`host` (resolved even when `0` was\n * requested) and an idempotent {@link close} for deterministic teardown\n * (daemon shutdown, tests). Mirrors the lower-level\n * {@link import('./http/listen.js').HttpServerHandle} so a test can boot, probe,\n * and tear down on an ephemeral port.\n */\nexport interface ServeGatewayHandle {\n /** The actually-bound HTTP port (resolved when `0` was requested). */\n port: number;\n /** Host/interface the HTTP listener is bound to. */\n host: string;\n /** The scope the gateway process serves. */\n scope: GatewayScope;\n /** Stop every bound listener (best-effort, idempotent); resolves once closed. */\n close(): Promise<void>;\n}\n\n/**\n * Boot the HTTP gateway as a supervised subsystem and return a live handle.\n *\n * Declares one scoped gateway subsystem hosting the HTTP transport (loopback\n * default) over the injected handler via {@link defineGatewaySubsystem}, starts\n * it, and reads the actually-bound port from the start context (so the caller —\n * and tests — learn the ephemeral port when `0` was requested). The returned\n * `close()` drives the subsystem's `shutdown(context)` so teardown is the same\n * lifecycle the daemon registry uses for every other supervised concern.\n *\n * Using `defineGatewaySubsystem` directly (rather than a full\n * `SubsystemRegistry`) keeps the bound HTTP handle in reach for the port\n * resolution while still routing through the canonical start→shutdown contract.\n *\n * @param opts - The injected handler + resolved bind coordinates.\n * @returns A promise resolving to the live {@link ServeGatewayHandle}.\n *\n * @example\n * ```ts\n * const handle = await serveGateway({\n * handler: createCliGatewayHandler(),\n * port: 0, // ephemeral\n * });\n * // POST http://127.0.0.1:${handle.port}/v1/tasks/show\n * await handle.close();\n * ```\n */\nexport async function serveGateway(opts: ServeGatewayOptions): Promise<ServeGatewayHandle> {\n const host = opts.host ?? DEFAULT_HOST;\n const scope: GatewayScope = opts.scope ?? 'global';\n\n const subsystem = defineGatewaySubsystem({\n scope,\n handler: opts.handler,\n http: { port: opts.port, host, studioStaticDir: opts.studioStaticDir },\n });\n\n const context = await subsystem.start();\n // The HTTP transport is configured, so `start()` always binds it.\n const boundPort = context.http?.port ?? opts.port;\n\n let closed = false;\n return {\n port: boundPort,\n host,\n scope,\n async close(): Promise<void> {\n if (closed) return;\n closed = true;\n await subsystem.shutdown(context);\n },\n };\n}\n"],"mappings":"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,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAIA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;AClSP;AAAA,EACE,0BAA0B;AAAA,EAC1B,4BAA4B;AAAA,EAC5B,uBAAuB;AAAA,EACvB;AAAA,OACK;AAcP,SAAS,YAAe,QAIJ;AAClB,MAAI,OAAO,SAAS;AAClB,QAAI,OAAO,SAAS,QAAW;AAC7B,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO,EAAE,MAAM,cAAc,SAAS,yCAAyC;AAAA,MACjF;AAAA,IACF;AACA,WAAO,EAAE,SAAS,MAAM,MAAM,OAAO,KAAK;AAAA,EAC5C;AACA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,OAAO,OAAO,QACV;AAAA,MACE,MAAM,OAAO,MAAM;AAAA,MACnB,SAAS,OAAO,MAAM;AAAA,MACtB,GAAI,OAAO,MAAM,UAAU,EAAE,SAAS,OAAO,MAAM,QAAQ,IAAI,CAAC;AAAA,IAClE,IACA,EAAE,MAAM,cAAc,SAAS,gBAAgB;AAAA,EACrD;AACF;AAoBO,SAAS,oBACd,aACgE;AAChE,SAAO,YAAY,wBAAwB,WAAW,CAAC;AACzD;AAkBO,SAAS,yBACd,aACA,YAC+D;AAC/D,SAAO,YAAY,6BAA6B,aAAa,UAAU,CAAC;AAC1E;AAgBA,eAAsB,uBACpB,aACyE;AACzE,SAAO,YAAY,MAAM,2BAA2B,WAAW,CAAC;AAClE;AAiBO,SAAS,eACd,QACA,YACyD;AACzD,SAAO,YAAY,UAAU,eAAe,QAAQ,UAAU,CAAC;AACjE;;;AClIA,IAAI,YAAyC;AAQtC,SAAS,cAAc,SAA4C;AACxE,cAAY;AACd;AAQO,SAAS,gBAA6C;AAC3D,SAAO;AACT;;;ACJA,IAAM,eAAe;AA6ErB,eAAsB,aAAa,MAAwD;AACzF,QAAM,OAAO,KAAK,QAAQ;AAC1B,QAAM,QAAsB,KAAK,SAAS;AAE1C,QAAM,YAAY,uBAAuB;AAAA,IACvC;AAAA,IACA,SAAS,KAAK;AAAA,IACd,MAAM,EAAE,MAAM,KAAK,MAAM,MAAM,iBAAiB,KAAK,gBAAgB;AAAA,EACvE,CAAC;AAED,QAAM,UAAU,MAAM,UAAU,MAAM;AAEtC,QAAM,YAAY,QAAQ,MAAM,QAAQ,KAAK;AAE7C,MAAI,SAAS;AACb,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,MAAM,QAAuB;AAC3B,UAAI,OAAQ;AACZ,eAAS;AACT,YAAM,UAAU,SAAS,OAAO;AAAA,IAClC;AAAA,EACF;AACF;","names":[]}
|
|
@@ -1,11 +1,233 @@
|
|
|
1
|
-
|
|
1
|
+
import { G as GatewayHandler } from '../../gateway-handler-DCU6E0a2.js';
|
|
2
|
+
import { OperationDef } from '@cleocode/contracts';
|
|
2
3
|
import '@cleocode/contracts/gateway';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* MCP wire types for the `@cleocode/runtime/gateway/mcp` transport adapter.
|
|
7
|
+
*
|
|
8
|
+
* A deliberately-minimal subset of the Model Context Protocol shapes the
|
|
9
|
+
* adapter needs — no external MCP SDK dependency. Mirrors the legacy
|
|
10
|
+
* `@cleocode/mcp-adapter` `types.ts` so the wire surface is unchanged.
|
|
11
|
+
*
|
|
12
|
+
* @task T11448
|
|
13
|
+
* @epic T11254
|
|
14
|
+
* @saga T11243
|
|
15
|
+
*/
|
|
16
|
+
/** JSON Schema property descriptor surfaced for a single tool input field. */
|
|
17
|
+
interface McpInputProperty {
|
|
18
|
+
/** JSON Schema primitive type (`'string'`, `'number'`, …). */
|
|
19
|
+
type: string;
|
|
20
|
+
/** Human-readable description shown in MCP clients. */
|
|
21
|
+
description: string;
|
|
22
|
+
/** Allowed values (JSON Schema `enum`) for finite-domain string params. */
|
|
23
|
+
enum?: readonly string[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* MCP tool definition shape (minimal — no external MCP SDK dependency).
|
|
27
|
+
* Structurally compatible with the legacy `@cleocode/mcp-adapter` `McpTool`.
|
|
28
|
+
*/
|
|
29
|
+
interface McpTool {
|
|
30
|
+
/** Stable tool name (snake_case, e.g. `cleo_sentient_status`). */
|
|
31
|
+
name: string;
|
|
32
|
+
/** Human-readable description shown in MCP clients. */
|
|
33
|
+
description: string;
|
|
34
|
+
/** JSON Schema for the tool's input parameters. */
|
|
35
|
+
inputSchema: {
|
|
36
|
+
type: 'object';
|
|
37
|
+
properties: Record<string, McpInputProperty>;
|
|
38
|
+
required?: string[];
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/** A single content block returned by a tool handler. */
|
|
42
|
+
interface McpContent {
|
|
43
|
+
type: 'text';
|
|
44
|
+
text: string;
|
|
45
|
+
}
|
|
46
|
+
/** Result returned by a tool handler over the MCP wire. */
|
|
47
|
+
interface McpToolResult {
|
|
48
|
+
content: McpContent[];
|
|
49
|
+
isError?: boolean;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* MCP stdio transport adapter — routes `tools/call` through the gateway.
|
|
54
|
+
*
|
|
55
|
+
* Serves the Model Context Protocol over stdio (newline-delimited JSON-RPC 2.0)
|
|
56
|
+
* so any MCP-compatible client (Claude Code, LLM-agnostic tools) can discover
|
|
57
|
+
* and invoke CLEO operations. Unlike the legacy standalone `@cleocode/mcp-adapter`
|
|
58
|
+
* — which called the `@cleocode/core` SDK directly — this adapter is a thin
|
|
59
|
+
* TRANSPORT over the unified gateway:
|
|
60
|
+
*
|
|
61
|
+
* MCP `tools/call` { name, arguments }
|
|
62
|
+
* → {@link GatewayOperationKey} (via the `mcpExposed` registry subset)
|
|
63
|
+
* → DispatchRequest { source: 'mcp', gateway, domain, operation, params }
|
|
64
|
+
* → injected {@link GatewayHandler}.handle()
|
|
65
|
+
* → DispatchResponse (LAFS envelope) → MCP tool result (JSON text content)
|
|
66
|
+
*
|
|
67
|
+
* The adapter owns ONLY wire concerns: JSON-RPC framing, the stdio read loop,
|
|
68
|
+
* `tools/list` generation, error rendering, and `process.exit` on stream close.
|
|
69
|
+
* All domain logic (resolution, validation, middleware, handler execution) lives
|
|
70
|
+
* behind the {@link GatewayHandler} — exactly mirroring how the CLI adapter
|
|
71
|
+
* wraps the same handler. `process.exit` and error-render stay HERE, never in
|
|
72
|
+
* the handlers (R3-T4 contract).
|
|
73
|
+
*
|
|
74
|
+
* `tools/list` is generated from the OPERATIONS registry behind the default-deny
|
|
75
|
+
* `mcpExposed` flag, so the external tool surface is identical to the historical
|
|
76
|
+
* standalone adapter (no behavior change).
|
|
77
|
+
*
|
|
78
|
+
* @task T11448
|
|
79
|
+
* @epic T11254
|
|
80
|
+
* @saga T11243
|
|
81
|
+
*/
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Route a single MCP `tools/call` through the gateway handler.
|
|
85
|
+
*
|
|
86
|
+
* Resolves the tool name to a `(domain, operation)` key against the exposed
|
|
87
|
+
* (`mcpExposed`) registry subset, builds a `source: 'mcp'` {@link DispatchRequest},
|
|
88
|
+
* and delegates to the injected {@link GatewayHandler}. Unknown tool names and
|
|
89
|
+
* thrown handler errors are rendered as MCP error results — never propagated as
|
|
90
|
+
* `process.exit` from this layer.
|
|
91
|
+
*
|
|
92
|
+
* @param handler - The injected transport-neutral gateway handler.
|
|
93
|
+
* @param toolName - The MCP `tools/call` tool name.
|
|
94
|
+
* @param args - The parsed tool arguments (already JSON-decoded by the client).
|
|
95
|
+
* @returns An MCP {@link McpToolResult}.
|
|
96
|
+
*/
|
|
97
|
+
declare function callTool(handler: GatewayHandler, toolName: string, args: Record<string, unknown>): Promise<McpToolResult>;
|
|
98
|
+
/**
|
|
99
|
+
* Options for {@link startMcpServer}.
|
|
100
|
+
*/
|
|
101
|
+
interface McpServerOptions {
|
|
102
|
+
/** Inbound stream (defaults to `process.stdin`). */
|
|
103
|
+
input?: NodeJS.ReadableStream;
|
|
104
|
+
/** Outbound stream (defaults to `process.stdout`). */
|
|
105
|
+
output?: NodeJS.WritableStream;
|
|
106
|
+
/**
|
|
107
|
+
* Whether to call `process.exit(0)` when the input stream closes.
|
|
108
|
+
* Defaults to `true` (production stdio). Tests pass `false`.
|
|
109
|
+
*/
|
|
110
|
+
exitOnClose?: boolean;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Start the MCP stdio server over the gateway.
|
|
114
|
+
*
|
|
115
|
+
* Reads newline-delimited JSON-RPC 2.0 requests from the input stream, routes
|
|
116
|
+
* `tools/call` through the injected {@link GatewayHandler}, and writes responses
|
|
117
|
+
* to the output stream. Each inbound line must be one complete JSON-RPC request.
|
|
118
|
+
*
|
|
119
|
+
* The caller assembles the {@link GatewayHandler} (via `createGatewayHandler`
|
|
120
|
+
* with its domain handlers + middleware) and injects it here — this adapter
|
|
121
|
+
* never builds handlers itself, keeping the runtime free of any
|
|
122
|
+
* `@cleocode/cleo` dependency.
|
|
123
|
+
*
|
|
124
|
+
* @param handler - The transport-neutral gateway handler to route through.
|
|
125
|
+
* @param opts - Optional stream + lifecycle overrides (defaults to stdio).
|
|
126
|
+
*/
|
|
127
|
+
declare function startMcpServer(handler: GatewayHandler, opts?: McpServerOptions): void;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* MCP tool-name <-> gateway-operation mapping.
|
|
131
|
+
*
|
|
132
|
+
* The MCP wire protocol identifies a tool by a single flat `name` string
|
|
133
|
+
* (snake_case, e.g. `cleo_sentient_propose_list`), whereas the gateway routes
|
|
134
|
+
* on a `(gateway, domain, operation)` triple (e.g.
|
|
135
|
+
* `query / sentient / propose.list`). This module is the bijective bridge
|
|
136
|
+
* between the two surfaces:
|
|
137
|
+
*
|
|
138
|
+
* gateway op → MCP tool name {@link operationToToolName}
|
|
139
|
+
* MCP tool name → domain+operation {@link toolNameToOperationKey}
|
|
140
|
+
*
|
|
141
|
+
* ## Naming convention (frozen — matches the legacy `@cleocode/mcp-adapter`)
|
|
142
|
+
*
|
|
143
|
+
* `cleo_<domain>_<operation>` where every `.` and `-` in the dotted operation
|
|
144
|
+
* name becomes `_`. The three historically-exposed tools therefore map as:
|
|
145
|
+
*
|
|
146
|
+
* | gateway op | MCP tool name |
|
|
147
|
+
* |-----------------------------|--------------------------------|
|
|
148
|
+
* | `sentient` · `status` | `cleo_sentient_status` |
|
|
149
|
+
* | `sentient` · `propose.list` | `cleo_sentient_propose_list` |
|
|
150
|
+
* | `sentient` · `propose.enable` | `cleo_sentient_propose_enable` |
|
|
151
|
+
*
|
|
152
|
+
* Preserving this exact mapping is what guarantees R3-T4's "no behavior change
|
|
153
|
+
* to the MCP tool surface" acceptance criterion.
|
|
154
|
+
*
|
|
155
|
+
* @task T11448
|
|
156
|
+
* @epic T11254
|
|
157
|
+
* @saga T11243
|
|
158
|
+
*/
|
|
159
|
+
|
|
160
|
+
/** Prefix every CLEO MCP tool name carries. */
|
|
161
|
+
declare const MCP_TOOL_PREFIX = "cleo_";
|
|
162
|
+
/**
|
|
163
|
+
* Identifies a gateway operation by its `(domain, operation)` pair. The CQRS
|
|
164
|
+
* gateway resolves which `Gateway` ('query' | 'mutate') the pair belongs to via
|
|
165
|
+
* the operation registry, so the MCP adapter does not need to carry it.
|
|
166
|
+
*/
|
|
167
|
+
interface GatewayOperationKey {
|
|
168
|
+
/** Canonical domain (e.g. `'sentient'`). */
|
|
169
|
+
readonly domain: string;
|
|
170
|
+
/** Dotted operation name (e.g. `'propose.list'`). */
|
|
171
|
+
readonly operation: string;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Derive the flat MCP tool name for a gateway operation.
|
|
175
|
+
*
|
|
176
|
+
* @param op - An {@link OperationDef} (or any object carrying `domain` +
|
|
177
|
+
* `operation`) from the registry.
|
|
178
|
+
* @returns The MCP tool name, e.g. `'cleo_sentient_propose_list'`.
|
|
179
|
+
*/
|
|
180
|
+
declare function operationToToolName(op: Pick<OperationDef, 'domain' | 'operation'>): string;
|
|
181
|
+
/**
|
|
182
|
+
* Resolve an MCP tool name back to its `(domain, operation)` gateway key.
|
|
183
|
+
*
|
|
184
|
+
* The reverse of {@link operationToToolName} cannot recover dots vs dashes from
|
|
185
|
+
* the snake_case wire form, so resolution is performed against the provided
|
|
186
|
+
* `exposed` set (the same `mcpExposed: true` subset used to build `tools/list`).
|
|
187
|
+
* This keeps the mapping exact and rejects unknown tool names.
|
|
188
|
+
*
|
|
189
|
+
* @param toolName - The MCP `tools/call` tool name.
|
|
190
|
+
* @param exposed - The exposed operation defs (the `mcpExposed` subset).
|
|
191
|
+
* @returns The matching {@link GatewayOperationKey}, or `undefined` when the
|
|
192
|
+
* tool name does not correspond to any exposed operation.
|
|
193
|
+
*/
|
|
194
|
+
declare function toolNameToOperationKey(toolName: string, exposed: readonly OperationDef[]): GatewayOperationKey | undefined;
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* MCP `tools/list` generation from the OPERATIONS registry.
|
|
198
|
+
*
|
|
199
|
+
* The MCP tool surface is **default-deny**: only {@link OperationDef} entries
|
|
200
|
+
* that explicitly set `mcpExposed: true` are surfaced. This replaces the legacy
|
|
201
|
+
* `@cleocode/mcp-adapter`'s hand-maintained `ALL_TOOLS` array with a single
|
|
202
|
+
* generation point driven by the canonical registry — promoting a new tool is
|
|
203
|
+
* now one `mcpExposed: true` edit in `@cleocode/contracts`, not a fork-and-copy
|
|
204
|
+
* into a standalone adapter.
|
|
205
|
+
*
|
|
206
|
+
* @task T11448
|
|
207
|
+
* @epic T11254
|
|
208
|
+
* @saga T11243
|
|
209
|
+
*/
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* The subset of OPERATIONS surfaced over MCP (default-deny `mcpExposed` filter).
|
|
213
|
+
*
|
|
214
|
+
* @returns Every {@link OperationDef} with `mcpExposed === true`, in registry
|
|
215
|
+
* order. Empty when no operation opts in.
|
|
216
|
+
*/
|
|
217
|
+
declare function exposedOperations(): OperationDef[];
|
|
218
|
+
/**
|
|
219
|
+
* Convert a single exposed {@link OperationDef} into its MCP tool definition.
|
|
220
|
+
*
|
|
221
|
+
* @param op - An operation with `mcpExposed === true`.
|
|
222
|
+
* @returns The MCP {@link McpTool} (name + description + inputSchema).
|
|
223
|
+
*/
|
|
224
|
+
declare function operationToMcpTool(op: OperationDef): McpTool;
|
|
225
|
+
/**
|
|
226
|
+
* Generate the full MCP `tools/list` payload from the registry.
|
|
227
|
+
*
|
|
228
|
+
* @returns Every exposed operation rendered as an {@link McpTool}, in registry
|
|
229
|
+
* order (stable across calls).
|
|
230
|
+
*/
|
|
231
|
+
declare function buildToolsList(): McpTool[];
|
|
232
|
+
|
|
233
|
+
export { type GatewayOperationKey, MCP_TOOL_PREFIX, type McpContent, type McpInputProperty, type McpServerOptions, type McpTool, type McpToolResult, buildToolsList, callTool, exposedOperations, operationToMcpTool, operationToToolName, startMcpServer, toolNameToOperationKey };
|
|
@@ -7,8 +7,8 @@ import {
|
|
|
7
7
|
operationToToolName,
|
|
8
8
|
startMcpServer,
|
|
9
9
|
toolNameToOperationKey
|
|
10
|
-
} from "../../chunk-
|
|
11
|
-
import "../../chunk-
|
|
10
|
+
} from "../../chunk-WO6LJMDC.js";
|
|
11
|
+
import "../../chunk-4PUSKGDO.js";
|
|
12
12
|
export {
|
|
13
13
|
MCP_TOOL_PREFIX,
|
|
14
14
|
buildToolsList,
|