@remnic/core 9.3.623 → 9.3.624

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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  EngramAccessHttpServer
3
- } from "./chunk-ZJSZNTEI.js";
3
+ } from "./chunk-FG76RDVI.js";
4
4
  import "./chunk-SEDEKFYQ.js";
5
5
  import "./chunk-2QSZNTDO.js";
6
6
  import "./chunk-RSUYKGGZ.js";
@@ -209,7 +209,7 @@ import {
209
209
  } from "./chunk-OADWQ5CR.js";
210
210
  import {
211
211
  EngramAccessHttpServer
212
- } from "./chunk-ZJSZNTEI.js";
212
+ } from "./chunk-FG76RDVI.js";
213
213
  import {
214
214
  EngramMcpServer
215
215
  } from "./chunk-I6UCUHLK.js";
@@ -6623,4 +6623,4 @@ export {
6623
6623
  resolveMemoryDirForNamespace,
6624
6624
  registerCli
6625
6625
  };
6626
- //# sourceMappingURL=chunk-C4PZTWTG.js.map
6626
+ //# sourceMappingURL=chunk-7TPH6UZL.js.map
@@ -741,12 +741,11 @@ var EngramAccessHttpServer = class {
741
741
  ...disclosure !== void 0 ? { disclosure } : {}
742
742
  });
743
743
  } catch (err) {
744
- const message = err instanceof Error ? err.message : String(err);
745
- if (message.startsWith("recallXray:")) {
744
+ if (err instanceof Error && err.message.startsWith("recallXray:")) {
746
745
  this.respondJson(res, 400, {
747
746
  error: "invalid_request",
748
747
  code: "invalid_request",
749
- message
748
+ message: err.message
750
749
  });
751
750
  return;
752
751
  }
@@ -1235,12 +1234,11 @@ var EngramAccessHttpServer = class {
1235
1234
  );
1236
1235
  this.respondJson(res, 200, snapshot);
1237
1236
  } catch (err) {
1238
- const message = err instanceof Error ? err.message : String(err);
1239
- if (message.startsWith("graphSnapshot:")) {
1237
+ if (err instanceof Error && err.message.startsWith("graphSnapshot:")) {
1240
1238
  this.respondJson(res, 400, {
1241
1239
  error: "invalid_request",
1242
1240
  code: "invalid_request",
1243
- message
1241
+ message: err.message
1244
1242
  });
1245
1243
  return;
1246
1244
  }
@@ -1847,4 +1845,4 @@ var EngramAccessHttpServer = class {
1847
1845
  export {
1848
1846
  EngramAccessHttpServer
1849
1847
  };
1850
- //# sourceMappingURL=chunk-ZJSZNTEI.js.map
1848
+ //# sourceMappingURL=chunk-FG76RDVI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/access-http.ts"],"sourcesContent":["import { createServer, type IncomingMessage, type Server, type ServerResponse } from \"node:http\";\nimport { randomUUID, timingSafeEqual } from \"node:crypto\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath, URL } from \"node:url\";\nimport { gunzipSync } from \"node:zlib\";\nimport { log } from \"./logger.js\";\nimport { EngramAccessInputError, type EngramAccessService } from \"./access-service.js\";\nimport { EngramMcpServer } from \"./access-mcp.js\";\nimport { validateRequest, type SchemaName, type SchemaTypeFor } from \"./access-schema.js\";\nimport {\n OFFLINE_SYNC_APPLY_MAX_BODY_BYTES,\n OFFLINE_SYNC_FILE_CONTENT_MAX_CHUNK_BYTES,\n OFFLINE_SYNC_SNAPSHOT_BASE_MAX_BODY_BYTES,\n} from \"./offline-sync.js\";\nimport type { RecallDisclosure, RecallPlanMode } from \"./types.js\";\nimport { isRecallDisclosure } from \"./types.js\";\nimport { isTrustZoneName, type TrustZoneName, type TrustZoneRecordKind, type TrustZoneSourceClass } from \"./trust-zones.js\";\nimport { AdapterRegistry, type ResolvedIdentity } from \"./adapters/index.js\";\nimport type { CitationEntry } from \"./citations.js\";\nimport {\n subscribeGraphEvents,\n type GraphEvent,\n} from \"./graph-events.js\";\nimport { expandTildePath } from \"./utils/path.js\";\nimport { projectTagProjectId } from \"./coding/coding-namespace.js\";\n\nexport interface EngramAccessHttpServerOptions {\n service: EngramAccessService;\n host?: string;\n port?: number;\n authToken?: string;\n /** Additional valid tokens (for multi-connector auth). Checked alongside authToken. */\n authTokens?: string[];\n /** Dynamic token loader — called on each auth check so new/revoked tokens take effect without restart. */\n authTokensGetter?: () => string[];\n principal?: string;\n maxBodyBytes?: number;\n adminConsoleEnabled?: boolean;\n adminConsolePublicDir?: string;\n trustPrincipalHeader?: boolean;\n /** Enable adapter-based identity resolution from request headers */\n enableAdapters?: boolean;\n /** Custom adapter registry (defaults to built-in adapters) */\n adapterRegistry?: AdapterRegistry;\n /** Enable oai-mem-citation blocks in recall responses (issue #379). */\n citationsEnabled?: boolean;\n /** Auto-enable citations for Codex adapter connections (issue #379). */\n citationsAutoDetect?: boolean;\n /** Advertise legacy engram.* tool aliases on tools/list (issue #1427). Default true. */\n emitLegacyTools?: boolean;\n}\n\nexport interface EngramAccessHttpServerStatus {\n running: boolean;\n host: string;\n port: number;\n maxBodyBytes: number;\n}\n\nfunction resolveDefaultAdminConsolePublicDir(): string {\n const thisDir = path.dirname(fileURLToPath(import.meta.url));\n const candidates = [\n // Standard: admin-console sibling to src/ (development layout)\n path.resolve(thisDir, \"../admin-console/public\"),\n // Bundled: admin-console inside dist/ alongside the bundle\n path.resolve(thisDir, \"./admin-console/public\"),\n // Package root: walk up from dist/ to the package root\n path.resolve(thisDir, \"../../admin-console/public\"),\n ];\n return candidates.find((candidate) => existsSync(candidate)) ?? candidates[0];\n}\n\nconst defaultAdminConsolePublicDir = resolveDefaultAdminConsolePublicDir();\nconst correlationIdStore = new AsyncLocalStorage<string>();\n\nconst WRITE_RATE_LIMIT_WINDOW_MS = 60_000;\nconst WRITE_RATE_LIMIT_MAX_REQUESTS = 30;\nconst TRUST_ZONE_RECORD_KINDS = [\"memory\", \"artifact\", \"state\", \"trajectory\", \"external\"] as const;\nconst TRUST_ZONE_SOURCE_CLASSES = [\"tool_output\", \"web_content\", \"subagent_trace\", \"system_memory\", \"user_input\", \"manual\"] as const;\n\nclass HttpError extends Error {\n readonly code: string;\n readonly details?: unknown;\n constructor(readonly status: number, message: string, code?: string, details?: unknown) {\n super(message);\n this.code = code ?? `http_${status}`;\n this.details = details;\n }\n}\n\nfunction hostToUrlAuthority(host: string): string {\n if (host.includes(\":\") && !host.startsWith(\"[\") && !host.endsWith(\"]\")) {\n return `[${host}]`;\n }\n return host;\n}\n\nfunction parseHttpServerPort(port: number | undefined): number {\n if (port === undefined) return 0;\n if (!Number.isInteger(port) || port < 0 || port > 65535) {\n throw new Error(\"access HTTP port must be an integer from 0 to 65535\");\n }\n return port;\n}\n\nfunction parseTrustZoneKindFilter(raw: string | null): TrustZoneRecordKind | undefined {\n if (raw === null) return undefined;\n if ((TRUST_ZONE_RECORD_KINDS as readonly string[]).includes(raw)) {\n return raw as TrustZoneRecordKind;\n }\n throw new HttpError(400, `kind must be one of ${TRUST_ZONE_RECORD_KINDS.join(\"|\")}`, \"invalid_kind_filter\");\n}\n\nfunction parseTrustZoneSourceClassFilter(raw: string | null): TrustZoneSourceClass | undefined {\n if (raw === null) return undefined;\n if ((TRUST_ZONE_SOURCE_CLASSES as readonly string[]).includes(raw)) {\n return raw as TrustZoneSourceClass;\n }\n throw new HttpError(400, `sourceClass must be one of ${TRUST_ZONE_SOURCE_CLASSES.join(\"|\")}`, \"invalid_source_class_filter\");\n}\n\nfunction parseTrustZoneFilter(raw: string | null): TrustZoneName | undefined {\n if (raw === null) return undefined;\n if (isTrustZoneName(raw)) {\n return raw;\n }\n throw new HttpError(400, \"zone must be one of quarantine|working|trusted\", \"invalid_zone_filter\");\n}\n\nfunction summarizeHttpRequest(req: IncomingMessage): string {\n const method = req.method ?? \"UNKNOWN\";\n try {\n const parsed = new URL(req.url ?? \"/\", \"http://localhost\");\n return `${method} ${parsed.pathname}`;\n } catch {\n return `${method} ${(req.url ?? \"/\").split(\"?\")[0]}`;\n }\n}\n\nfunction parseStrictIntegerQuery(\n raw: string | null,\n field: string,\n defaultValue: number,\n minValue: number,\n): number {\n if (raw === null) return defaultValue;\n if (!/^(?:0|[1-9]\\d*)$/.test(raw)) {\n throw new HttpError(400, `${field} must be an integer`, `invalid_${field}`);\n }\n const value = Number(raw);\n if (!Number.isInteger(value) || value < minValue) {\n throw new HttpError(400, `${field} must be an integer >= ${minValue}`, `invalid_${field}`);\n }\n return value;\n}\n\nfunction parseMemorySort(raw: string | null): \"updated_desc\" | \"updated_asc\" | \"created_desc\" | \"created_asc\" | undefined {\n if (raw === null) return undefined;\n if (\n raw === \"updated_desc\" ||\n raw === \"updated_asc\" ||\n raw === \"created_desc\" ||\n raw === \"created_asc\"\n ) {\n return raw;\n }\n throw new HttpError(400, \"sort must be one of updated_desc|updated_asc|created_desc|created_asc\", \"invalid_sort\");\n}\n\n/**\n * Decode a `:peerId` URL path segment, converting malformed percent-encoded\n * input (e.g., `%E0%A4%A`) into a 400 client error rather than letting\n * `URIError` bubble up as a 500 `internal_error`.\n */\nfunction decodePeerIdSegment(raw: string): string {\n try {\n return decodeURIComponent(raw);\n } catch {\n throw new EngramAccessInputError(\"peerId path segment is not valid percent-encoded input\");\n }\n}\n\nfunction codingContextFromProjectTag(projectTag: string): {\n projectId: string;\n branch: string | null;\n rootPath: string;\n defaultBranch: string | null;\n} {\n const projectId = projectTagProjectId(projectTag);\n return {\n projectId,\n branch: null,\n rootPath: projectId,\n defaultBranch: null,\n };\n}\n\nexport class EngramAccessHttpServer {\n private readonly service: EngramAccessService;\n private readonly host: string;\n private readonly requestedPort: number;\n private readonly authToken?: string;\n private readonly authTokens: string[];\n private readonly authTokensGetter?: () => string[];\n private readonly authenticatedPrincipal?: string;\n private readonly maxBodyBytes: number;\n private readonly adminConsoleEnabled: boolean;\n private readonly adminConsolePublicDir: string;\n private readonly trustPrincipalHeader: boolean;\n private readonly adapterRegistry: AdapterRegistry | null;\n private readonly writeRequestTimestamps: number[] = [];\n private readonly mcpServer: EngramMcpServer;\n private server: Server | null = null;\n private boundPort = 0;\n /** Active SSE response objects for /engram/v1/graph/events. */\n private readonly sseClients = new Set<ServerResponse>();\n /** Throttle batch: pending SSE event batches per client. */\n private readonly sseBatchTimers = new Map<ServerResponse, ReturnType<typeof setTimeout>>();\n private readonly ssePendingBatches = new Map<ServerResponse, GraphEvent[]>();\n /**\n * Per-client cleanup callbacks: clear heartbeat interval, flush timer,\n * unsubscribe from bus, and end the response. Stored here so `stop()`\n * can invoke them even when the client hasn't disconnected yet\n * (Cursor review thread `access-http.ts:232`).\n */\n private readonly sseCleanupFns = new Set<() => void>();\n\n constructor(options: EngramAccessHttpServerOptions) {\n this.service = options.service;\n this.host = options.host?.trim() || \"127.0.0.1\";\n this.requestedPort = parseHttpServerPort(options.port);\n this.authToken = options.authToken?.trim() || undefined;\n this.authTokens = (options.authTokens ?? []).map((t) => t.trim()).filter(Boolean);\n this.authTokensGetter = options.authTokensGetter;\n this.authenticatedPrincipal = options.principal?.trim() || undefined;\n this.maxBodyBytes = Number.isFinite(options.maxBodyBytes)\n ? Math.max(1, Math.floor(options.maxBodyBytes ?? 131072))\n : 131072;\n this.adminConsoleEnabled = options.adminConsoleEnabled !== false;\n this.adminConsolePublicDir = options.adminConsolePublicDir ?? defaultAdminConsolePublicDir;\n this.trustPrincipalHeader = options.trustPrincipalHeader === true;\n this.adapterRegistry = options.enableAdapters !== false\n ? (options.adapterRegistry ?? new AdapterRegistry())\n : null;\n this.mcpServer = new EngramMcpServer(this.service, {\n principal: options.principal,\n citationsEnabled: options.citationsEnabled,\n citationsAutoDetect: options.citationsAutoDetect,\n emitLegacyTools: options.emitLegacyTools,\n });\n }\n\n async start(): Promise<EngramAccessHttpServerStatus> {\n if (!this.authToken && this.authTokens.length === 0 && !this.authTokensGetter) {\n throw new Error(\"engram access HTTP requires authToken or authTokens\");\n }\n if (this.server) return this.status();\n\n const server = createServer((req, res) => {\n const correlationId = randomUUID();\n correlationIdStore.run(correlationId, () => {\n void this.handle(req, res, correlationId).catch((err) => {\n log.debug(`engram access HTTP request failed [${correlationId}]: ${err}`);\n if (err instanceof HttpError) {\n const payload: Record<string, unknown> = { error: err.message, code: err.code };\n if (err.details) payload.details = err.details;\n this.respondJson(res, err.status, payload);\n return;\n }\n if (err instanceof EngramAccessInputError) {\n this.respondJson(res, 400, { error: err.message, code: \"input_error\" });\n return;\n }\n if (res.headersSent) {\n res.destroy(err as Error);\n return;\n }\n log.error(\n `engram access HTTP internal error [${correlationId}] ${summarizeHttpRequest(req)}`,\n err,\n );\n this.respondJson(res, 500, { error: \"internal_error\", code: \"internal_error\" });\n });\n });\n });\n\n try {\n await new Promise<void>((resolve, reject) => {\n const onError = (err: Error) => {\n server.off(\"listening\", onListening);\n reject(err);\n };\n const onListening = () => {\n server.off(\"error\", onError);\n resolve();\n };\n server.once(\"error\", onError);\n server.once(\"listening\", onListening);\n server.listen(this.requestedPort, this.host);\n });\n } catch (err) {\n server.close();\n throw err;\n }\n\n this.server = server;\n const address = server.address();\n this.boundPort = typeof address === \"object\" && address ? address.port : this.requestedPort;\n return this.status();\n }\n\n async stop(): Promise<void> {\n if (!this.server) return;\n const server = this.server;\n this.server = null;\n this.boundPort = 0;\n // Invoke each SSE client's cleanup callback so heartbeat intervals,\n // batch timers, and graph-bus subscriptions are all released before the\n // HTTP server closes. Without this, long-running SSE connections leak\n // setInterval handles and EventEmitter listeners (Cursor review thread\n // `access-http.ts:232`).\n for (const cleanup of this.sseCleanupFns) {\n try { cleanup(); } catch { /* ignore */ }\n }\n this.sseCleanupFns.clear();\n // Belt-and-suspenders: clear any state not yet reached by cleanup fns.\n for (const [res, timer] of this.sseBatchTimers.entries()) {\n clearTimeout(timer);\n this.sseBatchTimers.delete(res);\n }\n this.ssePendingBatches.clear();\n for (const res of this.sseClients) {\n try { res.end(); } catch { /* ignore */ }\n }\n this.sseClients.clear();\n await new Promise<void>((resolve, reject) => {\n server.close((err) => (err ? reject(err) : resolve()));\n });\n }\n\n status(): EngramAccessHttpServerStatus {\n return {\n running: this.server !== null,\n host: this.host,\n port: this.boundPort,\n maxBodyBytes: this.maxBodyBytes,\n };\n }\n\n /**\n * Resolve the adapter identity for the incoming request.\n * Includes MCP clientInfo from the last initialize handshake if available.\n * Returns null if no adapter matches or adapters are disabled.\n */\n resolveAdapterIdentity(req: IncomingMessage): ResolvedIdentity | null {\n if (!this.adapterRegistry) return null;\n // Look up clientInfo for this specific MCP session to avoid cross-session leaks.\n // Non-MCP requests (no mcp-session-id header) get undefined clientInfo and\n // rely on HTTP headers for adapter matching.\n const sessionId = (() => {\n const raw = req.headers[\"mcp-session-id\"];\n return typeof raw === \"string\" ? raw.trim() : undefined;\n })();\n return this.adapterRegistry.resolve({\n headers: req.headers as Record<string, string | string[] | undefined>,\n clientInfo: this.mcpServer.getClientInfo(sessionId),\n });\n }\n\n /** Cache for per-request identity resolution (avoids double adapter resolution) */\n private identityCache = new WeakMap<IncomingMessage, { principal?: string; namespace?: string; sessionKey?: string }>();\n\n /** Resolve principal, namespace, and session key from request headers and adapter identity */\n private resolveRequestIdentity(req: IncomingMessage): { principal?: string; namespace?: string; sessionKey?: string } {\n const cached = this.identityCache.get(req);\n if (cached) return cached;\n let principal: string | undefined;\n let namespace: string | undefined;\n let sessionKey: string | undefined;\n\n // Explicit header override takes priority for principal\n if (this.trustPrincipalHeader) {\n const headerVal = req.headers[\"x-engram-principal\"];\n const raw = Array.isArray(headerVal) ? headerVal[0] : headerVal;\n if (typeof raw === \"string\") {\n const trimmed = raw.trim();\n if (trimmed.length > 0) {\n principal = trimmed;\n }\n }\n }\n\n if (!principal) {\n principal = this.authenticatedPrincipal;\n }\n\n // Try adapter-based identity resolution for namespace and, only when no\n // server principal is configured, an adapter-owned default principal.\n const adapterIdentity = this.resolveAdapterIdentity(req);\n if (adapterIdentity) {\n if (!principal) {\n principal = adapterIdentity.principal;\n }\n namespace = adapterIdentity.namespace;\n sessionKey = adapterIdentity.sessionKey;\n }\n\n const result = { principal, namespace, sessionKey };\n this.identityCache.set(req, result);\n return result;\n }\n\n private resolveRequestPrincipal(req: IncomingMessage): string | undefined {\n return this.resolveRequestIdentity(req).principal;\n }\n\n /** Resolve namespace: only use the explicit body value. Adapter-inferred namespace\n * is intentionally NOT used as a fallback for REST requests — omitting namespace\n * should default to the server's global namespace, not silently scope to an adapter. */\n private resolveNamespace(_req: IncomingMessage, bodyNamespace?: string): string | undefined {\n return bodyNamespace || undefined;\n }\n\n /**\n * Resolve the recall disclosure depth from the request (issue #677 PR\n * 2/4). Explicit body value wins; otherwise we accept a\n * `?disclosure=...` query parameter so curl/browser tooling can use the\n * three-tier surface without rewriting JSON. Invalid query values\n * throw `EngramAccessInputError` (CLAUDE.md rule 51 — no silent\n * fallback). An absent body field AND an absent query param yields\n * `undefined`, which the service maps to `DEFAULT_RECALL_DISCLOSURE`.\n */\n private resolveRecallDisclosure(\n bodyDisclosure: RecallDisclosure | undefined,\n parsed: URL,\n ): RecallDisclosure | undefined {\n if (bodyDisclosure !== undefined) {\n return bodyDisclosure;\n }\n const queryDisclosure = parsed.searchParams.get(\"disclosure\");\n if (queryDisclosure === null) {\n return undefined;\n }\n if (!isRecallDisclosure(queryDisclosure)) {\n throw new EngramAccessInputError(\n `disclosure must be one of: chunk, section, raw (got: ${queryDisclosure})`,\n );\n }\n return queryDisclosure;\n }\n\n private async handle(req: IncomingMessage, res: ServerResponse, correlationId: string): Promise<void> {\n const parsed = new URL(req.url ?? \"/\", `http://${hostToUrlAuthority(this.host)}`);\n const pathname = parsed.pathname;\n\n if (this.adminConsoleEnabled && await this.handleAdminConsole(req, res, pathname)) {\n return;\n }\n\n if (!this.isAuthorized(req, pathname)) {\n const body = JSON.stringify({ error: \"unauthorized\", code: \"unauthorized\" });\n res.writeHead(401, {\n \"content-type\": \"application/json; charset=utf-8\",\n \"www-authenticate\": \"Bearer\",\n \"x-request-id\": correlationId,\n });\n res.end(body);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/mcp\") {\n await this.handleMcpRequest(req, res);\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/health\") {\n this.respondJson(res, 200, await this.service.health());\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/adapters\") {\n const identity = this.resolveAdapterIdentity(req);\n this.respondJson(res, 200, {\n adaptersEnabled: this.adapterRegistry !== null,\n registered: this.adapterRegistry?.list() ?? [],\n resolved: identity,\n });\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/recall\") {\n const body = await this.readValidatedBody(req, \"recall\");\n // Preserve the distinction between `codingContext: null` (explicit\n // clear) and `codingContext` missing from the JSON payload\n // (untouched). The previous `?? undefined` collapsed both into\n // undefined, so callers lost the ability to clear the session's\n // attached context through the recall endpoint.\n const codingContext =\n \"codingContext\" in body ? body.codingContext : undefined;\n // Disclosure resolution (issue #677 PR 2/4): accept the value from\n // the validated body OR the `?disclosure=` query parameter, with\n // the body taking precedence so an explicit JSON payload is never\n // silently overridden by a stale URL. CLAUDE.md rule 51: invalid\n // query-param values throw, never fall back silently.\n const disclosure = this.resolveRecallDisclosure(body.disclosure, parsed);\n // Issue #680 — historical recall pin (`asOf`). Body field wins\n // over `?as_of=` query param. Empty query is rejected only when\n // the body didn't supply a valid pin (codex P2 + cursor Medium).\n const asOfQueryRaw = parsed.searchParams.get(\"as_of\");\n const bodyHasAsOf =\n typeof body.asOf === \"string\" && body.asOf.length > 0;\n if (\n !bodyHasAsOf &&\n asOfQueryRaw !== null &&\n asOfQueryRaw.length === 0\n ) {\n throw new EngramAccessInputError(\n \"as_of must be a non-empty timestamp (got empty value)\",\n );\n }\n const asOf =\n body.asOf ??\n (asOfQueryRaw !== null && asOfQueryRaw.length > 0\n ? asOfQueryRaw\n : undefined);\n // Tag filter (issue #689). Body presence wins over query params\n // — explicit `tags: []` in body clears the filter even with\n // stale `?tag=` URLs.\n const bodyHasTagsField =\n body !== null &&\n typeof body === \"object\" &&\n \"tags\" in (body as Record<string, unknown>);\n const bodyTagsValue = bodyHasTagsField\n ? (body as { tags?: unknown }).tags\n : undefined;\n const bodyTags = Array.isArray(bodyTagsValue)\n ? (bodyTagsValue as string[])\n : undefined;\n const queryTags = parsed.searchParams.getAll(\"tag\");\n const tags = bodyHasTagsField\n ? bodyTags\n : queryTags.length > 0\n ? queryTags\n : undefined;\n const bodyTagMatch = (body as { tagMatch?: unknown }).tagMatch;\n let tagMatch: \"any\" | \"all\" | undefined;\n if (bodyTagMatch !== undefined) {\n if (bodyTagMatch === \"any\" || bodyTagMatch === \"all\") {\n tagMatch = bodyTagMatch;\n }\n } else {\n const queryTagMatch = parsed.searchParams.get(\"tag_match\");\n if (queryTagMatch !== null) {\n if (queryTagMatch !== \"any\" && queryTagMatch !== \"all\") {\n throw new EngramAccessInputError(\n `tag_match must be one of: any, all (got: ${queryTagMatch})`,\n );\n }\n tagMatch = queryTagMatch;\n }\n }\n // Issue #681 — `?include_low_confidence=true|false` mirrors the CLI\n // `--include-low-confidence` flag. Body field wins so a JSON payload can\n // explicitly clear a stale query parameter.\n const bodyIncludeLowConfidence =\n (body as { includeLowConfidence?: unknown }).includeLowConfidence;\n const queryIncludeLowConfidence = parsed.searchParams.get(\"include_low_confidence\");\n if (\n bodyIncludeLowConfidence === undefined &&\n queryIncludeLowConfidence !== null &&\n queryIncludeLowConfidence !== \"true\" &&\n queryIncludeLowConfidence !== \"false\"\n ) {\n throw new EngramAccessInputError(\n `include_low_confidence must be one of: true, false (got: ${queryIncludeLowConfidence})`,\n );\n }\n const includeLowConfidence =\n bodyIncludeLowConfidence === true ||\n (bodyIncludeLowConfidence === undefined &&\n queryIncludeLowConfidence === \"true\");\n const response = await this.service.recall({\n query: body.query ?? \"\",\n sessionKey: body.sessionKey,\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n idempotencyKey: body.idempotencyKey,\n namespace: this.resolveNamespace(req, body.namespace),\n topK: body.topK,\n mode: body.mode as RecallPlanMode | \"auto\" | undefined,\n includeDebug: body.includeDebug === true,\n // Forward the validated disclosure depth to the service layer\n // (issue #677). The zod schema accepts/rejects body values;\n // `resolveRecallDisclosure()` validates the query-param fallback.\n disclosure,\n codingContext,\n // Forward cwd/projectTag for auto git-context resolution (issue #569).\n cwd: body.cwd,\n projectTag: body.projectTag,\n ...(asOf !== undefined ? { asOf } : {}),\n ...(tags !== undefined ? { tags } : {}),\n ...(tagMatch !== undefined ? { tagMatch } : {}),\n ...(includeLowConfidence ? { includeLowConfidence: true } : {}),\n });\n this.respondJson(res, 200, response);\n return;\n }\n\n // Attach / clear coding-agent context for a session (issue #569 PR 5).\n // Mirrors `setCodingContext` on the access service. Connectors call this\n // at session start after resolving a git context for the cwd; `remnic\n // doctor` (PR 8) surfaces the attached context.\n if (req.method === \"POST\" && pathname === \"/engram/v1/coding-context\") {\n const body = await this.readValidatedBody(req, \"setCodingContext\");\n const codingContext =\n body.codingContext !== undefined\n ? body.codingContext\n : typeof body.projectTag === \"string\"\n ? codingContextFromProjectTag(body.projectTag)\n : (() => {\n throw new EngramAccessInputError(\"codingContext or projectTag is required\");\n })();\n this.service.setCodingContext({\n sessionKey: body.sessionKey,\n codingContext,\n });\n this.respondJson(res, 200, { ok: true });\n return;\n }\n\n if (\n req.method === \"POST\" &&\n (pathname === \"/engram/v1/capsules/export\" || pathname === \"/remnic/v1/capsules/export\")\n ) {\n const body = await this.readValidatedBody(req, \"capsuleExport\");\n this.ensureWriteRateLimitAvailable();\n const result = await this.service.capsuleExport({\n name: body.name,\n namespace: this.resolveNamespace(req, body.namespace),\n principal: this.resolveRequestPrincipal(req),\n since: body.since,\n includeKinds: body.includeKinds,\n peerIds: body.peerIds,\n includeTranscripts: body.includeTranscripts,\n encrypt: body.encrypt,\n });\n this.recordWriteRateLimitHit();\n this.respondJson(res, 200, result);\n return;\n }\n\n if (\n req.method === \"POST\" &&\n (pathname === \"/engram/v1/capsules/import\" || pathname === \"/remnic/v1/capsules/import\")\n ) {\n const body = await this.readValidatedBody(req, \"capsuleImport\");\n this.ensureWriteRateLimitAvailable();\n const result = await this.service.capsuleImport({\n archivePath: expandTildePath(body.archivePath),\n namespace: this.resolveNamespace(req, body.namespace),\n principal: this.resolveRequestPrincipal(req),\n mode: body.mode,\n passphrase: body.passphrase,\n });\n this.recordWriteRateLimitHit();\n this.respondJson(res, 200, result);\n return;\n }\n\n if (\n req.method === \"GET\" &&\n (pathname === \"/engram/v1/offline-sync/snapshot\" || pathname === \"/remnic/v1/offline-sync/snapshot\")\n ) {\n const includeTranscriptsRaw = parsed.searchParams.get(\"include_transcripts\");\n const includeContentRaw = parsed.searchParams.get(\"content\");\n if (\n includeTranscriptsRaw !== null &&\n includeTranscriptsRaw !== \"true\" &&\n includeTranscriptsRaw !== \"false\"\n ) {\n throw new EngramAccessInputError(\n `include_transcripts must be one of: true, false (got: ${includeTranscriptsRaw})`,\n );\n }\n if (\n includeContentRaw !== null &&\n includeContentRaw !== \"true\" &&\n includeContentRaw !== \"false\"\n ) {\n throw new EngramAccessInputError(\n `content must be one of: true, false (got: ${includeContentRaw})`,\n );\n }\n const namespaceParam = parsed.searchParams.get(\"namespace\");\n const result = await this.service.offlineSyncSnapshot({\n namespace: this.resolveNamespace(\n req,\n namespaceParam && namespaceParam.length > 0 ? namespaceParam : undefined,\n ),\n principal: this.resolveRequestPrincipal(req),\n includeTranscripts: includeTranscriptsRaw !== \"false\",\n includeContent: includeContentRaw !== \"false\",\n });\n this.respondJson(res, 200, result);\n return;\n }\n\n if (\n req.method === \"GET\" &&\n (pathname === \"/engram/v1/offline-sync/snapshot-stream\" ||\n pathname === \"/remnic/v1/offline-sync/snapshot-stream\")\n ) {\n const includeTranscriptsRaw = parsed.searchParams.get(\"include_transcripts\");\n const includeContentRaw = parsed.searchParams.get(\"content\");\n if (\n includeTranscriptsRaw !== null &&\n includeTranscriptsRaw !== \"true\" &&\n includeTranscriptsRaw !== \"false\"\n ) {\n throw new EngramAccessInputError(\n `include_transcripts must be one of: true, false (got: ${includeTranscriptsRaw})`,\n );\n }\n if (\n includeContentRaw !== null &&\n includeContentRaw !== \"false\"\n ) {\n throw new EngramAccessInputError(\"snapshot-stream content must be false\");\n }\n const namespaceParam = parsed.searchParams.get(\"namespace\");\n const result = await this.service.offlineSyncSnapshotStream({\n namespace: this.resolveNamespace(\n req,\n namespaceParam && namespaceParam.length > 0 ? namespaceParam : undefined,\n ),\n principal: this.resolveRequestPrincipal(req),\n includeTranscripts: includeTranscriptsRaw !== \"false\",\n includeContent: false,\n signal: this.createRequestAbortSignal(req, res),\n });\n await this.respondOfflineSnapshotStream(res, result);\n return;\n }\n\n if (\n req.method === \"POST\" &&\n (pathname === \"/engram/v1/offline-sync/snapshot\" || pathname === \"/remnic/v1/offline-sync/snapshot\")\n ) {\n const body = await this.readValidatedBody(\n req,\n \"offlineSyncSnapshot\",\n OFFLINE_SYNC_SNAPSHOT_BASE_MAX_BODY_BYTES,\n );\n const result = await this.service.offlineSyncSnapshot({\n namespace: this.resolveNamespace(req, body.namespace),\n principal: this.resolveRequestPrincipal(req),\n includeTranscripts: body.includeTranscripts,\n includeContent: body.includeContent,\n baseFiles: body.baseFiles,\n ...(body.baseCapturedAt ? { baseCapturedAt: new Date(body.baseCapturedAt) } : {}),\n signal: this.createRequestAbortSignal(req, res),\n });\n this.respondJson(res, 200, result);\n return;\n }\n\n if (\n req.method === \"POST\" &&\n (pathname === \"/engram/v1/offline-sync/files\" || pathname === \"/remnic/v1/offline-sync/files\")\n ) {\n const body = await this.readValidatedBody(req, \"offlineSyncFiles\");\n const result = await this.service.offlineSyncFiles({\n namespace: this.resolveNamespace(req, body.namespace),\n principal: this.resolveRequestPrincipal(req),\n includeTranscripts: body.includeTranscripts,\n paths: body.paths,\n });\n this.respondJson(res, 200, result);\n return;\n }\n\n if (\n req.method === \"POST\" &&\n (\n pathname === \"/engram/v1/offline-sync/file-content\" ||\n pathname === \"/remnic/v1/offline-sync/file-content\"\n )\n ) {\n const body = await this.readValidatedBody(req, \"offlineSyncFileContent\");\n const result = await this.service.offlineSyncFileContent({\n namespace: this.resolveNamespace(req, body.namespace),\n principal: this.resolveRequestPrincipal(req),\n includeTranscripts: body.includeTranscripts,\n path: body.path,\n offset: body.offset,\n length: body.length,\n });\n this.respondBinary(res, 200, result.content, {\n \"x-remnic-namespace\": encodeURIComponent(result.namespace),\n \"x-remnic-file-path\": encodeURIComponent(result.path),\n \"x-remnic-file-bytes\": String(result.bytes),\n \"x-remnic-file-mtime-ms\": String(result.mtimeMs),\n \"x-remnic-chunk-offset\": String(result.offset),\n \"x-remnic-chunk-bytes\": String(result.chunkBytes),\n ...(result.sha256 ? { \"x-remnic-file-sha256\": result.sha256 } : {}),\n });\n return;\n }\n\n if (\n req.method === \"POST\" &&\n (\n pathname === \"/engram/v1/offline-sync/apply-file-content\" ||\n pathname === \"/remnic/v1/offline-sync/apply-file-content\"\n )\n ) {\n const namespaceParam = parsed.searchParams.get(\"namespace\");\n const bytes = this.readRequiredIntegerHeader(req, \"x-remnic-file-bytes\");\n const offset = this.readOptionalIntegerHeader(req, \"x-remnic-chunk-offset\") ?? 0;\n const content = await this.readBinaryBody(req, OFFLINE_SYNC_FILE_CONTENT_MAX_CHUNK_BYTES);\n const result = await this.service.offlineSyncApplyFileContent({\n namespace: this.resolveNamespace(\n req,\n namespaceParam && namespaceParam.length > 0 ? namespaceParam : undefined,\n ),\n principal: this.resolveRequestPrincipal(req),\n includeTranscripts: this.parseOptionalBooleanHeader(\n req,\n \"x-remnic-include-transcripts\",\n true,\n ),\n sourceId: this.readRequiredDecodedHeader(req, \"x-remnic-source-id\"),\n path: this.readRequiredDecodedHeader(req, \"x-remnic-file-path\"),\n sha256: this.readRequiredHeader(req, \"x-remnic-file-sha256\"),\n bytes,\n mtimeMs: this.readRequiredNumberHeader(req, \"x-remnic-file-mtime-ms\"),\n offset,\n baseSha256: this.readOptionalHeader(req, \"x-remnic-base-sha256\"),\n content,\n });\n this.respondJson(res, 200, result);\n return;\n }\n\n if (\n req.method === \"POST\" &&\n (pathname === \"/engram/v1/offline-sync/apply\" || pathname === \"/remnic/v1/offline-sync/apply\")\n ) {\n const body = await this.readValidatedBody(req, \"offlineSyncApply\", OFFLINE_SYNC_APPLY_MAX_BODY_BYTES);\n const result = await this.service.offlineSyncApply({\n namespace: this.resolveNamespace(req, body.namespace),\n principal: this.resolveRequestPrincipal(req),\n changeset: body.changeset,\n returnCurrentFiles: body.returnCurrentFiles,\n });\n this.respondJson(res, 200, result);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/recall/explain\") {\n const body = await this.readValidatedBody(req, \"recallExplain\");\n const response = await this.service.recallExplain({\n sessionKey: body.sessionKey,\n namespace: this.resolveNamespace(req, body.namespace),\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n });\n this.respondJson(res, 200, response);\n return;\n }\n\n if (\n req.method === \"POST\" &&\n (pathname === \"/engram/v1/action-confidence\" || pathname === \"/remnic/v1/action-confidence\")\n ) {\n const body = await this.readValidatedBody(req, \"actionConfidence\");\n this.respondJson(res, 200, await this.service.actionConfidence(body));\n return;\n }\n\n // Tier-explain (issue #518): structured per-result annotation from\n // the direct-answer retrieval tier. Orthogonal to /recall/explain\n // above, which returns a graph-path explanation document.\n if (req.method === \"GET\" && pathname === \"/engram/v1/recall/tier-explain\") {\n const sessionParam = parsed.searchParams.get(\"session\");\n const sessionKey = sessionParam && sessionParam.length > 0 ? sessionParam : undefined;\n const namespaceParam = parsed.searchParams.get(\"namespace\");\n const namespace = this.resolveNamespace(\n req,\n namespaceParam && namespaceParam.length > 0 ? namespaceParam : undefined,\n );\n const payload = await this.service.recallTierExplain(\n sessionKey,\n namespace,\n this.resolveRequestPrincipal(req),\n );\n this.respondJson(res, 200, payload);\n return;\n }\n\n // Recall X-ray (issue #570 PR 4): unified per-result attribution\n // snapshot. Requires bearer auth (same as every other endpoint\n // here) and enforces namespace scope before the recall fires\n // (CLAUDE.md rule 42). Query comes from the `q` search param so\n // GET stays cacheable; `namespace` / `session` / `budget` are\n // optional.\n if (req.method === \"GET\" && pathname === \"/engram/v1/recall/xray\") {\n const queryParam = parsed.searchParams.get(\"q\");\n if (!queryParam || queryParam.trim().length === 0) {\n this.respondJson(res, 400, {\n error: \"missing_query\",\n code: \"missing_query\",\n message: \"q search parameter is required and must be non-empty\",\n });\n return;\n }\n const sessionParam = parsed.searchParams.get(\"session\");\n const sessionKey = sessionParam && sessionParam.length > 0\n ? sessionParam\n : undefined;\n const namespaceParam = parsed.searchParams.get(\"namespace\");\n const namespace = this.resolveNamespace(\n req,\n namespaceParam && namespaceParam.length > 0\n ? namespaceParam\n : undefined,\n );\n const budgetParam = parsed.searchParams.get(\"budget\");\n // Reject invalid `budget` with 400 rather than silently\n // defaulting (CLAUDE.md rules 14 + 51).\n let budget: number | undefined;\n if (budgetParam !== null && budgetParam !== \"\") {\n const parsedBudget = Number(budgetParam);\n if (\n !Number.isFinite(parsedBudget)\n || parsedBudget <= 0\n || !Number.isInteger(parsedBudget)\n ) {\n this.respondJson(res, 400, {\n error: \"invalid_budget\",\n code: \"invalid_budget\",\n message:\n \"budget expects a positive integer\",\n });\n return;\n }\n budget = parsedBudget;\n }\n // Disclosure depth (issue #677 PR 3/4 telemetry plumbing). When\n // present, must match the chunk|section|raw allow-list; invalid\n // values surface as a 400 (CLAUDE.md rule 51 — no silent\n // fallback) rather than silently disabling the per-disclosure\n // summary table.\n const disclosureParam = parsed.searchParams.get(\"disclosure\");\n let disclosure: RecallDisclosure | undefined;\n if (disclosureParam !== null && disclosureParam.length > 0) {\n if (!isRecallDisclosure(disclosureParam)) {\n this.respondJson(res, 400, {\n error: \"invalid_disclosure\",\n code: \"invalid_disclosure\",\n message:\n \"disclosure must be one of: chunk, section, raw\",\n });\n return;\n }\n disclosure = disclosureParam;\n }\n // Only translate validation errors (empty query, bad budget)\n // into 400s. Backend faults (timeouts, storage errors,\n // unexpected orchestrator failures) must bubble to the global\n // `handle()` error handler so they return 500 and get logged\n // properly. `service.recallXray` prefixes its validation\n // errors with \"recallXray:\" so we key off that prefix rather\n // than catching everything.\n let payload: Awaited<ReturnType<typeof this.service.recallXray>>;\n try {\n payload = await this.service.recallXray({\n query: queryParam,\n sessionKey,\n namespace,\n budget,\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n ...(disclosure !== undefined ? { disclosure } : {}),\n });\n } catch (err) {\n // Only surface the message for the deliberately-prefixed recallXray\n // input-validation errors, and only when it is a real Error.message —\n // never String(err) of an arbitrary throw, which CodeQL flags as\n // stack-trace exposure (js/stack-trace-exposure). Validation errors are\n // always thrown as Error instances (see access-service.ts), so this is\n // behavior-preserving; anything else is a server-side fault and is\n // rethrown so the outer `handle()` catch returns 500 + logs it.\n if (err instanceof Error && err.message.startsWith(\"recallXray:\")) {\n this.respondJson(res, 400, {\n error: \"invalid_request\",\n code: \"invalid_request\",\n message: err.message,\n });\n return;\n }\n throw err;\n }\n this.respondJson(res, 200, payload);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/observe\") {\n const body = await this.readValidatedBody(req, \"observe\");\n this.ensureWriteRateLimitAvailable();\n const response = await this.service.observe({\n sessionKey: body.sessionKey,\n messages: body.messages.map((message) => ({\n role: message.role,\n content: message.content,\n sourceFormat: message.sourceFormat ?? undefined,\n rawContent: message.rawContent ?? undefined,\n parts: message.parts ?? undefined,\n })),\n namespace: this.resolveNamespace(req, body.namespace),\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n skipExtraction: body.skipExtraction === true,\n // Forward cwd/projectTag for auto git-context resolution (issue #569).\n cwd: body.cwd,\n projectTag: body.projectTag,\n });\n this.recordWriteRateLimitHit();\n this.respondJson(res, 202, response);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/lcm/search\") {\n const body = await this.readValidatedBody(req, \"lcmSearch\");\n const response = await this.service.lcmSearch({\n query: body.query,\n sessionKey: body.sessionKey,\n sessionPrefix: body.sessionPrefix,\n namespace: this.resolveNamespace(req, body.namespace),\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n limit: body.limit,\n });\n this.respondJson(res, 200, response);\n return;\n }\n\n if (\n req.method === \"POST\" &&\n (pathname === \"/engram/v1/lcm/compaction/flush\" || pathname === \"/remnic/v1/lcm/compaction/flush\")\n ) {\n const body = await this.readValidatedBody(req, \"lcmCompactionFlush\");\n this.ensureWriteRateLimitAvailable();\n const response = await this.service.lcmCompactionFlush({\n sessionKey: body.sessionKey,\n namespace: this.resolveNamespace(req, body.namespace),\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n });\n this.recordWriteRateLimitHit();\n this.respondJson(res, 200, response);\n return;\n }\n\n if (\n req.method === \"POST\" &&\n (pathname === \"/engram/v1/lcm/compaction/record\" || pathname === \"/remnic/v1/lcm/compaction/record\")\n ) {\n const body = await this.readValidatedBody(req, \"lcmCompactionRecord\");\n this.ensureWriteRateLimitAvailable();\n const response = await this.service.lcmCompactionRecord({\n sessionKey: body.sessionKey,\n namespace: this.resolveNamespace(req, body.namespace),\n tokensBefore: body.tokensBefore,\n tokensAfter: body.tokensAfter,\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n });\n this.recordWriteRateLimitHit();\n this.respondJson(res, 200, response);\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/lcm/status\") {\n this.respondJson(res, 200, await this.service.lcmStatus());\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/memories\") {\n const body = await this.readValidatedBody(req, \"memoryStore\");\n const request = {\n schemaVersion: body.schemaVersion,\n idempotencyKey: body.idempotencyKey,\n dryRun: body.dryRun === true,\n sessionKey: body.sessionKey,\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n content: body.content,\n category: body.category,\n confidence: body.confidence,\n namespace: this.resolveNamespace(req, body.namespace),\n tags: body.tags,\n entityRef: body.entityRef,\n ttl: body.ttl,\n sourceReason: body.sourceReason,\n cwd: body.cwd,\n projectTag: body.projectTag,\n };\n // Rate-limit enforcement is SOLELY authoritative inside memoryStore via\n // enforceWriteQuota: it runs atomically with the real idempotency-miss\n // determination (and the real resolved namespace), and is never invoked\n // for a replay. We deliberately do NOT pre-check here: the write namespace\n // is resolved from mutable session/git context, so a stale peek could\n // report \"miss\" for a request that is actually an idempotent replay in the\n // now-scoped namespace and hard-reject a safe replay with 429 (#1434 Codex\n // review). Letting the in-lock hook be the only hard gate avoids that.\n const response = await this.service.memoryStore(request, {\n enforceWriteQuota: () => this.ensureWriteRateLimitAvailable(),\n });\n if (this.shouldCountWriteRateLimit(response as { dryRun?: boolean; idempotencyReplay?: boolean })) {\n this.recordWriteRateLimitHit();\n }\n this.respondJson(res, this.writeResponseStatus(response), response);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/suggestions\") {\n const body = await this.readValidatedBody(req, \"suggestionSubmit\");\n const request = {\n schemaVersion: body.schemaVersion,\n idempotencyKey: body.idempotencyKey,\n dryRun: body.dryRun === true,\n sessionKey: body.sessionKey,\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n content: body.content,\n category: body.category,\n confidence: body.confidence,\n namespace: this.resolveNamespace(req, body.namespace),\n tags: body.tags,\n entityRef: body.entityRef,\n ttl: body.ttl,\n sourceReason: body.sourceReason,\n cwd: body.cwd,\n projectTag: body.projectTag,\n };\n // Quota enforcement is solely authoritative inside suggestionSubmit\n // (enforceWriteQuota), atomic with the real miss and never on a replay; no\n // HTTP pre-check, so a stale peek can't 429 a safe replay (#1434 Codex review).\n const response = await this.service.suggestionSubmit(request, {\n enforceWriteQuota: () => this.ensureWriteRateLimitAvailable(),\n });\n if (this.shouldCountWriteRateLimit(response as { dryRun?: boolean; idempotencyReplay?: boolean })) {\n this.recordWriteRateLimitHit();\n }\n this.respondJson(res, this.writeResponseStatus(response), response);\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/memories\") {\n const limit = parseStrictIntegerQuery(parsed.searchParams.get(\"limit\"), \"limit\", 50, 1);\n const offset = parseStrictIntegerQuery(parsed.searchParams.get(\"offset\"), \"offset\", 0, 0);\n const sort = parseMemorySort(parsed.searchParams.get(\"sort\"));\n const response = await this.service.memoryBrowse({\n query: parsed.searchParams.get(\"q\") ?? undefined,\n status: parsed.searchParams.get(\"status\") ?? undefined,\n category: parsed.searchParams.get(\"category\") ?? undefined,\n namespace: parsed.searchParams.get(\"namespace\") ?? undefined,\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n sort,\n limit,\n offset,\n });\n this.respondJson(res, 200, response);\n return;\n }\n\n const memoryMatch = pathname.match(/^\\/engram\\/v1\\/memories\\/([^/]+)$/);\n if (req.method === \"GET\" && memoryMatch) {\n const memoryId = decodeURIComponent(memoryMatch[1] ?? \"\");\n const namespace = parsed.searchParams.get(\"namespace\") ?? undefined;\n const response = await this.service.memoryGet(memoryId, namespace, this.resolveRequestPrincipal(req));\n this.respondJson(res, response.found ? 200 : 404, response);\n return;\n }\n\n const timelineMatch = pathname.match(/^\\/engram\\/v1\\/memories\\/([^/]+)\\/timeline$/);\n if (req.method === \"GET\" && timelineMatch) {\n const memoryId = decodeURIComponent(timelineMatch[1] ?? \"\");\n const namespace = parsed.searchParams.get(\"namespace\") ?? undefined;\n const limit = parseStrictIntegerQuery(parsed.searchParams.get(\"limit\"), \"limit\", 200, 1);\n const response = await this.service.memoryTimeline(memoryId, namespace, limit, this.resolveRequestPrincipal(req));\n this.respondJson(res, response.found ? 200 : 404, response);\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/entities\") {\n const limit = parseStrictIntegerQuery(parsed.searchParams.get(\"limit\"), \"limit\", 50, 1);\n const offset = parseStrictIntegerQuery(parsed.searchParams.get(\"offset\"), \"offset\", 0, 0);\n const response = await this.service.entityList({\n namespace: parsed.searchParams.get(\"namespace\") ?? undefined,\n query: parsed.searchParams.get(\"q\") ?? undefined,\n limit,\n offset,\n });\n this.respondJson(res, 200, response);\n return;\n }\n\n const entityMatch = pathname.match(/^\\/engram\\/v1\\/entities\\/([^/]+)$/);\n if (req.method === \"GET\" && entityMatch) {\n const entityName = decodeURIComponent(entityMatch[1] ?? \"\");\n const namespace = parsed.searchParams.get(\"namespace\") ?? undefined;\n const response = await this.service.entityGet(entityName, namespace);\n this.respondJson(res, response.found ? 200 : 404, response);\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/review-queue\") {\n const response = await this.service.reviewQueue(\n parsed.searchParams.get(\"runId\") ?? undefined,\n parsed.searchParams.get(\"namespace\") ?? undefined,\n this.resolveRequestPrincipal(req),\n );\n this.respondJson(res, 200, response);\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/maintenance\") {\n this.respondJson(res, 200, await this.service.maintenance(parsed.searchParams.get(\"namespace\") ?? undefined, this.resolveRequestPrincipal(req)));\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/quality\") {\n this.respondJson(res, 200, await this.service.quality(parsed.searchParams.get(\"namespace\") ?? undefined, this.resolveRequestPrincipal(req)));\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/trust-zones/status\") {\n this.respondJson(\n res,\n 200,\n await this.service.trustZoneStatus(parsed.searchParams.get(\"namespace\") ?? undefined, this.resolveRequestPrincipal(req)),\n );\n return;\n }\n\n // Procedural memory stats (issue #567 PR 5/5). Read-only; namespace is\n // scoped via the same resolver used by recall/trust-zones so cross-\n // tenant reads aren't possible (CLAUDE.md rule 42).\n if (req.method === \"GET\" && pathname === \"/engram/v1/procedural/stats\") {\n const namespaceParam = parsed.searchParams.get(\"namespace\");\n this.respondJson(\n res,\n 200,\n await this.service.procedureStats(\n {\n namespace: this.resolveNamespace(\n req,\n namespaceParam && namespaceParam.length > 0\n ? namespaceParam\n : undefined,\n ),\n },\n this.resolveRequestPrincipal(req),\n ),\n );\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/trust-zones/records\") {\n const limit = parseStrictIntegerQuery(parsed.searchParams.get(\"limit\"), \"limit\", 25, 1);\n const offset = parseStrictIntegerQuery(parsed.searchParams.get(\"offset\"), \"offset\", 0, 0);\n const response = await this.service.trustZoneBrowse({\n query: parsed.searchParams.get(\"q\") ?? undefined,\n zone: parseTrustZoneFilter(parsed.searchParams.get(\"zone\")),\n kind: parseTrustZoneKindFilter(parsed.searchParams.get(\"kind\")),\n sourceClass: parseTrustZoneSourceClassFilter(parsed.searchParams.get(\"sourceClass\")),\n namespace: parsed.searchParams.get(\"namespace\") ?? undefined,\n limit,\n offset,\n }, this.resolveRequestPrincipal(req));\n this.respondJson(res, 200, response);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/review-disposition\") {\n const body = await this.readValidatedBody(req, \"reviewDisposition\");\n this.ensureWriteRateLimitAvailable();\n const response = await this.service.reviewDisposition({\n memoryId: body.memoryId,\n status: body.status,\n reasonCode: body.reasonCode,\n namespace: this.resolveNamespace(req, body.namespace),\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n });\n if (this.shouldCountWriteRateLimit(response as unknown as { dryRun?: boolean; idempotencyReplay?: boolean })) {\n this.recordWriteRateLimitHit();\n }\n this.respondJson(res, 200, response);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/trust-zones/promote\") {\n const body = await this.readValidatedBody(req, \"trustZonePromote\");\n const dryRun = body.dryRun === true;\n if (!dryRun) {\n this.ensureWriteRateLimitAvailable();\n }\n const response = await this.service.trustZonePromote({\n recordId: body.recordId,\n targetZone: body.targetZone,\n promotionReason: body.promotionReason,\n recordedAt: body.recordedAt,\n summary: body.summary,\n dryRun,\n namespace: this.resolveNamespace(req, body.namespace),\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n });\n if (this.shouldCountWriteRateLimit(response as unknown as { dryRun?: boolean; idempotencyReplay?: boolean })) {\n this.recordWriteRateLimitHit();\n }\n this.respondJson(res, response.dryRun ? 200 : 201, response);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/trust-zones/demo-seed\") {\n const body = await this.readValidatedBody(req, \"trustZoneDemoSeed\");\n const dryRun = body.dryRun === true;\n if (!dryRun) {\n this.ensureWriteRateLimitAvailable();\n }\n const response = await this.service.trustZoneDemoSeed({\n scenario: body.scenario,\n recordedAt: body.recordedAt,\n dryRun,\n namespace: this.resolveNamespace(req, body.namespace),\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n });\n if (this.shouldCountWriteRateLimit(response as unknown as { dryRun?: boolean; idempotencyReplay?: boolean })) {\n this.recordWriteRateLimitHit();\n }\n this.respondJson(res, response.dryRun ? 200 : 201, response);\n return;\n }\n\n // Citation usage tracking (issue #379)\n if (req.method === \"POST\" && pathname === \"/v1/citations/observed\") {\n const body = await this.readJsonBody(req);\n if (!body || typeof body !== \"object\" || Array.isArray(body)) {\n throw new HttpError(400, \"request body must be a JSON object\", \"invalid_body\");\n }\n const payload = body as Record<string, unknown>;\n const sessionId = typeof payload.sessionId === \"string\" ? payload.sessionId : undefined;\n const namespace = typeof payload.namespace === \"string\" ? payload.namespace : undefined;\n const citationsRaw = payload.citations;\n if (!citationsRaw || typeof citationsRaw !== \"object\" || Array.isArray(citationsRaw)) {\n throw new HttpError(400, \"citations must be a JSON object with entries and rolloutIds\", \"invalid_citations\");\n }\n const citObj = citationsRaw as Record<string, unknown>;\n const entries: CitationEntry[] = [];\n if (Array.isArray(citObj.entries)) {\n for (const raw of citObj.entries) {\n if (raw && typeof raw === \"object\" && !Array.isArray(raw)) {\n const e = raw as Record<string, unknown>;\n if (\n typeof e.path === \"string\" &&\n typeof e.lineStart === \"number\" &&\n typeof e.lineEnd === \"number\"\n ) {\n entries.push({\n path: e.path,\n lineStart: e.lineStart,\n lineEnd: e.lineEnd,\n note: typeof e.note === \"string\" ? e.note : \"\",\n });\n }\n }\n }\n }\n const rolloutIds: string[] = [];\n if (Array.isArray(citObj.rolloutIds)) {\n for (const id of citObj.rolloutIds) {\n if (typeof id === \"string\" && id.length > 0) {\n rolloutIds.push(id);\n }\n }\n }\n\n // Record usage: for each citation entry, try to increment usage on the\n // matching memory. The service exposes recordAccess for this purpose.\n // Pass authenticatedPrincipal so namespace ACL checks use the same\n // identity resolution as other write endpoints (Finding #1, issue #379).\n let matched = 0;\n let submitted = 0;\n if (typeof this.service.recordCitationUsage === \"function\") {\n const result = await this.service.recordCitationUsage({\n sessionId,\n namespace: this.resolveNamespace(req, namespace),\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n entries,\n rolloutIds,\n });\n submitted = result.submitted;\n matched = result.matched;\n }\n\n this.respondJson(res, 200, {\n ok: true,\n submitted,\n matched,\n entriesReceived: entries.length,\n rolloutIdsReceived: rolloutIds.length,\n });\n return;\n }\n\n // ── Contradiction Review (issue #520) ─────────────────────────────────────\n if (req.method === \"GET\" && pathname === \"/engram/v1/review/contradictions\") {\n const VALID_FILTERS = new Set([\"all\", \"unresolved\", \"contradicts\", \"independent\", \"duplicates\", \"needs-user\"]);\n const rawFilter = parsed.searchParams.get(\"filter\") ?? \"unresolved\";\n if (!VALID_FILTERS.has(rawFilter)) {\n this.respondJson(res, 400, { error: `Invalid filter '${rawFilter}'. Valid: ${[...VALID_FILTERS].join(\", \")}` });\n return;\n }\n const namespace = parsed.searchParams.get(\"namespace\") ?? undefined;\n const limit = parseStrictIntegerQuery(parsed.searchParams.get(\"limit\"), \"limit\", 50, 1);\n const {\n isDefaultReviewNamespace,\n listPairs,\n } = await import(\"./contradiction/contradiction-review.js\");\n const principal = this.resolveRequestPrincipal(req);\n const resolved = await this.service.getReadableStorageForNamespace(namespace, principal);\n const reviewNamespace = this.service.configRef.namespacesEnabled ? resolved.namespace : undefined;\n const includeUnscopedForNamespace = Boolean(\n reviewNamespace && isDefaultReviewNamespace(this.service.configRef.defaultNamespace, namespace, reviewNamespace),\n );\n const result = listPairs(this.service.memoryDir, {\n filter: rawFilter as \"all\" | \"unresolved\" | \"contradicts\" | \"independent\" | \"duplicates\" | \"needs-user\",\n namespace: reviewNamespace,\n includeUnscopedForNamespace,\n limit,\n });\n this.respondJson(res, 200, result);\n return;\n }\n\n if (req.method === \"GET\" && pathname.startsWith(\"/engram/v1/review/contradictions/\")) {\n const pairId = pathname.split(\"/\").pop() ?? \"\";\n const { readPair } = await import(\"./contradiction/contradiction-review.js\");\n const pair = readPair(this.service.memoryDir, pairId);\n if (!pair) {\n this.respondJson(res, 404, { error: \"pair_not_found\" });\n return;\n }\n try {\n await this.service.getReadableStorageForNamespace(pair.namespace, this.resolveRequestPrincipal(req));\n } catch {\n this.respondJson(res, 404, { error: \"pair_not_found\" });\n return;\n }\n this.respondJson(res, 200, pair);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/review/resolve\") {\n const body = await this.readJsonBody(req) as Record<string, unknown>;\n const pairId = typeof body.pairId === \"string\" ? body.pairId : \"\";\n const verb = typeof body.verb === \"string\" ? body.verb : \"\";\n if (!pairId || !verb) {\n this.respondJson(res, 400, { error: \"pairId and verb are required\" });\n return;\n }\n const { isValidResolutionVerb, executeResolution } = await import(\"./contradiction/resolution.js\");\n if (!isValidResolutionVerb(verb)) {\n this.respondJson(res, 400, { error: `Invalid verb: ${verb}. Must be one of: keep-a, keep-b, merge, both-valid, needs-more-context` });\n return;\n }\n const principal = this.resolveRequestPrincipal(req);\n const result = await executeResolution(this.service.memoryDir, this.service.storageRef, pairId, verb, {\n mergedMemoryId: typeof body.mergedMemoryId === \"string\" ? body.mergedMemoryId : undefined,\n mergedContent: typeof body.mergedContent === \"string\" ? body.mergedContent : undefined,\n storageForNamespace: async (namespace) => {\n const resolved = await this.service.getWritableStorageForNamespace(namespace, principal);\n return resolved.storage;\n },\n });\n this.respondJson(res, 200, result);\n return;\n }\n\n // Graph snapshot (issue #691 PR 2/5) — read-only adjacency view used by\n // the admin-pane scaffold shipped in PR 1/5. All filters are query\n // params so the surface stays cacheable; invalid values yield 400 with\n // a descriptive body (CLAUDE.md rule 51 — never silently default).\n if (req.method === \"GET\" && pathname === \"/engram/v1/graph/snapshot\") {\n const limitRaw = parsed.searchParams.get(\"limit\");\n let limit: number | undefined;\n if (limitRaw !== null && limitRaw.length > 0) {\n const parsedLimit = Number(limitRaw);\n if (\n !Number.isFinite(parsedLimit)\n || !Number.isInteger(parsedLimit)\n || parsedLimit <= 0\n ) {\n this.respondJson(res, 400, {\n error: \"invalid_limit\",\n code: \"invalid_limit\",\n message: \"limit must be a positive integer\",\n });\n return;\n }\n limit = parsedLimit;\n }\n const sinceRaw = parsed.searchParams.get(\"since\");\n let since: string | undefined;\n if (sinceRaw !== null && sinceRaw.length > 0) {\n // Validate up-front so the access service can stay focused on the\n // pure snapshot logic (parser also runs there as a defense in\n // depth, but rejecting at the boundary preserves the\n // \"invalid_since\" error code instead of leaking a generic 500).\n if (!Number.isFinite(Date.parse(sinceRaw))) {\n this.respondJson(res, 400, {\n error: \"invalid_since\",\n code: \"invalid_since\",\n message: \"since must be a parseable ISO timestamp\",\n });\n return;\n }\n since = sinceRaw;\n }\n const focusNodeIdRaw = parsed.searchParams.get(\"focusNodeId\");\n const focusNodeId = focusNodeIdRaw && focusNodeIdRaw.length > 0\n ? focusNodeIdRaw\n : undefined;\n const categoriesRaw = parsed.searchParams.get(\"categories\");\n let categories: string[] | undefined;\n if (categoriesRaw !== null && categoriesRaw.length > 0) {\n categories = categoriesRaw\n .split(\",\")\n .map((value) => value.trim())\n .filter((value) => value.length > 0);\n if (categories.length === 0) {\n this.respondJson(res, 400, {\n error: \"invalid_categories\",\n code: \"invalid_categories\",\n message:\n \"categories must be a comma-separated list with at least one non-empty value\",\n });\n return;\n }\n }\n const namespaceParam = parsed.searchParams.get(\"namespace\");\n const namespace = this.resolveNamespace(\n req,\n namespaceParam && namespaceParam.length > 0 ? namespaceParam : undefined,\n );\n try {\n const snapshot = await this.service.graphSnapshot(\n {\n namespace,\n ...(limit !== undefined ? { limit } : {}),\n ...(since !== undefined ? { since } : {}),\n ...(focusNodeId !== undefined ? { focusNodeId } : {}),\n ...(categories !== undefined ? { categories } : {}),\n },\n this.resolveRequestPrincipal(req),\n );\n this.respondJson(res, 200, snapshot);\n } catch (err) {\n // As with recallXray above: surface only the deliberately-prefixed\n // graphSnapshot validation Error.message, never String(err) of an\n // arbitrary throw (CodeQL js/stack-trace-exposure). Validation errors are\n // always Error instances; anything else is rethrown as a 500.\n if (err instanceof Error && err.message.startsWith(\"graphSnapshot:\")) {\n this.respondJson(res, 400, {\n error: \"invalid_request\",\n code: \"invalid_request\",\n message: err.message,\n });\n return;\n }\n throw err;\n }\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/contradiction-scan\") {\n const body = await this.readJsonBody(req) as Record<string, unknown>;\n const { runContradictionScan } = await import(\"./contradiction/contradiction-scan.js\");\n const principal = this.resolveRequestPrincipal(req);\n const result = await runContradictionScan({\n storage: this.service.storageRef,\n config: this.service.configRef,\n memoryDir: this.service.memoryDir,\n embeddingLookupFactory: this.service.embeddingLookupFactoryRef,\n storageForNamespace: (namespace) =>\n this.service.getWritableStorageForNamespace(namespace, principal),\n localLlm: this.service.localLlmRef,\n fallbackLlm: this.service.fallbackLlmRef,\n namespace: typeof body.namespace === \"string\" ? body.namespace : undefined,\n });\n this.respondJson(res, 200, result);\n return;\n }\n\n // ── Graph mutation event stream (issue #691 PR 5/5) ──────────────────────\n //\n // GET /engram/v1/graph/events\n //\n // Server-Sent Events stream that emits graph mutation events in real time.\n // Event types: node-added, node-updated, edge-added, edge-updated, edge-removed.\n //\n // Auth: same Bearer token scheme as every other endpoint (checked above).\n //\n // The SSE handler subscribes to the in-process graph event bus for the\n // resolved memory dir. Events are batched within a 200 ms window so a\n // burst of writes (e.g. extraction of a large turn) doesn't overwhelm\n // the admin UI canvas with individual re-renders.\n //\n // The client receives a `data: <json>\\n\\n` line per batch. Each batch\n // payload is { events: GraphEvent[] }.\n //\n // The stream sends a heartbeat `data: {\"type\":\"heartbeat\"}\\n\\n` every\n // 25 s so load balancers and proxies don't time out idle connections.\n if (req.method === \"GET\" && pathname === \"/engram/v1/graph/events\") {\n await this.handleGraphEventsSSE(req, res);\n return;\n }\n\n // ── Peer Registry endpoints (issue #679) ─────────────────────────────────\n // GET /engram/v1/console/state — operator console engine-state snapshot (issue #688 PR 2/3).\n // Read-only; namespace-aware via resolveRequestPrincipal so cross-tenant\n // reads are not possible (CLAUDE.md rule 42).\n if (req.method === \"GET\" && pathname === \"/engram/v1/console/state\") {\n const namespace = parsed.searchParams.get(\"namespace\") ?? undefined;\n const snapshot = await this.service.consoleState(namespace, this.resolveRequestPrincipal(req));\n this.respondJson(res, 200, snapshot);\n return;\n }\n\n // GET /engram/v1/peers — list all peers\n // GET /engram/v1/peers/:id — get one peer\n // PUT /engram/v1/peers/:id — upsert (create/update)\n // DELETE /engram/v1/peers/:id — delete identity only (idempotent)\n // DELETE /engram/v1/peers/:id?forget=true — destructive full purge (issue #679 completion)\n // GET /engram/v1/peers/:id/profile — get peer profile\n if (req.method === \"GET\" && pathname === \"/engram/v1/peers\") {\n const result = await this.service.peerList();\n this.respondJson(res, 200, result);\n return;\n }\n\n const peerProfileMatch = /^\\/engram\\/v1\\/peers\\/([^/]+)\\/profile$/.exec(pathname);\n if (peerProfileMatch) {\n if (req.method !== \"GET\") {\n this.respondJson(res, 405, { error: \"method_not_allowed\", code: \"method_not_allowed\" });\n return;\n }\n const peerId = decodePeerIdSegment(peerProfileMatch[1] ?? \"\");\n const result = await this.service.peerProfileGet(peerId);\n if (!result.found) {\n this.respondJson(res, 404, { error: \"peer_profile_not_found\", code: \"peer_profile_not_found\" });\n return;\n }\n this.respondJson(res, 200, result);\n return;\n }\n\n const peerIdMatch = /^\\/engram\\/v1\\/peers\\/([^/]+)$/.exec(pathname);\n if (peerIdMatch) {\n const peerId = decodePeerIdSegment(peerIdMatch[1] ?? \"\");\n\n if (req.method === \"GET\") {\n const result = await this.service.peerGet(peerId);\n if (!result.found) {\n this.respondJson(res, 404, { error: \"peer_not_found\", code: \"peer_not_found\" });\n return;\n }\n this.respondJson(res, 200, result);\n return;\n }\n\n if (req.method === \"PUT\") {\n const body = await this.readJsonBody(req) as Record<string, unknown>;\n // Reject malformed types up front rather than silently dropping them\n // to undefined and letting peerSet fall back to defaults\n // (CLAUDE.md rule 51: no silent defaults on bad input).\n if (\"kind\" in body && body.kind !== undefined && typeof body.kind !== \"string\") {\n throw new EngramAccessInputError(\"kind must be a string when provided\");\n }\n if (\n \"displayName\" in body &&\n body.displayName !== undefined &&\n typeof body.displayName !== \"string\"\n ) {\n throw new EngramAccessInputError(\"displayName must be a string when provided\");\n }\n if (\"notes\" in body && body.notes !== undefined && typeof body.notes !== \"string\") {\n throw new EngramAccessInputError(\"notes must be a string when provided\");\n }\n const result = await this.service.peerSet({\n id: peerId,\n kind: typeof body.kind === \"string\" ? body.kind : undefined,\n displayName: typeof body.displayName === \"string\" ? body.displayName : undefined,\n notes: typeof body.notes === \"string\" ? body.notes : undefined,\n });\n this.respondJson(res, result.created ? 201 : 200, result);\n return;\n }\n\n if (req.method === \"DELETE\") {\n // `?forget=true` triggers the destructive full-purge path (issue #679\n // completion). The caller must also pass `confirm=yes` in the request\n // body; absent confirmation yields 400. Plain DELETE (no ?forget) keeps\n // the existing soft-delete behaviour (identity.md only).\n const forgetParam = parsed.searchParams.get(\"forget\");\n if (forgetParam === \"true\") {\n const body = await this.readJsonBody(req) as Record<string, unknown>;\n const confirm = typeof body.confirm === \"string\" ? body.confirm : \"\";\n if (confirm !== \"yes\") {\n this.respondJson(res, 400, {\n error: \"confirm_required\",\n code: \"confirm_required\",\n message: \"DELETE ?forget=true requires { confirm: 'yes' } in the request body\",\n });\n return;\n }\n const result = await this.service.peerForget(peerId, { confirm: \"yes\" });\n this.respondJson(res, 200, result);\n return;\n }\n const result = await this.service.peerDelete(peerId);\n this.respondJson(res, 200, result);\n return;\n }\n\n this.respondJson(res, 405, { error: \"method_not_allowed\", code: \"method_not_allowed\" });\n return;\n }\n\n // ── Dreams telemetry (issue #678 PR 3+4) ──────────────────────────────────\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/dreams/status\") {\n const { normalizeDreamsStatusWindowHours } = await import(\"./maintenance/dreams-ledger.js\");\n const windowHoursRaw = parsed.searchParams.get(\"windowHours\");\n let windowHours: number;\n try {\n windowHours = normalizeDreamsStatusWindowHours(\n windowHoursRaw !== null ? Number(windowHoursRaw) : undefined,\n );\n } catch {\n this.respondJson(res, 400, { error: \"windowHours must be a positive integer\" });\n return;\n }\n const namespaceParam = parsed.searchParams.get(\"namespace\");\n const namespace = namespaceParam && namespaceParam.length > 0 ? namespaceParam : undefined;\n const result = await this.service.dreamsStatus({\n windowHours,\n namespace,\n principal: this.resolveRequestPrincipal(req),\n });\n this.respondJson(res, 200, result);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/dreams/run\") {\n const body = await this.readJsonBody(req) as Record<string, unknown>;\n const VALID_PHASES = [\"lightSleep\", \"rem\", \"deepSleep\"] as const;\n const phase = typeof body.phase === \"string\" ? body.phase : undefined;\n if (!phase || !(VALID_PHASES as readonly string[]).includes(phase)) {\n this.respondJson(res, 400, {\n error: `phase is required and must be one of: ${VALID_PHASES.join(\", \")}`,\n });\n return;\n }\n if (\n \"dryRun\" in body &&\n body.dryRun !== undefined &&\n typeof body.dryRun !== \"boolean\"\n ) {\n this.respondJson(res, 400, {\n error: \"dryRun must be a boolean when provided\",\n });\n return;\n }\n if (\n \"namespace\" in body &&\n body.namespace !== undefined &&\n typeof body.namespace !== \"string\"\n ) {\n this.respondJson(res, 400, {\n error: \"namespace must be a string when provided\",\n });\n return;\n }\n const dryRun = body.dryRun === true;\n const namespace =\n typeof body.namespace === \"string\" ? body.namespace : undefined;\n if (!dryRun) {\n this.ensureWriteRateLimitAvailable();\n }\n const result = await this.service.dreamsRun({\n phase: phase as import(\"./types.js\").DreamsPhase,\n dryRun,\n namespace,\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n });\n if (this.shouldCountWriteRateLimit(result as { dryRun?: boolean; idempotencyReplay?: boolean })) {\n this.recordWriteRateLimitHit();\n }\n this.respondJson(res, 200, result);\n return;\n }\n\n this.respondJson(res, 404, { error: \"not_found\", code: \"not_found\" });\n }\n\n private createRequestAbortSignal(req: IncomingMessage, res: ServerResponse): AbortSignal {\n const controller = new AbortController();\n const abort = () => {\n if (!controller.signal.aborted) controller.abort();\n };\n req.once(\"aborted\", abort);\n res.once(\"close\", () => {\n if (!res.writableEnded) abort();\n });\n return controller.signal;\n }\n\n /**\n * SSE handler for /engram/v1/graph/events.\n *\n * Lifecycle:\n * 1. Write SSE headers (Content-Type: text/event-stream).\n * 2. Register this response in `sseClients`.\n * 3. Resolve the namespace from the request and subscribe to THAT\n * namespace's graph event bus (Codex P1: in multi-namespace\n * deployments each namespace has its own bus keyed by its storage\n * dir — subscribing to the global root leaks events across tenants).\n * 4. On each event, add to a 200 ms batch; flush batch as a single SSE frame.\n * 5. Send heartbeat every 25 s.\n * 6. On client disconnect (req \"close\"), clean up timers and unsubscribe.\n * 7. Register the cleanup callback in `sseCleanupFns` so `stop()` can\n * release the heartbeat interval and bus subscription even when the\n * client never disconnects (Cursor review thread `access-http.ts:232`).\n */\n private async handleGraphEventsSSE(req: IncomingMessage, res: ServerResponse): Promise<void> {\n // Resolve namespace from the ?namespace= query parameter (same pattern\n // as graphSnapshot and other read endpoints). Falls back to the\n // default namespace when absent.\n const parsed = new URL(req.url ?? \"/\", `http://${hostToUrlAuthority(this.host)}`);\n const namespaceParam = parsed.searchParams.get(\"namespace\");\n const namespace = namespaceParam && namespaceParam.length > 0 ? namespaceParam : undefined;\n // Resolve to the per-namespace storage directory so the bus subscription\n // is scoped to the correct tenant (CLAUDE.md rule 42).\n // Pass the request principal so namespace ACL is enforced — without it,\n // resolveReadableNamespace throws when namespacesEnabled=true (Cursor\n // thread PRRT_kwDORJXyws59snoR / Codex thread PRRT_kwDORJXyws59soGJ).\n const principal = this.resolveRequestPrincipal(req);\n const memoryDir = await this.service.getMemoryDirForNamespace(namespace, principal);\n\n res.writeHead(200, {\n \"content-type\": \"text/event-stream; charset=utf-8\",\n \"cache-control\": \"no-cache, no-store, must-revalidate\",\n \"connection\": \"keep-alive\",\n \"x-accel-buffering\": \"no\", // prevent nginx buffering\n \"transfer-encoding\": \"chunked\",\n });\n\n // Send initial \"connected\" frame so the client knows the stream is live.\n const writeSSE = (payload: unknown): void => {\n try {\n res.write(`data: ${JSON.stringify(payload)}\\n\\n`);\n } catch {\n // client already gone — cleanup will fire via \"close\"\n }\n };\n\n writeSSE({ type: \"connected\" });\n\n this.sseClients.add(res);\n\n // --- 200 ms batch throttle -----------------------------------------------\n const flushBatch = (): void => {\n const batch = this.ssePendingBatches.get(res);\n if (!batch || batch.length === 0) return;\n this.ssePendingBatches.delete(res);\n this.sseBatchTimers.delete(res);\n writeSSE({ type: \"batch\", events: batch });\n };\n\n const unsubscribe = subscribeGraphEvents(memoryDir, (event: GraphEvent) => {\n let batch = this.ssePendingBatches.get(res);\n if (!batch) {\n batch = [];\n this.ssePendingBatches.set(res, batch);\n }\n batch.push(event);\n if (!this.sseBatchTimers.has(res)) {\n this.sseBatchTimers.set(res, setTimeout(flushBatch, 200));\n }\n });\n\n // --- 25 s heartbeat -------------------------------------------------------\n const heartbeatInterval = setInterval(() => {\n writeSSE({ type: \"heartbeat\" });\n }, 25_000);\n\n // --- Cleanup on client disconnect -----------------------------------------\n const cleanup = (): void => {\n clearInterval(heartbeatInterval);\n const timer = this.sseBatchTimers.get(res);\n if (timer !== undefined) {\n clearTimeout(timer);\n this.sseBatchTimers.delete(res);\n }\n this.ssePendingBatches.delete(res);\n unsubscribe();\n this.sseClients.delete(res);\n this.sseCleanupFns.delete(cleanup);\n try { res.end(); } catch { /* ignore */ }\n };\n\n // Register so stop() can invoke cleanup even when the client is still\n // connected (releases the heartbeat interval and bus subscription\n // before the HTTP server is torn down).\n this.sseCleanupFns.add(cleanup);\n\n req.once(\"close\", cleanup);\n req.once(\"error\", cleanup);\n }\n\n private async handleMcpRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const body = await this.readJsonBody(req);\n const request = body as {\n jsonrpc?: string;\n id?: string | number | null;\n method?: string;\n params?: Record<string, unknown>;\n };\n\n // Enforce write rate limiting for MCP tool calls that mutate state,\n // matching the same protection applied to the REST write endpoints.\n // Pre-check ensures capacity; post-check skips counting dry runs and\n // idempotency replays, consistent with the REST handlers.\n const toolName = typeof request.params?.name === \"string\" ? request.params.name : \"\";\n const toolArgs = request.params?.arguments;\n const dreamsRunDryRun =\n (toolName === \"engram.dreams_run\" || toolName === \"remnic.dreams_run\") &&\n toolArgs !== null &&\n typeof toolArgs === \"object\" &&\n !Array.isArray(toolArgs) &&\n (toolArgs as { dryRun?: unknown }).dryRun === true;\n const memoryActionApplyDryRun =\n (toolName === \"engram.memory_action_apply\" || toolName === \"remnic.memory_action_apply\") &&\n toolArgs !== null &&\n typeof toolArgs === \"object\" &&\n !Array.isArray(toolArgs) &&\n (toolArgs as { dryRun?: unknown }).dryRun === true;\n const isMcpWrite =\n request.method === \"tools/call\" &&\n (\n toolName === \"engram.memory_store\" ||\n toolName === \"remnic.memory_store\" ||\n toolName === \"engram.suggestion_submit\" ||\n toolName === \"remnic.suggestion_submit\" ||\n toolName === \"engram.observe\" ||\n toolName === \"remnic.observe\" ||\n toolName === \"engram.lcm_compaction_flush\" ||\n toolName === \"remnic.lcm_compaction_flush\" ||\n toolName === \"engram.lcm_compaction_record\" ||\n toolName === \"remnic.lcm_compaction_record\" ||\n toolName === \"engram.capsule_export\" ||\n toolName === \"remnic.capsule_export\" ||\n toolName === \"engram.capsule_import\" ||\n toolName === \"remnic.capsule_import\" ||\n (\n !dreamsRunDryRun &&\n (toolName === \"engram.dreams_run\" || toolName === \"remnic.dreams_run\")\n ) ||\n (\n !memoryActionApplyDryRun &&\n (\n toolName === \"engram.memory_action_apply\" ||\n toolName === \"remnic.memory_action_apply\"\n )\n )\n );\n if (isMcpWrite) {\n this.ensureWriteRateLimitAvailable();\n }\n\n const sessionId = (() => {\n const raw = req.headers[\"mcp-session-id\"];\n return typeof raw === \"string\" ? raw.trim() : undefined;\n })();\n const mcpCorrelationId = correlationIdStore.getStore() ?? randomUUID();\n const requestIdentity = this.resolveRequestIdentity(req);\n const response = await this.mcpServer.handleRequest(request, {\n principalOverride: requestIdentity.principal,\n namespaceOverride: requestIdentity.namespace,\n sessionKeyOverride: requestIdentity.sessionKey,\n sessionId,\n correlationId: mcpCorrelationId,\n });\n\n if (isMcpWrite && response !== null) {\n const result = (response as Record<string, unknown>).result as Record<string, unknown> | undefined;\n const isError = result?.isError === true;\n const structured = result?.structuredContent as { dryRun?: boolean; idempotencyReplay?: boolean } | undefined;\n if (!isError && structured && this.shouldCountWriteRateLimit(structured)) {\n this.recordWriteRateLimitHit();\n }\n }\n if (response === null) {\n res.statusCode = 202;\n res.end();\n return;\n }\n // If this was an initialize response, pop the session ID keyed by\n // correlation ID (unique per HTTP request, not client-chosen JSON-RPC id).\n const assignedSessionId = this.mcpServer.popInitSessionId(mcpCorrelationId);\n if (assignedSessionId) {\n res.setHeader(\"mcp-session-id\", assignedSessionId);\n }\n this.respondJson(res, 200, response);\n }\n\n private respondJson(res: ServerResponse, status: number, payload: unknown): void {\n const body = JSON.stringify(payload, null, 2);\n res.statusCode = status;\n res.setHeader(\"content-type\", \"application/json; charset=utf-8\");\n res.setHeader(\"content-length\", String(Buffer.byteLength(body)));\n const cid = correlationIdStore.getStore();\n if (cid) {\n res.setHeader(\"x-request-id\", cid);\n }\n res.end(body);\n }\n\n private async respondOfflineSnapshotStream(\n res: ServerResponse,\n snapshot: Awaited<ReturnType<EngramAccessService[\"offlineSyncSnapshotStream\"]>>,\n ): Promise<void> {\n res.statusCode = 200;\n res.setHeader(\"content-type\", \"application/x-ndjson; charset=utf-8\");\n res.setHeader(\"cache-control\", \"no-store\");\n const cid = correlationIdStore.getStore();\n if (cid) {\n res.setHeader(\"x-request-id\", cid);\n }\n const waitForDrainOrClose = async (): Promise<boolean> => new Promise((resolve, reject) => {\n const cleanup = () => {\n res.off(\"drain\", onDrain);\n res.off(\"close\", onClose);\n res.off(\"error\", onError);\n };\n const onDrain = () => {\n cleanup();\n resolve(true);\n };\n const onClose = () => {\n cleanup();\n resolve(false);\n };\n const onError = (error: Error) => {\n cleanup();\n reject(error);\n };\n res.once(\"drain\", onDrain);\n res.once(\"close\", onClose);\n res.once(\"error\", onError);\n });\n const writeLine = async (payload: unknown): Promise<boolean> => {\n if (res.destroyed || res.writableEnded) return false;\n if (res.write(`${JSON.stringify(payload)}\\n`)) return true;\n if (res.destroyed || res.writableEnded) return false;\n return waitForDrainOrClose();\n };\n if (!await writeLine({\n type: \"snapshot\",\n namespace: snapshot.namespace,\n format: snapshot.format,\n schemaVersion: snapshot.schemaVersion,\n createdAt: snapshot.createdAt,\n sourceId: snapshot.sourceId,\n includeTranscripts: snapshot.includeTranscripts,\n })) return;\n for await (const file of snapshot.files) {\n if (!await writeLine({ type: \"file\", file })) return;\n }\n if (!res.destroyed && !res.writableEnded) {\n res.end();\n }\n }\n\n private respondBinary(\n res: ServerResponse,\n status: number,\n body: Buffer,\n headers: Record<string, string> = {},\n ): void {\n res.statusCode = status;\n res.setHeader(\"content-type\", \"application/octet-stream\");\n res.setHeader(\"content-length\", String(body.length));\n for (const [key, value] of Object.entries(headers)) {\n res.setHeader(key, value);\n }\n const cid = correlationIdStore.getStore();\n if (cid) {\n res.setHeader(\"x-request-id\", cid);\n }\n res.end(body);\n }\n\n private async handleAdminConsole(\n req: IncomingMessage,\n res: ServerResponse,\n pathname: string,\n ): Promise<boolean> {\n if (req.method !== \"GET\") return false;\n if (pathname === \"/remnic/ui\" || pathname === \"/engram/ui\") {\n res.statusCode = 301;\n res.setHeader(\"location\", pathname + \"/\");\n res.end();\n return true;\n }\n if (pathname === \"/remnic/ui/\" || pathname === \"/engram/ui/\") {\n await this.respondStatic(res, path.join(this.adminConsolePublicDir, \"index.html\"), \"text/html; charset=utf-8\");\n return true;\n }\n if (pathname === \"/remnic/ui/app.js\" || pathname === \"/engram/ui/app.js\") {\n await this.respondStatic(res, path.join(this.adminConsolePublicDir, \"app.js\"), \"application/javascript; charset=utf-8\");\n return true;\n }\n return false;\n }\n\n private async respondStatic(res: ServerResponse, filePath: string, contentType: string): Promise<void> {\n try {\n const body = await readFile(filePath, \"utf-8\");\n res.statusCode = 200;\n res.setHeader(\"content-type\", contentType);\n res.setHeader(\"content-length\", String(Buffer.byteLength(body)));\n res.end(body);\n } catch {\n this.respondJson(res, 404, { error: \"not_found\" });\n }\n }\n\n private async readJsonBody(\n req: IncomingMessage,\n maxBodyBytes = this.maxBodyBytes,\n ): Promise<Record<string, unknown>> {\n const encoding = (this.readOptionalHeader(req, \"content-encoding\") ?? \"identity\").toLowerCase();\n if (encoding !== \"identity\" && encoding !== \"gzip\") {\n throw new HttpError(415, \"unsupported_content_encoding\", \"unsupported_content_encoding\");\n }\n const chunks: Buffer[] = [];\n let total = 0;\n for await (const chunk of req) {\n const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n total += buffer.length;\n if (total > maxBodyBytes) {\n throw new HttpError(413, \"request_body_too_large\", \"request_body_too_large\");\n }\n chunks.push(buffer);\n }\n if (chunks.length === 0) return {};\n let body = Buffer.concat(chunks, total);\n if (encoding === \"gzip\") {\n try {\n body = gunzipSync(body, { maxOutputLength: maxBodyBytes });\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ERR_BUFFER_TOO_LARGE\") {\n throw new HttpError(413, \"request_body_too_large\", \"request_body_too_large\");\n }\n throw new HttpError(400, \"invalid_gzip_body\", \"invalid_gzip_body\");\n }\n if (body.byteLength > maxBodyBytes) {\n throw new HttpError(413, \"request_body_too_large\", \"request_body_too_large\");\n }\n }\n const raw = body.toString(\"utf-8\").trim();\n if (raw.length === 0) return {};\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw new HttpError(400, \"invalid_json\", \"invalid_json\");\n }\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new HttpError(400, \"invalid_json_object\", \"invalid_json_object\");\n }\n return parsed as Record<string, unknown>;\n }\n\n private async readBinaryBody(req: IncomingMessage, maxBytes: number): Promise<Buffer> {\n const chunks: Buffer[] = [];\n let total = 0;\n for await (const chunk of req) {\n const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n total += buffer.length;\n if (total > maxBytes) {\n throw new HttpError(413, \"request_body_too_large\", \"request_body_too_large\");\n }\n chunks.push(buffer);\n }\n return Buffer.concat(chunks, total);\n }\n\n private readRequiredHeader(req: IncomingMessage, name: string): string {\n const value = this.readOptionalHeader(req, name);\n if (value === undefined || value.length === 0) {\n throw new EngramAccessInputError(`${name} header is required`);\n }\n return value;\n }\n\n private readOptionalHeader(req: IncomingMessage, name: string): string | undefined {\n const raw = req.headers[name.toLowerCase()];\n if (Array.isArray(raw)) return raw[0]?.trim() || undefined;\n return raw?.trim() || undefined;\n }\n\n private readRequiredDecodedHeader(req: IncomingMessage, name: string): string {\n const raw = this.readRequiredHeader(req, name);\n try {\n return decodeURIComponent(raw);\n } catch {\n throw new EngramAccessInputError(`${name} header is not valid percent-encoded input`);\n }\n }\n\n private readRequiredIntegerHeader(req: IncomingMessage, name: string): number {\n const raw = this.readRequiredHeader(req, name);\n const parsed = Number(raw);\n if (!Number.isInteger(parsed) || parsed < 0) {\n throw new EngramAccessInputError(`${name} header must be a non-negative integer`);\n }\n return parsed;\n }\n\n private readOptionalIntegerHeader(req: IncomingMessage, name: string): number | undefined {\n const raw = this.readOptionalHeader(req, name);\n if (raw === undefined) return undefined;\n const parsed = Number(raw);\n if (!Number.isInteger(parsed) || parsed < 0) {\n throw new EngramAccessInputError(`${name} header must be a non-negative integer`);\n }\n return parsed;\n }\n\n private readRequiredNumberHeader(req: IncomingMessage, name: string): number {\n const raw = this.readRequiredHeader(req, name);\n const parsed = Number(raw);\n if (!Number.isFinite(parsed) || parsed < 0) {\n throw new EngramAccessInputError(`${name} header must be a non-negative finite number`);\n }\n return parsed;\n }\n\n private parseOptionalBooleanHeader(\n req: IncomingMessage,\n name: string,\n defaultValue: boolean,\n ): boolean {\n const raw = this.readOptionalHeader(req, name);\n if (raw === undefined) return defaultValue;\n if (raw === \"true\") return true;\n if (raw === \"false\") return false;\n throw new EngramAccessInputError(`${name} header must be one of: true, false`);\n }\n\n private async readValidatedBody<S extends SchemaName>(\n req: IncomingMessage,\n schemaName: S,\n maxBodyBytes?: number,\n ): Promise<SchemaTypeFor<S>> {\n const raw = await this.readJsonBody(req, maxBodyBytes);\n const result = validateRequest(schemaName, raw);\n if (!result.success) {\n throw new HttpError(400, result.error.error, \"validation_error\", result.error.details);\n }\n return result.data as SchemaTypeFor<S>;\n }\n\n private isAuthorized(req: IncomingMessage, pathname?: string): boolean {\n if (!this.authToken && this.authTokens.length === 0 && !this.authTokensGetter) return false;\n // Primary path: Authorization: Bearer <token> header.\n const raw = req.headers.authorization;\n let candidate: string | null = null;\n if (raw) {\n const separator = raw.indexOf(\" \");\n if (separator > 0) {\n const scheme = raw.slice(0, separator).toLowerCase();\n if (scheme === \"bearer\") {\n candidate = raw.slice(separator + 1).trim();\n }\n }\n }\n // Fallback: ?token= query parameter — ONLY accepted for the SSE\n // endpoint (/engram/v1/graph/events). EventSource cannot set request\n // headers, so SSE clients must pass the token via the query string.\n // Allowing this fallback on every endpoint would let a CSRF attacker\n // embed a credentialed URL anywhere — restricting it to SSE limits the\n // attack surface (Codex P2 review thread `access-http.ts:1406`; Cursor\n // review thread `access-http.ts:1412`). Authorization header always\n // wins; timing-safe compare used below.\n if (!candidate && pathname === \"/engram/v1/graph/events\") {\n try {\n const parsed = new URL(req.url ?? \"/\", `http://${hostToUrlAuthority(this.host)}`);\n const queryToken = parsed.searchParams.get(\"token\");\n if (queryToken && queryToken.length > 0) {\n candidate = queryToken;\n }\n } catch {\n // Malformed URL — don't authenticate\n }\n }\n if (!candidate) return false;\n const token = candidate;\n // Check primary token\n if (this.authToken && this.timingSafeStringEqual(token, this.authToken)) return true;\n // Check static multi-connector tokens\n for (const valid of this.authTokens) {\n if (this.timingSafeStringEqual(token, valid)) return true;\n }\n // Check dynamic tokens (reloaded per request for generate/revoke without restart)\n if (this.authTokensGetter) {\n for (const valid of this.authTokensGetter()) {\n if (this.timingSafeStringEqual(token, valid)) return true;\n }\n }\n return false;\n }\n\n private timingSafeStringEqual(a: string, b: string): boolean {\n const left = this.encodeSecret(a);\n const right = this.encodeSecret(b);\n if (!left || !right) return false;\n return timingSafeEqual(left, right);\n }\n\n private encodeSecret(value: string): Buffer | null {\n const encoded = Buffer.from(value, \"utf-8\");\n if (encoded.length > 1024) return null;\n const out = Buffer.alloc(2 + 1024);\n out.writeUInt16BE(encoded.length, 0);\n encoded.copy(out, 2);\n return out;\n }\n\n private writeResponseStatus(response: { dryRun: boolean; status: string }): number {\n if (response.dryRun === true) return 200;\n if (response.status === \"stored\" || response.status === \"queued_for_review\") return 201;\n return 200;\n }\n\n private ensureWriteRateLimitAvailable(): void {\n const now = Date.now();\n while (\n this.writeRequestTimestamps.length > 0 &&\n now - (this.writeRequestTimestamps[0] ?? 0) > WRITE_RATE_LIMIT_WINDOW_MS\n ) {\n this.writeRequestTimestamps.shift();\n }\n if (this.writeRequestTimestamps.length >= WRITE_RATE_LIMIT_MAX_REQUESTS) {\n throw new HttpError(429, \"write_rate_limited\", \"write_rate_limited\");\n }\n }\n\n private recordWriteRateLimitHit(): void {\n this.writeRequestTimestamps.push(Date.now());\n }\n\n private shouldCountWriteRateLimit(response: { dryRun?: boolean; idempotencyReplay?: boolean }): boolean {\n return response.dryRun !== true && response.idempotencyReplay !== true;\n }\n}\n"],"mappings":"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","names":["result"]}
package/dist/cli.js CHANGED
@@ -89,7 +89,7 @@ import {
89
89
  runWorkProductStatusCliCommand,
90
90
  runWorkProjectCliCommand,
91
91
  runWorkTaskCliCommand
92
- } from "./chunk-C4PZTWTG.js";
92
+ } from "./chunk-7TPH6UZL.js";
93
93
  import "./chunk-MC4FJXPA.js";
94
94
  import "./chunk-LQHDIS7L.js";
95
95
  import "./chunk-7F7Z6MOS.js";
@@ -183,7 +183,7 @@ import "./chunk-LBJBNWS2.js";
183
183
  import "./chunk-HQ6NIBL6.js";
184
184
  import "./chunk-PVGDJXVK.js";
185
185
  import "./chunk-OADWQ5CR.js";
186
- import "./chunk-ZJSZNTEI.js";
186
+ import "./chunk-FG76RDVI.js";
187
187
  import "./chunk-SEDEKFYQ.js";
188
188
  import "./chunk-2QSZNTDO.js";
189
189
  import "./chunk-RSUYKGGZ.js";
package/dist/index.js CHANGED
@@ -93,7 +93,7 @@ import {
93
93
  listTrainingExportAdapters,
94
94
  registerTrainingExportAdapter,
95
95
  runBulkImportCliCommand
96
- } from "./chunk-C4PZTWTG.js";
96
+ } from "./chunk-7TPH6UZL.js";
97
97
  import "./chunk-MC4FJXPA.js";
98
98
  import "./chunk-LQHDIS7L.js";
99
99
  import "./chunk-7F7Z6MOS.js";
@@ -478,7 +478,7 @@ import "./chunk-PVGDJXVK.js";
478
478
  import "./chunk-OADWQ5CR.js";
479
479
  import {
480
480
  EngramAccessHttpServer
481
- } from "./chunk-ZJSZNTEI.js";
481
+ } from "./chunk-FG76RDVI.js";
482
482
  import "./chunk-SEDEKFYQ.js";
483
483
  import "./chunk-2QSZNTDO.js";
484
484
  import "./chunk-RSUYKGGZ.js";
package/dist/schemas.d.ts CHANGED
@@ -275,12 +275,12 @@ declare const EntityMentionSchema: z.ZodObject<{
275
275
  title: z.ZodString;
276
276
  facts: z.ZodArray<z.ZodString, "many">;
277
277
  }, "strip", z.ZodTypeAny, {
278
- key: string;
279
278
  title: string;
279
+ key: string;
280
280
  facts: string[];
281
281
  }, {
282
- key: string;
283
282
  title: string;
283
+ key: string;
284
284
  facts: string[];
285
285
  }>, "many">>>;
286
286
  }, "strip", z.ZodTypeAny, {
@@ -288,8 +288,8 @@ declare const EntityMentionSchema: z.ZodObject<{
288
288
  name: string;
289
289
  facts: string[];
290
290
  structuredSections?: {
291
- key: string;
292
291
  title: string;
292
+ key: string;
293
293
  facts: string[];
294
294
  }[] | null | undefined;
295
295
  promptedByQuestion?: string | null | undefined;
@@ -298,8 +298,8 @@ declare const EntityMentionSchema: z.ZodObject<{
298
298
  name: string;
299
299
  facts: string[];
300
300
  structuredSections?: {
301
- key: string;
302
301
  title: string;
302
+ key: string;
303
303
  facts: string[];
304
304
  }[] | null | undefined;
305
305
  promptedByQuestion?: string | null | undefined;
@@ -584,12 +584,12 @@ declare const ProactiveExtractionResultSchema: z.ZodObject<{
584
584
  title: z.ZodString;
585
585
  facts: z.ZodArray<z.ZodString, "many">;
586
586
  }, "strip", z.ZodTypeAny, {
587
- key: string;
588
587
  title: string;
588
+ key: string;
589
589
  facts: string[];
590
590
  }, {
591
- key: string;
592
591
  title: string;
592
+ key: string;
593
593
  facts: string[];
594
594
  }>, "many">>>;
595
595
  }, "strip", z.ZodTypeAny, {
@@ -597,8 +597,8 @@ declare const ProactiveExtractionResultSchema: z.ZodObject<{
597
597
  name: string;
598
598
  facts: string[];
599
599
  structuredSections?: {
600
- key: string;
601
600
  title: string;
601
+ key: string;
602
602
  facts: string[];
603
603
  }[] | null | undefined;
604
604
  promptedByQuestion?: string | null | undefined;
@@ -607,8 +607,8 @@ declare const ProactiveExtractionResultSchema: z.ZodObject<{
607
607
  name: string;
608
608
  facts: string[];
609
609
  structuredSections?: {
610
- key: string;
611
610
  title: string;
611
+ key: string;
612
612
  facts: string[];
613
613
  }[] | null | undefined;
614
614
  promptedByQuestion?: string | null | undefined;
@@ -665,8 +665,8 @@ declare const ProactiveExtractionResultSchema: z.ZodObject<{
665
665
  name: string;
666
666
  facts: string[];
667
667
  structuredSections?: {
668
- key: string;
669
668
  title: string;
669
+ key: string;
670
670
  facts: string[];
671
671
  }[] | null | undefined;
672
672
  promptedByQuestion?: string | null | undefined;
@@ -714,8 +714,8 @@ declare const ProactiveExtractionResultSchema: z.ZodObject<{
714
714
  name: string;
715
715
  facts: string[];
716
716
  structuredSections?: {
717
- key: string;
718
717
  title: string;
718
+ key: string;
719
719
  facts: string[];
720
720
  }[] | null | undefined;
721
721
  promptedByQuestion?: string | null | undefined;
@@ -952,12 +952,12 @@ declare const ExtractionResultSchema: z.ZodObject<{
952
952
  title: z.ZodString;
953
953
  facts: z.ZodArray<z.ZodString, "many">;
954
954
  }, "strip", z.ZodTypeAny, {
955
- key: string;
956
955
  title: string;
956
+ key: string;
957
957
  facts: string[];
958
958
  }, {
959
- key: string;
960
959
  title: string;
960
+ key: string;
961
961
  facts: string[];
962
962
  }>, "many">>>;
963
963
  }, "strip", z.ZodTypeAny, {
@@ -965,8 +965,8 @@ declare const ExtractionResultSchema: z.ZodObject<{
965
965
  name: string;
966
966
  facts: string[];
967
967
  structuredSections?: {
968
- key: string;
969
968
  title: string;
969
+ key: string;
970
970
  facts: string[];
971
971
  }[] | null | undefined;
972
972
  promptedByQuestion?: string | null | undefined;
@@ -975,8 +975,8 @@ declare const ExtractionResultSchema: z.ZodObject<{
975
975
  name: string;
976
976
  facts: string[];
977
977
  structuredSections?: {
978
- key: string;
979
978
  title: string;
979
+ key: string;
980
980
  facts: string[];
981
981
  }[] | null | undefined;
982
982
  promptedByQuestion?: string | null | undefined;
@@ -1047,8 +1047,8 @@ declare const ExtractionResultSchema: z.ZodObject<{
1047
1047
  name: string;
1048
1048
  facts: string[];
1049
1049
  structuredSections?: {
1050
- key: string;
1051
1050
  title: string;
1051
+ key: string;
1052
1052
  facts: string[];
1053
1053
  }[] | null | undefined;
1054
1054
  promptedByQuestion?: string | null | undefined;
@@ -1102,8 +1102,8 @@ declare const ExtractionResultSchema: z.ZodObject<{
1102
1102
  name: string;
1103
1103
  facts: string[];
1104
1104
  structuredSections?: {
1105
- key: string;
1106
1105
  title: string;
1106
+ key: string;
1107
1107
  facts: string[];
1108
1108
  }[] | null | undefined;
1109
1109
  promptedByQuestion?: string | null | undefined;
@@ -1172,12 +1172,12 @@ declare const ConsolidationResultSchema: z.ZodObject<{
1172
1172
  title: z.ZodString;
1173
1173
  facts: z.ZodArray<z.ZodString, "many">;
1174
1174
  }, "strip", z.ZodTypeAny, {
1175
- key: string;
1176
1175
  title: string;
1176
+ key: string;
1177
1177
  facts: string[];
1178
1178
  }, {
1179
- key: string;
1180
1179
  title: string;
1180
+ key: string;
1181
1181
  facts: string[];
1182
1182
  }>, "many">>>;
1183
1183
  }, "strip", z.ZodTypeAny, {
@@ -1185,8 +1185,8 @@ declare const ConsolidationResultSchema: z.ZodObject<{
1185
1185
  name: string;
1186
1186
  facts: string[];
1187
1187
  structuredSections?: {
1188
- key: string;
1189
1188
  title: string;
1189
+ key: string;
1190
1190
  facts: string[];
1191
1191
  }[] | null | undefined;
1192
1192
  promptedByQuestion?: string | null | undefined;
@@ -1195,8 +1195,8 @@ declare const ConsolidationResultSchema: z.ZodObject<{
1195
1195
  name: string;
1196
1196
  facts: string[];
1197
1197
  structuredSections?: {
1198
- key: string;
1199
1198
  title: string;
1199
+ key: string;
1200
1200
  facts: string[];
1201
1201
  }[] | null | undefined;
1202
1202
  promptedByQuestion?: string | null | undefined;
@@ -1215,8 +1215,8 @@ declare const ConsolidationResultSchema: z.ZodObject<{
1215
1215
  name: string;
1216
1216
  facts: string[];
1217
1217
  structuredSections?: {
1218
- key: string;
1219
1218
  title: string;
1219
+ key: string;
1220
1220
  facts: string[];
1221
1221
  }[] | null | undefined;
1222
1222
  promptedByQuestion?: string | null | undefined;
@@ -1235,8 +1235,8 @@ declare const ConsolidationResultSchema: z.ZodObject<{
1235
1235
  name: string;
1236
1236
  facts: string[];
1237
1237
  structuredSections?: {
1238
- key: string;
1239
1238
  title: string;
1239
+ key: string;
1240
1240
  facts: string[];
1241
1241
  }[] | null | undefined;
1242
1242
  promptedByQuestion?: string | null | undefined;
@@ -313,13 +313,13 @@ declare const CapsuleBlockSchema: z.ZodObject<{
313
313
  peerProfiles: boolean;
314
314
  }>;
315
315
  }, "strip", z.ZodTypeAny, {
316
+ schemaVersion: string;
316
317
  includes: {
317
318
  procedural: boolean;
318
319
  taxonomy: boolean;
319
320
  identityAnchors: boolean;
320
321
  peerProfiles: boolean;
321
322
  };
322
- schemaVersion: string;
323
323
  id: string;
324
324
  description: string;
325
325
  version: string;
@@ -334,13 +334,13 @@ declare const CapsuleBlockSchema: z.ZodObject<{
334
334
  directAnswerEnabled: boolean;
335
335
  };
336
336
  }, {
337
+ schemaVersion: string;
337
338
  includes: {
338
339
  procedural: boolean;
339
340
  taxonomy: boolean;
340
341
  identityAnchors: boolean;
341
342
  peerProfiles: boolean;
342
343
  };
343
- schemaVersion: string;
344
344
  id: string;
345
345
  description: string;
346
346
  version: string;
@@ -464,13 +464,13 @@ declare const ExportManifestV2Schema: z.ZodObject<{
464
464
  peerProfiles: boolean;
465
465
  }>;
466
466
  }, "strip", z.ZodTypeAny, {
467
+ schemaVersion: string;
467
468
  includes: {
468
469
  procedural: boolean;
469
470
  taxonomy: boolean;
470
471
  identityAnchors: boolean;
471
472
  peerProfiles: boolean;
472
473
  };
473
- schemaVersion: string;
474
474
  id: string;
475
475
  description: string;
476
476
  version: string;
@@ -485,13 +485,13 @@ declare const ExportManifestV2Schema: z.ZodObject<{
485
485
  directAnswerEnabled: boolean;
486
486
  };
487
487
  }, {
488
+ schemaVersion: string;
488
489
  includes: {
489
490
  procedural: boolean;
490
491
  taxonomy: boolean;
491
492
  identityAnchors: boolean;
492
493
  peerProfiles: boolean;
493
494
  };
494
- schemaVersion: string;
495
495
  id: string;
496
496
  description: string;
497
497
  version: string;
@@ -518,13 +518,13 @@ declare const ExportManifestV2Schema: z.ZodObject<{
518
518
  pluginVersion: string;
519
519
  includesTranscripts: boolean;
520
520
  capsule: {
521
+ schemaVersion: string;
521
522
  includes: {
522
523
  procedural: boolean;
523
524
  taxonomy: boolean;
524
525
  identityAnchors: boolean;
525
526
  peerProfiles: boolean;
526
527
  };
527
- schemaVersion: string;
528
528
  id: string;
529
529
  description: string;
530
530
  version: string;
@@ -551,13 +551,13 @@ declare const ExportManifestV2Schema: z.ZodObject<{
551
551
  pluginVersion: string;
552
552
  includesTranscripts: boolean;
553
553
  capsule: {
554
+ schemaVersion: string;
554
555
  includes: {
555
556
  procedural: boolean;
556
557
  taxonomy: boolean;
557
558
  identityAnchors: boolean;
558
559
  peerProfiles: boolean;
559
560
  };
560
- schemaVersion: string;
561
561
  id: string;
562
562
  description: string;
563
563
  version: string;
@@ -683,13 +683,13 @@ declare const ExportBundleV2Schema: z.ZodObject<{
683
683
  peerProfiles: boolean;
684
684
  }>;
685
685
  }, "strip", z.ZodTypeAny, {
686
+ schemaVersion: string;
686
687
  includes: {
687
688
  procedural: boolean;
688
689
  taxonomy: boolean;
689
690
  identityAnchors: boolean;
690
691
  peerProfiles: boolean;
691
692
  };
692
- schemaVersion: string;
693
693
  id: string;
694
694
  description: string;
695
695
  version: string;
@@ -704,13 +704,13 @@ declare const ExportBundleV2Schema: z.ZodObject<{
704
704
  directAnswerEnabled: boolean;
705
705
  };
706
706
  }, {
707
+ schemaVersion: string;
707
708
  includes: {
708
709
  procedural: boolean;
709
710
  taxonomy: boolean;
710
711
  identityAnchors: boolean;
711
712
  peerProfiles: boolean;
712
713
  };
713
- schemaVersion: string;
714
714
  id: string;
715
715
  description: string;
716
716
  version: string;
@@ -737,13 +737,13 @@ declare const ExportBundleV2Schema: z.ZodObject<{
737
737
  pluginVersion: string;
738
738
  includesTranscripts: boolean;
739
739
  capsule: {
740
+ schemaVersion: string;
740
741
  includes: {
741
742
  procedural: boolean;
742
743
  taxonomy: boolean;
743
744
  identityAnchors: boolean;
744
745
  peerProfiles: boolean;
745
746
  };
746
- schemaVersion: string;
747
747
  id: string;
748
748
  description: string;
749
749
  version: string;
@@ -770,13 +770,13 @@ declare const ExportBundleV2Schema: z.ZodObject<{
770
770
  pluginVersion: string;
771
771
  includesTranscripts: boolean;
772
772
  capsule: {
773
+ schemaVersion: string;
773
774
  includes: {
774
775
  procedural: boolean;
775
776
  taxonomy: boolean;
776
777
  identityAnchors: boolean;
777
778
  peerProfiles: boolean;
778
779
  };
779
- schemaVersion: string;
780
780
  id: string;
781
781
  description: string;
782
782
  version: string;
@@ -815,13 +815,13 @@ declare const ExportBundleV2Schema: z.ZodObject<{
815
815
  pluginVersion: string;
816
816
  includesTranscripts: boolean;
817
817
  capsule: {
818
+ schemaVersion: string;
818
819
  includes: {
819
820
  procedural: boolean;
820
821
  taxonomy: boolean;
821
822
  identityAnchors: boolean;
822
823
  peerProfiles: boolean;
823
824
  };
824
- schemaVersion: string;
825
825
  id: string;
826
826
  description: string;
827
827
  version: string;
@@ -854,13 +854,13 @@ declare const ExportBundleV2Schema: z.ZodObject<{
854
854
  pluginVersion: string;
855
855
  includesTranscripts: boolean;
856
856
  capsule: {
857
+ schemaVersion: string;
857
858
  includes: {
858
859
  procedural: boolean;
859
860
  taxonomy: boolean;
860
861
  identityAnchors: boolean;
861
862
  peerProfiles: boolean;
862
863
  };
863
- schemaVersion: string;
864
864
  id: string;
865
865
  description: string;
866
866
  version: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remnic/core",
3
- "version": "9.3.623",
3
+ "version": "9.3.624",
4
4
  "description": "Framework-agnostic Remnic memory engine — orchestrator, storage, extraction, search, trust zones",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -984,17 +984,21 @@ export class EngramAccessHttpServer {
984
984
  ...(disclosure !== undefined ? { disclosure } : {}),
985
985
  });
986
986
  } catch (err) {
987
- const message = err instanceof Error ? err.message : String(err);
988
- if (message.startsWith("recallXray:")) {
987
+ // Only surface the message for the deliberately-prefixed recallXray
988
+ // input-validation errors, and only when it is a real Error.message
989
+ // never String(err) of an arbitrary throw, which CodeQL flags as
990
+ // stack-trace exposure (js/stack-trace-exposure). Validation errors are
991
+ // always thrown as Error instances (see access-service.ts), so this is
992
+ // behavior-preserving; anything else is a server-side fault and is
993
+ // rethrown so the outer `handle()` catch returns 500 + logs it.
994
+ if (err instanceof Error && err.message.startsWith("recallXray:")) {
989
995
  this.respondJson(res, 400, {
990
996
  error: "invalid_request",
991
997
  code: "invalid_request",
992
- message,
998
+ message: err.message,
993
999
  });
994
1000
  return;
995
1001
  }
996
- // Anything else is a server-side fault; rethrow so the
997
- // outer `handle()` catch returns 500 + logs the error.
998
1002
  throw err;
999
1003
  }
1000
1004
  this.respondJson(res, 200, payload);
@@ -1558,12 +1562,15 @@ export class EngramAccessHttpServer {
1558
1562
  );
1559
1563
  this.respondJson(res, 200, snapshot);
1560
1564
  } catch (err) {
1561
- const message = err instanceof Error ? err.message : String(err);
1562
- if (message.startsWith("graphSnapshot:")) {
1565
+ // As with recallXray above: surface only the deliberately-prefixed
1566
+ // graphSnapshot validation Error.message, never String(err) of an
1567
+ // arbitrary throw (CodeQL js/stack-trace-exposure). Validation errors are
1568
+ // always Error instances; anything else is rethrown as a 500.
1569
+ if (err instanceof Error && err.message.startsWith("graphSnapshot:")) {
1563
1570
  this.respondJson(res, 400, {
1564
1571
  error: "invalid_request",
1565
1572
  code: "invalid_request",
1566
- message,
1573
+ message: err.message,
1567
1574
  });
1568
1575
  return;
1569
1576
  }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/access-http.ts"],"sourcesContent":["import { createServer, type IncomingMessage, type Server, type ServerResponse } from \"node:http\";\nimport { randomUUID, timingSafeEqual } from \"node:crypto\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath, URL } from \"node:url\";\nimport { gunzipSync } from \"node:zlib\";\nimport { log } from \"./logger.js\";\nimport { EngramAccessInputError, type EngramAccessService } from \"./access-service.js\";\nimport { EngramMcpServer } from \"./access-mcp.js\";\nimport { validateRequest, type SchemaName, type SchemaTypeFor } from \"./access-schema.js\";\nimport {\n OFFLINE_SYNC_APPLY_MAX_BODY_BYTES,\n OFFLINE_SYNC_FILE_CONTENT_MAX_CHUNK_BYTES,\n OFFLINE_SYNC_SNAPSHOT_BASE_MAX_BODY_BYTES,\n} from \"./offline-sync.js\";\nimport type { RecallDisclosure, RecallPlanMode } from \"./types.js\";\nimport { isRecallDisclosure } from \"./types.js\";\nimport { isTrustZoneName, type TrustZoneName, type TrustZoneRecordKind, type TrustZoneSourceClass } from \"./trust-zones.js\";\nimport { AdapterRegistry, type ResolvedIdentity } from \"./adapters/index.js\";\nimport type { CitationEntry } from \"./citations.js\";\nimport {\n subscribeGraphEvents,\n type GraphEvent,\n} from \"./graph-events.js\";\nimport { expandTildePath } from \"./utils/path.js\";\nimport { projectTagProjectId } from \"./coding/coding-namespace.js\";\n\nexport interface EngramAccessHttpServerOptions {\n service: EngramAccessService;\n host?: string;\n port?: number;\n authToken?: string;\n /** Additional valid tokens (for multi-connector auth). Checked alongside authToken. */\n authTokens?: string[];\n /** Dynamic token loader — called on each auth check so new/revoked tokens take effect without restart. */\n authTokensGetter?: () => string[];\n principal?: string;\n maxBodyBytes?: number;\n adminConsoleEnabled?: boolean;\n adminConsolePublicDir?: string;\n trustPrincipalHeader?: boolean;\n /** Enable adapter-based identity resolution from request headers */\n enableAdapters?: boolean;\n /** Custom adapter registry (defaults to built-in adapters) */\n adapterRegistry?: AdapterRegistry;\n /** Enable oai-mem-citation blocks in recall responses (issue #379). */\n citationsEnabled?: boolean;\n /** Auto-enable citations for Codex adapter connections (issue #379). */\n citationsAutoDetect?: boolean;\n /** Advertise legacy engram.* tool aliases on tools/list (issue #1427). Default true. */\n emitLegacyTools?: boolean;\n}\n\nexport interface EngramAccessHttpServerStatus {\n running: boolean;\n host: string;\n port: number;\n maxBodyBytes: number;\n}\n\nfunction resolveDefaultAdminConsolePublicDir(): string {\n const thisDir = path.dirname(fileURLToPath(import.meta.url));\n const candidates = [\n // Standard: admin-console sibling to src/ (development layout)\n path.resolve(thisDir, \"../admin-console/public\"),\n // Bundled: admin-console inside dist/ alongside the bundle\n path.resolve(thisDir, \"./admin-console/public\"),\n // Package root: walk up from dist/ to the package root\n path.resolve(thisDir, \"../../admin-console/public\"),\n ];\n return candidates.find((candidate) => existsSync(candidate)) ?? candidates[0];\n}\n\nconst defaultAdminConsolePublicDir = resolveDefaultAdminConsolePublicDir();\nconst correlationIdStore = new AsyncLocalStorage<string>();\n\nconst WRITE_RATE_LIMIT_WINDOW_MS = 60_000;\nconst WRITE_RATE_LIMIT_MAX_REQUESTS = 30;\nconst TRUST_ZONE_RECORD_KINDS = [\"memory\", \"artifact\", \"state\", \"trajectory\", \"external\"] as const;\nconst TRUST_ZONE_SOURCE_CLASSES = [\"tool_output\", \"web_content\", \"subagent_trace\", \"system_memory\", \"user_input\", \"manual\"] as const;\n\nclass HttpError extends Error {\n readonly code: string;\n readonly details?: unknown;\n constructor(readonly status: number, message: string, code?: string, details?: unknown) {\n super(message);\n this.code = code ?? `http_${status}`;\n this.details = details;\n }\n}\n\nfunction hostToUrlAuthority(host: string): string {\n if (host.includes(\":\") && !host.startsWith(\"[\") && !host.endsWith(\"]\")) {\n return `[${host}]`;\n }\n return host;\n}\n\nfunction parseHttpServerPort(port: number | undefined): number {\n if (port === undefined) return 0;\n if (!Number.isInteger(port) || port < 0 || port > 65535) {\n throw new Error(\"access HTTP port must be an integer from 0 to 65535\");\n }\n return port;\n}\n\nfunction parseTrustZoneKindFilter(raw: string | null): TrustZoneRecordKind | undefined {\n if (raw === null) return undefined;\n if ((TRUST_ZONE_RECORD_KINDS as readonly string[]).includes(raw)) {\n return raw as TrustZoneRecordKind;\n }\n throw new HttpError(400, `kind must be one of ${TRUST_ZONE_RECORD_KINDS.join(\"|\")}`, \"invalid_kind_filter\");\n}\n\nfunction parseTrustZoneSourceClassFilter(raw: string | null): TrustZoneSourceClass | undefined {\n if (raw === null) return undefined;\n if ((TRUST_ZONE_SOURCE_CLASSES as readonly string[]).includes(raw)) {\n return raw as TrustZoneSourceClass;\n }\n throw new HttpError(400, `sourceClass must be one of ${TRUST_ZONE_SOURCE_CLASSES.join(\"|\")}`, \"invalid_source_class_filter\");\n}\n\nfunction parseTrustZoneFilter(raw: string | null): TrustZoneName | undefined {\n if (raw === null) return undefined;\n if (isTrustZoneName(raw)) {\n return raw;\n }\n throw new HttpError(400, \"zone must be one of quarantine|working|trusted\", \"invalid_zone_filter\");\n}\n\nfunction summarizeHttpRequest(req: IncomingMessage): string {\n const method = req.method ?? \"UNKNOWN\";\n try {\n const parsed = new URL(req.url ?? \"/\", \"http://localhost\");\n return `${method} ${parsed.pathname}`;\n } catch {\n return `${method} ${(req.url ?? \"/\").split(\"?\")[0]}`;\n }\n}\n\nfunction parseStrictIntegerQuery(\n raw: string | null,\n field: string,\n defaultValue: number,\n minValue: number,\n): number {\n if (raw === null) return defaultValue;\n if (!/^(?:0|[1-9]\\d*)$/.test(raw)) {\n throw new HttpError(400, `${field} must be an integer`, `invalid_${field}`);\n }\n const value = Number(raw);\n if (!Number.isInteger(value) || value < minValue) {\n throw new HttpError(400, `${field} must be an integer >= ${minValue}`, `invalid_${field}`);\n }\n return value;\n}\n\nfunction parseMemorySort(raw: string | null): \"updated_desc\" | \"updated_asc\" | \"created_desc\" | \"created_asc\" | undefined {\n if (raw === null) return undefined;\n if (\n raw === \"updated_desc\" ||\n raw === \"updated_asc\" ||\n raw === \"created_desc\" ||\n raw === \"created_asc\"\n ) {\n return raw;\n }\n throw new HttpError(400, \"sort must be one of updated_desc|updated_asc|created_desc|created_asc\", \"invalid_sort\");\n}\n\n/**\n * Decode a `:peerId` URL path segment, converting malformed percent-encoded\n * input (e.g., `%E0%A4%A`) into a 400 client error rather than letting\n * `URIError` bubble up as a 500 `internal_error`.\n */\nfunction decodePeerIdSegment(raw: string): string {\n try {\n return decodeURIComponent(raw);\n } catch {\n throw new EngramAccessInputError(\"peerId path segment is not valid percent-encoded input\");\n }\n}\n\nfunction codingContextFromProjectTag(projectTag: string): {\n projectId: string;\n branch: string | null;\n rootPath: string;\n defaultBranch: string | null;\n} {\n const projectId = projectTagProjectId(projectTag);\n return {\n projectId,\n branch: null,\n rootPath: projectId,\n defaultBranch: null,\n };\n}\n\nexport class EngramAccessHttpServer {\n private readonly service: EngramAccessService;\n private readonly host: string;\n private readonly requestedPort: number;\n private readonly authToken?: string;\n private readonly authTokens: string[];\n private readonly authTokensGetter?: () => string[];\n private readonly authenticatedPrincipal?: string;\n private readonly maxBodyBytes: number;\n private readonly adminConsoleEnabled: boolean;\n private readonly adminConsolePublicDir: string;\n private readonly trustPrincipalHeader: boolean;\n private readonly adapterRegistry: AdapterRegistry | null;\n private readonly writeRequestTimestamps: number[] = [];\n private readonly mcpServer: EngramMcpServer;\n private server: Server | null = null;\n private boundPort = 0;\n /** Active SSE response objects for /engram/v1/graph/events. */\n private readonly sseClients = new Set<ServerResponse>();\n /** Throttle batch: pending SSE event batches per client. */\n private readonly sseBatchTimers = new Map<ServerResponse, ReturnType<typeof setTimeout>>();\n private readonly ssePendingBatches = new Map<ServerResponse, GraphEvent[]>();\n /**\n * Per-client cleanup callbacks: clear heartbeat interval, flush timer,\n * unsubscribe from bus, and end the response. Stored here so `stop()`\n * can invoke them even when the client hasn't disconnected yet\n * (Cursor review thread `access-http.ts:232`).\n */\n private readonly sseCleanupFns = new Set<() => void>();\n\n constructor(options: EngramAccessHttpServerOptions) {\n this.service = options.service;\n this.host = options.host?.trim() || \"127.0.0.1\";\n this.requestedPort = parseHttpServerPort(options.port);\n this.authToken = options.authToken?.trim() || undefined;\n this.authTokens = (options.authTokens ?? []).map((t) => t.trim()).filter(Boolean);\n this.authTokensGetter = options.authTokensGetter;\n this.authenticatedPrincipal = options.principal?.trim() || undefined;\n this.maxBodyBytes = Number.isFinite(options.maxBodyBytes)\n ? Math.max(1, Math.floor(options.maxBodyBytes ?? 131072))\n : 131072;\n this.adminConsoleEnabled = options.adminConsoleEnabled !== false;\n this.adminConsolePublicDir = options.adminConsolePublicDir ?? defaultAdminConsolePublicDir;\n this.trustPrincipalHeader = options.trustPrincipalHeader === true;\n this.adapterRegistry = options.enableAdapters !== false\n ? (options.adapterRegistry ?? new AdapterRegistry())\n : null;\n this.mcpServer = new EngramMcpServer(this.service, {\n principal: options.principal,\n citationsEnabled: options.citationsEnabled,\n citationsAutoDetect: options.citationsAutoDetect,\n emitLegacyTools: options.emitLegacyTools,\n });\n }\n\n async start(): Promise<EngramAccessHttpServerStatus> {\n if (!this.authToken && this.authTokens.length === 0 && !this.authTokensGetter) {\n throw new Error(\"engram access HTTP requires authToken or authTokens\");\n }\n if (this.server) return this.status();\n\n const server = createServer((req, res) => {\n const correlationId = randomUUID();\n correlationIdStore.run(correlationId, () => {\n void this.handle(req, res, correlationId).catch((err) => {\n log.debug(`engram access HTTP request failed [${correlationId}]: ${err}`);\n if (err instanceof HttpError) {\n const payload: Record<string, unknown> = { error: err.message, code: err.code };\n if (err.details) payload.details = err.details;\n this.respondJson(res, err.status, payload);\n return;\n }\n if (err instanceof EngramAccessInputError) {\n this.respondJson(res, 400, { error: err.message, code: \"input_error\" });\n return;\n }\n if (res.headersSent) {\n res.destroy(err as Error);\n return;\n }\n log.error(\n `engram access HTTP internal error [${correlationId}] ${summarizeHttpRequest(req)}`,\n err,\n );\n this.respondJson(res, 500, { error: \"internal_error\", code: \"internal_error\" });\n });\n });\n });\n\n try {\n await new Promise<void>((resolve, reject) => {\n const onError = (err: Error) => {\n server.off(\"listening\", onListening);\n reject(err);\n };\n const onListening = () => {\n server.off(\"error\", onError);\n resolve();\n };\n server.once(\"error\", onError);\n server.once(\"listening\", onListening);\n server.listen(this.requestedPort, this.host);\n });\n } catch (err) {\n server.close();\n throw err;\n }\n\n this.server = server;\n const address = server.address();\n this.boundPort = typeof address === \"object\" && address ? address.port : this.requestedPort;\n return this.status();\n }\n\n async stop(): Promise<void> {\n if (!this.server) return;\n const server = this.server;\n this.server = null;\n this.boundPort = 0;\n // Invoke each SSE client's cleanup callback so heartbeat intervals,\n // batch timers, and graph-bus subscriptions are all released before the\n // HTTP server closes. Without this, long-running SSE connections leak\n // setInterval handles and EventEmitter listeners (Cursor review thread\n // `access-http.ts:232`).\n for (const cleanup of this.sseCleanupFns) {\n try { cleanup(); } catch { /* ignore */ }\n }\n this.sseCleanupFns.clear();\n // Belt-and-suspenders: clear any state not yet reached by cleanup fns.\n for (const [res, timer] of this.sseBatchTimers.entries()) {\n clearTimeout(timer);\n this.sseBatchTimers.delete(res);\n }\n this.ssePendingBatches.clear();\n for (const res of this.sseClients) {\n try { res.end(); } catch { /* ignore */ }\n }\n this.sseClients.clear();\n await new Promise<void>((resolve, reject) => {\n server.close((err) => (err ? reject(err) : resolve()));\n });\n }\n\n status(): EngramAccessHttpServerStatus {\n return {\n running: this.server !== null,\n host: this.host,\n port: this.boundPort,\n maxBodyBytes: this.maxBodyBytes,\n };\n }\n\n /**\n * Resolve the adapter identity for the incoming request.\n * Includes MCP clientInfo from the last initialize handshake if available.\n * Returns null if no adapter matches or adapters are disabled.\n */\n resolveAdapterIdentity(req: IncomingMessage): ResolvedIdentity | null {\n if (!this.adapterRegistry) return null;\n // Look up clientInfo for this specific MCP session to avoid cross-session leaks.\n // Non-MCP requests (no mcp-session-id header) get undefined clientInfo and\n // rely on HTTP headers for adapter matching.\n const sessionId = (() => {\n const raw = req.headers[\"mcp-session-id\"];\n return typeof raw === \"string\" ? raw.trim() : undefined;\n })();\n return this.adapterRegistry.resolve({\n headers: req.headers as Record<string, string | string[] | undefined>,\n clientInfo: this.mcpServer.getClientInfo(sessionId),\n });\n }\n\n /** Cache for per-request identity resolution (avoids double adapter resolution) */\n private identityCache = new WeakMap<IncomingMessage, { principal?: string; namespace?: string; sessionKey?: string }>();\n\n /** Resolve principal, namespace, and session key from request headers and adapter identity */\n private resolveRequestIdentity(req: IncomingMessage): { principal?: string; namespace?: string; sessionKey?: string } {\n const cached = this.identityCache.get(req);\n if (cached) return cached;\n let principal: string | undefined;\n let namespace: string | undefined;\n let sessionKey: string | undefined;\n\n // Explicit header override takes priority for principal\n if (this.trustPrincipalHeader) {\n const headerVal = req.headers[\"x-engram-principal\"];\n const raw = Array.isArray(headerVal) ? headerVal[0] : headerVal;\n if (typeof raw === \"string\") {\n const trimmed = raw.trim();\n if (trimmed.length > 0) {\n principal = trimmed;\n }\n }\n }\n\n if (!principal) {\n principal = this.authenticatedPrincipal;\n }\n\n // Try adapter-based identity resolution for namespace and, only when no\n // server principal is configured, an adapter-owned default principal.\n const adapterIdentity = this.resolveAdapterIdentity(req);\n if (adapterIdentity) {\n if (!principal) {\n principal = adapterIdentity.principal;\n }\n namespace = adapterIdentity.namespace;\n sessionKey = adapterIdentity.sessionKey;\n }\n\n const result = { principal, namespace, sessionKey };\n this.identityCache.set(req, result);\n return result;\n }\n\n private resolveRequestPrincipal(req: IncomingMessage): string | undefined {\n return this.resolveRequestIdentity(req).principal;\n }\n\n /** Resolve namespace: only use the explicit body value. Adapter-inferred namespace\n * is intentionally NOT used as a fallback for REST requests — omitting namespace\n * should default to the server's global namespace, not silently scope to an adapter. */\n private resolveNamespace(_req: IncomingMessage, bodyNamespace?: string): string | undefined {\n return bodyNamespace || undefined;\n }\n\n /**\n * Resolve the recall disclosure depth from the request (issue #677 PR\n * 2/4). Explicit body value wins; otherwise we accept a\n * `?disclosure=...` query parameter so curl/browser tooling can use the\n * three-tier surface without rewriting JSON. Invalid query values\n * throw `EngramAccessInputError` (CLAUDE.md rule 51 — no silent\n * fallback). An absent body field AND an absent query param yields\n * `undefined`, which the service maps to `DEFAULT_RECALL_DISCLOSURE`.\n */\n private resolveRecallDisclosure(\n bodyDisclosure: RecallDisclosure | undefined,\n parsed: URL,\n ): RecallDisclosure | undefined {\n if (bodyDisclosure !== undefined) {\n return bodyDisclosure;\n }\n const queryDisclosure = parsed.searchParams.get(\"disclosure\");\n if (queryDisclosure === null) {\n return undefined;\n }\n if (!isRecallDisclosure(queryDisclosure)) {\n throw new EngramAccessInputError(\n `disclosure must be one of: chunk, section, raw (got: ${queryDisclosure})`,\n );\n }\n return queryDisclosure;\n }\n\n private async handle(req: IncomingMessage, res: ServerResponse, correlationId: string): Promise<void> {\n const parsed = new URL(req.url ?? \"/\", `http://${hostToUrlAuthority(this.host)}`);\n const pathname = parsed.pathname;\n\n if (this.adminConsoleEnabled && await this.handleAdminConsole(req, res, pathname)) {\n return;\n }\n\n if (!this.isAuthorized(req, pathname)) {\n const body = JSON.stringify({ error: \"unauthorized\", code: \"unauthorized\" });\n res.writeHead(401, {\n \"content-type\": \"application/json; charset=utf-8\",\n \"www-authenticate\": \"Bearer\",\n \"x-request-id\": correlationId,\n });\n res.end(body);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/mcp\") {\n await this.handleMcpRequest(req, res);\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/health\") {\n this.respondJson(res, 200, await this.service.health());\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/adapters\") {\n const identity = this.resolveAdapterIdentity(req);\n this.respondJson(res, 200, {\n adaptersEnabled: this.adapterRegistry !== null,\n registered: this.adapterRegistry?.list() ?? [],\n resolved: identity,\n });\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/recall\") {\n const body = await this.readValidatedBody(req, \"recall\");\n // Preserve the distinction between `codingContext: null` (explicit\n // clear) and `codingContext` missing from the JSON payload\n // (untouched). The previous `?? undefined` collapsed both into\n // undefined, so callers lost the ability to clear the session's\n // attached context through the recall endpoint.\n const codingContext =\n \"codingContext\" in body ? body.codingContext : undefined;\n // Disclosure resolution (issue #677 PR 2/4): accept the value from\n // the validated body OR the `?disclosure=` query parameter, with\n // the body taking precedence so an explicit JSON payload is never\n // silently overridden by a stale URL. CLAUDE.md rule 51: invalid\n // query-param values throw, never fall back silently.\n const disclosure = this.resolveRecallDisclosure(body.disclosure, parsed);\n // Issue #680 — historical recall pin (`asOf`). Body field wins\n // over `?as_of=` query param. Empty query is rejected only when\n // the body didn't supply a valid pin (codex P2 + cursor Medium).\n const asOfQueryRaw = parsed.searchParams.get(\"as_of\");\n const bodyHasAsOf =\n typeof body.asOf === \"string\" && body.asOf.length > 0;\n if (\n !bodyHasAsOf &&\n asOfQueryRaw !== null &&\n asOfQueryRaw.length === 0\n ) {\n throw new EngramAccessInputError(\n \"as_of must be a non-empty timestamp (got empty value)\",\n );\n }\n const asOf =\n body.asOf ??\n (asOfQueryRaw !== null && asOfQueryRaw.length > 0\n ? asOfQueryRaw\n : undefined);\n // Tag filter (issue #689). Body presence wins over query params\n // — explicit `tags: []` in body clears the filter even with\n // stale `?tag=` URLs.\n const bodyHasTagsField =\n body !== null &&\n typeof body === \"object\" &&\n \"tags\" in (body as Record<string, unknown>);\n const bodyTagsValue = bodyHasTagsField\n ? (body as { tags?: unknown }).tags\n : undefined;\n const bodyTags = Array.isArray(bodyTagsValue)\n ? (bodyTagsValue as string[])\n : undefined;\n const queryTags = parsed.searchParams.getAll(\"tag\");\n const tags = bodyHasTagsField\n ? bodyTags\n : queryTags.length > 0\n ? queryTags\n : undefined;\n const bodyTagMatch = (body as { tagMatch?: unknown }).tagMatch;\n let tagMatch: \"any\" | \"all\" | undefined;\n if (bodyTagMatch !== undefined) {\n if (bodyTagMatch === \"any\" || bodyTagMatch === \"all\") {\n tagMatch = bodyTagMatch;\n }\n } else {\n const queryTagMatch = parsed.searchParams.get(\"tag_match\");\n if (queryTagMatch !== null) {\n if (queryTagMatch !== \"any\" && queryTagMatch !== \"all\") {\n throw new EngramAccessInputError(\n `tag_match must be one of: any, all (got: ${queryTagMatch})`,\n );\n }\n tagMatch = queryTagMatch;\n }\n }\n // Issue #681 — `?include_low_confidence=true|false` mirrors the CLI\n // `--include-low-confidence` flag. Body field wins so a JSON payload can\n // explicitly clear a stale query parameter.\n const bodyIncludeLowConfidence =\n (body as { includeLowConfidence?: unknown }).includeLowConfidence;\n const queryIncludeLowConfidence = parsed.searchParams.get(\"include_low_confidence\");\n if (\n bodyIncludeLowConfidence === undefined &&\n queryIncludeLowConfidence !== null &&\n queryIncludeLowConfidence !== \"true\" &&\n queryIncludeLowConfidence !== \"false\"\n ) {\n throw new EngramAccessInputError(\n `include_low_confidence must be one of: true, false (got: ${queryIncludeLowConfidence})`,\n );\n }\n const includeLowConfidence =\n bodyIncludeLowConfidence === true ||\n (bodyIncludeLowConfidence === undefined &&\n queryIncludeLowConfidence === \"true\");\n const response = await this.service.recall({\n query: body.query ?? \"\",\n sessionKey: body.sessionKey,\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n idempotencyKey: body.idempotencyKey,\n namespace: this.resolveNamespace(req, body.namespace),\n topK: body.topK,\n mode: body.mode as RecallPlanMode | \"auto\" | undefined,\n includeDebug: body.includeDebug === true,\n // Forward the validated disclosure depth to the service layer\n // (issue #677). The zod schema accepts/rejects body values;\n // `resolveRecallDisclosure()` validates the query-param fallback.\n disclosure,\n codingContext,\n // Forward cwd/projectTag for auto git-context resolution (issue #569).\n cwd: body.cwd,\n projectTag: body.projectTag,\n ...(asOf !== undefined ? { asOf } : {}),\n ...(tags !== undefined ? { tags } : {}),\n ...(tagMatch !== undefined ? { tagMatch } : {}),\n ...(includeLowConfidence ? { includeLowConfidence: true } : {}),\n });\n this.respondJson(res, 200, response);\n return;\n }\n\n // Attach / clear coding-agent context for a session (issue #569 PR 5).\n // Mirrors `setCodingContext` on the access service. Connectors call this\n // at session start after resolving a git context for the cwd; `remnic\n // doctor` (PR 8) surfaces the attached context.\n if (req.method === \"POST\" && pathname === \"/engram/v1/coding-context\") {\n const body = await this.readValidatedBody(req, \"setCodingContext\");\n const codingContext =\n body.codingContext !== undefined\n ? body.codingContext\n : typeof body.projectTag === \"string\"\n ? codingContextFromProjectTag(body.projectTag)\n : (() => {\n throw new EngramAccessInputError(\"codingContext or projectTag is required\");\n })();\n this.service.setCodingContext({\n sessionKey: body.sessionKey,\n codingContext,\n });\n this.respondJson(res, 200, { ok: true });\n return;\n }\n\n if (\n req.method === \"POST\" &&\n (pathname === \"/engram/v1/capsules/export\" || pathname === \"/remnic/v1/capsules/export\")\n ) {\n const body = await this.readValidatedBody(req, \"capsuleExport\");\n this.ensureWriteRateLimitAvailable();\n const result = await this.service.capsuleExport({\n name: body.name,\n namespace: this.resolveNamespace(req, body.namespace),\n principal: this.resolveRequestPrincipal(req),\n since: body.since,\n includeKinds: body.includeKinds,\n peerIds: body.peerIds,\n includeTranscripts: body.includeTranscripts,\n encrypt: body.encrypt,\n });\n this.recordWriteRateLimitHit();\n this.respondJson(res, 200, result);\n return;\n }\n\n if (\n req.method === \"POST\" &&\n (pathname === \"/engram/v1/capsules/import\" || pathname === \"/remnic/v1/capsules/import\")\n ) {\n const body = await this.readValidatedBody(req, \"capsuleImport\");\n this.ensureWriteRateLimitAvailable();\n const result = await this.service.capsuleImport({\n archivePath: expandTildePath(body.archivePath),\n namespace: this.resolveNamespace(req, body.namespace),\n principal: this.resolveRequestPrincipal(req),\n mode: body.mode,\n passphrase: body.passphrase,\n });\n this.recordWriteRateLimitHit();\n this.respondJson(res, 200, result);\n return;\n }\n\n if (\n req.method === \"GET\" &&\n (pathname === \"/engram/v1/offline-sync/snapshot\" || pathname === \"/remnic/v1/offline-sync/snapshot\")\n ) {\n const includeTranscriptsRaw = parsed.searchParams.get(\"include_transcripts\");\n const includeContentRaw = parsed.searchParams.get(\"content\");\n if (\n includeTranscriptsRaw !== null &&\n includeTranscriptsRaw !== \"true\" &&\n includeTranscriptsRaw !== \"false\"\n ) {\n throw new EngramAccessInputError(\n `include_transcripts must be one of: true, false (got: ${includeTranscriptsRaw})`,\n );\n }\n if (\n includeContentRaw !== null &&\n includeContentRaw !== \"true\" &&\n includeContentRaw !== \"false\"\n ) {\n throw new EngramAccessInputError(\n `content must be one of: true, false (got: ${includeContentRaw})`,\n );\n }\n const namespaceParam = parsed.searchParams.get(\"namespace\");\n const result = await this.service.offlineSyncSnapshot({\n namespace: this.resolveNamespace(\n req,\n namespaceParam && namespaceParam.length > 0 ? namespaceParam : undefined,\n ),\n principal: this.resolveRequestPrincipal(req),\n includeTranscripts: includeTranscriptsRaw !== \"false\",\n includeContent: includeContentRaw !== \"false\",\n });\n this.respondJson(res, 200, result);\n return;\n }\n\n if (\n req.method === \"GET\" &&\n (pathname === \"/engram/v1/offline-sync/snapshot-stream\" ||\n pathname === \"/remnic/v1/offline-sync/snapshot-stream\")\n ) {\n const includeTranscriptsRaw = parsed.searchParams.get(\"include_transcripts\");\n const includeContentRaw = parsed.searchParams.get(\"content\");\n if (\n includeTranscriptsRaw !== null &&\n includeTranscriptsRaw !== \"true\" &&\n includeTranscriptsRaw !== \"false\"\n ) {\n throw new EngramAccessInputError(\n `include_transcripts must be one of: true, false (got: ${includeTranscriptsRaw})`,\n );\n }\n if (\n includeContentRaw !== null &&\n includeContentRaw !== \"false\"\n ) {\n throw new EngramAccessInputError(\"snapshot-stream content must be false\");\n }\n const namespaceParam = parsed.searchParams.get(\"namespace\");\n const result = await this.service.offlineSyncSnapshotStream({\n namespace: this.resolveNamespace(\n req,\n namespaceParam && namespaceParam.length > 0 ? namespaceParam : undefined,\n ),\n principal: this.resolveRequestPrincipal(req),\n includeTranscripts: includeTranscriptsRaw !== \"false\",\n includeContent: false,\n signal: this.createRequestAbortSignal(req, res),\n });\n await this.respondOfflineSnapshotStream(res, result);\n return;\n }\n\n if (\n req.method === \"POST\" &&\n (pathname === \"/engram/v1/offline-sync/snapshot\" || pathname === \"/remnic/v1/offline-sync/snapshot\")\n ) {\n const body = await this.readValidatedBody(\n req,\n \"offlineSyncSnapshot\",\n OFFLINE_SYNC_SNAPSHOT_BASE_MAX_BODY_BYTES,\n );\n const result = await this.service.offlineSyncSnapshot({\n namespace: this.resolveNamespace(req, body.namespace),\n principal: this.resolveRequestPrincipal(req),\n includeTranscripts: body.includeTranscripts,\n includeContent: body.includeContent,\n baseFiles: body.baseFiles,\n ...(body.baseCapturedAt ? { baseCapturedAt: new Date(body.baseCapturedAt) } : {}),\n signal: this.createRequestAbortSignal(req, res),\n });\n this.respondJson(res, 200, result);\n return;\n }\n\n if (\n req.method === \"POST\" &&\n (pathname === \"/engram/v1/offline-sync/files\" || pathname === \"/remnic/v1/offline-sync/files\")\n ) {\n const body = await this.readValidatedBody(req, \"offlineSyncFiles\");\n const result = await this.service.offlineSyncFiles({\n namespace: this.resolveNamespace(req, body.namespace),\n principal: this.resolveRequestPrincipal(req),\n includeTranscripts: body.includeTranscripts,\n paths: body.paths,\n });\n this.respondJson(res, 200, result);\n return;\n }\n\n if (\n req.method === \"POST\" &&\n (\n pathname === \"/engram/v1/offline-sync/file-content\" ||\n pathname === \"/remnic/v1/offline-sync/file-content\"\n )\n ) {\n const body = await this.readValidatedBody(req, \"offlineSyncFileContent\");\n const result = await this.service.offlineSyncFileContent({\n namespace: this.resolveNamespace(req, body.namespace),\n principal: this.resolveRequestPrincipal(req),\n includeTranscripts: body.includeTranscripts,\n path: body.path,\n offset: body.offset,\n length: body.length,\n });\n this.respondBinary(res, 200, result.content, {\n \"x-remnic-namespace\": encodeURIComponent(result.namespace),\n \"x-remnic-file-path\": encodeURIComponent(result.path),\n \"x-remnic-file-bytes\": String(result.bytes),\n \"x-remnic-file-mtime-ms\": String(result.mtimeMs),\n \"x-remnic-chunk-offset\": String(result.offset),\n \"x-remnic-chunk-bytes\": String(result.chunkBytes),\n ...(result.sha256 ? { \"x-remnic-file-sha256\": result.sha256 } : {}),\n });\n return;\n }\n\n if (\n req.method === \"POST\" &&\n (\n pathname === \"/engram/v1/offline-sync/apply-file-content\" ||\n pathname === \"/remnic/v1/offline-sync/apply-file-content\"\n )\n ) {\n const namespaceParam = parsed.searchParams.get(\"namespace\");\n const bytes = this.readRequiredIntegerHeader(req, \"x-remnic-file-bytes\");\n const offset = this.readOptionalIntegerHeader(req, \"x-remnic-chunk-offset\") ?? 0;\n const content = await this.readBinaryBody(req, OFFLINE_SYNC_FILE_CONTENT_MAX_CHUNK_BYTES);\n const result = await this.service.offlineSyncApplyFileContent({\n namespace: this.resolveNamespace(\n req,\n namespaceParam && namespaceParam.length > 0 ? namespaceParam : undefined,\n ),\n principal: this.resolveRequestPrincipal(req),\n includeTranscripts: this.parseOptionalBooleanHeader(\n req,\n \"x-remnic-include-transcripts\",\n true,\n ),\n sourceId: this.readRequiredDecodedHeader(req, \"x-remnic-source-id\"),\n path: this.readRequiredDecodedHeader(req, \"x-remnic-file-path\"),\n sha256: this.readRequiredHeader(req, \"x-remnic-file-sha256\"),\n bytes,\n mtimeMs: this.readRequiredNumberHeader(req, \"x-remnic-file-mtime-ms\"),\n offset,\n baseSha256: this.readOptionalHeader(req, \"x-remnic-base-sha256\"),\n content,\n });\n this.respondJson(res, 200, result);\n return;\n }\n\n if (\n req.method === \"POST\" &&\n (pathname === \"/engram/v1/offline-sync/apply\" || pathname === \"/remnic/v1/offline-sync/apply\")\n ) {\n const body = await this.readValidatedBody(req, \"offlineSyncApply\", OFFLINE_SYNC_APPLY_MAX_BODY_BYTES);\n const result = await this.service.offlineSyncApply({\n namespace: this.resolveNamespace(req, body.namespace),\n principal: this.resolveRequestPrincipal(req),\n changeset: body.changeset,\n returnCurrentFiles: body.returnCurrentFiles,\n });\n this.respondJson(res, 200, result);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/recall/explain\") {\n const body = await this.readValidatedBody(req, \"recallExplain\");\n const response = await this.service.recallExplain({\n sessionKey: body.sessionKey,\n namespace: this.resolveNamespace(req, body.namespace),\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n });\n this.respondJson(res, 200, response);\n return;\n }\n\n if (\n req.method === \"POST\" &&\n (pathname === \"/engram/v1/action-confidence\" || pathname === \"/remnic/v1/action-confidence\")\n ) {\n const body = await this.readValidatedBody(req, \"actionConfidence\");\n this.respondJson(res, 200, await this.service.actionConfidence(body));\n return;\n }\n\n // Tier-explain (issue #518): structured per-result annotation from\n // the direct-answer retrieval tier. Orthogonal to /recall/explain\n // above, which returns a graph-path explanation document.\n if (req.method === \"GET\" && pathname === \"/engram/v1/recall/tier-explain\") {\n const sessionParam = parsed.searchParams.get(\"session\");\n const sessionKey = sessionParam && sessionParam.length > 0 ? sessionParam : undefined;\n const namespaceParam = parsed.searchParams.get(\"namespace\");\n const namespace = this.resolveNamespace(\n req,\n namespaceParam && namespaceParam.length > 0 ? namespaceParam : undefined,\n );\n const payload = await this.service.recallTierExplain(\n sessionKey,\n namespace,\n this.resolveRequestPrincipal(req),\n );\n this.respondJson(res, 200, payload);\n return;\n }\n\n // Recall X-ray (issue #570 PR 4): unified per-result attribution\n // snapshot. Requires bearer auth (same as every other endpoint\n // here) and enforces namespace scope before the recall fires\n // (CLAUDE.md rule 42). Query comes from the `q` search param so\n // GET stays cacheable; `namespace` / `session` / `budget` are\n // optional.\n if (req.method === \"GET\" && pathname === \"/engram/v1/recall/xray\") {\n const queryParam = parsed.searchParams.get(\"q\");\n if (!queryParam || queryParam.trim().length === 0) {\n this.respondJson(res, 400, {\n error: \"missing_query\",\n code: \"missing_query\",\n message: \"q search parameter is required and must be non-empty\",\n });\n return;\n }\n const sessionParam = parsed.searchParams.get(\"session\");\n const sessionKey = sessionParam && sessionParam.length > 0\n ? sessionParam\n : undefined;\n const namespaceParam = parsed.searchParams.get(\"namespace\");\n const namespace = this.resolveNamespace(\n req,\n namespaceParam && namespaceParam.length > 0\n ? namespaceParam\n : undefined,\n );\n const budgetParam = parsed.searchParams.get(\"budget\");\n // Reject invalid `budget` with 400 rather than silently\n // defaulting (CLAUDE.md rules 14 + 51).\n let budget: number | undefined;\n if (budgetParam !== null && budgetParam !== \"\") {\n const parsedBudget = Number(budgetParam);\n if (\n !Number.isFinite(parsedBudget)\n || parsedBudget <= 0\n || !Number.isInteger(parsedBudget)\n ) {\n this.respondJson(res, 400, {\n error: \"invalid_budget\",\n code: \"invalid_budget\",\n message:\n \"budget expects a positive integer\",\n });\n return;\n }\n budget = parsedBudget;\n }\n // Disclosure depth (issue #677 PR 3/4 telemetry plumbing). When\n // present, must match the chunk|section|raw allow-list; invalid\n // values surface as a 400 (CLAUDE.md rule 51 — no silent\n // fallback) rather than silently disabling the per-disclosure\n // summary table.\n const disclosureParam = parsed.searchParams.get(\"disclosure\");\n let disclosure: RecallDisclosure | undefined;\n if (disclosureParam !== null && disclosureParam.length > 0) {\n if (!isRecallDisclosure(disclosureParam)) {\n this.respondJson(res, 400, {\n error: \"invalid_disclosure\",\n code: \"invalid_disclosure\",\n message:\n \"disclosure must be one of: chunk, section, raw\",\n });\n return;\n }\n disclosure = disclosureParam;\n }\n // Only translate validation errors (empty query, bad budget)\n // into 400s. Backend faults (timeouts, storage errors,\n // unexpected orchestrator failures) must bubble to the global\n // `handle()` error handler so they return 500 and get logged\n // properly. `service.recallXray` prefixes its validation\n // errors with \"recallXray:\" so we key off that prefix rather\n // than catching everything.\n let payload: Awaited<ReturnType<typeof this.service.recallXray>>;\n try {\n payload = await this.service.recallXray({\n query: queryParam,\n sessionKey,\n namespace,\n budget,\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n ...(disclosure !== undefined ? { disclosure } : {}),\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (message.startsWith(\"recallXray:\")) {\n this.respondJson(res, 400, {\n error: \"invalid_request\",\n code: \"invalid_request\",\n message,\n });\n return;\n }\n // Anything else is a server-side fault; rethrow so the\n // outer `handle()` catch returns 500 + logs the error.\n throw err;\n }\n this.respondJson(res, 200, payload);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/observe\") {\n const body = await this.readValidatedBody(req, \"observe\");\n this.ensureWriteRateLimitAvailable();\n const response = await this.service.observe({\n sessionKey: body.sessionKey,\n messages: body.messages.map((message) => ({\n role: message.role,\n content: message.content,\n sourceFormat: message.sourceFormat ?? undefined,\n rawContent: message.rawContent ?? undefined,\n parts: message.parts ?? undefined,\n })),\n namespace: this.resolveNamespace(req, body.namespace),\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n skipExtraction: body.skipExtraction === true,\n // Forward cwd/projectTag for auto git-context resolution (issue #569).\n cwd: body.cwd,\n projectTag: body.projectTag,\n });\n this.recordWriteRateLimitHit();\n this.respondJson(res, 202, response);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/lcm/search\") {\n const body = await this.readValidatedBody(req, \"lcmSearch\");\n const response = await this.service.lcmSearch({\n query: body.query,\n sessionKey: body.sessionKey,\n sessionPrefix: body.sessionPrefix,\n namespace: this.resolveNamespace(req, body.namespace),\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n limit: body.limit,\n });\n this.respondJson(res, 200, response);\n return;\n }\n\n if (\n req.method === \"POST\" &&\n (pathname === \"/engram/v1/lcm/compaction/flush\" || pathname === \"/remnic/v1/lcm/compaction/flush\")\n ) {\n const body = await this.readValidatedBody(req, \"lcmCompactionFlush\");\n this.ensureWriteRateLimitAvailable();\n const response = await this.service.lcmCompactionFlush({\n sessionKey: body.sessionKey,\n namespace: this.resolveNamespace(req, body.namespace),\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n });\n this.recordWriteRateLimitHit();\n this.respondJson(res, 200, response);\n return;\n }\n\n if (\n req.method === \"POST\" &&\n (pathname === \"/engram/v1/lcm/compaction/record\" || pathname === \"/remnic/v1/lcm/compaction/record\")\n ) {\n const body = await this.readValidatedBody(req, \"lcmCompactionRecord\");\n this.ensureWriteRateLimitAvailable();\n const response = await this.service.lcmCompactionRecord({\n sessionKey: body.sessionKey,\n namespace: this.resolveNamespace(req, body.namespace),\n tokensBefore: body.tokensBefore,\n tokensAfter: body.tokensAfter,\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n });\n this.recordWriteRateLimitHit();\n this.respondJson(res, 200, response);\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/lcm/status\") {\n this.respondJson(res, 200, await this.service.lcmStatus());\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/memories\") {\n const body = await this.readValidatedBody(req, \"memoryStore\");\n const request = {\n schemaVersion: body.schemaVersion,\n idempotencyKey: body.idempotencyKey,\n dryRun: body.dryRun === true,\n sessionKey: body.sessionKey,\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n content: body.content,\n category: body.category,\n confidence: body.confidence,\n namespace: this.resolveNamespace(req, body.namespace),\n tags: body.tags,\n entityRef: body.entityRef,\n ttl: body.ttl,\n sourceReason: body.sourceReason,\n cwd: body.cwd,\n projectTag: body.projectTag,\n };\n // Rate-limit enforcement is SOLELY authoritative inside memoryStore via\n // enforceWriteQuota: it runs atomically with the real idempotency-miss\n // determination (and the real resolved namespace), and is never invoked\n // for a replay. We deliberately do NOT pre-check here: the write namespace\n // is resolved from mutable session/git context, so a stale peek could\n // report \"miss\" for a request that is actually an idempotent replay in the\n // now-scoped namespace and hard-reject a safe replay with 429 (#1434 Codex\n // review). Letting the in-lock hook be the only hard gate avoids that.\n const response = await this.service.memoryStore(request, {\n enforceWriteQuota: () => this.ensureWriteRateLimitAvailable(),\n });\n if (this.shouldCountWriteRateLimit(response as { dryRun?: boolean; idempotencyReplay?: boolean })) {\n this.recordWriteRateLimitHit();\n }\n this.respondJson(res, this.writeResponseStatus(response), response);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/suggestions\") {\n const body = await this.readValidatedBody(req, \"suggestionSubmit\");\n const request = {\n schemaVersion: body.schemaVersion,\n idempotencyKey: body.idempotencyKey,\n dryRun: body.dryRun === true,\n sessionKey: body.sessionKey,\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n content: body.content,\n category: body.category,\n confidence: body.confidence,\n namespace: this.resolveNamespace(req, body.namespace),\n tags: body.tags,\n entityRef: body.entityRef,\n ttl: body.ttl,\n sourceReason: body.sourceReason,\n cwd: body.cwd,\n projectTag: body.projectTag,\n };\n // Quota enforcement is solely authoritative inside suggestionSubmit\n // (enforceWriteQuota), atomic with the real miss and never on a replay; no\n // HTTP pre-check, so a stale peek can't 429 a safe replay (#1434 Codex review).\n const response = await this.service.suggestionSubmit(request, {\n enforceWriteQuota: () => this.ensureWriteRateLimitAvailable(),\n });\n if (this.shouldCountWriteRateLimit(response as { dryRun?: boolean; idempotencyReplay?: boolean })) {\n this.recordWriteRateLimitHit();\n }\n this.respondJson(res, this.writeResponseStatus(response), response);\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/memories\") {\n const limit = parseStrictIntegerQuery(parsed.searchParams.get(\"limit\"), \"limit\", 50, 1);\n const offset = parseStrictIntegerQuery(parsed.searchParams.get(\"offset\"), \"offset\", 0, 0);\n const sort = parseMemorySort(parsed.searchParams.get(\"sort\"));\n const response = await this.service.memoryBrowse({\n query: parsed.searchParams.get(\"q\") ?? undefined,\n status: parsed.searchParams.get(\"status\") ?? undefined,\n category: parsed.searchParams.get(\"category\") ?? undefined,\n namespace: parsed.searchParams.get(\"namespace\") ?? undefined,\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n sort,\n limit,\n offset,\n });\n this.respondJson(res, 200, response);\n return;\n }\n\n const memoryMatch = pathname.match(/^\\/engram\\/v1\\/memories\\/([^/]+)$/);\n if (req.method === \"GET\" && memoryMatch) {\n const memoryId = decodeURIComponent(memoryMatch[1] ?? \"\");\n const namespace = parsed.searchParams.get(\"namespace\") ?? undefined;\n const response = await this.service.memoryGet(memoryId, namespace, this.resolveRequestPrincipal(req));\n this.respondJson(res, response.found ? 200 : 404, response);\n return;\n }\n\n const timelineMatch = pathname.match(/^\\/engram\\/v1\\/memories\\/([^/]+)\\/timeline$/);\n if (req.method === \"GET\" && timelineMatch) {\n const memoryId = decodeURIComponent(timelineMatch[1] ?? \"\");\n const namespace = parsed.searchParams.get(\"namespace\") ?? undefined;\n const limit = parseStrictIntegerQuery(parsed.searchParams.get(\"limit\"), \"limit\", 200, 1);\n const response = await this.service.memoryTimeline(memoryId, namespace, limit, this.resolveRequestPrincipal(req));\n this.respondJson(res, response.found ? 200 : 404, response);\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/entities\") {\n const limit = parseStrictIntegerQuery(parsed.searchParams.get(\"limit\"), \"limit\", 50, 1);\n const offset = parseStrictIntegerQuery(parsed.searchParams.get(\"offset\"), \"offset\", 0, 0);\n const response = await this.service.entityList({\n namespace: parsed.searchParams.get(\"namespace\") ?? undefined,\n query: parsed.searchParams.get(\"q\") ?? undefined,\n limit,\n offset,\n });\n this.respondJson(res, 200, response);\n return;\n }\n\n const entityMatch = pathname.match(/^\\/engram\\/v1\\/entities\\/([^/]+)$/);\n if (req.method === \"GET\" && entityMatch) {\n const entityName = decodeURIComponent(entityMatch[1] ?? \"\");\n const namespace = parsed.searchParams.get(\"namespace\") ?? undefined;\n const response = await this.service.entityGet(entityName, namespace);\n this.respondJson(res, response.found ? 200 : 404, response);\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/review-queue\") {\n const response = await this.service.reviewQueue(\n parsed.searchParams.get(\"runId\") ?? undefined,\n parsed.searchParams.get(\"namespace\") ?? undefined,\n this.resolveRequestPrincipal(req),\n );\n this.respondJson(res, 200, response);\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/maintenance\") {\n this.respondJson(res, 200, await this.service.maintenance(parsed.searchParams.get(\"namespace\") ?? undefined, this.resolveRequestPrincipal(req)));\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/quality\") {\n this.respondJson(res, 200, await this.service.quality(parsed.searchParams.get(\"namespace\") ?? undefined, this.resolveRequestPrincipal(req)));\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/trust-zones/status\") {\n this.respondJson(\n res,\n 200,\n await this.service.trustZoneStatus(parsed.searchParams.get(\"namespace\") ?? undefined, this.resolveRequestPrincipal(req)),\n );\n return;\n }\n\n // Procedural memory stats (issue #567 PR 5/5). Read-only; namespace is\n // scoped via the same resolver used by recall/trust-zones so cross-\n // tenant reads aren't possible (CLAUDE.md rule 42).\n if (req.method === \"GET\" && pathname === \"/engram/v1/procedural/stats\") {\n const namespaceParam = parsed.searchParams.get(\"namespace\");\n this.respondJson(\n res,\n 200,\n await this.service.procedureStats(\n {\n namespace: this.resolveNamespace(\n req,\n namespaceParam && namespaceParam.length > 0\n ? namespaceParam\n : undefined,\n ),\n },\n this.resolveRequestPrincipal(req),\n ),\n );\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/trust-zones/records\") {\n const limit = parseStrictIntegerQuery(parsed.searchParams.get(\"limit\"), \"limit\", 25, 1);\n const offset = parseStrictIntegerQuery(parsed.searchParams.get(\"offset\"), \"offset\", 0, 0);\n const response = await this.service.trustZoneBrowse({\n query: parsed.searchParams.get(\"q\") ?? undefined,\n zone: parseTrustZoneFilter(parsed.searchParams.get(\"zone\")),\n kind: parseTrustZoneKindFilter(parsed.searchParams.get(\"kind\")),\n sourceClass: parseTrustZoneSourceClassFilter(parsed.searchParams.get(\"sourceClass\")),\n namespace: parsed.searchParams.get(\"namespace\") ?? undefined,\n limit,\n offset,\n }, this.resolveRequestPrincipal(req));\n this.respondJson(res, 200, response);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/review-disposition\") {\n const body = await this.readValidatedBody(req, \"reviewDisposition\");\n this.ensureWriteRateLimitAvailable();\n const response = await this.service.reviewDisposition({\n memoryId: body.memoryId,\n status: body.status,\n reasonCode: body.reasonCode,\n namespace: this.resolveNamespace(req, body.namespace),\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n });\n if (this.shouldCountWriteRateLimit(response as unknown as { dryRun?: boolean; idempotencyReplay?: boolean })) {\n this.recordWriteRateLimitHit();\n }\n this.respondJson(res, 200, response);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/trust-zones/promote\") {\n const body = await this.readValidatedBody(req, \"trustZonePromote\");\n const dryRun = body.dryRun === true;\n if (!dryRun) {\n this.ensureWriteRateLimitAvailable();\n }\n const response = await this.service.trustZonePromote({\n recordId: body.recordId,\n targetZone: body.targetZone,\n promotionReason: body.promotionReason,\n recordedAt: body.recordedAt,\n summary: body.summary,\n dryRun,\n namespace: this.resolveNamespace(req, body.namespace),\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n });\n if (this.shouldCountWriteRateLimit(response as unknown as { dryRun?: boolean; idempotencyReplay?: boolean })) {\n this.recordWriteRateLimitHit();\n }\n this.respondJson(res, response.dryRun ? 200 : 201, response);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/trust-zones/demo-seed\") {\n const body = await this.readValidatedBody(req, \"trustZoneDemoSeed\");\n const dryRun = body.dryRun === true;\n if (!dryRun) {\n this.ensureWriteRateLimitAvailable();\n }\n const response = await this.service.trustZoneDemoSeed({\n scenario: body.scenario,\n recordedAt: body.recordedAt,\n dryRun,\n namespace: this.resolveNamespace(req, body.namespace),\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n });\n if (this.shouldCountWriteRateLimit(response as unknown as { dryRun?: boolean; idempotencyReplay?: boolean })) {\n this.recordWriteRateLimitHit();\n }\n this.respondJson(res, response.dryRun ? 200 : 201, response);\n return;\n }\n\n // Citation usage tracking (issue #379)\n if (req.method === \"POST\" && pathname === \"/v1/citations/observed\") {\n const body = await this.readJsonBody(req);\n if (!body || typeof body !== \"object\" || Array.isArray(body)) {\n throw new HttpError(400, \"request body must be a JSON object\", \"invalid_body\");\n }\n const payload = body as Record<string, unknown>;\n const sessionId = typeof payload.sessionId === \"string\" ? payload.sessionId : undefined;\n const namespace = typeof payload.namespace === \"string\" ? payload.namespace : undefined;\n const citationsRaw = payload.citations;\n if (!citationsRaw || typeof citationsRaw !== \"object\" || Array.isArray(citationsRaw)) {\n throw new HttpError(400, \"citations must be a JSON object with entries and rolloutIds\", \"invalid_citations\");\n }\n const citObj = citationsRaw as Record<string, unknown>;\n const entries: CitationEntry[] = [];\n if (Array.isArray(citObj.entries)) {\n for (const raw of citObj.entries) {\n if (raw && typeof raw === \"object\" && !Array.isArray(raw)) {\n const e = raw as Record<string, unknown>;\n if (\n typeof e.path === \"string\" &&\n typeof e.lineStart === \"number\" &&\n typeof e.lineEnd === \"number\"\n ) {\n entries.push({\n path: e.path,\n lineStart: e.lineStart,\n lineEnd: e.lineEnd,\n note: typeof e.note === \"string\" ? e.note : \"\",\n });\n }\n }\n }\n }\n const rolloutIds: string[] = [];\n if (Array.isArray(citObj.rolloutIds)) {\n for (const id of citObj.rolloutIds) {\n if (typeof id === \"string\" && id.length > 0) {\n rolloutIds.push(id);\n }\n }\n }\n\n // Record usage: for each citation entry, try to increment usage on the\n // matching memory. The service exposes recordAccess for this purpose.\n // Pass authenticatedPrincipal so namespace ACL checks use the same\n // identity resolution as other write endpoints (Finding #1, issue #379).\n let matched = 0;\n let submitted = 0;\n if (typeof this.service.recordCitationUsage === \"function\") {\n const result = await this.service.recordCitationUsage({\n sessionId,\n namespace: this.resolveNamespace(req, namespace),\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n entries,\n rolloutIds,\n });\n submitted = result.submitted;\n matched = result.matched;\n }\n\n this.respondJson(res, 200, {\n ok: true,\n submitted,\n matched,\n entriesReceived: entries.length,\n rolloutIdsReceived: rolloutIds.length,\n });\n return;\n }\n\n // ── Contradiction Review (issue #520) ─────────────────────────────────────\n if (req.method === \"GET\" && pathname === \"/engram/v1/review/contradictions\") {\n const VALID_FILTERS = new Set([\"all\", \"unresolved\", \"contradicts\", \"independent\", \"duplicates\", \"needs-user\"]);\n const rawFilter = parsed.searchParams.get(\"filter\") ?? \"unresolved\";\n if (!VALID_FILTERS.has(rawFilter)) {\n this.respondJson(res, 400, { error: `Invalid filter '${rawFilter}'. Valid: ${[...VALID_FILTERS].join(\", \")}` });\n return;\n }\n const namespace = parsed.searchParams.get(\"namespace\") ?? undefined;\n const limit = parseStrictIntegerQuery(parsed.searchParams.get(\"limit\"), \"limit\", 50, 1);\n const {\n isDefaultReviewNamespace,\n listPairs,\n } = await import(\"./contradiction/contradiction-review.js\");\n const principal = this.resolveRequestPrincipal(req);\n const resolved = await this.service.getReadableStorageForNamespace(namespace, principal);\n const reviewNamespace = this.service.configRef.namespacesEnabled ? resolved.namespace : undefined;\n const includeUnscopedForNamespace = Boolean(\n reviewNamespace && isDefaultReviewNamespace(this.service.configRef.defaultNamespace, namespace, reviewNamespace),\n );\n const result = listPairs(this.service.memoryDir, {\n filter: rawFilter as \"all\" | \"unresolved\" | \"contradicts\" | \"independent\" | \"duplicates\" | \"needs-user\",\n namespace: reviewNamespace,\n includeUnscopedForNamespace,\n limit,\n });\n this.respondJson(res, 200, result);\n return;\n }\n\n if (req.method === \"GET\" && pathname.startsWith(\"/engram/v1/review/contradictions/\")) {\n const pairId = pathname.split(\"/\").pop() ?? \"\";\n const { readPair } = await import(\"./contradiction/contradiction-review.js\");\n const pair = readPair(this.service.memoryDir, pairId);\n if (!pair) {\n this.respondJson(res, 404, { error: \"pair_not_found\" });\n return;\n }\n try {\n await this.service.getReadableStorageForNamespace(pair.namespace, this.resolveRequestPrincipal(req));\n } catch {\n this.respondJson(res, 404, { error: \"pair_not_found\" });\n return;\n }\n this.respondJson(res, 200, pair);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/review/resolve\") {\n const body = await this.readJsonBody(req) as Record<string, unknown>;\n const pairId = typeof body.pairId === \"string\" ? body.pairId : \"\";\n const verb = typeof body.verb === \"string\" ? body.verb : \"\";\n if (!pairId || !verb) {\n this.respondJson(res, 400, { error: \"pairId and verb are required\" });\n return;\n }\n const { isValidResolutionVerb, executeResolution } = await import(\"./contradiction/resolution.js\");\n if (!isValidResolutionVerb(verb)) {\n this.respondJson(res, 400, { error: `Invalid verb: ${verb}. Must be one of: keep-a, keep-b, merge, both-valid, needs-more-context` });\n return;\n }\n const principal = this.resolveRequestPrincipal(req);\n const result = await executeResolution(this.service.memoryDir, this.service.storageRef, pairId, verb, {\n mergedMemoryId: typeof body.mergedMemoryId === \"string\" ? body.mergedMemoryId : undefined,\n mergedContent: typeof body.mergedContent === \"string\" ? body.mergedContent : undefined,\n storageForNamespace: async (namespace) => {\n const resolved = await this.service.getWritableStorageForNamespace(namespace, principal);\n return resolved.storage;\n },\n });\n this.respondJson(res, 200, result);\n return;\n }\n\n // Graph snapshot (issue #691 PR 2/5) — read-only adjacency view used by\n // the admin-pane scaffold shipped in PR 1/5. All filters are query\n // params so the surface stays cacheable; invalid values yield 400 with\n // a descriptive body (CLAUDE.md rule 51 — never silently default).\n if (req.method === \"GET\" && pathname === \"/engram/v1/graph/snapshot\") {\n const limitRaw = parsed.searchParams.get(\"limit\");\n let limit: number | undefined;\n if (limitRaw !== null && limitRaw.length > 0) {\n const parsedLimit = Number(limitRaw);\n if (\n !Number.isFinite(parsedLimit)\n || !Number.isInteger(parsedLimit)\n || parsedLimit <= 0\n ) {\n this.respondJson(res, 400, {\n error: \"invalid_limit\",\n code: \"invalid_limit\",\n message: \"limit must be a positive integer\",\n });\n return;\n }\n limit = parsedLimit;\n }\n const sinceRaw = parsed.searchParams.get(\"since\");\n let since: string | undefined;\n if (sinceRaw !== null && sinceRaw.length > 0) {\n // Validate up-front so the access service can stay focused on the\n // pure snapshot logic (parser also runs there as a defense in\n // depth, but rejecting at the boundary preserves the\n // \"invalid_since\" error code instead of leaking a generic 500).\n if (!Number.isFinite(Date.parse(sinceRaw))) {\n this.respondJson(res, 400, {\n error: \"invalid_since\",\n code: \"invalid_since\",\n message: \"since must be a parseable ISO timestamp\",\n });\n return;\n }\n since = sinceRaw;\n }\n const focusNodeIdRaw = parsed.searchParams.get(\"focusNodeId\");\n const focusNodeId = focusNodeIdRaw && focusNodeIdRaw.length > 0\n ? focusNodeIdRaw\n : undefined;\n const categoriesRaw = parsed.searchParams.get(\"categories\");\n let categories: string[] | undefined;\n if (categoriesRaw !== null && categoriesRaw.length > 0) {\n categories = categoriesRaw\n .split(\",\")\n .map((value) => value.trim())\n .filter((value) => value.length > 0);\n if (categories.length === 0) {\n this.respondJson(res, 400, {\n error: \"invalid_categories\",\n code: \"invalid_categories\",\n message:\n \"categories must be a comma-separated list with at least one non-empty value\",\n });\n return;\n }\n }\n const namespaceParam = parsed.searchParams.get(\"namespace\");\n const namespace = this.resolveNamespace(\n req,\n namespaceParam && namespaceParam.length > 0 ? namespaceParam : undefined,\n );\n try {\n const snapshot = await this.service.graphSnapshot(\n {\n namespace,\n ...(limit !== undefined ? { limit } : {}),\n ...(since !== undefined ? { since } : {}),\n ...(focusNodeId !== undefined ? { focusNodeId } : {}),\n ...(categories !== undefined ? { categories } : {}),\n },\n this.resolveRequestPrincipal(req),\n );\n this.respondJson(res, 200, snapshot);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (message.startsWith(\"graphSnapshot:\")) {\n this.respondJson(res, 400, {\n error: \"invalid_request\",\n code: \"invalid_request\",\n message,\n });\n return;\n }\n throw err;\n }\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/contradiction-scan\") {\n const body = await this.readJsonBody(req) as Record<string, unknown>;\n const { runContradictionScan } = await import(\"./contradiction/contradiction-scan.js\");\n const principal = this.resolveRequestPrincipal(req);\n const result = await runContradictionScan({\n storage: this.service.storageRef,\n config: this.service.configRef,\n memoryDir: this.service.memoryDir,\n embeddingLookupFactory: this.service.embeddingLookupFactoryRef,\n storageForNamespace: (namespace) =>\n this.service.getWritableStorageForNamespace(namespace, principal),\n localLlm: this.service.localLlmRef,\n fallbackLlm: this.service.fallbackLlmRef,\n namespace: typeof body.namespace === \"string\" ? body.namespace : undefined,\n });\n this.respondJson(res, 200, result);\n return;\n }\n\n // ── Graph mutation event stream (issue #691 PR 5/5) ──────────────────────\n //\n // GET /engram/v1/graph/events\n //\n // Server-Sent Events stream that emits graph mutation events in real time.\n // Event types: node-added, node-updated, edge-added, edge-updated, edge-removed.\n //\n // Auth: same Bearer token scheme as every other endpoint (checked above).\n //\n // The SSE handler subscribes to the in-process graph event bus for the\n // resolved memory dir. Events are batched within a 200 ms window so a\n // burst of writes (e.g. extraction of a large turn) doesn't overwhelm\n // the admin UI canvas with individual re-renders.\n //\n // The client receives a `data: <json>\\n\\n` line per batch. Each batch\n // payload is { events: GraphEvent[] }.\n //\n // The stream sends a heartbeat `data: {\"type\":\"heartbeat\"}\\n\\n` every\n // 25 s so load balancers and proxies don't time out idle connections.\n if (req.method === \"GET\" && pathname === \"/engram/v1/graph/events\") {\n await this.handleGraphEventsSSE(req, res);\n return;\n }\n\n // ── Peer Registry endpoints (issue #679) ─────────────────────────────────\n // GET /engram/v1/console/state — operator console engine-state snapshot (issue #688 PR 2/3).\n // Read-only; namespace-aware via resolveRequestPrincipal so cross-tenant\n // reads are not possible (CLAUDE.md rule 42).\n if (req.method === \"GET\" && pathname === \"/engram/v1/console/state\") {\n const namespace = parsed.searchParams.get(\"namespace\") ?? undefined;\n const snapshot = await this.service.consoleState(namespace, this.resolveRequestPrincipal(req));\n this.respondJson(res, 200, snapshot);\n return;\n }\n\n // GET /engram/v1/peers — list all peers\n // GET /engram/v1/peers/:id — get one peer\n // PUT /engram/v1/peers/:id — upsert (create/update)\n // DELETE /engram/v1/peers/:id — delete identity only (idempotent)\n // DELETE /engram/v1/peers/:id?forget=true — destructive full purge (issue #679 completion)\n // GET /engram/v1/peers/:id/profile — get peer profile\n if (req.method === \"GET\" && pathname === \"/engram/v1/peers\") {\n const result = await this.service.peerList();\n this.respondJson(res, 200, result);\n return;\n }\n\n const peerProfileMatch = /^\\/engram\\/v1\\/peers\\/([^/]+)\\/profile$/.exec(pathname);\n if (peerProfileMatch) {\n if (req.method !== \"GET\") {\n this.respondJson(res, 405, { error: \"method_not_allowed\", code: \"method_not_allowed\" });\n return;\n }\n const peerId = decodePeerIdSegment(peerProfileMatch[1] ?? \"\");\n const result = await this.service.peerProfileGet(peerId);\n if (!result.found) {\n this.respondJson(res, 404, { error: \"peer_profile_not_found\", code: \"peer_profile_not_found\" });\n return;\n }\n this.respondJson(res, 200, result);\n return;\n }\n\n const peerIdMatch = /^\\/engram\\/v1\\/peers\\/([^/]+)$/.exec(pathname);\n if (peerIdMatch) {\n const peerId = decodePeerIdSegment(peerIdMatch[1] ?? \"\");\n\n if (req.method === \"GET\") {\n const result = await this.service.peerGet(peerId);\n if (!result.found) {\n this.respondJson(res, 404, { error: \"peer_not_found\", code: \"peer_not_found\" });\n return;\n }\n this.respondJson(res, 200, result);\n return;\n }\n\n if (req.method === \"PUT\") {\n const body = await this.readJsonBody(req) as Record<string, unknown>;\n // Reject malformed types up front rather than silently dropping them\n // to undefined and letting peerSet fall back to defaults\n // (CLAUDE.md rule 51: no silent defaults on bad input).\n if (\"kind\" in body && body.kind !== undefined && typeof body.kind !== \"string\") {\n throw new EngramAccessInputError(\"kind must be a string when provided\");\n }\n if (\n \"displayName\" in body &&\n body.displayName !== undefined &&\n typeof body.displayName !== \"string\"\n ) {\n throw new EngramAccessInputError(\"displayName must be a string when provided\");\n }\n if (\"notes\" in body && body.notes !== undefined && typeof body.notes !== \"string\") {\n throw new EngramAccessInputError(\"notes must be a string when provided\");\n }\n const result = await this.service.peerSet({\n id: peerId,\n kind: typeof body.kind === \"string\" ? body.kind : undefined,\n displayName: typeof body.displayName === \"string\" ? body.displayName : undefined,\n notes: typeof body.notes === \"string\" ? body.notes : undefined,\n });\n this.respondJson(res, result.created ? 201 : 200, result);\n return;\n }\n\n if (req.method === \"DELETE\") {\n // `?forget=true` triggers the destructive full-purge path (issue #679\n // completion). The caller must also pass `confirm=yes` in the request\n // body; absent confirmation yields 400. Plain DELETE (no ?forget) keeps\n // the existing soft-delete behaviour (identity.md only).\n const forgetParam = parsed.searchParams.get(\"forget\");\n if (forgetParam === \"true\") {\n const body = await this.readJsonBody(req) as Record<string, unknown>;\n const confirm = typeof body.confirm === \"string\" ? body.confirm : \"\";\n if (confirm !== \"yes\") {\n this.respondJson(res, 400, {\n error: \"confirm_required\",\n code: \"confirm_required\",\n message: \"DELETE ?forget=true requires { confirm: 'yes' } in the request body\",\n });\n return;\n }\n const result = await this.service.peerForget(peerId, { confirm: \"yes\" });\n this.respondJson(res, 200, result);\n return;\n }\n const result = await this.service.peerDelete(peerId);\n this.respondJson(res, 200, result);\n return;\n }\n\n this.respondJson(res, 405, { error: \"method_not_allowed\", code: \"method_not_allowed\" });\n return;\n }\n\n // ── Dreams telemetry (issue #678 PR 3+4) ──────────────────────────────────\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/dreams/status\") {\n const { normalizeDreamsStatusWindowHours } = await import(\"./maintenance/dreams-ledger.js\");\n const windowHoursRaw = parsed.searchParams.get(\"windowHours\");\n let windowHours: number;\n try {\n windowHours = normalizeDreamsStatusWindowHours(\n windowHoursRaw !== null ? Number(windowHoursRaw) : undefined,\n );\n } catch {\n this.respondJson(res, 400, { error: \"windowHours must be a positive integer\" });\n return;\n }\n const namespaceParam = parsed.searchParams.get(\"namespace\");\n const namespace = namespaceParam && namespaceParam.length > 0 ? namespaceParam : undefined;\n const result = await this.service.dreamsStatus({\n windowHours,\n namespace,\n principal: this.resolveRequestPrincipal(req),\n });\n this.respondJson(res, 200, result);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/dreams/run\") {\n const body = await this.readJsonBody(req) as Record<string, unknown>;\n const VALID_PHASES = [\"lightSleep\", \"rem\", \"deepSleep\"] as const;\n const phase = typeof body.phase === \"string\" ? body.phase : undefined;\n if (!phase || !(VALID_PHASES as readonly string[]).includes(phase)) {\n this.respondJson(res, 400, {\n error: `phase is required and must be one of: ${VALID_PHASES.join(\", \")}`,\n });\n return;\n }\n if (\n \"dryRun\" in body &&\n body.dryRun !== undefined &&\n typeof body.dryRun !== \"boolean\"\n ) {\n this.respondJson(res, 400, {\n error: \"dryRun must be a boolean when provided\",\n });\n return;\n }\n if (\n \"namespace\" in body &&\n body.namespace !== undefined &&\n typeof body.namespace !== \"string\"\n ) {\n this.respondJson(res, 400, {\n error: \"namespace must be a string when provided\",\n });\n return;\n }\n const dryRun = body.dryRun === true;\n const namespace =\n typeof body.namespace === \"string\" ? body.namespace : undefined;\n if (!dryRun) {\n this.ensureWriteRateLimitAvailable();\n }\n const result = await this.service.dreamsRun({\n phase: phase as import(\"./types.js\").DreamsPhase,\n dryRun,\n namespace,\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n });\n if (this.shouldCountWriteRateLimit(result as { dryRun?: boolean; idempotencyReplay?: boolean })) {\n this.recordWriteRateLimitHit();\n }\n this.respondJson(res, 200, result);\n return;\n }\n\n this.respondJson(res, 404, { error: \"not_found\", code: \"not_found\" });\n }\n\n private createRequestAbortSignal(req: IncomingMessage, res: ServerResponse): AbortSignal {\n const controller = new AbortController();\n const abort = () => {\n if (!controller.signal.aborted) controller.abort();\n };\n req.once(\"aborted\", abort);\n res.once(\"close\", () => {\n if (!res.writableEnded) abort();\n });\n return controller.signal;\n }\n\n /**\n * SSE handler for /engram/v1/graph/events.\n *\n * Lifecycle:\n * 1. Write SSE headers (Content-Type: text/event-stream).\n * 2. Register this response in `sseClients`.\n * 3. Resolve the namespace from the request and subscribe to THAT\n * namespace's graph event bus (Codex P1: in multi-namespace\n * deployments each namespace has its own bus keyed by its storage\n * dir — subscribing to the global root leaks events across tenants).\n * 4. On each event, add to a 200 ms batch; flush batch as a single SSE frame.\n * 5. Send heartbeat every 25 s.\n * 6. On client disconnect (req \"close\"), clean up timers and unsubscribe.\n * 7. Register the cleanup callback in `sseCleanupFns` so `stop()` can\n * release the heartbeat interval and bus subscription even when the\n * client never disconnects (Cursor review thread `access-http.ts:232`).\n */\n private async handleGraphEventsSSE(req: IncomingMessage, res: ServerResponse): Promise<void> {\n // Resolve namespace from the ?namespace= query parameter (same pattern\n // as graphSnapshot and other read endpoints). Falls back to the\n // default namespace when absent.\n const parsed = new URL(req.url ?? \"/\", `http://${hostToUrlAuthority(this.host)}`);\n const namespaceParam = parsed.searchParams.get(\"namespace\");\n const namespace = namespaceParam && namespaceParam.length > 0 ? namespaceParam : undefined;\n // Resolve to the per-namespace storage directory so the bus subscription\n // is scoped to the correct tenant (CLAUDE.md rule 42).\n // Pass the request principal so namespace ACL is enforced — without it,\n // resolveReadableNamespace throws when namespacesEnabled=true (Cursor\n // thread PRRT_kwDORJXyws59snoR / Codex thread PRRT_kwDORJXyws59soGJ).\n const principal = this.resolveRequestPrincipal(req);\n const memoryDir = await this.service.getMemoryDirForNamespace(namespace, principal);\n\n res.writeHead(200, {\n \"content-type\": \"text/event-stream; charset=utf-8\",\n \"cache-control\": \"no-cache, no-store, must-revalidate\",\n \"connection\": \"keep-alive\",\n \"x-accel-buffering\": \"no\", // prevent nginx buffering\n \"transfer-encoding\": \"chunked\",\n });\n\n // Send initial \"connected\" frame so the client knows the stream is live.\n const writeSSE = (payload: unknown): void => {\n try {\n res.write(`data: ${JSON.stringify(payload)}\\n\\n`);\n } catch {\n // client already gone — cleanup will fire via \"close\"\n }\n };\n\n writeSSE({ type: \"connected\" });\n\n this.sseClients.add(res);\n\n // --- 200 ms batch throttle -----------------------------------------------\n const flushBatch = (): void => {\n const batch = this.ssePendingBatches.get(res);\n if (!batch || batch.length === 0) return;\n this.ssePendingBatches.delete(res);\n this.sseBatchTimers.delete(res);\n writeSSE({ type: \"batch\", events: batch });\n };\n\n const unsubscribe = subscribeGraphEvents(memoryDir, (event: GraphEvent) => {\n let batch = this.ssePendingBatches.get(res);\n if (!batch) {\n batch = [];\n this.ssePendingBatches.set(res, batch);\n }\n batch.push(event);\n if (!this.sseBatchTimers.has(res)) {\n this.sseBatchTimers.set(res, setTimeout(flushBatch, 200));\n }\n });\n\n // --- 25 s heartbeat -------------------------------------------------------\n const heartbeatInterval = setInterval(() => {\n writeSSE({ type: \"heartbeat\" });\n }, 25_000);\n\n // --- Cleanup on client disconnect -----------------------------------------\n const cleanup = (): void => {\n clearInterval(heartbeatInterval);\n const timer = this.sseBatchTimers.get(res);\n if (timer !== undefined) {\n clearTimeout(timer);\n this.sseBatchTimers.delete(res);\n }\n this.ssePendingBatches.delete(res);\n unsubscribe();\n this.sseClients.delete(res);\n this.sseCleanupFns.delete(cleanup);\n try { res.end(); } catch { /* ignore */ }\n };\n\n // Register so stop() can invoke cleanup even when the client is still\n // connected (releases the heartbeat interval and bus subscription\n // before the HTTP server is torn down).\n this.sseCleanupFns.add(cleanup);\n\n req.once(\"close\", cleanup);\n req.once(\"error\", cleanup);\n }\n\n private async handleMcpRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const body = await this.readJsonBody(req);\n const request = body as {\n jsonrpc?: string;\n id?: string | number | null;\n method?: string;\n params?: Record<string, unknown>;\n };\n\n // Enforce write rate limiting for MCP tool calls that mutate state,\n // matching the same protection applied to the REST write endpoints.\n // Pre-check ensures capacity; post-check skips counting dry runs and\n // idempotency replays, consistent with the REST handlers.\n const toolName = typeof request.params?.name === \"string\" ? request.params.name : \"\";\n const toolArgs = request.params?.arguments;\n const dreamsRunDryRun =\n (toolName === \"engram.dreams_run\" || toolName === \"remnic.dreams_run\") &&\n toolArgs !== null &&\n typeof toolArgs === \"object\" &&\n !Array.isArray(toolArgs) &&\n (toolArgs as { dryRun?: unknown }).dryRun === true;\n const memoryActionApplyDryRun =\n (toolName === \"engram.memory_action_apply\" || toolName === \"remnic.memory_action_apply\") &&\n toolArgs !== null &&\n typeof toolArgs === \"object\" &&\n !Array.isArray(toolArgs) &&\n (toolArgs as { dryRun?: unknown }).dryRun === true;\n const isMcpWrite =\n request.method === \"tools/call\" &&\n (\n toolName === \"engram.memory_store\" ||\n toolName === \"remnic.memory_store\" ||\n toolName === \"engram.suggestion_submit\" ||\n toolName === \"remnic.suggestion_submit\" ||\n toolName === \"engram.observe\" ||\n toolName === \"remnic.observe\" ||\n toolName === \"engram.lcm_compaction_flush\" ||\n toolName === \"remnic.lcm_compaction_flush\" ||\n toolName === \"engram.lcm_compaction_record\" ||\n toolName === \"remnic.lcm_compaction_record\" ||\n toolName === \"engram.capsule_export\" ||\n toolName === \"remnic.capsule_export\" ||\n toolName === \"engram.capsule_import\" ||\n toolName === \"remnic.capsule_import\" ||\n (\n !dreamsRunDryRun &&\n (toolName === \"engram.dreams_run\" || toolName === \"remnic.dreams_run\")\n ) ||\n (\n !memoryActionApplyDryRun &&\n (\n toolName === \"engram.memory_action_apply\" ||\n toolName === \"remnic.memory_action_apply\"\n )\n )\n );\n if (isMcpWrite) {\n this.ensureWriteRateLimitAvailable();\n }\n\n const sessionId = (() => {\n const raw = req.headers[\"mcp-session-id\"];\n return typeof raw === \"string\" ? raw.trim() : undefined;\n })();\n const mcpCorrelationId = correlationIdStore.getStore() ?? randomUUID();\n const requestIdentity = this.resolveRequestIdentity(req);\n const response = await this.mcpServer.handleRequest(request, {\n principalOverride: requestIdentity.principal,\n namespaceOverride: requestIdentity.namespace,\n sessionKeyOverride: requestIdentity.sessionKey,\n sessionId,\n correlationId: mcpCorrelationId,\n });\n\n if (isMcpWrite && response !== null) {\n const result = (response as Record<string, unknown>).result as Record<string, unknown> | undefined;\n const isError = result?.isError === true;\n const structured = result?.structuredContent as { dryRun?: boolean; idempotencyReplay?: boolean } | undefined;\n if (!isError && structured && this.shouldCountWriteRateLimit(structured)) {\n this.recordWriteRateLimitHit();\n }\n }\n if (response === null) {\n res.statusCode = 202;\n res.end();\n return;\n }\n // If this was an initialize response, pop the session ID keyed by\n // correlation ID (unique per HTTP request, not client-chosen JSON-RPC id).\n const assignedSessionId = this.mcpServer.popInitSessionId(mcpCorrelationId);\n if (assignedSessionId) {\n res.setHeader(\"mcp-session-id\", assignedSessionId);\n }\n this.respondJson(res, 200, response);\n }\n\n private respondJson(res: ServerResponse, status: number, payload: unknown): void {\n const body = JSON.stringify(payload, null, 2);\n res.statusCode = status;\n res.setHeader(\"content-type\", \"application/json; charset=utf-8\");\n res.setHeader(\"content-length\", String(Buffer.byteLength(body)));\n const cid = correlationIdStore.getStore();\n if (cid) {\n res.setHeader(\"x-request-id\", cid);\n }\n res.end(body);\n }\n\n private async respondOfflineSnapshotStream(\n res: ServerResponse,\n snapshot: Awaited<ReturnType<EngramAccessService[\"offlineSyncSnapshotStream\"]>>,\n ): Promise<void> {\n res.statusCode = 200;\n res.setHeader(\"content-type\", \"application/x-ndjson; charset=utf-8\");\n res.setHeader(\"cache-control\", \"no-store\");\n const cid = correlationIdStore.getStore();\n if (cid) {\n res.setHeader(\"x-request-id\", cid);\n }\n const waitForDrainOrClose = async (): Promise<boolean> => new Promise((resolve, reject) => {\n const cleanup = () => {\n res.off(\"drain\", onDrain);\n res.off(\"close\", onClose);\n res.off(\"error\", onError);\n };\n const onDrain = () => {\n cleanup();\n resolve(true);\n };\n const onClose = () => {\n cleanup();\n resolve(false);\n };\n const onError = (error: Error) => {\n cleanup();\n reject(error);\n };\n res.once(\"drain\", onDrain);\n res.once(\"close\", onClose);\n res.once(\"error\", onError);\n });\n const writeLine = async (payload: unknown): Promise<boolean> => {\n if (res.destroyed || res.writableEnded) return false;\n if (res.write(`${JSON.stringify(payload)}\\n`)) return true;\n if (res.destroyed || res.writableEnded) return false;\n return waitForDrainOrClose();\n };\n if (!await writeLine({\n type: \"snapshot\",\n namespace: snapshot.namespace,\n format: snapshot.format,\n schemaVersion: snapshot.schemaVersion,\n createdAt: snapshot.createdAt,\n sourceId: snapshot.sourceId,\n includeTranscripts: snapshot.includeTranscripts,\n })) return;\n for await (const file of snapshot.files) {\n if (!await writeLine({ type: \"file\", file })) return;\n }\n if (!res.destroyed && !res.writableEnded) {\n res.end();\n }\n }\n\n private respondBinary(\n res: ServerResponse,\n status: number,\n body: Buffer,\n headers: Record<string, string> = {},\n ): void {\n res.statusCode = status;\n res.setHeader(\"content-type\", \"application/octet-stream\");\n res.setHeader(\"content-length\", String(body.length));\n for (const [key, value] of Object.entries(headers)) {\n res.setHeader(key, value);\n }\n const cid = correlationIdStore.getStore();\n if (cid) {\n res.setHeader(\"x-request-id\", cid);\n }\n res.end(body);\n }\n\n private async handleAdminConsole(\n req: IncomingMessage,\n res: ServerResponse,\n pathname: string,\n ): Promise<boolean> {\n if (req.method !== \"GET\") return false;\n if (pathname === \"/remnic/ui\" || pathname === \"/engram/ui\") {\n res.statusCode = 301;\n res.setHeader(\"location\", pathname + \"/\");\n res.end();\n return true;\n }\n if (pathname === \"/remnic/ui/\" || pathname === \"/engram/ui/\") {\n await this.respondStatic(res, path.join(this.adminConsolePublicDir, \"index.html\"), \"text/html; charset=utf-8\");\n return true;\n }\n if (pathname === \"/remnic/ui/app.js\" || pathname === \"/engram/ui/app.js\") {\n await this.respondStatic(res, path.join(this.adminConsolePublicDir, \"app.js\"), \"application/javascript; charset=utf-8\");\n return true;\n }\n return false;\n }\n\n private async respondStatic(res: ServerResponse, filePath: string, contentType: string): Promise<void> {\n try {\n const body = await readFile(filePath, \"utf-8\");\n res.statusCode = 200;\n res.setHeader(\"content-type\", contentType);\n res.setHeader(\"content-length\", String(Buffer.byteLength(body)));\n res.end(body);\n } catch {\n this.respondJson(res, 404, { error: \"not_found\" });\n }\n }\n\n private async readJsonBody(\n req: IncomingMessage,\n maxBodyBytes = this.maxBodyBytes,\n ): Promise<Record<string, unknown>> {\n const encoding = (this.readOptionalHeader(req, \"content-encoding\") ?? \"identity\").toLowerCase();\n if (encoding !== \"identity\" && encoding !== \"gzip\") {\n throw new HttpError(415, \"unsupported_content_encoding\", \"unsupported_content_encoding\");\n }\n const chunks: Buffer[] = [];\n let total = 0;\n for await (const chunk of req) {\n const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n total += buffer.length;\n if (total > maxBodyBytes) {\n throw new HttpError(413, \"request_body_too_large\", \"request_body_too_large\");\n }\n chunks.push(buffer);\n }\n if (chunks.length === 0) return {};\n let body = Buffer.concat(chunks, total);\n if (encoding === \"gzip\") {\n try {\n body = gunzipSync(body, { maxOutputLength: maxBodyBytes });\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ERR_BUFFER_TOO_LARGE\") {\n throw new HttpError(413, \"request_body_too_large\", \"request_body_too_large\");\n }\n throw new HttpError(400, \"invalid_gzip_body\", \"invalid_gzip_body\");\n }\n if (body.byteLength > maxBodyBytes) {\n throw new HttpError(413, \"request_body_too_large\", \"request_body_too_large\");\n }\n }\n const raw = body.toString(\"utf-8\").trim();\n if (raw.length === 0) return {};\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw new HttpError(400, \"invalid_json\", \"invalid_json\");\n }\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new HttpError(400, \"invalid_json_object\", \"invalid_json_object\");\n }\n return parsed as Record<string, unknown>;\n }\n\n private async readBinaryBody(req: IncomingMessage, maxBytes: number): Promise<Buffer> {\n const chunks: Buffer[] = [];\n let total = 0;\n for await (const chunk of req) {\n const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n total += buffer.length;\n if (total > maxBytes) {\n throw new HttpError(413, \"request_body_too_large\", \"request_body_too_large\");\n }\n chunks.push(buffer);\n }\n return Buffer.concat(chunks, total);\n }\n\n private readRequiredHeader(req: IncomingMessage, name: string): string {\n const value = this.readOptionalHeader(req, name);\n if (value === undefined || value.length === 0) {\n throw new EngramAccessInputError(`${name} header is required`);\n }\n return value;\n }\n\n private readOptionalHeader(req: IncomingMessage, name: string): string | undefined {\n const raw = req.headers[name.toLowerCase()];\n if (Array.isArray(raw)) return raw[0]?.trim() || undefined;\n return raw?.trim() || undefined;\n }\n\n private readRequiredDecodedHeader(req: IncomingMessage, name: string): string {\n const raw = this.readRequiredHeader(req, name);\n try {\n return decodeURIComponent(raw);\n } catch {\n throw new EngramAccessInputError(`${name} header is not valid percent-encoded input`);\n }\n }\n\n private readRequiredIntegerHeader(req: IncomingMessage, name: string): number {\n const raw = this.readRequiredHeader(req, name);\n const parsed = Number(raw);\n if (!Number.isInteger(parsed) || parsed < 0) {\n throw new EngramAccessInputError(`${name} header must be a non-negative integer`);\n }\n return parsed;\n }\n\n private readOptionalIntegerHeader(req: IncomingMessage, name: string): number | undefined {\n const raw = this.readOptionalHeader(req, name);\n if (raw === undefined) return undefined;\n const parsed = Number(raw);\n if (!Number.isInteger(parsed) || parsed < 0) {\n throw new EngramAccessInputError(`${name} header must be a non-negative integer`);\n }\n return parsed;\n }\n\n private readRequiredNumberHeader(req: IncomingMessage, name: string): number {\n const raw = this.readRequiredHeader(req, name);\n const parsed = Number(raw);\n if (!Number.isFinite(parsed) || parsed < 0) {\n throw new EngramAccessInputError(`${name} header must be a non-negative finite number`);\n }\n return parsed;\n }\n\n private parseOptionalBooleanHeader(\n req: IncomingMessage,\n name: string,\n defaultValue: boolean,\n ): boolean {\n const raw = this.readOptionalHeader(req, name);\n if (raw === undefined) return defaultValue;\n if (raw === \"true\") return true;\n if (raw === \"false\") return false;\n throw new EngramAccessInputError(`${name} header must be one of: true, false`);\n }\n\n private async readValidatedBody<S extends SchemaName>(\n req: IncomingMessage,\n schemaName: S,\n maxBodyBytes?: number,\n ): Promise<SchemaTypeFor<S>> {\n const raw = await this.readJsonBody(req, maxBodyBytes);\n const result = validateRequest(schemaName, raw);\n if (!result.success) {\n throw new HttpError(400, result.error.error, \"validation_error\", result.error.details);\n }\n return result.data as SchemaTypeFor<S>;\n }\n\n private isAuthorized(req: IncomingMessage, pathname?: string): boolean {\n if (!this.authToken && this.authTokens.length === 0 && !this.authTokensGetter) return false;\n // Primary path: Authorization: Bearer <token> header.\n const raw = req.headers.authorization;\n let candidate: string | null = null;\n if (raw) {\n const separator = raw.indexOf(\" \");\n if (separator > 0) {\n const scheme = raw.slice(0, separator).toLowerCase();\n if (scheme === \"bearer\") {\n candidate = raw.slice(separator + 1).trim();\n }\n }\n }\n // Fallback: ?token= query parameter — ONLY accepted for the SSE\n // endpoint (/engram/v1/graph/events). EventSource cannot set request\n // headers, so SSE clients must pass the token via the query string.\n // Allowing this fallback on every endpoint would let a CSRF attacker\n // embed a credentialed URL anywhere — restricting it to SSE limits the\n // attack surface (Codex P2 review thread `access-http.ts:1406`; Cursor\n // review thread `access-http.ts:1412`). Authorization header always\n // wins; timing-safe compare used below.\n if (!candidate && pathname === \"/engram/v1/graph/events\") {\n try {\n const parsed = new URL(req.url ?? \"/\", `http://${hostToUrlAuthority(this.host)}`);\n const queryToken = parsed.searchParams.get(\"token\");\n if (queryToken && queryToken.length > 0) {\n candidate = queryToken;\n }\n } catch {\n // Malformed URL — don't authenticate\n }\n }\n if (!candidate) return false;\n const token = candidate;\n // Check primary token\n if (this.authToken && this.timingSafeStringEqual(token, this.authToken)) return true;\n // Check static multi-connector tokens\n for (const valid of this.authTokens) {\n if (this.timingSafeStringEqual(token, valid)) return true;\n }\n // Check dynamic tokens (reloaded per request for generate/revoke without restart)\n if (this.authTokensGetter) {\n for (const valid of this.authTokensGetter()) {\n if (this.timingSafeStringEqual(token, valid)) return true;\n }\n }\n return false;\n }\n\n private timingSafeStringEqual(a: string, b: string): boolean {\n const left = this.encodeSecret(a);\n const right = this.encodeSecret(b);\n if (!left || !right) return false;\n return timingSafeEqual(left, right);\n }\n\n private encodeSecret(value: string): Buffer | null {\n const encoded = Buffer.from(value, \"utf-8\");\n if (encoded.length > 1024) return null;\n const out = Buffer.alloc(2 + 1024);\n out.writeUInt16BE(encoded.length, 0);\n encoded.copy(out, 2);\n return out;\n }\n\n private writeResponseStatus(response: { dryRun: boolean; status: string }): number {\n if (response.dryRun === true) return 200;\n if (response.status === \"stored\" || response.status === \"queued_for_review\") return 201;\n return 200;\n }\n\n private ensureWriteRateLimitAvailable(): void {\n const now = Date.now();\n while (\n this.writeRequestTimestamps.length > 0 &&\n now - (this.writeRequestTimestamps[0] ?? 0) > WRITE_RATE_LIMIT_WINDOW_MS\n ) {\n this.writeRequestTimestamps.shift();\n }\n if (this.writeRequestTimestamps.length >= WRITE_RATE_LIMIT_MAX_REQUESTS) {\n throw new HttpError(429, \"write_rate_limited\", \"write_rate_limited\");\n }\n }\n\n private recordWriteRateLimitHit(): void {\n this.writeRequestTimestamps.push(Date.now());\n }\n\n private shouldCountWriteRateLimit(response: { dryRun?: boolean; idempotencyReplay?: boolean }): boolean {\n return response.dryRun !== true && response.idempotencyReplay !== true;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,oBAA4E;AACrF,SAAS,YAAY,uBAAuB;AAC5C,SAAS,yBAAyB;AAClC,SAAS,kBAAkB;AAC3B,SAAS,gBAAgB;AACzB,OAAO,UAAU;AACjB,SAAS,eAAe,WAAW;AACnC,SAAS,kBAAkB;AAuD3B,SAAS,sCAA8C;AACrD,QAAM,UAAU,KAAK,QAAQ,cAAc,YAAY,GAAG,CAAC;AAC3D,QAAM,aAAa;AAAA;AAAA,IAEjB,KAAK,QAAQ,SAAS,yBAAyB;AAAA;AAAA,IAE/C,KAAK,QAAQ,SAAS,wBAAwB;AAAA;AAAA,IAE9C,KAAK,QAAQ,SAAS,4BAA4B;AAAA,EACpD;AACA,SAAO,WAAW,KAAK,CAAC,cAAc,WAAW,SAAS,CAAC,KAAK,WAAW,CAAC;AAC9E;AAEA,IAAM,+BAA+B,oCAAoC;AACzE,IAAM,qBAAqB,IAAI,kBAA0B;AAEzD,IAAM,6BAA6B;AACnC,IAAM,gCAAgC;AACtC,IAAM,0BAA0B,CAAC,UAAU,YAAY,SAAS,cAAc,UAAU;AACxF,IAAM,4BAA4B,CAAC,eAAe,eAAe,kBAAkB,iBAAiB,cAAc,QAAQ;AAE1H,IAAM,YAAN,cAAwB,MAAM;AAAA,EAG5B,YAAqB,QAAgB,SAAiB,MAAe,SAAmB;AACtF,UAAM,OAAO;AADM;AAEnB,SAAK,OAAO,QAAQ,QAAQ,MAAM;AAClC,SAAK,UAAU;AAAA,EACjB;AAAA,EAJqB;AAAA,EAFZ;AAAA,EACA;AAMX;AAEA,SAAS,mBAAmB,MAAsB;AAChD,MAAI,KAAK,SAAS,GAAG,KAAK,CAAC,KAAK,WAAW,GAAG,KAAK,CAAC,KAAK,SAAS,GAAG,GAAG;AACtE,WAAO,IAAI,IAAI;AAAA,EACjB;AACA,SAAO;AACT;AAEA,SAAS,oBAAoB,MAAkC;AAC7D,MAAI,SAAS,OAAW,QAAO;AAC/B,MAAI,CAAC,OAAO,UAAU,IAAI,KAAK,OAAO,KAAK,OAAO,OAAO;AACvD,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACvE;AACA,SAAO;AACT;AAEA,SAAS,yBAAyB,KAAqD;AACrF,MAAI,QAAQ,KAAM,QAAO;AACzB,MAAK,wBAA8C,SAAS,GAAG,GAAG;AAChE,WAAO;AAAA,EACT;AACA,QAAM,IAAI,UAAU,KAAK,uBAAuB,wBAAwB,KAAK,GAAG,CAAC,IAAI,qBAAqB;AAC5G;AAEA,SAAS,gCAAgC,KAAsD;AAC7F,MAAI,QAAQ,KAAM,QAAO;AACzB,MAAK,0BAAgD,SAAS,GAAG,GAAG;AAClE,WAAO;AAAA,EACT;AACA,QAAM,IAAI,UAAU,KAAK,8BAA8B,0BAA0B,KAAK,GAAG,CAAC,IAAI,6BAA6B;AAC7H;AAEA,SAAS,qBAAqB,KAA+C;AAC3E,MAAI,QAAQ,KAAM,QAAO;AACzB,MAAI,gBAAgB,GAAG,GAAG;AACxB,WAAO;AAAA,EACT;AACA,QAAM,IAAI,UAAU,KAAK,kDAAkD,qBAAqB;AAClG;AAEA,SAAS,qBAAqB,KAA8B;AAC1D,QAAM,SAAS,IAAI,UAAU;AAC7B,MAAI;AACF,UAAM,SAAS,IAAI,IAAI,IAAI,OAAO,KAAK,kBAAkB;AACzD,WAAO,GAAG,MAAM,IAAI,OAAO,QAAQ;AAAA,EACrC,QAAQ;AACN,WAAO,GAAG,MAAM,KAAK,IAAI,OAAO,KAAK,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA,EACpD;AACF;AAEA,SAAS,wBACP,KACA,OACA,cACA,UACQ;AACR,MAAI,QAAQ,KAAM,QAAO;AACzB,MAAI,CAAC,mBAAmB,KAAK,GAAG,GAAG;AACjC,UAAM,IAAI,UAAU,KAAK,GAAG,KAAK,uBAAuB,WAAW,KAAK,EAAE;AAAA,EAC5E;AACA,QAAM,QAAQ,OAAO,GAAG;AACxB,MAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,UAAU;AAChD,UAAM,IAAI,UAAU,KAAK,GAAG,KAAK,0BAA0B,QAAQ,IAAI,WAAW,KAAK,EAAE;AAAA,EAC3F;AACA,SAAO;AACT;AAEA,SAAS,gBAAgB,KAAiG;AACxH,MAAI,QAAQ,KAAM,QAAO;AACzB,MACE,QAAQ,kBACR,QAAQ,iBACR,QAAQ,kBACR,QAAQ,eACR;AACA,WAAO;AAAA,EACT;AACA,QAAM,IAAI,UAAU,KAAK,yEAAyE,cAAc;AAClH;AAOA,SAAS,oBAAoB,KAAqB;AAChD,MAAI;AACF,WAAO,mBAAmB,GAAG;AAAA,EAC/B,QAAQ;AACN,UAAM,IAAI,uBAAuB,wDAAwD;AAAA,EAC3F;AACF;AAEA,SAAS,4BAA4B,YAKnC;AACA,QAAM,YAAY,oBAAoB,UAAU;AAChD,SAAO;AAAA,IACL;AAAA,IACA,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,eAAe;AAAA,EACjB;AACF;AAEO,IAAM,yBAAN,MAA6B;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,yBAAmC,CAAC;AAAA,EACpC;AAAA,EACT,SAAwB;AAAA,EACxB,YAAY;AAAA;AAAA,EAEH,aAAa,oBAAI,IAAoB;AAAA;AAAA,EAErC,iBAAiB,oBAAI,IAAmD;AAAA,EACxE,oBAAoB,oBAAI,IAAkC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO1D,gBAAgB,oBAAI,IAAgB;AAAA,EAErD,YAAY,SAAwC;AAClD,SAAK,UAAU,QAAQ;AACvB,SAAK,OAAO,QAAQ,MAAM,KAAK,KAAK;AACpC,SAAK,gBAAgB,oBAAoB,QAAQ,IAAI;AACrD,SAAK,YAAY,QAAQ,WAAW,KAAK,KAAK;AAC9C,SAAK,cAAc,QAAQ,cAAc,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO;AAChF,SAAK,mBAAmB,QAAQ;AAChC,SAAK,yBAAyB,QAAQ,WAAW,KAAK,KAAK;AAC3D,SAAK,eAAe,OAAO,SAAS,QAAQ,YAAY,IACpD,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,gBAAgB,MAAM,CAAC,IACtD;AACJ,SAAK,sBAAsB,QAAQ,wBAAwB;AAC3D,SAAK,wBAAwB,QAAQ,yBAAyB;AAC9D,SAAK,uBAAuB,QAAQ,yBAAyB;AAC7D,SAAK,kBAAkB,QAAQ,mBAAmB,QAC7C,QAAQ,mBAAmB,IAAI,gBAAgB,IAChD;AACJ,SAAK,YAAY,IAAI,gBAAgB,KAAK,SAAS;AAAA,MACjD,WAAW,QAAQ;AAAA,MACnB,kBAAkB,QAAQ;AAAA,MAC1B,qBAAqB,QAAQ;AAAA,MAC7B,iBAAiB,QAAQ;AAAA,IAC3B,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,QAA+C;AACnD,QAAI,CAAC,KAAK,aAAa,KAAK,WAAW,WAAW,KAAK,CAAC,KAAK,kBAAkB;AAC7E,YAAM,IAAI,MAAM,qDAAqD;AAAA,IACvE;AACA,QAAI,KAAK,OAAQ,QAAO,KAAK,OAAO;AAEpC,UAAM,SAAS,aAAa,CAAC,KAAK,QAAQ;AACxC,YAAM,gBAAgB,WAAW;AACjC,yBAAmB,IAAI,eAAe,MAAM;AAC1C,aAAK,KAAK,OAAO,KAAK,KAAK,aAAa,EAAE,MAAM,CAAC,QAAQ;AACvD,cAAI,MAAM,sCAAsC,aAAa,MAAM,GAAG,EAAE;AACxE,cAAI,eAAe,WAAW;AAC5B,kBAAM,UAAmC,EAAE,OAAO,IAAI,SAAS,MAAM,IAAI,KAAK;AAC9E,gBAAI,IAAI,QAAS,SAAQ,UAAU,IAAI;AACvC,iBAAK,YAAY,KAAK,IAAI,QAAQ,OAAO;AACzC;AAAA,UACF;AACA,cAAI,eAAe,wBAAwB;AACzC,iBAAK,YAAY,KAAK,KAAK,EAAE,OAAO,IAAI,SAAS,MAAM,cAAc,CAAC;AACtE;AAAA,UACF;AACA,cAAI,IAAI,aAAa;AACnB,gBAAI,QAAQ,GAAY;AACxB;AAAA,UACF;AACA,cAAI;AAAA,YACF,sCAAsC,aAAa,KAAK,qBAAqB,GAAG,CAAC;AAAA,YACjF;AAAA,UACF;AACA,eAAK,YAAY,KAAK,KAAK,EAAE,OAAO,kBAAkB,MAAM,iBAAiB,CAAC;AAAA,QAChF,CAAC;AAAA,MACH,CAAC;AAAA,IACH,CAAC;AAED,QAAI;AACF,YAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,cAAM,UAAU,CAAC,QAAe;AAC9B,iBAAO,IAAI,aAAa,WAAW;AACnC,iBAAO,GAAG;AAAA,QACZ;AACA,cAAM,cAAc,MAAM;AACxB,iBAAO,IAAI,SAAS,OAAO;AAC3B,kBAAQ;AAAA,QACV;AACA,eAAO,KAAK,SAAS,OAAO;AAC5B,eAAO,KAAK,aAAa,WAAW;AACpC,eAAO,OAAO,KAAK,eAAe,KAAK,IAAI;AAAA,MAC7C,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,aAAO,MAAM;AACb,YAAM;AAAA,IACR;AAEA,SAAK,SAAS;AACd,UAAM,UAAU,OAAO,QAAQ;AAC/B,SAAK,YAAY,OAAO,YAAY,YAAY,UAAU,QAAQ,OAAO,KAAK;AAC9E,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,MAAM,OAAsB;AAC1B,QAAI,CAAC,KAAK,OAAQ;AAClB,UAAM,SAAS,KAAK;AACpB,SAAK,SAAS;AACd,SAAK,YAAY;AAMjB,eAAW,WAAW,KAAK,eAAe;AACxC,UAAI;AAAE,gBAAQ;AAAA,MAAG,QAAQ;AAAA,MAAe;AAAA,IAC1C;AACA,SAAK,cAAc,MAAM;AAEzB,eAAW,CAAC,KAAK,KAAK,KAAK,KAAK,eAAe,QAAQ,GAAG;AACxD,mBAAa,KAAK;AAClB,WAAK,eAAe,OAAO,GAAG;AAAA,IAChC;AACA,SAAK,kBAAkB,MAAM;AAC7B,eAAW,OAAO,KAAK,YAAY;AACjC,UAAI;AAAE,YAAI,IAAI;AAAA,MAAG,QAAQ;AAAA,MAAe;AAAA,IAC1C;AACA,SAAK,WAAW,MAAM;AACtB,UAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,aAAO,MAAM,CAAC,QAAS,MAAM,OAAO,GAAG,IAAI,QAAQ,CAAE;AAAA,IACvD,CAAC;AAAA,EACH;AAAA,EAEA,SAAuC;AACrC,WAAO;AAAA,MACL,SAAS,KAAK,WAAW;AAAA,MACzB,MAAM,KAAK;AAAA,MACX,MAAM,KAAK;AAAA,MACX,cAAc,KAAK;AAAA,IACrB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,uBAAuB,KAA+C;AACpE,QAAI,CAAC,KAAK,gBAAiB,QAAO;AAIlC,UAAM,aAAa,MAAM;AACvB,YAAM,MAAM,IAAI,QAAQ,gBAAgB;AACxC,aAAO,OAAO,QAAQ,WAAW,IAAI,KAAK,IAAI;AAAA,IAChD,GAAG;AACH,WAAO,KAAK,gBAAgB,QAAQ;AAAA,MAClC,SAAS,IAAI;AAAA,MACb,YAAY,KAAK,UAAU,cAAc,SAAS;AAAA,IACpD,CAAC;AAAA,EACH;AAAA;AAAA,EAGQ,gBAAgB,oBAAI,QAA0F;AAAA;AAAA,EAG9G,uBAAuB,KAAuF;AACpH,UAAM,SAAS,KAAK,cAAc,IAAI,GAAG;AACzC,QAAI,OAAQ,QAAO;AACnB,QAAI;AACJ,QAAI;AACJ,QAAI;AAGJ,QAAI,KAAK,sBAAsB;AAC7B,YAAM,YAAY,IAAI,QAAQ,oBAAoB;AAClD,YAAM,MAAM,MAAM,QAAQ,SAAS,IAAI,UAAU,CAAC,IAAI;AACtD,UAAI,OAAO,QAAQ,UAAU;AAC3B,cAAM,UAAU,IAAI,KAAK;AACzB,YAAI,QAAQ,SAAS,GAAG;AACtB,sBAAY;AAAA,QACd;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,WAAW;AACd,kBAAY,KAAK;AAAA,IACnB;AAIA,UAAM,kBAAkB,KAAK,uBAAuB,GAAG;AACvD,QAAI,iBAAiB;AACnB,UAAI,CAAC,WAAW;AACd,oBAAY,gBAAgB;AAAA,MAC9B;AACA,kBAAY,gBAAgB;AAC5B,mBAAa,gBAAgB;AAAA,IAC/B;AAEA,UAAM,SAAS,EAAE,WAAW,WAAW,WAAW;AAClD,SAAK,cAAc,IAAI,KAAK,MAAM;AAClC,WAAO;AAAA,EACT;AAAA,EAEQ,wBAAwB,KAA0C;AACxE,WAAO,KAAK,uBAAuB,GAAG,EAAE;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAiB,MAAuB,eAA4C;AAC1F,WAAO,iBAAiB;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWQ,wBACN,gBACA,QAC8B;AAC9B,QAAI,mBAAmB,QAAW;AAChC,aAAO;AAAA,IACT;AACA,UAAM,kBAAkB,OAAO,aAAa,IAAI,YAAY;AAC5D,QAAI,oBAAoB,MAAM;AAC5B,aAAO;AAAA,IACT;AACA,QAAI,CAAC,mBAAmB,eAAe,GAAG;AACxC,YAAM,IAAI;AAAA,QACR,wDAAwD,eAAe;AAAA,MACzE;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,OAAO,KAAsB,KAAqB,eAAsC;AACpG,UAAM,SAAS,IAAI,IAAI,IAAI,OAAO,KAAK,UAAU,mBAAmB,KAAK,IAAI,CAAC,EAAE;AAChF,UAAM,WAAW,OAAO;AAExB,QAAI,KAAK,uBAAuB,MAAM,KAAK,mBAAmB,KAAK,KAAK,QAAQ,GAAG;AACjF;AAAA,IACF;AAEA,QAAI,CAAC,KAAK,aAAa,KAAK,QAAQ,GAAG;AACrC,YAAM,OAAO,KAAK,UAAU,EAAE,OAAO,gBAAgB,MAAM,eAAe,CAAC;AAC3E,UAAI,UAAU,KAAK;AAAA,QACjB,gBAAgB;AAAA,QAChB,oBAAoB;AAAA,QACpB,gBAAgB;AAAA,MAClB,CAAC;AACD,UAAI,IAAI,IAAI;AACZ;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,UAAU,aAAa,QAAQ;AAChD,YAAM,KAAK,iBAAiB,KAAK,GAAG;AACpC;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,SAAS,aAAa,qBAAqB;AAC5D,WAAK,YAAY,KAAK,KAAK,MAAM,KAAK,QAAQ,OAAO,CAAC;AACtD;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,SAAS,aAAa,uBAAuB;AAC9D,YAAM,WAAW,KAAK,uBAAuB,GAAG;AAChD,WAAK,YAAY,KAAK,KAAK;AAAA,QACzB,iBAAiB,KAAK,oBAAoB;AAAA,QAC1C,YAAY,KAAK,iBAAiB,KAAK,KAAK,CAAC;AAAA,QAC7C,UAAU;AAAA,MACZ,CAAC;AACD;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,UAAU,aAAa,qBAAqB;AAC7D,YAAM,OAAO,MAAM,KAAK,kBAAkB,KAAK,QAAQ;AAMvD,YAAM,gBACJ,mBAAmB,OAAO,KAAK,gBAAgB;AAMjD,YAAM,aAAa,KAAK,wBAAwB,KAAK,YAAY,MAAM;AAIvE,YAAM,eAAe,OAAO,aAAa,IAAI,OAAO;AACpD,YAAM,cACJ,OAAO,KAAK,SAAS,YAAY,KAAK,KAAK,SAAS;AACtD,UACE,CAAC,eACD,iBAAiB,QACjB,aAAa,WAAW,GACxB;AACA,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AACA,YAAM,OACJ,KAAK,SACJ,iBAAiB,QAAQ,aAAa,SAAS,IAC5C,eACA;AAIN,YAAM,mBACJ,SAAS,QACT,OAAO,SAAS,YAChB,UAAW;AACb,YAAM,gBAAgB,mBACjB,KAA4B,OAC7B;AACJ,YAAM,WAAW,MAAM,QAAQ,aAAa,IACvC,gBACD;AACJ,YAAM,YAAY,OAAO,aAAa,OAAO,KAAK;AAClD,YAAM,OAAO,mBACT,WACA,UAAU,SAAS,IACjB,YACA;AACN,YAAM,eAAgB,KAAgC;AACtD,UAAI;AACJ,UAAI,iBAAiB,QAAW;AAC9B,YAAI,iBAAiB,SAAS,iBAAiB,OAAO;AACpD,qBAAW;AAAA,QACb;AAAA,MACF,OAAO;AACL,cAAM,gBAAgB,OAAO,aAAa,IAAI,WAAW;AACzD,YAAI,kBAAkB,MAAM;AAC1B,cAAI,kBAAkB,SAAS,kBAAkB,OAAO;AACtD,kBAAM,IAAI;AAAA,cACR,4CAA4C,aAAa;AAAA,YAC3D;AAAA,UACF;AACA,qBAAW;AAAA,QACb;AAAA,MACF;AAIA,YAAM,2BACH,KAA4C;AAC/C,YAAM,4BAA4B,OAAO,aAAa,IAAI,wBAAwB;AAClF,UACE,6BAA6B,UAC7B,8BAA8B,QAC9B,8BAA8B,UAC9B,8BAA8B,SAC9B;AACA,cAAM,IAAI;AAAA,UACR,4DAA4D,yBAAyB;AAAA,QACvF;AAAA,MACF;AACA,YAAM,uBACJ,6BAA6B,QAC5B,6BAA6B,UAC5B,8BAA8B;AAClC,YAAM,WAAW,MAAM,KAAK,QAAQ,OAAO;AAAA,QACzC,OAAO,KAAK,SAAS;AAAA,QACrB,YAAY,KAAK;AAAA,QACjB,wBAAwB,KAAK,wBAAwB,GAAG;AAAA,QACxD,gBAAgB,KAAK;AAAA,QACrB,WAAW,KAAK,iBAAiB,KAAK,KAAK,SAAS;AAAA,QACpD,MAAM,KAAK;AAAA,QACX,MAAM,KAAK;AAAA,QACX,cAAc,KAAK,iBAAiB;AAAA;AAAA;AAAA;AAAA,QAIpC;AAAA,QACA;AAAA;AAAA,QAEA,KAAK,KAAK;AAAA,QACV,YAAY,KAAK;AAAA,QACjB,GAAI,SAAS,SAAY,EAAE,KAAK,IAAI,CAAC;AAAA,QACrC,GAAI,SAAS,SAAY,EAAE,KAAK,IAAI,CAAC;AAAA,QACrC,GAAI,aAAa,SAAY,EAAE,SAAS,IAAI,CAAC;AAAA,QAC7C,GAAI,uBAAuB,EAAE,sBAAsB,KAAK,IAAI,CAAC;AAAA,MAC/D,CAAC;AACD,WAAK,YAAY,KAAK,KAAK,QAAQ;AACnC;AAAA,IACF;AAMA,QAAI,IAAI,WAAW,UAAU,aAAa,6BAA6B;AACrE,YAAM,OAAO,MAAM,KAAK,kBAAkB,KAAK,kBAAkB;AACjE,YAAM,gBACJ,KAAK,kBAAkB,SACnB,KAAK,gBACL,OAAO,KAAK,eAAe,WACzB,4BAA4B,KAAK,UAAU,KAC1C,MAAM;AACL,cAAM,IAAI,uBAAuB,yCAAyC;AAAA,MAC5E,GAAG;AACX,WAAK,QAAQ,iBAAiB;AAAA,QAC5B,YAAY,KAAK;AAAA,QACjB;AAAA,MACF,CAAC;AACD,WAAK,YAAY,KAAK,KAAK,EAAE,IAAI,KAAK,CAAC;AACvC;AAAA,IACF;AAEA,QACE,IAAI,WAAW,WACd,aAAa,gCAAgC,aAAa,+BAC3D;AACA,YAAM,OAAO,MAAM,KAAK,kBAAkB,KAAK,eAAe;AAC9D,WAAK,8BAA8B;AACnC,YAAM,SAAS,MAAM,KAAK,QAAQ,cAAc;AAAA,QAC9C,MAAM,KAAK;AAAA,QACX,WAAW,KAAK,iBAAiB,KAAK,KAAK,SAAS;AAAA,QACpD,WAAW,KAAK,wBAAwB,GAAG;AAAA,QAC3C,OAAO,KAAK;AAAA,QACZ,cAAc,KAAK;AAAA,QACnB,SAAS,KAAK;AAAA,QACd,oBAAoB,KAAK;AAAA,QACzB,SAAS,KAAK;AAAA,MAChB,CAAC;AACD,WAAK,wBAAwB;AAC7B,WAAK,YAAY,KAAK,KAAK,MAAM;AACjC;AAAA,IACF;AAEA,QACE,IAAI,WAAW,WACd,aAAa,gCAAgC,aAAa,+BAC3D;AACA,YAAM,OAAO,MAAM,KAAK,kBAAkB,KAAK,eAAe;AAC9D,WAAK,8BAA8B;AACnC,YAAM,SAAS,MAAM,KAAK,QAAQ,cAAc;AAAA,QAC9C,aAAa,gBAAgB,KAAK,WAAW;AAAA,QAC7C,WAAW,KAAK,iBAAiB,KAAK,KAAK,SAAS;AAAA,QACpD,WAAW,KAAK,wBAAwB,GAAG;AAAA,QAC3C,MAAM,KAAK;AAAA,QACX,YAAY,KAAK;AAAA,MACnB,CAAC;AACD,WAAK,wBAAwB;AAC7B,WAAK,YAAY,KAAK,KAAK,MAAM;AACjC;AAAA,IACF;AAEA,QACE,IAAI,WAAW,UACd,aAAa,sCAAsC,aAAa,qCACjE;AACA,YAAM,wBAAwB,OAAO,aAAa,IAAI,qBAAqB;AAC3E,YAAM,oBAAoB,OAAO,aAAa,IAAI,SAAS;AAC3D,UACE,0BAA0B,QAC1B,0BAA0B,UAC1B,0BAA0B,SAC1B;AACA,cAAM,IAAI;AAAA,UACR,yDAAyD,qBAAqB;AAAA,QAChF;AAAA,MACF;AACA,UACE,sBAAsB,QACtB,sBAAsB,UACtB,sBAAsB,SACtB;AACA,cAAM,IAAI;AAAA,UACR,6CAA6C,iBAAiB;AAAA,QAChE;AAAA,MACF;AACA,YAAM,iBAAiB,OAAO,aAAa,IAAI,WAAW;AAC1D,YAAM,SAAS,MAAM,KAAK,QAAQ,oBAAoB;AAAA,QACpD,WAAW,KAAK;AAAA,UACd;AAAA,UACA,kBAAkB,eAAe,SAAS,IAAI,iBAAiB;AAAA,QACjE;AAAA,QACA,WAAW,KAAK,wBAAwB,GAAG;AAAA,QAC3C,oBAAoB,0BAA0B;AAAA,QAC9C,gBAAgB,sBAAsB;AAAA,MACxC,CAAC;AACD,WAAK,YAAY,KAAK,KAAK,MAAM;AACjC;AAAA,IACF;AAEA,QACE,IAAI,WAAW,UACd,aAAa,6CACZ,aAAa,4CACf;AACA,YAAM,wBAAwB,OAAO,aAAa,IAAI,qBAAqB;AAC3E,YAAM,oBAAoB,OAAO,aAAa,IAAI,SAAS;AAC3D,UACE,0BAA0B,QAC1B,0BAA0B,UAC1B,0BAA0B,SAC1B;AACA,cAAM,IAAI;AAAA,UACR,yDAAyD,qBAAqB;AAAA,QAChF;AAAA,MACF;AACA,UACE,sBAAsB,QACtB,sBAAsB,SACtB;AACA,cAAM,IAAI,uBAAuB,uCAAuC;AAAA,MAC1E;AACA,YAAM,iBAAiB,OAAO,aAAa,IAAI,WAAW;AAC1D,YAAM,SAAS,MAAM,KAAK,QAAQ,0BAA0B;AAAA,QAC1D,WAAW,KAAK;AAAA,UACd;AAAA,UACA,kBAAkB,eAAe,SAAS,IAAI,iBAAiB;AAAA,QACjE;AAAA,QACA,WAAW,KAAK,wBAAwB,GAAG;AAAA,QAC3C,oBAAoB,0BAA0B;AAAA,QAC9C,gBAAgB;AAAA,QAChB,QAAQ,KAAK,yBAAyB,KAAK,GAAG;AAAA,MAChD,CAAC;AACD,YAAM,KAAK,6BAA6B,KAAK,MAAM;AACnD;AAAA,IACF;AAEA,QACE,IAAI,WAAW,WACd,aAAa,sCAAsC,aAAa,qCACjE;AACA,YAAM,OAAO,MAAM,KAAK;AAAA,QACtB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,YAAM,SAAS,MAAM,KAAK,QAAQ,oBAAoB;AAAA,QACpD,WAAW,KAAK,iBAAiB,KAAK,KAAK,SAAS;AAAA,QACpD,WAAW,KAAK,wBAAwB,GAAG;AAAA,QAC3C,oBAAoB,KAAK;AAAA,QACzB,gBAAgB,KAAK;AAAA,QACrB,WAAW,KAAK;AAAA,QAChB,GAAI,KAAK,iBAAiB,EAAE,gBAAgB,IAAI,KAAK,KAAK,cAAc,EAAE,IAAI,CAAC;AAAA,QAC/E,QAAQ,KAAK,yBAAyB,KAAK,GAAG;AAAA,MAChD,CAAC;AACD,WAAK,YAAY,KAAK,KAAK,MAAM;AACjC;AAAA,IACF;AAEA,QACE,IAAI,WAAW,WACd,aAAa,mCAAmC,aAAa,kCAC9D;AACA,YAAM,OAAO,MAAM,KAAK,kBAAkB,KAAK,kBAAkB;AACjE,YAAM,SAAS,MAAM,KAAK,QAAQ,iBAAiB;AAAA,QACjD,WAAW,KAAK,iBAAiB,KAAK,KAAK,SAAS;AAAA,QACpD,WAAW,KAAK,wBAAwB,GAAG;AAAA,QAC3C,oBAAoB,KAAK;AAAA,QACzB,OAAO,KAAK;AAAA,MACd,CAAC;AACD,WAAK,YAAY,KAAK,KAAK,MAAM;AACjC;AAAA,IACF;AAEA,QACE,IAAI,WAAW,WAEb,aAAa,0CACb,aAAa,yCAEf;AACA,YAAM,OAAO,MAAM,KAAK,kBAAkB,KAAK,wBAAwB;AACvE,YAAM,SAAS,MAAM,KAAK,QAAQ,uBAAuB;AAAA,QACvD,WAAW,KAAK,iBAAiB,KAAK,KAAK,SAAS;AAAA,QACpD,WAAW,KAAK,wBAAwB,GAAG;AAAA,QAC3C,oBAAoB,KAAK;AAAA,QACzB,MAAM,KAAK;AAAA,QACX,QAAQ,KAAK;AAAA,QACb,QAAQ,KAAK;AAAA,MACf,CAAC;AACD,WAAK,cAAc,KAAK,KAAK,OAAO,SAAS;AAAA,QAC3C,sBAAsB,mBAAmB,OAAO,SAAS;AAAA,QACzD,sBAAsB,mBAAmB,OAAO,IAAI;AAAA,QACpD,uBAAuB,OAAO,OAAO,KAAK;AAAA,QAC1C,0BAA0B,OAAO,OAAO,OAAO;AAAA,QAC/C,yBAAyB,OAAO,OAAO,MAAM;AAAA,QAC7C,wBAAwB,OAAO,OAAO,UAAU;AAAA,QAChD,GAAI,OAAO,SAAS,EAAE,wBAAwB,OAAO,OAAO,IAAI,CAAC;AAAA,MACnE,CAAC;AACD;AAAA,IACF;AAEA,QACE,IAAI,WAAW,WAEb,aAAa,gDACb,aAAa,+CAEf;AACA,YAAM,iBAAiB,OAAO,aAAa,IAAI,WAAW;AAC1D,YAAM,QAAQ,KAAK,0BAA0B,KAAK,qBAAqB;AACvE,YAAM,SAAS,KAAK,0BAA0B,KAAK,uBAAuB,KAAK;AAC/E,YAAM,UAAU,MAAM,KAAK,eAAe,KAAK,yCAAyC;AACxF,YAAM,SAAS,MAAM,KAAK,QAAQ,4BAA4B;AAAA,QAC5D,WAAW,KAAK;AAAA,UACd;AAAA,UACA,kBAAkB,eAAe,SAAS,IAAI,iBAAiB;AAAA,QACjE;AAAA,QACA,WAAW,KAAK,wBAAwB,GAAG;AAAA,QAC3C,oBAAoB,KAAK;AAAA,UACvB;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA,UAAU,KAAK,0BAA0B,KAAK,oBAAoB;AAAA,QAClE,MAAM,KAAK,0BAA0B,KAAK,oBAAoB;AAAA,QAC9D,QAAQ,KAAK,mBAAmB,KAAK,sBAAsB;AAAA,QAC3D;AAAA,QACA,SAAS,KAAK,yBAAyB,KAAK,wBAAwB;AAAA,QACpE;AAAA,QACA,YAAY,KAAK,mBAAmB,KAAK,sBAAsB;AAAA,QAC/D;AAAA,MACF,CAAC;AACD,WAAK,YAAY,KAAK,KAAK,MAAM;AACjC;AAAA,IACF;AAEA,QACE,IAAI,WAAW,WACd,aAAa,mCAAmC,aAAa,kCAC9D;AACA,YAAM,OAAO,MAAM,KAAK,kBAAkB,KAAK,oBAAoB,iCAAiC;AACpG,YAAM,SAAS,MAAM,KAAK,QAAQ,iBAAiB;AAAA,QACjD,WAAW,KAAK,iBAAiB,KAAK,KAAK,SAAS;AAAA,QACpD,WAAW,KAAK,wBAAwB,GAAG;AAAA,QAC3C,WAAW,KAAK;AAAA,QAChB,oBAAoB,KAAK;AAAA,MAC3B,CAAC;AACD,WAAK,YAAY,KAAK,KAAK,MAAM;AACjC;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,UAAU,aAAa,6BAA6B;AACrE,YAAM,OAAO,MAAM,KAAK,kBAAkB,KAAK,eAAe;AAC9D,YAAM,WAAW,MAAM,KAAK,QAAQ,cAAc;AAAA,QAChD,YAAY,KAAK;AAAA,QACjB,WAAW,KAAK,iBAAiB,KAAK,KAAK,SAAS;AAAA,QACpD,wBAAwB,KAAK,wBAAwB,GAAG;AAAA,MAC1D,CAAC;AACD,WAAK,YAAY,KAAK,KAAK,QAAQ;AACnC;AAAA,IACF;AAEA,QACE,IAAI,WAAW,WACd,aAAa,kCAAkC,aAAa,iCAC7D;AACA,YAAM,OAAO,MAAM,KAAK,kBAAkB,KAAK,kBAAkB;AACjE,WAAK,YAAY,KAAK,KAAK,MAAM,KAAK,QAAQ,iBAAiB,IAAI,CAAC;AACpE;AAAA,IACF;AAKA,QAAI,IAAI,WAAW,SAAS,aAAa,kCAAkC;AACzE,YAAM,eAAe,OAAO,aAAa,IAAI,SAAS;AACtD,YAAM,aAAa,gBAAgB,aAAa,SAAS,IAAI,eAAe;AAC5E,YAAM,iBAAiB,OAAO,aAAa,IAAI,WAAW;AAC1D,YAAM,YAAY,KAAK;AAAA,QACrB;AAAA,QACA,kBAAkB,eAAe,SAAS,IAAI,iBAAiB;AAAA,MACjE;AACA,YAAM,UAAU,MAAM,KAAK,QAAQ;AAAA,QACjC;AAAA,QACA;AAAA,QACA,KAAK,wBAAwB,GAAG;AAAA,MAClC;AACA,WAAK,YAAY,KAAK,KAAK,OAAO;AAClC;AAAA,IACF;AAQA,QAAI,IAAI,WAAW,SAAS,aAAa,0BAA0B;AACjE,YAAM,aAAa,OAAO,aAAa,IAAI,GAAG;AAC9C,UAAI,CAAC,cAAc,WAAW,KAAK,EAAE,WAAW,GAAG;AACjD,aAAK,YAAY,KAAK,KAAK;AAAA,UACzB,OAAO;AAAA,UACP,MAAM;AAAA,UACN,SAAS;AAAA,QACX,CAAC;AACD;AAAA,MACF;AACA,YAAM,eAAe,OAAO,aAAa,IAAI,SAAS;AACtD,YAAM,aAAa,gBAAgB,aAAa,SAAS,IACrD,eACA;AACJ,YAAM,iBAAiB,OAAO,aAAa,IAAI,WAAW;AAC1D,YAAM,YAAY,KAAK;AAAA,QACrB;AAAA,QACA,kBAAkB,eAAe,SAAS,IACtC,iBACA;AAAA,MACN;AACA,YAAM,cAAc,OAAO,aAAa,IAAI,QAAQ;AAGpD,UAAI;AACJ,UAAI,gBAAgB,QAAQ,gBAAgB,IAAI;AAC9C,cAAM,eAAe,OAAO,WAAW;AACvC,YACE,CAAC,OAAO,SAAS,YAAY,KAC1B,gBAAgB,KAChB,CAAC,OAAO,UAAU,YAAY,GACjC;AACA,eAAK,YAAY,KAAK,KAAK;AAAA,YACzB,OAAO;AAAA,YACP,MAAM;AAAA,YACN,SACE;AAAA,UACJ,CAAC;AACD;AAAA,QACF;AACA,iBAAS;AAAA,MACX;AAMA,YAAM,kBAAkB,OAAO,aAAa,IAAI,YAAY;AAC5D,UAAI;AACJ,UAAI,oBAAoB,QAAQ,gBAAgB,SAAS,GAAG;AAC1D,YAAI,CAAC,mBAAmB,eAAe,GAAG;AACxC,eAAK,YAAY,KAAK,KAAK;AAAA,YACzB,OAAO;AAAA,YACP,MAAM;AAAA,YACN,SACE;AAAA,UACJ,CAAC;AACD;AAAA,QACF;AACA,qBAAa;AAAA,MACf;AAQA,UAAI;AACJ,UAAI;AACF,kBAAU,MAAM,KAAK,QAAQ,WAAW;AAAA,UACtC,OAAO;AAAA,UACP;AAAA,UACA;AAAA,UACA;AAAA,UACA,wBAAwB,KAAK,wBAAwB,GAAG;AAAA,UACxD,GAAI,eAAe,SAAY,EAAE,WAAW,IAAI,CAAC;AAAA,QACnD,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,YAAI,QAAQ,WAAW,aAAa,GAAG;AACrC,eAAK,YAAY,KAAK,KAAK;AAAA,YACzB,OAAO;AAAA,YACP,MAAM;AAAA,YACN;AAAA,UACF,CAAC;AACD;AAAA,QACF;AAGA,cAAM;AAAA,MACR;AACA,WAAK,YAAY,KAAK,KAAK,OAAO;AAClC;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,UAAU,aAAa,sBAAsB;AAC9D,YAAM,OAAO,MAAM,KAAK,kBAAkB,KAAK,SAAS;AACxD,WAAK,8BAA8B;AACnC,YAAM,WAAW,MAAM,KAAK,QAAQ,QAAQ;AAAA,QAC1C,YAAY,KAAK;AAAA,QACjB,UAAU,KAAK,SAAS,IAAI,CAAC,aAAa;AAAA,UACxC,MAAM,QAAQ;AAAA,UACd,SAAS,QAAQ;AAAA,UACjB,cAAc,QAAQ,gBAAgB;AAAA,UACtC,YAAY,QAAQ,cAAc;AAAA,UAClC,OAAO,QAAQ,SAAS;AAAA,QAC1B,EAAE;AAAA,QACF,WAAW,KAAK,iBAAiB,KAAK,KAAK,SAAS;AAAA,QACpD,wBAAwB,KAAK,wBAAwB,GAAG;AAAA,QACxD,gBAAgB,KAAK,mBAAmB;AAAA;AAAA,QAExC,KAAK,KAAK;AAAA,QACV,YAAY,KAAK;AAAA,MACnB,CAAC;AACD,WAAK,wBAAwB;AAC7B,WAAK,YAAY,KAAK,KAAK,QAAQ;AACnC;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,UAAU,aAAa,yBAAyB;AACjE,YAAM,OAAO,MAAM,KAAK,kBAAkB,KAAK,WAAW;AAC1D,YAAM,WAAW,MAAM,KAAK,QAAQ,UAAU;AAAA,QAC5C,OAAO,KAAK;AAAA,QACZ,YAAY,KAAK;AAAA,QACjB,eAAe,KAAK;AAAA,QACpB,WAAW,KAAK,iBAAiB,KAAK,KAAK,SAAS;AAAA,QACpD,wBAAwB,KAAK,wBAAwB,GAAG;AAAA,QACxD,OAAO,KAAK;AAAA,MACd,CAAC;AACD,WAAK,YAAY,KAAK,KAAK,QAAQ;AACnC;AAAA,IACF;AAEA,QACE,IAAI,WAAW,WACd,aAAa,qCAAqC,aAAa,oCAChE;AACA,YAAM,OAAO,MAAM,KAAK,kBAAkB,KAAK,oBAAoB;AACnE,WAAK,8BAA8B;AACnC,YAAM,WAAW,MAAM,KAAK,QAAQ,mBAAmB;AAAA,QACrD,YAAY,KAAK;AAAA,QACjB,WAAW,KAAK,iBAAiB,KAAK,KAAK,SAAS;AAAA,QACpD,wBAAwB,KAAK,wBAAwB,GAAG;AAAA,MAC1D,CAAC;AACD,WAAK,wBAAwB;AAC7B,WAAK,YAAY,KAAK,KAAK,QAAQ;AACnC;AAAA,IACF;AAEA,QACE,IAAI,WAAW,WACd,aAAa,sCAAsC,aAAa,qCACjE;AACA,YAAM,OAAO,MAAM,KAAK,kBAAkB,KAAK,qBAAqB;AACpE,WAAK,8BAA8B;AACnC,YAAM,WAAW,MAAM,KAAK,QAAQ,oBAAoB;AAAA,QACtD,YAAY,KAAK;AAAA,QACjB,WAAW,KAAK,iBAAiB,KAAK,KAAK,SAAS;AAAA,QACpD,cAAc,KAAK;AAAA,QACnB,aAAa,KAAK;AAAA,QAClB,wBAAwB,KAAK,wBAAwB,GAAG;AAAA,MAC1D,CAAC;AACD,WAAK,wBAAwB;AAC7B,WAAK,YAAY,KAAK,KAAK,QAAQ;AACnC;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,SAAS,aAAa,yBAAyB;AAChE,WAAK,YAAY,KAAK,KAAK,MAAM,KAAK,QAAQ,UAAU,CAAC;AACzD;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,UAAU,aAAa,uBAAuB;AAC/D,YAAM,OAAO,MAAM,KAAK,kBAAkB,KAAK,aAAa;AAC5D,YAAM,UAAU;AAAA,QACd,eAAe,KAAK;AAAA,QACpB,gBAAgB,KAAK;AAAA,QACrB,QAAQ,KAAK,WAAW;AAAA,QACxB,YAAY,KAAK;AAAA,QACjB,wBAAwB,KAAK,wBAAwB,GAAG;AAAA,QACxD,SAAS,KAAK;AAAA,QACd,UAAU,KAAK;AAAA,QACf,YAAY,KAAK;AAAA,QACjB,WAAW,KAAK,iBAAiB,KAAK,KAAK,SAAS;AAAA,QACpD,MAAM,KAAK;AAAA,QACX,WAAW,KAAK;AAAA,QAChB,KAAK,KAAK;AAAA,QACV,cAAc,KAAK;AAAA,QACnB,KAAK,KAAK;AAAA,QACV,YAAY,KAAK;AAAA,MACnB;AASA,YAAM,WAAW,MAAM,KAAK,QAAQ,YAAY,SAAS;AAAA,QACvD,mBAAmB,MAAM,KAAK,8BAA8B;AAAA,MAC9D,CAAC;AACD,UAAI,KAAK,0BAA0B,QAA6D,GAAG;AACjG,aAAK,wBAAwB;AAAA,MAC/B;AACA,WAAK,YAAY,KAAK,KAAK,oBAAoB,QAAQ,GAAG,QAAQ;AAClE;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,UAAU,aAAa,0BAA0B;AAClE,YAAM,OAAO,MAAM,KAAK,kBAAkB,KAAK,kBAAkB;AACjE,YAAM,UAAU;AAAA,QACd,eAAe,KAAK;AAAA,QACpB,gBAAgB,KAAK;AAAA,QACrB,QAAQ,KAAK,WAAW;AAAA,QACxB,YAAY,KAAK;AAAA,QACjB,wBAAwB,KAAK,wBAAwB,GAAG;AAAA,QACxD,SAAS,KAAK;AAAA,QACd,UAAU,KAAK;AAAA,QACf,YAAY,KAAK;AAAA,QACjB,WAAW,KAAK,iBAAiB,KAAK,KAAK,SAAS;AAAA,QACpD,MAAM,KAAK;AAAA,QACX,WAAW,KAAK;AAAA,QAChB,KAAK,KAAK;AAAA,QACV,cAAc,KAAK;AAAA,QACnB,KAAK,KAAK;AAAA,QACV,YAAY,KAAK;AAAA,MACnB;AAIA,YAAM,WAAW,MAAM,KAAK,QAAQ,iBAAiB,SAAS;AAAA,QAC5D,mBAAmB,MAAM,KAAK,8BAA8B;AAAA,MAC9D,CAAC;AACD,UAAI,KAAK,0BAA0B,QAA6D,GAAG;AACjG,aAAK,wBAAwB;AAAA,MAC/B;AACA,WAAK,YAAY,KAAK,KAAK,oBAAoB,QAAQ,GAAG,QAAQ;AAClE;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,SAAS,aAAa,uBAAuB;AAC9D,YAAM,QAAQ,wBAAwB,OAAO,aAAa,IAAI,OAAO,GAAG,SAAS,IAAI,CAAC;AACtF,YAAM,SAAS,wBAAwB,OAAO,aAAa,IAAI,QAAQ,GAAG,UAAU,GAAG,CAAC;AACxF,YAAM,OAAO,gBAAgB,OAAO,aAAa,IAAI,MAAM,CAAC;AAC5D,YAAM,WAAW,MAAM,KAAK,QAAQ,aAAa;AAAA,QAC/C,OAAO,OAAO,aAAa,IAAI,GAAG,KAAK;AAAA,QACvC,QAAQ,OAAO,aAAa,IAAI,QAAQ,KAAK;AAAA,QAC7C,UAAU,OAAO,aAAa,IAAI,UAAU,KAAK;AAAA,QACjD,WAAW,OAAO,aAAa,IAAI,WAAW,KAAK;AAAA,QACnD,wBAAwB,KAAK,wBAAwB,GAAG;AAAA,QACxD;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AACD,WAAK,YAAY,KAAK,KAAK,QAAQ;AACnC;AAAA,IACF;AAEA,UAAM,cAAc,SAAS,MAAM,mCAAmC;AACtE,QAAI,IAAI,WAAW,SAAS,aAAa;AACvC,YAAM,WAAW,mBAAmB,YAAY,CAAC,KAAK,EAAE;AACxD,YAAM,YAAY,OAAO,aAAa,IAAI,WAAW,KAAK;AAC1D,YAAM,WAAW,MAAM,KAAK,QAAQ,UAAU,UAAU,WAAW,KAAK,wBAAwB,GAAG,CAAC;AACpG,WAAK,YAAY,KAAK,SAAS,QAAQ,MAAM,KAAK,QAAQ;AAC1D;AAAA,IACF;AAEA,UAAM,gBAAgB,SAAS,MAAM,6CAA6C;AAClF,QAAI,IAAI,WAAW,SAAS,eAAe;AACzC,YAAM,WAAW,mBAAmB,cAAc,CAAC,KAAK,EAAE;AAC1D,YAAM,YAAY,OAAO,aAAa,IAAI,WAAW,KAAK;AAC1D,YAAM,QAAQ,wBAAwB,OAAO,aAAa,IAAI,OAAO,GAAG,SAAS,KAAK,CAAC;AACvF,YAAM,WAAW,MAAM,KAAK,QAAQ,eAAe,UAAU,WAAW,OAAO,KAAK,wBAAwB,GAAG,CAAC;AAChH,WAAK,YAAY,KAAK,SAAS,QAAQ,MAAM,KAAK,QAAQ;AAC1D;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,SAAS,aAAa,uBAAuB;AAC9D,YAAM,QAAQ,wBAAwB,OAAO,aAAa,IAAI,OAAO,GAAG,SAAS,IAAI,CAAC;AACtF,YAAM,SAAS,wBAAwB,OAAO,aAAa,IAAI,QAAQ,GAAG,UAAU,GAAG,CAAC;AACxF,YAAM,WAAW,MAAM,KAAK,QAAQ,WAAW;AAAA,QAC7C,WAAW,OAAO,aAAa,IAAI,WAAW,KAAK;AAAA,QACnD,OAAO,OAAO,aAAa,IAAI,GAAG,KAAK;AAAA,QACvC;AAAA,QACA;AAAA,MACF,CAAC;AACD,WAAK,YAAY,KAAK,KAAK,QAAQ;AACnC;AAAA,IACF;AAEA,UAAM,cAAc,SAAS,MAAM,mCAAmC;AACtE,QAAI,IAAI,WAAW,SAAS,aAAa;AACvC,YAAM,aAAa,mBAAmB,YAAY,CAAC,KAAK,EAAE;AAC1D,YAAM,YAAY,OAAO,aAAa,IAAI,WAAW,KAAK;AAC1D,YAAM,WAAW,MAAM,KAAK,QAAQ,UAAU,YAAY,SAAS;AACnE,WAAK,YAAY,KAAK,SAAS,QAAQ,MAAM,KAAK,QAAQ;AAC1D;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,SAAS,aAAa,2BAA2B;AAClE,YAAM,WAAW,MAAM,KAAK,QAAQ;AAAA,QAClC,OAAO,aAAa,IAAI,OAAO,KAAK;AAAA,QACpC,OAAO,aAAa,IAAI,WAAW,KAAK;AAAA,QACxC,KAAK,wBAAwB,GAAG;AAAA,MAClC;AACA,WAAK,YAAY,KAAK,KAAK,QAAQ;AACnC;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,SAAS,aAAa,0BAA0B;AACjE,WAAK,YAAY,KAAK,KAAK,MAAM,KAAK,QAAQ,YAAY,OAAO,aAAa,IAAI,WAAW,KAAK,QAAW,KAAK,wBAAwB,GAAG,CAAC,CAAC;AAC/I;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,SAAS,aAAa,sBAAsB;AAC7D,WAAK,YAAY,KAAK,KAAK,MAAM,KAAK,QAAQ,QAAQ,OAAO,aAAa,IAAI,WAAW,KAAK,QAAW,KAAK,wBAAwB,GAAG,CAAC,CAAC;AAC3I;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,SAAS,aAAa,iCAAiC;AACxE,WAAK;AAAA,QACH;AAAA,QACA;AAAA,QACA,MAAM,KAAK,QAAQ,gBAAgB,OAAO,aAAa,IAAI,WAAW,KAAK,QAAW,KAAK,wBAAwB,GAAG,CAAC;AAAA,MACzH;AACA;AAAA,IACF;AAKA,QAAI,IAAI,WAAW,SAAS,aAAa,+BAA+B;AACtE,YAAM,iBAAiB,OAAO,aAAa,IAAI,WAAW;AAC1D,WAAK;AAAA,QACH;AAAA,QACA;AAAA,QACA,MAAM,KAAK,QAAQ;AAAA,UACjB;AAAA,YACE,WAAW,KAAK;AAAA,cACd;AAAA,cACA,kBAAkB,eAAe,SAAS,IACtC,iBACA;AAAA,YACN;AAAA,UACF;AAAA,UACA,KAAK,wBAAwB,GAAG;AAAA,QAClC;AAAA,MACF;AACA;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,SAAS,aAAa,kCAAkC;AACzE,YAAM,QAAQ,wBAAwB,OAAO,aAAa,IAAI,OAAO,GAAG,SAAS,IAAI,CAAC;AACtF,YAAM,SAAS,wBAAwB,OAAO,aAAa,IAAI,QAAQ,GAAG,UAAU,GAAG,CAAC;AACxF,YAAM,WAAW,MAAM,KAAK,QAAQ,gBAAgB;AAAA,QAClD,OAAO,OAAO,aAAa,IAAI,GAAG,KAAK;AAAA,QACvC,MAAM,qBAAqB,OAAO,aAAa,IAAI,MAAM,CAAC;AAAA,QAC1D,MAAM,yBAAyB,OAAO,aAAa,IAAI,MAAM,CAAC;AAAA,QAC9D,aAAa,gCAAgC,OAAO,aAAa,IAAI,aAAa,CAAC;AAAA,QACnF,WAAW,OAAO,aAAa,IAAI,WAAW,KAAK;AAAA,QACnD;AAAA,QACA;AAAA,MACF,GAAG,KAAK,wBAAwB,GAAG,CAAC;AACpC,WAAK,YAAY,KAAK,KAAK,QAAQ;AACnC;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,UAAU,aAAa,iCAAiC;AACzE,YAAM,OAAO,MAAM,KAAK,kBAAkB,KAAK,mBAAmB;AAClE,WAAK,8BAA8B;AACnC,YAAM,WAAW,MAAM,KAAK,QAAQ,kBAAkB;AAAA,QACpD,UAAU,KAAK;AAAA,QACf,QAAQ,KAAK;AAAA,QACb,YAAY,KAAK;AAAA,QACjB,WAAW,KAAK,iBAAiB,KAAK,KAAK,SAAS;AAAA,QACpD,wBAAwB,KAAK,wBAAwB,GAAG;AAAA,MAC1D,CAAC;AACD,UAAI,KAAK,0BAA0B,QAAwE,GAAG;AAC5G,aAAK,wBAAwB;AAAA,MAC/B;AACA,WAAK,YAAY,KAAK,KAAK,QAAQ;AACnC;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,UAAU,aAAa,kCAAkC;AAC1E,YAAM,OAAO,MAAM,KAAK,kBAAkB,KAAK,kBAAkB;AACjE,YAAM,SAAS,KAAK,WAAW;AAC/B,UAAI,CAAC,QAAQ;AACX,aAAK,8BAA8B;AAAA,MACrC;AACA,YAAM,WAAW,MAAM,KAAK,QAAQ,iBAAiB;AAAA,QACnD,UAAU,KAAK;AAAA,QACf,YAAY,KAAK;AAAA,QACjB,iBAAiB,KAAK;AAAA,QACtB,YAAY,KAAK;AAAA,QACjB,SAAS,KAAK;AAAA,QACd;AAAA,QACA,WAAW,KAAK,iBAAiB,KAAK,KAAK,SAAS;AAAA,QACpD,wBAAwB,KAAK,wBAAwB,GAAG;AAAA,MAC1D,CAAC;AACD,UAAI,KAAK,0BAA0B,QAAwE,GAAG;AAC5G,aAAK,wBAAwB;AAAA,MAC/B;AACA,WAAK,YAAY,KAAK,SAAS,SAAS,MAAM,KAAK,QAAQ;AAC3D;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,UAAU,aAAa,oCAAoC;AAC5E,YAAM,OAAO,MAAM,KAAK,kBAAkB,KAAK,mBAAmB;AAClE,YAAM,SAAS,KAAK,WAAW;AAC/B,UAAI,CAAC,QAAQ;AACX,aAAK,8BAA8B;AAAA,MACrC;AACA,YAAM,WAAW,MAAM,KAAK,QAAQ,kBAAkB;AAAA,QACpD,UAAU,KAAK;AAAA,QACf,YAAY,KAAK;AAAA,QACjB;AAAA,QACA,WAAW,KAAK,iBAAiB,KAAK,KAAK,SAAS;AAAA,QACpD,wBAAwB,KAAK,wBAAwB,GAAG;AAAA,MAC1D,CAAC;AACD,UAAI,KAAK,0BAA0B,QAAwE,GAAG;AAC5G,aAAK,wBAAwB;AAAA,MAC/B;AACA,WAAK,YAAY,KAAK,SAAS,SAAS,MAAM,KAAK,QAAQ;AAC3D;AAAA,IACF;AAGA,QAAI,IAAI,WAAW,UAAU,aAAa,0BAA0B;AAClE,YAAM,OAAO,MAAM,KAAK,aAAa,GAAG;AACxC,UAAI,CAAC,QAAQ,OAAO,SAAS,YAAY,MAAM,QAAQ,IAAI,GAAG;AAC5D,cAAM,IAAI,UAAU,KAAK,sCAAsC,cAAc;AAAA,MAC/E;AACA,YAAM,UAAU;AAChB,YAAM,YAAY,OAAO,QAAQ,cAAc,WAAW,QAAQ,YAAY;AAC9E,YAAM,YAAY,OAAO,QAAQ,cAAc,WAAW,QAAQ,YAAY;AAC9E,YAAM,eAAe,QAAQ;AAC7B,UAAI,CAAC,gBAAgB,OAAO,iBAAiB,YAAY,MAAM,QAAQ,YAAY,GAAG;AACpF,cAAM,IAAI,UAAU,KAAK,+DAA+D,mBAAmB;AAAA,MAC7G;AACA,YAAM,SAAS;AACf,YAAM,UAA2B,CAAC;AAClC,UAAI,MAAM,QAAQ,OAAO,OAAO,GAAG;AACjC,mBAAW,OAAO,OAAO,SAAS;AAChC,cAAI,OAAO,OAAO,QAAQ,YAAY,CAAC,MAAM,QAAQ,GAAG,GAAG;AACzD,kBAAM,IAAI;AACV,gBACE,OAAO,EAAE,SAAS,YAClB,OAAO,EAAE,cAAc,YACvB,OAAO,EAAE,YAAY,UACrB;AACA,sBAAQ,KAAK;AAAA,gBACX,MAAM,EAAE;AAAA,gBACR,WAAW,EAAE;AAAA,gBACb,SAAS,EAAE;AAAA,gBACX,MAAM,OAAO,EAAE,SAAS,WAAW,EAAE,OAAO;AAAA,cAC9C,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,YAAM,aAAuB,CAAC;AAC9B,UAAI,MAAM,QAAQ,OAAO,UAAU,GAAG;AACpC,mBAAW,MAAM,OAAO,YAAY;AAClC,cAAI,OAAO,OAAO,YAAY,GAAG,SAAS,GAAG;AAC3C,uBAAW,KAAK,EAAE;AAAA,UACpB;AAAA,QACF;AAAA,MACF;AAMA,UAAI,UAAU;AACd,UAAI,YAAY;AAChB,UAAI,OAAO,KAAK,QAAQ,wBAAwB,YAAY;AAC1D,cAAM,SAAS,MAAM,KAAK,QAAQ,oBAAoB;AAAA,UACpD;AAAA,UACA,WAAW,KAAK,iBAAiB,KAAK,SAAS;AAAA,UAC/C,wBAAwB,KAAK,wBAAwB,GAAG;AAAA,UACxD;AAAA,UACA;AAAA,QACF,CAAC;AACD,oBAAY,OAAO;AACnB,kBAAU,OAAO;AAAA,MACnB;AAEA,WAAK,YAAY,KAAK,KAAK;AAAA,QACzB,IAAI;AAAA,QACJ;AAAA,QACA;AAAA,QACA,iBAAiB,QAAQ;AAAA,QACzB,oBAAoB,WAAW;AAAA,MACjC,CAAC;AACD;AAAA,IACF;AAGA,QAAI,IAAI,WAAW,SAAS,aAAa,oCAAoC;AAC3E,YAAM,gBAAgB,oBAAI,IAAI,CAAC,OAAO,cAAc,eAAe,eAAe,cAAc,YAAY,CAAC;AAC7G,YAAM,YAAY,OAAO,aAAa,IAAI,QAAQ,KAAK;AACvD,UAAI,CAAC,cAAc,IAAI,SAAS,GAAG;AACjC,aAAK,YAAY,KAAK,KAAK,EAAE,OAAO,mBAAmB,SAAS,aAAa,CAAC,GAAG,aAAa,EAAE,KAAK,IAAI,CAAC,GAAG,CAAC;AAC9G;AAAA,MACF;AACA,YAAM,YAAY,OAAO,aAAa,IAAI,WAAW,KAAK;AAC1D,YAAM,QAAQ,wBAAwB,OAAO,aAAa,IAAI,OAAO,GAAG,SAAS,IAAI,CAAC;AACtF,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,MACF,IAAI,MAAM,OAAO,oCAAyC;AAC1D,YAAM,YAAY,KAAK,wBAAwB,GAAG;AAClD,YAAM,WAAW,MAAM,KAAK,QAAQ,+BAA+B,WAAW,SAAS;AACvF,YAAM,kBAAkB,KAAK,QAAQ,UAAU,oBAAoB,SAAS,YAAY;AACxF,YAAM,8BAA8B;AAAA,QAClC,mBAAmB,yBAAyB,KAAK,QAAQ,UAAU,kBAAkB,WAAW,eAAe;AAAA,MACjH;AACA,YAAM,SAAS,UAAU,KAAK,QAAQ,WAAW;AAAA,QAC/C,QAAQ;AAAA,QACR,WAAW;AAAA,QACX;AAAA,QACA;AAAA,MACF,CAAC;AACD,WAAK,YAAY,KAAK,KAAK,MAAM;AACjC;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,SAAS,SAAS,WAAW,mCAAmC,GAAG;AACpF,YAAM,SAAS,SAAS,MAAM,GAAG,EAAE,IAAI,KAAK;AAC5C,YAAM,EAAE,SAAS,IAAI,MAAM,OAAO,oCAAyC;AAC3E,YAAM,OAAO,SAAS,KAAK,QAAQ,WAAW,MAAM;AACpD,UAAI,CAAC,MAAM;AACT,aAAK,YAAY,KAAK,KAAK,EAAE,OAAO,iBAAiB,CAAC;AACtD;AAAA,MACF;AACA,UAAI;AACF,cAAM,KAAK,QAAQ,+BAA+B,KAAK,WAAW,KAAK,wBAAwB,GAAG,CAAC;AAAA,MACrG,QAAQ;AACN,aAAK,YAAY,KAAK,KAAK,EAAE,OAAO,iBAAiB,CAAC;AACtD;AAAA,MACF;AACA,WAAK,YAAY,KAAK,KAAK,IAAI;AAC/B;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,UAAU,aAAa,6BAA6B;AACrE,YAAM,OAAO,MAAM,KAAK,aAAa,GAAG;AACxC,YAAM,SAAS,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS;AAC/D,YAAM,OAAO,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO;AACzD,UAAI,CAAC,UAAU,CAAC,MAAM;AACpB,aAAK,YAAY,KAAK,KAAK,EAAE,OAAO,+BAA+B,CAAC;AACpE;AAAA,MACF;AACA,YAAM,EAAE,uBAAuB,kBAAkB,IAAI,MAAM,OAAO,0BAA+B;AACjG,UAAI,CAAC,sBAAsB,IAAI,GAAG;AAChC,aAAK,YAAY,KAAK,KAAK,EAAE,OAAO,iBAAiB,IAAI,0EAA0E,CAAC;AACpI;AAAA,MACF;AACA,YAAM,YAAY,KAAK,wBAAwB,GAAG;AAClD,YAAM,SAAS,MAAM,kBAAkB,KAAK,QAAQ,WAAW,KAAK,QAAQ,YAAY,QAAQ,MAAM;AAAA,QACpG,gBAAgB,OAAO,KAAK,mBAAmB,WAAW,KAAK,iBAAiB;AAAA,QAChF,eAAe,OAAO,KAAK,kBAAkB,WAAW,KAAK,gBAAgB;AAAA,QAC7E,qBAAqB,OAAO,cAAc;AACxC,gBAAM,WAAW,MAAM,KAAK,QAAQ,+BAA+B,WAAW,SAAS;AACvF,iBAAO,SAAS;AAAA,QAClB;AAAA,MACF,CAAC;AACD,WAAK,YAAY,KAAK,KAAK,MAAM;AACjC;AAAA,IACF;AAMA,QAAI,IAAI,WAAW,SAAS,aAAa,6BAA6B;AACpE,YAAM,WAAW,OAAO,aAAa,IAAI,OAAO;AAChD,UAAI;AACJ,UAAI,aAAa,QAAQ,SAAS,SAAS,GAAG;AAC5C,cAAM,cAAc,OAAO,QAAQ;AACnC,YACE,CAAC,OAAO,SAAS,WAAW,KACzB,CAAC,OAAO,UAAU,WAAW,KAC7B,eAAe,GAClB;AACA,eAAK,YAAY,KAAK,KAAK;AAAA,YACzB,OAAO;AAAA,YACP,MAAM;AAAA,YACN,SAAS;AAAA,UACX,CAAC;AACD;AAAA,QACF;AACA,gBAAQ;AAAA,MACV;AACA,YAAM,WAAW,OAAO,aAAa,IAAI,OAAO;AAChD,UAAI;AACJ,UAAI,aAAa,QAAQ,SAAS,SAAS,GAAG;AAK5C,YAAI,CAAC,OAAO,SAAS,KAAK,MAAM,QAAQ,CAAC,GAAG;AAC1C,eAAK,YAAY,KAAK,KAAK;AAAA,YACzB,OAAO;AAAA,YACP,MAAM;AAAA,YACN,SAAS;AAAA,UACX,CAAC;AACD;AAAA,QACF;AACA,gBAAQ;AAAA,MACV;AACA,YAAM,iBAAiB,OAAO,aAAa,IAAI,aAAa;AAC5D,YAAM,cAAc,kBAAkB,eAAe,SAAS,IAC1D,iBACA;AACJ,YAAM,gBAAgB,OAAO,aAAa,IAAI,YAAY;AAC1D,UAAI;AACJ,UAAI,kBAAkB,QAAQ,cAAc,SAAS,GAAG;AACtD,qBAAa,cACV,MAAM,GAAG,EACT,IAAI,CAAC,UAAU,MAAM,KAAK,CAAC,EAC3B,OAAO,CAAC,UAAU,MAAM,SAAS,CAAC;AACrC,YAAI,WAAW,WAAW,GAAG;AAC3B,eAAK,YAAY,KAAK,KAAK;AAAA,YACzB,OAAO;AAAA,YACP,MAAM;AAAA,YACN,SACE;AAAA,UACJ,CAAC;AACD;AAAA,QACF;AAAA,MACF;AACA,YAAM,iBAAiB,OAAO,aAAa,IAAI,WAAW;AAC1D,YAAM,YAAY,KAAK;AAAA,QACrB;AAAA,QACA,kBAAkB,eAAe,SAAS,IAAI,iBAAiB;AAAA,MACjE;AACA,UAAI;AACF,cAAM,WAAW,MAAM,KAAK,QAAQ;AAAA,UAClC;AAAA,YACE;AAAA,YACA,GAAI,UAAU,SAAY,EAAE,MAAM,IAAI,CAAC;AAAA,YACvC,GAAI,UAAU,SAAY,EAAE,MAAM,IAAI,CAAC;AAAA,YACvC,GAAI,gBAAgB,SAAY,EAAE,YAAY,IAAI,CAAC;AAAA,YACnD,GAAI,eAAe,SAAY,EAAE,WAAW,IAAI,CAAC;AAAA,UACnD;AAAA,UACA,KAAK,wBAAwB,GAAG;AAAA,QAClC;AACA,aAAK,YAAY,KAAK,KAAK,QAAQ;AAAA,MACrC,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,YAAI,QAAQ,WAAW,gBAAgB,GAAG;AACxC,eAAK,YAAY,KAAK,KAAK;AAAA,YACzB,OAAO;AAAA,YACP,MAAM;AAAA,YACN;AAAA,UACF,CAAC;AACD;AAAA,QACF;AACA,cAAM;AAAA,MACR;AACA;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,UAAU,aAAa,iCAAiC;AACzE,YAAM,OAAO,MAAM,KAAK,aAAa,GAAG;AACxC,YAAM,EAAE,qBAAqB,IAAI,MAAM,OAAO,kCAAuC;AACrF,YAAM,YAAY,KAAK,wBAAwB,GAAG;AAClD,YAAM,SAAS,MAAM,qBAAqB;AAAA,QACxC,SAAS,KAAK,QAAQ;AAAA,QACtB,QAAQ,KAAK,QAAQ;AAAA,QACrB,WAAW,KAAK,QAAQ;AAAA,QACxB,wBAAwB,KAAK,QAAQ;AAAA,QACrC,qBAAqB,CAAC,cACpB,KAAK,QAAQ,+BAA+B,WAAW,SAAS;AAAA,QAClE,UAAU,KAAK,QAAQ;AAAA,QACvB,aAAa,KAAK,QAAQ;AAAA,QAC1B,WAAW,OAAO,KAAK,cAAc,WAAW,KAAK,YAAY;AAAA,MACnE,CAAC;AACD,WAAK,YAAY,KAAK,KAAK,MAAM;AACjC;AAAA,IACF;AAqBA,QAAI,IAAI,WAAW,SAAS,aAAa,2BAA2B;AAClE,YAAM,KAAK,qBAAqB,KAAK,GAAG;AACxC;AAAA,IACF;AAMA,QAAI,IAAI,WAAW,SAAS,aAAa,4BAA4B;AACnE,YAAM,YAAY,OAAO,aAAa,IAAI,WAAW,KAAK;AAC1D,YAAM,WAAW,MAAM,KAAK,QAAQ,aAAa,WAAW,KAAK,wBAAwB,GAAG,CAAC;AAC7F,WAAK,YAAY,KAAK,KAAK,QAAQ;AACnC;AAAA,IACF;AAQA,QAAI,IAAI,WAAW,SAAS,aAAa,oBAAoB;AAC3D,YAAM,SAAS,MAAM,KAAK,QAAQ,SAAS;AAC3C,WAAK,YAAY,KAAK,KAAK,MAAM;AACjC;AAAA,IACF;AAEA,UAAM,mBAAmB,0CAA0C,KAAK,QAAQ;AAChF,QAAI,kBAAkB;AACpB,UAAI,IAAI,WAAW,OAAO;AACxB,aAAK,YAAY,KAAK,KAAK,EAAE,OAAO,sBAAsB,MAAM,qBAAqB,CAAC;AACtF;AAAA,MACF;AACA,YAAM,SAAS,oBAAoB,iBAAiB,CAAC,KAAK,EAAE;AAC5D,YAAM,SAAS,MAAM,KAAK,QAAQ,eAAe,MAAM;AACvD,UAAI,CAAC,OAAO,OAAO;AACjB,aAAK,YAAY,KAAK,KAAK,EAAE,OAAO,0BAA0B,MAAM,yBAAyB,CAAC;AAC9F;AAAA,MACF;AACA,WAAK,YAAY,KAAK,KAAK,MAAM;AACjC;AAAA,IACF;AAEA,UAAM,cAAc,iCAAiC,KAAK,QAAQ;AAClE,QAAI,aAAa;AACf,YAAM,SAAS,oBAAoB,YAAY,CAAC,KAAK,EAAE;AAEvD,UAAI,IAAI,WAAW,OAAO;AACxB,cAAM,SAAS,MAAM,KAAK,QAAQ,QAAQ,MAAM;AAChD,YAAI,CAAC,OAAO,OAAO;AACjB,eAAK,YAAY,KAAK,KAAK,EAAE,OAAO,kBAAkB,MAAM,iBAAiB,CAAC;AAC9E;AAAA,QACF;AACA,aAAK,YAAY,KAAK,KAAK,MAAM;AACjC;AAAA,MACF;AAEA,UAAI,IAAI,WAAW,OAAO;AACxB,cAAM,OAAO,MAAM,KAAK,aAAa,GAAG;AAIxC,YAAI,UAAU,QAAQ,KAAK,SAAS,UAAa,OAAO,KAAK,SAAS,UAAU;AAC9E,gBAAM,IAAI,uBAAuB,qCAAqC;AAAA,QACxE;AACA,YACE,iBAAiB,QACjB,KAAK,gBAAgB,UACrB,OAAO,KAAK,gBAAgB,UAC5B;AACA,gBAAM,IAAI,uBAAuB,4CAA4C;AAAA,QAC/E;AACA,YAAI,WAAW,QAAQ,KAAK,UAAU,UAAa,OAAO,KAAK,UAAU,UAAU;AACjF,gBAAM,IAAI,uBAAuB,sCAAsC;AAAA,QACzE;AACA,cAAM,SAAS,MAAM,KAAK,QAAQ,QAAQ;AAAA,UACxC,IAAI;AAAA,UACJ,MAAM,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO;AAAA,UAClD,aAAa,OAAO,KAAK,gBAAgB,WAAW,KAAK,cAAc;AAAA,UACvE,OAAO,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ;AAAA,QACvD,CAAC;AACD,aAAK,YAAY,KAAK,OAAO,UAAU,MAAM,KAAK,MAAM;AACxD;AAAA,MACF;AAEA,UAAI,IAAI,WAAW,UAAU;AAK3B,cAAM,cAAc,OAAO,aAAa,IAAI,QAAQ;AACpD,YAAI,gBAAgB,QAAQ;AAC1B,gBAAM,OAAO,MAAM,KAAK,aAAa,GAAG;AACxC,gBAAM,UAAU,OAAO,KAAK,YAAY,WAAW,KAAK,UAAU;AAClE,cAAI,YAAY,OAAO;AACrB,iBAAK,YAAY,KAAK,KAAK;AAAA,cACzB,OAAO;AAAA,cACP,MAAM;AAAA,cACN,SAAS;AAAA,YACX,CAAC;AACD;AAAA,UACF;AACA,gBAAMA,UAAS,MAAM,KAAK,QAAQ,WAAW,QAAQ,EAAE,SAAS,MAAM,CAAC;AACvE,eAAK,YAAY,KAAK,KAAKA,OAAM;AACjC;AAAA,QACF;AACA,cAAM,SAAS,MAAM,KAAK,QAAQ,WAAW,MAAM;AACnD,aAAK,YAAY,KAAK,KAAK,MAAM;AACjC;AAAA,MACF;AAEA,WAAK,YAAY,KAAK,KAAK,EAAE,OAAO,sBAAsB,MAAM,qBAAqB,CAAC;AACtF;AAAA,IACF;AAIA,QAAI,IAAI,WAAW,SAAS,aAAa,4BAA4B;AACnE,YAAM,EAAE,iCAAiC,IAAI,MAAM,OAAO,6BAAgC;AAC1F,YAAM,iBAAiB,OAAO,aAAa,IAAI,aAAa;AAC5D,UAAI;AACJ,UAAI;AACF,sBAAc;AAAA,UACZ,mBAAmB,OAAO,OAAO,cAAc,IAAI;AAAA,QACrD;AAAA,MACF,QAAQ;AACN,aAAK,YAAY,KAAK,KAAK,EAAE,OAAO,yCAAyC,CAAC;AAC9E;AAAA,MACF;AACA,YAAM,iBAAiB,OAAO,aAAa,IAAI,WAAW;AAC1D,YAAM,YAAY,kBAAkB,eAAe,SAAS,IAAI,iBAAiB;AACjF,YAAM,SAAS,MAAM,KAAK,QAAQ,aAAa;AAAA,QAC7C;AAAA,QACA;AAAA,QACA,WAAW,KAAK,wBAAwB,GAAG;AAAA,MAC7C,CAAC;AACD,WAAK,YAAY,KAAK,KAAK,MAAM;AACjC;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,UAAU,aAAa,yBAAyB;AACjE,YAAM,OAAO,MAAM,KAAK,aAAa,GAAG;AACxC,YAAM,eAAe,CAAC,cAAc,OAAO,WAAW;AACtD,YAAM,QAAQ,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ;AAC5D,UAAI,CAAC,SAAS,CAAE,aAAmC,SAAS,KAAK,GAAG;AAClE,aAAK,YAAY,KAAK,KAAK;AAAA,UACzB,OAAO,yCAAyC,aAAa,KAAK,IAAI,CAAC;AAAA,QACzE,CAAC;AACD;AAAA,MACF;AACA,UACE,YAAY,QACZ,KAAK,WAAW,UAChB,OAAO,KAAK,WAAW,WACvB;AACA,aAAK,YAAY,KAAK,KAAK;AAAA,UACzB,OAAO;AAAA,QACT,CAAC;AACD;AAAA,MACF;AACA,UACE,eAAe,QACf,KAAK,cAAc,UACnB,OAAO,KAAK,cAAc,UAC1B;AACA,aAAK,YAAY,KAAK,KAAK;AAAA,UACzB,OAAO;AAAA,QACT,CAAC;AACD;AAAA,MACF;AACA,YAAM,SAAS,KAAK,WAAW;AAC/B,YAAM,YACJ,OAAO,KAAK,cAAc,WAAW,KAAK,YAAY;AACxD,UAAI,CAAC,QAAQ;AACX,aAAK,8BAA8B;AAAA,MACrC;AACA,YAAM,SAAS,MAAM,KAAK,QAAQ,UAAU;AAAA,QAC1C;AAAA,QACA;AAAA,QACA;AAAA,QACA,wBAAwB,KAAK,wBAAwB,GAAG;AAAA,MAC1D,CAAC;AACD,UAAI,KAAK,0BAA0B,MAA2D,GAAG;AAC/F,aAAK,wBAAwB;AAAA,MAC/B;AACA,WAAK,YAAY,KAAK,KAAK,MAAM;AACjC;AAAA,IACF;AAEA,SAAK,YAAY,KAAK,KAAK,EAAE,OAAO,aAAa,MAAM,YAAY,CAAC;AAAA,EACtE;AAAA,EAEQ,yBAAyB,KAAsB,KAAkC;AACvF,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,QAAQ,MAAM;AAClB,UAAI,CAAC,WAAW,OAAO,QAAS,YAAW,MAAM;AAAA,IACnD;AACA,QAAI,KAAK,WAAW,KAAK;AACzB,QAAI,KAAK,SAAS,MAAM;AACtB,UAAI,CAAC,IAAI,cAAe,OAAM;AAAA,IAChC,CAAC;AACD,WAAO,WAAW;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,MAAc,qBAAqB,KAAsB,KAAoC;AAI3F,UAAM,SAAS,IAAI,IAAI,IAAI,OAAO,KAAK,UAAU,mBAAmB,KAAK,IAAI,CAAC,EAAE;AAChF,UAAM,iBAAiB,OAAO,aAAa,IAAI,WAAW;AAC1D,UAAM,YAAY,kBAAkB,eAAe,SAAS,IAAI,iBAAiB;AAMjF,UAAM,YAAY,KAAK,wBAAwB,GAAG;AAClD,UAAM,YAAY,MAAM,KAAK,QAAQ,yBAAyB,WAAW,SAAS;AAElF,QAAI,UAAU,KAAK;AAAA,MACjB,gBAAgB;AAAA,MAChB,iBAAiB;AAAA,MACjB,cAAc;AAAA,MACd,qBAAqB;AAAA;AAAA,MACrB,qBAAqB;AAAA,IACvB,CAAC;AAGD,UAAM,WAAW,CAAC,YAA2B;AAC3C,UAAI;AACF,YAAI,MAAM,SAAS,KAAK,UAAU,OAAO,CAAC;AAAA;AAAA,CAAM;AAAA,MAClD,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,aAAS,EAAE,MAAM,YAAY,CAAC;AAE9B,SAAK,WAAW,IAAI,GAAG;AAGvB,UAAM,aAAa,MAAY;AAC7B,YAAM,QAAQ,KAAK,kBAAkB,IAAI,GAAG;AAC5C,UAAI,CAAC,SAAS,MAAM,WAAW,EAAG;AAClC,WAAK,kBAAkB,OAAO,GAAG;AACjC,WAAK,eAAe,OAAO,GAAG;AAC9B,eAAS,EAAE,MAAM,SAAS,QAAQ,MAAM,CAAC;AAAA,IAC3C;AAEA,UAAM,cAAc,qBAAqB,WAAW,CAAC,UAAsB;AACzE,UAAI,QAAQ,KAAK,kBAAkB,IAAI,GAAG;AAC1C,UAAI,CAAC,OAAO;AACV,gBAAQ,CAAC;AACT,aAAK,kBAAkB,IAAI,KAAK,KAAK;AAAA,MACvC;AACA,YAAM,KAAK,KAAK;AAChB,UAAI,CAAC,KAAK,eAAe,IAAI,GAAG,GAAG;AACjC,aAAK,eAAe,IAAI,KAAK,WAAW,YAAY,GAAG,CAAC;AAAA,MAC1D;AAAA,IACF,CAAC;AAGD,UAAM,oBAAoB,YAAY,MAAM;AAC1C,eAAS,EAAE,MAAM,YAAY,CAAC;AAAA,IAChC,GAAG,IAAM;AAGT,UAAM,UAAU,MAAY;AAC1B,oBAAc,iBAAiB;AAC/B,YAAM,QAAQ,KAAK,eAAe,IAAI,GAAG;AACzC,UAAI,UAAU,QAAW;AACvB,qBAAa,KAAK;AAClB,aAAK,eAAe,OAAO,GAAG;AAAA,MAChC;AACA,WAAK,kBAAkB,OAAO,GAAG;AACjC,kBAAY;AACZ,WAAK,WAAW,OAAO,GAAG;AAC1B,WAAK,cAAc,OAAO,OAAO;AACjC,UAAI;AAAE,YAAI,IAAI;AAAA,MAAG,QAAQ;AAAA,MAAe;AAAA,IAC1C;AAKA,SAAK,cAAc,IAAI,OAAO;AAE9B,QAAI,KAAK,SAAS,OAAO;AACzB,QAAI,KAAK,SAAS,OAAO;AAAA,EAC3B;AAAA,EAEA,MAAc,iBAAiB,KAAsB,KAAoC;AACvF,UAAM,OAAO,MAAM,KAAK,aAAa,GAAG;AACxC,UAAM,UAAU;AAWhB,UAAM,WAAW,OAAO,QAAQ,QAAQ,SAAS,WAAW,QAAQ,OAAO,OAAO;AAClF,UAAM,WAAW,QAAQ,QAAQ;AACjC,UAAM,mBACH,aAAa,uBAAuB,aAAa,wBAClD,aAAa,QACb,OAAO,aAAa,YACpB,CAAC,MAAM,QAAQ,QAAQ,KACtB,SAAkC,WAAW;AAChD,UAAM,2BACH,aAAa,gCAAgC,aAAa,iCAC3D,aAAa,QACb,OAAO,aAAa,YACpB,CAAC,MAAM,QAAQ,QAAQ,KACtB,SAAkC,WAAW;AAChD,UAAM,aACJ,QAAQ,WAAW,iBAEjB,aAAa,yBACb,aAAa,yBACb,aAAa,8BACb,aAAa,8BACb,aAAa,oBACb,aAAa,oBACb,aAAa,iCACb,aAAa,iCACb,aAAa,kCACb,aAAa,kCACb,aAAa,2BACb,aAAa,2BACb,aAAa,2BACb,aAAa,2BAEX,CAAC,oBACA,aAAa,uBAAuB,aAAa,wBAGlD,CAAC,4BAEC,aAAa,gCACb,aAAa;AAIrB,QAAI,YAAY;AACd,WAAK,8BAA8B;AAAA,IACrC;AAEA,UAAM,aAAa,MAAM;AACvB,YAAM,MAAM,IAAI,QAAQ,gBAAgB;AACxC,aAAO,OAAO,QAAQ,WAAW,IAAI,KAAK,IAAI;AAAA,IAChD,GAAG;AACH,UAAM,mBAAmB,mBAAmB,SAAS,KAAK,WAAW;AACrE,UAAM,kBAAkB,KAAK,uBAAuB,GAAG;AACvD,UAAM,WAAW,MAAM,KAAK,UAAU,cAAc,SAAS;AAAA,MAC3D,mBAAmB,gBAAgB;AAAA,MACnC,mBAAmB,gBAAgB;AAAA,MACnC,oBAAoB,gBAAgB;AAAA,MACpC;AAAA,MACA,eAAe;AAAA,IACjB,CAAC;AAED,QAAI,cAAc,aAAa,MAAM;AACnC,YAAM,SAAU,SAAqC;AACrD,YAAM,UAAU,QAAQ,YAAY;AACpC,YAAM,aAAa,QAAQ;AAC3B,UAAI,CAAC,WAAW,cAAc,KAAK,0BAA0B,UAAU,GAAG;AACxE,aAAK,wBAAwB;AAAA,MAC/B;AAAA,IACF;AACA,QAAI,aAAa,MAAM;AACrB,UAAI,aAAa;AACjB,UAAI,IAAI;AACR;AAAA,IACF;AAGA,UAAM,oBAAoB,KAAK,UAAU,iBAAiB,gBAAgB;AAC1E,QAAI,mBAAmB;AACrB,UAAI,UAAU,kBAAkB,iBAAiB;AAAA,IACnD;AACA,SAAK,YAAY,KAAK,KAAK,QAAQ;AAAA,EACrC;AAAA,EAEQ,YAAY,KAAqB,QAAgB,SAAwB;AAC/E,UAAM,OAAO,KAAK,UAAU,SAAS,MAAM,CAAC;AAC5C,QAAI,aAAa;AACjB,QAAI,UAAU,gBAAgB,iCAAiC;AAC/D,QAAI,UAAU,kBAAkB,OAAO,OAAO,WAAW,IAAI,CAAC,CAAC;AAC/D,UAAM,MAAM,mBAAmB,SAAS;AACxC,QAAI,KAAK;AACP,UAAI,UAAU,gBAAgB,GAAG;AAAA,IACnC;AACA,QAAI,IAAI,IAAI;AAAA,EACd;AAAA,EAEA,MAAc,6BACZ,KACA,UACe;AACf,QAAI,aAAa;AACjB,QAAI,UAAU,gBAAgB,qCAAqC;AACnE,QAAI,UAAU,iBAAiB,UAAU;AACzC,UAAM,MAAM,mBAAmB,SAAS;AACxC,QAAI,KAAK;AACP,UAAI,UAAU,gBAAgB,GAAG;AAAA,IACnC;AACA,UAAM,sBAAsB,YAA8B,IAAI,QAAQ,CAAC,SAAS,WAAW;AACzF,YAAM,UAAU,MAAM;AACpB,YAAI,IAAI,SAAS,OAAO;AACxB,YAAI,IAAI,SAAS,OAAO;AACxB,YAAI,IAAI,SAAS,OAAO;AAAA,MAC1B;AACA,YAAM,UAAU,MAAM;AACpB,gBAAQ;AACR,gBAAQ,IAAI;AAAA,MACd;AACA,YAAM,UAAU,MAAM;AACpB,gBAAQ;AACR,gBAAQ,KAAK;AAAA,MACf;AACA,YAAM,UAAU,CAAC,UAAiB;AAChC,gBAAQ;AACR,eAAO,KAAK;AAAA,MACd;AACA,UAAI,KAAK,SAAS,OAAO;AACzB,UAAI,KAAK,SAAS,OAAO;AACzB,UAAI,KAAK,SAAS,OAAO;AAAA,IAC3B,CAAC;AACD,UAAM,YAAY,OAAO,YAAuC;AAC9D,UAAI,IAAI,aAAa,IAAI,cAAe,QAAO;AAC/C,UAAI,IAAI,MAAM,GAAG,KAAK,UAAU,OAAO,CAAC;AAAA,CAAI,EAAG,QAAO;AACtD,UAAI,IAAI,aAAa,IAAI,cAAe,QAAO;AAC/C,aAAO,oBAAoB;AAAA,IAC7B;AACA,QAAI,CAAC,MAAM,UAAU;AAAA,MACnB,MAAM;AAAA,MACN,WAAW,SAAS;AAAA,MACpB,QAAQ,SAAS;AAAA,MACjB,eAAe,SAAS;AAAA,MACxB,WAAW,SAAS;AAAA,MACpB,UAAU,SAAS;AAAA,MACnB,oBAAoB,SAAS;AAAA,IAC/B,CAAC,EAAG;AACJ,qBAAiB,QAAQ,SAAS,OAAO;AACvC,UAAI,CAAC,MAAM,UAAU,EAAE,MAAM,QAAQ,KAAK,CAAC,EAAG;AAAA,IAChD;AACA,QAAI,CAAC,IAAI,aAAa,CAAC,IAAI,eAAe;AACxC,UAAI,IAAI;AAAA,IACV;AAAA,EACF;AAAA,EAEQ,cACN,KACA,QACA,MACA,UAAkC,CAAC,GAC7B;AACN,QAAI,aAAa;AACjB,QAAI,UAAU,gBAAgB,0BAA0B;AACxD,QAAI,UAAU,kBAAkB,OAAO,KAAK,MAAM,CAAC;AACnD,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG;AAClD,UAAI,UAAU,KAAK,KAAK;AAAA,IAC1B;AACA,UAAM,MAAM,mBAAmB,SAAS;AACxC,QAAI,KAAK;AACP,UAAI,UAAU,gBAAgB,GAAG;AAAA,IACnC;AACA,QAAI,IAAI,IAAI;AAAA,EACd;AAAA,EAEA,MAAc,mBACZ,KACA,KACA,UACkB;AAClB,QAAI,IAAI,WAAW,MAAO,QAAO;AACjC,QAAI,aAAa,gBAAgB,aAAa,cAAc;AAC1D,UAAI,aAAa;AACjB,UAAI,UAAU,YAAY,WAAW,GAAG;AACxC,UAAI,IAAI;AACR,aAAO;AAAA,IACT;AACA,QAAI,aAAa,iBAAiB,aAAa,eAAe;AAC5D,YAAM,KAAK,cAAc,KAAK,KAAK,KAAK,KAAK,uBAAuB,YAAY,GAAG,0BAA0B;AAC7G,aAAO;AAAA,IACT;AACA,QAAI,aAAa,uBAAuB,aAAa,qBAAqB;AACxE,YAAM,KAAK,cAAc,KAAK,KAAK,KAAK,KAAK,uBAAuB,QAAQ,GAAG,uCAAuC;AACtH,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,cAAc,KAAqB,UAAkB,aAAoC;AACrG,QAAI;AACF,YAAM,OAAO,MAAM,SAAS,UAAU,OAAO;AAC7C,UAAI,aAAa;AACjB,UAAI,UAAU,gBAAgB,WAAW;AACzC,UAAI,UAAU,kBAAkB,OAAO,OAAO,WAAW,IAAI,CAAC,CAAC;AAC/D,UAAI,IAAI,IAAI;AAAA,IACd,QAAQ;AACN,WAAK,YAAY,KAAK,KAAK,EAAE,OAAO,YAAY,CAAC;AAAA,IACnD;AAAA,EACF;AAAA,EAEA,MAAc,aACZ,KACA,eAAe,KAAK,cACc;AAClC,UAAM,YAAY,KAAK,mBAAmB,KAAK,kBAAkB,KAAK,YAAY,YAAY;AAC9F,QAAI,aAAa,cAAc,aAAa,QAAQ;AAClD,YAAM,IAAI,UAAU,KAAK,gCAAgC,8BAA8B;AAAA,IACzF;AACA,UAAM,SAAmB,CAAC;AAC1B,QAAI,QAAQ;AACZ,qBAAiB,SAAS,KAAK;AAC7B,YAAM,SAAS,OAAO,SAAS,KAAK,IAAI,QAAQ,OAAO,KAAK,KAAK;AACjE,eAAS,OAAO;AAChB,UAAI,QAAQ,cAAc;AACxB,cAAM,IAAI,UAAU,KAAK,0BAA0B,wBAAwB;AAAA,MAC7E;AACA,aAAO,KAAK,MAAM;AAAA,IACpB;AACA,QAAI,OAAO,WAAW,EAAG,QAAO,CAAC;AACjC,QAAI,OAAO,OAAO,OAAO,QAAQ,KAAK;AACtC,QAAI,aAAa,QAAQ;AACvB,UAAI;AACF,eAAO,WAAW,MAAM,EAAE,iBAAiB,aAAa,CAAC;AAAA,MAC3D,SAAS,OAAO;AACd,YAAK,MAAgC,SAAS,wBAAwB;AACpE,gBAAM,IAAI,UAAU,KAAK,0BAA0B,wBAAwB;AAAA,QAC7E;AACA,cAAM,IAAI,UAAU,KAAK,qBAAqB,mBAAmB;AAAA,MACnE;AACA,UAAI,KAAK,aAAa,cAAc;AAClC,cAAM,IAAI,UAAU,KAAK,0BAA0B,wBAAwB;AAAA,MAC7E;AAAA,IACF;AACA,UAAM,MAAM,KAAK,SAAS,OAAO,EAAE,KAAK;AACxC,QAAI,IAAI,WAAW,EAAG,QAAO,CAAC;AAC9B,QAAI;AACJ,QAAI;AACF,eAAS,KAAK,MAAM,GAAG;AAAA,IACzB,QAAQ;AACN,YAAM,IAAI,UAAU,KAAK,gBAAgB,cAAc;AAAA,IACzD;AACA,QAAI,CAAC,UAAU,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,GAAG;AAClE,YAAM,IAAI,UAAU,KAAK,uBAAuB,qBAAqB;AAAA,IACvE;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,eAAe,KAAsB,UAAmC;AACpF,UAAM,SAAmB,CAAC;AAC1B,QAAI,QAAQ;AACZ,qBAAiB,SAAS,KAAK;AAC7B,YAAM,SAAS,OAAO,SAAS,KAAK,IAAI,QAAQ,OAAO,KAAK,KAAK;AACjE,eAAS,OAAO;AAChB,UAAI,QAAQ,UAAU;AACpB,cAAM,IAAI,UAAU,KAAK,0BAA0B,wBAAwB;AAAA,MAC7E;AACA,aAAO,KAAK,MAAM;AAAA,IACpB;AACA,WAAO,OAAO,OAAO,QAAQ,KAAK;AAAA,EACpC;AAAA,EAEQ,mBAAmB,KAAsB,MAAsB;AACrE,UAAM,QAAQ,KAAK,mBAAmB,KAAK,IAAI;AAC/C,QAAI,UAAU,UAAa,MAAM,WAAW,GAAG;AAC7C,YAAM,IAAI,uBAAuB,GAAG,IAAI,qBAAqB;AAAA,IAC/D;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,mBAAmB,KAAsB,MAAkC;AACjF,UAAM,MAAM,IAAI,QAAQ,KAAK,YAAY,CAAC;AAC1C,QAAI,MAAM,QAAQ,GAAG,EAAG,QAAO,IAAI,CAAC,GAAG,KAAK,KAAK;AACjD,WAAO,KAAK,KAAK,KAAK;AAAA,EACxB;AAAA,EAEQ,0BAA0B,KAAsB,MAAsB;AAC5E,UAAM,MAAM,KAAK,mBAAmB,KAAK,IAAI;AAC7C,QAAI;AACF,aAAO,mBAAmB,GAAG;AAAA,IAC/B,QAAQ;AACN,YAAM,IAAI,uBAAuB,GAAG,IAAI,4CAA4C;AAAA,IACtF;AAAA,EACF;AAAA,EAEQ,0BAA0B,KAAsB,MAAsB;AAC5E,UAAM,MAAM,KAAK,mBAAmB,KAAK,IAAI;AAC7C,UAAM,SAAS,OAAO,GAAG;AACzB,QAAI,CAAC,OAAO,UAAU,MAAM,KAAK,SAAS,GAAG;AAC3C,YAAM,IAAI,uBAAuB,GAAG,IAAI,wCAAwC;AAAA,IAClF;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,0BAA0B,KAAsB,MAAkC;AACxF,UAAM,MAAM,KAAK,mBAAmB,KAAK,IAAI;AAC7C,QAAI,QAAQ,OAAW,QAAO;AAC9B,UAAM,SAAS,OAAO,GAAG;AACzB,QAAI,CAAC,OAAO,UAAU,MAAM,KAAK,SAAS,GAAG;AAC3C,YAAM,IAAI,uBAAuB,GAAG,IAAI,wCAAwC;AAAA,IAClF;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,yBAAyB,KAAsB,MAAsB;AAC3E,UAAM,MAAM,KAAK,mBAAmB,KAAK,IAAI;AAC7C,UAAM,SAAS,OAAO,GAAG;AACzB,QAAI,CAAC,OAAO,SAAS,MAAM,KAAK,SAAS,GAAG;AAC1C,YAAM,IAAI,uBAAuB,GAAG,IAAI,8CAA8C;AAAA,IACxF;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,2BACN,KACA,MACA,cACS;AACT,UAAM,MAAM,KAAK,mBAAmB,KAAK,IAAI;AAC7C,QAAI,QAAQ,OAAW,QAAO;AAC9B,QAAI,QAAQ,OAAQ,QAAO;AAC3B,QAAI,QAAQ,QAAS,QAAO;AAC5B,UAAM,IAAI,uBAAuB,GAAG,IAAI,qCAAqC;AAAA,EAC/E;AAAA,EAEA,MAAc,kBACZ,KACA,YACA,cAC2B;AAC3B,UAAM,MAAM,MAAM,KAAK,aAAa,KAAK,YAAY;AACrD,UAAM,SAAS,gBAAgB,YAAY,GAAG;AAC9C,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,IAAI,UAAU,KAAK,OAAO,MAAM,OAAO,oBAAoB,OAAO,MAAM,OAAO;AAAA,IACvF;AACA,WAAO,OAAO;AAAA,EAChB;AAAA,EAEQ,aAAa,KAAsB,UAA4B;AACrE,QAAI,CAAC,KAAK,aAAa,KAAK,WAAW,WAAW,KAAK,CAAC,KAAK,iBAAkB,QAAO;AAEtF,UAAM,MAAM,IAAI,QAAQ;AACxB,QAAI,YAA2B;AAC/B,QAAI,KAAK;AACP,YAAM,YAAY,IAAI,QAAQ,GAAG;AACjC,UAAI,YAAY,GAAG;AACjB,cAAM,SAAS,IAAI,MAAM,GAAG,SAAS,EAAE,YAAY;AACnD,YAAI,WAAW,UAAU;AACvB,sBAAY,IAAI,MAAM,YAAY,CAAC,EAAE,KAAK;AAAA,QAC5C;AAAA,MACF;AAAA,IACF;AASA,QAAI,CAAC,aAAa,aAAa,2BAA2B;AACxD,UAAI;AACF,cAAM,SAAS,IAAI,IAAI,IAAI,OAAO,KAAK,UAAU,mBAAmB,KAAK,IAAI,CAAC,EAAE;AAChF,cAAM,aAAa,OAAO,aAAa,IAAI,OAAO;AAClD,YAAI,cAAc,WAAW,SAAS,GAAG;AACvC,sBAAY;AAAA,QACd;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AACA,QAAI,CAAC,UAAW,QAAO;AACvB,UAAM,QAAQ;AAEd,QAAI,KAAK,aAAa,KAAK,sBAAsB,OAAO,KAAK,SAAS,EAAG,QAAO;AAEhF,eAAW,SAAS,KAAK,YAAY;AACnC,UAAI,KAAK,sBAAsB,OAAO,KAAK,EAAG,QAAO;AAAA,IACvD;AAEA,QAAI,KAAK,kBAAkB;AACzB,iBAAW,SAAS,KAAK,iBAAiB,GAAG;AAC3C,YAAI,KAAK,sBAAsB,OAAO,KAAK,EAAG,QAAO;AAAA,MACvD;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,sBAAsB,GAAW,GAAoB;AAC3D,UAAM,OAAO,KAAK,aAAa,CAAC;AAChC,UAAM,QAAQ,KAAK,aAAa,CAAC;AACjC,QAAI,CAAC,QAAQ,CAAC,MAAO,QAAO;AAC5B,WAAO,gBAAgB,MAAM,KAAK;AAAA,EACpC;AAAA,EAEQ,aAAa,OAA8B;AACjD,UAAM,UAAU,OAAO,KAAK,OAAO,OAAO;AAC1C,QAAI,QAAQ,SAAS,KAAM,QAAO;AAClC,UAAM,MAAM,OAAO,MAAM,IAAI,IAAI;AACjC,QAAI,cAAc,QAAQ,QAAQ,CAAC;AACnC,YAAQ,KAAK,KAAK,CAAC;AACnB,WAAO;AAAA,EACT;AAAA,EAEQ,oBAAoB,UAAuD;AACjF,QAAI,SAAS,WAAW,KAAM,QAAO;AACrC,QAAI,SAAS,WAAW,YAAY,SAAS,WAAW,oBAAqB,QAAO;AACpF,WAAO;AAAA,EACT;AAAA,EAEQ,gCAAsC;AAC5C,UAAM,MAAM,KAAK,IAAI;AACrB,WACE,KAAK,uBAAuB,SAAS,KACrC,OAAO,KAAK,uBAAuB,CAAC,KAAK,KAAK,4BAC9C;AACA,WAAK,uBAAuB,MAAM;AAAA,IACpC;AACA,QAAI,KAAK,uBAAuB,UAAU,+BAA+B;AACvE,YAAM,IAAI,UAAU,KAAK,sBAAsB,oBAAoB;AAAA,IACrE;AAAA,EACF;AAAA,EAEQ,0BAAgC;AACtC,SAAK,uBAAuB,KAAK,KAAK,IAAI,CAAC;AAAA,EAC7C;AAAA,EAEQ,0BAA0B,UAAsE;AACtG,WAAO,SAAS,WAAW,QAAQ,SAAS,sBAAsB;AAAA,EACpE;AACF;","names":["result"]}