@nifrajs/cli 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/docs/types.json CHANGED
@@ -303,6 +303,90 @@
303
303
  "signature": "export declare function applyResponseHeaders(headers: Headers, res: NodeHeaderSink): void;",
304
304
  "doc": "/**\n * Copy a Web `Response`'s headers onto a Node response, emitting EACH `Set-Cookie` as its own header. The\n * `Headers` iterator (and `.get`) join multiple set-cookie values with \", \", which corrupts cookies — e.g.\n * better-auth's `session_token` + `session_data` collapse into one unparseable cookie and the session is\n * silently lost. `getSetCookie()` returns them split; Node's `setHeader` emits one header per array element.\n */"
305
305
  },
306
+ {
307
+ "name": "ApprovalBindingError",
308
+ "kind": "class",
309
+ "package": "@nifrajs/core",
310
+ "signature": "export declare class ApprovalBindingError extends Error {\n constructor();\n}"
311
+ },
312
+ {
313
+ "name": "ApprovalConsumeResult",
314
+ "kind": "type",
315
+ "package": "@nifrajs/core",
316
+ "signature": "export type ApprovalConsumeResult = {\n readonly state: \"consumed\";\n} | {\n readonly state: \"missing\" | \"pending\" | \"denied\" | \"expired\" | \"replay\" | \"binding\" | \"token\";\n};"
317
+ },
318
+ {
319
+ "name": "ApprovalCoordinator",
320
+ "kind": "interface",
321
+ "package": "@nifrajs/core",
322
+ "signature": "export interface ApprovalCoordinator extends CapabilityApprovalGate {\n decide(input: {\n readonly approvalId: string;\n readonly tenantId: string;\n readonly decision: \"approved\" | \"denied\";\n readonly decidedBy: string;\n }): Promise<void>;\n get(approvalId: string): Promise<ApprovalRecord | undefined>;\n}"
323
+ },
324
+ {
325
+ "name": "ApprovalCoordinatorOptions",
326
+ "kind": "interface",
327
+ "package": "@nifrajs/core",
328
+ "signature": "export interface ApprovalCoordinatorOptions {\n readonly store: ApprovalStore;\n /** At least 32 random bytes, kept separately from the approval store. */\n readonly secret: Uint8Array;\n readonly ttlMs?: number;\n readonly now?: () => number;\n /** Tests/local development only. Production approval records require a durable store. */\n readonly allowMemoryStore?: boolean;\n}"
329
+ },
330
+ {
331
+ "name": "ApprovalDeniedError",
332
+ "kind": "class",
333
+ "package": "@nifrajs/core",
334
+ "signature": "export declare class ApprovalDeniedError extends Error {\n constructor();\n}"
335
+ },
336
+ {
337
+ "name": "ApprovalPendingError",
338
+ "kind": "class",
339
+ "package": "@nifrajs/core",
340
+ "signature": "export declare class ApprovalPendingError extends Error {\n constructor();\n}"
341
+ },
342
+ {
343
+ "name": "ApprovalRecord",
344
+ "kind": "interface",
345
+ "package": "@nifrajs/core",
346
+ "signature": "export interface ApprovalRecord {\n readonly approvalId: string;\n readonly effectId: string;\n readonly capability: string;\n readonly target?: string;\n readonly digest?: string;\n readonly tenantId: string;\n readonly principalId: string;\n readonly tokenHash: string;\n readonly state: ApprovalState;\n readonly createdAt: number;\n readonly expiresAt: number;\n readonly updatedAt: number;\n readonly decidedBy?: string;\n readonly version: number;\n}"
347
+ },
348
+ {
349
+ "name": "ApprovalRequiredError",
350
+ "kind": "class",
351
+ "package": "@nifrajs/core",
352
+ "signature": "export declare class ApprovalRequiredError extends Error {\n readonly approvalId: string;\n readonly effectId: string;\n readonly resumeToken: string;\n readonly expiresAt: number;\n constructor(approvalId: string, effectId: string, resumeToken: string, expiresAt: number);\n}"
353
+ },
354
+ {
355
+ "name": "ApprovalState",
356
+ "kind": "type",
357
+ "package": "@nifrajs/core",
358
+ "signature": "export type ApprovalState = \"pending\" | \"approved\" | \"denied\" | \"consumed\" | \"expired\";"
359
+ },
360
+ {
361
+ "name": "ApprovalStore",
362
+ "kind": "interface",
363
+ "package": "@nifrajs/core",
364
+ "signature": "export interface ApprovalStore {\n readonly durability?: \"memory\" | \"durable\";\n create(record: ApprovalRecord): boolean | Promise<boolean>;\n get(approvalId: string): ApprovalRecord | undefined | Promise<ApprovalRecord | undefined>;\n decide(input: {\n readonly approvalId: string;\n readonly tenantId: string;\n readonly decision: \"approved\" | \"denied\";\n readonly decidedBy: string;\n readonly now: number;\n }): boolean | Promise<boolean>;\n /**\n * Atomically validate binding/token/state and change `approved` to `consumed`. Two concurrent\n * callers with one token must yield exactly one `consumed` and one `replay` result.\n */\n consume(input: {\n readonly approvalId: string;\n readonly tenantId: string;\n readonly principalId: string;\n readonly capability: string;\n readonly target?: string;\n readonly digest?: string;\n readonly tokenHash: string;\n readonly now: number;\n }): ApprovalConsumeResult | Promise<ApprovalConsumeResult>;\n}"
365
+ },
366
+ {
367
+ "name": "ApprovalTokenExpiredError",
368
+ "kind": "class",
369
+ "package": "@nifrajs/core",
370
+ "signature": "export declare class ApprovalTokenExpiredError extends Error {\n constructor();\n}"
371
+ },
372
+ {
373
+ "name": "ApprovalTokenInvalidError",
374
+ "kind": "class",
375
+ "package": "@nifrajs/core",
376
+ "signature": "export declare class ApprovalTokenInvalidError extends Error {\n constructor();\n}"
377
+ },
378
+ {
379
+ "name": "ApprovalTokenReplayError",
380
+ "kind": "class",
381
+ "package": "@nifrajs/core",
382
+ "signature": "export declare class ApprovalTokenReplayError extends Error {\n constructor();\n}"
383
+ },
384
+ {
385
+ "name": "AroundCapabilityOptions",
386
+ "kind": "interface",
387
+ "package": "@nifrajs/core",
388
+ "signature": "export interface AroundCapabilityOptions {\n /** Maximum admission time in milliseconds. Default 30_000. */\n readonly timeoutMs?: number;\n}"
389
+ },
306
390
  {
307
391
  "name": "assertAdapterCertification",
308
392
  "kind": "function",
@@ -648,6 +732,12 @@
648
732
  "package": "@nifrajs/middleware",
649
733
  "signature": "export interface BearerOptions<P> {\n /** Verify a bearer token → a principal (truthy) or `null`/`undefined` (rejected). May be async\n * (DB/JWT lookup). For a constant-secret comparison, use a constant-time compare — never `===`. */\n readonly verify: (token: string) => MaybePromise<P | null | undefined>;\n /** When `true`, requests without a valid token pass through (`principal` is `null`) instead of `401`. */\n readonly optional?: boolean;\n /** `realm` for the `WWW-Authenticate: Bearer` header on `401`. Default `\"api\"`. */\n readonly realm?: string;\n}"
650
734
  },
735
+ {
736
+ "name": "beginRequestEffectTracking",
737
+ "kind": "function",
738
+ "package": "@nifrajs/core",
739
+ "signature": "export declare function beginRequestEffectTracking(request: Request): EffectEvidenceScope;"
740
+ },
651
741
  {
652
742
  "name": "betterAuth",
653
743
  "kind": "function",
@@ -981,6 +1071,25 @@
981
1071
  "package": "@nifrajs/core",
982
1072
  "signature": "export type CapabilityAccess = \"read\" | \"write\";"
983
1073
  },
1074
+ {
1075
+ "name": "CapabilityAdmissionAbortedError",
1076
+ "kind": "class",
1077
+ "package": "@nifrajs/core",
1078
+ "signature": "export declare class CapabilityAdmissionAbortedError extends Error {\n readonly capability: string;\n readonly effectId: string;\n constructor(capability: string, effectId: string);\n}",
1079
+ "doc": "/** The request was cancelled while capability admission was pending. */"
1080
+ },
1081
+ {
1082
+ "name": "CapabilityApprovalGate",
1083
+ "kind": "interface",
1084
+ "package": "@nifrajs/core",
1085
+ "signature": "export interface CapabilityApprovalGate {\n authorize(input: {\n readonly effectId: string;\n readonly capability: string;\n readonly target?: string;\n readonly digest?: string;\n readonly identity: CapabilityExecutionIdentity;\n readonly resumeToken?: string;\n readonly signal: AbortSignal;\n }): void | PromiseLike<void>;\n}"
1086
+ },
1087
+ {
1088
+ "name": "CapabilityApprovalInput",
1089
+ "kind": "interface",
1090
+ "package": "@nifrajs/core",
1091
+ "signature": "export interface CapabilityApprovalInput extends CapabilityExecutionIdentity {\n /** Signed token returned by the approval coordinator after the first suspended attempt. */\n readonly resumeToken?: string;\n}"
1092
+ },
984
1093
  {
985
1094
  "name": "CapabilityAssuranceReport",
986
1095
  "kind": "interface",
@@ -993,6 +1102,13 @@
993
1102
  "package": "@nifrajs/core",
994
1103
  "signature": "export interface CapabilityDefinition {\n readonly id: string;\n /** Domain state is subject to HTTP method semantics; operational writes (logs/metrics) are not. */\n readonly zone: CapabilityZone;\n readonly access: CapabilityAccess;\n /** Evidence required when this capability may execute. Default `none`. */\n readonly idempotency?: CapabilityIdempotency;\n}"
995
1104
  },
1105
+ {
1106
+ "name": "CapabilityDeniedError",
1107
+ "kind": "class",
1108
+ "package": "@nifrajs/core",
1109
+ "signature": "export declare class CapabilityDeniedError extends Error {\n readonly capability: string;\n readonly effectId: string;\n constructor(capability: string, effectId: string);\n}",
1110
+ "doc": "/** A capability admission policy returned without calling `next()`. */"
1111
+ },
996
1112
  {
997
1113
  "name": "CapabilityEvidence",
998
1114
  "kind": "interface",
@@ -1012,6 +1128,40 @@
1012
1128
  "package": "@nifrajs/core",
1013
1129
  "signature": "export interface CapabilityEvidenceSet {\n readonly routes: readonly RouteCapabilityEvidence[];\n}"
1014
1130
  },
1131
+ {
1132
+ "name": "CapabilityExecutionContext",
1133
+ "kind": "interface",
1134
+ "package": "@nifrajs/core",
1135
+ "signature": "export interface CapabilityExecutionContext {\n readonly effectId: string;\n readonly signal: AbortSignal;\n}",
1136
+ "doc": "/** Context passed to the owned effect callback. Use the signal for cancellation-aware I/O. */"
1137
+ },
1138
+ {
1139
+ "name": "CapabilityExecutionIdentity",
1140
+ "kind": "interface",
1141
+ "package": "@nifrajs/core",
1142
+ "signature": "export interface CapabilityExecutionIdentity {\n readonly tenantId: string;\n readonly principalId: string;\n}",
1143
+ "doc": "/** Server-owned identity binding for durable admission. Values are opaque tokens, never payloads. */"
1144
+ },
1145
+ {
1146
+ "name": "CapabilityExecutionJournal",
1147
+ "kind": "interface",
1148
+ "package": "@nifrajs/core",
1149
+ "signature": "export interface CapabilityExecutionJournal {\n intent(input: {\n readonly effectId: string;\n readonly capability: string;\n readonly target?: string;\n readonly digest?: string;\n readonly identity?: CapabilityExecutionIdentity;\n }): void | PromiseLike<void>;\n executing(effectId: string): void | PromiseLike<void>;\n committed(effectId: string): void | PromiseLike<void>;\n failed(effectId: string, input: {\n readonly began: boolean;\n readonly errorCode: string;\n }): void | PromiseLike<void>;\n}",
1150
+ "doc": "/** Durable, token-only journal seam. Implementations must fail closed on transition failure. */"
1151
+ },
1152
+ {
1153
+ "name": "CapabilityExecutionOptions",
1154
+ "kind": "interface",
1155
+ "package": "@nifrajs/core",
1156
+ "signature": "export interface CapabilityExecutionOptions extends UseCapabilityOptions {\n readonly approval?: CapabilityApprovalInput & {\n readonly gate: CapabilityApprovalGate;\n };\n readonly journal?: CapabilityExecutionJournal;\n}",
1157
+ "doc": "/** Durable controls consumed by `executeCapability`; none of these fields enter the effect ledger. */"
1158
+ },
1159
+ {
1160
+ "name": "CapabilityExecutor",
1161
+ "kind": "type",
1162
+ "package": "@nifrajs/core",
1163
+ "signature": "export type CapabilityExecutor<T> = (execution: CapabilityExecutionContext) => T | PromiseLike<T>;"
1164
+ },
1015
1165
  {
1016
1166
  "name": "CapabilityFinding",
1017
1167
  "kind": "interface",
@@ -1028,7 +1178,7 @@
1028
1178
  "name": "CapabilityGuard",
1029
1179
  "kind": "interface",
1030
1180
  "package": "@nifrajs/core",
1031
- "signature": "export interface CapabilityGuard {\n readonly allowed: readonly string[];\n readonly method: string;\n readonly path: string;\n readonly onUse?: (event: CapabilityUseEvent) => void;\n}"
1181
+ "signature": "export interface CapabilityGuard {\n readonly allowed: readonly string[];\n readonly method: string;\n readonly path: string;\n readonly onUse?: (event: CapabilityUseEvent) => void;\n readonly trackEffect?: (context: object, committed: boolean) => void;\n readonly interceptors: readonly RegisteredCapabilityInterceptor[];\n readonly observers: readonly EffectLifecycleObserver[];\n}"
1032
1182
  },
1033
1183
  {
1034
1184
  "name": "CapabilityIdempotency",
@@ -1048,6 +1198,47 @@
1048
1198
  "package": "@nifrajs/cli",
1049
1199
  "signature": "export interface CapabilityImportViolation {\n readonly method: string;\n readonly path: string;\n readonly module: string;\n readonly specifier: string;\n readonly reason: string;\n readonly chain: readonly string[];\n}"
1050
1200
  },
1201
+ {
1202
+ "name": "CapabilityInterceptor",
1203
+ "kind": "type",
1204
+ "package": "@nifrajs/core",
1205
+ "signature": "export type CapabilityInterceptor = (event: CapabilityInterceptorEvent, next: CapabilityInterceptorNext) => void | PromiseLike<void>;"
1206
+ },
1207
+ {
1208
+ "name": "CapabilityInterceptorEvent",
1209
+ "kind": "interface",
1210
+ "package": "@nifrajs/core",
1211
+ "signature": "export interface CapabilityInterceptorEvent extends CapabilityUseEvent {\n readonly effectId: string;\n readonly signal: AbortSignal;\n readonly target?: string;\n readonly cost?: EffectCost;\n readonly digest?: string;\n}",
1212
+ "doc": "/** Token-only metadata supplied to an asynchronous capability admission interceptor. */"
1213
+ },
1214
+ {
1215
+ "name": "CapabilityInterceptorNext",
1216
+ "kind": "type",
1217
+ "package": "@nifrajs/core",
1218
+ "signature": "export type CapabilityInterceptorNext = () => Promise<void>;",
1219
+ "doc": "/** Continue to the next admission policy. The owned effect runs only after the full chain admits. */"
1220
+ },
1221
+ {
1222
+ "name": "CapabilityInterceptorProtocolError",
1223
+ "kind": "class",
1224
+ "package": "@nifrajs/core",
1225
+ "signature": "export declare class CapabilityInterceptorProtocolError extends Error {\n readonly capability: string;\n readonly effectId: string;\n constructor(capability: string, effectId: string);\n}",
1226
+ "doc": "/** An interceptor called its one-shot `next()` continuation more than once. */"
1227
+ },
1228
+ {
1229
+ "name": "CapabilityInterceptorTimeoutError",
1230
+ "kind": "class",
1231
+ "package": "@nifrajs/core",
1232
+ "signature": "export declare class CapabilityInterceptorTimeoutError extends Error {\n readonly capability: string;\n readonly effectId: string;\n readonly timeoutMs: number;\n constructor(capability: string, effectId: string, timeoutMs: number);\n}",
1233
+ "doc": "/** A capability admission policy exceeded its configured bound. */"
1234
+ },
1235
+ {
1236
+ "name": "CapabilityJournalTransitionError",
1237
+ "kind": "class",
1238
+ "package": "@nifrajs/core",
1239
+ "signature": "export declare class CapabilityJournalTransitionError extends Error {\n readonly capability: string;\n readonly effectId: string;\n readonly transition: \"committed\";\n constructor(capability: string, effectId: string, transition: \"committed\");\n}",
1240
+ "doc": "/** The effect may have committed, but its durable terminal transition could not be recorded. */"
1241
+ },
1051
1242
  {
1052
1243
  "name": "CapabilityOutcomeOptions",
1053
1244
  "kind": "interface",
@@ -1456,7 +1647,7 @@
1456
1647
  "name": "ClientOptions",
1457
1648
  "kind": "interface",
1458
1649
  "package": "@nifrajs/client",
1459
- "signature": "export interface ClientOptions {\n /** Headers sent on every request (a per-call `headers` option is merged on top). */\n readonly headers?: Record<string, string>;\n /** Override the `fetch` implementation (tests, an in-process bridge, a custom agent, etc.). */\n readonly fetch?: FetchFn;\n /**\n * Runs before each request (including each retry). Return a header map to MERGE onto the outgoing\n * request — the place to inject a fresh auth token. `await`ed, so async token refresh works.\n */\n readonly onRequest?: (request: {\n readonly url: string;\n readonly method: string;\n readonly headers: Record<string, string>;\n readonly body: unknown;\n }) => MaybePromise<Record<string, string> | undefined>;\n /** Runs after a response arrives (once per call, on the final response). Observe-only. */\n readonly onResponse?: (response: {\n readonly url: string;\n readonly method: string;\n readonly response: Response;\n }) => MaybePromise<void>;\n /** Abort a call that takes longer than this many ms. Surfaces as `{ ok: false, status: 0 }` with a\n * `timeout` error, never a throw. Combined with a per-call `signal`. */\n readonly timeoutMs?: number;\n /** Enable safe automatic retries. See {@link ClientRetryOptions}. */\n readonly retry?: ClientRetryOptions;\n}"
1650
+ "signature": "export interface ClientOptions {\n /** Headers sent on every request (a per-call `headers` option is merged on top). */\n readonly headers?: Record<string, string>;\n /** Override the `fetch` implementation (tests, an in-process bridge, a custom agent, etc.). */\n readonly fetch?: FetchFn;\n /**\n * Runs before each request (including each retry). Return a header map to MERGE onto the outgoing\n * request — the place to inject a fresh auth token. `await`ed, so async token refresh works.\n */\n readonly onRequest?: (request: {\n readonly url: string;\n readonly method: string;\n readonly headers: Record<string, string>;\n readonly body: unknown;\n }) => MaybePromise<Record<string, string> | undefined>;\n /** Runs after a response arrives (once per call, on the final response). Observe-only. */\n readonly onResponse?: (response: {\n readonly url: string;\n readonly method: string;\n readonly response: Response;\n }) => MaybePromise<void>;\n /** Abort a call that takes longer than this many ms. Surfaces as `{ ok: false, status: 0 }` with a\n * `timeout` error, never a throw. Combined with a per-call `signal`. */\n readonly timeoutMs?: number;\n /** Enable safe automatic retries. See {@link ClientRetryOptions}. */\n readonly retry?: ClientRetryOptions;\n /**\n * Opt into a versioned transport representation. Plain JSON remains the default. Responses are\n * decoded through the bounded registry, and WebSocket frames use the same codec.\n */\n readonly transport?: {\n readonly codec: TransportCodec;\n readonly registry?: TransportCodecRegistry;\n readonly maxBytes?: number;\n };\n}"
1460
1651
  },
1461
1652
  {
1462
1653
  "name": "ClientRetryOptions",
@@ -1962,6 +2153,12 @@
1962
2153
  "signature": "export declare function createAdmissionController(options: AdmissionOptions): AdmissionControllerHandle;",
1963
2154
  "doc": "/**\n * Build a capacity-admission controller. Pass the returned handle as the server's `admission` option.\n */"
1964
2155
  },
2156
+ {
2157
+ "name": "createApprovalCoordinator",
2158
+ "kind": "function",
2159
+ "package": "@nifrajs/core",
2160
+ "signature": "export declare function createApprovalCoordinator(options: ApprovalCoordinatorOptions): ApprovalCoordinator;"
2161
+ },
1965
2162
  {
1966
2163
  "name": "createBunWsHandlers",
1967
2164
  "kind": "function",
@@ -1987,7 +2184,7 @@
1987
2184
  "name": "createCapabilityGuard",
1988
2185
  "kind": "function",
1989
2186
  "package": "@nifrajs/core",
1990
- "signature": "export declare function createCapabilityGuard(allowed: readonly string[], method: string, path: string, onUse: ((event: CapabilityUseEvent) => void) | undefined): CapabilityGuard;"
2187
+ "signature": "export declare function createCapabilityGuard(allowed: readonly string[], method: string, path: string, onUse: ((event: CapabilityUseEvent) => void) | undefined, trackEffect: ((context: object, committed: boolean) => void) | undefined, interceptors: readonly RegisteredCapabilityInterceptor[], observers: readonly EffectLifecycleObserver[]): CapabilityGuard;"
1991
2188
  },
1992
2189
  {
1993
2190
  "name": "createClientRouter",
@@ -2009,6 +2206,25 @@
2009
2206
  "signature": "export declare function createDevServer(options: DevServerOptions): Promise<DevServer>;",
2010
2207
  "doc": "/** Start the dev server: build → serve → watch → rebuild + reload on change. */"
2011
2208
  },
2209
+ {
2210
+ "name": "createDurableEffectJournal",
2211
+ "kind": "function",
2212
+ "package": "@nifrajs/core",
2213
+ "signature": "export declare function createDurableEffectJournal(options: DurableEffectJournalOptions): CapabilityExecutionJournal;"
2214
+ },
2215
+ {
2216
+ "name": "createDurableExecutionAdapter",
2217
+ "kind": "function",
2218
+ "package": "@nifrajs/core",
2219
+ "signature": "export declare function createDurableExecutionAdapter(backend: DurableRecordBackend): DurableExecutionAdapter;"
2220
+ },
2221
+ {
2222
+ "name": "createEffectEvidenceScope",
2223
+ "kind": "function",
2224
+ "package": "@nifrajs/core",
2225
+ "signature": "export declare function createEffectEvidenceScope(): EffectEvidenceScope;",
2226
+ "doc": "/** Lightweight aggregate evidence shared by request idempotency and full owned-effect runners. */"
2227
+ },
2012
2228
  {
2013
2229
  "name": "createEffectLedgerRuntime",
2014
2230
  "kind": "function",
@@ -2016,6 +2232,12 @@
2016
2232
  "signature": "export declare function createEffectLedgerRuntime(options: EffectLedgerOptions): EffectLedgerRuntime;",
2017
2233
  "doc": "/**\n * Build an effect-ledger runtime from the app-wide options. `sink` receives the sealed, token-only\n * ledger when a capability-declaring route settles with recorded entries; `maxEntries` bounds a single\n * request's ledger; `chain` opts into the per-entry hash chain.\n */"
2018
2234
  },
2235
+ {
2236
+ "name": "createEffectScope",
2237
+ "kind": "function",
2238
+ "package": "@nifrajs/core",
2239
+ "signature": "export declare function createEffectScope(options?: EffectScopeOptions, evidenceScope?: EffectEvidenceScope): EffectScope;"
2240
+ },
2019
2241
  {
2020
2242
  "name": "createEventLoopLagSampler",
2021
2243
  "kind": "function",
@@ -2192,6 +2414,12 @@
2192
2414
  "package": "@nifrajs/core",
2193
2415
  "signature": "export interface CreateRequestLedgerOptions {\n /** HTTP method of the matched route. */\n readonly method: string;\n /** The registered route pattern — callers must never pass the concrete request URL. */\n readonly path: string;\n /** The route's declared capability tokens, surfaced verbatim on the sealed ledger. Default `[]`. */\n readonly declared?: readonly string[];\n /** Entry bound; exceeding it throws {@link EffectLedgerOverflowError}. Default {@link DEFAULT_MAX_ENTRIES}. */\n readonly maxEntries?: number;\n /** Compute the tamper-evident hash chain at seal. Default false. */\n readonly chain?: boolean;\n /** Injectable monotonic clock (ms) for deterministic tests. Default `performance.now`. */\n readonly clock?: () => number;\n}"
2194
2416
  },
2417
+ {
2418
+ "name": "createSagaEngine",
2419
+ "kind": "function",
2420
+ "package": "@nifrajs/core",
2421
+ "signature": "export declare function createSagaEngine(options: SagaEngineOptions): SagaEngine;"
2422
+ },
2195
2423
  {
2196
2424
  "name": "createScheduler",
2197
2425
  "kind": "function",
@@ -2212,6 +2440,12 @@
2212
2440
  "signature": "export declare function createStylesheetEmitter(build: PluginBuilder, namespace: string): StylesheetEmitter;",
2213
2441
  "doc": "/**\n * Wire the virtual-CSS-module handlers onto `build` for `namespace`, returning an {@link StylesheetEmitter}.\n * The `namespace` must be a plain identifier (letters/`-`); it's used verbatim as the import suffix and\n * the Bun namespace. Only the `\"dom\"` build should emit CSS — the `\"ssr\"` build ships no stylesheet.\n */"
2214
2442
  },
2443
+ {
2444
+ "name": "createTransportCodecRegistry",
2445
+ "kind": "function",
2446
+ "package": "@nifrajs/core",
2447
+ "signature": "export declare function createTransportCodecRegistry(codecs: readonly TransportCodec[], fallback?: TransportCodec): TransportCodecRegistry;"
2448
+ },
2215
2449
  {
2216
2450
  "name": "createUnboundedRequestBudget",
2217
2451
  "kind": "function",
@@ -2416,6 +2650,13 @@
2416
2650
  "signature": "export declare function declaredCapabilities(context: object): readonly string[];",
2417
2651
  "doc": "/**\n * Read the route's token-only declaration for admission plugins. This intentionally exposes neither\n * the request nor runtime evidence; it is the stable public seam for private entitlement policy.\n */"
2418
2652
  },
2653
+ {
2654
+ "name": "decode",
2655
+ "kind": "function",
2656
+ "package": "@nifrajs/core",
2657
+ "signature": "export declare function decode(wire: Wire, limits?: WireDecodeLimits): unknown;",
2658
+ "doc": "/** Reconstruct the original value from a {@link Wire} form produced by {@link encode}. */"
2659
+ },
2419
2660
  {
2420
2661
  "name": "decodeBase64",
2421
2662
  "kind": "function",
@@ -2443,12 +2684,30 @@
2443
2684
  "signature": "export declare function decodeRouteParams(raw: Record<string, string>): Record<string, string> | null;",
2444
2685
  "doc": "/** Decode router captures under one rule. Plain values take the zero-allocation path; malformed\n * escapes return `null`, allowing HTTP to emit 400 while client navigation declines the match. */"
2445
2686
  },
2687
+ {
2688
+ "name": "decodeTransportFrame",
2689
+ "kind": "function",
2690
+ "package": "@nifrajs/core",
2691
+ "signature": "export declare function decodeTransportFrame(frame: string, registry?: TransportCodecRegistry, options?: TransportDecodeOptions): unknown;"
2692
+ },
2693
+ {
2694
+ "name": "decodeTransportResponse",
2695
+ "kind": "function",
2696
+ "package": "@nifrajs/core",
2697
+ "signature": "export declare function decodeTransportResponse(response: Response, registry?: TransportCodecRegistry, options?: TransportDecodeOptions): Promise<unknown>;"
2698
+ },
2446
2699
  {
2447
2700
  "name": "DEFAULT_ASSURANCE_CONFIG",
2448
2701
  "kind": "const",
2449
2702
  "package": "@nifrajs/cli",
2450
2703
  "signature": "export declare const DEFAULT_ASSURANCE_CONFIG = \"nifra.assurance.ts\";"
2451
2704
  },
2705
+ {
2706
+ "name": "DEFAULT_CAPABILITY_INTERCEPTOR_TIMEOUT_MS",
2707
+ "kind": "const",
2708
+ "package": "@nifrajs/core",
2709
+ "signature": "export declare const DEFAULT_CAPABILITY_INTERCEPTOR_TIMEOUT_MS = 30000;"
2710
+ },
2452
2711
  {
2453
2712
  "name": "DEFAULT_DEV_PORT",
2454
2713
  "kind": "const",
@@ -2489,6 +2748,18 @@
2489
2748
  "package": "@nifrajs/cli",
2490
2749
  "signature": "export declare const DEFAULT_SNAPSHOT_FILE = \"api-snapshot.json\";"
2491
2750
  },
2751
+ {
2752
+ "name": "DEFAULT_WIRE_DECODE_LIMITS",
2753
+ "kind": "const",
2754
+ "package": "@nifrajs/core",
2755
+ "signature": "export declare const DEFAULT_WIRE_DECODE_LIMITS: Readonly<Required<WireDecodeLimits>>;"
2756
+ },
2757
+ {
2758
+ "name": "defaultTransportCodecs",
2759
+ "kind": "const",
2760
+ "package": "@nifrajs/core",
2761
+ "signature": "export declare const defaultTransportCodecs: TransportCodecRegistry;"
2762
+ },
2492
2763
  {
2493
2764
  "name": "defer",
2494
2765
  "kind": "function",
@@ -2617,6 +2888,12 @@
2617
2888
  "signature": "export declare const defineRouterPlugin: typeof defineIdentityPlugin;",
2618
2889
  "doc": "/**\n * Alias of {@link defineIdentityPlugin} with a name that says what it's FOR: a plugin that **mounts\n * routes/hooks but adds no context type** (an auth router, an audit logger). Use this - not\n * {@link definePlugin} - for any such plugin, or the typed client silently collapses to `any`. The\n * \"identity\" in {@link defineIdentityPlugin} refers to the type-identity it preserves; `defineRouterPlugin`\n * is the same thing under a clearer name.\n *\n * Mount routes as a **side effect**, then return the app unchanged (registering via `.get`/`.post` would\n * change the type away from the identity `S`; the mounted routes run but aren't in the caller's typed\n * registry - that's the trade that keeps everything else typed):\n *\n * ```ts\n * export const scim = defineRouterPlugin(\"scim\", (app) => {\n * app.get(\"/scim/v2/Users\", listUsers) // side effect: mounted at runtime\n * return app // return S unchanged → routes added after .use(scim) stay typed\n * })\n * const api = server().get(\"/a\", h).use(scim).get(\"/b\", h) // /a AND /b stay typed\n * ```\n */"
2619
2890
  },
2891
+ {
2892
+ "name": "defineSaga",
2893
+ "kind": "function",
2894
+ "package": "@nifrajs/core",
2895
+ "signature": "export declare function defineSaga<I, C extends Record<string, unknown>>(definition: SagaDefinition<I, C>): SagaDefinition<I, C>;"
2896
+ },
2620
2897
  {
2621
2898
  "name": "DehydratedState",
2622
2899
  "kind": "interface",
@@ -2871,6 +3148,54 @@
2871
3148
  "package": "@nifrajs/cli",
2872
3149
  "signature": "export interface DuplicateInstallFinding {\n readonly package: string;\n readonly copies: readonly DuplicateInstallCopy[];\n}"
2873
3150
  },
3151
+ {
3152
+ "name": "DurableEffectJournalOptions",
3153
+ "kind": "interface",
3154
+ "package": "@nifrajs/core",
3155
+ "signature": "export interface DurableEffectJournalOptions {\n readonly store: DurableEffectStore;\n readonly now?: () => number;\n /** Tests/local development only. Production journals require `store.durability === \"durable\"`. */\n readonly allowMemoryStore?: boolean;\n}"
3156
+ },
3157
+ {
3158
+ "name": "DurableEffectRecord",
3159
+ "kind": "interface",
3160
+ "package": "@nifrajs/core",
3161
+ "signature": "export interface DurableEffectRecord {\n readonly effectId: string;\n readonly capability: string;\n readonly target?: string;\n readonly digest?: string;\n readonly tenantId?: string;\n readonly principalId?: string;\n readonly state: DurableEffectState;\n readonly createdAt: number;\n readonly updatedAt: number;\n readonly errorCode?: string;\n readonly version: number;\n}"
3162
+ },
3163
+ {
3164
+ "name": "DurableEffectState",
3165
+ "kind": "type",
3166
+ "package": "@nifrajs/core",
3167
+ "signature": "export type DurableEffectState = \"admission\" | \"executing\" | \"committed\" | \"failed\" | \"unknown\";"
3168
+ },
3169
+ {
3170
+ "name": "DurableEffectStore",
3171
+ "kind": "interface",
3172
+ "package": "@nifrajs/core",
3173
+ "signature": "export interface DurableEffectStore {\n readonly durability?: \"memory\" | \"durable\";\n create(record: DurableEffectRecord): boolean | Promise<boolean>;\n get(effectId: string): DurableEffectRecord | undefined | Promise<DurableEffectRecord | undefined>;\n /** Atomic compare-and-set; exactly one caller may advance the supplied `version` and `from` state. */\n transition(input: {\n readonly effectId: string;\n readonly version: number;\n readonly from: DurableEffectState;\n readonly to: DurableEffectState;\n readonly updatedAt: number;\n readonly errorCode?: string;\n }): boolean | Promise<boolean>;\n /** Bounded operational scan. Transition-only stores do not need to implement reconciliation. */\n scan?(input: ReconciliationScanOptions<DurableEffectState>): ReconciliationScanPage<DurableEffectRecord> | Promise<ReconciliationScanPage<DurableEffectRecord>>;\n /** @deprecated Compatibility fallback; production reconciliation should implement `scan`. */\n list?(): readonly DurableEffectRecord[] | Promise<readonly DurableEffectRecord[]>;\n}"
3174
+ },
3175
+ {
3176
+ "name": "DurableEffectTransitionError",
3177
+ "kind": "class",
3178
+ "package": "@nifrajs/core",
3179
+ "signature": "export declare class DurableEffectTransitionError extends Error {\n readonly effectId: string;\n readonly transition: string;\n constructor(effectId: string, transition: string);\n}"
3180
+ },
3181
+ {
3182
+ "name": "DurableExecutionAdapter",
3183
+ "kind": "interface",
3184
+ "package": "@nifrajs/core",
3185
+ "signature": "export interface DurableExecutionAdapter {\n readonly effects: DurableEffectStore;\n readonly approvals: ApprovalStore;\n readonly sagas: SagaStore;\n readonly leases: ReconciliationLeaseStore;\n}"
3186
+ },
3187
+ {
3188
+ "name": "DurableExecutionConformanceResult",
3189
+ "kind": "interface",
3190
+ "package": "@nifrajs/core",
3191
+ "signature": "export interface DurableExecutionConformanceResult {\n readonly effects: true;\n readonly approvals: true;\n readonly sagas: true;\n readonly leases: true;\n}"
3192
+ },
3193
+ {
3194
+ "name": "DurableObjectExecutionAdapter",
3195
+ "kind": "class",
3196
+ "package": "@nifrajs/core",
3197
+ "signature": "export declare class DurableObjectExecutionAdapter implements DurableExecutionAdapter {\n readonly effects: DurableEffectStore;\n readonly approvals: ApprovalStore;\n readonly sagas: SagaStore;\n readonly leases: ReconciliationLeaseStore;\n readonly backend: DurableObjectRecordBackend;\n constructor(storage: DurableObjectStorage);\n}"
3198
+ },
2874
3199
  {
2875
3200
  "name": "DurableObjectNamespaceLike",
2876
3201
  "kind": "interface",
@@ -2878,6 +3203,36 @@
2878
3203
  "signature": "export interface DurableObjectNamespaceLike {\n idFromName(name: string): unknown;\n get(id: unknown): {\n fetch(request: Request): Promise<Response>;\n };\n}",
2879
3204
  "doc": "/** Structural view of a Cloudflare Durable Object namespace binding — keeps `@cloudflare/workers-types`\n * out of `@nifrajs/core`. The real `DurableObjectNamespace` satisfies it. */"
2880
3205
  },
3206
+ {
3207
+ "name": "DurableObjectRecordBackend",
3208
+ "kind": "class",
3209
+ "package": "@nifrajs/core",
3210
+ "signature": "export declare class DurableObjectRecordBackend implements DurableRecordBackend {\n private readonly storage;\n constructor(storage: DurableObjectStorage);\n private recordKey;\n private leaseKey;\n create(kind: DurableRecordKind, id: string, record: {\n readonly version: number;\n readonly state?: string;\n readonly updatedAt?: number;\n }): Promise<boolean>;\n get<T extends {\n readonly version: number;\n }>(kind: DurableRecordKind, id: string): Promise<T | undefined>;\n compareAndSet(kind: DurableRecordKind, id: string, expectedVersion: number, record: {\n readonly version: number;\n readonly state?: string;\n readonly updatedAt?: number;\n }): Promise<boolean>;\n scan<T extends {\n readonly state: string;\n readonly updatedAt: number;\n }>(kind: DurableRecordKind, input: ReconciliationScanOptions<string>): Promise<ReconciliationScanPage<T>>;\n acquireLease(input: Parameters<DurableRecordBackend[\"acquireLease\"]>[0]): Promise<ReconciliationLease | undefined>;\n renewLease(input: Parameters<DurableRecordBackend[\"renewLease\"]>[0]): Promise<boolean>;\n checkpointLease(input: Parameters<DurableRecordBackend[\"checkpointLease\"]>[0]): Promise<boolean>;\n releaseLease(input: Parameters<DurableRecordBackend[\"releaseLease\"]>[0]): Promise<boolean>;\n}"
3211
+ },
3212
+ {
3213
+ "name": "DurableObjectStorage",
3214
+ "kind": "interface",
3215
+ "package": "@nifrajs/core",
3216
+ "signature": "export interface DurableObjectStorage extends DurableObjectStorageTransaction {\n transaction<T>(closure: (transaction: DurableObjectStorageTransaction) => Promise<T>): Promise<T>;\n}"
3217
+ },
3218
+ {
3219
+ "name": "DurableObjectStorageTransaction",
3220
+ "kind": "interface",
3221
+ "package": "@nifrajs/core",
3222
+ "signature": "export interface DurableObjectStorageTransaction {\n get<T = unknown>(key: string): Promise<T | undefined>;\n put<T = unknown>(key: string, value: T): Promise<void>;\n list<T = unknown>(options?: {\n readonly prefix?: string;\n readonly startAfter?: string;\n readonly limit?: number;\n }): Promise<Map<string, T>>;\n}"
3223
+ },
3224
+ {
3225
+ "name": "DurableRecordBackend",
3226
+ "kind": "interface",
3227
+ "package": "@nifrajs/core",
3228
+ "signature": "export interface DurableRecordBackend {\n create(kind: DurableRecordKind, id: string, record: {\n readonly version: number;\n readonly state?: string;\n readonly updatedAt?: number;\n }): Promise<boolean>;\n get<T extends {\n readonly version: number;\n }>(kind: DurableRecordKind, id: string): Promise<T | undefined>;\n compareAndSet(kind: DurableRecordKind, id: string, expectedVersion: number, record: {\n readonly version: number;\n readonly state?: string;\n readonly updatedAt?: number;\n }): Promise<boolean>;\n scan<T extends {\n readonly state: string;\n readonly updatedAt: number;\n }>(kind: DurableRecordKind, input: ReconciliationScanOptions<string>): Promise<ReconciliationScanPage<T>>;\n acquireLease(input: {\n readonly name: string;\n readonly owner: string;\n readonly now: number;\n readonly leaseMs: number;\n }): Promise<ReconciliationLease | undefined>;\n renewLease(input: {\n readonly name: string;\n readonly owner: string;\n readonly token: string;\n readonly now: number;\n readonly leaseMs: number;\n }): Promise<boolean>;\n checkpointLease(input: {\n readonly name: string;\n readonly owner: string;\n readonly token: string;\n readonly cursor?: string;\n }): Promise<boolean>;\n releaseLease(input: {\n readonly name: string;\n readonly owner: string;\n readonly token: string;\n }): Promise<boolean>;\n}"
3229
+ },
3230
+ {
3231
+ "name": "DurableRecordKind",
3232
+ "kind": "type",
3233
+ "package": "@nifrajs/core",
3234
+ "signature": "export type DurableRecordKind = \"effect\" | \"approval\" | \"saga\";"
3235
+ },
2881
3236
  {
2882
3237
  "name": "effect",
2883
3238
  "kind": "function",
@@ -2903,16 +3258,22 @@
2903
3258
  "name": "EffectEntry",
2904
3259
  "kind": "interface",
2905
3260
  "package": "@nifrajs/core",
2906
- "signature": "export interface EffectEntry {\n /** Monotonic position within the request (0-based). The replay/simulation order. */\n readonly seq: number;\n /** Milliseconds from the ledger's (injectable) clock at append time. */\n readonly at: number;\n readonly capability: string;\n readonly phase: EffectPhase;\n readonly target?: string;\n readonly cost?: EffectCost;\n readonly digest?: string;\n readonly error?: {\n readonly code: string;\n };\n}",
3261
+ "signature": "export interface EffectEntry {\n /** Monotonic position within the request (0-based). The replay/simulation order. */\n readonly seq: number;\n /** Milliseconds from the ledger's (injectable) clock at append time. */\n readonly at: number;\n readonly effectId?: string;\n readonly capability: string;\n readonly phase: EffectPhase;\n readonly target?: string;\n readonly cost?: EffectCost;\n readonly digest?: string;\n readonly error?: {\n readonly code: string;\n };\n}",
2907
3262
  "doc": "/** One recorded effect. Frozen; token-only by construction (no payload field exists). */"
2908
3263
  },
2909
3264
  {
2910
3265
  "name": "EffectEntryInput",
2911
3266
  "kind": "interface",
2912
3267
  "package": "@nifrajs/core",
2913
- "signature": "export interface EffectEntryInput {\n /** Capability token (`db.write`, `payments.charge`). Must be a valid capability id. */\n readonly capability: string;\n /** Default `\"intent\"`. Record `committed`/`failed`/`compensated` only after the outcome is known. */\n readonly phase?: EffectPhase;\n /** Adapter/resource token (`repo:orders`, `provider:payments`). A token — never a value or a row. */\n readonly target?: string;\n /** Dimensionless counters; see {@link EffectCost}. At most {@link MAX_COST_AXES} axes. */\n readonly cost?: EffectCost;\n /** Optional keyed-HMAC digest of the effect payload (see {@link computeEffectDigest}); hex, 64 chars. */\n readonly digest?: string;\n /** Outcome error as a bounded token code — never a message, never a stack. */\n readonly error?: {\n readonly code: string;\n };\n}",
3268
+ "signature": "export interface EffectEntryInput extends EffectMetadata {\n /** Opaque execution correlation token shared by one intent and its terminal outcome. */\n readonly effectId?: string;\n /** Capability token (`db.write`, `payments.charge`). Must be a valid capability id. */\n readonly capability: string;\n /** Default `\"intent\"`. Record `committed`/`failed`/`compensated` only after the outcome is known. */\n readonly phase?: EffectPhase;\n /** Outcome error as a bounded token code — never a message, never a stack. */\n readonly error?: {\n readonly code: string;\n };\n}",
2914
3269
  "doc": "/** Caller-supplied fields for one entry. Everything else (`seq`, `at`) is assigned by the ledger. */"
2915
3270
  },
3271
+ {
3272
+ "name": "EffectEvidenceScope",
3273
+ "kind": "interface",
3274
+ "package": "@nifrajs/core",
3275
+ "signature": "export interface EffectEvidenceScope {\n evidence(): EffectScopeEvidence;\n /** Legacy/manual effects cannot prove a terminal outcome and therefore become ambiguous. */\n markBegan(): void;\n /** Pair a prior manual `markBegan()` with a proven commit. */\n markCommitted(): void;\n /** Preserve uncertainty when a caller loses the terminal outcome. */\n markAmbiguous(): void;\n /** Settle one begun effect as a proven terminal failure without claiming it committed. */\n markFailed(): void;\n /**\n * Declare that the enclosing request may release its idempotency reservation if it returns a\n * server error before any owned effect begins.\n */\n markSafeToRetry(): void;\n /** True only while the retry declaration remains backed by evidence that no effect began. */\n safeToRetry(): boolean;\n}"
3276
+ },
2916
3277
  {
2917
3278
  "name": "effectLedger",
2918
3279
  "kind": "function",
@@ -2955,6 +3316,40 @@
2955
3316
  "signature": "export declare class EffectLedgerSealedError extends Error {\n constructor();\n}",
2956
3317
  "doc": "/** Thrown by `append` after `seal()` — e.g. an effect attempted while streaming a response body. */"
2957
3318
  },
3319
+ {
3320
+ "name": "EffectLifecycleEvent",
3321
+ "kind": "interface",
3322
+ "package": "@nifrajs/core",
3323
+ "signature": "export interface EffectLifecycleEvent extends EffectMetadata {\n readonly effectId: string;\n readonly capability: string;\n readonly stage: EffectLifecycleStage;\n readonly phase: EffectLifecyclePhase;\n readonly at: number;\n readonly durationMs?: number;\n readonly attempt?: number;\n readonly errorCode?: string;\n readonly trace?: EffectTraceParent;\n}",
3324
+ "doc": "/**\n * Token-only lifecycle evidence. There is deliberately no payload, argument, result, error message,\n * request, or context field, so observation adapters cannot accidentally export business data.\n */"
3325
+ },
3326
+ {
3327
+ "name": "EffectLifecycleObserver",
3328
+ "kind": "type",
3329
+ "package": "@nifrajs/core",
3330
+ "signature": "export type EffectLifecycleObserver = (event: EffectLifecycleEvent) => void;",
3331
+ "doc": "/** Observation is fail-open: a broken sink must never change effect behavior. */"
3332
+ },
3333
+ {
3334
+ "name": "EffectLifecyclePhase",
3335
+ "kind": "type",
3336
+ "package": "@nifrajs/core",
3337
+ "signature": "export type EffectLifecyclePhase = \"started\" | \"succeeded\" | \"failed\" | \"ambiguous\";"
3338
+ },
3339
+ {
3340
+ "name": "EffectLifecycleStage",
3341
+ "kind": "type",
3342
+ "package": "@nifrajs/core",
3343
+ "signature": "export type EffectLifecycleStage = \"admission\" | \"execution\" | \"compensation\" | \"reconciliation\";",
3344
+ "doc": "/** A bounded, payload-free stage in an effect's lifecycle. */"
3345
+ },
3346
+ {
3347
+ "name": "EffectMetadata",
3348
+ "kind": "interface",
3349
+ "package": "@nifrajs/core",
3350
+ "signature": "export interface EffectMetadata {\n /** Adapter/resource token (`repo:orders`, `provider:payments`). A token — never a value or a row. */\n readonly target?: string;\n /** Dimensionless counters; see {@link EffectCost}. At most {@link MAX_COST_AXES} axes. */\n readonly cost?: EffectCost;\n /** Optional keyed-HMAC digest of the effect payload (see {@link computeEffectDigest}); hex, 64 chars. */\n readonly digest?: string;\n}",
3351
+ "doc": "/** Token-only caller metadata shared by an effect intent and outcome. */"
3352
+ },
2958
3353
  {
2959
3354
  "name": "EffectPhase",
2960
3355
  "kind": "type",
@@ -2962,6 +3357,81 @@
2962
3357
  "signature": "export type EffectPhase = \"intent\" | \"committed\" | \"failed\" | \"compensated\";",
2963
3358
  "doc": "/** Lifecycle phase of one effect. `intent` precedes execution; the rest describe its outcome. */"
2964
3359
  },
3360
+ {
3361
+ "name": "EffectReconciliationFinding",
3362
+ "kind": "interface",
3363
+ "package": "@nifrajs/core",
3364
+ "signature": "export interface EffectReconciliationFinding {\n readonly effectId: string;\n readonly capability: string;\n readonly state: \"incomplete\" | \"ambiguous\";\n readonly updatedAt: number;\n}"
3365
+ },
3366
+ {
3367
+ "name": "EffectScope",
3368
+ "kind": "interface",
3369
+ "package": "@nifrajs/core",
3370
+ "signature": "export interface EffectScope extends EffectEvidenceScope {\n run<T>(options: OwnedEffectRunOptions<T>, execute: (context: OwnedEffectContext) => T | PromiseLike<T>): Promise<T>;\n}"
3371
+ },
3372
+ {
3373
+ "name": "EffectScopeEvidence",
3374
+ "kind": "interface",
3375
+ "package": "@nifrajs/core",
3376
+ "signature": "export interface EffectScopeEvidence {\n readonly began: boolean;\n readonly committed: boolean;\n readonly ambiguous: boolean;\n}"
3377
+ },
3378
+ {
3379
+ "name": "effectScopeForContext",
3380
+ "kind": "function",
3381
+ "package": "@nifrajs/core",
3382
+ "signature": "export declare function effectScopeForContext(context: object): EffectEvidenceScope | undefined;"
3383
+ },
3384
+ {
3385
+ "name": "EffectScopeOptions",
3386
+ "kind": "interface",
3387
+ "package": "@nifrajs/core",
3388
+ "signature": "export interface EffectScopeOptions {\n readonly observers?: readonly EffectLifecycleObserver[];\n readonly signal?: AbortSignal;\n readonly effectId?: () => string;\n}"
3389
+ },
3390
+ {
3391
+ "name": "EffectTraceParent",
3392
+ "kind": "interface",
3393
+ "package": "@nifrajs/core",
3394
+ "signature": "export interface EffectTraceParent {\n readonly traceId: string;\n readonly spanId: string;\n readonly sampled: boolean;\n}",
3395
+ "doc": "/** Trace-parent tokens copied structurally from an installed tracing plugin. */"
3396
+ },
3397
+ {
3398
+ "name": "effectTraceParentOf",
3399
+ "kind": "function",
3400
+ "package": "@nifrajs/core",
3401
+ "signature": "export declare function effectTraceParentOf(context: object): EffectTraceParent | undefined;"
3402
+ },
3403
+ {
3404
+ "name": "effectTracing",
3405
+ "kind": "function",
3406
+ "package": "@nifrajs/otel",
3407
+ "signature": "export declare function effectTracing(options?: EffectTracingOptions): EffectTracingPlugin;",
3408
+ "doc": "/**\n * Installs child effect spans on subsequent routes. The observer consumes only the constrained\n * `EffectLifecycleEvent` contract; request/business payloads and error text cannot enter an export.\n */"
3409
+ },
3410
+ {
3411
+ "name": "EffectTracingOptions",
3412
+ "kind": "interface",
3413
+ "package": "@nifrajs/otel",
3414
+ "signature": "export interface EffectTracingOptions {\n readonly exporter?: ObservationAdapter;\n readonly adapters?: readonly ObservationAdapter[];\n /** Maximum unmatched started events retained at once. Default 10,000. */\n readonly maxActive?: number;\n /** Opportunistically expire unmatched events older than this many milliseconds. Default 5 min. */\n readonly maxActiveAgeMs?: number;\n /** Injectable wall clock for deterministic retention tests. */\n readonly now?: () => number;\n}"
3415
+ },
3416
+ {
3417
+ "name": "EffectTracingPlugin",
3418
+ "kind": "interface",
3419
+ "package": "@nifrajs/otel",
3420
+ "signature": "export interface EffectTracingPlugin extends IdentityPlugin {\n /** Pass the same observer to `createSagaEngine({ observer })` and reconciliation helpers. */\n readonly observer: EffectLifecycleObserver;\n}"
3421
+ },
3422
+ {
3423
+ "name": "emitEffectLifecycle",
3424
+ "kind": "function",
3425
+ "package": "@nifrajs/core",
3426
+ "signature": "export declare function emitEffectLifecycle(observers: readonly EffectLifecycleObserver[], input: EmitEffectLifecycleInput): void;",
3427
+ "doc": "/** @internal Validate, freeze, and fan out one token-only event. */"
3428
+ },
3429
+ {
3430
+ "name": "EmitEffectLifecycleInput",
3431
+ "kind": "interface",
3432
+ "package": "@nifrajs/core",
3433
+ "signature": "export interface EmitEffectLifecycleInput extends EffectMetadata {\n readonly effectId: string;\n readonly capability: string;\n readonly stage: EffectLifecycleStage;\n readonly phase: EffectLifecyclePhase;\n readonly at?: number;\n readonly durationMs?: number;\n readonly attempt?: number;\n readonly errorCode?: string;\n readonly trace?: EffectTraceParent;\n}"
3434
+ },
2965
3435
  {
2966
3436
  "name": "EMPTY_PARAMS",
2967
3437
  "kind": "const",
@@ -2994,6 +3464,13 @@
2994
3464
  "package": "@nifrajs/web",
2995
3465
  "signature": "export interface EnableDraftOptions {\n /** Cookie lifetime in **seconds** (default `3600` = 1h). Keep it short — draft is an editor session. */\n readonly maxAgeSeconds?: number;\n /** Cookie `Path` (default `\"/\"`). */\n readonly path?: string;\n /** Override the `Secure` attribute (defaults to `true` — secure-by-default). Pass `false` only for\n * local `http://` dev, where a `Secure` cookie isn't stored. */\n readonly secure?: boolean;\n}"
2996
3466
  },
3467
+ {
3468
+ "name": "encode",
3469
+ "kind": "function",
3470
+ "package": "@nifrajs/core",
3471
+ "signature": "export declare function encode(value: unknown): Wire;",
3472
+ "doc": "/** Encode any supported value into a JSON-safe {@link Wire} form. */"
3473
+ },
2997
3474
  {
2998
3475
  "name": "encodeCursor",
2999
3476
  "kind": "function",
@@ -3001,6 +3478,18 @@
3001
3478
  "signature": "export declare function encodeCursor(value: unknown): string;",
3002
3479
  "doc": "/** Encode any JSON-serializable value (e.g. the last row's sort key) into an opaque cursor string. */"
3003
3480
  },
3481
+ {
3482
+ "name": "encodeTransportFrame",
3483
+ "kind": "function",
3484
+ "package": "@nifrajs/core",
3485
+ "signature": "export declare function encodeTransportFrame(value: unknown, codec?: TransportCodec): string;"
3486
+ },
3487
+ {
3488
+ "name": "encodeTransportResponse",
3489
+ "kind": "function",
3490
+ "package": "@nifrajs/core",
3491
+ "signature": "export declare function encodeTransportResponse(value: unknown, codec?: TransportCodec, init?: ResponseInit): Response;"
3492
+ },
3004
3493
  {
3005
3494
  "name": "EndObservation",
3006
3495
  "kind": "interface",
@@ -3183,6 +3672,13 @@
3183
3672
  "signature": "export interface Example {\n readonly name: string;\n /** The doc page's title, e.g. \"Nifra — Auth & sessions\". */\n readonly topic: string;\n /** The doc page slug, e.g. \"auth\" — a short, matchable tag. */\n readonly slug: string;\n readonly code: string;\n}",
3184
3673
  "doc": "/**\n * `nifra_example` — verified, copy-pasteable code examples for agents. The corpus is `examples.json`\n * (written into this package by `bun run gen:llms`): the same doc snippets `check:docs` typechecks\n * against the live `@nifrajs/*` API. So every example this returns is GUARANTEED to compile against the\n * installed version — the antidote to an agent hallucinating a framework API from stale training.\n *\n * Keyword-scored over each example's name/topic/slug (curated identifiers, heavily weighted) and its\n * code body. No query → a grouped index of what's available (the cheap discovery call).\n */"
3185
3674
  },
3675
+ {
3676
+ "name": "executeCapability",
3677
+ "kind": "function",
3678
+ "package": "@nifrajs/core",
3679
+ "signature": "export declare function executeCapability<T>(context: object, capability: string, options: CapabilityExecutionOptions, executor: CapabilityExecutor<T>): Promise<T>;",
3680
+ "doc": "/**\n * Execute one owned effect behind a fail-closed capability boundary. The boundary assigns a stable\n * effect id, records intent before execution, and records exactly one terminal outcome automatically.\n * The callback result and errors never enter the token-only ledger.\n */"
3681
+ },
3186
3682
  {
3187
3683
  "name": "ExecutionContext",
3188
3684
  "kind": "interface",
@@ -4075,7 +4571,7 @@
4075
4571
  "name": "IdempotencyRuntime",
4076
4572
  "kind": "interface",
4077
4573
  "package": "@nifrajs/core",
4078
- "signature": "export interface IdempotencyRuntime {\n /** Resolve a route's declared idempotency into a pinned store + defaults, or `undefined` when off. */\n resolve(schema: RouteSchema | undefined, authenticated: boolean, maxBodyBytes: number): ResolvedIdempotency | undefined;\n /** The dedupe lane: read the key, fingerprint the request, consult the store, run/replay/reject. */\n run<T>(config: ResolvedIdempotency, req: Request, platform: Platform | undefined, entry: unknown, params: Record<string, string>, search: string | undefined, wrapResponse: (response: Response) => T, host: IdempotencyHost): Promise<T>;\n}",
4574
+ "signature": "export interface IdempotencyRuntime {\n readonly trackEffect: (context: object, committed: boolean) => void;\n /** Resolve a route's declared idempotency into a pinned store + defaults, or `undefined` when off. */\n resolve(schema: RouteSchema | undefined, authenticated: boolean, maxBodyBytes: number): ResolvedIdempotency | undefined;\n /** The dedupe lane: read the key, fingerprint the request, consult the store, run/replay/reject. */\n run<T>(config: ResolvedIdempotency, req: Request, platform: Platform | undefined, entry: unknown, params: Record<string, string>, search: string | undefined, wrapResponse: (response: Response) => T, host: IdempotencyHost): Promise<T>;\n}",
4079
4575
  "doc": "/** The injected idempotency implementation the kernel calls through when the plugin is installed. */"
4080
4576
  },
4081
4577
  {
@@ -5147,6 +5643,50 @@
5147
5643
  "signature": "export declare const MAP_DEFERRED_SOURCE = \"const mapDeferred = (d) => {\\n if (!d || typeof d !== \\\"object\\\") return d\\n if (typeof d.__nifra_deferred === \\\"number\\\") return { __nifra_deferred: true, id: d.__nifra_deferred, promise: window.__nifraDeferred(d.__nifra_deferred) }\\n if (Array.isArray(d)) return d.map(mapDeferred)\\n const out = {}\\n for (const k in d) out[k] = mapDeferred(d[k])\\n return out\\n}\";",
5148
5644
  "doc": "/**\n * Source emitted into the generated client entry: maps serialized `{__nifra_deferred: id}` placeholders\n * (at any depth — nested objects/arrays) to the registry's promises, so the component receives real\n * promises to `<Await>`. A no-op for data without placeholders (so non-deferred pages are unchanged).\n */"
5149
5645
  },
5646
+ {
5647
+ "name": "markBeaconEffectBegan",
5648
+ "kind": "function",
5649
+ "package": "@nifrajs/core",
5650
+ "signature": "export declare function markBeaconEffectBegan(context: object): void;",
5651
+ "doc": "/** A legacy beacon cannot prove what happens after the call, so it is immediately ambiguous. */"
5652
+ },
5653
+ {
5654
+ "name": "markEffect",
5655
+ "kind": "function",
5656
+ "package": "@nifrajs/core",
5657
+ "signature": "export declare function markEffect(context: object, committed: boolean): void;"
5658
+ },
5659
+ {
5660
+ "name": "markEffectAmbiguous",
5661
+ "kind": "function",
5662
+ "package": "@nifrajs/core",
5663
+ "signature": "export declare function markEffectAmbiguous(context: object): void;"
5664
+ },
5665
+ {
5666
+ "name": "markEffectCommitted",
5667
+ "kind": "function",
5668
+ "package": "@nifrajs/core",
5669
+ "signature": "export declare function markEffectCommitted(context: object): void;"
5670
+ },
5671
+ {
5672
+ "name": "markEffectExecuting",
5673
+ "kind": "function",
5674
+ "package": "@nifrajs/core",
5675
+ "signature": "export declare function markEffectExecuting(context: object): void;"
5676
+ },
5677
+ {
5678
+ "name": "markIdempotencySafeToRetry",
5679
+ "kind": "function",
5680
+ "package": "@nifrajs/core",
5681
+ "signature": "export declare function markIdempotencySafeToRetry(context: object): void;",
5682
+ "doc": "/**\n * Opt a concrete 5xx response into releasing its idempotency reservation, but only while the\n * request-local effect scope still proves that no owned effect began.\n */"
5683
+ },
5684
+ {
5685
+ "name": "markRequestSafeToRetry",
5686
+ "kind": "function",
5687
+ "package": "@nifrajs/core",
5688
+ "signature": "export declare function markRequestSafeToRetry(context: object): void;"
5689
+ },
5150
5690
  {
5151
5691
  "name": "matches",
5152
5692
  "kind": "function",
@@ -5410,6 +5950,12 @@
5410
5950
  "signature": "export interface McpWidget {\n readonly uri: string;\n readonly resource: McpResource;\n readonly meta: Record<string, unknown>;\n}",
5411
5951
  "doc": "/** A widget: the resource to register on the server, its `ui://` URI, and the `_meta` link for its tool. */"
5412
5952
  },
5953
+ {
5954
+ "name": "MemoryApprovalStore",
5955
+ "kind": "class",
5956
+ "package": "@nifrajs/core",
5957
+ "signature": "export declare class MemoryApprovalStore implements ApprovalStore {\n readonly durability: \"memory\";\n private readonly records;\n create(record: ApprovalRecord): boolean;\n get(approvalId: string): ApprovalRecord | undefined;\n decide(input: Parameters<ApprovalStore[\"decide\"]>[0]): boolean;\n consume(input: Parameters<ApprovalStore[\"consume\"]>[0]): ApprovalConsumeResult;\n list(): readonly ApprovalRecord[];\n}"
5958
+ },
5413
5959
  {
5414
5960
  "name": "MemoryCache",
5415
5961
  "kind": "class",
@@ -5441,6 +5987,19 @@
5441
5987
  "package": "@nifrajs/core",
5442
5988
  "signature": "export interface MemoryCausalityStoreOptions {\n /** Global record bound. Default 10,000. */\n readonly maxRecords?: number;\n /** In-memory evidence disappears on restart and is rejected in production unless explicitly allowed. */\n readonly allowInProduction?: boolean;\n}"
5443
5989
  },
5990
+ {
5991
+ "name": "MemoryDurableEffectStore",
5992
+ "kind": "class",
5993
+ "package": "@nifrajs/core",
5994
+ "signature": "export declare class MemoryDurableEffectStore implements DurableEffectStore {\n readonly durability: \"memory\";\n private readonly records;\n private readonly byState;\n create(record: DurableEffectRecord): boolean;\n get(effectId: string): DurableEffectRecord | undefined;\n transition(input: Parameters<DurableEffectStore[\"transition\"]>[0]): boolean;\n list(): readonly DurableEffectRecord[];\n scan(input: ReconciliationScanOptions<DurableEffectState>): ReconciliationScanPage<DurableEffectRecord>;\n}"
5995
+ },
5996
+ {
5997
+ "name": "MemoryDurableRecordBackend",
5998
+ "kind": "class",
5999
+ "package": "@nifrajs/core",
6000
+ "signature": "export declare class MemoryDurableRecordBackend implements DurableRecordBackend {\n private readonly records;\n private readonly leases;\n private key;\n create(kind: DurableRecordKind, id: string, record: {\n readonly version: number;\n readonly state?: string;\n readonly updatedAt?: number;\n }): Promise<boolean>;\n get<T extends {\n readonly version: number;\n }>(kind: DurableRecordKind, id: string): Promise<T | undefined>;\n compareAndSet(kind: DurableRecordKind, id: string, expectedVersion: number, record: {\n readonly version: number;\n readonly state?: string;\n readonly updatedAt?: number;\n }): Promise<boolean>;\n scan<T extends {\n readonly state: string;\n readonly updatedAt: number;\n }>(kind: DurableRecordKind, input: ReconciliationScanOptions<string>): Promise<ReconciliationScanPage<T>>;\n acquireLease(input: Parameters<DurableRecordBackend[\"acquireLease\"]>[0]): Promise<ReconciliationLease | undefined>;\n renewLease(input: Parameters<DurableRecordBackend[\"renewLease\"]>[0]): Promise<boolean>;\n checkpointLease(input: Parameters<DurableRecordBackend[\"checkpointLease\"]>[0]): Promise<boolean>;\n releaseLease(input: Parameters<DurableRecordBackend[\"releaseLease\"]>[0]): Promise<boolean>;\n}",
6001
+ "doc": "/** Deterministic reference backend for tests and adapter conformance; not for production. */"
6002
+ },
5444
6003
  {
5445
6004
  "name": "MemoryIdempotencyStore",
5446
6005
  "kind": "class",
@@ -5486,6 +6045,12 @@
5486
6045
  "package": "@nifrajs/core",
5487
6046
  "signature": "export interface MemoryLedgerSinkOptions {\n /** Retain at most this many sealed ledgers (oldest evicted first). Default 1000. */\n readonly maxLedgers?: number;\n}"
5488
6047
  },
6048
+ {
6049
+ "name": "MemoryReconciliationLeaseStore",
6050
+ "kind": "class",
6051
+ "package": "@nifrajs/core",
6052
+ "signature": "export declare class MemoryReconciliationLeaseStore implements ReconciliationLeaseStore {\n readonly durability: \"memory\";\n private readonly records;\n acquire(input: Parameters<ReconciliationLeaseStore[\"acquire\"]>[0]): ReconciliationLease | undefined;\n renew(input: Parameters<ReconciliationLeaseStore[\"renew\"]>[0]): boolean;\n checkpoint(input: Parameters<ReconciliationLeaseStore[\"checkpoint\"]>[0]): boolean;\n release(input: Parameters<ReconciliationLeaseStore[\"release\"]>[0]): boolean;\n}"
6053
+ },
5489
6054
  {
5490
6055
  "name": "MemoryResponseCache",
5491
6056
  "kind": "class",
@@ -5498,6 +6063,12 @@
5498
6063
  "package": "@nifrajs/middleware",
5499
6064
  "signature": "export interface MemoryResponseCacheOptions {\n /** Maximum entries retained. Default `1000`. Oldest entries are evicted first. */\n readonly maxEntries?: number;\n /** Allow in-process cache in production. Off by default because it is per-instance. */\n readonly allowInProduction?: boolean;\n}"
5500
6065
  },
6066
+ {
6067
+ "name": "MemorySagaStore",
6068
+ "kind": "class",
6069
+ "package": "@nifrajs/core",
6070
+ "signature": "export declare class MemorySagaStore implements SagaStore {\n readonly durability: \"memory\";\n private readonly records;\n private readonly byState;\n create(record: SagaRecord): boolean;\n get(sagaId: string): SagaRecord | undefined;\n compareAndSet(input: Parameters<SagaStore[\"compareAndSet\"]>[0]): boolean;\n list(): readonly SagaRecord[];\n scan(input: ReconciliationScanOptions<SagaState>): ReconciliationScanPage<SagaRecord>;\n}"
6071
+ },
5501
6072
  {
5502
6073
  "name": "MemorySessionStore",
5503
6074
  "kind": "class",
@@ -5830,7 +6401,7 @@
5830
6401
  "name": "ndjsonStream",
5831
6402
  "kind": "function",
5832
6403
  "package": "@nifrajs/web",
5833
- "signature": "export declare function ndjsonStream(forClient: unknown, deferred: ReadonlyArray<{\n readonly id: number;\n readonly promise: Promise<unknown>;\n}>): ReadableStream<Uint8Array>;",
6404
+ "signature": "export declare function ndjsonStream(forClient: unknown, deferred: ReadonlyArray<{\n readonly id: number;\n readonly promise: Promise<unknown>;\n}>, codec?: TransportCodec): ReadableStream<Uint8Array>;",
5834
6405
  "doc": "/**\n * Stream a loader result as NDJSON for a client (soft) navigation: line 1 is the critical data with\n * `{__nifra_deferred: id}` placeholders (`forClient`), then one line per deferred as its promise\n * settles — `{\"i\": id, \"v\": value}` on resolve, `{\"i\": id, \"e\": \"deferred_error\"}` on reject (a\n * rejection is data, not a stream error; the opaque code never leaks the raw reason). Closes when all\n * settle. The client (`defaultFetchData`) returns the\n * data after line 1 and settles `<Await>`'s markers as the resolution lines arrive. `JSON.stringify`\n * escapes newlines in values, so each line is NDJSON-safe; no HTML escaping (this is a fetch body,\n * parsed with `JSON.parse`, never injected into markup).\n */"
5835
6406
  },
5836
6407
  {
@@ -6030,6 +6601,13 @@
6030
6601
  "package": "@nifrajs/node",
6031
6602
  "signature": "export interface NodeServer {\n /** The bound port (resolved when `port: 0` is requested). */\n readonly port: number;\n /**\n * Stop accepting connections, let in-flight requests drain (up to `drainMs`), then\n * force-close stragglers + idle keep-alives. Mirrors nifra's Bun `stop()`.\n */\n stop(options?: {\n drainMs?: number;\n }): Promise<void>;\n}"
6032
6603
  },
6604
+ {
6605
+ "name": "normalizeEffectMetadata",
6606
+ "kind": "function",
6607
+ "package": "@nifrajs/core",
6608
+ "signature": "export declare function normalizeEffectMetadata(input: EffectMetadata): EffectMetadata;",
6609
+ "doc": "/** Validate, copy, and freeze token-only effect metadata before it reaches a ledger or policy hook. */"
6610
+ },
6033
6611
  {
6034
6612
  "name": "normalizeRolldownPlugins",
6035
6613
  "kind": "function",
@@ -6235,6 +6813,24 @@
6235
6813
  "signature": "export type OutputOf<H extends (...args: never[]) => unknown> = Exclude<Awaited<ReturnType<H>>, Response>;",
6236
6814
  "doc": "/** The client-visible output of a handler: its awaited return, minus raw `Response`. */"
6237
6815
  },
6816
+ {
6817
+ "name": "OwnedEffectContext",
6818
+ "kind": "interface",
6819
+ "package": "@nifrajs/core",
6820
+ "signature": "export interface OwnedEffectContext extends EffectMetadata {\n readonly effectId: string;\n readonly capability: string;\n readonly stage: Exclude<EffectLifecycleStage, \"admission\" | \"reconciliation\">;\n readonly signal: AbortSignal;\n readonly attempt?: number;\n}"
6821
+ },
6822
+ {
6823
+ "name": "OwnedEffectRunOptions",
6824
+ "kind": "interface",
6825
+ "package": "@nifrajs/core",
6826
+ "signature": "export interface OwnedEffectRunOptions<T> extends EffectMetadata {\n readonly effectId?: string;\n readonly capability: string;\n readonly stage?: Exclude<EffectLifecycleStage, \"admission\" | \"reconciliation\">;\n readonly signal?: AbortSignal;\n readonly attempt?: number;\n readonly trace?: EffectTraceParent;\n /** Per-run observers, combined with the scope's observers. */\n readonly observers?: readonly EffectLifecycleObserver[];\n /** Optional admission boundary executed before the effect is marked as begun. */\n readonly admit?: (context: OwnedEffectContext) => void | PromiseLike<void>;\n readonly transitions?: OwnedEffectTransitions<T>;\n readonly errorCode?: string | ((error: unknown, began: boolean) => string);\n /** Classify a caught execution failure when the caller can prove it is terminal. */\n readonly failurePhase?: (error: unknown, began: boolean) => \"failed\" | \"ambiguous\";\n}"
6827
+ },
6828
+ {
6829
+ "name": "OwnedEffectTransitions",
6830
+ "kind": "interface",
6831
+ "package": "@nifrajs/core",
6832
+ "signature": "export interface OwnedEffectTransitions<T> {\n intent?(context: OwnedEffectContext): void | PromiseLike<void>;\n executing?(context: OwnedEffectContext): void | PromiseLike<void>;\n committed?(context: OwnedEffectContext, result: T): void | PromiseLike<void>;\n failed?(context: OwnedEffectContext, input: {\n readonly began: boolean;\n readonly errorCode: string;\n readonly error: unknown;\n }): void | PromiseLike<void>;\n}"
6833
+ },
6238
6834
  {
6239
6835
  "name": "packageOf",
6240
6836
  "kind": "function",
@@ -6283,6 +6879,13 @@
6283
6879
  "package": "@nifrajs/core",
6284
6880
  "signature": "export type Params<Path extends string> = Prettify<RawParams<Path>>;"
6285
6881
  },
6882
+ {
6883
+ "name": "parse",
6884
+ "kind": "function",
6885
+ "package": "@nifrajs/core",
6886
+ "signature": "export declare function parse(text: string, limits?: WireDecodeLimits): unknown;",
6887
+ "doc": "/** `JSON.parse` + `decode` in one call - the rich-type equivalent of `JSON.parse`. */"
6888
+ },
6286
6889
  {
6287
6890
  "name": "parseArgs",
6288
6891
  "kind": "function",
@@ -6402,7 +7005,7 @@
6402
7005
  "name": "parseNdjsonData",
6403
7006
  "kind": "function",
6404
7007
  "package": "@nifrajs/web",
6405
- "signature": "export declare function parseNdjsonData(stream: ReadableStream<Uint8Array>, signal?: AbortSignal): Promise<unknown>;",
7008
+ "signature": "export declare function parseNdjsonData(stream: ReadableStream<Uint8Array>, signal?: AbortSignal, codec?: TransportCodec): Promise<unknown>;",
6406
7009
  "doc": "/**\n * Client side of {@link ndjsonStream} (used by the router's `defaultFetchData` on a soft nav): read\n * the NDJSON body into a data object whose deferred markers settle as resolution lines arrive.\n * Returns after **line 1** so the router can apply the critical data + render immediately; the\n * markers' promises settle/reject in the background. If the stream ends (or `signal` aborts) with\n * markers unsettled, they reject — so `<Await>` never hangs.\n */"
6407
7010
  },
6408
7011
  {
@@ -6480,6 +7083,12 @@
6480
7083
  "signature": "export declare function pipeWebBodyToNode(body: ReadableStream<Uint8Array> | null, res: NodeResLike): Promise<void>;",
6481
7084
  "doc": "/**\n * Stream a Web `Response` body to a Node response chunk-by-chunk. Buffering the whole body (e.g.\n * `arrayBuffer()`) waits for the stream to END — which an open-ended SSE (`text/event-stream`) body never\n * does, so it hung `nifra dev` (the Bun production server streamed it fine). This flushes each chunk as it\n * arrives and cancels the reader if the client disconnects; a finite body just streams its chunk(s) + ends.\n */"
6482
7085
  },
7086
+ {
7087
+ "name": "plainJsonCodec",
7088
+ "kind": "const",
7089
+ "package": "@nifrajs/core",
7090
+ "signature": "export declare const plainJsonCodec: TransportCodec;"
7091
+ },
6483
7092
  {
6484
7093
  "name": "Platform",
6485
7094
  "kind": "interface",
@@ -6562,6 +7171,30 @@
6562
7171
  "signature": "export type PostcssProcessor = (plugins?: readonly unknown[]) => {\n process(css: string, options: {\n readonly from?: string;\n readonly to?: string;\n }): PromiseLike<{\n readonly css: string;\n }>;\n};",
6563
7172
  "doc": "/** The subset of the `postcss` API this plugin uses (structural, so no hard dependency on its types). */"
6564
7173
  },
7174
+ {
7175
+ "name": "PostgresClient",
7176
+ "kind": "interface",
7177
+ "package": "@nifrajs/core",
7178
+ "signature": "export interface PostgresClient {\n query(sql: string, values?: readonly unknown[]): Promise<PostgresQueryResult>;\n}"
7179
+ },
7180
+ {
7181
+ "name": "PostgresDurableExecutionAdapter",
7182
+ "kind": "class",
7183
+ "package": "@nifrajs/core",
7184
+ "signature": "export declare class PostgresDurableExecutionAdapter implements DurableExecutionAdapter {\n readonly effects: DurableEffectStore;\n readonly approvals: ApprovalStore;\n readonly sagas: SagaStore;\n readonly leases: ReconciliationLeaseStore;\n readonly backend: PostgresDurableRecordBackend;\n constructor(client: PostgresClient, options?: {\n readonly tablePrefix?: string;\n });\n migrate(): Promise<void>;\n}"
7185
+ },
7186
+ {
7187
+ "name": "PostgresDurableRecordBackend",
7188
+ "kind": "class",
7189
+ "package": "@nifrajs/core",
7190
+ "signature": "export declare class PostgresDurableRecordBackend implements DurableRecordBackend {\n private readonly client;\n readonly recordsTable: string;\n readonly leasesTable: string;\n constructor(client: PostgresClient, options?: {\n readonly tablePrefix?: string;\n });\n migrate(): Promise<void>;\n create(kind: DurableRecordKind, id: string, record: {\n readonly version: number;\n readonly state?: string;\n readonly updatedAt?: number;\n }): Promise<boolean>;\n get<T extends {\n readonly version: number;\n }>(kind: DurableRecordKind, id: string): Promise<T | undefined>;\n compareAndSet(kind: DurableRecordKind, id: string, expectedVersion: number, record: {\n readonly version: number;\n readonly state?: string;\n readonly updatedAt?: number;\n }): Promise<boolean>;\n scan<T extends {\n readonly state: string;\n readonly updatedAt: number;\n }>(kind: DurableRecordKind, input: ReconciliationScanOptions<string>): Promise<ReconciliationScanPage<T>>;\n acquireLease(input: Parameters<DurableRecordBackend[\"acquireLease\"]>[0]): Promise<ReconciliationLease | undefined>;\n renewLease(input: Parameters<DurableRecordBackend[\"renewLease\"]>[0]): Promise<boolean>;\n checkpointLease(input: Parameters<DurableRecordBackend[\"checkpointLease\"]>[0]): Promise<boolean>;\n releaseLease(input: Parameters<DurableRecordBackend[\"releaseLease\"]>[0]): Promise<boolean>;\n}"
7191
+ },
7192
+ {
7193
+ "name": "PostgresQueryResult",
7194
+ "kind": "interface",
7195
+ "package": "@nifrajs/core",
7196
+ "signature": "export interface PostgresQueryResult {\n readonly rows: readonly Record<string, unknown>[];\n readonly rowCount?: number;\n}"
7197
+ },
6565
7198
  {
6566
7199
  "name": "poweredBy",
6567
7200
  "kind": "function",
@@ -7085,6 +7718,78 @@
7085
7718
  "signature": "export declare const recipe: UpgradeRecipe;",
7086
7719
  "doc": "/**\n * Upgrade recipe for nifra 1.8.0.\n *\n * 1.8.0 is a fixed-group bump: every `@nifrajs/*` package moves in lockstep. The pin sweep sets them\n * all to 1.8.0 (preserving each spec's `^`/`~`/exact style). 1.8.0 introduced no breaking import moves\n * in the public packages — the new surfaces (route assurance, adversarial testing, `@nifrajs/events`)\n * are additive — so `importMoves` is empty. The notes flag the additive follow-ups a bump can't do for\n * you (wiring the new assurance config), keeping the runner honest about what it did and didn't touch.\n */"
7087
7720
  },
7721
+ {
7722
+ "name": "reconcileEffects",
7723
+ "kind": "function",
7724
+ "package": "@nifrajs/core",
7725
+ "signature": "export declare function reconcileEffects(store: DurableEffectStore, options: {\n readonly staleBefore: number;\n readonly observer?: EffectLifecycleObserver;\n}): Promise<readonly EffectReconciliationFinding[]>;"
7726
+ },
7727
+ {
7728
+ "name": "reconcileEffectsPage",
7729
+ "kind": "function",
7730
+ "package": "@nifrajs/core",
7731
+ "signature": "export declare function reconcileEffectsPage(store: DurableEffectStore, options: {\n readonly staleBefore: number;\n readonly observer?: EffectLifecycleObserver;\n readonly cursor?: string;\n readonly limit?: number;\n}): Promise<ReconciliationPage<EffectReconciliationFinding>>;"
7732
+ },
7733
+ {
7734
+ "name": "reconcileSagas",
7735
+ "kind": "function",
7736
+ "package": "@nifrajs/core",
7737
+ "signature": "export declare function reconcileSagas(store: SagaStore, options: {\n readonly staleBefore: number;\n}): Promise<readonly SagaReconciliationFinding[]>;"
7738
+ },
7739
+ {
7740
+ "name": "reconcileSagasPage",
7741
+ "kind": "function",
7742
+ "package": "@nifrajs/core",
7743
+ "signature": "export declare function reconcileSagasPage(store: SagaStore, options: {\n readonly staleBefore: number;\n readonly cursor?: string;\n readonly limit?: number;\n}): Promise<ReconciliationPage<SagaReconciliationFinding>>;"
7744
+ },
7745
+ {
7746
+ "name": "ReconciliationLease",
7747
+ "kind": "interface",
7748
+ "package": "@nifrajs/core",
7749
+ "signature": "export interface ReconciliationLease {\n readonly name: string;\n readonly owner: string;\n readonly token: string;\n readonly expiresAt: number;\n readonly cursor?: string;\n}"
7750
+ },
7751
+ {
7752
+ "name": "ReconciliationLeaseStore",
7753
+ "kind": "interface",
7754
+ "package": "@nifrajs/core",
7755
+ "signature": "export interface ReconciliationLeaseStore {\n readonly durability?: \"memory\" | \"durable\";\n acquire(input: {\n readonly name: string;\n readonly owner: string;\n readonly now: number;\n readonly leaseMs: number;\n }): ReconciliationLease | undefined | Promise<ReconciliationLease | undefined>;\n renew(input: {\n readonly name: string;\n readonly owner: string;\n readonly token: string;\n readonly now: number;\n readonly leaseMs: number;\n }): boolean | Promise<boolean>;\n checkpoint(input: {\n readonly name: string;\n readonly owner: string;\n readonly token: string;\n readonly cursor?: string;\n }): boolean | Promise<boolean>;\n release(input: {\n readonly name: string;\n readonly owner: string;\n readonly token: string;\n }): boolean | Promise<boolean>;\n}"
7756
+ },
7757
+ {
7758
+ "name": "ReconciliationPage",
7759
+ "kind": "interface",
7760
+ "package": "@nifrajs/core",
7761
+ "signature": "export interface ReconciliationPage<Finding> {\n readonly findings: readonly Finding[];\n readonly cursor?: string;\n}"
7762
+ },
7763
+ {
7764
+ "name": "ReconciliationScanOptions",
7765
+ "kind": "interface",
7766
+ "package": "@nifrajs/core",
7767
+ "signature": "export interface ReconciliationScanOptions<State extends string> {\n readonly states: readonly State[];\n readonly updatedBefore?: number;\n readonly cursor?: string;\n readonly limit: number;\n}"
7768
+ },
7769
+ {
7770
+ "name": "ReconciliationScanPage",
7771
+ "kind": "interface",
7772
+ "package": "@nifrajs/core",
7773
+ "signature": "export interface ReconciliationScanPage<Record> {\n readonly records: readonly Record[];\n readonly cursor?: string;\n}"
7774
+ },
7775
+ {
7776
+ "name": "ReconciliationWorkerEvent",
7777
+ "kind": "type",
7778
+ "package": "@nifrajs/core",
7779
+ "signature": "export type ReconciliationWorkerEvent = {\n readonly type: \"acquired\" | \"released\" | \"lease-lost\";\n readonly name: string;\n} | {\n readonly type: \"page\" | \"checkpoint\";\n readonly name: string;\n readonly scanned: number;\n readonly handled: number;\n} | {\n readonly type: \"failed\";\n readonly name: string;\n readonly errorCode: \"scan\" | \"handle\";\n};"
7780
+ },
7781
+ {
7782
+ "name": "ReconciliationWorkerOptions",
7783
+ "kind": "interface",
7784
+ "package": "@nifrajs/core",
7785
+ "signature": "export interface ReconciliationWorkerOptions<Finding> {\n readonly name: string;\n readonly owner: string;\n readonly leases: ReconciliationLeaseStore;\n readonly leaseMs?: number;\n readonly batchSize?: number;\n readonly maxPages?: number;\n readonly concurrency?: number;\n readonly signal?: AbortSignal;\n readonly now?: () => number;\n readonly scan: (input: {\n readonly cursor?: string;\n readonly limit: number;\n readonly signal: AbortSignal;\n }) => {\n readonly findings: readonly Finding[];\n readonly cursor?: string;\n } | Promise<{\n readonly findings: readonly Finding[];\n readonly cursor?: string;\n }>;\n readonly filter?: (finding: Finding) => boolean;\n readonly handle: (finding: Finding, signal: AbortSignal) => void | PromiseLike<void>;\n readonly observe?: (event: ReconciliationWorkerEvent) => void;\n}"
7786
+ },
7787
+ {
7788
+ "name": "ReconciliationWorkerResult",
7789
+ "kind": "interface",
7790
+ "package": "@nifrajs/core",
7791
+ "signature": "export interface ReconciliationWorkerResult {\n readonly acquired: boolean;\n readonly pages: number;\n readonly scanned: number;\n readonly handled: number;\n}"
7792
+ },
7088
7793
  {
7089
7794
  "name": "recordCapabilityOutcome",
7090
7795
  "kind": "function",
@@ -7174,6 +7879,12 @@
7174
7879
  "signature": "export declare function reflectSchema(value: unknown): SchemaReflection;",
7175
7880
  "doc": "/**\n * Reflect a Standard Schema, Nifra/TypeBox schema carrier, or raw JSON Schema. Never throws.\n * Validation-only schemas have `standard` but no `jsonSchema`; raw JSON Schema has the reverse.\n */"
7176
7881
  },
7882
+ {
7883
+ "name": "RegisteredCapabilityInterceptor",
7884
+ "kind": "interface",
7885
+ "package": "@nifrajs/core",
7886
+ "signature": "export interface RegisteredCapabilityInterceptor {\n readonly interceptor: CapabilityInterceptor;\n readonly timeoutMs: number;\n}"
7887
+ },
7177
7888
  {
7178
7889
  "name": "registerFormat",
7179
7890
  "kind": "function",
@@ -7378,6 +8089,24 @@
7378
8089
  "package": "@nifrajs/core",
7379
8090
  "signature": "export declare class RequestContext implements RawContext {\n params: Record<string, string>;\n body: unknown;\n private searchValue;\n private signalValue;\n private budgetValue;\n private platformValue;\n private setValue;\n private queryValue;\n private queryReady;\n private cookiesValue;\n private readonly source;\n private readonly maxBodyBytes;\n constructor(source: RequestSource, params: Record<string, string>, maxBodyBytes: number);\n constructor(source: RequestSource, params: Record<string, string>, search: string | undefined, signal: AbortSignal, budget: RequestBudget, platform: Platform | undefined, maxBodyBytes: number);\n static native(source: RequestSource, params: Record<string, string>, maxBodyBytes: number): RequestContext;\n [CONTEXT_SET](): CtxSet | undefined;\n get [CONTEXT_SEARCH](): string;\n get set(): CtxSet;\n get signal(): AbortSignal;\n get budget(): RequestBudget;\n get env(): unknown;\n get clientIp(): string | undefined;\n get waitUntil(): (promise: Promise<unknown>) => void;\n get req(): Request;\n get request(): Request;\n json(body: unknown, init?: ResponseInit | number): Response;\n text(body: string, init?: ResponseInit | number): Response;\n get query(): unknown;\n set query(v: unknown);\n get cookies(): Readonly<Record<string, string>>;\n boundedBody(maxBytes?: number): Promise<Uint8Array>;\n boundedJson<T = unknown>(maxBytes?: number): Promise<T>;\n}"
7380
8091
  },
8092
+ {
8093
+ "name": "requestEffectEvidence",
8094
+ "kind": "function",
8095
+ "package": "@nifrajs/core",
8096
+ "signature": "export declare function requestEffectEvidence(request: Request): RequestEffectEvidence;"
8097
+ },
8098
+ {
8099
+ "name": "RequestEffectEvidence",
8100
+ "kind": "type",
8101
+ "package": "@nifrajs/core",
8102
+ "signature": "export type RequestEffectEvidence = EffectScopeEvidence;"
8103
+ },
8104
+ {
8105
+ "name": "requestEffectScope",
8106
+ "kind": "function",
8107
+ "package": "@nifrajs/core",
8108
+ "signature": "export declare function requestEffectScope(request: Request): EffectEvidenceScope | undefined;"
8109
+ },
7381
8110
  {
7382
8111
  "name": "requestId",
7383
8112
  "kind": "function",
@@ -7391,6 +8120,12 @@
7391
8120
  "package": "@nifrajs/middleware",
7392
8121
  "signature": "export interface RequestIdOptions {\n /** Header read for an inbound id (trace propagation) + echoed on the response. Default `\"x-request-id\"`. */\n readonly header?: string;\n /** Generate an id when the inbound header is absent. Default `crypto.randomUUID()`. */\n readonly generate?: () => string;\n}"
7393
8122
  },
8123
+ {
8124
+ "name": "requestIsSafeToRetry",
8125
+ "kind": "function",
8126
+ "package": "@nifrajs/core",
8127
+ "signature": "export declare function requestIsSafeToRetry(request: Request): boolean;"
8128
+ },
7394
8129
  {
7395
8130
  "name": "RequestLedger",
7396
8131
  "kind": "interface",
@@ -7715,6 +8450,18 @@
7715
8450
  "signature": "export declare function rewriteVersionSpec(spec: string, toVersion: string): string | null;",
7716
8451
  "doc": "/**\n * Rewrite a dependency version spec to `toVersion`, preserving the range operator (`^`, `~`, …).\n * Returns null when the spec is not a plain semver spec (→ skip it) or already equals the target.\n */"
7717
8452
  },
8453
+ {
8454
+ "name": "richWireCodec",
8455
+ "kind": "function",
8456
+ "package": "@nifrajs/core",
8457
+ "signature": "export declare function richWireCodec(options?: RichWireCodecOptions): TransportCodec;"
8458
+ },
8459
+ {
8460
+ "name": "RichWireCodecOptions",
8461
+ "kind": "interface",
8462
+ "package": "@nifrajs/core",
8463
+ "signature": "export interface RichWireCodecOptions {\n readonly limits?: WireDecodeLimits;\n}"
8464
+ },
7718
8465
  {
7719
8466
  "name": "robots",
7720
8467
  "kind": "function",
@@ -8067,6 +8814,19 @@
8067
8814
  "signature": "export declare function runDoctor(cwd: string, opts?: {\n readonly json?: boolean;\n readonly autoFix?: boolean;\n}): Promise<boolean>;",
8068
8815
  "doc": "/** Run doctor; print a report (`--json` for machine output) and return whether it passed. */"
8069
8816
  },
8817
+ {
8818
+ "name": "runDurableExecutionAdapterConformance",
8819
+ "kind": "function",
8820
+ "package": "@nifrajs/core",
8821
+ "signature": "export declare function runDurableExecutionAdapterConformance(adapter: DurableExecutionAdapter): Promise<DurableExecutionConformanceResult>;",
8822
+ "doc": "/** Runtime-independent conformance suite reusable by adapter authors and CI. */"
8823
+ },
8824
+ {
8825
+ "name": "runEffectReconciliationWorker",
8826
+ "kind": "function",
8827
+ "package": "@nifrajs/core",
8828
+ "signature": "export declare function runEffectReconciliationWorker(store: DurableEffectStore, options: SpecializedWorkerOptions<EffectReconciliationFinding>): Promise<ReconciliationWorkerResult>;"
8829
+ },
8070
8830
  {
8071
8831
  "name": "runFailureScenario",
8072
8832
  "kind": "function",
@@ -8147,6 +8907,12 @@
8147
8907
  "package": "@nifrajs/mcp-db",
8148
8908
  "signature": "export interface RunQueryOptions {\n /**\n * REQUIRED. Authorize each `run_query` call at the transport boundary (inspect the inbound\n * Request's auth). Return false to reject with a JSON-RPC error. There is no unauthenticated\n * mode — schema tools are the anonymous surface. Note: `run_query` is therefore HTTP-only;\n * direct `handle()` dispatch rejects it (no Request to authorize — fails closed).\n */\n readonly authorize: (context: McpDbAuthorizeContext) => boolean | Promise<boolean>;\n /** Max rows returned per query (default 100). */\n readonly maxRows?: number;\n /** Max serialized result size in bytes (default 100 KB). */\n readonly maxResultBytes?: number;\n}"
8149
8909
  },
8910
+ {
8911
+ "name": "runReconciliationWorker",
8912
+ "kind": "function",
8913
+ "package": "@nifrajs/core",
8914
+ "signature": "export declare function runReconciliationWorker<Finding>(options: ReconciliationWorkerOptions<Finding>): Promise<ReconciliationWorkerResult>;"
8915
+ },
8150
8916
  {
8151
8917
  "name": "runRequest",
8152
8918
  "kind": "function",
@@ -8161,6 +8927,12 @@
8161
8927
  "signature": "export interface RunResult {\n readonly label?: string;\n readonly method: string;\n readonly path: string;\n /** `true` when the app returned a 2xx response. `false` for non-2xx, or when `app.fetch` threw. */\n readonly ok: boolean;\n /** HTTP status — present when the app returned a response (absent when it threw). */\n readonly status?: number;\n readonly statusText?: string;\n readonly headers?: Readonly<Record<string, string>>;\n /** Parsed JSON when the response is JSON; otherwise the (possibly truncated) text. */\n readonly body?: unknown;\n /** The response body as text, truncated to `maxBodyChars`. */\n readonly bodyText?: string;\n /** `true` when `bodyText` was cut to the cap. */\n readonly truncated?: boolean;\n /** Wall-clock time for this request, milliseconds. */\n readonly durationMs: number;\n /** Set when `app.fetch` threw (the app crashed) rather than returning a response. */\n readonly error?: {\n readonly name: string;\n readonly message: string;\n readonly stack?: string;\n };\n}",
8162
8928
  "doc": "/** The captured outcome of one request. */"
8163
8929
  },
8930
+ {
8931
+ "name": "runSagaReconciliationWorker",
8932
+ "kind": "function",
8933
+ "package": "@nifrajs/core",
8934
+ "signature": "export declare function runSagaReconciliationWorker(store: SagaStore, options: SpecializedWorkerOptions<SagaReconciliationFinding>): Promise<ReconciliationWorkerResult>;"
8935
+ },
8164
8936
  {
8165
8937
  "name": "runSnapshot",
8166
8938
  "kind": "function",
@@ -8200,6 +8972,13 @@
8200
8972
  "package": "@nifrajs/middleware",
8201
8973
  "signature": "export declare const SAFE_METHODS: Set<string>;"
8202
8974
  },
8975
+ {
8976
+ "name": "safeEqual",
8977
+ "kind": "function",
8978
+ "package": "@nifrajs/core",
8979
+ "signature": "export declare function safeEqual(a: string | undefined, b: string | undefined): boolean;",
8980
+ "doc": "/**\n * Constant-time string comparison for credential-shaped values - lease tokens, token hashes, and\n * binding digests.\n *\n * `a !== b` returns as soon as it finds a differing character, so how long it takes reveals how much\n * of a guess was correct. That is only exploitable when an attacker can submit guesses and measure,\n * which is not the case on every path here - but these values are credentials, the comparison is on\n * the verification path, and doing it correctly costs nothing. Doing it inconsistently is what makes\n * the one place that matters easy to miss.\n *\n * Length is compared first, so a length difference is still observable. Every value compared through\n * this helper is fixed-width by construction (a UUID, a SHA-256 hex/base64url digest), so length\n * carries no secret. Content comparison always visits every character.\n *\n * Synchronous on purpose: the callers are store transitions and lease checks that are themselves\n * synchronous. A hash-then-compare variant (which would also hide length) is available as\n * `timingSafeEqualString` in `@nifrajs/middleware`, but it is async and would force those paths async.\n */"
8981
+ },
8203
8982
  {
8204
8983
  "name": "safeJoin",
8205
8984
  "kind": "function",
@@ -8207,6 +8986,109 @@
8207
8986
  "signature": "export declare function safeJoin(cwd: string, rel: string): string;",
8208
8987
  "doc": "/** Confine a project-relative path under `cwd` and return the absolute path. Rejects a spec that escapes\n * the root (defense-in-depth — these specs are constants, but the cwd-confinement invariant is enforced\n * at the seam, not assumed). Exported so the invariant is directly testable. */"
8209
8988
  },
8989
+ {
8990
+ "name": "SagaAmbiguityResolution",
8991
+ "kind": "type",
8992
+ "package": "@nifrajs/core",
8993
+ "signature": "export type SagaAmbiguityResolution = {\n readonly kind: \"execution\";\n readonly step: string;\n readonly effectId: string;\n readonly outcome: \"committed\";\n /** Provider-confirmed result required by later saga steps. */\n readonly result: unknown;\n} | {\n readonly kind: \"execution\";\n readonly step: string;\n readonly effectId: string;\n readonly outcome: \"not-committed\";\n readonly errorCode?: string;\n} | {\n readonly kind: \"compensation\";\n readonly step: string;\n readonly effectId: string;\n readonly outcome: \"compensated\" | \"not-compensated\";\n};"
8994
+ },
8995
+ {
8996
+ "name": "SagaAmbiguousStepError",
8997
+ "kind": "class",
8998
+ "package": "@nifrajs/core",
8999
+ "signature": "export declare class SagaAmbiguousStepError extends Error {\n readonly sagaId: string;\n readonly step: string;\n readonly effectId: string;\n constructor(sagaId: string, step: string, effectId: string);\n}"
9000
+ },
9001
+ {
9002
+ "name": "SagaCompensationContext",
9003
+ "kind": "interface",
9004
+ "package": "@nifrajs/core",
9005
+ "signature": "export interface SagaCompensationContext {\n readonly effectId: string;\n readonly sagaId: string;\n readonly attempt: number;\n readonly signal: AbortSignal;\n}"
9006
+ },
9007
+ {
9008
+ "name": "SagaConcurrencyError",
9009
+ "kind": "class",
9010
+ "package": "@nifrajs/core",
9011
+ "signature": "export declare class SagaConcurrencyError extends Error {\n readonly sagaId: string;\n constructor(sagaId: string);\n}"
9012
+ },
9013
+ {
9014
+ "name": "SagaDefinition",
9015
+ "kind": "interface",
9016
+ "package": "@nifrajs/core",
9017
+ "signature": "export interface SagaDefinition<I, C extends Record<string, unknown>> {\n readonly name: string;\n readonly capability?: string;\n readonly run: (context: SagaRunContext<C>, input: I) => void | PromiseLike<void>;\n readonly compensators: {\n readonly [K in keyof C]: (args: C[K], context: SagaCompensationContext) => void | PromiseLike<void>;\n };\n readonly retry?: {\n readonly maxAttempts?: number;\n readonly backoffMs?: (attempt: number) => number;\n };\n}"
9018
+ },
9019
+ {
9020
+ "name": "SagaEngine",
9021
+ "kind": "interface",
9022
+ "package": "@nifrajs/core",
9023
+ "signature": "export interface SagaEngine {\n execute<I, C extends Record<string, unknown>>(definition: SagaDefinition<I, C>, sagaId: string, input: I, options?: {\n readonly signal?: AbortSignal;\n }): Promise<SagaRecord>;\n resume<I, C extends Record<string, unknown>>(definition: SagaDefinition<I, C>, sagaId: string, options?: {\n readonly signal?: AbortSignal;\n }): Promise<SagaRecord>;\n compensate<I, C extends Record<string, unknown>>(definition: SagaDefinition<I, C>, sagaId: string, options?: {\n readonly signal?: AbortSignal;\n }): Promise<SagaRecord>;\n /**\n * Apply a provider/operator-confirmed outcome to an ambiguous durable transition. The supplied\n * effect id must match the stored execution/compensation id, preventing a stale review from\n * resolving a later operation. The caller remains responsible for authenticating and authorizing\n * the operator. Call `resume` or `compensate` after the resolution.\n */\n resolveAmbiguity<I, C extends Record<string, unknown>>(definition: SagaDefinition<I, C>, sagaId: string, resolution: SagaAmbiguityResolution): Promise<SagaRecord>;\n}"
9024
+ },
9025
+ {
9026
+ "name": "SagaEngineOptions",
9027
+ "kind": "interface",
9028
+ "package": "@nifrajs/core",
9029
+ "signature": "export interface SagaEngineOptions {\n readonly store: SagaStore;\n readonly now?: () => number;\n readonly observer?: EffectLifecycleObserver;\n /** Tests/local development only. Production sagas require a durable store. */\n readonly allowMemoryStore?: boolean;\n}"
9030
+ },
9031
+ {
9032
+ "name": "SagaReconciliationFinding",
9033
+ "kind": "interface",
9034
+ "package": "@nifrajs/core",
9035
+ "signature": "export interface SagaReconciliationFinding {\n readonly sagaId: string;\n readonly state: SagaState;\n readonly step?: string;\n readonly effectId?: string;\n readonly reason: \"stale-running\" | \"ambiguous-execution\" | \"ambiguous-compensation\" | \"manual-review\";\n}"
9036
+ },
9037
+ {
9038
+ "name": "SagaRecord",
9039
+ "kind": "interface",
9040
+ "package": "@nifrajs/core",
9041
+ "signature": "export interface SagaRecord {\n readonly sagaId: string;\n readonly definition: string;\n readonly state: SagaState;\n readonly input: unknown;\n readonly steps: readonly SagaStepRecord[];\n readonly createdAt: number;\n readonly updatedAt: number;\n readonly version: number;\n}"
9042
+ },
9043
+ {
9044
+ "name": "SagaResolutionError",
9045
+ "kind": "class",
9046
+ "package": "@nifrajs/core",
9047
+ "signature": "export declare class SagaResolutionError extends Error {\n readonly sagaId: string;\n readonly step: string;\n constructor(sagaId: string, step: string, message: string);\n}"
9048
+ },
9049
+ {
9050
+ "name": "SagaRunContext",
9051
+ "kind": "interface",
9052
+ "package": "@nifrajs/core",
9053
+ "signature": "export interface SagaRunContext<C extends Record<string, unknown>> {\n step<K extends keyof C & string, T>(name: K, compensationArgs: C[K], execute: (context: SagaStepExecutionContext) => T | PromiseLike<T>): Promise<T>;\n}"
9054
+ },
9055
+ {
9056
+ "name": "SagaState",
9057
+ "kind": "type",
9058
+ "package": "@nifrajs/core",
9059
+ "signature": "export type SagaState = \"running\" | \"compensating\" | \"completed\" | \"compensated\" | \"manual-review\";"
9060
+ },
9061
+ {
9062
+ "name": "SagaStepExecutionContext",
9063
+ "kind": "interface",
9064
+ "package": "@nifrajs/core",
9065
+ "signature": "export interface SagaStepExecutionContext {\n readonly effectId: string;\n readonly signal: AbortSignal;\n}"
9066
+ },
9067
+ {
9068
+ "name": "SagaStepNotCommittedError",
9069
+ "kind": "class",
9070
+ "package": "@nifrajs/core",
9071
+ "signature": "export declare class SagaStepNotCommittedError extends Error {\n readonly code: string;\n constructor(code?: string);\n}",
9072
+ "doc": "/** Throw this only when a provider conclusively proves that no effect committed. */"
9073
+ },
9074
+ {
9075
+ "name": "SagaStepRecord",
9076
+ "kind": "interface",
9077
+ "package": "@nifrajs/core",
9078
+ "signature": "export interface SagaStepRecord {\n readonly name: string;\n readonly effectId: string;\n readonly compensationEffectId: string;\n readonly state: SagaStepState;\n readonly compensationArgs: unknown;\n readonly result?: unknown;\n readonly attempts: number;\n readonly nextAttemptAt?: number;\n readonly errorCode?: string;\n}"
9079
+ },
9080
+ {
9081
+ "name": "SagaStepState",
9082
+ "kind": "type",
9083
+ "package": "@nifrajs/core",
9084
+ "signature": "export type SagaStepState = \"executing\" | \"committed\" | \"failed\" | \"ambiguous\" | \"compensating\" | \"compensation-failed\" | \"compensated\";"
9085
+ },
9086
+ {
9087
+ "name": "SagaStore",
9088
+ "kind": "interface",
9089
+ "package": "@nifrajs/core",
9090
+ "signature": "export interface SagaStore {\n readonly durability?: \"memory\" | \"durable\";\n create(record: SagaRecord): boolean | Promise<boolean>;\n get(sagaId: string): SagaRecord | undefined | Promise<SagaRecord | undefined>;\n /** Atomic version compare-and-set; this is the saga engine's crash/concurrency boundary. */\n compareAndSet(input: {\n readonly sagaId: string;\n readonly version: number;\n readonly record: SagaRecord;\n }): boolean | Promise<boolean>;\n /** Bounded operational scan. Transition-only stores do not need to implement reconciliation. */\n scan?(input: ReconciliationScanOptions<SagaState>): ReconciliationScanPage<SagaRecord> | Promise<ReconciliationScanPage<SagaRecord>>;\n /** @deprecated Compatibility fallback; production reconciliation should implement `scan`. */\n list?(): readonly SagaRecord[] | Promise<readonly SagaRecord[]>;\n}"
9091
+ },
8210
9092
  {
8211
9093
  "name": "sanitizeOutputNames",
8212
9094
  "kind": "function",
@@ -8571,7 +9453,7 @@
8571
9453
  "name": "Server",
8572
9454
  "kind": "class",
8573
9455
  "package": "@nifrajs/core",
8574
- "signature": "export declare class Server<R extends Registry = EmptyRegistry, Ctx = EmptyContext> {\n private readonly catalog;\n /** WebSocket routes, matched separately at upgrade time (a GET + `Upgrade: websocket`). */\n private readonly wsRouter;\n private wsRouteCount;\n /** In-process pub/sub backing `ws.subscribe(topic)` + `app.publish(topic, data)` (single-instance).\n * Created by the first `app.ws()` via the `@nifrajs/core/ws` runtime — `undefined` until then, so a\n * no-WebSocket app never constructs (or bundles) it. */\n private topics;\n private readonly maxBodyBytes;\n private readonly wsMaxPayloadBytes;\n private readonly requestTimeoutMs;\n /** Opt-in caller-IP trust declaration; `undefined` = socket peer only, no forwarded header believed. */\n private readonly clientIpTrust;\n private readonly acceptInboundDeadlines;\n private readonly maxInboundDeadlineMs;\n private readonly deadlineAdmissionOptions;\n private readonly gracefulSignals;\n /** Capacity-admission gate; `undefined` = off (the request path pays nothing). */\n private readonly capacityGate;\n private readonly onCapabilityUse;\n /** The installed effect-ledger runtime (owns the sink + per-route resolution + settle), or\n * `undefined` when the effect-ledger plugin is not installed. */\n private effectLedgerRuntime;\n /** The installed idempotency runtime (owns the app-wide default store + the dedupe lane), or\n * `undefined` when the idempotency plugin is not installed. */\n private idempotencyRuntime;\n /** Installed opt-in runtime for `.tool()`/`.resource()`/`.prompt()`; `undefined` until `.use(mcp())`. */\n private mcpRuntime;\n /** Installed Node-direct renderer for direct `resolveNode()` callers; `undefined` until `.use(nodeDirect())`. */\n private nodeOutcomeRuntime;\n /** Installed streaming runtime for `.sse()` routes; `undefined` until `.use(streaming())`. */\n private sseRuntime;\n /** Installed WebSocket runtime for `.ws()` routes; `undefined` until `.use(websocket())`. */\n private wsRuntime;\n private readonly logger;\n /** App-wide validation-error fallback; a route's own `schema.onValidationError` takes precedence. */\n private readonly defaultOnValidationError?;\n private bunServer;\n private sealed;\n private readonly derives;\n private readonly decorations;\n private readonly beforeHandleHooks;\n private readonly afterHandleHooks;\n private readonly onErrorHooks;\n private readonly aroundHooks;\n private readonly onRequestHooks;\n private readonly onResponseHooks;\n private readonly onResponseFinalizedHooks;\n private readonly responseRequests;\n /** Names of plugins/middleware already applied via `use` — for idempotent dedupe. */\n private readonly appliedPlugins;\n /** Order-scoped evidence captured by routes registered after an assured plugin. */\n private readonly activeAssurance;\n /** App-wide evidence from global hooks; applies retroactively to every route. */\n private readonly globalAssurance;\n /** App-declared MCP resources / prompts (via {@link resource} / {@link prompt}), read by `nifra mcp`. */\n private readonly mcpResourceList;\n private readonly mcpPromptList;\n constructor(options?: ServerOptions);\n private assertConfigurable;\n /** Add a per-request, computed context extension for subsequent routes. */\n derive<D extends object>(fn: (context: Context & Ctx) => MaybePromise<D>): Server<R, Ctx & D>;\n /** Add a static context value for subsequent routes. */\n decorate<const K extends string, V>(key: K, value: V): Server<R, Ctx & Record<K, V>>;\n /**\n * Run before routing on the raw request. Return a `Response` to short-circuit, or a replacement\n * `Request` to continue routing with a rewritten method/URL/headers. Global.\n */\n onRequest(fn: (req: Request, platform?: Platform<EnvOf<Ctx>>) => MaybePromise<OnRequestResult>): this;\n /** Run after validation, before the handler; a non-`undefined` return short-circuits. Order-scoped. */\n beforeHandle(fn: (context: Context & Ctx) => MaybePromise<unknown>): this;\n /**\n * Wrap the matched route lifecycle for subsequent routes. This is intentionally generic over the\n * route output, so wrappers like async context storage do not force Node's direct JSON path through\n * a Web `Response`. The first registered wrapper is outermost.\n */\n around(fn: <T>(context: Context & Ctx, next: () => MaybePromise<T>) => MaybePromise<T>): this;\n /** Transform the handler's result before it is serialized. Order-scoped. */\n afterHandle(fn: (result: unknown, context: Context & Ctx) => MaybePromise<unknown>): this;\n /** Handle a thrown error; a non-`undefined` return becomes the response (else the default 500). Order-scoped. */\n onError(fn: (error: unknown, context: Context & Ctx) => MaybePromise<unknown>): this;\n /** Transform every outgoing response — success, error, 404, 405, short-circuit. Global. */\n onResponse(fn: (response: Response, req: Request) => MaybePromise<Response>): this;\n /** Observe the terminal response after all transformations. Observers are ordered and fail-open. */\n onResponseFinalized(fn: (outcome: ResponseFinalization, req: Request) => MaybePromise<void>): this;\n /**\n * Apply a type-**identity** plugin ({@link IdentityPlugin}, from {@link defineIdentityPlugin}) — it\n * registers routes/hooks but doesn't change the types, so this returns `this` with the route registry\n * and context fully intact. This overload exists specifically so a *named* identity plugin (e.g.\n * `@nifrajs/better-auth`) threads the registry: its `& { pluginName }` intersection would otherwise\n * defeat the generic inference of the transforming overload below and collapse the result to `any`.\n */\n use(plugin: IdentityPlugin): this;\n /**\n * Apply a **plugin function** — `(app) => app`, typically built with {@link definePlugin}. It's\n * called with `this` and its result is returned, so an inline plugin's `derive`/`decorate` thread\n * the added context to handlers defined after `use` (the overload is generic over the concrete\n * `this`). A named plugin already applied is skipped (idempotent dedupe).\n */\n use<Out extends AnyServer>(plugin: (app: this) => Out): Out;\n /**\n * Apply a {@link Middleware} bundle — wire each hook it provides to its lifecycle point. Returns\n * `this` (no context-type merging); call it before the routes its `beforeHandle`/`afterHandle`\n * should cover (those are order-scoped; `onRequest`/`onResponse` are global). A named bundle already\n * applied is skipped (idempotent).\n */\n use(mw: Middleware): this;\n get<Path extends string, S extends RouteSchema, H extends Handler<Path, S, Ctx>>(path: Path, schema: S, handler: H): Server<AddRoute<R, \"GET\", Path, RouteInfoFor<Path, S, OutputOf<H>>>, Ctx>;\n get<Path extends string, H extends Handler<Path, RouteSchema, Ctx>>(path: Path, handler: H): Server<AddRoute<R, \"GET\", Path, RouteInfoFor<Path, Record<never, never>, OutputOf<H>>>, Ctx>;\n /**\n * Register a **typed SSE route** — a GET endpoint streaming `text/event-stream` whose event\n * payloads are contracted by `schema.sse`. The handler receives the validated context plus a\n * {@link TypedSSEStream}: `stream.send(event)` is compile-time-checked against the schema and\n * JSON-serialized into the SSE `data:` field. The typed client sees the marker and grows a\n * `.subscribe(onEvent)` for the route with the same payload type — end-to-end typed streaming.\n *\n * import { streaming } from \"@nifrajs/core/sse\" // .use(streaming()) enables .sse()\n * const app = server().use(streaming()).sse(\"/feed\", { sse: t.object({ id: t.integer(), title: t.string() }) },\n * async (c, stream) => {\n * stream.send({ id: 1, title: \"hello\" }) // typed\n * await waitForDisconnect(stream.signal)\n * },\n * { keepAlive: 15_000 })\n *\n * // client: const off = api.feed.subscribe((post) => console.log(post.title))\n *\n * `init` passes through to the underlying {@link sse} helper (`keepAlive`, extra headers). The\n * connection closes when the handler resolves, `stream.close()` runs, or the client disconnects\n * (`stream.signal`). Query/body schemas validate exactly as on any other route.\n */\n sse<Path extends string, S extends RouteSchema & {\n sse: StandardSchemaV1;\n }>(path: Path, schema: S, run: (context: Context<Path, S> & Ctx, stream: TypedSSEStream<InferOutput<S[\"sse\"]>>) => void | Promise<void>, init?: SSEInit): Server<AddRoute<R, \"GET\", Path, RouteInfoFor<Path, S, Response>>, Ctx>;\n post<Path extends string, S extends RouteSchema, H extends Handler<Path, S, Ctx>>(path: Path, schema: S, handler: H): Server<AddRoute<R, \"POST\", Path, RouteInfoFor<Path, S, OutputOf<H>>>, Ctx>;\n post<Path extends string, H extends Handler<Path, RouteSchema, Ctx>>(path: Path, handler: H): Server<AddRoute<R, \"POST\", Path, RouteInfoFor<Path, Record<never, never>, OutputOf<H>>>, Ctx>;\n put<Path extends string, S extends RouteSchema, H extends Handler<Path, S, Ctx>>(path: Path, schema: S, handler: H): Server<AddRoute<R, \"PUT\", Path, RouteInfoFor<Path, S, OutputOf<H>>>, Ctx>;\n put<Path extends string, H extends Handler<Path, RouteSchema, Ctx>>(path: Path, handler: H): Server<AddRoute<R, \"PUT\", Path, RouteInfoFor<Path, Record<never, never>, OutputOf<H>>>, Ctx>;\n patch<Path extends string, S extends RouteSchema, H extends Handler<Path, S, Ctx>>(path: Path, schema: S, handler: H): Server<AddRoute<R, \"PATCH\", Path, RouteInfoFor<Path, S, OutputOf<H>>>, Ctx>;\n patch<Path extends string, H extends Handler<Path, RouteSchema, Ctx>>(path: Path, handler: H): Server<AddRoute<R, \"PATCH\", Path, RouteInfoFor<Path, Record<never, never>, OutputOf<H>>>, Ctx>;\n delete<Path extends string, S extends RouteSchema, H extends Handler<Path, S, Ctx>>(path: Path, schema: S, handler: H): Server<AddRoute<R, \"DELETE\", Path, RouteInfoFor<Path, S, OutputOf<H>>>, Ctx>;\n delete<Path extends string, H extends Handler<Path, RouteSchema, Ctx>>(path: Path, handler: H): Server<AddRoute<R, \"DELETE\", Path, RouteInfoFor<Path, Record<never, never>, OutputOf<H>>>, Ctx>;\n /**\n * Declare an **MCP tool** an agent can call (via `nifra mcp`, or a mounted MCP endpoint): a typed\n * `POST /_nifra/tool/<name>` route whose `input`/`output` schemas contract the call and surface in\n * `tools/list`. Requires `.use(mcp())` - without it, `.tool()` is a registration error, so an\n * ordinary HTTP app never bundles the MCP wiring. Siblings: {@link resource}, {@link prompt}.\n *\n * import { mcp } from \"@nifrajs/core/mcp\"\n * const app = server().use(mcp()).tool(\n * \"search\",\n * { description: \"Search posts\", input: t.object({ q: t.string() }) },\n * ({ q }) => findPosts(q),\n * )\n */\n tool<Name extends string, S extends {\n description: string;\n input: StandardSchemaV1;\n output?: StandardSchemaV1;\n annotations?: ToolAnnotations;\n }, H extends (input: InferOutput<S[\"input\"]>, ctx: Context & Ctx) => MaybePromise<S[\"output\"] extends StandardSchemaV1 ? InferOutput<S[\"output\"]> : unknown>>(name: Name, config: S, handler: H): Server<AddRoute<R, \"POST\", `/_nifra/tool/${Name}`, RouteInfoFor<`/_nifra/tool/${Name}`, S[\"output\"] extends StandardSchemaV1 ? {\n body: S[\"input\"];\n response: S[\"output\"];\n } : {\n body: S[\"input\"];\n }, OutputOf<H>>>, Ctx>;\n /**\n * Declare an MCP **resource** — read-only data an agent can fetch through `nifra mcp` (app config, a\n * generated document, …). `read` runs in the app process, so capture whatever app state it needs in the\n * closure. `uri` is the MCP resource identifier (e.g. `\"myapp://config\"`). The sibling of {@link tool}\n * for the resource half of MCP.\n */\n resource(uri: string, config: {\n readonly name: string;\n readonly description?: string;\n readonly mimeType?: string;\n }, read: McpResourceDescriptor[\"read\"]): Server<R, Ctx>;\n /**\n * Declare an MCP **prompt** — a reusable prompt template an agent can fetch through `nifra mcp`.\n * `handler` receives the caller's arguments and returns the rendered messages.\n */\n prompt(name: string, config: {\n readonly description: string;\n readonly arguments?: readonly PromptArgument[];\n }, handler: McpPromptDescriptor[\"handler\"]): Server<R, Ctx>;\n /** The MCP resources declared via {@link resource} — enumerated by `nifra mcp`. */\n mcpResources(): readonly McpResourceDescriptor[];\n /** The MCP prompts declared via {@link prompt} — enumerated by `nifra mcp`. */\n mcpPrompts(): readonly McpPromptDescriptor[];\n /**\n * Register a **WebSocket** route. The connection upgrades on a `GET` to `path` carrying\n * `Upgrade: websocket`; the optional `handler.upgrade(c)` runs in the request context first and may\n * reject (return a `Response`) or seed per-connection `ws.data`. WebSockets are served by the\n * adapter (`listen()`, `@nifrajs/node`, `@nifrajs/deno`, `toFetchHandler`) — not by bare `app.fetch`, which\n * has no socket (a WS path through `app.fetch` is a normal HTTP response).\n *\n * The route also enters the type-level registry (under the pseudo-method `\"WS\"`), so the typed\n * client grows a `.ws()` handle for it: `messageSchema` types what the client may `send`,\n * `sendSchema` types the frames it receives. Passing explicit type arguments (`ws<MyData>(…)`)\n * defeats path-literal inference and skips the registry entry - the route still serves, it is just\n * invisible to `client<App>`; prefer typing `data` via `upgrade()`'s return.\n *\n * app.ws(\"/chat\", { open: (ws) => ws.send(\"hi\"), message: (ws, data) => ws.send(data) })\n */\n ws<Data = unknown, Schema extends StandardSchemaV1 | undefined = undefined, Send extends StandardSchemaV1 | undefined = undefined, Path extends string = string>(path: Path, handler: WebSocketHandler<Data, EnvOf<Ctx>, Schema, Send>): string extends Path ? Server<R, Ctx> : Server<AddRoute<R, \"WS\", Path, WsRouteInfoFor<Path, Schema, Send>>, Ctx>;\n /**\n * Broadcast `data` to every WebSocket connection subscribed to `topic` (via `ws.subscribe(topic)`).\n * In-process and **single-instance** (see {@link TopicRegistry}) — a multi-instance deploy must bridge\n * an external fan-out (Redis, a Durable Object) to this. A no-op when nobody is subscribed.\n */\n publish(topic: string, data: string | ArrayBufferView | ArrayBuffer): void;\n private route;\n /**\n * Low-level route registration shared by the inline builder and `implement()`.\n * Captures the server's current `derive`/`decorate` chain into the route — this\n * is the \"compiled\", order-scoped per-route chain.\n */\n register(method: Method, path: string, schema: RouteSchema | undefined, handler: (context: never) => unknown): void;\n /** Register a contract/group route batch atomically. Every route captures the same current chain it\n * would capture through {@link register}; no route becomes visible unless the full batch validates. */\n registerBatch(routes: readonly {\n readonly method: Method;\n readonly path: string;\n readonly schema: RouteSchema | undefined;\n readonly handler: (context: never) => unknown;\n }[]): void;\n private prepareRoute;\n /** Collapse route-invariant lifecycle decisions into one runner at registration. The request path\n * performs no eligibility ladder: it supplies request state to this already-selected plan. */\n private compileExecutionPlan;\n /** The idempotency lane's bridge back into the normal matched lanes, resolved to a concrete Response\n * (the lane buffers the body, then replays it through the route's real validation + handler). */\n private idempotencyRunLanes;\n /** @internal Symbol-keyed install seam for the `idempotency()` plugin. Off the public typed surface. */\n [INSTALL_IDEMPOTENCY](runtime: IdempotencyRuntime): void;\n /** @internal Symbol-keyed install seam for the `mcp()` plugin. Off the public typed surface. */\n [INSTALL_MCP](runtime: McpRuntime): void;\n /** @internal Symbol-keyed install seam for the `nodeDirect()` plugin. Off the public typed surface. */\n [INSTALL_NODE_DIRECT](runtime: NodeOutcomeRuntime): void;\n /** @internal Symbol-keyed install seam for the `streaming()` plugin. Off the public typed surface. */\n [INSTALL_SSE](runtime: SseRuntime): void;\n /** @internal Symbol-keyed install seam for the `websocket()` plugin. Off the public typed surface. */\n [INSTALL_WS](runtime: WsRuntime): void;\n /**\n * Merge another server's routes into this one — the composition escape hatch for large apps.\n *\n * WHY: the fluent chain accumulates one type-alias level per route, and TypeScript resolves\n * that stack in one recursion — a single chain hits TS2589 at ~95 routes. Groups keep every\n * chain short: build each domain (`listings`, `agents`, …) as its own `server()` (its registry\n * resolves independently), then `app.merge(listings).merge(agents)` — each merge adds ONE level\n * regardless of group size. 300+ routes stay fully typed (see many-routes.test-d.ts). The\n * other escape hatch is contract-first `implement()`, whose registry is a single object type.\n *\n * Semantics: merged routes keep the chains captured where they were DEFINED — the group's\n * `derive`/`decorate`/`beforeHandle`/`afterHandle`/`onError`/`around` apply to its routes\n * exactly as they did standalone, so a group wires its own plugins. The group's request-level\n * hooks (`onRequest`/`onResponse`/`onResponseFinalized`) are appended to this server's. This\n * server's route-scoped chains do NOT retroactively wrap merged routes (order-scoped, like\n * routes registered before a `derive`). Fail closed: a path+method collision throws\n * `RouteConfigError` at merge time, and a group with WebSocket routes is refused (register\n * those on the parent).\n */\n merge<R2 extends Registry, Ctx2>(other: Server<R2, Ctx2>): Server<R & R2, Ctx>;\n /** A fused renderer closes over runtime services to keep its seven-argument JSC fast path. Merging\n * rebinds that closure once to the executing server; generic plans already receive the runtime. */\n private bindFusedRuntime;\n /**\n * Enumerate the registered routes (method, path, input schemas), in registration\n * order. Powers `toOpenAPI` and other introspection; the router trie itself no\n * longer holds the original patterns.\n */\n routes(): ReadonlyArray<RouteDescriptor>;\n /**\n * Resolve a `Request` to a `Response` — the whole lifecycle, testable without a port. The\n * optional `platform` carries edge inputs (`env`, `waitUntil`); edge adapters pass it, and\n * Bun/Node/Deno omit it (then `c.env` is `undefined` and `c.waitUntil` runs fire-and-forget).\n */\n fetch(req: Request, platform?: Platform<EnvOf<Ctx>>): MaybePromise<Response>;\n private fetchSource;\n private fetchSourceInner;\n /** Web response path when Bun already matched the route. The lifecycle and response hooks remain\n * exactly the same as {@link fetchSource}; only portable URL scanning + trie lookup are skipped. */\n private fetchMatched;\n private fetchMatchedInner;\n /**\n * Run `produce` under the capacity gate: admit → run → release exactly once when the response is\n * produced (or the run throws). Only reached when {@link capacityGate} is set, so the off path pays\n * nothing. The slot is held for the duration of handler execution, not the streaming of the body —\n * capacity here bounds concurrent *work*, matching how in-flight is counted.\n */\n private admitGated;\n private runAdmitted;\n /**\n * Like {@link fetch}, but renders a plain-data result **without** building a Web `Response` — the\n * `@nifrajs/node` adapter serializes the returned primitives straight to the socket, skipping the undici\n * `Response` build + body drain (the bulk of the Node bridge cost, measured ≈4µs/req). A handler that\n * returns a `Response`, an error/short-circuit, or any registered `onResponse` hook falls back to the\n * full Web path (`{ kind: \"response\" }`), so behavior is identical — only the common JSON-data case is\n * faster. Same lifecycle as {@link fetch} (body cap, validation, hooks all run); only the final\n * render differs.\n */\n resolveNode(req: Request, platform?: Platform<EnvOf<Ctx>>): MaybePromise<NodeServeOutcome>;\n resolveNodeSource(source: RequestSource, platform?: Platform<EnvOf<Ctx>>, suppliedRuntime?: NodeOutcomeRuntime): MaybePromise<NodeServeOutcome>;\n /**\n * Resolve a WebSocket upgrade — the seam every serving adapter uses. Returns `pass` (not a WS\n * upgrade for a registered route → handle as normal HTTP), `reject` (a WS route matched but\n * `upgrade()` rejected, or the path was malformed → return `response`), or `upgrade` (perform the\n * runtime upgrade, then dispatch the native socket's events to `handler`, seeding `ws.data` with\n * `data`). Runs the route's `upgrade(c)` guard in a real request context. Synchronous unless\n * `upgrade()` is async; a throw rejects with a flat 500 (no detail leaked).\n */\n resolveWebSocketUpgrade(req: Request, platform?: Platform<EnvOf<Ctx>>): MaybePromise<WebSocketUpgradeOutcome>;\n /** Bun `fetch` when WS routes exist: try a WS upgrade first, else run the normal HTTP lifecycle.\n * `undefined` ⇒ Bun owns the upgraded socket; a `Response` ⇒ a normal reply or a rejected upgrade.\n * (The socket dispatch itself lives in `ws-bun.ts`, loaded via `@nifrajs/core/ws`.) */\n private bunFetchWithWebSocket;\n /**\n * The shared lifecycle, generic over how the final value is rendered: `finalize` turns a handler's\n * result + `set` into the output `T` (`toResponse` → a Web `Response`; `toNodeOutcome` → node-direct\n * primitives), `wrapResponse` lifts an early/error `Response` into that same `T`, and `onTimeout`\n * produces the 503. The Web `fetch` and `resolveNode` are thin callers over this one routing +\n * context + lifecycle implementation — no duplication across the trust boundary.\n */\n /** Apply the `clientIp` trust declaration to the adapter's raw socket peer, returning a platform\n * whose `clientIp` is the derived caller. Only called when a trust declaration is configured. */\n private deriveClientIp;\n private dispatch;\n /**\n * onRequest short-circuit path. Synchronous as long as every hook returns synchronously (the\n * common case — e.g. CORS returning `undefined` for a non-preflight request): an `async` version\n * here put EVERY request of any app with one onRequest hook onto the promise machinery, profiled\n * at ~13% of a realistic request. The first hook that returns a Promise hands the REMAINING\n * hooks to the async continuation; behavior is identical.\n */\n private runWithOnRequest;\n /** Async tail of {@link runWithOnRequest}: applies the first awaited hook's outcome, then runs\n * the remaining hooks (awaiting freely — we're already async here). */\n private continueOnRequest;\n private takeResponseRequest;\n /**\n * Route → build context → run. Synchronous through to the handler for a **bare** route\n * (selected by its compiled plan), so a sync handler produces its result with zero promise allocations;\n * routes with validation/hooks keep the full async {@link runLifecycle}, unchanged.\n */\n private routeAndRun;\n /** Run a route that has already been matched by the runtime or Nifra's portable router. */\n private runMatched;\n /** Supply request-specific deadline state to the route's precompiled execution plan. */\n private runMatchedLanes;\n /** @internal Symbol-keyed install seam for the `effectLedger()` plugin. Off the public typed surface. */\n [INSTALL_EFFECT_LEDGER](runtime: EffectLedgerRuntime): void;\n /** The narrowest bare route: a syntactic `() => ...` handler cannot observe the context argument, so\n * successful requests can skip allocating `RequestContext`. Errors still allocate one for logging. */\n private runContextlessBare;\n private contextlessBareError;\n /**\n * The synchronous fast path selected by a route's execution plan: apply static decorations, call the\n * handler, render the result — **no `await`** unless the handler itself returns a promise. It mirrors\n * the bare slice of {@link runLifecycle} (which a bare route would otherwise no-op through) and shares\n * {@link logRequestError}; a bare route has no `onError` hooks, so error handling is fully synchronous\n * (a thrown `Response` is control flow; anything else is a logged flat 500). This is where nifra skips\n * the per-request async-frame tax — the same win codegen routers get, but without `eval`.\n */\n private runBare;\n /** Bare-route error rendering — identical to {@link runLifecycle}'s catch minus the (absent) onError\n * loop: a thrown `Response` is returned as deliberate control flow; anything else is logged + 500. */\n /**\n * Build a route's fused Web renderer. Composition happens once at\n * registration; the returned closure is what every request to the route runs. Behavior is\n * byte-identical to the generic `runBare`/`runContextlessBare` + `toResponse` pair — same\n * decoration order, same error routing (thrown `Response` = control flow; anything else logs and\n * 500s), same respond semantics (the lifecycle parity suite pins it).\n */\n private buildFusedWeb;\n private bareError;\n private runWithAround;\n private runAround;\n private runBodyOnly;\n /** Validate + run the handler for the bodyOnly path — shared by the inline fast path and the\n * streaming fallback. A method (not per-request closures) so the hot path allocates nothing\n * beyond the one `.then` continuation. */\n private finishBodyOnly;\n private executeHandler;\n private handleValidationErrorRecovery;\n private applyBodyValidation;\n private runQueryOnly;\n /** Validate-result → set `ctx.query` → run handler. A method (not a per-request closure), the\n * query analogue of {@link applyBodyValidation}. */\n private applyQueryValidation;\n /**\n * Thread the response through each global `onResponse` hook. Stays SYNCHRONOUS until a hook\n * actually returns a Promise — an `async` version forced a promise + microtask on EVERY response\n * of any app with an onResponse hook (cors/securityHeaders/etag/timing all use onResponse), the\n * same ~13%/req tax the onRequest walk was de-async'd to avoid. The first async hook hands the\n * rest to {@link continueOnResponse}.\n */\n private applyOnResponse;\n private applyOnResponseAndFinalize;\n private completeResponseFinalization;\n private failResponseFinalization;\n /** Notify terminal observers in order while isolating both sync and async failures. */\n private notifyResponseFinalized;\n /** Async tail of {@link applyOnResponse}: runs the remaining hooks once one has gone async. */\n private continueOnResponse;\n /**\n * Bound the response time. On timeout we abort `ctx.signal` (so cancellation-aware\n * handlers can bail) and return 503; the in-flight work keeps running but its\n * result is discarded — JS can't forcibly cancel a promise.\n */\n private withTimeout;\n /**\n * The post-match lifecycle: validate → derive → beforeHandle → handler → afterHandle, with onError.\n * Generic over the render: a success value goes through `finalize(result, set)` (a Web `Response`, or\n * node-direct primitives); an early/error `Response` (validation, thrown, 500) through `wrapResponse`.\n */\n private runLifecycle;\n private handleLifecycleError;\n /** Log an unhandled request error to the (redacting) logger — shared by {@link runLifecycle} and the\n * bare fast path ({@link bareError}) so both record the same fields. Never throws; never leaks. */\n private logRequestError;\n private readAndValidateBody;\n /** Apply validation and its recovery hook on the generic lifecycle lane. Recovery is completed\n * before derives/beforeHandle run, matching the body-only and query-only execution lanes. */\n private applyLifecycleValidation;\n /**\n * Read the body as text, capped at `maxBodyBytes`. Rejects (`null`) on a\n * `Content-Length` over the cap *before* buffering, and aborts mid-stream once the\n * running byte count exceeds it — so a lying or absent length can't force us to\n * buffer an oversized payload.\n *\n * Fast path: when a non-chunked request carries a `Content-Length` within the cap,\n * a native `req.json()` is already bounded — under HTTP/1.1 + HTTP/2 framing the\n * runtime delivers at most `Content-Length` bytes — so we skip the manual stream\n * loop and a separate text decode. It trusts the wire\n * *framing*, not the header value: nifra only ever receives framed Requests from the\n * runtime's HTTP server, never a hand-built one with a mismatched length. Chunked or\n * length-less bodies fall through to the streaming byte-cap guard below.\n */\n private readBoundedJson;\n /** Adapt one route's compiled execution plan to Bun's already-matched request shape. Route\n * semantics remain in the plan; this closure only supplies native params and deadline fallback. */\n private compileBunNativeHandler;\n /** Compile portable route registrations into Bun's native route table. Apps with request-rewrite\n * hooks or WebSockets retain the single portable dispatcher because those features must run before\n * route selection/upgrade. Named wildcards also stay on the fallback until Bun exposes their raw\n * capture semantics; static and `:param` routes take the native lane. */\n private buildBunNativeRoutes;\n /**\n * Start a `Bun.serve` instance bound to `port` (use `0` for an ephemeral port).\n *\n * `reusePort` sets `SO_REUSEPORT` so **multiple processes can bind the same port** and the kernel\n * load-balances connections across them — the standard way to use every core (Bun is\n * single-threaded per process). Spawn one process per core, each calling\n * `app.listen(PORT, { reusePort: true })`; see `examples/cluster.ts`. Every process must opt in,\n * and all of them must be the same app. Linux balances ~evenly; macOS accepts the flag but may\n * favor one socket (fine for dev, measure on Linux for production numbers).\n *\n * `hostname` is the bind address, defaulting to Bun's `0.0.0.0` (every interface). Pass\n * `\"127.0.0.1\"` to bind loopback only - an admin surface, a sidecar, or anything that must not be\n * reachable off the box. Omitting it when you meant to restrict is a real exposure, so it is a\n * first-class option rather than something a caller has to drop down to `Bun.serve` for.\n */\n listen(port: number, options?: {\n readonly reusePort?: boolean;\n readonly hostname?: string;\n }): RunningServer;\n /**\n * Gracefully stop: wait for in-flight requests to finish (up to `drainMs`), then\n * issue a single terminal stop — graceful if everything drained, forced if\n * stragglers remain. Safe to call when not listening.\n *\n * The Bun semantics: poll `pendingRequests` (awaiting\n * `stop()`'s promise drops in-flight requests), and decide graceful-vs-forced in\n * ONE call (Bun can't escalate an already-graceful `stop()` to a forced close).\n * New connections may be accepted during the drain window; in a real deploy the\n * load balancer has already stopped routing here, and `drainMs` bounds it.\n */\n stop({ drainMs }?: {\n drainMs?: number;\n }): Promise<void>;\n private installSignalHandlers;\n}",
9456
+ "signature": "export declare class Server<R extends Registry = EmptyRegistry, Ctx = EmptyContext> {\n private readonly catalog;\n /** WebSocket routes, matched separately at upgrade time (a GET + `Upgrade: websocket`). */\n private readonly wsRouter;\n private wsRouteCount;\n /** In-process pub/sub backing `ws.subscribe(topic)` + `app.publish(topic, data)` (single-instance).\n * Created by the first `app.ws()` via the `@nifrajs/core/ws` runtime — `undefined` until then, so a\n * no-WebSocket app never constructs (or bundles) it. */\n private topics;\n private readonly maxBodyBytes;\n private readonly wsMaxPayloadBytes;\n private readonly requestTimeoutMs;\n /** Opt-in caller-IP trust declaration; `undefined` = socket peer only, no forwarded header believed. */\n private readonly clientIpTrust;\n private readonly acceptInboundDeadlines;\n private readonly maxInboundDeadlineMs;\n private readonly deadlineAdmissionOptions;\n private readonly gracefulSignals;\n /** Capacity-admission gate; `undefined` = off (the request path pays nothing). */\n private readonly capacityGate;\n private readonly onCapabilityUse;\n private readonly capabilityInterceptors;\n private readonly capabilityObservers;\n /** The installed effect-ledger runtime (owns the sink + per-route resolution + settle), or\n * `undefined` when the effect-ledger plugin is not installed. */\n private effectLedgerRuntime;\n /** The installed idempotency runtime (owns the app-wide default store + the dedupe lane), or\n * `undefined` when the idempotency plugin is not installed. */\n private idempotencyRuntime;\n /** Installed opt-in runtime for `.tool()`/`.resource()`/`.prompt()`; `undefined` until `.use(mcp())`. */\n private mcpRuntime;\n /** Installed Node-direct renderer for direct `resolveNode()` callers; `undefined` until `.use(nodeDirect())`. */\n private nodeOutcomeRuntime;\n /** Installed streaming runtime for `.sse()` routes; `undefined` until `.use(streaming())`. */\n private sseRuntime;\n /** Installed WebSocket runtime for `.ws()` routes; `undefined` until `.use(websocket())`. */\n private wsRuntime;\n private readonly logger;\n /** App-wide validation-error fallback; a route's own `schema.onValidationError` takes precedence. */\n private readonly defaultOnValidationError?;\n private bunServer;\n private sealed;\n private readonly derives;\n private readonly decorations;\n private readonly beforeHandleHooks;\n private readonly afterHandleHooks;\n private readonly onErrorHooks;\n private readonly aroundHooks;\n private readonly onRequestHooks;\n private readonly onResponseHooks;\n private readonly onResponseFinalizedHooks;\n private readonly responseRequests;\n /** Names of plugins/middleware already applied via `use` — for idempotent dedupe. */\n private readonly appliedPlugins;\n /** Order-scoped evidence captured by routes registered after an assured plugin. */\n private readonly activeAssurance;\n /** App-wide evidence from global hooks; applies retroactively to every route. */\n private readonly globalAssurance;\n /** App-declared MCP resources / prompts (via {@link resource} / {@link prompt}), read by `nifra mcp`. */\n private readonly mcpResourceList;\n private readonly mcpPromptList;\n constructor(options?: ServerOptions);\n private assertConfigurable;\n /** Add a per-request, computed context extension for subsequent routes. */\n derive<D extends object>(fn: (context: Context & Ctx) => MaybePromise<D>): Server<R, Ctx & D>;\n /** Add a static context value for subsequent routes. */\n decorate<const K extends string, V>(key: K, value: V): Server<R, Ctx & Record<K, V>>;\n /**\n * Run before routing on the raw request. Return a `Response` to short-circuit, or a replacement\n * `Request` to continue routing with a rewritten method/URL/headers. Global.\n */\n onRequest(fn: (req: Request, platform?: Platform<EnvOf<Ctx>>) => MaybePromise<OnRequestResult>): this;\n /** Run after validation, before the handler; a non-`undefined` return short-circuits. Order-scoped. */\n beforeHandle(fn: (context: Context & Ctx) => MaybePromise<unknown>): this;\n /**\n * Wrap the matched route lifecycle for subsequent routes. This is intentionally generic over the\n * route output, so wrappers like async context storage do not force Node's direct JSON path through\n * a Web `Response`. The first registered wrapper is outermost.\n */\n around(fn: <T>(context: Context & Ctx, next: () => MaybePromise<T>) => MaybePromise<T>): this;\n /**\n * Asynchronously admit each subsequent `executeCapability()` call before its owned effect runs.\n * Interceptors receive token-only metadata plus an abort signal and must call `next()` exactly once\n * to admit. Returning without `next()`, timing out, aborting, or throwing fails the effect closed.\n */\n aroundCapability(interceptor: CapabilityInterceptor, options?: AroundCapabilityOptions): this;\n /** Observe token-only admission/execution lifecycle events for subsequent capability routes. */\n observeCapability(observer: EffectLifecycleObserver): this;\n /** Transform the handler's result before it is serialized. Order-scoped. */\n afterHandle(fn: (result: unknown, context: Context & Ctx) => MaybePromise<unknown>): this;\n /** Handle a thrown error; a non-`undefined` return becomes the response (else the default 500). Order-scoped. */\n onError(fn: (error: unknown, context: Context & Ctx) => MaybePromise<unknown>): this;\n /** Transform every outgoing response — success, error, 404, 405, short-circuit. Global. */\n onResponse(fn: (response: Response, req: Request) => MaybePromise<Response>): this;\n /** Observe the terminal response after all transformations. Observers are ordered and fail-open. */\n onResponseFinalized(fn: (outcome: ResponseFinalization, req: Request) => MaybePromise<void>): this;\n /**\n * Apply a type-**identity** plugin ({@link IdentityPlugin}, from {@link defineIdentityPlugin}) — it\n * registers routes/hooks but doesn't change the types, so this returns `this` with the route registry\n * and context fully intact. This overload exists specifically so a *named* identity plugin (e.g.\n * `@nifrajs/better-auth`) threads the registry: its `& { pluginName }` intersection would otherwise\n * defeat the generic inference of the transforming overload below and collapse the result to `any`.\n */\n use(plugin: IdentityPlugin): this;\n /**\n * Apply a **plugin function** — `(app) => app`, typically built with {@link definePlugin}. It's\n * called with `this` and its result is returned, so an inline plugin's `derive`/`decorate` thread\n * the added context to handlers defined after `use` (the overload is generic over the concrete\n * `this`). A named plugin already applied is skipped (idempotent dedupe).\n */\n use<Out extends AnyServer>(plugin: (app: this) => Out): Out;\n /**\n * Apply a {@link Middleware} bundle — wire each hook it provides to its lifecycle point. Returns\n * `this` (no context-type merging); call it before the routes its `beforeHandle`/`afterHandle`\n * should cover (those are order-scoped; `onRequest`/`onResponse` are global). A named bundle already\n * applied is skipped (idempotent).\n */\n use(mw: Middleware): this;\n get<Path extends string, S extends RouteSchema, H extends Handler<Path, S, Ctx>>(path: Path, schema: S, handler: H): Server<AddRoute<R, \"GET\", Path, RouteInfoFor<Path, S, OutputOf<H>>>, Ctx>;\n get<Path extends string, H extends Handler<Path, RouteSchema, Ctx>>(path: Path, handler: H): Server<AddRoute<R, \"GET\", Path, RouteInfoFor<Path, Record<never, never>, OutputOf<H>>>, Ctx>;\n /**\n * Register a **typed SSE route** — a GET endpoint streaming `text/event-stream` whose event\n * payloads are contracted by `schema.sse`. The handler receives the validated context plus a\n * {@link TypedSSEStream}: `stream.send(event)` is compile-time-checked against the schema and\n * JSON-serialized into the SSE `data:` field. The typed client sees the marker and grows a\n * `.subscribe(onEvent)` for the route with the same payload type — end-to-end typed streaming.\n *\n * import { streaming } from \"@nifrajs/core/sse\" // .use(streaming()) enables .sse()\n * const app = server().use(streaming()).sse(\"/feed\", { sse: t.object({ id: t.integer(), title: t.string() }) },\n * async (c, stream) => {\n * stream.send({ id: 1, title: \"hello\" }) // typed\n * await waitForDisconnect(stream.signal)\n * },\n * { keepAlive: 15_000 })\n *\n * // client: const off = api.feed.subscribe((post) => console.log(post.title))\n *\n * `init` passes through to the underlying {@link sse} helper (`keepAlive`, extra headers). The\n * connection closes when the handler resolves, `stream.close()` runs, or the client disconnects\n * (`stream.signal`). Query/body schemas validate exactly as on any other route.\n */\n sse<Path extends string, S extends RouteSchema & {\n sse: StandardSchemaV1;\n }>(path: Path, schema: S, run: (context: Context<Path, S> & Ctx, stream: TypedSSEStream<InferOutput<S[\"sse\"]>>) => void | Promise<void>, init?: SSEInit): Server<AddRoute<R, \"GET\", Path, RouteInfoFor<Path, S, Response>>, Ctx>;\n post<Path extends string, S extends RouteSchema, H extends Handler<Path, S, Ctx>>(path: Path, schema: S, handler: H): Server<AddRoute<R, \"POST\", Path, RouteInfoFor<Path, S, OutputOf<H>>>, Ctx>;\n post<Path extends string, H extends Handler<Path, RouteSchema, Ctx>>(path: Path, handler: H): Server<AddRoute<R, \"POST\", Path, RouteInfoFor<Path, Record<never, never>, OutputOf<H>>>, Ctx>;\n put<Path extends string, S extends RouteSchema, H extends Handler<Path, S, Ctx>>(path: Path, schema: S, handler: H): Server<AddRoute<R, \"PUT\", Path, RouteInfoFor<Path, S, OutputOf<H>>>, Ctx>;\n put<Path extends string, H extends Handler<Path, RouteSchema, Ctx>>(path: Path, handler: H): Server<AddRoute<R, \"PUT\", Path, RouteInfoFor<Path, Record<never, never>, OutputOf<H>>>, Ctx>;\n patch<Path extends string, S extends RouteSchema, H extends Handler<Path, S, Ctx>>(path: Path, schema: S, handler: H): Server<AddRoute<R, \"PATCH\", Path, RouteInfoFor<Path, S, OutputOf<H>>>, Ctx>;\n patch<Path extends string, H extends Handler<Path, RouteSchema, Ctx>>(path: Path, handler: H): Server<AddRoute<R, \"PATCH\", Path, RouteInfoFor<Path, Record<never, never>, OutputOf<H>>>, Ctx>;\n delete<Path extends string, S extends RouteSchema, H extends Handler<Path, S, Ctx>>(path: Path, schema: S, handler: H): Server<AddRoute<R, \"DELETE\", Path, RouteInfoFor<Path, S, OutputOf<H>>>, Ctx>;\n delete<Path extends string, H extends Handler<Path, RouteSchema, Ctx>>(path: Path, handler: H): Server<AddRoute<R, \"DELETE\", Path, RouteInfoFor<Path, Record<never, never>, OutputOf<H>>>, Ctx>;\n /**\n * Declare an **MCP tool** an agent can call (via `nifra mcp`, or a mounted MCP endpoint): a typed\n * `POST /_nifra/tool/<name>` route whose `input`/`output` schemas contract the call and surface in\n * `tools/list`. Requires `.use(mcp())` - without it, `.tool()` is a registration error, so an\n * ordinary HTTP app never bundles the MCP wiring. Siblings: {@link resource}, {@link prompt}.\n *\n * import { mcp } from \"@nifrajs/core/mcp\"\n * const app = server().use(mcp()).tool(\n * \"search\",\n * { description: \"Search posts\", input: t.object({ q: t.string() }) },\n * ({ q }) => findPosts(q),\n * )\n */\n tool<Name extends string, S extends {\n description: string;\n input: StandardSchemaV1;\n output?: StandardSchemaV1;\n annotations?: ToolAnnotations;\n }, H extends (input: InferOutput<S[\"input\"]>, ctx: Context & Ctx) => MaybePromise<S[\"output\"] extends StandardSchemaV1 ? InferOutput<S[\"output\"]> : unknown>>(name: Name, config: S, handler: H): Server<AddRoute<R, \"POST\", `/_nifra/tool/${Name}`, RouteInfoFor<`/_nifra/tool/${Name}`, S[\"output\"] extends StandardSchemaV1 ? {\n body: S[\"input\"];\n response: S[\"output\"];\n } : {\n body: S[\"input\"];\n }, OutputOf<H>>>, Ctx>;\n /**\n * Declare an MCP **resource** — read-only data an agent can fetch through `nifra mcp` (app config, a\n * generated document, …). `read` runs in the app process, so capture whatever app state it needs in the\n * closure. `uri` is the MCP resource identifier (e.g. `\"myapp://config\"`). The sibling of {@link tool}\n * for the resource half of MCP.\n */\n resource(uri: string, config: {\n readonly name: string;\n readonly description?: string;\n readonly mimeType?: string;\n }, read: McpResourceDescriptor[\"read\"]): Server<R, Ctx>;\n /**\n * Declare an MCP **prompt** — a reusable prompt template an agent can fetch through `nifra mcp`.\n * `handler` receives the caller's arguments and returns the rendered messages.\n */\n prompt(name: string, config: {\n readonly description: string;\n readonly arguments?: readonly PromptArgument[];\n }, handler: McpPromptDescriptor[\"handler\"]): Server<R, Ctx>;\n /** The MCP resources declared via {@link resource} — enumerated by `nifra mcp`. */\n mcpResources(): readonly McpResourceDescriptor[];\n /** The MCP prompts declared via {@link prompt} — enumerated by `nifra mcp`. */\n mcpPrompts(): readonly McpPromptDescriptor[];\n /**\n * Register a **WebSocket** route. The connection upgrades on a `GET` to `path` carrying\n * `Upgrade: websocket`; the optional `handler.upgrade(c)` runs in the request context first and may\n * reject (return a `Response`) or seed per-connection `ws.data`. WebSockets are served by the\n * adapter (`listen()`, `@nifrajs/node`, `@nifrajs/deno`, `toFetchHandler`) — not by bare `app.fetch`, which\n * has no socket (a WS path through `app.fetch` is a normal HTTP response).\n *\n * The route also enters the type-level registry (under the pseudo-method `\"WS\"`), so the typed\n * client grows a `.ws()` handle for it: `messageSchema` types what the client may `send`,\n * `sendSchema` types the frames it receives. Passing explicit type arguments (`ws<MyData>(…)`)\n * defeats path-literal inference and skips the registry entry - the route still serves, it is just\n * invisible to `client<App>`; prefer typing `data` via `upgrade()`'s return.\n *\n * app.ws(\"/chat\", { open: (ws) => ws.send(\"hi\"), message: (ws, data) => ws.send(data) })\n */\n ws<Data = unknown, Schema extends StandardSchemaV1 | undefined = undefined, Send extends StandardSchemaV1 | undefined = undefined, Path extends string = string>(path: Path, handler: WebSocketHandler<Data, EnvOf<Ctx>, Schema, Send>): string extends Path ? Server<R, Ctx> : Server<AddRoute<R, \"WS\", Path, WsRouteInfoFor<Path, Schema, Send>>, Ctx>;\n /**\n * Broadcast `data` to every WebSocket connection subscribed to `topic` (via `ws.subscribe(topic)`).\n * In-process and **single-instance** (see {@link TopicRegistry}) — a multi-instance deploy must bridge\n * an external fan-out (Redis, a Durable Object) to this. A no-op when nobody is subscribed.\n */\n publish(topic: string, data: string | ArrayBufferView | ArrayBuffer): void;\n private route;\n /**\n * Low-level route registration shared by the inline builder and `implement()`.\n * Captures the server's current `derive`/`decorate` chain into the route — this\n * is the \"compiled\", order-scoped per-route chain.\n */\n register(method: Method, path: string, schema: RouteSchema | undefined, handler: (context: never) => unknown): void;\n /** Register a contract/group route batch atomically. Every route captures the same current chain it\n * would capture through {@link register}; no route becomes visible unless the full batch validates. */\n registerBatch(routes: readonly {\n readonly method: Method;\n readonly path: string;\n readonly schema: RouteSchema | undefined;\n readonly handler: (context: never) => unknown;\n }[]): void;\n private prepareRoute;\n /** Collapse route-invariant lifecycle decisions into one runner at registration. The request path\n * performs no eligibility ladder: it supplies request state to this already-selected plan. */\n private compileExecutionPlan;\n /** The idempotency lane's bridge back into the normal matched lanes, resolved to a concrete Response\n * (the lane buffers the body, then replays it through the route's real validation + handler). */\n private idempotencyRunLanes;\n /** @internal Symbol-keyed install seam for the `idempotency()` plugin. Off the public typed surface. */\n [INSTALL_IDEMPOTENCY](runtime: IdempotencyRuntime): void;\n /** @internal Symbol-keyed install seam for the `mcp()` plugin. Off the public typed surface. */\n [INSTALL_MCP](runtime: McpRuntime): void;\n /** @internal Symbol-keyed install seam for the `nodeDirect()` plugin. Off the public typed surface. */\n [INSTALL_NODE_DIRECT](runtime: NodeOutcomeRuntime): void;\n /** @internal Symbol-keyed install seam for the `streaming()` plugin. Off the public typed surface. */\n [INSTALL_SSE](runtime: SseRuntime): void;\n /** @internal Symbol-keyed install seam for the `websocket()` plugin. Off the public typed surface. */\n [INSTALL_WS](runtime: WsRuntime): void;\n /**\n * Merge another server's routes into this one — the composition escape hatch for large apps.\n *\n * WHY: the fluent chain accumulates one type-alias level per route, and TypeScript resolves\n * that stack in one recursion — a single chain hits TS2589 at ~95 routes. Groups keep every\n * chain short: build each domain (`listings`, `agents`, …) as its own `server()` (its registry\n * resolves independently), then `app.merge(listings).merge(agents)` — each merge adds ONE level\n * regardless of group size. 300+ routes stay fully typed (see many-routes.test-d.ts). The\n * other escape hatch is contract-first `implement()`, whose registry is a single object type.\n *\n * Semantics: merged routes keep the chains captured where they were DEFINED — the group's\n * `derive`/`decorate`/`beforeHandle`/`afterHandle`/`onError`/`around` apply to its routes\n * exactly as they did standalone, so a group wires its own plugins. The group's request-level\n * hooks (`onRequest`/`onResponse`/`onResponseFinalized`) are appended to this server's. This\n * server's route-scoped chains do NOT retroactively wrap merged routes (order-scoped, like\n * routes registered before a `derive`). Fail closed: a path+method collision throws\n * `RouteConfigError` at merge time, and a group with WebSocket routes is refused (register\n * those on the parent).\n */\n merge<R2 extends Registry, Ctx2>(other: Server<R2, Ctx2>): Server<R & R2, Ctx>;\n /** A fused renderer closes over runtime services to keep its seven-argument JSC fast path. Merging\n * rebinds that closure once to the executing server; generic plans already receive the runtime. */\n private bindFusedRuntime;\n /**\n * Enumerate the registered routes (method, path, input schemas), in registration\n * order. Powers `toOpenAPI` and other introspection; the router trie itself no\n * longer holds the original patterns.\n */\n routes(): ReadonlyArray<RouteDescriptor>;\n /**\n * Resolve a `Request` to a `Response` — the whole lifecycle, testable without a port. The\n * optional `platform` carries edge inputs (`env`, `waitUntil`); edge adapters pass it, and\n * Bun/Node/Deno omit it (then `c.env` is `undefined` and `c.waitUntil` runs fire-and-forget).\n */\n fetch(req: Request, platform?: Platform<EnvOf<Ctx>>): MaybePromise<Response>;\n private fetchSource;\n private fetchSourceInner;\n /** Web response path when Bun already matched the route. The lifecycle and response hooks remain\n * exactly the same as {@link fetchSource}; only portable URL scanning + trie lookup are skipped. */\n private fetchMatched;\n private fetchMatchedInner;\n /**\n * Run `produce` under the capacity gate: admit → run → release exactly once when the response is\n * produced (or the run throws). Only reached when {@link capacityGate} is set, so the off path pays\n * nothing. The slot is held for the duration of handler execution, not the streaming of the body —\n * capacity here bounds concurrent *work*, matching how in-flight is counted.\n */\n private admitGated;\n private runAdmitted;\n /**\n * Like {@link fetch}, but renders a plain-data result **without** building a Web `Response` — the\n * `@nifrajs/node` adapter serializes the returned primitives straight to the socket, skipping the undici\n * `Response` build + body drain (the bulk of the Node bridge cost, measured ≈4µs/req). A handler that\n * returns a `Response`, an error/short-circuit, or any registered `onResponse` hook falls back to the\n * full Web path (`{ kind: \"response\" }`), so behavior is identical — only the common JSON-data case is\n * faster. Same lifecycle as {@link fetch} (body cap, validation, hooks all run); only the final\n * render differs.\n */\n resolveNode(req: Request, platform?: Platform<EnvOf<Ctx>>): MaybePromise<NodeServeOutcome>;\n resolveNodeSource(source: RequestSource, platform?: Platform<EnvOf<Ctx>>, suppliedRuntime?: NodeOutcomeRuntime): MaybePromise<NodeServeOutcome>;\n /**\n * Resolve a WebSocket upgrade — the seam every serving adapter uses. Returns `pass` (not a WS\n * upgrade for a registered route → handle as normal HTTP), `reject` (a WS route matched but\n * `upgrade()` rejected, or the path was malformed → return `response`), or `upgrade` (perform the\n * runtime upgrade, then dispatch the native socket's events to `handler`, seeding `ws.data` with\n * `data`). Runs the route's `upgrade(c)` guard in a real request context. Synchronous unless\n * `upgrade()` is async; a throw rejects with a flat 500 (no detail leaked).\n */\n resolveWebSocketUpgrade(req: Request, platform?: Platform<EnvOf<Ctx>>): MaybePromise<WebSocketUpgradeOutcome>;\n /** Bun `fetch` when WS routes exist: try a WS upgrade first, else run the normal HTTP lifecycle.\n * `undefined` ⇒ Bun owns the upgraded socket; a `Response` ⇒ a normal reply or a rejected upgrade.\n * (The socket dispatch itself lives in `ws-bun.ts`, loaded via `@nifrajs/core/ws`.) */\n private bunFetchWithWebSocket;\n /**\n * The shared lifecycle, generic over how the final value is rendered: `finalize` turns a handler's\n * result + `set` into the output `T` (`toResponse` → a Web `Response`; `toNodeOutcome` → node-direct\n * primitives), `wrapResponse` lifts an early/error `Response` into that same `T`, and `onTimeout`\n * produces the 503. The Web `fetch` and `resolveNode` are thin callers over this one routing +\n * context + lifecycle implementation — no duplication across the trust boundary.\n */\n /** Apply the `clientIp` trust declaration to the adapter's raw socket peer, returning a platform\n * whose `clientIp` is the derived caller. Only called when a trust declaration is configured. */\n private deriveClientIp;\n private dispatch;\n /**\n * onRequest short-circuit path. Synchronous as long as every hook returns synchronously (the\n * common case — e.g. CORS returning `undefined` for a non-preflight request): an `async` version\n * here put EVERY request of any app with one onRequest hook onto the promise machinery, profiled\n * at ~13% of a realistic request. The first hook that returns a Promise hands the REMAINING\n * hooks to the async continuation; behavior is identical.\n */\n private runWithOnRequest;\n /** Async tail of {@link runWithOnRequest}: applies the first awaited hook's outcome, then runs\n * the remaining hooks (awaiting freely — we're already async here). */\n private continueOnRequest;\n private takeResponseRequest;\n /**\n * Route → build context → run. Synchronous through to the handler for a **bare** route\n * (selected by its compiled plan), so a sync handler produces its result with zero promise allocations;\n * routes with validation/hooks keep the full async {@link runLifecycle}, unchanged.\n */\n private routeAndRun;\n /** Run a route that has already been matched by the runtime or Nifra's portable router. */\n private runMatched;\n /** Supply request-specific deadline state to the route's precompiled execution plan. */\n private runMatchedLanes;\n /** @internal Symbol-keyed install seam for the `effectLedger()` plugin. Off the public typed surface. */\n [INSTALL_EFFECT_LEDGER](runtime: EffectLedgerRuntime): void;\n /** The narrowest bare route: a syntactic `() => ...` handler cannot observe the context argument, so\n * successful requests can skip allocating `RequestContext`. Errors still allocate one for logging. */\n private runContextlessBare;\n private contextlessBareError;\n /**\n * The synchronous fast path selected by a route's execution plan: apply static decorations, call the\n * handler, render the result — **no `await`** unless the handler itself returns a promise. It mirrors\n * the bare slice of {@link runLifecycle} (which a bare route would otherwise no-op through) and shares\n * {@link logRequestError}; a bare route has no `onError` hooks, so error handling is fully synchronous\n * (a thrown `Response` is control flow; anything else is a logged flat 500). This is where nifra skips\n * the per-request async-frame tax — the same win codegen routers get, but without `eval`.\n */\n private runBare;\n /** Bare-route error rendering — identical to {@link runLifecycle}'s catch minus the (absent) onError\n * loop: a thrown `Response` is returned as deliberate control flow; anything else is logged + 500. */\n /**\n * Build a route's fused Web renderer. Composition happens once at\n * registration; the returned closure is what every request to the route runs. Behavior is\n * byte-identical to the generic `runBare`/`runContextlessBare` + `toResponse` pair — same\n * decoration order, same error routing (thrown `Response` = control flow; anything else logs and\n * 500s), same respond semantics (the lifecycle parity suite pins it).\n */\n private buildFusedWeb;\n private bareError;\n private runWithAround;\n private runAround;\n private runBodyOnly;\n /** Validate + run the handler for the bodyOnly path — shared by the inline fast path and the\n * streaming fallback. A method (not per-request closures) so the hot path allocates nothing\n * beyond the one `.then` continuation. */\n private finishBodyOnly;\n private executeHandler;\n private handleValidationErrorRecovery;\n private applyBodyValidation;\n private runQueryOnly;\n /** Validate-result → set `ctx.query` → run handler. A method (not a per-request closure), the\n * query analogue of {@link applyBodyValidation}. */\n private applyQueryValidation;\n /**\n * Thread the response through each global `onResponse` hook. Stays SYNCHRONOUS until a hook\n * actually returns a Promise — an `async` version forced a promise + microtask on EVERY response\n * of any app with an onResponse hook (cors/securityHeaders/etag/timing all use onResponse), the\n * same ~13%/req tax the onRequest walk was de-async'd to avoid. The first async hook hands the\n * rest to {@link continueOnResponse}.\n */\n private applyOnResponse;\n private applyOnResponseAndFinalize;\n private completeResponseFinalization;\n private failResponseFinalization;\n /** Notify terminal observers in order while isolating both sync and async failures. */\n private notifyResponseFinalized;\n /** Async tail of {@link applyOnResponse}: runs the remaining hooks once one has gone async. */\n private continueOnResponse;\n /**\n * Bound the response time. On timeout we abort `ctx.signal` (so cancellation-aware\n * handlers can bail) and return 503; the in-flight work keeps running but its\n * result is discarded — JS can't forcibly cancel a promise.\n */\n private withTimeout;\n /**\n * The post-match lifecycle: validate → derive → beforeHandle → handler → afterHandle, with onError.\n * Generic over the render: a success value goes through `finalize(result, set)` (a Web `Response`, or\n * node-direct primitives); an early/error `Response` (validation, thrown, 500) through `wrapResponse`.\n */\n private runLifecycle;\n private handleLifecycleError;\n /** Log an unhandled request error to the (redacting) logger — shared by {@link runLifecycle} and the\n * bare fast path ({@link bareError}) so both record the same fields. Never throws; never leaks. */\n private logRequestError;\n private readAndValidateBody;\n /** Apply validation and its recovery hook on the generic lifecycle lane. Recovery is completed\n * before derives/beforeHandle run, matching the body-only and query-only execution lanes. */\n private applyLifecycleValidation;\n /**\n * Read the body as text, capped at `maxBodyBytes`. Rejects (`null`) on a\n * `Content-Length` over the cap *before* buffering, and aborts mid-stream once the\n * running byte count exceeds it — so a lying or absent length can't force us to\n * buffer an oversized payload.\n *\n * Fast path: when a non-chunked request carries a `Content-Length` within the cap,\n * a native `req.json()` is already bounded — under HTTP/1.1 + HTTP/2 framing the\n * runtime delivers at most `Content-Length` bytes — so we skip the manual stream\n * loop and a separate text decode. It trusts the wire\n * *framing*, not the header value: nifra only ever receives framed Requests from the\n * runtime's HTTP server, never a hand-built one with a mismatched length. Chunked or\n * length-less bodies fall through to the streaming byte-cap guard below.\n */\n private readBoundedJson;\n /** Adapt one route's compiled execution plan to Bun's already-matched request shape. Route\n * semantics remain in the plan; this closure only supplies native params and deadline fallback. */\n private compileBunNativeHandler;\n /** Compile portable route registrations into Bun's native route table. Apps with request-rewrite\n * hooks or WebSockets retain the single portable dispatcher because those features must run before\n * route selection/upgrade. Named wildcards also stay on the fallback until Bun exposes their raw\n * capture semantics; static and `:param` routes take the native lane. */\n private buildBunNativeRoutes;\n /**\n * Start a `Bun.serve` instance bound to `port` (use `0` for an ephemeral port).\n *\n * `reusePort` sets `SO_REUSEPORT` so **multiple processes can bind the same port** and the kernel\n * load-balances connections across them — the standard way to use every core (Bun is\n * single-threaded per process). Spawn one process per core, each calling\n * `app.listen(PORT, { reusePort: true })`; see `examples/cluster.ts`. Every process must opt in,\n * and all of them must be the same app. Linux balances ~evenly; macOS accepts the flag but may\n * favor one socket (fine for dev, measure on Linux for production numbers).\n *\n * `hostname` is the bind address, defaulting to Bun's `0.0.0.0` (every interface). Pass\n * `\"127.0.0.1\"` to bind loopback only - an admin surface, a sidecar, or anything that must not be\n * reachable off the box. Omitting it when you meant to restrict is a real exposure, so it is a\n * first-class option rather than something a caller has to drop down to `Bun.serve` for.\n */\n listen(port: number, options?: {\n readonly reusePort?: boolean;\n readonly hostname?: string;\n }): RunningServer;\n /**\n * Gracefully stop: wait for in-flight requests to finish (up to `drainMs`), then\n * issue a single terminal stop — graceful if everything drained, forced if\n * stragglers remain. Safe to call when not listening.\n *\n * The Bun semantics: poll `pendingRequests` (awaiting\n * `stop()`'s promise drops in-flight requests), and decide graceful-vs-forced in\n * ONE call (Bun can't escalate an already-graceful `stop()` to a forced close).\n * New connections may be accepted during the drain window; in a real deploy the\n * load balancer has already stopped routing here, and `drainMs` bounds it.\n */\n stop({ drainMs }?: {\n drainMs?: number;\n }): Promise<void>;\n private installSignalHandlers;\n}",
8575
9457
  "doc": "/**\n * The inline server. Routes are chainable and fully type-inferred. `derive`/\n * `decorate` extend the handler context (`Ctx`) for routes defined *after* them,\n * with full types; `Ctx` is server-only and never touches the client registry.\n *\n * app.decorate(\"db\", db).derive((c) => ({ user: auth(c) }))\n * .get(\"/me\", (c) => c.user) // c.user + c.db are typed\n */"
8576
9458
  },
8577
9459
  {
@@ -8963,6 +9845,12 @@
8963
9845
  "signature": "export declare function splitSections(markdown: string): DocSection[];",
8964
9846
  "doc": "/** Split the generated doc into its `##` sections (the `# title` intro becomes \"Overview\"). */"
8965
9847
  },
9848
+ {
9849
+ "name": "SQLiteClient",
9850
+ "kind": "interface",
9851
+ "package": "@nifrajs/core",
9852
+ "signature": "export interface SQLiteClient {\n exec(sql: string): unknown;\n query(sql: string): SQLiteStatement;\n}"
9853
+ },
8966
9854
  {
8967
9855
  "name": "SqliteDatabaseLike",
8968
9856
  "kind": "interface",
@@ -8970,6 +9858,30 @@
8970
9858
  "signature": "export interface SqliteDatabaseLike {\n /** Prepare a statement; `all` runs it and returns row objects. */\n prepare(sql: string): {\n all(...params: unknown[]): unknown[];\n };\n /** Execute a statement for its side effect (used only for `PRAGMA query_only`). */\n run(sql: string): unknown;\n}",
8971
9859
  "doc": "/** The structural slice of `bun:sqlite`'s `Database` this package needs. */"
8972
9860
  },
9861
+ {
9862
+ "name": "SQLiteDurableExecutionAdapter",
9863
+ "kind": "class",
9864
+ "package": "@nifrajs/core",
9865
+ "signature": "export declare class SQLiteDurableExecutionAdapter implements DurableExecutionAdapter {\n readonly effects: DurableEffectStore;\n readonly approvals: ApprovalStore;\n readonly sagas: SagaStore;\n readonly leases: ReconciliationLeaseStore;\n readonly backend: SQLiteDurableRecordBackend;\n constructor(client: SQLiteClient, options?: {\n readonly tablePrefix?: string;\n });\n migrate(): void;\n}"
9866
+ },
9867
+ {
9868
+ "name": "SQLiteDurableRecordBackend",
9869
+ "kind": "class",
9870
+ "package": "@nifrajs/core",
9871
+ "signature": "export declare class SQLiteDurableRecordBackend implements DurableRecordBackend {\n private readonly client;\n readonly recordsTable: string;\n readonly leasesTable: string;\n constructor(client: SQLiteClient, options?: {\n readonly tablePrefix?: string;\n });\n migrate(): void;\n create(kind: DurableRecordKind, id: string, record: {\n readonly version: number;\n readonly state?: string;\n readonly updatedAt?: number;\n }): Promise<boolean>;\n get<T extends {\n readonly version: number;\n }>(kind: DurableRecordKind, id: string): Promise<T | undefined>;\n compareAndSet(kind: DurableRecordKind, id: string, expectedVersion: number, record: {\n readonly version: number;\n readonly state?: string;\n readonly updatedAt?: number;\n }): Promise<boolean>;\n scan<T extends {\n readonly state: string;\n readonly updatedAt: number;\n }>(kind: DurableRecordKind, input: ReconciliationScanOptions<string>): Promise<ReconciliationScanPage<T>>;\n acquireLease(input: Parameters<DurableRecordBackend[\"acquireLease\"]>[0]): Promise<ReconciliationLease | undefined>;\n renewLease(input: Parameters<DurableRecordBackend[\"renewLease\"]>[0]): Promise<boolean>;\n checkpointLease(input: Parameters<DurableRecordBackend[\"checkpointLease\"]>[0]): Promise<boolean>;\n releaseLease(input: Parameters<DurableRecordBackend[\"releaseLease\"]>[0]): Promise<boolean>;\n}"
9872
+ },
9873
+ {
9874
+ "name": "SQLiteRunResult",
9875
+ "kind": "interface",
9876
+ "package": "@nifrajs/core",
9877
+ "signature": "export interface SQLiteRunResult {\n readonly changes: number;\n}"
9878
+ },
9879
+ {
9880
+ "name": "SQLiteStatement",
9881
+ "kind": "interface",
9882
+ "package": "@nifrajs/core",
9883
+ "signature": "export interface SQLiteStatement {\n run(...values: readonly unknown[]): SQLiteRunResult;\n get(...values: readonly unknown[]): Record<string, unknown> | null | undefined;\n all(...values: readonly unknown[]): readonly (Record<string, unknown> | undefined)[];\n}"
9884
+ },
8973
9885
  {
8974
9886
  "name": "sse",
8975
9887
  "kind": "function",
@@ -9281,6 +10193,13 @@
9281
10193
  "signature": "export declare function string(opts?: Base<string> & Optional): StandardSchemaV1<string | undefined>;",
9282
10194
  "doc": "/** A required (or defaulted/optional) non-empty string. */"
9283
10195
  },
10196
+ {
10197
+ "name": "stringify",
10198
+ "kind": "function",
10199
+ "package": "@nifrajs/core",
10200
+ "signature": "export declare function stringify(value: unknown): string;",
10201
+ "doc": "/** `encode` + `JSON.stringify` in one call - the rich-type equivalent of `JSON.stringify`. */"
10202
+ },
9284
10203
  {
9285
10204
  "name": "stripComments",
9286
10205
  "kind": "function",
@@ -9689,6 +10608,55 @@
9689
10608
  "signature": "export interface TransitiveServerImportFinding extends ServerImportFinding {\n /** `[routeFile, ...as-written specifiers…, sink]` — the shortest path the walk found. Length 2 means\n * the route imports the sink directly (same as the regex scan's direct edge). */\n readonly chain: readonly string[];\n /** True when a precise transitive resolve wasn't possible for the first hop (a bare pkg / path alias),\n * so the chain is the honest direct edge rather than a fabricated deeper path. */\n readonly fallback: boolean;\n}",
9690
10609
  "doc": "/** One transitive server-only finding: the route module, the route's offending top-level import (the\n * first hop / `specifier`), the line + snippet of that import, and the FULL chain to the sink. */"
9691
10610
  },
10611
+ {
10612
+ "name": "TransportCodec",
10613
+ "kind": "interface",
10614
+ "package": "@nifrajs/core",
10615
+ "signature": "export interface TransportCodec {\n readonly id: string;\n readonly version: number;\n readonly mediaType: string;\n encode(value: unknown): string;\n decode(text: string): unknown;\n}"
10616
+ },
10617
+ {
10618
+ "name": "TransportCodecError",
10619
+ "kind": "class",
10620
+ "package": "@nifrajs/core",
10621
+ "signature": "export declare class TransportCodecError extends TypeError {\n constructor(message: string);\n}"
10622
+ },
10623
+ {
10624
+ "name": "TransportCodecRegistry",
10625
+ "kind": "interface",
10626
+ "package": "@nifrajs/core",
10627
+ "signature": "export interface TransportCodecRegistry {\n readonly fallback: TransportCodec;\n forContentType(contentType: string | null): TransportCodec;\n negotiate(accept: string | null): TransportCodec;\n byIdentity(id: string, version: number): TransportCodec;\n}"
10628
+ },
10629
+ {
10630
+ "name": "transportCodecs",
10631
+ "kind": "function",
10632
+ "package": "@nifrajs/core",
10633
+ "signature": "export declare function transportCodecs(registry: TransportCodecRegistry, options?: TransportCodecsOptions): IdentityPlugin;"
10634
+ },
10635
+ {
10636
+ "name": "TransportCodecsOptions",
10637
+ "kind": "interface",
10638
+ "package": "@nifrajs/core",
10639
+ "signature": "export interface TransportCodecsOptions {\n /** Maximum encoded request bytes. Keep aligned with `server({ maxBodyBytes })`. */\n readonly maxBytes?: number;\n}"
10640
+ },
10641
+ {
10642
+ "name": "TransportDecodeOptions",
10643
+ "kind": "interface",
10644
+ "package": "@nifrajs/core",
10645
+ "signature": "export interface TransportDecodeOptions {\n readonly maxBytes?: number;\n}",
10646
+ "doc": "/**\n * Versioned, bounded codecs shared by HTTP bodies, loader streams, and WebSocket frames. Plain JSON\n * remains the zero-configuration fast path; rich wire is explicit and preserves non-JSON values.\n */"
10647
+ },
10648
+ {
10649
+ "name": "TransportDecodeResult",
10650
+ "kind": "type",
10651
+ "package": "@nifrajs/core",
10652
+ "signature": "export type TransportDecodeResult = {\n readonly matched: false;\n} | {\n readonly matched: true;\n readonly value: unknown;\n} | {\n readonly matched: true;\n readonly response: Response;\n};"
10653
+ },
10654
+ {
10655
+ "name": "TransportRuntime",
10656
+ "kind": "interface",
10657
+ "package": "@nifrajs/core",
10658
+ "signature": "export interface TransportRuntime {\n responseCodec(accept: string | null): TransportCodec;\n decodeRequest(source: TransportBodySource, contentType: string, maxBytes: number): Promise<TransportDecodeResult>;\n}"
10659
+ },
9692
10660
  {
9693
10661
  "name": "Treaty",
9694
10662
  "kind": "type",
@@ -10315,7 +11283,7 @@
10315
11283
  "name": "VERSION",
10316
11284
  "kind": "const",
10317
11285
  "package": "@nifrajs/core",
10318
- "signature": "export declare const VERSION: \"2.0.0\";",
11286
+ "signature": "export declare const VERSION: \"2.1.0\";",
10319
11287
  "doc": "/**\n * Current package version. A hardcoded literal on purpose — core runs on the edge (no fs), so it can't\n * read its own package.json at runtime. `scripts/version.ts` rewrites it on every release bump and\n * `check:publish` asserts it equals `@nifrajs/core`'s package version.\n */"
10320
11288
  },
10321
11289
  {
@@ -10429,7 +11397,7 @@
10429
11397
  "name": "WebSocketHandler",
10430
11398
  "kind": "interface",
10431
11399
  "package": "@nifrajs/core",
10432
- "signature": "export interface WebSocketHandler<Data = unknown, Env = unknown, Schema extends StandardSchemaV1 | undefined = undefined, Send extends StandardSchemaV1 | undefined = undefined> {\n /**\n * Cross-site WebSocket hijacking (CSWSH) guard — checked BEFORE `upgrade()`. A browser does not\n * apply CORS to WebSocket handshakes and DOES send the page's cookies, so without an Origin check\n * any site can open an authenticated socket to your app. Set this to lock the route to known\n * origins: a string allow-list (exact `Origin` header match) or a predicate. A request whose\n * `Origin` doesn't match (or is absent, for the allow-list form) is rejected with `403` before any\n * per-connection work.\n *\n * **When omitted, the default is same-origin:** a cross-origin BROWSER handshake (an `Origin` header\n * whose host differs from the request's) is rejected with `403`. Non-browser clients (no `Origin`) and\n * same-origin browsers pass. Set this to allow specific cross-origin clients, or `() => true` for a\n * genuinely public socket. Non-browser clients can spoof `Origin`, so this is a browser-CSWSH defense,\n * not authentication — pair it with auth in `upgrade()`.\n */\n allowedOrigins?: ReadonlyArray<string> | ((origin: string | null) => boolean);\n /**\n * Runs in the HTTP request context **before** the upgrade (and after {@link allowedOrigins}) — the\n * place to authenticate or rate-limit. Return the initial per-connection `data` (→ `ws.data`), or a\n * `Response` to **reject** the upgrade (the client never connects). Omit to accept with\n * `data: undefined`. A thrown error rejects with a flat 500.\n */\n upgrade?(c: WebSocketContext<Env>): MaybePromise<Data | Response>;\n /**\n * Contract-first messages: a Standard Schema (`t`, zod, valibot, …) validating each **inbound** frame.\n * Text frames are parsed as JSON first. When set, `message` receives the validated, typed value; a\n * non-JSON or schema-invalid frame is routed to `onInvalidMessage` (or dropped if that's omitted).\n */\n messageSchema?: Schema;\n /**\n * The **outbound** frame contract (server → client), a Standard Schema. Purely type-level: it types\n * the frames the typed client's `.ws()` handle receives, and documents what this route pushes. The\n * server does NOT runtime-validate its own sends - the inbound `messageSchema` guards the trust\n * boundary; outbound honesty is the handler author's code, checked by tests.\n */\n sendSchema?: Send;\n open?(ws: NifraWebSocket<Data>): MaybePromise<void>;\n message?(ws: NifraWebSocket<Data>, data: WsMessageInput<Schema>): MaybePromise<void>;\n /** Inbound frame that failed JSON parse or `messageSchema` validation (only fires when a schema is\n * set). `raw` is the original frame; `issues` are the Standard Schema issues (one synthetic issue for\n * a JSON parse failure). Omit to silently drop invalid frames. */\n onInvalidMessage?(ws: NifraWebSocket<Data>, issues: ReadonlyArray<StandardIssue>, raw: WebSocketData): MaybePromise<void>;\n close?(ws: NifraWebSocket<Data>, code: number, reason: string): MaybePromise<void>;\n error?(ws: NifraWebSocket<Data>, error: unknown): MaybePromise<void>;\n}",
11400
+ "signature": "export interface WebSocketHandler<Data = unknown, Env = unknown, Schema extends StandardSchemaV1 | undefined = undefined, Send extends StandardSchemaV1 | undefined = undefined> {\n /**\n * Cross-site WebSocket hijacking (CSWSH) guard — checked BEFORE `upgrade()`. A browser does not\n * apply CORS to WebSocket handshakes and DOES send the page's cookies, so without an Origin check\n * any site can open an authenticated socket to your app. Set this to lock the route to known\n * origins: a string allow-list (exact `Origin` header match) or a predicate. A request whose\n * `Origin` doesn't match (or is absent, for the allow-list form) is rejected with `403` before any\n * per-connection work.\n *\n * **When omitted, the default is same-origin:** a cross-origin BROWSER handshake (an `Origin` header\n * whose host differs from the request's) is rejected with `403`. Non-browser clients (no `Origin`) and\n * same-origin browsers pass. Set this to allow specific cross-origin clients, or `() => true` for a\n * genuinely public socket. Non-browser clients can spoof `Origin`, so this is a browser-CSWSH defense,\n * not authentication — pair it with auth in `upgrade()`.\n */\n allowedOrigins?: ReadonlyArray<string> | ((origin: string | null) => boolean);\n /**\n * Runs in the HTTP request context **before** the upgrade (and after {@link allowedOrigins}) — the\n * place to authenticate or rate-limit. Return the initial per-connection `data` (→ `ws.data`), or a\n * `Response` to **reject** the upgrade (the client never connects). Omit to accept with\n * `data: undefined`. A thrown error rejects with a flat 500.\n */\n upgrade?(c: WebSocketContext<Env>): MaybePromise<Data | Response>;\n /**\n * Contract-first messages: a Standard Schema (`t`, zod, valibot, …) validating each **inbound** frame.\n * Text frames are parsed as JSON first. When set, `message` receives the validated, typed value; a\n * non-JSON or schema-invalid frame is routed to `onInvalidMessage` (or dropped if that's omitted).\n */\n messageSchema?: Schema;\n /**\n * The **outbound** frame contract (server → client), a Standard Schema. Purely type-level: it types\n * the frames the typed client's `.ws()` handle receives, and documents what this route pushes. The\n * server does NOT runtime-validate its own sends - the inbound `messageSchema` guards the trust\n * boundary; outbound honesty is the handler author's code, checked by tests.\n */\n sendSchema?: Send;\n /** Decode versioned transport frames before inbound schema validation. Omit for legacy JSON. */\n transport?: {\n readonly registry: TransportCodecRegistry;\n readonly maxBytes?: number;\n };\n open?(ws: NifraWebSocket<Data>): MaybePromise<void>;\n message?(ws: NifraWebSocket<Data>, data: WsMessageInput<Schema>): MaybePromise<void>;\n /** Inbound frame that failed JSON parse or `messageSchema` validation (only fires when a schema is\n * set). `raw` is the original frame; `issues` are the Standard Schema issues (one synthetic issue for\n * a JSON parse failure). Omit to silently drop invalid frames. */\n onInvalidMessage?(ws: NifraWebSocket<Data>, issues: ReadonlyArray<StandardIssue>, raw: WebSocketData): MaybePromise<void>;\n close?(ws: NifraWebSocket<Data>, code: number, reason: string): MaybePromise<void>;\n error?(ws: NifraWebSocket<Data>, error: unknown): MaybePromise<void>;\n}",
10433
11401
  "doc": "/** A WebSocket route's lifecycle. All callbacks optional; only `message` is needed for an echo. */"
10434
11402
  },
10435
11403
  {
@@ -10452,6 +11420,34 @@
10452
11420
  "signature": "export declare function widgetDocument(opts: DefineMcpWidgetOptions): string;",
10453
11421
  "doc": "/** Assemble the full self-contained widget document (bridge inlined in `<head>` so body scripts can use\n * `mcpApp` immediately). */"
10454
11422
  },
11423
+ {
11424
+ "name": "Wire",
11425
+ "kind": "interface",
11426
+ "package": "@nifrajs/core",
11427
+ "signature": "export interface Wire {\n /** The root value: an inline primitive/scalar, or a `{ [TAG]: \"ref\", i }` into {@link Wire.n}. */\n readonly r: unknown;\n /** Interned container and rich-type nodes, addressed by index from `ref`s. */\n readonly n: readonly unknown[];\n}",
11428
+ "doc": "/** The JSON-safe encoded form produced by {@link encode} and consumed by {@link decode}. */"
11429
+ },
11430
+ {
11431
+ "name": "WireDecodeError",
11432
+ "kind": "class",
11433
+ "package": "@nifrajs/core",
11434
+ "signature": "export declare class WireDecodeError extends TypeError {\n constructor(message: string);\n}",
11435
+ "doc": "/** Thrown by {@link decode} for a wire value carrying an unknown tag, a bad index, or malformed shape. */"
11436
+ },
11437
+ {
11438
+ "name": "WireDecodeLimits",
11439
+ "kind": "interface",
11440
+ "package": "@nifrajs/core",
11441
+ "signature": "export interface WireDecodeLimits {\n /** Maximum number of interned nodes. Default 10,000. */\n readonly maxNodes?: number;\n /** Maximum nesting depth across containers and references. Default 256. */\n readonly maxDepth?: number;\n /** Maximum total object/array/map/set entries visited. Default 100,000. */\n readonly maxCollectionEntries?: number;\n /** Maximum UTF-8 string plus decoded binary bytes materialized. Default 16 MiB. */\n readonly maxDecodedBytes?: number;\n}",
11442
+ "doc": "/** Resource limits applied while reconstructing transport-controlled wire data. */"
11443
+ },
11444
+ {
11445
+ "name": "WireEncodeError",
11446
+ "kind": "class",
11447
+ "package": "@nifrajs/core",
11448
+ "signature": "export declare class WireEncodeError extends TypeError {\n constructor(message: string);\n}",
11449
+ "doc": "/** Thrown by {@link encode} for a value it will not encode (a function or a symbol). */"
11450
+ },
10455
11451
  {
10456
11452
  "name": "withDeadlineHeader",
10457
11453
  "kind": "function",