@nifrajs/cli 1.1.0 → 1.2.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/dist/cli.js CHANGED
@@ -68,7 +68,7 @@ routes/ from the current directory. Run from your project root.
68
68
  Port: \`dev\` and \`start\` share the default ${DEFAULT_DEV_PORT}. Override with \`--port <n>\` (alias \`-p\`) or the
69
69
  \`PORT\` env var (\`--port\` wins over \`PORT\`, which wins over the default).`;
70
70
  // Kept in lockstep with packages/cli/package.json by check:publish's version-consistency gate.
71
- const CLI_VERSION = "1.1.0";
71
+ const CLI_VERSION = "1.2.0";
72
72
  // A render adapter + nifra server are opaque to the CLI (it just forwards them); cast at the seam.
73
73
  const asAdapter = (v) => v;
74
74
  const asBunPlugins = (v) => v;
package/dist/mcp-http.js CHANGED
@@ -19,7 +19,7 @@ import { loadTypesCorpus } from "./types-search.js";
19
19
  // tool factory + the transport core from one entry: `import { respondMcpHttp, docsTools } from "@nifrajs/cli/mcp"`.
20
20
  export { docsTools } from "./mcp-docs-tools.js";
21
21
  // Kept in lockstep with packages/cli/package.json by check:publish's version-consistency gate.
22
- const VERSION = "1.1.0";
22
+ const VERSION = "1.2.0";
23
23
  const SERVER_INFO = { name: "nifra-docs", version: VERSION };
24
24
  const DOCS_HEALTH = "nifra docs MCP — POST JSON-RPC 2.0 here (methods: initialize, tools/list, tools/call). Tools: nifra_docs, nifra_example.";
25
25
  /** The two project-independent tools, reading the package's bundled corpus from disk (CLI use). */
@@ -8,7 +8,7 @@ nifra is a Bun-native, contract-first, framework-agnostic full-stack TypeScript
8
8
 
9
9
  - **ESM-only.** Bun is the first-class runtime (`app.listen(port)` → `Bun.serve`); every other runtime uses `app.fetch`. No CommonJS.
10
10
  - **The client never throws.** Every `@nifrajs/client` call returns `{ ok, status, data, error }` — branch on it, don't try/catch.
11
- - **Validate at the boundary.** Per-route `body`/`query`/`params`/`headers`/`response` is any Standard Schema (zod/valibot/arktype) or `@nifrajs/schema`'s `t`; invalid input → structured `400` before the handler runs.
11
+ - **Validate at the boundary.** Per-route `body`/`query`/`params`/`headers`/`response` is any Standard Schema (zod/valibot/arktype) or `@nifrajs/schema`'s `t`; invalid input → structured `422` before the handler runs.
12
12
  - **Secure by default.** Body-size cap, `requestTimeoutMs` + `c.signal`, graceful shutdown, redacting logger, same-origin `redirect()`, constant-time secret comparison, fail-closed middleware.
13
13
  - **Money** in integer minor units; **time** parsed to absolute UTC at the boundary.
14
14
  - Throwing a `Response` anywhere in the lifecycle is control flow (returned as-is), not an error.
@@ -4666,7 +4666,7 @@ export type App = typeof app // hand this to @nifrajs/client for end-to-end type
4666
4666
  surface — handlers lift over unchanged.
4667
4667
  - **Validation at the boundary.** Per-route `body`/`query` is any
4668
4668
  [Standard Schema](https://standardschema.dev) (zod/valibot/arktype, or `@nifrajs/schema`'s
4669
- `t`); invalid input is rejected with a structured `400` before the handler runs.
4669
+ `t`); invalid input is rejected with a structured `422` before the handler runs.
4670
4670
  - **Lifecycle middleware.** `derive`/`decorate` extend the typed context;
4671
4671
  `onRequest`/`beforeHandle`/`afterHandle`/`onResponse`/`onError` run around handlers;
4672
4672
  `use(middleware)` applies a bundle.
package/docs/types.json CHANGED
@@ -148,13 +148,6 @@
148
148
  "signature": "export interface AppLike {\n fetch(request: Request): Response | Promise<Response>;\n}",
149
149
  "doc": "/** Anything with a Web-standard fetch handler — a nifra app, or any `(Request) => Response`. Declared\n * structurally so this package has zero dependency on `@nifrajs/core`. */"
150
150
  },
151
- {
152
- "name": "AppLike",
153
- "kind": "interface",
154
- "package": "@nifrajs/testing",
155
- "signature": "export interface AppLike {\n fetch(request: Request): Response | Promise<Response>;\n}",
156
- "doc": "/** The minimal shape a nifra `server()` app satisfies — its own `fetch`. */"
157
- },
158
151
  {
159
152
  "name": "applyDoctorAutoFix",
160
153
  "kind": "function",
@@ -183,13 +176,6 @@
183
176
  "signature": "export declare function assertAuthableDb(db: DbChoice): void;",
184
177
  "doc": "/**\n * Guard `--auth` against a DB whose ORM has no clean better-auth adapter. Throws an actionable error\n * for Kysely (passing a raw dialect to better-auth is manual wiring we won't fake-scaffold). Called by\n * the CLI before scaffolding so the failure is early and explains the fix.\n */"
185
178
  },
186
- {
187
- "name": "assertSafeKey",
188
- "kind": "function",
189
- "package": "@nifrajs/storage",
190
- "signature": "export declare function assertSafeKey(key: string): void;",
191
- "doc": "/** Throw {@link StorageKeyError} unless `key` is a safe relative storage key. */"
192
- },
193
179
  {
194
180
  "name": "attachWebSocket",
195
181
  "kind": "function",
@@ -294,13 +280,6 @@
294
280
  "signature": "export declare function backendRoutes(backend: unknown): RouteDesc[];",
295
281
  "doc": "/** Read the backend's registered routes, if it's a `server()` with a `.routes()` method. */"
296
282
  },
297
- {
298
- "name": "Backoff",
299
- "kind": "type",
300
- "package": "@nifrajs/jobs",
301
- "signature": "export type Backoff = (attempt: number) => number;",
302
- "doc": "/** ms to wait before the next attempt, given the number of attempts already made (1-based). */"
303
- },
304
283
  {
305
284
  "name": "base64UrlDecode",
306
285
  "kind": "function",
@@ -554,12 +533,6 @@
554
533
  "signature": "export declare function cache(options: CacheOptions): Middleware;",
555
534
  "doc": "/**\n * Full response cache for small, cacheable responses. Use a shared `store` in production. The\n * middleware honors `Cache-Control` by default, avoids `Set-Cookie`, caps stored bytes, emits `Age`,\n * and keeps `Vary` headers aligned with the cache key.\n */"
556
535
  },
557
- {
558
- "name": "Cache",
559
- "kind": "interface",
560
- "package": "@nifrajs/cache",
561
- "signature": "export interface Cache {\n /** The cached value for `key`, or `undefined` if missing/expired. Pass `T` for the value type. */\n get<T = unknown>(key: string): Promise<T | undefined>;\n /** Whether a live (non-expired) entry exists. */\n has(key: string): Promise<boolean>;\n /** Store `value` under `key`. */\n set<T>(key: string, value: T, options?: SetOptions): Promise<void>;\n delete(key: string): Promise<void>;\n /** Drop every entry tagged `tag`. */\n invalidateTag(tag: string): Promise<void>;\n clear(): Promise<void>;\n /**\n * Cache-aside: return the cached value, or run `loader`, store the result, and return it. Stampede-safe\n * (concurrent misses for one key share a single `loader` call) and SWR-aware (a stale-but-live value is\n * returned immediately while a deduped background refresh runs). A throwing `loader` is NOT cached.\n */\n wrap<T>(key: string, loader: () => T, options?: WrapOptions): Promise<Awaited<T>>;\n}"
562
- },
563
536
  {
564
537
  "name": "cacheControl",
565
538
  "kind": "function",
@@ -592,25 +565,12 @@
592
565
  "signature": "export interface CachedResponse {\n /** The rendered document (UTF-8 HTML, fully buffered). */\n readonly body: string;\n readonly status: number;\n /** Response headers to replay (e.g. `content-type`). */\n readonly headers: Readonly<Record<string, string>>;\n /** When this entry was stored, via the injected clock (ms epoch). */\n readonly storedAt: number;\n /** Freshness window (ms): `now - storedAt >= revalidate` ⇒ stale (serve it, regenerate behind it). */\n readonly revalidate: number;\n}",
593
566
  "doc": "/** A cached SSR response — the bytes + metadata a {@link CacheStore} persists. */"
594
567
  },
595
- {
596
- "name": "CacheOptions",
597
- "kind": "interface",
598
- "package": "@nifrajs/cache",
599
- "signature": "export interface CacheOptions {\n /** Storage adapter. Default: a fresh {@link MemoryCache}. */\n readonly store?: CacheStore;\n /** Default TTL (ms) for `set`/`wrap` when none is given. Default 60_000. */\n readonly defaultTtlMs?: number;\n /** Injectable clock (tests). Default `() => Date.now()`. */\n readonly now?: () => number;\n /** Called when a background SWR revalidation throws. Default: `console.error`. */\n readonly onError?: (error: unknown, key: string) => void;\n}"
600
- },
601
568
  {
602
569
  "name": "CacheOptions",
603
570
  "kind": "interface",
604
571
  "package": "@nifrajs/middleware",
605
572
  "signature": "export interface CacheOptions {\n readonly store: ResponseCacheStore;\n /** Time to live in milliseconds. */\n readonly ttlMs: number;\n /** Methods cached. Default `[\"GET\", \"HEAD\"]`. */\n readonly methods?: readonly string[];\n /** Status predicate. Default: `200` only. */\n readonly status?: (status: number) => boolean;\n /** Header names included in the cache key and emitted in `Vary`. */\n readonly vary?: readonly string[];\n /** Custom cache key. Receives the normalized `vary` headers through the request itself. */\n readonly key?: (request: Request) => string;\n /** Maximum response bytes to store. Default `1_000_000`. Larger responses pass through. */\n readonly maxBytes?: number;\n /** Respect request `Cache-Control: no-cache/no-store`. Default `true`. */\n readonly respectRequestCacheControl?: boolean;\n /** Respect response `Cache-Control: private/no-store`. Default `true`. */\n readonly respectResponseCacheControl?: boolean;\n /** Cache responses with `Set-Cookie`. Default `false`. */\n readonly cacheSetCookie?: boolean;\n /** Cache responses to requests bearing `Authorization` or `Cookie` even when the response is not\n * explicitly `Cache-Control: public` (or `s-maxage`). Default `false`: a shared cache must not store a\n * personalized response (RFC 9111 §3.5), or it would be replayed to other users. Leave this off unless\n * the cached route is genuinely the same for every caller. */\n readonly cacheAuthenticated?: boolean;\n /** Response header for cache status. Default `\"x-nifra-cache\"`; set `false` to disable. */\n readonly cacheStatusHeader?: string | false;\n}"
606
573
  },
607
- {
608
- "name": "CacheStore",
609
- "kind": "interface",
610
- "package": "@nifrajs/cache",
611
- "signature": "export interface CacheStore {\n /** The live entry for `key`, or `undefined` if missing or hard-expired (`now >= expiresAt`). */\n get(key: string): StoredEntry | undefined | Promise<StoredEntry | undefined>;\n /** Store `entry` under `key`, indexed by `tags` for {@link CacheStore.invalidateTag}. */\n set(key: string, entry: StoredEntry, tags: readonly string[]): void | Promise<void>;\n delete(key: string): void | Promise<void>;\n /** Drop every entry carrying `tag`. */\n invalidateTag(tag: string): void | Promise<void>;\n clear(): void | Promise<void>;\n}",
612
- "doc": "/**\n * Raw key→entry storage. The default {@link MemoryCache} is in-process; implement this over CF KV /\n * Redis / etc. for a cache shared across instances. All methods may be sync or async — the cache awaits them.\n */"
613
- },
614
574
  {
615
575
  "name": "CacheStore",
616
576
  "kind": "interface",
@@ -949,20 +909,6 @@
949
909
  "signature": "export type ContractShape = Record<string, OperationDef>;",
950
910
  "doc": "/** A contract: named operations. Names are the handler keys and OpenAPI operationIds. */"
951
911
  },
952
- {
953
- "name": "cookieJar",
954
- "kind": "function",
955
- "package": "@nifrajs/testing",
956
- "signature": "export declare function cookieJar(): CookieJar;",
957
- "doc": "/** Create an empty cookie jar. */"
958
- },
959
- {
960
- "name": "CookieJar",
961
- "kind": "interface",
962
- "package": "@nifrajs/testing",
963
- "signature": "export interface CookieJar {\n /** The current `Cookie` request-header value (`\"a=1; b=2\"`, or `\"\"` when empty). */\n header(): string;\n /** Set the `Cookie` header on `headers` when the jar is non-empty. */\n applyTo(headers: Headers): void;\n /** Absorb every `Set-Cookie` on a response (setting or, on removal, deleting each). */\n store(response: {\n headers: Headers;\n }): void;\n set(name: string, value: string): void;\n get(name: string): string | undefined;\n clear(): void;\n readonly size: number;\n}",
964
- "doc": "/**\n * A tiny cookie jar for in-process tests — parses `Set-Cookie` off responses and emits a `Cookie`\n * request header, so a login → authenticated-request flow works without threading headers by hand. It\n * honours removal (`Max-Age=0` / a past `Expires`) so logout clears the cookie; other attributes\n * (Domain/Path/Secure/SameSite) are ignored — everything is same-origin in-process.\n */"
965
- },
966
912
  {
967
913
  "name": "CookieOptions",
968
914
  "kind": "interface",
@@ -996,13 +942,6 @@
996
942
  "signature": "export declare function createBunWsHandlers(topics: TopicRegistry): BunWsHandlers;",
997
943
  "doc": "/** The shared Bun `websocket` dispatcher config for one app — each connection's\n * `ws.data.handler` is the matched route's handler, set by `server.upgrade`. */"
998
944
  },
999
- {
1000
- "name": "createCache",
1001
- "kind": "function",
1002
- "package": "@nifrajs/cache",
1003
- "signature": "export declare function createCache(options?: CacheOptions): Cache;",
1004
- "doc": "/** Create a cache over the given (or a fresh in-memory) store. */"
1005
- },
1006
945
  {
1007
946
  "name": "createCachedAppLoader",
1008
947
  "kind": "function",
@@ -1096,13 +1035,6 @@
1096
1035
  "signature": "export interface CreateQueryResult<T> {\n /** Reactive accessor for the {@link QueryState} (`status`/`data`/`error`/`isFetching`/`updatedAt`). */\n readonly state: Accessor<QueryState<T>>;\n /** Force a refetch (ignores `staleTime`). */\n readonly refetch: () => Promise<T>;\n}",
1097
1036
  "doc": "/** A query's reactive state accessor plus `refetch`. */"
1098
1037
  },
1099
- {
1100
- "name": "createQueue",
1101
- "kind": "function",
1102
- "package": "@nifrajs/jobs",
1103
- "signature": "export declare function createQueue(options?: QueueOptions): Queue;",
1104
- "doc": "/** Create a job queue. Define jobs, enqueue payloads, and `start()` a worker (or `drain()` once). */"
1105
- },
1106
1038
  {
1107
1039
  "name": "createScheduler",
1108
1040
  "kind": "function",
@@ -1261,13 +1193,6 @@
1261
1193
  "package": "@nifrajs/middleware",
1262
1194
  "signature": "export declare function decodeBase64(input: string): Uint8Array<ArrayBuffer> | null;"
1263
1195
  },
1264
- {
1265
- "name": "decodeCursor",
1266
- "kind": "function",
1267
- "package": "@nifrajs/schema",
1268
- "signature": "export declare function decodeCursor<T = unknown>(cursor: string | null | undefined): T | undefined;",
1269
- "doc": "/** Decode a cursor back to its value. Returns `undefined` for a null/empty/malformed cursor — treat that\n * as \"start from the beginning\" rather than erroring on a client-supplied string. */"
1270
- },
1271
1196
  {
1272
1197
  "name": "DecodedImage",
1273
1198
  "kind": "interface",
@@ -1577,19 +1502,6 @@
1577
1502
  "package": "@nifrajs/web",
1578
1503
  "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}"
1579
1504
  },
1580
- {
1581
- "name": "encodeCursor",
1582
- "kind": "function",
1583
- "package": "@nifrajs/schema",
1584
- "signature": "export declare function encodeCursor(value: unknown): string;",
1585
- "doc": "/** Encode any JSON-serializable value (e.g. the last row's sort key) into an opaque cursor string. */"
1586
- },
1587
- {
1588
- "name": "EnqueueOptions",
1589
- "kind": "interface",
1590
- "package": "@nifrajs/jobs",
1591
- "signature": "export interface EnqueueOptions {\n /** Delay before the job becomes eligible. Ignored if `runAt` is set. */\n readonly delayMs?: number;\n /** Absolute epoch-ms eligibility time. Overrides `delayMs`. */\n readonly runAt?: number;\n}"
1592
- },
1593
1505
  {
1594
1506
  "name": "ensureDefaultFormats",
1595
1507
  "kind": "function",
@@ -1715,19 +1627,6 @@
1715
1627
  "signature": "export interface ExecutionContext {\n waitUntil(promise: Promise<unknown>): void;\n}",
1716
1628
  "doc": "/** A Cloudflare Workers-style execution context (the `fetch` 3rd arg). Structural — only\n * `waitUntil` is used; declared here so `@nifrajs/core` needs no Workers type dependency. */"
1717
1629
  },
1718
- {
1719
- "name": "exponentialBackoff",
1720
- "kind": "function",
1721
- "package": "@nifrajs/jobs",
1722
- "signature": "export declare function exponentialBackoff(options?: ExponentialOptions): Backoff;",
1723
- "doc": "/** Exponential backoff: `baseMs * 2^(attempt-1)`, capped at `maxMs`, with optional jitter. */"
1724
- },
1725
- {
1726
- "name": "ExponentialOptions",
1727
- "kind": "interface",
1728
- "package": "@nifrajs/jobs",
1729
- "signature": "export interface ExponentialOptions {\n /** Delay before the FIRST retry (attempt 1). Default 1000. */\n readonly baseMs?: number;\n /** Upper bound on the delay. Default 30_000. */\n readonly maxMs?: number;\n /** Full-jitter fraction in [0,1]: the delay is scaled by `1 - jitter*rand`. Default 0 (deterministic). */\n readonly jitter?: number;\n /** Injectable randomness for jitter (tests). Default `Math.random`. */\n readonly random?: () => number;\n}"
1730
- },
1731
1630
  {
1732
1631
  "name": "FEATURE_IDS",
1733
1632
  "kind": "const",
@@ -1825,20 +1724,6 @@
1825
1724
  "signature": "export type FetchRouteData = (path: string, match: RouteMatch, signal?: AbortSignal) => Promise<unknown>;",
1826
1725
  "doc": "/** How a router fetches a route's loader data on navigation. `signal` aborts a superseded fetch\n * (and its deferred stream). */"
1827
1726
  },
1828
- {
1829
- "name": "FieldKey",
1830
- "kind": "type",
1831
- "package": "@nifrajs/web",
1832
- "signature": "export type FieldKey<App, Path extends string, Method extends string> = [\n RouteBody<App, Path, Method>\n] extends [never] ? never : keyof RouteBody<App, Path, Method> & string;",
1833
- "doc": "/** The valid field names for that route's body — the schema's keys as a string union. */"
1834
- },
1835
- {
1836
- "name": "FieldProps",
1837
- "kind": "type",
1838
- "package": "@nifrajs/web",
1839
- "signature": "export type FieldProps = Record<string, unknown>;",
1840
- "doc": "/** Extra attributes merged into the returned input props (id, type, defaultValue, placeholder, …). */"
1841
- },
1842
1727
  {
1843
1728
  "name": "filePathToPattern",
1844
1729
  "kind": "function",
@@ -1853,12 +1738,6 @@
1853
1738
  "signature": "export declare function filePathToPatterns(file: string): string[];",
1854
1739
  "doc": "/**\n * Derive **every** nifra router pattern a route file maps to (relative to the routes dir):\n * `index` → the parent path, `[id]` → `:id`, `[...slug]` → `*slug` (catch-all, captures the rest of\n * the path into one param), `(group)` folders are dropped from the URL (organization only), and an\n * optional `[[lang]]` expands the set — once with the segment present (`:lang`) and once absent. A file\n * with no optionals yields exactly one pattern. Throws on an invalid param or a catch-all that isn't\n * the last segment.\n */"
1855
1740
  },
1856
- {
1857
- "name": "FileStorage",
1858
- "kind": "class",
1859
- "package": "@nifrajs/storage",
1860
- "signature": "export declare class FileStorage implements StorageAdapter {\n private readonly root;\n constructor(root: string);\n /** Resolve `key` to an absolute path, asserting it stays inside `root` (defense-in-depth on top of `assertSafeKey`). */\n private pathFor;\n put(key: string, data: StorageData, _options?: PutOptions): Promise<void>;\n get(key: string): Promise<StorageObject | null>;\n delete(key: string): Promise<void>;\n exists(key: string): Promise<boolean>;\n list(options?: ListOptions): Promise<string[]>;\n private walk;\n}"
1861
- },
1862
1741
  {
1863
1742
  "name": "FileType",
1864
1743
  "kind": "interface",
@@ -1873,13 +1752,6 @@
1873
1752
  "signature": "export declare function fillRoutePattern(pattern: string, params: Record<string, string>): {\n path: string;\n missing: string[];\n};",
1874
1753
  "doc": "/**\n * Substitute a route pattern's `:param` segments with concrete values: `/users/:id` + `{id:\"7\"}` →\n * `/users/7`. Returns the filled path plus any params that had no value (a `getStaticPaths` bug) so\n * the caller can skip rather than emit a path with a literal `:name`. Shared by the SSG driver and\n * {@link enumeratePrerenderedPaths}.\n */"
1875
1754
  },
1876
- {
1877
- "name": "fixedBackoff",
1878
- "kind": "const",
1879
- "package": "@nifrajs/jobs",
1880
- "signature": "export declare const fixedBackoff: (ms: number) => Backoff;",
1881
- "doc": "/** Fixed delay before every retry. */"
1882
- },
1883
1755
  {
1884
1756
  "name": "Flags",
1885
1757
  "kind": "interface",
@@ -1959,19 +1831,6 @@
1959
1831
  "signature": "export declare function formatTraceparent(traceId: string, spanId: string, sampled: boolean): string;",
1960
1832
  "doc": "/** Format a `traceparent` header value (version `00`). */"
1961
1833
  },
1962
- {
1963
- "name": "formFor",
1964
- "kind": "function",
1965
- "package": "@nifrajs/web",
1966
- "signature": "export declare function formFor<App, Path extends RoutePaths<App>, Method extends string = \"post\">(): FormHandle<App, Path, Method>;",
1967
- "doc": "/**\n * Bind a form to a backend route's body schema at the type level. `App` is `typeof backend`; `Path` is\n * constrained to the app's real routes (a wrong path is a type error); `Method` defaults to `\"post\"`.\n */"
1968
- },
1969
- {
1970
- "name": "FormHandle",
1971
- "kind": "interface",
1972
- "package": "@nifrajs/web",
1973
- "signature": "export interface FormHandle<App, Path extends string, Method extends string> {\n /** Input props for a schema field. `name` is constrained to the body's keys — a typo, or a field the\n * schema doesn't have, is a COMPILE error. Spread onto an element: `<input {...f.field(\"text\")} />`. */\n field<K extends FieldKey<App, Path, Method>>(name: K, props?: FieldProps): FieldProps & {\n name: K;\n };\n /** `formData.get`, key-constrained to the body's fields — reading an orphan key won't compile. */\n read<K extends FieldKey<App, Path, Method>>(form: FormData, name: K): FormEntry;\n /** `formData.getAll`, key-checked the same way. */\n readAll<K extends FieldKey<App, Path, Method>>(form: FormData, name: K): FormEntries;\n}"
1974
- },
1975
1834
  {
1976
1835
  "name": "Framework",
1977
1836
  "kind": "type",
@@ -2016,8 +1875,8 @@
2016
1875
  "name": "fromTypeBox",
2017
1876
  "kind": "function",
2018
1877
  "package": "@nifrajs/schema",
2019
- "signature": "export declare function fromTypeBox<T extends TSchema>(schema: T, options?: {\n readonly coerce?: boolean;\n}): NifraSchema<T>;",
2020
- "doc": "/**\n * Wrap a TypeBox schema as a `NifraSchema`.\n *\n * **Validation is fast where it can be, and works everywhere.** The first `validate`\n * builds a compiled `TypeCompiler` validator (codegen via `new Function`) and memoizes\n * it — composing schemas (`t.object({ a: t.string() })`) never compiles the inner\n * pieces; only a schema actually used to validate a request pays the one-time codegen\n * cost. On Bun and Node this is the only path and it is untouched.\n *\n * Edge runtimes (Cloudflare Workers, Vercel Edge, Deno Deploy) **forbid dynamic code\n * generation**, so that first compile throws there. We catch it once per schema and\n * fall back to TypeBox's eval-free `Value` checker — same semantics (and same global\n * `FormatRegistry`, so `t.string({ format })` behaves identically), no `new Function`.\n * The branch is decided once and memoized, so the hot path is a single check either way.\n *\n * Exposed (not just used internally by `t`) so a TypeBox schema authored directly can\n * be adapted without leaving the Standard Schema world.\n *\n * `options.coerce` runs TypeBox's `Value.Convert` (string→number/integer/boolean, per the schema)\n * BEFORE validating. Query values always arrive as strings (`?limit=20` → `\"20\"`), so a query schema\n * with a numeric field can't validate without this — it's how `t.pageQuery` yields a real `number`.\n * Leave it OFF (the default) for body/JSON schemas: a JSON number is already a number, and coercing\n * would silently accept `\"20\"` where the contract said `20`.\n */"
1878
+ "signature": "export declare function fromTypeBox<T extends TSchema>(schema: T): NifraSchema<T>;",
1879
+ "doc": "/**\n * Wrap a TypeBox schema as a `NifraSchema`.\n *\n * **Validation is fast where it can be, and works everywhere.** The first `validate`\n * builds a compiled `TypeCompiler` validator (codegen via `new Function`) and memoizes\n * it — composing schemas (`t.object({ a: t.string() })`) never compiles the inner\n * pieces; only a schema actually used to validate a request pays the one-time codegen\n * cost. On Bun and Node this is the only path and it is untouched.\n *\n * Edge runtimes (Cloudflare Workers, Vercel Edge, Deno Deploy) **forbid dynamic code\n * generation**, so that first compile throws there. We catch it once per schema and\n * fall back to TypeBox's eval-free `Value` checker — same semantics (and same global\n * `FormatRegistry`, so `t.string({ format })` behaves identically), no `new Function`.\n * The branch is decided once and memoized, so the hot path is a single check either way.\n *\n * Exposed (not just used internally by `t`) so a TypeBox schema authored directly can\n * be adapted without leaving the Standard Schema world.\n */"
2021
1880
  },
2022
1881
  {
2023
1882
  "name": "generateClientEntry",
@@ -2722,61 +2581,6 @@
2722
2581
  "signature": "export declare const issue: (message: string) => {\n readonly issues: ReadonlyArray<StandardIssue>;\n};",
2723
2582
  "doc": "/** A single issue. Messages NEVER include the variable's value — it may be a secret. */"
2724
2583
  },
2725
- {
2726
- "name": "JobContext",
2727
- "kind": "interface",
2728
- "package": "@nifrajs/jobs",
2729
- "signature": "export interface JobContext {\n readonly id: string;\n readonly name: string;\n /** 1 on the first run, 2 on the first retry, … */\n readonly attempt: number;\n}",
2730
- "doc": "/** What a handler receives alongside the payload: identity + which attempt this is (1-based). */"
2731
- },
2732
- {
2733
- "name": "JobCounts",
2734
- "kind": "interface",
2735
- "package": "@nifrajs/jobs",
2736
- "signature": "export interface JobCounts {\n /** Eligible or waiting, not currently leased. */\n readonly pending: number;\n /** Leased and in flight. */\n readonly active: number;\n /** Dead-lettered (exhausted retries). */\n readonly dead: number;\n}"
2737
- },
2738
- {
2739
- "name": "JobDefinition",
2740
- "kind": "interface",
2741
- "package": "@nifrajs/jobs",
2742
- "signature": "export interface JobDefinition<Payload> {\n readonly handler: JobHandler<Payload>;\n /** Optional Standard Schema — validates the payload at `enqueue` (the trust boundary); a failure throws. */\n readonly input?: StandardSchemaV1<Payload>;\n /** `number` is shorthand for `{ attempts }`. */\n readonly retries?: number | RetryPolicy;\n}",
2743
- "doc": "/** A job definition registered on a queue. */"
2744
- },
2745
- {
2746
- "name": "JobError",
2747
- "kind": "class",
2748
- "package": "@nifrajs/jobs",
2749
- "signature": "export declare class JobError extends Error {\n readonly name = \"JobError\";\n}",
2750
- "doc": "/** Thrown for a misuse of the queue API (duplicate/unknown job name). */"
2751
- },
2752
- {
2753
- "name": "JobHandle",
2754
- "kind": "interface",
2755
- "package": "@nifrajs/jobs",
2756
- "signature": "export interface JobHandle<Payload> {\n readonly name: string;\n enqueue(payload: Payload, options?: EnqueueOptions): Promise<string>;\n}",
2757
- "doc": "/** A typed handle to enqueue a defined job. */"
2758
- },
2759
- {
2760
- "name": "JobHandler",
2761
- "kind": "type",
2762
- "package": "@nifrajs/jobs",
2763
- "signature": "export type JobHandler<Payload> = (payload: Payload, ctx: JobContext) => void | Promise<void>;",
2764
- "doc": "/** A job processor. A throw/rejection routes to `onError` and triggers retry/dead-letter — never crashes the worker. */"
2765
- },
2766
- {
2767
- "name": "JobStore",
2768
- "kind": "interface",
2769
- "package": "@nifrajs/jobs",
2770
- "signature": "export interface JobStore {\n /** Persist a new job; return its id. */\n enqueue(job: {\n name: string;\n payload: unknown;\n runAt: number;\n maxAttempts: number;\n }): string | Promise<string>;\n /** Atomically claim up to `limit` jobs due at/before `now`, hiding them for `leaseMs`. */\n lease(now: number, limit: number, leaseMs: number): StoredJob[] | Promise<StoredJob[]>;\n /** A job finished successfully — remove it. */\n complete(id: string): void | Promise<void>;\n /** A job failed but has attempts left — bump its attempt count and reschedule for `runAt`. */\n retry(id: string, runAt: number): void | Promise<void>;\n /** A job exhausted its attempts — move it to the dead-letter set with the last error. */\n deadLetter(id: string, error: string): void | Promise<void>;\n /** Snapshot counts (observability + tests). */\n counts(): JobCounts | Promise<JobCounts>;\n}",
2771
- "doc": "/**\n * Persistence + leasing for the queue. The default {@link MemoryJobStore} is single-process (dev / a\n * single long-running server); implement this over Redis/Postgres/etc. for durability or multiple\n * workers. All methods may be sync or async — the queue awaits them.\n */"
2772
- },
2773
- {
2774
- "name": "JobValidationError",
2775
- "kind": "class",
2776
- "package": "@nifrajs/jobs",
2777
- "signature": "export declare class JobValidationError extends Error {\n readonly job: string;\n readonly issues: ReadonlyArray<{\n readonly message: string;\n }>;\n readonly name = \"JobValidationError\";\n constructor(job: string, issues: ReadonlyArray<{\n readonly message: string;\n }>);\n}",
2778
- "doc": "/** Thrown by `enqueue` when the payload fails the job's `input` schema (validation at the trust boundary). */"
2779
- },
2780
2584
  {
2781
2585
  "name": "jsonError",
2782
2586
  "kind": "function",
@@ -2961,12 +2765,6 @@
2961
2765
  "signature": "export interface LinkDescriptor {\n readonly rel?: string;\n readonly href?: string;\n readonly hreflang?: string;\n readonly crossorigin?: string;\n readonly media?: string;\n readonly sizes?: string;\n readonly type?: string;\n readonly as?: string;\n readonly integrity?: string;\n readonly referrerpolicy?: string;\n readonly fetchpriority?: string;\n readonly title?: string;\n readonly imagesrcset?: string;\n readonly imagesizes?: string;\n readonly color?: string;\n readonly disabled?: boolean;\n readonly [attr: string]: string | boolean | undefined;\n}",
2962
2766
  "doc": "/**\n * One `<link>` tag's attributes for a route/layout's `meta.link`. The common HTML `<link>` attributes\n * are spelled out and **optional** so a typed partial like `{ rel, href, hreflang }` is assignable —\n * the previous `Record<string, string>` required *every* value to be a present string, which rejected\n * exactly that idiomatic shape (the bug this fixes). The index signature keeps custom/`data-*` attrs\n * (and any future standard attr) passing without a cast; `boolean` covers boolean attributes like\n * `disabled` (rendered as a bare attribute when `true`, omitted when `false`), and `undefined` lets a\n * caller spread in a conditionally-absent attribute. Attribute *names* are still shape-validated and\n * values HTML-escaped at render — a widened type never widens the injection surface.\n */"
2963
2767
  },
2964
- {
2965
- "name": "ListOptions",
2966
- "kind": "interface",
2967
- "package": "@nifrajs/storage",
2968
- "signature": "export interface ListOptions {\n /** Only keys starting with this prefix. */\n readonly prefix?: string;\n /** Cap the number of keys returned. */\n readonly limit?: number;\n}"
2969
- },
2970
2768
  {
2971
2769
  "name": "load",
2972
2770
  "kind": "function",
@@ -3165,8 +2963,8 @@
3165
2963
  "name": "MCP_CLI_VERSION",
3166
2964
  "kind": "const",
3167
2965
  "package": "create-nifra",
3168
- "signature": "export declare const MCP_CLI_VERSION: string;",
3169
- "doc": "/**\n * The `@nifrajs/cli` version the launch command pins to — DERIVED at load time from this package's own\n * `version`, never hardcoded. `fixed` changeset versioning ([[\"@nifrajs/*\", \"create-nifra\", \"nifra\"]] in\n * `.changeset/config.json`) bumps `create-nifra` and `@nifrajs/cli` in lockstep, so `create-nifra@x`\n * always means `@nifrajs/cli@x`. Deriving it here means a release bump has nothing to forget to update —\n * there is no stale literal to drift (the 1.0.0 cut shipped a beta pin exactly this way). `check:publish`\n * still asserts it equals `@nifrajs/cli`'s version as a belt-and-suspenders guard on the `fixed` link.\n *\n * Resolves correctly under BOTH export conditions: the `bun` export runs `src/agent-files.ts`\n * (`../package.json` → the package root) and the tsc `default` export runs `dist/agent-files.js`\n * (`../package.json` → the same root, since `dist/` sits beside the manifest). npm always ships a\n * package's own `package.json`, so the read can't miss at install time.\n *\n * Why pin at all instead of `bunx @nifrajs/cli mcp`: `bunx` keys its cache on the exact version spec.\n * An UNPINNED spec resolves to the `latest` tag once, then `bunx` reuses that cached copy on every\n * later spawn WITHOUT re-checking the registry — so an editor that once launched an older `@nifrajs/cli`\n * keeps respawning the stale binary even after a newer one is published (the MCP server silently runs\n * old code). Pinning the exact version makes the version part of the cache key, so each release fetches\n * fresh and a stale cache can never shadow it. The cost: an already-scaffolded app's `.mcp.json` freezes\n * at its scaffold-time version until `nifra init-agents` is re-run — an acceptable, deterministic trade.\n */"
2966
+ "signature": "export declare const MCP_CLI_VERSION: \"1.0.0\";",
2967
+ "doc": "/**\n * The `@nifrajs/cli` version the launch command pins to. Kept in lockstep with the published\n * `@nifrajs/cli` version by `scripts/version.ts` (alongside the cli.ts / mcp-http.ts constants).\n *\n * Why pin at all instead of `bunx @nifrajs/cli mcp`: `bunx` keys its cache on the exact version spec.\n * An UNPINNED spec resolves to the `latest` tag once, then `bunx` reuses that cached copy on every\n * later spawn WITHOUT re-checking the registry — so an editor that once launched an older `@nifrajs/cli`\n * keeps respawning the stale binary even after a newer one is published (the MCP server silently runs\n * old code). Pinning the exact version makes the version part of the cache key, so each release fetches\n * fresh and a stale cache can never shadow it. The cost: an already-scaffolded app's `.mcp.json` freezes\n * at its scaffold-time version until `nifra init-agents` is re-run — an acceptable, deterministic trade.\n */"
3170
2968
  },
3171
2969
  {
3172
2970
  "name": "MCP_CONFIG",
@@ -3186,7 +2984,7 @@
3186
2984
  "name": "MCP_SERVER_ARGS",
3187
2985
  "kind": "const",
3188
2986
  "package": "create-nifra",
3189
- "signature": "export declare const MCP_SERVER_ARGS: readonly [`@nifrajs/cli@${string}`, \"mcp\"];"
2987
+ "signature": "export declare const MCP_SERVER_ARGS: readonly [\"@nifrajs/cli@1.0.0\", \"mcp\"];"
3190
2988
  },
3191
2989
  {
3192
2990
  "name": "MCP_SERVER_COMMAND",
@@ -3319,18 +3117,6 @@
3319
3117
  "signature": "export interface McpWidget {\n readonly uri: string;\n readonly resource: McpResource;\n readonly meta: Record<string, unknown>;\n}",
3320
3118
  "doc": "/** A widget: the resource to register on the server, its `ui://` URI, and the `_meta` link for its tool. */"
3321
3119
  },
3322
- {
3323
- "name": "MemoryCache",
3324
- "kind": "class",
3325
- "package": "@nifrajs/cache",
3326
- "signature": "export declare class MemoryCache implements CacheStore {\n private readonly rows;\n private readonly tagIndex;\n private readonly maxEntries;\n private readonly now;\n constructor(options?: MemoryCacheOptions);\n get(key: string): StoredEntry | undefined;\n set(key: string, entry: StoredEntry, tags: readonly string[]): void;\n delete(key: string): void;\n invalidateTag(tag: string): void;\n clear(): void;\n /** Live entry count (for observability/tests). */\n size(): number;\n /** Remove a key and unlink it from every tag set it belonged to. */\n private evict;\n}"
3327
- },
3328
- {
3329
- "name": "MemoryCacheOptions",
3330
- "kind": "interface",
3331
- "package": "@nifrajs/cache",
3332
- "signature": "export interface MemoryCacheOptions {\n /** Evict the least-recently-used entry once the count exceeds this. `0` (default) = unbounded. */\n readonly maxEntries?: number;\n /** Injectable clock (tests). Default `() => Date.now()`. */\n readonly now?: () => number;\n}"
3333
- },
3334
3120
  {
3335
3121
  "name": "MemoryCacheStore",
3336
3122
  "kind": "class",
@@ -3357,13 +3143,6 @@
3357
3143
  "package": "@nifrajs/middleware",
3358
3144
  "signature": "export interface MemoryIdempotencyStoreOptions {\n /** Allow the in-memory store in production. Off by default — a per-instance store can't dedupe across instances. */\n readonly allowInProduction?: boolean;\n}"
3359
3145
  },
3360
- {
3361
- "name": "MemoryJobStore",
3362
- "kind": "class",
3363
- "package": "@nifrajs/jobs",
3364
- "signature": "export declare class MemoryJobStore implements JobStore {\n private readonly jobs;\n private readonly dead;\n private seq;\n private readonly idFor;\n constructor(options?: {\n idFor?: () => string;\n });\n enqueue(job: {\n name: string;\n payload: unknown;\n runAt: number;\n maxAttempts: number;\n }): string;\n lease(now: number, limit: number, leaseMs: number): StoredJob[];\n complete(id: string): void;\n retry(id: string, runAt: number): void;\n deadLetter(id: string, error: string): void;\n counts(now?: number): JobCounts;\n /** The dead-letter queue — inspect/requeue failed jobs (not part of the {@link JobStore} contract). */\n deadLetters(): DeadRecord[];\n}",
3365
- "doc": "/** Construct an in-memory job store. `idFor` is injectable for deterministic tests. */"
3366
- },
3367
3146
  {
3368
3147
  "name": "MemoryResponseCache",
3369
3148
  "kind": "class",
@@ -3389,12 +3168,6 @@
3389
3168
  "package": "@nifrajs/auth",
3390
3169
  "signature": "export interface MemorySessionStoreOptions {\n /** Allow the in-memory store in production. Off by default — per-instance sessions don't hold across\n * instances and are lost on restart. */\n readonly allowInProduction?: boolean;\n /** Hard cap on stored sessions; the oldest-inserted is evicted past it (default 10_000). */\n readonly max?: number;\n}"
3391
3170
  },
3392
- {
3393
- "name": "MemoryStorage",
3394
- "kind": "class",
3395
- "package": "@nifrajs/storage",
3396
- "signature": "export declare class MemoryStorage implements StorageAdapter {\n private readonly objects;\n put(key: string, data: StorageData, options?: PutOptions): Promise<void>;\n get(key: string): Promise<StorageObject | null>;\n delete(key: string): Promise<void>;\n exists(key: string): Promise<boolean>;\n list(options?: ListOptions): Promise<string[]>;\n}"
3397
- },
3398
3171
  {
3399
3172
  "name": "MemoryStore",
3400
3173
  "kind": "class",
@@ -3629,13 +3402,6 @@
3629
3402
  "signature": "export interface NifraWebSocket<Data = unknown> {\n /** Send a text (`string`) or binary (`ArrayBuffer`/typed-array) frame. No-op once closed. */\n send(data: string | ArrayBufferView | ArrayBuffer): void;\n /** Close the connection (optional code 1000–4999 + short reason). */\n close(code?: number, reason?: string): void;\n /** `WebSocket.readyState` (0 CONNECTING · 1 OPEN · 2 CLOSING · 3 CLOSED). */\n readonly readyState: number;\n /** Join a pub/sub topic — `app.publish(topic, data)` then reaches this connection. Idempotent. */\n subscribe(topic: string): void;\n /** Leave a pub/sub topic. Idempotent. (All topics are dropped automatically on close.) */\n unsubscribe(topic: string): void;\n /** Per-connection state — seeded by `upgrade()`, mutable for the connection's lifetime. */\n data: Data;\n /** Escape hatch to the runtime's native socket (Bun `ServerWebSocket`, Web `WebSocket`, `ws`). */\n readonly raw: unknown;\n}",
3630
3403
  "doc": "/** The portable socket handed to WS lifecycle callbacks. Each adapter wraps its native socket. */"
3631
3404
  },
3632
- {
3633
- "name": "noBackoff",
3634
- "kind": "const",
3635
- "package": "@nifrajs/jobs",
3636
- "signature": "export declare const noBackoff: Backoff;",
3637
- "doc": "/** No delay — retry immediately. */"
3638
- },
3639
3405
  {
3640
3406
  "name": "NodeBuiltinFinding",
3641
3407
  "kind": "interface",
@@ -3794,13 +3560,6 @@
3794
3560
  "signature": "export declare function packageOf(spec: string): string | undefined;",
3795
3561
  "doc": "/**\n * Resolve an import specifier to the npm package name it would install as, or `undefined` when it isn't\n * an npm dependency at all (a relative/absolute path, a runtime builtin, or a malformed scope like the\n * `@/…` path-alias convention). `@scope/name/sub` → `@scope/name`; `name/sub` → `name`.\n */"
3796
3562
  },
3797
- {
3798
- "name": "Page",
3799
- "kind": "interface",
3800
- "package": "@nifrajs/schema",
3801
- "signature": "export interface Page<Item> {\n readonly items: Item[];\n readonly nextCursor: string | null;\n}",
3802
- "doc": "/** A cursor-pagination page — matches the shape of `t.paginated(item)`. */"
3803
- },
3804
3563
  {
3805
3564
  "name": "PageRouteInput",
3806
3565
  "kind": "interface",
@@ -3815,13 +3574,6 @@
3815
3574
  "signature": "export declare function pageRoutesSection(manifest: Manifest | undefined): string;",
3816
3575
  "doc": "/** Markdown section listing the file-routed pages (URL pattern → source file). */"
3817
3576
  },
3818
- {
3819
- "name": "paginate",
3820
- "kind": "function",
3821
- "package": "@nifrajs/schema",
3822
- "signature": "export declare function paginate<Row>(rows: readonly Row[], limit: number, cursorOf: (row: Row) => unknown): Page<Row>;",
3823
- "doc": "/**\n * Build a page from rows you fetched with `limit + 1`. If the extra row came back there are more pages:\n * drop it and emit a `nextCursor` from the last KEPT row via `cursorOf`; otherwise `nextCursor` is `null`.\n *\n * const rows = await db.notes.after(decodeCursor(query.cursor)).take(limit + 1)\n * return paginate(rows, limit, (note) => note.id)\n */"
3824
- },
3825
3577
  {
3826
3578
  "name": "Params",
3827
3579
  "kind": "type",
@@ -4178,12 +3930,6 @@
4178
3930
  "signature": "export declare function publicEnvDefines(prefix: string, env: Readonly<Record<string, string | undefined>>): Record<string, string>;",
4179
3931
  "doc": "/**\n * The `process.env.<NAME>` → `JSON.stringify(value)` define entries for every env var whose name\n * carries `prefix` (the Vite/Next public-env convention). Exposing ONLY the prefixed vars is the\n * security boundary: an unprefixed var (a secret) never gets a define, so the bare `process.env`\n * define resolves it to `undefined` in the client bundle. An empty `prefix` exposes nothing (the\n * opt-out). Pure + exported so the prefix/redaction contract is unit-testable without a real build.\n */"
4180
3932
  },
4181
- {
4182
- "name": "PutOptions",
4183
- "kind": "interface",
4184
- "package": "@nifrajs/storage",
4185
- "signature": "export interface PutOptions {\n /** MIME type stored alongside the object (returned by `get`). */\n readonly contentType?: string;\n /** Arbitrary string metadata stored with the object. */\n readonly metadata?: Readonly<Record<string, string>>;\n}"
4186
- },
4187
3933
  {
4188
3934
  "name": "QueryClient",
4189
3935
  "kind": "interface",
@@ -4244,44 +3990,12 @@
4244
3990
  "signature": "export type QueryValue = string | string[];",
4245
3991
  "doc": "/** A query value: a single occurrence is a string; a repeated key promotes to a string[] so an\n * array query schema (`t.array(t.string())`) can validate `?tag=a&tag=b` — last-wins silently\n * dropped values before (audit 2026-06). Single-occurrence keys stay plain strings, so existing\n * `t.string()` schemas are untouched; a repeated key against a string schema now FAILS validation\n * (an explicit 400 beats silently picking one). */"
4246
3992
  },
4247
- {
4248
- "name": "Queue",
4249
- "kind": "interface",
4250
- "package": "@nifrajs/jobs",
4251
- "signature": "export interface Queue {\n /** Register a typed job. Throws now (not at run time) on a duplicate name. */\n define<Payload>(name: string, definition: JobDefinition<Payload>): JobHandle<Payload>;\n /** Enqueue by name (the {@link JobHandle} is the typed alternative). */\n enqueue(name: string, payload: unknown, options?: EnqueueOptions): Promise<string>;\n /** Run ONE poll round: lease up to `concurrency` due jobs, run them, await them. Returns the count run.\n * Re-entrant-safe (a concurrent call returns the in-flight round). Used by `start()` and by Workers. */\n process(): Promise<number>;\n /** Process repeatedly until no job is due (one-shot batch drain). */\n drain(): Promise<number>;\n /** Start the background worker (Bun/Node/Deno). */\n start(options?: WorkerOptions): Worker;\n /** Current store counts. */\n counts(): JobCounts | Promise<JobCounts>;\n /** The underlying store (for dead-letter inspection, custom drivers). */\n readonly store: JobStore;\n}"
4252
- },
4253
- {
4254
- "name": "QueueOptions",
4255
- "kind": "interface",
4256
- "package": "@nifrajs/jobs",
4257
- "signature": "export interface QueueOptions {\n /** Persistence. Default: a fresh {@link MemoryJobStore} (single-process). */\n readonly store?: JobStore;\n /** Called when a handler throws (before retry/dead-letter). Default: `console.error`. A throwing handler here is swallowed. */\n readonly onError?: (error: unknown, jobName: string) => void;\n /** Injectable clock (tests). Default `() => Date.now()`. */\n readonly now?: () => number;\n /** Default attempts for jobs that don't set `retries`. Default 3. */\n readonly defaultAttempts?: number;\n /** Default backoff for jobs that don't set one. Default {@link exponentialBackoff}. */\n readonly backoff?: Backoff;\n}"
4258
- },
4259
3993
  {
4260
3994
  "name": "quotedHeaderValue",
4261
3995
  "kind": "function",
4262
3996
  "package": "@nifrajs/middleware",
4263
3997
  "signature": "export declare function quotedHeaderValue(value: string): string;"
4264
3998
  },
4265
- {
4266
- "name": "R2BucketLike",
4267
- "kind": "interface",
4268
- "package": "@nifrajs/storage",
4269
- "signature": "export interface R2BucketLike {\n put(key: string, value: ArrayBuffer | ArrayBufferView, options?: {\n httpMetadata?: {\n contentType?: string;\n };\n customMetadata?: Record<string, string>;\n }): Promise<unknown>;\n get(key: string): Promise<(R2ObjectLike & {\n arrayBuffer(): Promise<ArrayBuffer>;\n }) | null>;\n head(key: string): Promise<R2ObjectLike | null>;\n delete(key: string): Promise<void>;\n list(options?: {\n prefix?: string;\n limit?: number;\n }): Promise<{\n objects: ReadonlyArray<{\n key: string;\n }>;\n }>;\n}",
4270
- "doc": "/** The slice of the R2 bucket binding this adapter calls. `env.<BUCKET>` satisfies it. */"
4271
- },
4272
- {
4273
- "name": "R2ObjectLike",
4274
- "kind": "interface",
4275
- "package": "@nifrajs/storage",
4276
- "signature": "export interface R2ObjectLike {\n readonly size: number;\n readonly httpMetadata?: {\n readonly contentType?: string;\n };\n readonly customMetadata?: Record<string, string>;\n}",
4277
- "doc": "/** The slice of R2's object metadata this adapter reads. */"
4278
- },
4279
- {
4280
- "name": "R2Storage",
4281
- "kind": "class",
4282
- "package": "@nifrajs/storage",
4283
- "signature": "export declare class R2Storage implements StorageAdapter {\n private readonly bucket;\n constructor(bucket: R2BucketLike);\n put(key: string, data: StorageData, options?: PutOptions): Promise<void>;\n get(key: string): Promise<StorageObject | null>;\n delete(key: string): Promise<void>;\n exists(key: string): Promise<boolean>;\n list(options?: ListOptions): Promise<string[]>;\n}"
4284
- },
4285
3999
  {
4286
4000
  "name": "rateLimit",
4287
4001
  "kind": "function",
@@ -4769,12 +4483,6 @@
4769
4483
  "signature": "export type Result<Data> = {\n readonly ok: true;\n readonly status: number;\n readonly data: Data;\n readonly error: null;\n} | {\n readonly ok: false;\n readonly status: number;\n readonly data: null;\n readonly error: ApiError;\n};",
4770
4484
  "doc": "/**\n * The outcome of a client call. The client never throws — inspect `ok` (or\n * `error`) to branch. On success `data` is the (JSON-shaped) response body; on\n * failure `error` carries the server's structured error or a transport error.\n */"
4771
4485
  },
4772
- {
4773
- "name": "RetryPolicy",
4774
- "kind": "interface",
4775
- "package": "@nifrajs/jobs",
4776
- "signature": "export interface RetryPolicy {\n /** Total attempts before dead-lettering (incl. the first). Default 3. `1` = no retries. */\n readonly attempts: number;\n /** Delay before each retry. Default {@link exponentialBackoff}. */\n readonly backoff?: Backoff;\n}"
4777
- },
4778
4486
  {
4779
4487
  "name": "revalidate",
4780
4488
  "kind": "function",
@@ -4835,13 +4543,6 @@
4835
4543
  "signature": "export declare const ROUTE_GLOBAL = \"__NIFRA_ROUTE__\";",
4836
4544
  "doc": "/** Global the server writes the matched route id into; the client uses it to pick the chain. */"
4837
4545
  },
4838
- {
4839
- "name": "RouteBody",
4840
- "kind": "type",
4841
- "package": "@nifrajs/web",
4842
- "signature": "export type RouteBody<App, Path extends string, Method extends string> = Path extends keyof RegistryOf<App> ? Uppercase<Method> extends keyof RegistryOf<App>[Path] ? (RegistryOf<App>[Path][Uppercase<Method>] & RouteInfo)[\"body\"] : never : never;",
4843
- "doc": "/** The body object type of `App`'s `Method Path` route (`never` when the route declares no body). */"
4844
- },
4845
4546
  {
4846
4547
  "name": "RouteConfigError",
4847
4548
  "kind": "class",
@@ -4926,13 +4627,6 @@
4926
4627
  "signature": "export interface RouteModule {\n readonly default: unknown;\n readonly loader?: Loader;\n readonly action?: Action;\n readonly meta?: MetaInput;\n /**\n * Opt this route out of nifra's full-document client hydration. The server still renders the full\n * HTML document, loaders/actions still run, and native links/forms still work; the generated app\n * client, route chunks, and loader globals are omitted for hard navigations. Intended for static or\n * island-hydrated pages where interactivity is mounted by smaller, explicit client entries.\n */\n readonly hydrate?: boolean;\n /**\n * Opt a **static** route (no `:param`/`*`) into build-time prerendering (SSG): `prerenderRoutes`\n * (from `@nifrajs/web/build`) renders it to a static `index.html` at build. The loader runs at build\n * with the in-process `api` (build-safe data only — no per-request cookies/secrets); `defer()` on a\n * prerendered route resolves at build. For **dynamic** routes use {@link getStaticPaths} instead.\n */\n readonly prerender?: boolean;\n /**\n * Enumerate the concrete params to prerender for a **dynamic** (`:param`) route — the SSG path list\n * (blogs/docs/etc.). Runs at build; `prerenderRoutes` renders one `index.html` per returned path.\n */\n readonly getStaticPaths?: GetStaticPaths;\n /**\n * ISR freshness for this route, in **seconds**. `createWebApp` emits it as an `x-nifra-revalidate`\n * response header that `withISR` reads to set the page's cache TTL (overriding the wrapper's\n * default). Older-than-`revalidate` cached pages are served stale while regenerating.\n */\n readonly revalidate?: number;\n /**\n * No-framework island bundles (`@nifrajs/web/islands`) to load on this route, as `<script\n * type=\"module\">` in the document tail. Loaded **regardless of `hydrate`** — pair with\n * `export const hydrate = false` for a static page that ships zero framework JS and mounts\n * interactivity through `<Island>` markers + `mountIslands` enhancers instead.\n */\n readonly islandScripts?: readonly string[];\n}",
4927
4628
  "doc": "/** A route module — the default component + optional loader / action / meta. */"
4928
4629
  },
4929
- {
4930
- "name": "RoutePaths",
4931
- "kind": "type",
4932
- "package": "@nifrajs/web",
4933
- "signature": "export type RoutePaths<App> = keyof RegistryOf<App> & string;",
4934
- "doc": "/** Every route path the app declares — constrains `Path`, so a wrong path is itself a type error. */"
4935
- },
4936
4630
  {
4937
4631
  "name": "routePathToFile",
4938
4632
  "kind": "function",
@@ -5564,12 +5258,6 @@
5564
5258
  "signature": "export declare function setMountedRouter(router: ClientRouter | undefined): void;",
5565
5259
  "doc": "/** Register (or clear) the router that owns fetchers — called by `mountRouter`. Not for app use. */"
5566
5260
  },
5567
- {
5568
- "name": "SetOptions",
5569
- "kind": "interface",
5570
- "package": "@nifrajs/cache",
5571
- "signature": "export interface SetOptions {\n /** Time-to-live (ms) before the value goes stale. Default: the cache's `defaultTtlMs`. */\n readonly ttlMs?: number;\n /** Extra ms past TTL during which the stale value is served while a background refresh runs. Default 0. */\n readonly swrMs?: number;\n /** Tags for group invalidation via `invalidateTag`. */\n readonly tags?: readonly string[];\n}"
5572
- },
5573
5261
  {
5574
5262
  "name": "setWsRuntime",
5575
5263
  "kind": "function",
@@ -5824,13 +5512,6 @@
5824
5512
  "package": "@nifrajs/env",
5825
5513
  "signature": "export type StandardResult<Output> = {\n readonly value: Output;\n readonly issues?: undefined;\n} | {\n readonly issues: ReadonlyArray<StandardIssue>;\n};"
5826
5514
  },
5827
- {
5828
- "name": "StandardResult",
5829
- "kind": "type",
5830
- "package": "@nifrajs/jobs",
5831
- "signature": "export type StandardResult<Output> = {\n readonly value: Output;\n readonly issues?: undefined;\n} | {\n readonly issues: ReadonlyArray<{\n readonly message: string;\n }>;\n};",
5832
- "doc": "/** The validate-result half of the Standard Schema spec. */"
5833
- },
5834
5515
  {
5835
5516
  "name": "StandardSchemaProps",
5836
5517
  "kind": "interface",
@@ -5850,13 +5531,6 @@
5850
5531
  "package": "@nifrajs/env",
5851
5532
  "signature": "export interface StandardSchemaV1<Output = unknown> {\n readonly \"~standard\": {\n readonly version: 1;\n readonly vendor: string;\n readonly validate: (value: unknown) => StandardResult<Output> | Promise<StandardResult<Output>>;\n readonly types?: {\n readonly output: Output;\n };\n };\n}"
5852
5533
  },
5853
- {
5854
- "name": "StandardSchemaV1",
5855
- "kind": "interface",
5856
- "package": "@nifrajs/jobs",
5857
- "signature": "export interface StandardSchemaV1<Output = unknown> {\n readonly \"~standard\": {\n readonly version: 1;\n readonly vendor: string;\n readonly validate: (value: unknown) => StandardResult<Output> | Promise<StandardResult<Output>>;\n readonly types?: {\n readonly input: unknown;\n readonly output: Output;\n };\n };\n}",
5858
- "doc": "/** A minimal structural view of a Standard Schema validator (v1). `t.object(...)` satisfies it. */"
5859
- },
5860
5534
  {
5861
5535
  "name": "StandardSuccess",
5862
5536
  "kind": "interface",
@@ -5903,48 +5577,6 @@
5903
5577
  "signature": "export interface StaticRoutes {\n /** Concrete prerendered paths — static `prerender` routes + each `getStaticPaths` entry. */\n readonly paths: string[];\n /** Per dynamic route pattern, its `getStaticPaths` `fallback` (`\"ssr\"` default). `createWebApp` uses\n * `\"404\"` to reject an unlisted path under that route at runtime (the path simply doesn't exist). */\n readonly fallbacks: Record<string, \"ssr\" | \"404\">;\n}",
5904
5578
  "doc": "/** The static-routing facts a server needs from the route modules: which concrete paths are\n * prerendered, plus each dynamic route's `getStaticPaths` fallback policy. */"
5905
5579
  },
5906
- {
5907
- "name": "StorageAdapter",
5908
- "kind": "interface",
5909
- "package": "@nifrajs/storage",
5910
- "signature": "export interface StorageAdapter {\n /** Store `data` under `key`, overwriting any existing object. */\n put(key: string, data: StorageData, options?: PutOptions): Promise<void>;\n /** Read the object at `key`, or `null` if it doesn't exist. */\n get(key: string): Promise<StorageObject | null>;\n /** Remove `key`. No-op if it doesn't exist. */\n delete(key: string): Promise<void>;\n /** Whether an object exists at `key`. */\n exists(key: string): Promise<boolean>;\n /** List stored keys (optionally filtered by prefix + capped). */\n list(options?: ListOptions): Promise<string[]>;\n}",
5911
- "doc": "/**\n * A blob store keyed by string. Keys are POSIX-ish paths (`avatars/u1.png`); every adapter rejects unsafe\n * keys (absolute, `..` traversal, NUL, backslash) so a key valid in one adapter is valid in all. All\n * methods are async.\n */"
5912
- },
5913
- {
5914
- "name": "StorageData",
5915
- "kind": "type",
5916
- "package": "@nifrajs/storage",
5917
- "signature": "export type StorageData = Uint8Array | ArrayBuffer | string;",
5918
- "doc": "/** Accepted `put` payloads — normalized to bytes by each adapter. */"
5919
- },
5920
- {
5921
- "name": "StorageKeyError",
5922
- "kind": "class",
5923
- "package": "@nifrajs/storage",
5924
- "signature": "export declare class StorageKeyError extends Error {\n readonly name = \"StorageKeyError\";\n}",
5925
- "doc": "/**\n * Storage-key safety. A key is a POSIX-ish relative path (`avatars/u1.png`); we reject anything that\n * could escape a `FileStorage` root or otherwise misbehave — absolute paths, `..` traversal, NUL bytes,\n * and backslashes (Windows traversal). Enforced by EVERY adapter (not just `FileStorage`) so a key is\n * portable across them, and so the check can't be forgotten on the one adapter where it's a vulnerability.\n */"
5926
- },
5927
- {
5928
- "name": "StorageObject",
5929
- "kind": "interface",
5930
- "package": "@nifrajs/storage",
5931
- "signature": "export interface StorageObject {\n readonly body: Uint8Array;\n readonly size: number;\n readonly contentType?: string;\n readonly metadata?: Readonly<Record<string, string>>;\n}",
5932
- "doc": "/** An object read back from storage. `body` is buffered (not streamed) — fine for typical uploads. */"
5933
- },
5934
- {
5935
- "name": "StoredEntry",
5936
- "kind": "interface",
5937
- "package": "@nifrajs/cache",
5938
- "signature": "export interface StoredEntry {\n readonly value: unknown;\n /** Epoch-ms after which the entry is gone — a miss. */\n readonly expiresAt: number;\n /** Epoch-ms after which the entry is stale: still served during the SWR window while a refresh runs.\n * Equal to `expiresAt` when there's no stale-while-revalidate window. */\n readonly staleAt: number;\n}",
5939
- "doc": "/** A cached entry as the store holds it. */"
5940
- },
5941
- {
5942
- "name": "StoredJob",
5943
- "kind": "interface",
5944
- "package": "@nifrajs/jobs",
5945
- "signature": "export interface StoredJob {\n readonly id: string;\n readonly name: string;\n readonly payload: unknown;\n readonly attempt: number;\n readonly maxAttempts: number;\n}",
5946
- "doc": "/** A job as handed back by {@link JobStore.lease}. `attempt` is the count of PRIOR attempts (0 the first time). */"
5947
- },
5948
5580
  {
5949
5581
  "name": "string",
5950
5582
  "kind": "function",
@@ -6024,7 +5656,7 @@
6024
5656
  "name": "t",
6025
5657
  "kind": "const",
6026
5658
  "package": "@nifrajs/schema",
6027
- "signature": "export declare const t: {\n readonly string: (options?: StringOptions) => NifraSchema<import(\"@sinclair/typebox\").TString>;\n readonly number: (options?: NumberOptions) => NifraSchema<import(\"@sinclair/typebox\").TNumber>;\n readonly integer: (options?: IntegerOptions) => NifraSchema<import(\"@sinclair/typebox\").TInteger>;\n readonly boolean: () => NifraSchema<import(\"@sinclair/typebox\").TBoolean>;\n readonly null: () => NifraSchema<import(\"@sinclair/typebox\").TNull>;\n readonly literal: <const L extends TLiteralValue>(value: L) => NifraSchema<import(\"@sinclair/typebox\").TLiteral<L>>;\n readonly object: <P extends Props>(props: P, options?: ObjectOptions) => NifraSchema<import(\"@sinclair/typebox\").TObject<{ [K in keyof P]: P[K][\"jsonSchema\"]; }>>;\n /** Like `t.object` but ACCEPTS (and passes through) unknown fields — the explicit opt-out of the\n * strict default. Prefer `t.object` unless you genuinely need an open object. */\n readonly looseObject: <P extends Props>(props: P, options?: ObjectOptions) => NifraSchema<import(\"@sinclair/typebox\").TObject<{ [K in keyof P]: P[K][\"jsonSchema\"]; }>>;\n readonly array: <T extends TSchema>(item: NifraSchema<T>, options?: ArrayOptions) => NifraSchema<import(\"@sinclair/typebox\").TArray<T>>;\n /** Marks a property optional inside `t.object`; standalone it is `T | undefined`. */\n readonly optional: <T extends TSchema>(schema: NifraSchema<T>) => NifraSchema<T extends import(\"@sinclair/typebox\").TOptional<infer S extends TSchema> ? import(\"@sinclair/typebox\").TOptional<S> : import(\"@sinclair/typebox\").Ensure<import(\"@sinclair/typebox\").TOptional<T>>>;\n readonly union: <const S extends readonly NifraSchema[]>(schemas: S) => NifraSchema<TUnion<{ -readonly [K in keyof S]: S[K][\"jsonSchema\"]; }>>;\n readonly record: <T extends TSchema>(value: NifraSchema<T>, options?: ObjectOptions) => NifraSchema<import(\"@sinclair/typebox\").TRecord<import(\"@sinclair/typebox\").TString, T>>;\n /** A cursor-pagination response envelope: `{ items: T[]; nextCursor: string | null }` (`null` = last page). */\n readonly paginated: <T extends TSchema>(item: NifraSchema<T>, options?: ObjectOptions) => NifraSchema<import(\"@sinclair/typebox\").TObject<{\n items: import(\"@sinclair/typebox\").TArray<T>;\n nextCursor: TUnion<[import(\"@sinclair/typebox\").TString, import(\"@sinclair/typebox\").TNull]>;\n }>>;\n /** A request query schema for cursor pagination: `{ cursor?: string; limit?: number }`. `maxLimit`\n * caps `limit` — a larger value fails validation (a 400), so a client can't request an unbounded page.\n * `coerce` is on because query values arrive as strings (`?limit=20` → `\"20\"`); it's what makes `limit`\n * a real `number` in the handler (`c.query.limit`), not a string. */\n readonly pageQuery: (options?: {\n maxLimit?: number;\n }) => NifraSchema<import(\"@sinclair/typebox\").TObject<{\n cursor: import(\"@sinclair/typebox\").TOptional<import(\"@sinclair/typebox\").TString>;\n limit: import(\"@sinclair/typebox\").TOptional<import(\"@sinclair/typebox\").TInteger>;\n }>>;\n};",
5659
+ "signature": "export declare const t: {\n readonly string: (options?: StringOptions) => NifraSchema<import(\"@sinclair/typebox\").TString>;\n readonly number: (options?: NumberOptions) => NifraSchema<import(\"@sinclair/typebox\").TNumber>;\n readonly integer: (options?: IntegerOptions) => NifraSchema<import(\"@sinclair/typebox\").TInteger>;\n readonly boolean: () => NifraSchema<import(\"@sinclair/typebox\").TBoolean>;\n readonly null: () => NifraSchema<import(\"@sinclair/typebox\").TNull>;\n readonly literal: <const L extends TLiteralValue>(value: L) => NifraSchema<import(\"@sinclair/typebox\").TLiteral<L>>;\n readonly object: <P extends Props>(props: P, options?: ObjectOptions) => NifraSchema<import(\"@sinclair/typebox\").TObject<{ [K in keyof P]: P[K][\"jsonSchema\"]; }>>;\n /** Like `t.object` but ACCEPTS (and passes through) unknown fields — the explicit opt-out of the\n * strict default. Prefer `t.object` unless you genuinely need an open object. */\n readonly looseObject: <P extends Props>(props: P, options?: ObjectOptions) => NifraSchema<import(\"@sinclair/typebox\").TObject<{ [K in keyof P]: P[K][\"jsonSchema\"]; }>>;\n readonly array: <T extends TSchema>(item: NifraSchema<T>, options?: ArrayOptions) => NifraSchema<import(\"@sinclair/typebox\").TArray<T>>;\n /** Marks a property optional inside `t.object`; standalone it is `T | undefined`. */\n readonly optional: <T extends TSchema>(schema: NifraSchema<T>) => NifraSchema<T extends import(\"@sinclair/typebox\").TOptional<infer S extends TSchema> ? import(\"@sinclair/typebox\").TOptional<S> : import(\"@sinclair/typebox\").Ensure<import(\"@sinclair/typebox\").TOptional<T>>>;\n readonly union: <const S extends readonly NifraSchema[]>(schemas: S) => NifraSchema<TUnion<{ -readonly [K in keyof S]: S[K][\"jsonSchema\"]; }>>;\n readonly record: <T extends TSchema>(value: NifraSchema<T>, options?: ObjectOptions) => NifraSchema<import(\"@sinclair/typebox\").TRecord<import(\"@sinclair/typebox\").TString, T>>;\n};",
6028
5660
  "doc": "/**\n * The built-in schema builder. Each constructor returns a `NifraSchema` — a\n * Standard Schema whose validated output type flows into `c.body`/`c.query`, and\n * whose `jsonSchema` powers `toOpenAPI`. Options (min/max, length, pattern, …)\n * pass straight through to TypeBox and so become JSON Schema constraints.\n *\n * Composite constructors are generic over the *inner* TypeBox schema `T extends\n * TSchema` (not over `NifraSchema`): reading `.jsonSchema` off a value typed only as\n * `NifraSchema` would erase to the `TSchema` constraint and collapse the output type\n * to `unknown`. Capturing `T` keeps `Static<T>` precise (`string[]`, not\n * `unknown[]`).\n */"
6029
5661
  },
6030
5662
  {
@@ -6060,25 +5692,6 @@
6060
5692
  "signature": "export declare const testClient: typeof inProcessClient;",
6061
5693
  "doc": "/**\n * The in-process test client — the Fastify-`inject` / supertest equivalent for nifra. Drives the\n * app's own `fetch` directly: no server, no port, no network, the full real lifecycle (validation,\n * middleware, contracts, auth), and end-to-end types from `App`. Calls never throw — branch on\n * `res.ok`. An alias of {@link inProcessClient} with a test-focused name; identical behavior.\n *\n * ```ts\n * import { testClient } from \"@nifrajs/client\"\n * import { app } from \"../src/app\"\n *\n * const api = testClient<typeof app>(app)\n * const res = await api.users({ id: \"42\" }).get()\n * expect(res.ok && res.data.id).toBe(\"42\")\n * ```\n */"
6062
5694
  },
6063
- {
6064
- "name": "testSession",
6065
- "kind": "function",
6066
- "package": "@nifrajs/testing",
6067
- "signature": "export declare function testSession<App extends AppLike>(app: App, options?: TestSessionOptions): TestSession<App>;",
6068
- "doc": "/** Create a cookie-persisting in-process test client for `app`. */"
6069
- },
6070
- {
6071
- "name": "TestSession",
6072
- "kind": "interface",
6073
- "package": "@nifrajs/testing",
6074
- "signature": "export interface TestSession<App> {\n /** The end-to-end-typed in-process client — every call carries + captures cookies. */\n readonly client: Treaty<App>;\n /** The jar backing this session — inspect (`cookies.get(\"sid\")`), seed, or `clear()` it. */\n readonly cookies: CookieJar;\n}"
6075
- },
6076
- {
6077
- "name": "TestSessionOptions",
6078
- "kind": "interface",
6079
- "package": "@nifrajs/testing",
6080
- "signature": "export interface TestSessionOptions extends Omit<ClientOptions, \"fetch\"> {\n /** Origin used to resolve relative paths. Default `\"http://nifra.internal\"`. */\n readonly origin?: string;\n /** Reuse an existing jar (e.g. seed a session cookie, or share one across sessions). */\n readonly cookies?: CookieJar;\n}"
6081
- },
6082
5695
  {
6083
5696
  "name": "TestSummary",
6084
5697
  "kind": "interface",
@@ -6141,13 +5754,6 @@
6141
5754
  "package": "@nifrajs/middleware",
6142
5755
  "signature": "export declare function timingSafeEqualString(a: string, b: string): Promise<boolean>;"
6143
5756
  },
6144
- {
6145
- "name": "toBytes",
6146
- "kind": "function",
6147
- "package": "@nifrajs/storage",
6148
- "signature": "export declare function toBytes(data: StorageData): Uint8Array;",
6149
- "doc": "/** Normalize any accepted payload to bytes. */"
6150
- },
6151
5757
  {
6152
5758
  "name": "toFetchHandler",
6153
5759
  "kind": "function",
@@ -6651,8 +6257,8 @@
6651
6257
  "name": "VERSION",
6652
6258
  "kind": "const",
6653
6259
  "package": "@nifrajs/core",
6654
- "signature": "export declare const VERSION: \"1.1.0\";",
6655
- "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, so the literal can't go stale\n * (it shipped at \"0.0.0\" through 1.0.0 before those guards existed). Kept narrow (`as const`) so\n * consumers can pin it at the type level — see `test/version.test-d.ts`.\n */"
6260
+ "signature": "export declare const VERSION: \"0.0.0\";",
6261
+ "doc": "/** Current package version. Kept as a literal so type-level tests can pin it. */"
6656
6262
  },
6657
6263
  {
6658
6264
  "name": "ViteDevServer",
@@ -6789,24 +6395,6 @@
6789
6395
  "signature": "export declare function withISR(app: ISRApp, options: ISROptions): (req: Request, platform?: ISRPlatform) => Promise<Response>;",
6790
6396
  "doc": "/**\n * Wrap a nifra app with **Incremental Static Regeneration**: a cacheable page is served from\n * {@link CacheStore} when fresh, served **stale while a fresh copy regenerates in the background**\n * (`platform.waitUntil` on edge), or rendered + stored on a miss. Framework-agnostic (it caches the\n * rendered bytes). Returns a `fetch(req, platform?)` handler — hand it to `Bun.serve`/the Workers\n * `export default`, etc. Regeneration is single-flight per key (no stampede on a hot stale page).\n *\n * Each route's freshness comes from the `revalidate` header the app sets (per-route\n * `export const revalidate`), falling back to `options.revalidate`. Only full-document `text/html`\n * GET 200s are cached; everything else (assets, data-mode GETs, redirects, errors) passes through.\n */"
6791
6397
  },
6792
- {
6793
- "name": "Worker",
6794
- "kind": "interface",
6795
- "package": "@nifrajs/jobs",
6796
- "signature": "export interface Worker {\n /** Stop polling and await the in-flight round (graceful). */\n stop(): Promise<void>;\n readonly running: boolean;\n}"
6797
- },
6798
- {
6799
- "name": "WorkerOptions",
6800
- "kind": "interface",
6801
- "package": "@nifrajs/jobs",
6802
- "signature": "export interface WorkerOptions {\n /** Max jobs in flight at once. Default 1. */\n readonly concurrency?: number;\n /** How often to poll the store for due jobs (ms). Default 250. */\n readonly pollIntervalMs?: number;\n /** How long a leased job is hidden before it's considered abandoned and re-leased (ms). Default 30_000. */\n readonly leaseMs?: number;\n}"
6803
- },
6804
- {
6805
- "name": "WrapOptions",
6806
- "kind": "type",
6807
- "package": "@nifrajs/cache",
6808
- "signature": "export type WrapOptions = SetOptions;"
6809
- },
6810
6398
  {
6811
6399
  "name": "wrapWebSocketMessageValidation",
6812
6400
  "kind": "function",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nifrajs/cli",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "The nifra CLI — zero-config dev/build/start for a nifra app (`nifra dev`, `nifra build`, `nifra start`).",
5
5
  "keywords": [
6
6
  "bun",
@@ -41,12 +41,12 @@
41
41
  "access": "public"
42
42
  },
43
43
  "dependencies": {
44
- "@nifrajs/client": "1.1.0",
45
- "@nifrajs/mcp": "1.1.0",
46
- "@nifrajs/runner": "1.1.0",
47
- "@nifrajs/schema": "1.1.0",
48
- "@nifrajs/web": "1.1.0",
49
- "create-nifra": "1.1.0"
44
+ "@nifrajs/client": "1.2.0",
45
+ "@nifrajs/mcp": "1.2.0",
46
+ "@nifrajs/runner": "1.2.0",
47
+ "@nifrajs/schema": "1.2.0",
48
+ "@nifrajs/web": "1.2.0",
49
+ "create-nifra": "1.2.0"
50
50
  },
51
51
  "repository": {
52
52
  "type": "git",
package/src/cli.ts CHANGED
@@ -82,7 +82,7 @@ Port: \`dev\` and \`start\` share the default ${DEFAULT_DEV_PORT}. Override with
82
82
  \`PORT\` env var (\`--port\` wins over \`PORT\`, which wins over the default).`
83
83
 
84
84
  // Kept in lockstep with packages/cli/package.json by check:publish's version-consistency gate.
85
- const CLI_VERSION = "1.1.0"
85
+ const CLI_VERSION = "1.2.0"
86
86
 
87
87
  // A render adapter + nifra server are opaque to the CLI (it just forwards them); cast at the seam.
88
88
  const asAdapter = (v: unknown): RenderAdapter => v as RenderAdapter
package/src/mcp-http.ts CHANGED
@@ -26,7 +26,7 @@ export { docsTools } from "./mcp-docs-tools.ts"
26
26
  export type { TypeEntry } from "./types-search.ts"
27
27
 
28
28
  // Kept in lockstep with packages/cli/package.json by check:publish's version-consistency gate.
29
- const VERSION = "1.1.0"
29
+ const VERSION = "1.2.0"
30
30
  const SERVER_INFO = { name: "nifra-docs", version: VERSION }
31
31
  const DOCS_HEALTH =
32
32
  "nifra docs MCP — POST JSON-RPC 2.0 here (methods: initialize, tools/list, tools/call). Tools: nifra_docs, nifra_example."