@nifrajs/cli 3.1.0 → 3.3.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/README.md +10 -0
- package/dist/assure-hydration.d.ts.map +1 -1
- package/dist/assure-hydration.js +6 -1
- package/dist/assure-hydration.js.map +1 -1
- package/dist/assure.d.ts.map +1 -1
- package/dist/assure.js +3 -2
- package/dist/assure.js.map +1 -1
- package/dist/check-diagnostics.d.ts +165 -0
- package/dist/check-diagnostics.d.ts.map +1 -0
- package/dist/check-diagnostics.js +1009 -0
- package/dist/check-diagnostics.js.map +1 -0
- package/dist/check-scan.d.ts +245 -0
- package/dist/check-scan.d.ts.map +1 -0
- package/dist/check-scan.js +1599 -0
- package/dist/check-scan.js.map +1 -0
- package/dist/check.d.ts +4 -324
- package/dist/check.d.ts.map +1 -1
- package/dist/check.js +8 -2366
- package/dist/check.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +247 -10
- package/dist/cli.js.map +1 -1
- package/dist/command-catalog.d.ts +21 -1
- package/dist/command-catalog.d.ts.map +1 -1
- package/dist/command-catalog.js +122 -0
- package/dist/command-catalog.js.map +1 -1
- package/dist/env-file.js +5 -5
- package/dist/env-file.js.map +1 -1
- package/dist/frontend-guidance.d.ts +57 -0
- package/dist/frontend-guidance.d.ts.map +1 -0
- package/dist/frontend-guidance.js +195 -0
- package/dist/frontend-guidance.js.map +1 -0
- package/dist/levels-tool.d.ts.map +1 -1
- package/dist/levels-tool.js +6 -0
- package/dist/levels-tool.js.map +1 -1
- package/dist/load.d.ts.map +1 -1
- package/dist/load.js +4 -1
- package/dist/load.js.map +1 -1
- package/dist/mcp-context.d.ts +48 -0
- package/dist/mcp-context.d.ts.map +1 -0
- package/dist/mcp-context.js +215 -0
- package/dist/mcp-context.js.map +1 -0
- package/dist/mcp-docs-tools.d.ts.map +1 -1
- package/dist/mcp-docs-tools.js +31 -0
- package/dist/mcp-docs-tools.js.map +1 -1
- package/dist/mcp-exec.d.ts +74 -0
- package/dist/mcp-exec.d.ts.map +1 -0
- package/dist/mcp-exec.js +844 -0
- package/dist/mcp-exec.js.map +1 -0
- package/dist/mcp-http.js +1 -1
- package/dist/mcp-io.d.ts +26 -0
- package/dist/mcp-io.d.ts.map +1 -0
- package/dist/mcp-io.js +100 -0
- package/dist/mcp-io.js.map +1 -0
- package/dist/mcp-reflect.d.ts +16 -0
- package/dist/mcp-reflect.d.ts.map +1 -0
- package/dist/mcp-reflect.js +101 -0
- package/dist/mcp-reflect.js.map +1 -0
- package/dist/mcp-root.d.ts +7 -0
- package/dist/mcp-root.d.ts.map +1 -1
- package/dist/mcp-root.js +51 -3
- package/dist/mcp-root.js.map +1 -1
- package/dist/mcp.d.ts +10 -92
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +13 -1232
- package/dist/mcp.js.map +1 -1
- package/dist/openapi-tool.d.ts +5 -10
- package/dist/openapi-tool.d.ts.map +1 -1
- package/dist/openapi-tool.js +21 -2
- package/dist/openapi-tool.js.map +1 -1
- package/dist/openapi-types.d.ts +21 -0
- package/dist/openapi-types.d.ts.map +1 -0
- package/dist/openapi-types.js +214 -0
- package/dist/openapi-types.js.map +1 -0
- package/dist/port.d.ts.map +1 -1
- package/dist/port.js +2 -1
- package/dist/port.js.map +1 -1
- package/dist/project-facts.d.ts +2 -1
- package/dist/project-facts.d.ts.map +1 -1
- package/dist/project-facts.js.map +1 -1
- package/dist/release-verification.d.ts +4 -1
- package/dist/release-verification.d.ts.map +1 -1
- package/dist/release-verification.js +6 -138
- package/dist/release-verification.js.map +1 -1
- package/dist/rules/codes.d.ts +4 -0
- package/dist/rules/codes.d.ts.map +1 -1
- package/dist/rules/codes.js +4 -0
- package/dist/rules/codes.js.map +1 -1
- package/dist/rules/islands.d.ts +4 -0
- package/dist/rules/islands.d.ts.map +1 -0
- package/dist/rules/islands.js +155 -0
- package/dist/rules/islands.js.map +1 -0
- package/dist/rules/nano.d.ts +6 -0
- package/dist/rules/nano.d.ts.map +1 -0
- package/dist/rules/nano.js +264 -0
- package/dist/rules/nano.js.map +1 -0
- package/dist/rules/security.d.ts.map +1 -1
- package/dist/rules/security.js +38 -4
- package/dist/rules/security.js.map +1 -1
- package/dist/scaffold.d.ts +12 -6
- package/dist/scaffold.d.ts.map +1 -1
- package/dist/scaffold.js +149 -10
- package/dist/scaffold.js.map +1 -1
- package/dist/search-terms.d.ts.map +1 -1
- package/dist/search-terms.js +5 -3
- package/dist/search-terms.js.map +1 -1
- package/dist/stylex-migrate.d.ts +38 -0
- package/dist/stylex-migrate.d.ts.map +1 -0
- package/dist/stylex-migrate.js +1052 -0
- package/dist/stylex-migrate.js.map +1 -0
- package/dist/sync-manifest.d.ts.map +1 -1
- package/dist/sync-manifest.js +2 -1
- package/dist/sync-manifest.js.map +1 -1
- package/dist/verification-plan.d.ts +24 -0
- package/dist/verification-plan.d.ts.map +1 -0
- package/dist/verification-plan.js +116 -0
- package/dist/verification-plan.js.map +1 -0
- package/dist/work-graph.d.ts.map +1 -1
- package/dist/work-graph.js +6 -3
- package/dist/work-graph.js.map +1 -1
- package/docs/examples.json +46 -4
- package/docs/llms-full.txt +1346 -28
- package/docs/types.json +4185 -87
- package/package.json +9 -9
- package/src/assure-hydration.ts +6 -1
- package/src/assure.ts +4 -2
- package/src/check-diagnostics.ts +1219 -0
- package/src/check-scan.ts +1825 -0
- package/src/check.ts +47 -2752
- package/src/cli.ts +252 -10
- package/src/command-catalog.ts +155 -0
- package/src/env-file.ts +5 -5
- package/src/frontend-guidance.ts +259 -0
- package/src/levels-tool.ts +6 -0
- package/src/load.ts +4 -1
- package/src/mcp-context.ts +266 -0
- package/src/mcp-docs-tools.ts +37 -0
- package/src/mcp-exec.ts +1040 -0
- package/src/mcp-http.ts +1 -1
- package/src/mcp-io.ts +118 -0
- package/src/mcp-reflect.ts +140 -0
- package/src/mcp-root.ts +62 -4
- package/src/mcp.ts +61 -1511
- package/src/openapi-tool.ts +32 -2
- package/src/openapi-types.ts +261 -0
- package/src/port.ts +2 -1
- package/src/project-facts.ts +2 -4
- package/src/release-verification.ts +22 -164
- package/src/rules/codes.ts +4 -0
- package/src/rules/islands.ts +171 -0
- package/src/rules/nano.ts +295 -0
- package/src/rules/security.ts +40 -4
- package/src/scaffold.ts +169 -9
- package/src/search-terms.ts +7 -3
- package/src/stylex-migrate.ts +1139 -0
- package/src/sync-manifest.ts +2 -1
- package/src/verification-plan.ts +242 -0
- package/src/work-graph.ts +6 -3
package/docs/llms-full.txt
CHANGED
|
@@ -958,15 +958,48 @@ function Row({ id }: { id: string }) {
|
|
|
958
958
|
const anyPending = useFetchers().some((f) => f.snapshot().pending)
|
|
959
959
|
```
|
|
960
960
|
|
|
961
|
-
## Nifra - Rendering: SSG & ISR
|
|
961
|
+
## Nifra - Rendering: SSR, streaming, SSG & ISR
|
|
962
962
|
|
|
963
|
-
>
|
|
963
|
+
> Render critical HTML first, stream deferred data progressively, prerender static routes, and cache rendered pages with stale-while-revalidate - on every runtime including the edge.
|
|
964
964
|
|
|
965
965
|
Nifra renders on one framework-agnostic seam, so the same app can be server-rendered per
|
|
966
|
-
request (the default), **prerendered** to static files at build (SSG), or cached and served
|
|
966
|
+
request (the default), streamed progressively, **prerendered** to static files at build (SSG), or cached and served
|
|
967
967
|
**stale-while-revalidate** (ISR) - and every strategy works on Bun, Node, Deno, **and**
|
|
968
968
|
the edge.
|
|
969
969
|
|
|
970
|
+
### Progressive rendering with `defer()`
|
|
971
|
+
|
|
972
|
+
Keep critical loader data in the first HTML shell and mark slower, non-critical values with
|
|
973
|
+
`defer()`. Nifra flushes the document shell and the adapter's rendered stream first,
|
|
974
|
+
then sends each deferred resolution through `<Await>` without a second data
|
|
975
|
+
fetch. The same protocol works for actions and soft navigations, including NDJSON on the client
|
|
976
|
+
side.
|
|
977
|
+
|
|
978
|
+
```ts
|
|
979
|
+
import { defer } from "@nifrajs/web"
|
|
980
|
+
|
|
981
|
+
export async function loader({ api }: LoaderArgs<typeof app>) {
|
|
982
|
+
return {
|
|
983
|
+
product: (await api.products.get()).data, // critical: rendered in the first shell
|
|
984
|
+
reviews: defer(api.reviews.get()), // non-critical: streamed when ready
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
export default function Product(props: { data: LoaderData<typeof loader> }) {
|
|
989
|
+
return (
|
|
990
|
+
<>
|
|
991
|
+
<ProductSummary product={props.data.product} />
|
|
992
|
+
<Await resolve={props.data.reviews} fallback={<p>Loading reviews…</p>}>
|
|
993
|
+
{(reviews) => <Reviews items={reviews} />}
|
|
994
|
+
</Await>
|
|
995
|
+
</>
|
|
996
|
+
)
|
|
997
|
+
}
|
|
998
|
+
```
|
|
999
|
+
|
|
1000
|
+
This is request-time progressive SSR/partial rendering. It is distinct from build-time SSG:
|
|
1001
|
+
the shell is not a precomputed PPR artifact, and deferred values remain request-scoped.
|
|
1002
|
+
|
|
970
1003
|
### SSG - prerender at build
|
|
971
1004
|
|
|
972
1005
|
Opt a static route into prerendering with `export const prerender = true`. Its
|
|
@@ -1225,6 +1258,374 @@ if (document.documentElement.hasAttribute("data-nifra-hydrated")) start()
|
|
|
1225
1258
|
else document.addEventListener("nifra:hydrated", start, { once: true })
|
|
1226
1259
|
```
|
|
1227
1260
|
|
|
1261
|
+
## Nifra - Islands: the AI-safe interactivity lane
|
|
1262
|
+
|
|
1263
|
+
> Add interactivity to a zero-runtime vanilla page with islands - imperative DOM enhancers, no framework runtime, no hydration. Explicit code an AI (or a human) gets right first try: mount, coordinate over a typed bus, always return cleanup.
|
|
1264
|
+
|
|
1265
|
+
A `@nifrajs/web-vanilla` page ships zero framework runtime. When one corner needs
|
|
1266
|
+
to be interactive, you don't turn on hydration - you mount an **island**: a
|
|
1267
|
+
small, plain-DOM enhancer over a server-rendered element. Explicit imperative code with no
|
|
1268
|
+
hidden reactivity - the shape an AI agent (or a human) gets right on the first try.
|
|
1269
|
+
|
|
1270
|
+
### Why islands, not hydration
|
|
1271
|
+
|
|
1272
|
+
Vanilla routes set `export const hydrate = false` - there is no client framework
|
|
1273
|
+
to hydrate with, and that is the point. The five framework adapters give you a reactive
|
|
1274
|
+
runtime and pay for it in client JS and in the subtle failure modes (stale closures,
|
|
1275
|
+
hydration mismatch, what-re-runs-when) that trip up generated code. Islands take the other
|
|
1276
|
+
trade: no runtime, no reactivity to get wrong. You wire the DOM by hand and hand back a
|
|
1277
|
+
teardown. Reach for a framework adapter when you genuinely need a stateful app UI; reach for
|
|
1278
|
+
islands for widgets on an otherwise-static page.
|
|
1279
|
+
|
|
1280
|
+
### Mount an island
|
|
1281
|
+
|
|
1282
|
+
Render a `<nifra-island>` marker in your page (props are inline JSON), then
|
|
1283
|
+
bundle one entry that calls `mountIslands`. Load it via the route's
|
|
1284
|
+
`islandScripts`.
|
|
1285
|
+
|
|
1286
|
+
```ts
|
|
1287
|
+
// doc-check: skip - server-rendered island marker (HTML, not a checkable module).
|
|
1288
|
+
// In your @nifrajs/web-vanilla page, render the host element with inline JSON props:
|
|
1289
|
+
html`<nifra-island data-id="counter" data-props=${JSON.stringify({ start: 0 })}>
|
|
1290
|
+
<output>0</output>
|
|
1291
|
+
<button type="button">+1</button>
|
|
1292
|
+
</nifra-island>`
|
|
1293
|
+
```
|
|
1294
|
+
|
|
1295
|
+
```ts
|
|
1296
|
+
// doc-check: skip - browser DOM enhancer, typechecked in @nifrajs/web under its DOM lib.
|
|
1297
|
+
import { defineIsland, mountIslands } from "@nifrajs/web/islands"
|
|
1298
|
+
|
|
1299
|
+
// defineIsland pins the data-props type; the body is plain imperative DOM. ALWAYS return the
|
|
1300
|
+
// teardown for anything you wire - mountIslands calls it on soft-nav (NF-C020 warns if you forget).
|
|
1301
|
+
const counter = defineIsland<{ start: number }>((el, props) => {
|
|
1302
|
+
let n = props.start
|
|
1303
|
+
const out = el.querySelector("output")!
|
|
1304
|
+
const onClick = () => { out.textContent = String(++n) }
|
|
1305
|
+
el.querySelector("button")?.addEventListener("click", onClick)
|
|
1306
|
+
return () => el.querySelector("button")?.removeEventListener("click", onClick)
|
|
1307
|
+
})
|
|
1308
|
+
|
|
1309
|
+
// One bundle entry, loaded via the route's `islandScripts`.
|
|
1310
|
+
mountIslands({ counter })
|
|
1311
|
+
```
|
|
1312
|
+
|
|
1313
|
+
`defineIsland<Props>` is a zero-cost identity helper - its only job is to
|
|
1314
|
+
type `props` and `el` so the body needs no cast. Keep the body
|
|
1315
|
+
imperative: read the DOM, add listeners, **return the cleanup**. The returned
|
|
1316
|
+
function runs on soft-nav teardown; forget it and every navigation leaks the listener -
|
|
1317
|
+
`nifra check` flags exactly that as `NF-C020`.
|
|
1318
|
+
|
|
1319
|
+
### Coordinate islands with a typed bus
|
|
1320
|
+
|
|
1321
|
+
Islands are isolated by design - each enhances one element and shares no state. When two must
|
|
1322
|
+
talk (an “add to cart” button and a cart badge), use a
|
|
1323
|
+
`createIslandBus`: one typed channel, created once and closed over by each
|
|
1324
|
+
enhancer. No implicit global, so concurrent renders and tests never cross-talk.
|
|
1325
|
+
|
|
1326
|
+
```ts
|
|
1327
|
+
import { createIslandBus } from "@nifrajs/web/islands"
|
|
1328
|
+
|
|
1329
|
+
// One typed channel, created once and closed over by every enhancer that needs it.
|
|
1330
|
+
type CartEvents = { "cart:add": { sku: string }; "cart:count": number }
|
|
1331
|
+
const bus = createIslandBus<CartEvents>()
|
|
1332
|
+
|
|
1333
|
+
const off = bus.on("cart:count", (n) => console.log("cart now has", n, "items"))
|
|
1334
|
+
bus.emit("cart:add", { sku: "ABC-1" })
|
|
1335
|
+
off() // unsubscribe - also usable directly as an island's cleanup
|
|
1336
|
+
```
|
|
1337
|
+
|
|
1338
|
+
The bus is synchronous, in-memory, and carries no history - a subscriber sees only events
|
|
1339
|
+
emitted after it subscribes. A throwing handler is isolated from the others. Because
|
|
1340
|
+
`on()` returns its own unsubscribe, an enhancer whose only job is to listen can
|
|
1341
|
+
return it directly as its cleanup:
|
|
1342
|
+
|
|
1343
|
+
```ts
|
|
1344
|
+
// doc-check: skip - browser DOM enhancer, typechecked in @nifrajs/web under its DOM lib.
|
|
1345
|
+
import { createIslandBus, defineIsland, mountIslands } from "@nifrajs/web/islands"
|
|
1346
|
+
|
|
1347
|
+
type CartEvents = { "cart:add": { sku: string }; "cart:count": number }
|
|
1348
|
+
const bus = createIslandBus<CartEvents>()
|
|
1349
|
+
|
|
1350
|
+
// Two islands that never import each other - they meet only on the bus.
|
|
1351
|
+
const addButton = defineIsland<{ sku: string }>((el, props) => {
|
|
1352
|
+
const onClick = () => bus.emit("cart:add", { sku: props.sku })
|
|
1353
|
+
el.addEventListener("click", onClick)
|
|
1354
|
+
return () => el.removeEventListener("click", onClick)
|
|
1355
|
+
})
|
|
1356
|
+
|
|
1357
|
+
let count = 0
|
|
1358
|
+
const badge = defineIsland((el) => {
|
|
1359
|
+
const unsubscribe = bus.on("cart:add", () => {
|
|
1360
|
+
count += 1
|
|
1361
|
+
el.textContent = String(count)
|
|
1362
|
+
bus.emit("cart:count", count)
|
|
1363
|
+
})
|
|
1364
|
+
return unsubscribe // the on() unsubscribe IS the cleanup
|
|
1365
|
+
})
|
|
1366
|
+
|
|
1367
|
+
mountIslands({ addButton, badge })
|
|
1368
|
+
```
|
|
1369
|
+
|
|
1370
|
+
### Pattern: filter drives results
|
|
1371
|
+
|
|
1372
|
+
The same shape scales to any “one island changes, another reacts” case. Each
|
|
1373
|
+
island owns only its own DOM; they meet on the channel, never in a shared store.
|
|
1374
|
+
|
|
1375
|
+
```ts
|
|
1376
|
+
// doc-check: skip - browser DOM enhancer, typechecked in @nifrajs/web under its DOM lib.
|
|
1377
|
+
import { createIslandBus, defineIsland, mountIslands } from "@nifrajs/web/islands"
|
|
1378
|
+
|
|
1379
|
+
// filter -> results, one directional channel. The results island owns its own DOM; the filter
|
|
1380
|
+
// island owns none of it. No shared store, no reactive tree - a message and two enhancers.
|
|
1381
|
+
const bus = createIslandBus<{ "filter:set": string }>()
|
|
1382
|
+
|
|
1383
|
+
const filter = defineIsland((el) => {
|
|
1384
|
+
const input = el.querySelector("input")!
|
|
1385
|
+
const onInput = () => bus.emit("filter:set", input.value.toLowerCase())
|
|
1386
|
+
input.addEventListener("input", onInput)
|
|
1387
|
+
return () => input.removeEventListener("input", onInput)
|
|
1388
|
+
})
|
|
1389
|
+
|
|
1390
|
+
const results = defineIsland((el) =>
|
|
1391
|
+
bus.on("filter:set", (q) => {
|
|
1392
|
+
for (const row of el.querySelectorAll<HTMLElement>("[data-name]")) {
|
|
1393
|
+
const name = row.dataset.name ?? ""
|
|
1394
|
+
row.hidden = q !== "" && !name.toLowerCase().includes(q)
|
|
1395
|
+
}
|
|
1396
|
+
}),
|
|
1397
|
+
)
|
|
1398
|
+
|
|
1399
|
+
mountIslands({ filter, results })
|
|
1400
|
+
```
|
|
1401
|
+
|
|
1402
|
+
### Load strategies
|
|
1403
|
+
|
|
1404
|
+
A marker's `data-strategy` defers its enhancer: `load` (default),
|
|
1405
|
+
`idle`, `visible` (mount when it scrolls into view), or a
|
|
1406
|
+
`media` query. An island with no matching enhancer, or an invalid strategy, stays
|
|
1407
|
+
inert server-rendered HTML - forward-compatible, never a runtime error.
|
|
1408
|
+
|
|
1409
|
+
## Nifra - nano: explicit reactivity for small apps
|
|
1410
|
+
|
|
1411
|
+
> nano is the AI-safe small-app lane: signal + computed(fn, [deps]) + keyed bindList, no VDOM, no auto-tracking. Every reactive edge is a visible call, so its three mistakes are static lints (NF-C021/C022/C023) with a fix recipe - the same closed loop that makes the backend AI-safe, now on the frontend.
|
|
1412
|
+
|
|
1413
|
+
`@nifrajs/web/nano` is the middle lane between a static
|
|
1414
|
+
[island](/docs/islands) and a full framework adapter. It gives you a signal, a
|
|
1415
|
+
derived `computed`, and a keyed list - enough to build a small app with local
|
|
1416
|
+
state a human edits - and nothing else. No virtual DOM, no template compiler, no
|
|
1417
|
+
auto-tracking. Every reactive edge is a call you write, which is exactly what lets a tool
|
|
1418
|
+
catch the mistakes before runtime.
|
|
1419
|
+
|
|
1420
|
+
### Why a fourth lane
|
|
1421
|
+
|
|
1422
|
+
A framework fails generated code not because it is unfamiliar but because its reactivity is
|
|
1423
|
+
_implicit_: an effect silently tracks what it read, a stale closure captures the wrong
|
|
1424
|
+
value, a render mismatches hydration - all silent, all runtime. Preact fixes the
|
|
1425
|
+
**size** of that model (3 KB) but copies its footguns faithfully. nano
|
|
1426
|
+
fixes the **failure model** for the small-app band: dependencies are an explicit
|
|
1427
|
+
array, list keys are a required argument, cleanups are a returned value. Each of those is a
|
|
1428
|
+
thing a static check can see. Reach for nano when a page needs local state and a keyed list;
|
|
1429
|
+
reach for a [framework adapter](/docs/frameworks) the moment you need client
|
|
1430
|
+
routing, nested view state, or suspense.
|
|
1431
|
+
|
|
1432
|
+
### Signals and computed
|
|
1433
|
+
|
|
1434
|
+
A `signal` holds a value; `.get()` reads it and `.set(...)`
|
|
1435
|
+
replaces it (deduped with `Object.is`). A `computed` derives a value and
|
|
1436
|
+
declares its sources as an explicit deps array - it recomputes when a listed source changes,
|
|
1437
|
+
never by magic. Both are synchronous and framework-free.
|
|
1438
|
+
|
|
1439
|
+
```ts
|
|
1440
|
+
import { signal, computed } from "@nifrajs/web/nano"
|
|
1441
|
+
|
|
1442
|
+
// State is a signal: reads are .get(), writes are .set(...). Every edge is a call you can see.
|
|
1443
|
+
const count = signal(0)
|
|
1444
|
+
|
|
1445
|
+
// Derived state declares its dependencies EXPLICITLY - the array is the whole contract. It
|
|
1446
|
+
// recomputes when (and only when) a listed source changes. Object.is-deduped, like signal.
|
|
1447
|
+
const doubled = computed(() => count.get() * 2, [count])
|
|
1448
|
+
|
|
1449
|
+
const off = doubled.subscribe((v) => console.log("doubled is now", v))
|
|
1450
|
+
count.set(5) // logs: doubled is now 10
|
|
1451
|
+
off() // unsubscribe
|
|
1452
|
+
```
|
|
1453
|
+
|
|
1454
|
+
The deps array is the whole contract, and its one failure mode is catchable: a
|
|
1455
|
+
`computed` whose body reads a signal the array omits will never recompute when that
|
|
1456
|
+
signal changes. `nifra check` flags exactly that as `NF-C023` - the
|
|
1457
|
+
check reads which signals the body calls `.get()` on and compares them to the
|
|
1458
|
+
array. A framework's auto-tracked effect gives a tool nothing to compare, which is why
|
|
1459
|
+
the equivalent lint elsewhere is a best-effort warning, not a gate.
|
|
1460
|
+
|
|
1461
|
+
### Bind a signal to the DOM
|
|
1462
|
+
|
|
1463
|
+
`bind` is the one-value edge: it applies your function immediately and on every
|
|
1464
|
+
change, and returns a disposer. **Collect the disposer.** A bare
|
|
1465
|
+
`bind(...)` whose return value is discarded leaks its subscription on soft-nav -
|
|
1466
|
+
`nifra check` flags it as `NF-C021`.
|
|
1467
|
+
|
|
1468
|
+
```ts
|
|
1469
|
+
// doc-check: skip - browser DOM enhancer, typechecked in @nifrajs/web under its DOM lib.
|
|
1470
|
+
import { signal, bind } from "@nifrajs/web/nano"
|
|
1471
|
+
|
|
1472
|
+
const label = signal("hello")
|
|
1473
|
+
|
|
1474
|
+
// bind applies immediately AND on every change; it returns the disposer. COLLECT it - a bare
|
|
1475
|
+
// bind(...) that drops its return leaks the subscription on soft-nav (nifra check flags NF-C021).
|
|
1476
|
+
const off = bind(document.querySelector("h1")!, label, (el, v) => { el.textContent = v })
|
|
1477
|
+
label.set("world") // the <h1> updates synchronously
|
|
1478
|
+
// ...on teardown: off()
|
|
1479
|
+
```
|
|
1480
|
+
|
|
1481
|
+
### Keyed lists with bindList
|
|
1482
|
+
|
|
1483
|
+
`bindList` keeps a container's children in sync with an array by key - a keyed
|
|
1484
|
+
reconcile like a framework's list diff, but you spell the key out. Add, remove, and
|
|
1485
|
+
reorder reuse the matching node (preserving focus and scroll) instead of rebuilding the list.
|
|
1486
|
+
Key by a **stable id** on the item; keying by the array index reuses the wrong
|
|
1487
|
+
node on reorder, and `nifra check` flags it as `NF-C022`.
|
|
1488
|
+
|
|
1489
|
+
```ts
|
|
1490
|
+
// doc-check: skip - browser DOM enhancer, typechecked in @nifrajs/web under its DOM lib.
|
|
1491
|
+
import { signal, bindList } from "@nifrajs/web/nano"
|
|
1492
|
+
|
|
1493
|
+
interface Todo { id: string; text: string; done: boolean }
|
|
1494
|
+
const todos = signal<Todo[]>([])
|
|
1495
|
+
|
|
1496
|
+
// bindList keeps a container's children in sync with an array by KEY - a keyed reconcile, like a
|
|
1497
|
+
// framework's list diff, but explicit. Add/remove/reorder reuse the right node instead of rebuilding.
|
|
1498
|
+
const off = bindList(todos, document.querySelector("ul")!, {
|
|
1499
|
+
key: (t) => t.id, // a STABLE id on the item. Keying by the array index is NF-C022 - reorder breaks.
|
|
1500
|
+
create: (t) => { const li = document.createElement("li"); li.dataset.id = t.id; return li },
|
|
1501
|
+
update: (li, t) => { li.textContent = t.text; li.classList.toggle("done", t.done) },
|
|
1502
|
+
})
|
|
1503
|
+
|
|
1504
|
+
todos.set([...todos.get(), { id: crypto.randomUUID(), text: "buy milk", done: false }])
|
|
1505
|
+
// ...on teardown: off()
|
|
1506
|
+
```
|
|
1507
|
+
|
|
1508
|
+
### Async state with resource
|
|
1509
|
+
|
|
1510
|
+
`resource(fetcher, [deps])` is nano's answer to “suspense” - an
|
|
1511
|
+
async cell whose value is an explicit `{ status, value, error }` union.
|
|
1512
|
+
It runs the fetcher immediately and again whenever a declared dep changes, and it handles the
|
|
1513
|
+
two things people get wrong by hand: the fetcher receives an `AbortSignal`, and a
|
|
1514
|
+
superseded request is aborted with its late result dropped, so the newest fetch always wins -
|
|
1515
|
+
no stale-response flicker. There is no thrown promise and no magic boundary; it is a value you
|
|
1516
|
+
read or bind like any other.
|
|
1517
|
+
|
|
1518
|
+
```ts
|
|
1519
|
+
import { signal, resource } from "@nifrajs/web/nano"
|
|
1520
|
+
|
|
1521
|
+
const userId = signal(1)
|
|
1522
|
+
|
|
1523
|
+
// resource(fetcher, [deps]) is an async cell: it fetches immediately and again whenever a declared
|
|
1524
|
+
// dep changes. The fetcher gets an AbortSignal; a superseded fetch is aborted and its late result
|
|
1525
|
+
// dropped, so the newest request always wins - no stale-response flicker to hand-guard.
|
|
1526
|
+
const user = resource(async (sig) => {
|
|
1527
|
+
const res = await fetch(`/api/users/${userId.get()}`, { signal: sig })
|
|
1528
|
+
return (await res.json()) as { name: string }
|
|
1529
|
+
}, [userId])
|
|
1530
|
+
|
|
1531
|
+
// The value is an explicit union - status is "pending" | "error" | "ready", never a secret undefined.
|
|
1532
|
+
const off = user.subscribe((s) => {
|
|
1533
|
+
if (s.status === "ready") console.log("got", s.value.name)
|
|
1534
|
+
})
|
|
1535
|
+
userId.set(2) // refetches; the deps array is what NF-C023 checks against the fetcher's .get() reads
|
|
1536
|
+
// ...on teardown: off()
|
|
1537
|
+
```
|
|
1538
|
+
|
|
1539
|
+
The deps array is checked exactly like `computed`: a `resource` whose
|
|
1540
|
+
fetcher reads a signal the array omits won't refetch when it changes, and
|
|
1541
|
+
`nifra check` flags it as `NF-C023`. Bind it to the DOM with
|
|
1542
|
+
`bindResource`, which dispatches on `status` - one handler per state,
|
|
1543
|
+
`ready` required, so a still-loading value can never render as a stray
|
|
1544
|
+
`undefined`.
|
|
1545
|
+
|
|
1546
|
+
```ts
|
|
1547
|
+
// doc-check: skip - browser DOM enhancer, typechecked in @nifrajs/web under its DOM lib.
|
|
1548
|
+
import { signal, resource, bindResource } from "@nifrajs/web/nano"
|
|
1549
|
+
|
|
1550
|
+
const userId = signal(1)
|
|
1551
|
+
const user = resource(async (sig) => {
|
|
1552
|
+
const res = await fetch(`/api/users/${userId.get()}`, { signal: sig })
|
|
1553
|
+
return (await res.json()) as { name: string }
|
|
1554
|
+
}, [userId])
|
|
1555
|
+
|
|
1556
|
+
// bindResource dispatches on status - one handler per state, ready required. Like bind it returns a
|
|
1557
|
+
// disposer (a bare bindResource(...) that drops it is NF-C021).
|
|
1558
|
+
const off = bindResource(document.querySelector("[data-user]")!, user, {
|
|
1559
|
+
pending: (el) => { el.textContent = "Loading…" },
|
|
1560
|
+
ready: (el, u) => { el.textContent = u.name },
|
|
1561
|
+
error: (el) => { el.textContent = "Could not load user" },
|
|
1562
|
+
})
|
|
1563
|
+
// ...on teardown: off()
|
|
1564
|
+
```
|
|
1565
|
+
|
|
1566
|
+
### nano inside an island
|
|
1567
|
+
|
|
1568
|
+
nano owns state and DOM edges; an [island](/docs/islands) owns mount and teardown.
|
|
1569
|
+
Put the signals in the enhancer, collect every disposer, and return one cleanup that calls
|
|
1570
|
+
them all. Scaffold this shape with
|
|
1571
|
+
`nifra_scaffold { path, variant: "stateful" }` on a vanilla
|
|
1572
|
+
project - it emits the golden pattern below.
|
|
1573
|
+
|
|
1574
|
+
```ts
|
|
1575
|
+
// doc-check: skip - browser DOM enhancer, typechecked in @nifrajs/web under its DOM lib.
|
|
1576
|
+
import { defineIsland, mountIslands } from "@nifrajs/web/islands"
|
|
1577
|
+
import { signal, computed, bind, bindList } from "@nifrajs/web/nano"
|
|
1578
|
+
|
|
1579
|
+
interface Todo { id: string; text: string; done: boolean }
|
|
1580
|
+
|
|
1581
|
+
// nano lives INSIDE an island - the island owns mount/teardown, nano owns the state and the DOM edges.
|
|
1582
|
+
const todos = defineIsland<{ items: Todo[] }>((el, props) => {
|
|
1583
|
+
const items = signal<Todo[]>(props.items)
|
|
1584
|
+
const remaining = computed(() => items.get().filter((t) => !t.done).length, [items])
|
|
1585
|
+
|
|
1586
|
+
// Collect every disposer; the island's cleanup calls them all (this is what NF-C021 protects).
|
|
1587
|
+
const cleanups: Array<() => void> = []
|
|
1588
|
+
cleanups.push(bind(el.querySelector("[data-count]")!, remaining, (n, v) => {
|
|
1589
|
+
n.textContent = String(v) + " left"
|
|
1590
|
+
}))
|
|
1591
|
+
cleanups.push(bindList(items, el.querySelector("[data-list]")!, {
|
|
1592
|
+
key: (t) => t.id,
|
|
1593
|
+
create: (t) => { const li = document.createElement("li"); li.dataset.id = t.id; return li },
|
|
1594
|
+
update: (li, t) => { li.textContent = t.text; li.classList.toggle("done", t.done) },
|
|
1595
|
+
}))
|
|
1596
|
+
|
|
1597
|
+
const add = (text: string) =>
|
|
1598
|
+
items.set([...items.get(), { id: crypto.randomUUID(), text, done: false }])
|
|
1599
|
+
void add
|
|
1600
|
+
|
|
1601
|
+
return () => { for (const off of cleanups) off() }
|
|
1602
|
+
})
|
|
1603
|
+
|
|
1604
|
+
mountIslands({ todos })
|
|
1605
|
+
```
|
|
1606
|
+
|
|
1607
|
+
### The three checks
|
|
1608
|
+
|
|
1609
|
+
nano's explicitness is the whole point: because each reactive edge is a visible call, its
|
|
1610
|
+
three mistakes are static lints with a fix recipe - the same closed loop (`scaffold`
|
|
1611
|
+
→ `check` → `fix` → `verify`) that makes the
|
|
1612
|
+
backend AI-safe, now on the frontend.
|
|
1613
|
+
|
|
1614
|
+
-
|
|
1615
|
+
`NF-C021` - a `bind`/`bindList` whose disposer is
|
|
1616
|
+
discarded. Collect it; call it on teardown.
|
|
1617
|
+
|
|
1618
|
+
-
|
|
1619
|
+
`NF-C022` - a `bindList` keyed by the array index. Key by a stable id.
|
|
1620
|
+
|
|
1621
|
+
-
|
|
1622
|
+
`NF-C023` - a `computed` that reads a signal its deps omit. Add it to
|
|
1623
|
+
the deps array.
|
|
1624
|
+
|
|
1625
|
+
All three _warn_ - a false positive must never fail a build - and each carries a fix
|
|
1626
|
+
recipe an agent can apply. Where nano stops (client routing, nested views, suspense), stop
|
|
1627
|
+
adding nano and reach for `@nifrajs/web-preact` or another framework adapter.
|
|
1628
|
+
|
|
1228
1629
|
## Nifra - Streaming
|
|
1229
1630
|
|
|
1230
1631
|
> Streaming SSR, Suspense, and defer() in Nifra - on every runtime including the edge.
|
|
@@ -2967,6 +3368,7 @@ const image = createImageHandler({
|
|
|
2967
3368
|
root: "./public", // local sources resolve under here (traversal+symlink guarded)
|
|
2968
3369
|
allowedOrigins: ["https://cdn.example"], // remote sources: allowlist only (omit ⇒ none)
|
|
2969
3370
|
// maxWidth, maxSourceBytes, maxSourcePixels, concurrency, cacheMaxAge - all tunable
|
|
3371
|
+
// immutable: true, // only for content-versioned source URLs
|
|
2970
3372
|
})
|
|
2971
3373
|
|
|
2972
3374
|
// mount it in your router:
|
|
@@ -2989,9 +3391,10 @@ probe), and a concurrency semaphore bounding the CPU-heavy codec work.
|
|
|
2989
3391
|
|
|
2990
3392
|
-
|
|
2991
3393
|
**Correct + cacheable.** Never upscales past the intrinsic width; negotiates WebP via
|
|
2992
|
-
`Accept` (with `Vary: Accept`);
|
|
2993
|
-
`
|
|
2994
|
-
|
|
3394
|
+
`Accept` (with `Vary: Accept`); and hashes the emitted bytes for a strong
|
|
3395
|
+
`ETag`, so a changed source at the same URL cannot receive a false `304`.
|
|
3396
|
+
The mutable-safe default is a one-hour `max-age`; opt into `immutable` only
|
|
3397
|
+
when every source URL is content-versioned.
|
|
2995
3398
|
|
|
2996
3399
|
The handler reads the filesystem, so its _local-source_ path targets **Node/Bun servers**
|
|
2997
3400
|
- but the codec itself is a pluggable `ImageBackend`, so it runs anywhere (see below).
|
|
@@ -3819,6 +4222,48 @@ export const vitePlugins = [react()] // dev HMR (Fast Refresh)
|
|
|
3819
4222
|
// define = { __VUE_OPTIONS_API__: "true", ... } // Vue feature flags
|
|
3820
4223
|
```
|
|
3821
4224
|
|
|
4225
|
+
### Tailwind to StyleX
|
|
4226
|
+
|
|
4227
|
+
Nifra includes a conservative codemod for moving static Tailwind classes to StyleX. It is a dry
|
|
4228
|
+
run by default, so inspect the proposed edits first:
|
|
4229
|
+
|
|
4230
|
+
Supported static `className` attributes become `stylex.props(...)` calls
|
|
4231
|
+
backed by a local `stylex.create(...)` table. Responsive breakpoints and
|
|
4232
|
+
element-local pseudo-classes such as `hover:` are supported. Dynamic class
|
|
4233
|
+
expressions, arbitrary values, parent-dependent variants, and unknown utilities stay unchanged
|
|
4234
|
+
and are reported with file/line evidence. A non-zero exit status means manual migration issues
|
|
4235
|
+
remain.
|
|
4236
|
+
|
|
4237
|
+
StyleX compilation is native to Nifra's Bun pipeline. Install the runtime and compiler peers,
|
|
4238
|
+
then register both the browser and SSR transforms:
|
|
4239
|
+
|
|
4240
|
+
```ts
|
|
4241
|
+
# Install the runtime and the optional compiler peers.
|
|
4242
|
+
bun add @stylexjs/stylex
|
|
4243
|
+
bun add -d @babel/core @stylexjs/babel-plugin @babel/plugin-syntax-flow \
|
|
4244
|
+
@babel/plugin-syntax-jsx @babel/plugin-syntax-typescript
|
|
4245
|
+
```
|
|
4246
|
+
|
|
4247
|
+
```ts
|
|
4248
|
+
// nifra.config.ts - Bun's client and SSR build transforms.
|
|
4249
|
+
import { stylexBunPlugin } from "@nifrajs/web/plugins/stylex"
|
|
4250
|
+
|
|
4251
|
+
export const clientPlugins = [stylexBunPlugin("dom")]
|
|
4252
|
+
export const serverPlugins = [stylexBunPlugin("ssr")]
|
|
4253
|
+
```
|
|
4254
|
+
|
|
4255
|
+
If the project intentionally uses Vite, add the Vite adapter alongside its existing Vite
|
|
4256
|
+
transforms. Nifra will use Vite when `vitePlugins` are the app's only transforms:
|
|
4257
|
+
|
|
4258
|
+
```ts
|
|
4259
|
+
// doc-check: skip - requires the third-party Vite React plugin
|
|
4260
|
+
// If the app intentionally uses Vite, keep StyleX in vitePlugins.
|
|
4261
|
+
import react from "@vitejs/plugin-react"
|
|
4262
|
+
import { stylexVite } from "@nifrajs/web/plugins/stylex"
|
|
4263
|
+
|
|
4264
|
+
export const vitePlugins = [react(), stylexVite()]
|
|
4265
|
+
```
|
|
4266
|
+
|
|
3822
4267
|
### Scope
|
|
3823
4268
|
|
|
3824
4269
|
`nifra build` defaults to a self-hosted Bun server. Use `--target node`,
|
|
@@ -3828,7 +4273,7 @@ the command printed by the build.
|
|
|
3828
4273
|
|
|
3829
4274
|
## Nifra - Coding agents
|
|
3830
4275
|
|
|
3831
|
-
>
|
|
4276
|
+
> Nifra's agent layer: live MCP tools, bounded repairable turns, native approvals, resumable evidence, content-free browser views, capability registry, decision inbox, Run Studio, A2A, and AG-UI.
|
|
3832
4277
|
|
|
3833
4278
|
Nifra ships an MCP server. It is not a documentation lookup bolted onto a framework: an agent
|
|
3834
4279
|
can read the project, learn the real API, run actual requests against the backend it just
|
|
@@ -3912,6 +4357,8 @@ nifra_check # typecheck + lints, each with a structured fix
|
|
|
3912
4357
|
nifra_fix # applies the mechanical ones
|
|
3913
4358
|
nifra_run {request} # a real request through the backend: status, headers, parsed body
|
|
3914
4359
|
nifra_render {path} # SSR a page route, returns the HTML
|
|
4360
|
+
nifra_inspect {port} # recent dev-server request traces: status, duration, ISR hit/miss
|
|
4361
|
+
nifra_explain {error} # turn a failure into a structured diagnostic and fix
|
|
3915
4362
|
nifra_test # bun test, bounded structured results
|
|
3916
4363
|
|
|
3917
4364
|
# 4. What does it now prove?
|
|
@@ -3993,8 +4440,8 @@ nifra levels --min 1
|
|
|
3993
4440
|
|
|
3994
4441
|
### Building agent features, not just serving them
|
|
3995
4442
|
|
|
3996
|
-
The tools above let an agent work on your app.
|
|
3997
|
-
the app you are building is itself an AI feature.
|
|
4443
|
+
The tools above let an agent work on your app. Nifra also provides provider-neutral building
|
|
4444
|
+
blocks for the opposite case, where the app you are building is itself an AI feature.
|
|
3998
4445
|
|
|
3999
4446
|
**
|
|
4000
4447
|
`@nifrajs/prompt`
|
|
@@ -4036,6 +4483,139 @@ serves a SQLite database as its own MCP server, fail-closed: allowlisted schema
|
|
|
4036
4483
|
default, and read-only queries only when you opt in, with plan verification. Handing a model a
|
|
4037
4484
|
database connection is not the same as handing it a query tool, and this is the second one.
|
|
4038
4485
|
|
|
4486
|
+
### Run a coding agent
|
|
4487
|
+
|
|
4488
|
+
`@nifrajs/agent-protocol` is the small versioned session and event contract.
|
|
4489
|
+
`@nifrajs/coding-agent` provides the standalone `nifra-agent` host with
|
|
4490
|
+
bounded sessions, checkpoints, workflows, extensions, verification, and authenticated local
|
|
4491
|
+
RPC. `@nifrajs/pi` is an optional Pi backend; other backends implement the same
|
|
4492
|
+
protocol port.
|
|
4493
|
+
|
|
4494
|
+
```ts
|
|
4495
|
+
bun add @nifrajs/coding-agent @nifrajs/pi
|
|
4496
|
+
|
|
4497
|
+
# Interactive, one-shot, JSON, and local RPC modes are available.
|
|
4498
|
+
bunx nifra-agent --backend pi
|
|
4499
|
+
bunx nifra-agent --backend pi --message "run the checks and explain failures"
|
|
4500
|
+
```
|
|
4501
|
+
|
|
4502
|
+
The public host keeps live queues and captured evidence bounded, filters verification process
|
|
4503
|
+
environments, and treats extensions as an explicit opt-in. Post-turn `check`,
|
|
4504
|
+
`assure`, or `test` gates emit `verification.completed` and
|
|
4505
|
+
`repair.required`; when enabled, the host sends a bounded repair prompt and reruns
|
|
4506
|
+
the gate until it passes or the attempt cap is reached. The local process adapter and extension
|
|
4507
|
+
worker are crash-containment helpers, not hostile-code sandboxes.
|
|
4508
|
+
|
|
4509
|
+
```ts
|
|
4510
|
+
# Post-turn gates are opt-in. A failed gate becomes bounded repair work.
|
|
4511
|
+
bunx nifra-agent --backend pi --message "implement the change" \
|
|
4512
|
+
--verify-after-turn check,assure --max-repair-attempts 2
|
|
4513
|
+
|
|
4514
|
+
# Set --max-repair-attempts 0 for observe-only verification.
|
|
4515
|
+
```
|
|
4516
|
+
|
|
4517
|
+
### Native approval protocol
|
|
4518
|
+
|
|
4519
|
+
`@nifrajs/coding-agent` can pause a native tool call at the decision boundary and
|
|
4520
|
+
emit `approval.required` with an opaque approval id, action, capability, and bounded
|
|
4521
|
+
coordinates. Resolve it through the host or RPC with `approval.resolve`; the backend
|
|
4522
|
+
emits `approval.resolved` and only then executes the tool. Denial, cancellation,
|
|
4523
|
+
timeout, and closed sessions all fail closed, and `approvalTimeoutMs` bounds how long
|
|
4524
|
+
a pending decision can remain open.
|
|
4525
|
+
|
|
4526
|
+
### Expose the same agent to other clients
|
|
4527
|
+
|
|
4528
|
+
`@nifrajs/a2a` mounts an A2A 1.0 card and JSON-RPC/SSE binding.
|
|
4529
|
+
`@nifrajs/ag-ui` mounts the AG-UI event stream. Both drive the same bounded runner,
|
|
4530
|
+
compose step evidence with telemetry, and support typed human-in-the-loop continuation. Model
|
|
4531
|
+
ports, state stores, capabilities, and approval transports are injected per request.
|
|
4532
|
+
|
|
4533
|
+
```ts
|
|
4534
|
+
import { server } from "@nifrajs/core"
|
|
4535
|
+
import { mountA2A } from "@nifrajs/a2a"
|
|
4536
|
+
import { mountAgUI } from "@nifrajs/ag-ui"
|
|
4537
|
+
import type { AgentPorts } from "@nifrajs/agent"
|
|
4538
|
+
import { agent } from "./agent"
|
|
4539
|
+
|
|
4540
|
+
declare const myModelPort: AgentPorts["model"]
|
|
4541
|
+
declare const myStateStore: NonNullable<AgentPorts["state"]>
|
|
4542
|
+
|
|
4543
|
+
const app = server()
|
|
4544
|
+
const ports = () => ({
|
|
4545
|
+
model: myModelPort,
|
|
4546
|
+
capabilities: ["search.read"],
|
|
4547
|
+
state: myStateStore, // scope this to the request subject
|
|
4548
|
+
})
|
|
4549
|
+
|
|
4550
|
+
mountA2A(app, {
|
|
4551
|
+
agent,
|
|
4552
|
+
card: { url: "https://api.example.com/a2a", version: "1.0.0" },
|
|
4553
|
+
ports,
|
|
4554
|
+
})
|
|
4555
|
+
mountAgUI(app, { agent, ports })
|
|
4556
|
+
|
|
4557
|
+
// A2A: GET the card, POST JSON-RPC, optional SSE streaming.
|
|
4558
|
+
// AG-UI: POST RunAgentInput, receive the event stream over SSE.
|
|
4559
|
+
```
|
|
4560
|
+
|
|
4561
|
+
These mounts deliberately do not authenticate callers: put the route behind your application's
|
|
4562
|
+
auth and authorization middleware, and scope every injected port to the request subject.
|
|
4563
|
+
|
|
4564
|
+
### Browser views and the Workbench
|
|
4565
|
+
|
|
4566
|
+
`@nifrajs/agent-app` is a backend-free browser SDK for negotiated commands, ordered
|
|
4567
|
+
and resumable event streams, approvals, handoffs, and Run Studio projections. It negotiates
|
|
4568
|
+
optional features including `approvals`, `checkpoint`,
|
|
4569
|
+
`fork`, `handoff`, `inbox`, `reload`,
|
|
4570
|
+
`resume`, and `workflows`, so a browser can degrade deliberately when a
|
|
4571
|
+
host does not offer one. Its public views contain structure - statuses, counters, coordinates,
|
|
4572
|
+
and error codes - rather than prompts, tool payloads, model output, or filesystem paths. The
|
|
4573
|
+
optional Workbench uses that same surface: run
|
|
4574
|
+
`bun run --filter '@nifrajs/workbench' dev -- --cwd /path/to/project` for the local
|
|
4575
|
+
browser client.
|
|
4576
|
+
|
|
4577
|
+
```ts
|
|
4578
|
+
import { AgentAppClient, HttpAgentTransport } from "@nifrajs/agent-app"
|
|
4579
|
+
|
|
4580
|
+
declare function currentToken(): string
|
|
4581
|
+
declare function render(view: unknown): void
|
|
4582
|
+
|
|
4583
|
+
const client = new AgentAppClient(new HttpAgentTransport({
|
|
4584
|
+
endpoint: "http://127.0.0.1:8787",
|
|
4585
|
+
authorize: () => currentToken(), // minted per request; never stored by the transport
|
|
4586
|
+
}))
|
|
4587
|
+
|
|
4588
|
+
const session = await client.createSession()
|
|
4589
|
+
for await (const view of client.send("summarize the diff")) {
|
|
4590
|
+
render(view) // content-free status, counts, coordinates, and error codes
|
|
4591
|
+
}
|
|
4592
|
+
```
|
|
4593
|
+
|
|
4594
|
+
### Capability registry, decision inbox, and Run Studio
|
|
4595
|
+
|
|
4596
|
+
The Workbench's `registry.list` view shows content-free identity cards for admitted
|
|
4597
|
+
capabilities: kind, name, version, schema digest, required capability tokens, and approval,
|
|
4598
|
+
retry, idempotency, and isolation classes. It never renders a prompt, input schema, tool
|
|
4599
|
+
payload, model output, or filesystem path.
|
|
4600
|
+
|
|
4601
|
+
The `inbox` feature lists pending approval and handoff boundaries by exact structural
|
|
4602
|
+
coordinate - run, node, capability, child vector, request id, and expiry. Every approve, deny,
|
|
4603
|
+
assign, resolve, or cancel command carries that coordinate, so stale, mismatched, or expired
|
|
4604
|
+
decisions are refused by the host. `run.studio` projects the same bounded evidence
|
|
4605
|
+
into a run graph, retry/recovery timeline, eval comparison, and deterministic fault-injection
|
|
4606
|
+
view. These are presentation-safe views: content stays in the host.
|
|
4607
|
+
|
|
4608
|
+
### Evidence, streaming, and telemetry
|
|
4609
|
+
|
|
4610
|
+
`@nifrajs/agent` runs bounded typed turns with tool contracts, budgets, approvals,
|
|
4611
|
+
resumable token-only evidence, model deltas, and a transient shared-state channel. Add an
|
|
4612
|
+
`evidenceLog` to the HTTP seams for SSE replay after a dropped connection; replay
|
|
4613
|
+
resumes evidence and never re-executes the turn. The additive run-lifecycle contract supplies
|
|
4614
|
+
content-free snapshots, ordered evidence refs, feature negotiation, handoff state, and cursor
|
|
4615
|
+
resume. `@nifrajs/agent-telemetry` converts the same constrained evidence into
|
|
4616
|
+
fail-open OpenTelemetry run and step spans. Providers, credentials, durable storage, retention,
|
|
4617
|
+
and tenant policy remain application-owned ports.
|
|
4618
|
+
|
|
4039
4619
|
### Projects without a web config
|
|
4040
4620
|
|
|
4041
4621
|
A backend-only project - the shape `create-nifra`'s default template produces - has
|
|
@@ -7457,21 +8037,41 @@ isolated fixtures and a test database. Never point a contract laboratory at prod
|
|
|
7457
8037
|
|
|
7458
8038
|
## Nifra - Types-first architecture
|
|
7459
8039
|
|
|
7460
|
-
>
|
|
8040
|
+
> Nifra infers route types from path literals and handlers automatically, with optional Standard Schemas for validation, explicit contracts, OpenAPI, and agent-readable APIs.
|
|
8041
|
+
|
|
8042
|
+
Nifra starts with automatic inference. A route's path literal, handler context, and return
|
|
8043
|
+
value produce its TypeScript surface; add a Standard Schema when you need runtime validation,
|
|
8044
|
+
coercion, or an explicit request/response contract. The same server type then drives the
|
|
8045
|
+
no-codegen client and the agent-readable API surface.
|
|
8046
|
+
|
|
8047
|
+
### Inline inference first
|
|
8048
|
+
|
|
8049
|
+
The chainable builder is fully type-inferred. Path parameters are parsed from the route
|
|
8050
|
+
pattern, handler context is typed automatically, and plain return values become the success
|
|
8051
|
+
response seen by the client. This is the quick-start style, similar to Elysia's inline route
|
|
8052
|
+
inference.
|
|
7461
8053
|
|
|
7462
|
-
|
|
7463
|
-
|
|
7464
|
-
|
|
8054
|
+
```ts
|
|
8055
|
+
import { server } from "@nifrajs/core/server"
|
|
8056
|
+
|
|
8057
|
+
export const app = server()
|
|
8058
|
+
.get("/users/:id", (c) => ({ id: c.params.id, name: "Ada" }))
|
|
8059
|
+
// c.params.id is inferred from the path; the return type becomes the client response.
|
|
8060
|
+
.post("/users", () => ({ created: true }))
|
|
8061
|
+
|
|
8062
|
+
// No schema, annotation, or codegen is required for the route types.
|
|
8063
|
+
```
|
|
7465
8064
|
|
|
7466
|
-
###
|
|
8065
|
+
### Schemas at the trust boundary
|
|
7467
8066
|
|
|
7468
|
-
|
|
7469
|
-
|
|
8067
|
+
Attach a Standard Schema when inputs must be validated before the handler runs, or when you
|
|
8068
|
+
want an explicit response contract. Path params are already inferred from `:id`;
|
|
8069
|
+
the `params` schema below adds runtime constraints/coercion as well.
|
|
7470
8070
|
|
|
7471
8071
|
```ts
|
|
7472
8072
|
import { t } from "@nifrajs/schema"
|
|
7473
8073
|
|
|
7474
|
-
//
|
|
8074
|
+
// Add a schema when the boundary needs runtime validation or a declared contract.
|
|
7475
8075
|
export const GetUser = {
|
|
7476
8076
|
params: t.object({ id: t.string() }),
|
|
7477
8077
|
response: t.object({
|
|
@@ -7501,9 +8101,10 @@ export const app = server().get("/users/:id", GetUser, (c) => {
|
|
|
7501
8101
|
|
|
7502
8102
|
### Inferred types
|
|
7503
8103
|
|
|
7504
|
-
|
|
7505
|
-
|
|
7506
|
-
|
|
8104
|
+
Without a schema, `c.params.id` is still `string` and the handler return
|
|
8105
|
+
is captured automatically. With a schema, its output types the handler and its declared
|
|
8106
|
+
`response` constrains what the handler may return. Change either the route or the
|
|
8107
|
+
contract and the typed client follows at compile time.
|
|
7507
8108
|
|
|
7508
8109
|
### The typed client
|
|
7509
8110
|
|
|
@@ -7525,6 +8126,16 @@ if (res.ok) {
|
|
|
7525
8126
|
}
|
|
7526
8127
|
```
|
|
7527
8128
|
|
|
8129
|
+
### Contract-first when the surface must be separate
|
|
8130
|
+
|
|
8131
|
+
Inline inference is the default. If the API needs to be shared, versioned, or implemented by
|
|
8132
|
+
more than one service, declare it with `defineContract` and connect handlers with
|
|
8133
|
+
`implement`. That keeps the contract type available without importing a server
|
|
8134
|
+
implementation into the client.
|
|
8135
|
+
|
|
8136
|
+
See [Framework contract](/docs/contract) for the decoupled form and its scaling
|
|
8137
|
+
guidance.
|
|
8138
|
+
|
|
7528
8139
|
### OpenAPI
|
|
7529
8140
|
|
|
7530
8141
|
The `openapi()` middleware builds an OpenAPI 3.1 document from your registered
|
|
@@ -7674,6 +8285,222 @@ level that regressed comes back with the reason it broke.
|
|
|
7674
8285
|
|
|
7675
8286
|
# Package reference (READMEs)
|
|
7676
8287
|
|
|
8288
|
+
## @nifrajs/a2a
|
|
8289
|
+
|
|
8290
|
+
Mount a nifra agent as an [Agent2Agent (A2A)](https://a2a-protocol.org) protocol server. The agent card is served on GET, the A2A 1.0 JSON-RPC binding on POST: `SendMessage` runs one bounded agent turn, `SendStreamingMessage` streams step evidence over SSE, `GetTask` projects the stored turn state.
|
|
8291
|
+
|
|
8292
|
+
A protocol bridge over [`@nifrajs/agent`](../agent) - the request body reuses core's single bounded, prototype-guarded trust boundary, and the model, durable state store, and approval transport are injected per request through the same `ports` factory `mountAgent` uses. Dependency-free beyond the two nifra peers.
|
|
8293
|
+
|
|
8294
|
+
## Install
|
|
8295
|
+
|
|
8296
|
+
```bash
|
|
8297
|
+
bun add @nifrajs/a2a @nifrajs/agent
|
|
8298
|
+
```
|
|
8299
|
+
|
|
8300
|
+
## Mount
|
|
8301
|
+
|
|
8302
|
+
```ts
|
|
8303
|
+
import { server } from "@nifrajs/core"
|
|
8304
|
+
import { mountA2A } from "@nifrajs/a2a"
|
|
8305
|
+
import { agent } from "./agent" // an AgentDefinition
|
|
8306
|
+
|
|
8307
|
+
const app = server()
|
|
8308
|
+
mountA2A(app, {
|
|
8309
|
+
agent,
|
|
8310
|
+
card: { url: "https://api.example.com/a2a", version: "1.0.0" },
|
|
8311
|
+
ports: (c) => ({
|
|
8312
|
+
model: myModelPort, // scope to the request subject
|
|
8313
|
+
capabilities: ["search.read"],
|
|
8314
|
+
state: myStateStore, // required for GetTask and resume
|
|
8315
|
+
}),
|
|
8316
|
+
})
|
|
8317
|
+
// GET /.well-known/agent-card.json - the agent card
|
|
8318
|
+
// POST /a2a - SendMessage | SendStreamingMessage | GetTask
|
|
8319
|
+
```
|
|
8320
|
+
|
|
8321
|
+
## Task mapping
|
|
8322
|
+
|
|
8323
|
+
One A2A task is one agent turn: `taskId` is the runner's `turnId`.
|
|
8324
|
+
|
|
8325
|
+
| Run result | Task state |
|
|
8326
|
+
| --- | --- |
|
|
8327
|
+
| completed with output | `TASK_STATE_COMPLETED` + an `output` artifact |
|
|
8328
|
+
| completed with a typed error | `TASK_STATE_FAILED` (error in `metadata`) |
|
|
8329
|
+
| suspended (approval, budget, model, max turns) | `TASK_STATE_INPUT_REQUIRED` |
|
|
8330
|
+
| suspended (cancelled) | `TASK_STATE_CANCELED` |
|
|
8331
|
+
|
|
8332
|
+
Agent input is `message.metadata.input` when present, otherwise the first `text` part. Structured output returns as a `text` part carrying JSON.
|
|
8333
|
+
|
|
8334
|
+
## Human-in-the-loop resume
|
|
8335
|
+
|
|
8336
|
+
A suspended task's status message carries the pending continuation in `metadata`. Send it back to continue the same task - the runtime keeps state token-only, so a suspended tool's input must be replayed in `continuation.input`:
|
|
8337
|
+
|
|
8338
|
+
```jsonc
|
|
8339
|
+
{
|
|
8340
|
+
"jsonrpc": "2.0", "id": 2, "method": "SendMessage",
|
|
8341
|
+
"params": {
|
|
8342
|
+
"message": {
|
|
8343
|
+
"messageId": "m2", "role": "ROLE_USER", "parts": [],
|
|
8344
|
+
"taskId": "<task id from the suspension>",
|
|
8345
|
+
"metadata": {
|
|
8346
|
+
"input": { "prompt": "go" },
|
|
8347
|
+
"resume": {
|
|
8348
|
+
"continuation": { "kind": "approval", "tool": "search.read", "effectId": "…", "input": { "q": "…" } },
|
|
8349
|
+
"approval": { "granted": true }
|
|
8350
|
+
}
|
|
8351
|
+
}
|
|
8352
|
+
}
|
|
8353
|
+
}
|
|
8354
|
+
}
|
|
8355
|
+
```
|
|
8356
|
+
|
|
8357
|
+
Cross-request registries (cancellation, subscription fan-out, push notifications) are deliberately out of scope for the stateless seam; those spec methods answer `UnsupportedOperationError` (-32004).
|
|
8358
|
+
|
|
8359
|
+
The seam performs no authentication or authorization - wrap it with your app's route guards and scope every port in `ports(c)` to the caller.
|
|
8360
|
+
|
|
8361
|
+
## Docs
|
|
8362
|
+
|
|
8363
|
+
Part of the **[nifra](https://nifra.dev)** full-stack TypeScript framework - one core, five UI libraries, every runtime. Scaffold a new app with `bun create nifra`.
|
|
8364
|
+
|
|
8365
|
+
For AI agents, see [`LLM.md`](./LLM.md) and the full corpus
|
|
8366
|
+
[`../../llms-full.txt`](../../llms-full.txt).
|
|
8367
|
+
|
|
8368
|
+
## @nifrajs/ag-ui
|
|
8369
|
+
|
|
8370
|
+
Mount a nifra agent as an [AG-UI](https://docs.ag-ui.com) (Agent-User Interaction protocol) endpoint: one POST accepting `RunAgentInput`, a stream of AG-UI events out over SSE - run lifecycle, step and tool-call events projected from the runner's step evidence, text message events for the output, and a typed continuation for human-in-the-loop resume.
|
|
8371
|
+
|
|
8372
|
+
A protocol bridge over [`@nifrajs/agent`](../agent) - the request body reuses core's single bounded, prototype-guarded trust boundary, and the model, durable state store, and approval transport are injected per request through the same `ports` factory `mountAgent` uses. Dependency-free beyond the two nifra peers.
|
|
8373
|
+
|
|
8374
|
+
## Install
|
|
8375
|
+
|
|
8376
|
+
```bash
|
|
8377
|
+
bun add @nifrajs/ag-ui @nifrajs/agent
|
|
8378
|
+
```
|
|
8379
|
+
|
|
8380
|
+
## Mount
|
|
8381
|
+
|
|
8382
|
+
```ts
|
|
8383
|
+
import { server } from "@nifrajs/core"
|
|
8384
|
+
import { mountAgUI } from "@nifrajs/ag-ui"
|
|
8385
|
+
import { agent } from "./agent" // an AgentDefinition
|
|
8386
|
+
|
|
8387
|
+
const app = server()
|
|
8388
|
+
mountAgUI(app, {
|
|
8389
|
+
agent,
|
|
8390
|
+
ports: (c) => ({
|
|
8391
|
+
model: myModelPort, // scope to the request subject
|
|
8392
|
+
capabilities: ["search.read"],
|
|
8393
|
+
state: myStateStore, // required for resume
|
|
8394
|
+
}),
|
|
8395
|
+
})
|
|
8396
|
+
// POST /agui - RunAgentInput in, AG-UI events out (SSE)
|
|
8397
|
+
```
|
|
8398
|
+
|
|
8399
|
+
## Event mapping
|
|
8400
|
+
|
|
8401
|
+
| Runner | AG-UI events |
|
|
8402
|
+
| --- | --- |
|
|
8403
|
+
| run starts | `RUN_STARTED`, then `CUSTOM { name: "nifra.turn" }` announcing the turn id |
|
|
8404
|
+
| tool evidence | `TOOL_CALL_START` / `TOOL_CALL_END`, then `TOOL_CALL_RESULT` whose `content` is the token-only outcome `{ "outcome": "committed" \| "failed" \| "denied", "code"? }` |
|
|
8405
|
+
| model, approval, budget, state evidence | `STEP_STARTED` / `STEP_FINISHED` |
|
|
8406
|
+
| model text deltas | live `TEXT_MESSAGE_START` / `_CONTENT` (see streaming below) |
|
|
8407
|
+
| model reasoning deltas | `REASONING_START` / `REASONING_MESSAGE_START` / `_CONTENT` / `_END` / `REASONING_END` |
|
|
8408
|
+
| model tool-args deltas | provisional `TOOL_CALL_START` + `TOOL_CALL_ARGS`, closed by the call's tool evidence |
|
|
8409
|
+
| shared state | `STATE_SNAPSHOT` on the seed and `STATE_DELTA` (RFC 6902 ops) per patch (see below) |
|
|
8410
|
+
| model usage deltas | summed per `(provider, model)` into the `usage: TokenUsage[]` array on `RUN_FINISHED` |
|
|
8411
|
+
| completed output | `TEXT_MESSAGE_START` / `_CONTENT` / `_END` (unless text was streamed), an optional `MESSAGES_SNAPSHOT` (see below), then `RUN_FINISHED` with `result` and `outcome: { "type": "success" }` |
|
|
8412
|
+
| completed with a typed error | `RUN_ERROR` |
|
|
8413
|
+
| suspended | `CUSTOM { name: "nifra.pending" }` with the continuation, then `RUN_FINISHED` with `outcome: { "type": "interrupt", "interrupts": [...] }` |
|
|
8414
|
+
|
|
8415
|
+
Evidence-derived events carry the evidence `timestamp`. The runtime is token-only by design - `TOOL_CALL_RESULT` reports the outcome and error code, never the tool's payload.
|
|
8416
|
+
|
|
8417
|
+
Agent input is `forwardedProps.input` when present, otherwise the content of the last `role: "user"` message.
|
|
8418
|
+
|
|
8419
|
+
## Token streaming
|
|
8420
|
+
|
|
8421
|
+
A model port that calls the request's optional `onDelta` callback (see `@nifrajs/agent`'s `AgentModelDelta`) streams live:
|
|
8422
|
+
|
|
8423
|
+
- `{ kind: "text", text }` opens a `TEXT_MESSAGE` and streams each chunk as `TEXT_MESSAGE_CONTENT`. When any text was streamed, the terminal text block is suppressed - the streamed text IS the assistant message, so a streaming port must stream all user-visible text. A non-streaming port keeps the single terminal block; nothing changes for it.
|
|
8424
|
+
- `{ kind: "reasoning", text }` streams a `REASONING_*` message.
|
|
8425
|
+
- `{ kind: "tool-args", name?, argsText }` opens a provisional `TOOL_CALL_START` (id `<turnId>:call:<n>`) and streams `TOOL_CALL_ARGS`. The tool evidence that follows closes the same call - `TOOL_CALL_END` plus the token-only `TOOL_CALL_RESULT` - instead of opening a second one.
|
|
8426
|
+
- `{ kind: "usage", provider?, model?, inputTokens?, ... }` never becomes a frame. The counts are summed per `(provider, model)` across the run's model decisions and stamped as the spec `usage: TokenUsage[]` array on the terminal `RUN_FINISHED` (success and interrupt alike); non-finite figures are ignored.
|
|
8427
|
+
|
|
8428
|
+
Each stream closes when a different delta kind starts, when tool evidence lands, or at the end of the run. Deltas are transient observer data: a `Last-Event-ID` replay carries evidence frames and the stored, unsuppressed terminal events only - the stored `RUN_FINISHED` keeps its `usage`.
|
|
8429
|
+
|
|
8430
|
+
## Shared state
|
|
8431
|
+
|
|
8432
|
+
The `ports` factory receives `(c, run)`; `run.sharedState` is the run's `AgentSharedState` channel and `run.turnId` the resolved turn id. `body.state` seeds the document and is announced with an upfront `STATE_SNAPSHOT`; every `patch` from a port or tool executor streams as `STATE_DELTA` carrying the RFC 6902 ops. A first patch on an unseeded document announces itself as a `STATE_SNAPSHOT` instead of a delta against a base the client never saw. The channel is per-run and transient - nothing in it is persisted.
|
|
8433
|
+
|
|
8434
|
+
```ts
|
|
8435
|
+
mountAgUI(app, {
|
|
8436
|
+
agent,
|
|
8437
|
+
ports: (c, run) => ({
|
|
8438
|
+
model: myStreamingModelPort(run.sharedState), // patch progress as the run advances
|
|
8439
|
+
capabilities: ["search.read"],
|
|
8440
|
+
}),
|
|
8441
|
+
})
|
|
8442
|
+
```
|
|
8443
|
+
|
|
8444
|
+
With `emitMessagesSnapshot: true`, a successful run also emits `MESSAGES_SNAPSHOT` - the request's `messages` echoed back with the assistant output message appended - before `RUN_FINISHED`. It is off by default: the snapshot echoes client message payloads, and terminal events persist to the evidence log when one is configured.
|
|
8445
|
+
|
|
8446
|
+
## Human-in-the-loop resume
|
|
8447
|
+
|
|
8448
|
+
A suspended run finishes with `outcome: { "type": "interrupt", "interrupts": [interrupt] }` where the interrupt is:
|
|
8449
|
+
|
|
8450
|
+
```jsonc
|
|
8451
|
+
{
|
|
8452
|
+
"id": "<turnId>",
|
|
8453
|
+
"reason": "approval", // approval | budget | model | cancelled | max_turns
|
|
8454
|
+
"toolCallId": "<effectId>", // present for tool suspensions
|
|
8455
|
+
"responseSchema": { /* JSON Schema for the resume payload */ },
|
|
8456
|
+
"metadata": { "turnId": "…", "continuation": { "kind": "approval", "tool": "…", "effectId": "…" } }
|
|
8457
|
+
}
|
|
8458
|
+
```
|
|
8459
|
+
|
|
8460
|
+
Resume with the AG-UI `resume` array. The runtime keeps state token-only - it holds no interrupt registry - so the payload must echo `metadata.continuation`, with the suspended tool's input replayed in `continuation.input`:
|
|
8461
|
+
|
|
8462
|
+
```jsonc
|
|
8463
|
+
{
|
|
8464
|
+
"threadId": "thread-1", "runId": "run-2", "messages": [],
|
|
8465
|
+
"forwardedProps": { "input": { "prompt": "go" } },
|
|
8466
|
+
"resume": [{
|
|
8467
|
+
"interruptId": "<interrupt id>",
|
|
8468
|
+
"status": "resolved", // "cancelled" without an approval resumes as a denial
|
|
8469
|
+
"payload": {
|
|
8470
|
+
"continuation": { "kind": "approval", "tool": "search.read", "effectId": "…", "input": { "q": "…" } },
|
|
8471
|
+
"approval": { "granted": true }
|
|
8472
|
+
}
|
|
8473
|
+
}]
|
|
8474
|
+
}
|
|
8475
|
+
```
|
|
8476
|
+
|
|
8477
|
+
The pre-interrupt form - the same `{ continuation, approval? }` object in `forwardedProps.resume` plus `forwardedProps.turnId` - keeps working. A resume that fails validation is ignored and the POST starts a fresh run.
|
|
8478
|
+
|
|
8479
|
+
## Resumable streams
|
|
8480
|
+
|
|
8481
|
+
Pass an `evidenceLog` to make a dropped SSE connection resumable. Evidence-derived frames then
|
|
8482
|
+
carry SSE `id: <seq>`; a client reconnects by re-POSTing the same body with a `Last-Event-ID`
|
|
8483
|
+
header and receives the missed events, rejoining a still-running turn live or replaying the stored
|
|
8484
|
+
terminal events - the run is never re-executed.
|
|
8485
|
+
|
|
8486
|
+
```ts
|
|
8487
|
+
import { createMemoryAgentEvidenceLog } from "@nifrajs/agent/events"
|
|
8488
|
+
|
|
8489
|
+
mountAgUI(app, { agent, ports, evidenceLog: createMemoryAgentEvidenceLog() })
|
|
8490
|
+
```
|
|
8491
|
+
|
|
8492
|
+
The in-memory log is the single-process dev/test reference; a durable, multi-process log is an
|
|
8493
|
+
adapter implementing the same `AgentEvidenceLog` interface.
|
|
8494
|
+
|
|
8495
|
+
The seam performs no authentication or authorization - wrap it with your app's route guards and scope every port in `ports(c)` to the caller.
|
|
8496
|
+
|
|
8497
|
+
## Docs
|
|
8498
|
+
|
|
8499
|
+
Part of the **[nifra](https://nifra.dev)** full-stack TypeScript framework - one core, five UI libraries, every runtime. Scaffold a new app with `bun create nifra`.
|
|
8500
|
+
|
|
8501
|
+
For AI agents, see [`LLM.md`](./LLM.md) and the full corpus
|
|
8502
|
+
[`../../llms-full.txt`](../../llms-full.txt).
|
|
8503
|
+
|
|
7677
8504
|
## @nifrajs/agent
|
|
7678
8505
|
|
|
7679
8506
|
Provider-neutral, typed, resumable agent turns over Nifra tool contracts.
|
|
@@ -7694,6 +8521,42 @@ const result = await runAgent(definition, { value: input }, ports, {
|
|
|
7694
8521
|
The public in-memory adapters are for local development and tests. Durable state, provider
|
|
7695
8522
|
credentials, and operated policy remain adapter concerns.
|
|
7696
8523
|
|
|
8524
|
+
Gateway and deployment contracts are deliberately provider-neutral. Retry, fallback, budget,
|
|
8525
|
+
deadline, workspace, and hostile-code isolation claims are admitted only from a host-approved
|
|
8526
|
+
capability report. The local and replay reference profiles are not hostile-code sandboxes, and no
|
|
8527
|
+
public package loads provider credentials or promises durable execution.
|
|
8528
|
+
|
|
8529
|
+
Several telemetry consumers can observe the same run: `combineAgentTelemetry(a, b, ...)` fans step
|
|
8530
|
+
evidence out to every port in order, so an SSE evidence stream and an exporter (for example
|
|
8531
|
+
`@nifrajs/agent-telemetry`'s `traceAgentRun`) compose instead of displacing each other. The HTTP
|
|
8532
|
+
seams (`mountAgent`, `@nifrajs/a2a`, `@nifrajs/ag-ui`) compose their streaming evidence with any
|
|
8533
|
+
telemetry port supplied through `ports`.
|
|
8534
|
+
|
|
8535
|
+
A model port can stream: when the caller wires an `AgentDeltaSink` into `ports.deltas`, every model
|
|
8536
|
+
request carries an optional `onDelta` callback the port may call per chunk - user-visible text,
|
|
8537
|
+
reasoning text, the raw argument text of the tool call being formed, or a `usage` delta reporting
|
|
8538
|
+
the decision's settled token counts (optionally attributed to a provider and model, for observers
|
|
8539
|
+
to sum across the run). Deltas are transient
|
|
8540
|
+
observer data for live UIs (`@nifrajs/ag-ui` projects them onto `TEXT_MESSAGE_*`, `REASONING_*`,
|
|
8541
|
+
and `TOOL_CALL_ARGS` frames): they are never validated, persisted, or replayed, and a failing sink
|
|
8542
|
+
never fails the model step. `combineAgentDeltaSinks(a, b, ...)` fans deltas out the way
|
|
8543
|
+
`combineAgentTelemetry` fans evidence.
|
|
8544
|
+
|
|
8545
|
+
`createAgentSharedState(initial)` is the run's shared UI state channel: a JSON document any port or
|
|
8546
|
+
tool executor patches with RFC 6902 operations (`add`, `replace`, `remove`), with subscribers
|
|
8547
|
+
observing every applied batch. Patches apply atomically - an invalid op rejects the whole batch -
|
|
8548
|
+
and prototype-grafting pointer segments are refused. The document is per-run observer data, not
|
|
8549
|
+
turn state: nothing in it is persisted by the runtime. `@nifrajs/ag-ui` projects the channel onto
|
|
8550
|
+
AG-UI `STATE_SNAPSHOT`/`STATE_DELTA` events.
|
|
8551
|
+
|
|
8552
|
+
SSE streams are resumable: give `mountAgent` (or `@nifrajs/ag-ui`'s `mountAgUI`) an `evidenceLog`
|
|
8553
|
+
and `step` frames carry `id: <seq>`. A client that loses the connection re-POSTs the same `turnId`
|
|
8554
|
+
with a `Last-Event-ID` header and receives the missed evidence, rejoining a still-running turn live
|
|
8555
|
+
or replaying the stored terminal frame - the run is never re-executed.
|
|
8556
|
+
`createMemoryAgentEvidenceLog` (from `@nifrajs/agent/events`) is the single-process dev/test
|
|
8557
|
+
reference; a durable, multi-process log is an adapter implementing the same `AgentEvidenceLog`
|
|
8558
|
+
interface.
|
|
8559
|
+
|
|
7697
8560
|
Execution policies can be required by a tool contract. `createLocalProcessAdapter` applies cwd and
|
|
7698
8561
|
environment filtering, timeouts, and cancellation to child processes. The local adapter is NOT a
|
|
7699
8562
|
security boundary. Without OS-level sandboxing it contains crashes and accidents, not hostile code.
|
|
@@ -7701,6 +8564,111 @@ security boundary. Without OS-level sandboxing it contains crashes and accidents
|
|
|
7701
8564
|
For the compact agent contract, see [`LLM.md`](./LLM.md). The full machine-readable corpus is
|
|
7702
8565
|
[`../../llms-full.txt`](../../llms-full.txt).
|
|
7703
8566
|
|
|
8567
|
+
## @nifrajs/agent-app
|
|
8568
|
+
|
|
8569
|
+
A presentation-safe browser SDK for Nifra agent hosts.
|
|
8570
|
+
|
|
8571
|
+
This package depends on **only** `@nifrajs/agent-protocol`. It pulls in no backend, model provider,
|
|
8572
|
+
storage, or UI framework, so it can be bundled into browser-facing code without dragging a private
|
|
8573
|
+
engine or payload content across the boundary. Everything it surfaces upward is a content-free view
|
|
8574
|
+
model: identifiers, lifecycle statuses, counters, and opaque references. A prompt becomes a character
|
|
8575
|
+
count; a tool result becomes an `ok` flag and an error *code*; a compaction becomes before/after token
|
|
8576
|
+
counts.
|
|
8577
|
+
|
|
8578
|
+
## What it does
|
|
8579
|
+
|
|
8580
|
+
- **Feature negotiation.** On session creation the client intersects the features it can drive with the
|
|
8581
|
+
capabilities the host advertises, and gates the matching operations behind `requireFeature`.
|
|
8582
|
+
- **Caller auth.** An optional `authorize` hook mints a bearer token per request. The token is placed
|
|
8583
|
+
on the outgoing `Authorization` header and never stored on the transport, copied into a result, or
|
|
8584
|
+
written to a log.
|
|
8585
|
+
- **Ordered, deduplicated streaming.** A turn arrives as an ordered stream of `AgentEventView`s.
|
|
8586
|
+
Out-of-order and redelivered frames are reordered and de-duplicated by sequence; a bounded buffer
|
|
8587
|
+
skips an unfilled gap rather than stalling.
|
|
8588
|
+
- **Cursor resume.** A persisted log can be replayed from a cursor. A cursor whose next record was
|
|
8589
|
+
evicted from the retained window asks the caller to resync.
|
|
8590
|
+
- **Approvals and handoffs.** Pending approvals list as identifiers; decisions and handoff outcomes go
|
|
8591
|
+
back through negotiated commands.
|
|
8592
|
+
- **Run Studio views.** Run graphs, retry/recovery timelines, eval comparisons, and fault-injection
|
|
8593
|
+
rows consume only protocol evidence and bounded replay references.
|
|
8594
|
+
- **Escape hatch.** `command()` reaches host-specific surfaces outside the negotiated contract and
|
|
8595
|
+
still returns a bounded `CommandOutcome` - it never throws the credential.
|
|
8596
|
+
|
|
8597
|
+
## Usage
|
|
8598
|
+
|
|
8599
|
+
```ts
|
|
8600
|
+
import { AgentAppClient, HttpAgentTransport } from "@nifrajs/agent-app"
|
|
8601
|
+
|
|
8602
|
+
const transport = new HttpAgentTransport({
|
|
8603
|
+
endpoint: "http://127.0.0.1:8787",
|
|
8604
|
+
authorize: () => currentToken(), // per-request; never stored
|
|
8605
|
+
})
|
|
8606
|
+
const client = new AgentAppClient(transport)
|
|
8607
|
+
|
|
8608
|
+
const session = await client.createSession()
|
|
8609
|
+
if (client.supports("resume")) {
|
|
8610
|
+
const replay = await client.resume({ cursor: lastCursor })
|
|
8611
|
+
// replay.entries: { seq, at, type }[] - no payloads
|
|
8612
|
+
}
|
|
8613
|
+
|
|
8614
|
+
for await (const view of client.send("summarize the diff")) {
|
|
8615
|
+
// view is content-free: e.g. { kind: "assistant.delta", seq, chars }
|
|
8616
|
+
}
|
|
8617
|
+
```
|
|
8618
|
+
|
|
8619
|
+
## Boundary
|
|
8620
|
+
|
|
8621
|
+
The transport receives the host's full event stream in order to derive counts, but the client's public
|
|
8622
|
+
output is projected to content-free view models. That projection is the seam: an application built on
|
|
8623
|
+
this SDK can render progress and resolve interactions, and cannot reconstruct a prompt, tool payload,
|
|
8624
|
+
model completion, diagnostic report, or filesystem path. The `scripts/check-agent-boundary.ts` gate
|
|
8625
|
+
enforces that this package imports nothing but `@nifrajs/agent-protocol`.
|
|
8626
|
+
|
|
8627
|
+
The SDK is transport-neutral and opt-in: it does not retain payloads, provide identity or tenancy,
|
|
8628
|
+
claim a remote security boundary, or imply durable delivery. Production hosts own authorization,
|
|
8629
|
+
retention, and adapter policy.
|
|
8630
|
+
|
|
8631
|
+
## License
|
|
8632
|
+
|
|
8633
|
+
MIT
|
|
8634
|
+
|
|
8635
|
+
For AI agents, see [`LLM.md`](./LLM.md) and the full corpus
|
|
8636
|
+
[`../../llms-full.txt`](../../llms-full.txt).
|
|
8637
|
+
|
|
8638
|
+
## @nifrajs/agent-protocol
|
|
8639
|
+
|
|
8640
|
+
Small, backend-neutral contracts for local coding-agent sessions.
|
|
8641
|
+
|
|
8642
|
+
The package contains versioned session snapshots, streamed assistant/tool/approval
|
|
8643
|
+
events, bounded live event streams, and backend interfaces. It has no runtime
|
|
8644
|
+
dependencies and does not import Nifra framework packages, model SDKs, or UI code.
|
|
8645
|
+
|
|
8646
|
+
```ts
|
|
8647
|
+
import { createAgentEventStream } from "@nifrajs/agent-protocol"
|
|
8648
|
+
|
|
8649
|
+
const events = createAgentEventStream(256)
|
|
8650
|
+
events.push(/* a versioned AgentEvent */)
|
|
8651
|
+
```
|
|
8652
|
+
|
|
8653
|
+
Use `@nifrajs/pi` for the Pi backend or implement `AgentBackend` for another
|
|
8654
|
+
runtime. The protocol is intentionally small so CLI, desktop, mobile, and CI
|
|
8655
|
+
clients can share it without pulling in the Nifra application framework.
|
|
8656
|
+
|
|
8657
|
+
## Version 1 compatibility
|
|
8658
|
+
|
|
8659
|
+
Version 1 is additive. Hosts advertise capabilities and clients use only the negotiated intersection;
|
|
8660
|
+
an unsupported command is a stable `feature_unsupported` result. Optional fields are ignored by older
|
|
8661
|
+
peers, while a cursor gap returns `resync_required` instead of silently skipping evidence. A future
|
|
8662
|
+
major requires a recorded semantic incompatibility, dual decoders, cross-version fixtures, and an
|
|
8663
|
+
approved migration plan.
|
|
8664
|
+
|
|
8665
|
+
Run evidence and lifecycle values are structural only: identifiers, statuses, counters, timestamps,
|
|
8666
|
+
digests, and opaque references. Prompts, model output, tool arguments, and filesystem paths do not
|
|
8667
|
+
belong in these public contracts.
|
|
8668
|
+
|
|
8669
|
+
For AI agents, see [`LLM.md`](./LLM.md) and the full corpus
|
|
8670
|
+
[`../../llms-full.txt`](../../llms-full.txt).
|
|
8671
|
+
|
|
7704
8672
|
## @nifrajs/agent-telemetry
|
|
7705
8673
|
|
|
7706
8674
|
Child-span telemetry for AI tool calls made through Nifra tool and MCP endpoints.
|
|
@@ -7719,6 +8687,35 @@ Requests under `/_nifra/tool/*` and requests to `/mcp` receive tool-name, input-
|
|
|
7719
8687
|
duration, and status observations. When `@nifrajs/otel` owns the request observation, tool spans are
|
|
7720
8688
|
attached as children; otherwise the plugin creates a standalone observation. Other routes pass through.
|
|
7721
8689
|
|
|
8690
|
+
## Tracing agent runs
|
|
8691
|
+
|
|
8692
|
+
`traceAgentRun` turns a `@nifrajs/agent` run's step evidence into an OpenTelemetry trace: one
|
|
8693
|
+
`nifra.agent.run` span per run, one child span per evidence item, with tool names, effect ids, error
|
|
8694
|
+
codes, and effect-ledger heads carried as span attributes. Only the runner's constrained evidence
|
|
8695
|
+
fields are exported - prompts, tool inputs, and outputs cannot enter a trace.
|
|
8696
|
+
|
|
8697
|
+
Orchestration correlation is opt-in and cardinality-bounded. Allowed attributes are run, plan, node,
|
|
8698
|
+
attempt, evidence, replay, and trace coordinates plus bounded status/error codes. Content-bearing or
|
|
8699
|
+
unbounded attributes are rejected; the exporter is not a payload retention sink.
|
|
8700
|
+
|
|
8701
|
+
```ts
|
|
8702
|
+
import { traceAgentRun } from "@nifrajs/agent-telemetry"
|
|
8703
|
+
import { combineAgentTelemetry, runAgent } from "@nifrajs/agent"
|
|
8704
|
+
|
|
8705
|
+
const trace = traceAgentRun({ agent: agent.name, turnId, exporter })
|
|
8706
|
+
const result = await runAgent(agent, input, {
|
|
8707
|
+
...ports,
|
|
8708
|
+
telemetry: combineAgentTelemetry(ports.telemetry, trace.telemetry),
|
|
8709
|
+
})
|
|
8710
|
+
trace.end(result)
|
|
8711
|
+
```
|
|
8712
|
+
|
|
8713
|
+
Model evidence arrives as a started/terminal pair and becomes one timed `nifra.agent.model` span;
|
|
8714
|
+
tool, approval, budget, and state evidence are terminal-only and become instant children. Pass
|
|
8715
|
+
`parent` (for example the enclosing request observation's `context`) to nest runs under the HTTP
|
|
8716
|
+
span, or `traceparent` to continue an inbound W3C trace; `trace.context` is the run span's identity,
|
|
8717
|
+
forwardable with `traceHeaders`. Telemetry is fail-open: a throwing exporter never fails the turn.
|
|
8718
|
+
|
|
7722
8719
|
## For AI agents
|
|
7723
8720
|
|
|
7724
8721
|
Start with [`LLM.md`](./LLM.md) - this package's contract card (the exports you call + its footguns),
|
|
@@ -7949,8 +8946,9 @@ await cache.invalidateTag(`user:${id}`)
|
|
|
7949
8946
|
|
|
7950
8947
|
## Stores
|
|
7951
8948
|
|
|
7952
|
-
The default `MemoryCache` is in-process with
|
|
7953
|
-
|
|
8949
|
+
The default `MemoryCache` is in-process with incremental expiry, a tag index, and a 10,000-entry LRU
|
|
8950
|
+
cap. Tune it with `new MemoryCache({ maxEntries: 2_000 })`; `maxEntries: 0` is the explicit unbounded
|
|
8951
|
+
opt-in. For a cache shared across instances, implement `CacheStore`
|
|
7954
8952
|
(`get` / `set` / `delete` / `invalidateTag` / `clear`) over CF KV, Redis, etc.:
|
|
7955
8953
|
|
|
7956
8954
|
```ts
|
|
@@ -7987,6 +8985,7 @@ nifra start [--port <n>] [--out <dir>] Run the generated Bun server at <out>
|
|
|
7987
8985
|
nifra context Print this project's API + page routes + conventions.
|
|
7988
8986
|
nifra mcp MCP server (stdio) exposing this project to a coding agent.
|
|
7989
8987
|
nifra check [--json] Gate: typecheck + lints; --json includes fixes/suggestions.
|
|
8988
|
+
nifra migrate --from tailwind --to stylex Dry-run safe static Tailwind → StyleX migration; --write applies it.
|
|
7990
8989
|
nifra assure [--config <file>] [--json] Gate reflected routes against enforcement evidence.
|
|
7991
8990
|
nifra capabilities check [--json] Gate effect provenance + the reviewed capability lockfile.
|
|
7992
8991
|
nifra manifest emit [--sign <key-ref>] Emit the hash-verified route trust artifact after assurance.
|
|
@@ -8049,6 +9048,15 @@ For hand-rolled own-API `fetch()` calls, `nifra check` stays conservative: simpl
|
|
|
8049
9048
|
that match a statically visible Nifra route get an exact typed-client rewrite diff; dynamic URLs, custom
|
|
8050
9049
|
headers, bodies, query strings, or ambiguous routes fall back to manual steps.
|
|
8051
9050
|
|
|
9051
|
+
## `nifra migrate --from tailwind --to stylex`
|
|
9052
|
+
|
|
9053
|
+
This command is a dry run by default. It rewrites static `className` attributes whose utilities have a
|
|
9054
|
+
direct StyleX equivalent into `stylex.props(...)` plus a local `stylex.create(...)` table. Use
|
|
9055
|
+
`--write` to apply the safe changes, and `--dir` to scan a project subdirectory. Responsive breakpoints
|
|
9056
|
+
and element-local pseudo-classes are supported; dynamic expressions, arbitrary values, parent-dependent
|
|
9057
|
+
variants, and unknown utilities are left untouched and reported with file and line evidence. A non-zero
|
|
9058
|
+
exit status means manual migration issues remain.
|
|
9059
|
+
|
|
8052
9060
|
When a library such as Better Auth intentionally owns a mounted prefix outside the Nifra contract,
|
|
8053
9061
|
declare that prefix in `nifra.check.json` so its relative calls do not keep CI red:
|
|
8054
9062
|
|
|
@@ -8175,6 +9183,76 @@ one cheap read instead of the whole corpus. For the wider framework: the repo's
|
|
|
8175
9183
|
[`llms-full.txt`](../../llms-full.txt) is the full machine-readable corpus. Run `nifra check` as the
|
|
8176
9184
|
done-gate, or `nifra mcp` to give the agent live project tools.
|
|
8177
9185
|
|
|
9186
|
+
## @nifrajs/coding-agent
|
|
9187
|
+
|
|
9188
|
+
Standalone, extensible Nifra coding-agent host and CLI.
|
|
9189
|
+
|
|
9190
|
+
The package provides `nifra-agent` in interactive, one-shot, JSON, and local
|
|
9191
|
+
loopback RPC modes. It adds sessions, checkpoints, bounded compaction,
|
|
9192
|
+
transactional TypeScript extensions, self-healing repair stages, workflows,
|
|
9193
|
+
bounded subagents, and Nifra verification descriptors without changing Nifra's
|
|
9194
|
+
framework runtime.
|
|
9195
|
+
|
|
9196
|
+
Extensions can register bounded workflows that are listed and run through the
|
|
9197
|
+
authenticated RPC surface. Capability manifests, project workspace policies,
|
|
9198
|
+
optional isolated-worktree leases, and a pre-activation syntax gate keep those
|
|
9199
|
+
customizations explicit and replaceable.
|
|
9200
|
+
|
|
9201
|
+
```sh
|
|
9202
|
+
bunx nifra-agent --backend pi
|
|
9203
|
+
bunx nifra-agent --backend pi --message "run the checks and explain failures"
|
|
9204
|
+
bunx nifra-agent --backend pi --verify-after-turn check --max-repair-attempts 2
|
|
9205
|
+
bunx nifra-agent --backend replay --replay ./session-events.jsonl --json
|
|
9206
|
+
```
|
|
9207
|
+
|
|
9208
|
+
When --verify-after-turn is enabled, a failed gate becomes a bounded repair turn: the host sends
|
|
9209
|
+
the failure diagnostics back to the agent, runs the gate again, and stops on success or after the
|
|
9210
|
+
configured attempt cap. Use --max-repair-attempts 0 for observe-only verification.
|
|
9211
|
+
|
|
9212
|
+
For embedding, use `CodingAgentHost` or `CodingAgentRpcServer`. The host keeps
|
|
9213
|
+
live event queues bounded, filters verification subprocess environments, and
|
|
9214
|
+
requires explicit local RPC authorization. Install this package only when an
|
|
9215
|
+
application wants the agent product.
|
|
9216
|
+
|
|
9217
|
+
RPC failures return actionable bounded error messages by default. For a trusted
|
|
9218
|
+
loopback debugger, set `exposeErrorStacks: true` (or pass
|
|
9219
|
+
`--expose-error-stacks` to `nifra-agent --rpc`) to include bounded exception
|
|
9220
|
+
stacks. This option is rejected for remote binding.
|
|
9221
|
+
|
|
9222
|
+
`IsolatedExtensionWorker` is an opt-in process-backed crash-containment seam for
|
|
9223
|
+
extensions. It is not a hostile-code sandbox; use OS-level isolation before
|
|
9224
|
+
loading code you do not trust.
|
|
9225
|
+
|
|
9226
|
+
`NifraBackend` is a small provider port for a future native backend. It accepts
|
|
9227
|
+
an injected model implementation and bounded tools without importing a provider
|
|
9228
|
+
SDK. `ReplayBackend` and `readReplayEvents` provide deterministic protocol
|
|
9229
|
+
replays for CI and Workbench regression tests.
|
|
9230
|
+
|
|
9231
|
+
## At-least-once run dispatch
|
|
9232
|
+
|
|
9233
|
+
`@nifrajs/coding-agent/orchestration` also exports an evidence-only run dispatch port and an adapter
|
|
9234
|
+
over `@nifrajs/jobs`. Dispatch is at-least-once: a lease may be delivered again after worker loss or
|
|
9235
|
+
lease expiry. Every logical node attempt receives a stable idempotency key derived from the plan,
|
|
9236
|
+
run, node, and attempt boundary. Effects must provide a matching proof before recovery can settle a
|
|
9237
|
+
completed boundary; an unproven post-effect failure is dead-lettered rather than guessed safe.
|
|
9238
|
+
|
|
9239
|
+
`createMemoryRunDispatchStore()` is disposable single-process test infrastructure. It makes no
|
|
9240
|
+
durability, hosted-worker, retention, tenant-authorization, or exactly-once guarantee. Durable
|
|
9241
|
+
operated adapters implement the exported `RunDispatchStore` and `DurableDispatchAdapter` ports in
|
|
9242
|
+
their own data layer, including authorization, row policy, retention, reconciliation, and worker
|
|
9243
|
+
health. The public package does not store prompts, model output, tool arguments, or job payloads in
|
|
9244
|
+
its dispatch evidence.
|
|
9245
|
+
|
|
9246
|
+
Legacy `FileSessionStore` files remain supported for explicit local compatibility. Use
|
|
9247
|
+
`nifra-agent --migrate-session <id> --migrate-from <legacy-dir> --migrate-to <evidence-dir>` to
|
|
9248
|
+
create a separately validated, evidence-only target. The source is left untouched and the command
|
|
9249
|
+
does not switch an active configuration pointer; see
|
|
9250
|
+
[`docs/agent-platform/protocol-and-session-migration.md`](../../docs/agent-platform/protocol-and-session-migration.md)
|
|
9251
|
+
for rollback and protocol compatibility details.
|
|
9252
|
+
|
|
9253
|
+
For AI agents, see [`LLM.md`](./LLM.md) and the full corpus
|
|
9254
|
+
[`../../llms-full.txt`](../../llms-full.txt).
|
|
9255
|
+
|
|
8178
9256
|
## @nifrajs/content
|
|
8179
9257
|
|
|
8180
9258
|
Typed, schema-validated content collections for nifra - Markdown + frontmatter, framework-agnostic.
|
|
@@ -8267,6 +9345,27 @@ import { defineChannel, memoryChannelHub } from "@nifrajs/core/channel"
|
|
|
8267
9345
|
- **Inline or contract-first.** Write routes inline (types inferred from the
|
|
8268
9346
|
builder), or `defineContract(...)` + `implement(...)` for a decoupled, versionable
|
|
8269
9347
|
surface - handlers lift over unchanged.
|
|
9348
|
+
|
|
9349
|
+
### Scaling route tables
|
|
9350
|
+
|
|
9351
|
+
Fluent chains are the best fit for a small route surface. TypeScript's type-instantiation budget
|
|
9352
|
+
usually becomes the limiting factor around 95-100 chained routes because every call both infers its
|
|
9353
|
+
handler context and re-threads the growing typed registry. The runtime router is not the limit, and
|
|
9354
|
+
the routes remain fully typed when you compose them as short domain groups:
|
|
9355
|
+
|
|
9356
|
+
```ts
|
|
9357
|
+
const listings = server()
|
|
9358
|
+
.get("/listings", () => ({ ok: true }))
|
|
9359
|
+
.get("/listings/:id", (c) => ({ id: c.params.id }))
|
|
9360
|
+
const agents = server().get("/agents/:id", (c) => ({ id: c.params.id }))
|
|
9361
|
+
|
|
9362
|
+
const app = server().get("/health", () => ({ ok: true })).merge(listings).merge(agents)
|
|
9363
|
+
```
|
|
9364
|
+
|
|
9365
|
+
Each group's routes keep the middleware and assurance captured when that group was defined. For a
|
|
9366
|
+
contract-owned surface, `defineContract(...)` + `implement(...)` is the other escape hatch: the
|
|
9367
|
+
registry is declared as one object type, so it does not grow one fluent-instantiation level per
|
|
9368
|
+
route. Split groups before the compiler reports `TS2589`, rather than weakening the route types.
|
|
8270
9369
|
- **Validation at the boundary.** Per-route `body`/`query` is any
|
|
8271
9370
|
[Standard Schema](https://standardschema.dev) (zod/valibot/arktype, or `@nifrajs/schema`'s
|
|
8272
9371
|
`t`); invalid input is rejected with a structured `422` before the handler runs.
|
|
@@ -8677,6 +9776,126 @@ one cheap read instead of the whole corpus. For the wider framework: the repo's
|
|
|
8677
9776
|
[`llms-full.txt`](../../llms-full.txt) is the full machine-readable corpus. Run `nifra check` as the
|
|
8678
9777
|
done-gate, or `nifra mcp` to give the agent live project tools.
|
|
8679
9778
|
|
|
9779
|
+
## @nifrajs/graphql
|
|
9780
|
+
|
|
9781
|
+
Mount a GraphQL endpoint on a nifra app. A spec-compliant [GraphQL-over-HTTP](https://graphql.github.io/graphql-over-http/draft/) handler, `graphql-transport-ws` subscriptions over nifra's native WebSocket lane, and your typed nifra context piped straight into resolvers.
|
|
9782
|
+
|
|
9783
|
+
It executes with the `graphql` package's own `parse`/`validate`/`execute`/`subscribe` - no HTTP framework is re-bundled, the request body reuses core's single bounded, prototype-guarded trust boundary, and the query text is never logged.
|
|
9784
|
+
|
|
9785
|
+
## Install
|
|
9786
|
+
|
|
9787
|
+
```bash
|
|
9788
|
+
bun add @nifrajs/graphql graphql
|
|
9789
|
+
# subscriptions also need:
|
|
9790
|
+
bun add graphql-ws
|
|
9791
|
+
```
|
|
9792
|
+
|
|
9793
|
+
`graphql` is a required peer; `graphql-ws` is optional (only for subscriptions).
|
|
9794
|
+
|
|
9795
|
+
## Queries and mutations
|
|
9796
|
+
|
|
9797
|
+
```ts
|
|
9798
|
+
import { server } from "@nifrajs/core"
|
|
9799
|
+
import { mountGraphql } from "@nifrajs/graphql"
|
|
9800
|
+
import { buildSchema } from "graphql"
|
|
9801
|
+
|
|
9802
|
+
const schema = buildSchema(`
|
|
9803
|
+
type Query { hello: String }
|
|
9804
|
+
type Mutation { echo(msg: String!): String }
|
|
9805
|
+
`)
|
|
9806
|
+
|
|
9807
|
+
const rootValue = {
|
|
9808
|
+
hello: () => "world",
|
|
9809
|
+
echo: ({ msg }: { msg: string }) => msg,
|
|
9810
|
+
}
|
|
9811
|
+
|
|
9812
|
+
const app = server()
|
|
9813
|
+
mountGraphql(app, { schema, rootValue })
|
|
9814
|
+
// POST /graphql - queries + mutations
|
|
9815
|
+
// GET /graphql - queries only (idempotent, cacheable)
|
|
9816
|
+
```
|
|
9817
|
+
|
|
9818
|
+
Prefer the handler directly? Mount it yourself:
|
|
9819
|
+
|
|
9820
|
+
```ts
|
|
9821
|
+
import { respondGraphql } from "@nifrajs/graphql"
|
|
9822
|
+
|
|
9823
|
+
app.post("/graphql", (c) => respondGraphql(c.req, { schema, rootValue }))
|
|
9824
|
+
```
|
|
9825
|
+
|
|
9826
|
+
## Context injection
|
|
9827
|
+
|
|
9828
|
+
The one thing a plain third-party mount cannot do: derive the resolver `contextValue` from what your nifra handler already resolved (auth subject, env, params).
|
|
9829
|
+
|
|
9830
|
+
```ts
|
|
9831
|
+
mountGraphql(app, {
|
|
9832
|
+
schema,
|
|
9833
|
+
context: ({ request, nifra }) => ({
|
|
9834
|
+
user: nifra?.env, // nifra route context, when mounted via mountGraphql
|
|
9835
|
+
ip: request.headers.get("x-forwarded-for"),
|
|
9836
|
+
}),
|
|
9837
|
+
})
|
|
9838
|
+
```
|
|
9839
|
+
|
|
9840
|
+
Resolvers read it as their third argument.
|
|
9841
|
+
|
|
9842
|
+
## Subscriptions
|
|
9843
|
+
|
|
9844
|
+
Subscriptions run over the same route via `graphql-transport-ws`. Bring a subscription source - the bundled in-memory `createPubSub` is the reference implementation; swap in a durable bus (Redis, a Durable Object, NATS) that exposes the same `{ publish, subscribe }` shape for multi-instance deploys.
|
|
9845
|
+
|
|
9846
|
+
```ts
|
|
9847
|
+
import { server } from "@nifrajs/core"
|
|
9848
|
+
import { websocket } from "@nifrajs/core/ws"
|
|
9849
|
+
import { mountGraphql, createPubSub } from "@nifrajs/graphql"
|
|
9850
|
+
|
|
9851
|
+
const pubsub = createPubSub<number>()
|
|
9852
|
+
|
|
9853
|
+
const app = server().use(websocket())
|
|
9854
|
+
mountGraphql(app, {
|
|
9855
|
+
schema,
|
|
9856
|
+
context: () => ({ pubsub }),
|
|
9857
|
+
subscriptions: true,
|
|
9858
|
+
})
|
|
9859
|
+
|
|
9860
|
+
// A resolver:
|
|
9861
|
+
// count: { subscribe: (_, __, ctx) => ctx.pubsub.subscribe("count"), resolve: (n) => n }
|
|
9862
|
+
// Push an event from anywhere:
|
|
9863
|
+
pubsub.publish("count", 1)
|
|
9864
|
+
```
|
|
9865
|
+
|
|
9866
|
+
The route must negotiate the `graphql-transport-ws` subprotocol at the WebSocket layer for a browser `graphql-ws` client to connect.
|
|
9867
|
+
|
|
9868
|
+
## Options
|
|
9869
|
+
|
|
9870
|
+
| Option | Default | Purpose |
|
|
9871
|
+
| --- | --- | --- |
|
|
9872
|
+
| `schema` | - | Executable `GraphQLSchema` (required). |
|
|
9873
|
+
| `context` | `{}` | Build the resolver `contextValue` per operation. |
|
|
9874
|
+
| `rootValue` | - | Root value passed to the executor. |
|
|
9875
|
+
| `maxBodyBytes` | `1_000_000` | Request body cap; larger bodies answer 413. |
|
|
9876
|
+
| `protoPoisoning` | `"reject"` | Prototype-pollution policy for the JSON body. |
|
|
9877
|
+
| `allowedOrigins` | reflect `*` | CORS origin allowlist. |
|
|
9878
|
+
| `authorize` | - | Per-request guard; return `false` for 401. |
|
|
9879
|
+
| `enableGet` | `true` | Serve `GET /graphql` (queries only). |
|
|
9880
|
+
| `subscriptions` | `false` | `true` (reuse schema/context) or explicit WS options. |
|
|
9881
|
+
| `legacyJsonResponse` | `false` | Old always-200 `application/json` shape. |
|
|
9882
|
+
|
|
9883
|
+
## Responses
|
|
9884
|
+
|
|
9885
|
+
By default responses use the `application/graphql-response+json` media type with spec status codes: `200` for an executed result (including field errors in `errors`), `400` for a parse or validation failure, `401` for a rejected `authorize`, `405` for a mutation attempted over GET. Set `legacyJsonResponse: true` for the older always-`200` `application/json` behavior some clients expect.
|
|
9886
|
+
|
|
9887
|
+
## License
|
|
9888
|
+
|
|
9889
|
+
MIT
|
|
9890
|
+
|
|
9891
|
+
## For AI agents
|
|
9892
|
+
|
|
9893
|
+
Start with [`LLM.md`](./LLM.md) - this package's contract card (the exports you call + its footguns),
|
|
9894
|
+
one cheap read instead of the whole corpus. For the wider framework: the repo's
|
|
9895
|
+
[`AGENTS.md`](../../AGENTS.md) is the copy-paste quick reference, and
|
|
9896
|
+
[`llms-full.txt`](../../llms-full.txt) is the full machine-readable corpus. Run `nifra check` as the
|
|
9897
|
+
done-gate, or `nifra mcp` to give the agent live project tools.
|
|
9898
|
+
|
|
8680
9899
|
## @nifrajs/i18n
|
|
8681
9900
|
|
|
8682
9901
|
Framework-agnostic i18n for nifra - locale negotiation + a tiny ICU message formatter on the platform Intl. Dependency-free.
|
|
@@ -8917,6 +10136,12 @@ const q = createQueue({ store: new RedisJobStore(redis) })
|
|
|
8917
10136
|
Leasing is at-least-once: a leased job is hidden for `leaseMs`; a worker that dies mid-job releases it
|
|
8918
10137
|
back automatically. Make handlers **idempotent**.
|
|
8919
10138
|
|
|
10139
|
+
The queue remains agent-agnostic. `@nifrajs/coding-agent` can place content-free run-dispatch
|
|
10140
|
+
identities in a dedicated `JobStore`, but this package does not import or define agent concepts. A
|
|
10141
|
+
`MemoryJobStore` is disposable single-process storage; production durability, authorization,
|
|
10142
|
+
retention, reconciliation, and worker coordination belong to the caller's operated adapter. No
|
|
10143
|
+
exactly-once delivery guarantee is implied by a lease.
|
|
10144
|
+
|
|
8920
10145
|
## Cloudflare Workers
|
|
8921
10146
|
|
|
8922
10147
|
Workers has no long-lived process, so don't call `start()`. Back the queue with a durable store and a
|
|
@@ -8976,6 +10201,10 @@ Mount `mcp.fetch` at `POST /mcp`. The package also exposes the JSON-RPC protocol
|
|
|
8976
10201
|
layers directly, plus `defineMcpWidget` and the React adapter for tool results that render UI in MCP
|
|
8977
10202
|
hosts.
|
|
8978
10203
|
|
|
10204
|
+
Clients that include `text/event-stream` in `Accept` receive progress notifications as they happen,
|
|
10205
|
+
followed by the final JSON-RPC response in the same stream. An SSE `GET /mcp` opens a cancellable
|
|
10206
|
+
server-message connection; a plain `GET /mcp` remains a health page.
|
|
10207
|
+
|
|
8979
10208
|
## For AI agents
|
|
8980
10209
|
|
|
8981
10210
|
Start with [`LLM.md`](./LLM.md) - this package's contract card (the exports you call + its footguns),
|
|
@@ -9357,6 +10586,43 @@ one cheap read instead of the whole corpus. For the wider framework: the repo's
|
|
|
9357
10586
|
[`llms-full.txt`](../../llms-full.txt) is the full machine-readable corpus. Run `nifra check` as the
|
|
9358
10587
|
done-gate, or `nifra mcp` to give the agent live project tools.
|
|
9359
10588
|
|
|
10589
|
+
## @nifrajs/pi
|
|
10590
|
+
|
|
10591
|
+
Lightweight Pi JSONL/RPC adapter for the Nifra agent protocol.
|
|
10592
|
+
|
|
10593
|
+
It starts Pi in headless RPC mode, maps Pi lifecycle, assistant, tool,
|
|
10594
|
+
compaction, extension, and error events into `@nifrajs/agent-protocol`, and
|
|
10595
|
+
supports cancellation, reload, session identity, and bounded event buffering.
|
|
10596
|
+
|
|
10597
|
+
Reload defaults to a process restart with the same Pi session ID. This is the
|
|
10598
|
+
reliable reload primitive in Pi's documented RPC protocol: the transcript stays
|
|
10599
|
+
in Pi's session store while the new process loads changed extensions. The tiny
|
|
10600
|
+
public-API bridge is still loaded for interactive Pi use. Set
|
|
10601
|
+
`reloadCommand: "prompt"` only for an RPC implementation that dispatches slash
|
|
10602
|
+
commands, or `reloadCommand: "rpc"` for one that provides a top-level reload
|
|
10603
|
+
command. Set `enableReloadBridge: false` when supplying a custom bridge.
|
|
10604
|
+
|
|
10605
|
+
Set `enableNifraTools: true` to load the separately packaged Pi extension with
|
|
10606
|
+
`nifra_context`, `nifra_check`, `nifra_assure`, and `nifra_test` tools. The
|
|
10607
|
+
default is off so embedding Pi stays minimal.
|
|
10608
|
+
|
|
10609
|
+
```ts
|
|
10610
|
+
import { PiBackend } from "@nifrajs/pi"
|
|
10611
|
+
|
|
10612
|
+
const backend = new PiBackend()
|
|
10613
|
+
const session = await backend.createSession({ cwd: process.cwd() })
|
|
10614
|
+
for await (const event of backend.send({ sessionId: session.id, message: "inspect this project" })) {
|
|
10615
|
+
console.log(event.type)
|
|
10616
|
+
}
|
|
10617
|
+
```
|
|
10618
|
+
|
|
10619
|
+
Pi stays an optional dependency of the agent product. Nothing in this package is
|
|
10620
|
+
reachable from `@nifrajs/core`, `@nifrajs/client`, `@nifrajs/web`, or
|
|
10621
|
+
`@nifrajs/schema`.
|
|
10622
|
+
|
|
10623
|
+
For AI agents, see [`LLM.md`](./LLM.md) and the full corpus
|
|
10624
|
+
[`../../llms-full.txt`](../../llms-full.txt).
|
|
10625
|
+
|
|
9360
10626
|
## @nifrajs/prompt
|
|
9361
10627
|
|
|
9362
10628
|
Provider-neutral, type-safe prompts with Standard Schema input and validated structured output.
|
|
@@ -9410,7 +10676,7 @@ const upstream = createProxy({ upstream: "http://127.0.0.1:8081" })
|
|
|
9410
10676
|
const app = server().mountFetch("/api", upstream, { stripPrefix: true })
|
|
9411
10677
|
```
|
|
9412
10678
|
|
|
9413
|
-
The upstream is a **bare origin** fixed at construction - the forwarded URL is built by mutating a clone of that origin, never by resolving request-derived strings, so no request input can change which host is dialed. Hop-by-hop and `Connection`-nominated headers are stripped in both directions
|
|
10679
|
+
The upstream is a **bare origin** fixed at construction - the forwarded URL is built by mutating a clone of that origin, never by resolving request-derived strings, so no request input can change which host is dialed. Hop-by-hop and `Connection`-nominated headers are stripped in both directions. Caller IP/protocol metadata is dropped unless `forwardClientIp: true`; the inbound Host is never trusted, and `X-Forwarded-Host` is emitted only from a fixed `forwardedHost`. Upstream redirects are never followed, and TLS verification has no off switch. Unreachable upstreams answer a flat `502`; the deadline (`timeoutMs`, default 30s) answers `504`.
|
|
9414
10680
|
|
|
9415
10681
|
## Docs
|
|
9416
10682
|
|
|
@@ -9572,6 +10838,11 @@ pi install npm:@nifrajs/skills
|
|
|
9572
10838
|
/plugin install nifra@nifra
|
|
9573
10839
|
```
|
|
9574
10840
|
|
|
10841
|
+
The plugin registers the Nifra MCP server as well as the skills, so a fresh install has the live tools
|
|
10842
|
+
the skills tell it to prefer. Its launch spec is deliberately unpinned - a plugin is installed once and
|
|
10843
|
+
opened against many projects, so the CLI resolves per project and the server reports version skew
|
|
10844
|
+
itself rather than freezing one version across all of them.
|
|
10845
|
+
|
|
9575
10846
|
**Anything that reads a skills directory** (Cursor, `.agents/skills`, a project `.pi/skills`)
|
|
9576
10847
|
|
|
9577
10848
|
```sh
|
|
@@ -9588,6 +10859,9 @@ against the version installed in the project being edited:
|
|
|
9588
10859
|
bunx @nifrajs/cli init-agents # register the MCP server in an existing app
|
|
9589
10860
|
```
|
|
9590
10861
|
|
|
10862
|
+
The Claude Code plugin brings its own copy of that server, so `init-agents` is for the other surfaces -
|
|
10863
|
+
and for committing a version-pinned `.mcp.json` that every contributor on the project shares.
|
|
10864
|
+
|
|
9591
10865
|
Not in a Nifra project? The docs tools are hosted at `https://mcp.nifra.dev`.
|
|
9592
10866
|
|
|
9593
10867
|
That split is the anti-drift design: a skill that restated the API would rot on the next release,
|
|
@@ -9867,6 +11141,14 @@ that every call carries and captures cookies via a shared jar.
|
|
|
9867
11141
|
|
|
9868
11142
|
For a **stateless** request (no cookies), use `testClient` from `@nifrajs/client` directly.
|
|
9869
11143
|
|
|
11144
|
+
### Agent evaluation and failure matrix
|
|
11145
|
+
|
|
11146
|
+
`runAgentEvalComposition` composes trajectory replay, fault profiles, contract invariants,
|
|
11147
|
+
idempotency proofs, and adapter certification. Reports expose explicit invariant and rubric cases,
|
|
11148
|
+
stable regression IDs, schedule tokens, and digests; they do not retain prompts, tool payloads,
|
|
11149
|
+
model output, labels, or a single opaque quality score. The failure matrix covers model, tool,
|
|
11150
|
+
approval, cancellation, lease, cursor, registry, and deployment boundaries.
|
|
11151
|
+
|
|
9870
11152
|
## For AI agents
|
|
9871
11153
|
|
|
9872
11154
|
Start with [`LLM.md`](./LLM.md) - this package's contract card (the exports you call + its footguns),
|
|
@@ -10077,6 +11359,14 @@ Zero-framework render adapter for @nifrajs/web - auto-escaping tagged-template H
|
|
|
10077
11359
|
|
|
10078
11360
|
Part of the **[nifra](https://nifra.dev)** full-stack TypeScript framework - one core, five UI libraries, every runtime. Scaffold a new app with `bun create nifra`.
|
|
10079
11361
|
|
|
11362
|
+
## The AI-safe lane
|
|
11363
|
+
|
|
11364
|
+
Vanilla is the render adapter an agent gets right on the first try. It ships no framework runtime, so there is no hydration, no reactivity, and none of the failure modes (stale closures, hydration mismatch, what-re-runs-when) that trip up generated code. You get true SSR plus every server feature - loaders, actions, ISR/SSG, streaming, head management - unchanged from `@nifrajs/web`; those live in the core, not the view layer.
|
|
11365
|
+
|
|
11366
|
+
Interactivity is added with **islands**, not hydration: small imperative DOM enhancers over server-rendered elements. `defineIsland` types the props, `createIslandBus` coordinates islands over a typed channel, and every enhancer returns its cleanup - the one rule `nifra check` enforces (`NF-C020`). See the [islands cookbook](https://nifra.dev/docs/islands) for the counter, cart-badge, and filter patterns, or run `nifra scaffold` on a vanilla route for the golden stub.
|
|
11367
|
+
|
|
11368
|
+
Need a stateful app UI with reactive components? That is what the five framework adapters are for - reach for `@nifrajs/web-preact` or `@nifrajs/web-solid` when you want a small reactive runtime.
|
|
11369
|
+
|
|
10080
11370
|
## Install
|
|
10081
11371
|
|
|
10082
11372
|
```sh
|
|
@@ -10237,13 +11527,29 @@ done-gate, or `nifra mcp` to give the agent live project tools.
|
|
|
10237
11527
|
|
|
10238
11528
|
# Complete export index (generated from each package's src/index.ts)
|
|
10239
11529
|
|
|
11530
|
+
## @nifrajs/a2a
|
|
11531
|
+
|
|
11532
|
+
`A2A_ERROR_CODES`, `A2A_PROTOCOL_VERSION`, `A2AAgentCard`, `A2AAgentSkill`, `A2ACardInfo`, `A2AMountableApp`, `A2ARouteContext`, `A2ATaskState`, `AGENT_CARD_WELL_KNOWN_PATH`, `agentCard`, `mountA2A`, `MountA2AOptions`
|
|
11533
|
+
|
|
11534
|
+
## @nifrajs/ag-ui
|
|
11535
|
+
|
|
11536
|
+
`AgUIMountableApp`, `AgUIRouteContext`, `AgUIRunContext`, `AgUIRunUsage`, `mountAgUI`, `MountAgUIOptions`
|
|
11537
|
+
|
|
10240
11538
|
## @nifrajs/agent
|
|
10241
11539
|
|
|
10242
|
-
`AgentApprovalPort`, `AgentApprovalResult`, `AgentDefinition`, `AgentModelPort`, `AgentModelRequest`, `AgentModelResponse`, `AgentPendingContinuation`, `AgentPendingKind`, `AgentPorts`, `AgentRunResult`, `AgentStateStore`, `AgentStatus`, `AgentStepEvidence`, `AgentTelemetryPort`, `AgentToolContract`, `AgentToolDescriptor`, `AgentToolResult`, `AgentTranscript`, `AgentTurnBaseResult`, `AgentTurnError`, `AgentTurnInput`, `AgentTurnResult`, `AgentTurnState`, `createAgentState`, `createLocalProcessAdapter`, `ExecutionPolicy`, `ExecutionPolicyAdapter`, `LOCAL_PROCESS_LIMITATION`, `LocalProcessAdapter`, `LocalProcessAdapterOptions`, `LocalProcessPolicyError`, `LocalProcessRequest`, `LocalProcessResult`, `MemoryAgentStateStore`, `replayAgent`, `resumeAgent`, `runAgent`, `RunAgentOptions`, `turn`
|
|
11540
|
+
`AgentApprovalPort`, `AgentApprovalResult`, `AgentDefinition`, `AgentDeltaSink`, `AgentDeployment`, `AgentDeploymentAdapter`, `AgentDeploymentPlan`, `AgentModelDelta`, `AgentModelPort`, `AgentModelRequest`, `AgentModelResponse`, `AgentPendingContinuation`, `AgentPendingKind`, `AgentPorts`, `AgentRunResult`, `AgentSharedState`, `AgentStatePatchOp`, `AgentStateStore`, `AgentStatus`, `AgentStepEvidence`, `AgentTelemetryPort`, `AgentToolContract`, `AgentToolDescriptor`, `AgentToolResult`, `AgentTranscript`, `AgentTurnBaseResult`, `AgentTurnError`, `AgentTurnInput`, `AgentTurnResult`, `AgentTurnState`, `ApprovalClass`, `assertDeploymentAuthorityMonotonic`, `CAPABILITY_DESCRIPTOR_VERSION`, `CapabilityDescriptor`, `CapabilityKind`, `combineAgentDeltaSinks`, `combineAgentTelemetry`, `composeDescriptor`, `composeRegistrySnapshot`, `createAgentSharedState`, `createAgentState`, `createDeploymentAuthority`, `createLocalProcessAdapter`, `createStructuredOutputParser`, `DeploymentActivationOptions`, `DeploymentAuthority`, `DeploymentCancellation`, `DeploymentCancelRequest`, `DeploymentCancelResult`, `DeploymentCapabilities`, `DeploymentCapabilityReport`, `DeploymentDisposeRequest`, `DeploymentDisposeResult`, `DeploymentError`, `DeploymentErrorCode`, `DeploymentEvidence`, `DeploymentFilesystem`, `DeploymentInspection`, `DeploymentInspectRequest`, `DeploymentNetwork`, `DeploymentPrepareRequest`, `DeploymentPrepareResult`, `DeploymentProcess`, `DeploymentRuntime`, `DeploymentSecrets`, `DeploymentStartRequest`, `DeploymentStartResult`, `DeploymentState`, `descriptorFromTool`, `DescriptorInput`, `ExecutionPolicy`, `ExecutionPolicyAdapter`, `FakeModelGateway`, `FakeModelGatewayOptions`, `HostileCodeIsolation`, `IdempotencyClass`, `isModelGatewayErrorCode`, `IsolationClass`, `LOCAL_PROCESS_LIMITATION`, `LocalProcessAdapter`, `LocalProcessAdapterOptions`, `LocalProcessPolicyError`, `LocalProcessRequest`, `LocalProcessResult`, `MemoryAgentStateStore`, `MODEL_GATEWAY_ERROR_CODES`, `ModelGateway`, `ModelGatewayAttemptRequest`, `ModelGatewayBudget`, `ModelGatewayEnvelope`, `ModelGatewayError`, `ModelGatewayErrorCode`, `ModelGatewayEvidence`, `ModelGatewayExecutionResult`, `ModelGatewayFailure`, `ModelGatewayFailureError`, `ModelGatewayRawResult`, `ModelGatewayRequest`, `ModelGatewayResult`, `ModelGatewaySuccess`, `ModelGatewayTerminalFailure`, `ModelGatewayUsage`, `ModelRoute`, `ModelRoutePolicy`, `ModelRouteRef`, `parseCapabilityDescriptor`, `parseDeploymentCapabilityReport`, `parseDeploymentPlan`, `parseModelGatewayError`, `parseModelGatewayResult`, `REGISTRY_SNAPSHOT_VERSION`, `RegistryError`, `RegistryErrorCode`, `RegistrySnapshot`, `replayAgent`, `ReplayModelGateway`, `ReplayModelGatewayOptions`, `resumeAgent`, `RetryClass`, `runAgent`, `RunAgentOptions`, `runModelGateway`, `structuredOutputParser`, `StructuredOutputParser`, `ToolDescriptorOptions`, `turn`
|
|
11541
|
+
|
|
11542
|
+
## @nifrajs/agent-app
|
|
11543
|
+
|
|
11544
|
+
`AGENT_APP_FEATURES`, `AgentAppClient`, `AgentAppClientOptions`, `AgentAppError`, `AgentEventView`, `AgentTransport`, `AgentTransportError`, `AgentTransportRequest`, `ApprovalRequiredView`, `ApprovalResolvedView`, `AssistantChunkView`, `AuthProvider`, `boundaryCommands`, `BoundaryDecisionResult`, `boundaryIsStale`, `BoundaryItemView`, `BoundaryStateView`, `CommandOutcome`, `CreateSessionInput`, `EvalComparisonView`, `EvidenceTimelineView`, `ExtensionReloadedView`, `FaultInjectionView`, `HandoffView`, `HttpAgentTransport`, `HttpAgentTransportOptions`, `MemoryCompactedView`, `OrderedEventBuffer`, `parseEventStream`, `PendingApprovalView`, `RegistryCapabilityView`, `RepairRequiredView`, `ReplayEntryView`, `ReplayResult`, `ResolveHandoffInput`, `ResumeInput`, `RunStudioNodeState`, `RunStudioNodeView`, `RunStudioView`, `RunView`, `SessionFailedView`, `SessionLifecycleView`, `SessionStoppedView`, `SessionView`, `toEvalComparisonView`, `toEventView`, `toEvidenceTimelineView`, `toFaultInjectionViews`, `toHandoffView`, `ToolCompletedView`, `ToolDeltaView`, `ToolStartedView`, `toRegistryCapabilityView`, `toRunStudioView`, `toRunView`, `toSessionView`, `TurnStartedView`, `VerificationCompletedView`, `virtualizeEvidenceRows`
|
|
11545
|
+
|
|
11546
|
+
## @nifrajs/agent-protocol
|
|
11547
|
+
|
|
11548
|
+
`AGENT_PROTOCOL_VERSION`, `AgentApprovalRequiredEvent`, `AgentApprovalResolvedEvent`, `AgentAssistantDeltaEvent`, `AgentAssistantMessageEvent`, `AgentBackend`, `AgentBackendInfo`, `agentError`, `AgentError`, `AgentEvent`, `AgentEventPayload`, `AgentEventSink`, `AgentEventStream`, `AgentEventType`, `AgentExtensionReloadedEvent`, `AgentMemoryCompactedEvent`, `AgentRepairRequiredEvent`, `AgentRepairTask`, `AgentSessionCheckpoint`, `AgentSessionCompletedEvent`, `AgentSessionEventBase`, `AgentSessionFailedEvent`, `AgentSessionSnapshot`, `AgentSessionStartedEvent`, `AgentSessionStatus`, `AgentSessionStoppedEvent`, `AgentSessionUpdatedEvent`, `AgentToolCompletedEvent`, `AgentToolDeltaEvent`, `AgentToolStartedEvent`, `AgentTurnStartedEvent`, `AgentVerificationCompletedEvent`, `createAgentEventStream`, `CreateSessionInput`, `ForkSessionInput`, `ForkSessionResult`, `isAgentEvent`, `ReloadResult`, `SendMessageInput`
|
|
10243
11549
|
|
|
10244
11550
|
## @nifrajs/agent-telemetry
|
|
10245
11551
|
|
|
10246
|
-
`agentTelemetry`, `AgentTelemetryOptions`, `consoleAgentExporter`
|
|
11552
|
+
`AgentRunEvidence`, `AgentRunOutcome`, `AgentRunTrace`, `agentTelemetry`, `AgentTelemetryOptions`, `consoleAgentExporter`, `orchestrationTelemetry`, `OrchestrationTelemetry`, `OrchestrationTelemetryEvent`, `OrchestrationTelemetryKind`, `OrchestrationTelemetryOptions`, `traceAgentRun`, `TraceAgentRunOptions`
|
|
10247
11553
|
|
|
10248
11554
|
## @nifrajs/auth
|
|
10249
11555
|
|
|
@@ -10265,13 +11571,17 @@ done-gate, or `nifra mcp` to give the agent live project tools.
|
|
|
10265
11571
|
|
|
10266
11572
|
`ActionArgs`, `ActionData`, `ApiError`, `ApiProxy`, `client`, `ClientOptions`, `ClientRetryOptions`, `FetchFn`, `inProcessClient`, `InProcessClient`, `InProcessClientOptions`, `Jsonify`, `LoaderArgs`, `LoaderData`, `RegistryOf`, `RESERVED_EXACT_KEYS`, `RESERVED_KEY_READOUT`, `RESERVED_VERB_KEYS`, `reservedKeyFor`, `ResponseContractViolation`, `Result`, `SubscribeOptions`, `Subscription`, `testClient`, `Treaty`, `TreatyFromRegistry`, `WsCallOptions`, `WsHandle`
|
|
10267
11573
|
|
|
11574
|
+
## @nifrajs/coding-agent
|
|
11575
|
+
|
|
11576
|
+
`AGENT_CAPABILITY_MANIFEST_VERSION`, `AGENT_PRESETS`, `AgentCapability`, `AgentCapabilityManifest`, `AgentPlan`, `AgentPreset`, `AgentPresetName`, `ApprovalDecision`, `ApprovalManager`, `ApprovalManagerOptions`, `ApprovalMatchRejection`, `ApprovalMatchResult`, `ApprovalRequest`, `approvalRequestFromEvent`, `approvalResolvedEvent`, `BoundedSubagentRunner`, `BoundedText`, `CapabilityDescriptor`, `CiDeploymentAdapter`, `CodingAgentExtension`, `CodingAgentHost`, `CodingAgentHostOptions`, `CodingAgentRpcServer`, `CodingAgentRpcServerHandle`, `CodingAgentRpcServerOptions`, `CompactionReport`, `ContextRecord`, `ContextWindow`, `ContextWindowOptions`, `createCapabilityManifest`, `createCiDeploymentAdapter`, `createLocalProcessDeploymentAdapter`, `createNativeGatewayModelPort`, `createNifraTools`, `createPresetSpec`, `createReplayDeploymentAdapter`, `createVerificationRepairTask`, `deniedCapabilities`, `DEPLOYMENT_REFERENCE_PROFILES`, `discoverExtensions`, `ExtensionCommand`, `ExtensionContext`, `extensionDescriptor`, `ExtensionDescriptorOptions`, `extensionDescriptors`, `ExtensionDescriptorSource`, `ExtensionEventHandler`, `ExtensionHost`, `ExtensionHostOptions`, `ExtensionProvider`, `ExtensionReloadResult`, `ExtensionSubagent`, `ExtensionTool`, `FileSessionStore`, `FileSessionStoreOptions`, `getAgentPreset`, `HandoffCoordinator`, `HandoffCoordinatorOptions`, `HandoffDecision`, `HandoffError`, `HandoffRejection`, `HandoffView`, `HealingEvent`, `HealingOptions`, `HealingResult`, `IsolatedExtensionSnapshot`, `IsolatedExtensionTool`, `IsolatedExtensionWorker`, `IsolatedExtensionWorkerOptions`, `LocalProcessDeploymentAdapter`, `migrateLegacySession`, `MigrateLegacySessionOptions`, `NativeApprovalPort`, `NativeGatewayModelPortOptions`, `NativeMessage`, `NativeModelChunk`, `NativeModelPort`, `NativeModelRequest`, `NativeModelResponse`, `NativeTool`, `NIFRA_AGENT_INSTRUCTIONS`, `NifraAgentTool`, `NifraBackend`, `NifraBackendOptions`, `NifraContextOptions`, `NifraContextResult`, `OpenHandoffInput`, `parseCapabilityManifest`, `parseSessionEvidenceRecord`, `PiBackend`, `PiBackendOptions`, `PlanEvent`, `PlanPhase`, `PlanResult`, `PlanRunner`, `PlanRunnerOptions`, `ProjectDiffOptions`, `ProjectDiffResult`, `readBoundedText`, `readProjectDiff`, `readReplayEvents`, `RepairProposal`, `ReplayBackend`, `ReplayBackendOptions`, `ReplayDeploymentAdapter`, `runNifraContext`, `runNifraVerification`, `SelfHealingController`, `SESSION_EVIDENCE_VERSION`, `SessionEvidenceRecord`, `SessionLogEntry`, `SessionMigrationError`, `SessionMigrationReport`, `SessionStore`, `stableSessionEventCode`, `SubagentExecutor`, `SubagentResult`, `SubagentRunnerOptions`, `SubagentSpec`, `UiExtensionHost`, `UiExtensionHostOptions`, `UiExtensionManifest`, `UiExtensionSlot`, `UiReloadResult`, `UiStatusWidget`, `UiThemeDescriptor`, `validateExtensionModule`, `VerificationOptions`, `VerificationRepairTask`, `VerificationResult`, `WorkflowContext`, `WorkflowEvent`, `WorkflowResult`, `WorkflowRunner`, `WorkflowRunnerOptions`, `WorkflowStep`
|
|
11577
|
+
|
|
10268
11578
|
## @nifrajs/content
|
|
10269
11579
|
|
|
10270
11580
|
`bakeCollection`, `BakedCollection`, `BakedCollectionIndex`, `BakedCollectionJoin`, `BakedIndexBucket`, `ContentFieldKey`, `Entry`, `fromBaked`, `fromBakedIndex`, `fromBakedJoin`, `indexCollection`, `IndexedCollection`, `IndexedJoin`, `IndexOptions`, `IndexPage`, `IndexQueryOptions`, `IndexRange`, `IndexRanges`, `IndexSort`, `IndexWhere`, `InferSchema`, `JoinCardinality`, `joinCollections`, `JoinedRow`, `parseEntry`, `ParseEntryOptions`, `parseFrontmatter`, `SharedKey`, `StandardSchemaV1`, `StaticCollection`
|
|
10271
11581
|
|
|
10272
11582
|
## @nifrajs/core
|
|
10273
11583
|
|
|
10274
|
-
`Version`, `VERSION`
|
|
11584
|
+
`AdmissionController`, `AdmissionDecision`, `AnyServer`, `commonSecretPatterns`, `Context`, `ContextPlugin`, `cookieNamePrefix`, `CookieOptions`, `CookieSecret`, `defineContextPlugin`, `defineIdentityPlugin`, `definePlugin`, `DefinePluginResult`, `defineRouterPlugin`, `DurableObjectNamespaceLike`, `ExecutionContext`, `FetchApp`, `FRAMEWORK_NAME`, `FrameworkError`, `FrameworkName`, `Handler`, `IdentityPlugin`, `InferInput`, `InferOutput`, `isSameOriginPath`, `isSameOriginRequest`, `jsonLogger`, `LambdaEvent`, `LambdaHandler`, `LambdaResponse`, `LambdaV1Event`, `LambdaV2Event`, `LogFields`, `Logger`, `McpPromptDescriptor`, `McpResourceDescriptor`, `Method`, `METHODS`, `Middleware`, `NetlifyEvent`, `NetlifyHandler`, `NifraFeatureVersion`, `NifraPlugin`, `NifraWebSocket`, `NodeRequestContext`, `NodeRequestHook`, `NodeResponseContext`, `NodeResponseHook`, `NodeServeOutcome`, `OnRequestResult`, `Params`, `parseCookies`, `pathnameOf`, `PlainRender`, `Platform`, `PlatformResponse`, `PluginTypeCollapsed`, `Prettify`, `PromptArgument`, `PromptMessage`, `redactLogFields`, `RedactOptions`, `Registry`, `ResponseBodyHook`, `ResponseBodyReplacement`, `ResponseControls`, `ResponseFinalization`, `ResponseHeadersHook`, `ResponseHeadersView`, `ResponseMapFor`, `ResponseResult`, `RouteConfigError`, `RouteConfigErrorCode`, `RouteDescriptor`, `RouteInfo`, `RouteInfoFor`, `Router`, `RouterMatch`, `RouteSchema`, `RunningServer`, `ScheduledController`, `ScheduledHandler`, `serializeCookie`, `server`, `Server`, `ServerOptions`, `signValue`, `silentLogger`, `SSEContext`, `SSEInit`, `SSEMessage`, `SSEStream`, `StandardIssue`, `StandardResult`, `StandardSchemaV1`, `StandardTypes`, `StandardWebSocket`, `status`, `StatusResponse`, `toFetchHandler`, `toLambdaHandler`, `toNetlifyHandler`, `ToolAnnotations`, `toVercelHandler`, `TypedSSEStream`, `unsignValue`, `UrlParts`, `urlPartsOf`, `ValidationOutcome`, `VercelHandler`, `Version`, `VERSION`, `WebSocketContext`, `WebSocketData`, `WebSocketHandler`, `WebSocketUpgradeOutcome`
|
|
10275
11585
|
|
|
10276
11586
|
## @nifrajs/cron
|
|
10277
11587
|
|
|
@@ -10297,6 +11607,10 @@ done-gate, or `nifra mcp` to give the agent live project tools.
|
|
|
10297
11607
|
|
|
10298
11608
|
`createEventRegistry`, `defineEventContract`, `EventContract`, `EventContractError`, `EventEnvelope`, `EventParseResult`, `EventRegistry`, `RegistryParseResult`
|
|
10299
11609
|
|
|
11610
|
+
## @nifrajs/graphql
|
|
11611
|
+
|
|
11612
|
+
`buildContext`, `createPubSub`, `GraphqlContextBuilder`, `GraphqlContextInput`, `GraphqlHttpOptions`, `GraphqlPubSub`, `graphqlWebSocket`, `GraphqlWsOptions`, `mountGraphql`, `MountGraphqlOptions`, `NifraContextLike`, `respondGraphql`
|
|
11613
|
+
|
|
10300
11614
|
## @nifrajs/i18n
|
|
10301
11615
|
|
|
10302
11616
|
`createFormatter`, `Formatter`, `Locale`, `LocaleParts`, `LocaleSource`, `Messages`, `negotiateLocale`, `NegotiateOptions`, `ResolvedLocale`, `resolveLocale`
|
|
@@ -10341,6 +11655,10 @@ done-gate, or `nifra mcp` to give the agent live project tools.
|
|
|
10341
11655
|
|
|
10342
11656
|
`ActiveObservation`, `AttributeValue`, `causalitySpanLink`, `combineObservationAdapters`, `consoleSpanExporter`, `createObservationLifecycle`, `effectTracing`, `EffectTracingOptions`, `EffectTracingPlugin`, `EndObservation`, `formatTraceparent`, `generateSpanId`, `generateTraceId`, `NifraSpan`, `ObservationAdapter`, `ObservationClock`, `ObservationContext`, `ObservationLifecycle`, `ObservationLifecycleOptions`, `ObservationLink`, `ObservationParent`, `otlpExporter`, `OtlpExporter`, `OtlpExporterOptions`, `ParsedTraceparent`, `parseTraceparent`, `SpanStatus`, `StartObservation`, `TraceContext`, `traceHeaders`, `tracing`, `TracingOptions`
|
|
10343
11657
|
|
|
11658
|
+
## @nifrajs/pi
|
|
11659
|
+
|
|
11660
|
+
`PiBackend`, `PiBackendOptions`
|
|
11661
|
+
|
|
10344
11662
|
## @nifrajs/prompt
|
|
10345
11663
|
|
|
10346
11664
|
`prompt`, `Prompt`, `PromptInputError`, `PromptMessage`, `PromptOutputError`, `PromptRequest`, `PromptResponseFormat`, `RunOptions`
|
|
@@ -10363,7 +11681,7 @@ done-gate, or `nifra mcp` to give the agent live project tools.
|
|
|
10363
11681
|
|
|
10364
11682
|
## @nifrajs/testing
|
|
10365
11683
|
|
|
10366
|
-
`AdapterCertificationError`, `AdapterCertificationProfile`, `AdapterCertificationReport`, `AdversarialContractError`, `AdversarialContractOptions`, `AdversarialContractReport`, `AdversarialContractResult`, `AppLike`, `assertAdapterCertification`, `assertAdversarialContract`, `assertIncidentReplays`, `assertTrajectoryInvariants`, `cacheStoreCertificationProfile`, `CapturedRequest`, `CapturedRequestInput`, `captureIncident`, `CaptureIncidentOptions`, `CertifiableCacheEntry`, `CertifiableCacheStore`, `CertifiableDomainEvent`, `CertifiableEventDeliveryAdapter`, `CertifiableEventRecord`, `CertifiableJobStore`, `CertifiableRuntimeAdapter`, `CertifiableRuntimeServer`, `CertifiableStorageAdapter`, `CertificationCapabilityEvidence`, `CertificationCheck`, `CertificationCheckEvidence`, `certifyAdapter`, `checkTrajectoryInvariants`, `ContractCaseContext`, `ContractCaseKind`, `ContractCoverageGap`, `ContractCoverageGapCode`, `ContractReplay`, `ContractRuntime`, `ContractTarget`, `ContractTestApp`, `ContractWitness`, `cookieJar`, `CookieJar`, `createFailureLab`, `createTrajectoryTranscript`, `CreateTrajectoryTranscriptOptions`, `defineCertificationProfile`, `defineFaultProfile`, `EffectLedger`, `eventDeliveryCertificationProfile`, `FailureDirective`, `FailureEvidence`, `FailureInjectedError`, `FailureKind`, `FailureLab`, `FailureLabOptions`, `FailureReplay`, `FailureScenario`, `FailureScenarioReport`, `FaultProfile`, `FaultProfileFault`, `FaultProfileFaultKind`, `FaultProfileReport`, `FaultProfileScenario`, `FaultProfileScenarioReport`, `generateRegressionTest`, `GenerateRegressionTestOptions`, `httpToolAdapter`, `IdempotencyDivergence`, `IdempotencyProof`, `IncidentCapsule`, `IncidentReplayError`, `IncidentReplayResult`, `inProcessToolAdapter`, `jobStoreCertificationProfile`, `mcpToolAdapter`, `proveIdempotency`, `recordTrajectory`, `redactForEmission`, `referenceFaultProfile`, `replayIncident`, `ReplayIncidentOptions`, `replayTrajectory`, `ReplayTrajectoryOptions`, `runAdversarialContract`, `runFailureScenario`, `runFaultProfile`, `RunFaultProfileOptions`, `runtimeAdapterCertificationProfile`, `runTrajectory`, `shapeOf`, `storageAdapterCertificationProfile`, `testSession`, `TestSession`, `TestSessionOptions`, `testToolAdapter`, `TrajectoryInvariantId`, `TrajectoryInvariantOptions`, `TrajectoryInvariantResult`, `trajectoryRegressionId`, `TrajectoryReplayResult`, `TrajectoryRun`, `TrajectoryTranscript`, `verifyAdapterCertification`
|
|
11684
|
+
`AdapterCertificationError`, `AdapterCertificationProfile`, `AdapterCertificationReport`, `AdversarialContractError`, `AdversarialContractOptions`, `AdversarialContractReport`, `AdversarialContractResult`, `AgentEvalCase`, `AgentEvalComponentEvidence`, `AgentEvalCompositionOptions`, `AgentEvalCompositionReport`, `AgentEvalRegressionError`, `AgentEvalReport`, `AgentEvalSuite`, `AgentEvalSuiteSpec`, `AgentFailureMatrixCase`, `AgentFailureMatrixError`, `AgentFailureMatrixKind`, `AgentFailureMatrixReport`, `AppLike`, `assertAdapterCertification`, `assertAdversarialContract`, `assertAgentEval`, `assertAgentEvalBaseline`, `assertAgentFailureMatrix`, `assertIncidentReplays`, `assertTrajectoryInvariants`, `BaselineComparison`, `BaselineOptions`, `cacheStoreCertificationProfile`, `CapturedRequest`, `CapturedRequestInput`, `captureIncident`, `CaptureIncidentOptions`, `CaseComparison`, `CaseResult`, `CertifiableCacheEntry`, `CertifiableCacheStore`, `CertifiableDeploymentAdapter`, `CertifiableDescriptorAdapter`, `CertifiableDomainEvent`, `CertifiableEventDeliveryAdapter`, `CertifiableEventRecord`, `CertifiableJobStore`, `CertifiableModelGateway`, `CertifiableRuntimeAdapter`, `CertifiableRuntimeServer`, `CertifiableStorageAdapter`, `CertificationCapabilityEvidence`, `CertificationCheck`, `CertificationCheckEvidence`, `certifyAdapter`, `checkTrajectoryInvariants`, `compareAgentEvalBaseline`, `ComparisonCode`, `ContractCaseContext`, `ContractCaseKind`, `ContractCoverageGap`, `ContractCoverageGapCode`, `ContractLabHandler`, `ContractLabRuntimeAdapter`, `ContractLabServer`, `ContractLabWitness`, `contractLabWitnesses`, `ContractReplay`, `ContractRuntime`, `ContractTarget`, `ContractTestApp`, `ContractWitness`, `cookieJar`, `CookieJar`, `createFailureLab`, `createReferenceContractLabHandler`, `createTrajectoryTranscript`, `CreateTrajectoryTranscriptOptions`, `defineAgentEvalSuite`, `defineCertificationProfile`, `defineFaultProfile`, `deploymentAdapterCertificationProfile`, `deploymentCertificationProfile`, `EffectLedger`, `eventDeliveryCertificationProfile`, `FailureDirective`, `FailureEvidence`, `FailureInjectedError`, `FailureKind`, `FailureLab`, `FailureLabOptions`, `FailureReplay`, `FailureScenario`, `FailureScenarioReport`, `FaultProfile`, `FaultProfileFault`, `FaultProfileFaultKind`, `FaultProfileReport`, `FaultProfileScenario`, `FaultProfileScenarioReport`, `gatewayCertificationProfile`, `generateRegressionTest`, `GenerateRegressionTestOptions`, `httpToolAdapter`, `IdempotencyDivergence`, `IdempotencyProof`, `IncidentCapsule`, `IncidentReplayError`, `IncidentReplayResult`, `inProcessToolAdapter`, `jobStoreCertificationProfile`, `mcpToolAdapter`, `modelGatewayCertificationProfile`, `parseRubricVerdict`, `proveIdempotency`, `recordTrajectory`, `redactForEmission`, `referenceFaultProfile`, `registryCertificationProfile`, `replayIncident`, `ReplayIncidentOptions`, `replayTrajectory`, `ReplayTrajectoryOptions`, `RubricShape`, `RubricSpec`, `RubricVerdict`, `runAdversarialContract`, `runAgentEvalComposition`, `runAgentFailureMatrix`, `runContractLab`, `runContractLabOverHttp`, `runContractLabThroughAdapter`, `runFailureScenario`, `runFaultProfile`, `RunFaultProfileOptions`, `runtimeAdapterCertificationProfile`, `runTrajectory`, `ScoreTolerance`, `shapeOf`, `storageAdapterCertificationProfile`, `testSession`, `TestSession`, `TestSessionOptions`, `testToolAdapter`, `TrajectoryInvariantId`, `TrajectoryInvariantOptions`, `TrajectoryInvariantResult`, `trajectoryRegressionId`, `TrajectoryReplayResult`, `TrajectoryRun`, `TrajectoryTranscript`, `verifyAdapterCertification`
|
|
10367
11685
|
|
|
10368
11686
|
## @nifrajs/ts-plugin
|
|
10369
11687
|
|
|
@@ -10375,7 +11693,7 @@ done-gate, or `nifra mcp` to give the agent live project tools.
|
|
|
10375
11693
|
|
|
10376
11694
|
## @nifrajs/web
|
|
10377
11695
|
|
|
10378
|
-
`Action`, `ACTION_GLOBAL`, `
|
|
11696
|
+
`Action`, `ACTION_GLOBAL`, `assertRenderAdapterConformance`, `assertStaticBoundaryImports`, `Blocker`, `BlockerController`, `BlockerFunction`, `BlockerLocation`, `BlockerState`, `Boundary`, `BOUNDARY_GLOBAL`, `BoundaryDescriptor`, `boundaryDescriptors`, `BoundaryError`, `BoundaryMode`, `boundaryModeKey`, `BoundaryRegistration`, `BoundaryRequestCtx`, `BoundaryState`, `BoundaryStates`, `BoundaryStatus`, `BrowserNavigate`, `buildManifest`, `CachedResponse`, `CacheStore`, `canonical`, `ClientAction`, `ClientActionArgs`, `ClientActionResult`, `ClientLoader`, `ClientLoaderArgs`, `ClientRequestBody`, `ClientRouteHooks`, `ClientRouter`, `ClientRouterOptions`, `createClientRouter`, `createMatcher`, `createMutation`, `createQueryClient`, `createWebApp`, `CreateWebAppOptions`, `DATA_GLOBAL`, `DATA_HEADER`, `DEFAULT_DEV_PORT`, `defer`, `Deferred`, `DehydratedState`, `disableDraft`, `DRAFT_COOKIE`, `DraftCookieControls`, `DynamicBoundary`, `DynamicBoundaryBatch`, `enableDraft`, `EnableDraftOptions`, `enumerateStaticRoutes`, `Fetcher`, `FetcherState`, `FetchRouteData`, `filePathToPattern`, `filePathToPatterns`, `FontDisplay`, `fontFace`, `FontFace`, `fontPreload`, `FontPreloadInput`, `FontSource`, `generateClientEntry`, `GenerateClientEntryOptions`, `generateRouteSearchTypes`, `GenerateRouteSearchTypesOptions`, `generateServerManifest`, `GenerateServerManifestOptions`, `getBrowserNavigate`, `GetStaticPaths`, `gone`, `hashQueryKey`, `IDLE_BLOCKER`, `InertScriptType`, `InfiniteData`, `InfiniteQueryHandle`, `InfiniteQueryOptions`, `InterceptBoundary`, `isDraftEnabled`, `ISR_REVALIDATE_HEADER`, `ISR_REVALIDATE_TAGS_HEADER`, `ISR_STATUS_HEADER`, `ISRApp`, `ISROptions`, `ISRPlatform`, `jsonLd`, `KVCacheStore`, `KVCacheStoreOptions`, `KVNamespaceLike`, `LAYOUT_DATA_GLOBAL`, `LayoutEntry`, `LinkDescriptor`, `Loader`, `LoaderContext`, `Manifest`, `MemoryCacheStore`, `MemoryCacheStoreOptions`, `MemoryStaticBoundaryCache`, `mergeHeads`, `Meta`, `MetaArgs`, `MetaDescriptor`, `MetaInput`, `MountRouterOptions`, `MutationCallbacks`, `MutationHandle`, `MutationState`, `MutationStatus`, `NAV_FROM_HEADER`, `NavigateFunction`, `NavigateOptions`, `NavigateSearchOf`, `NavigateTargetInput`, `notFound`, `openGraph`, `OpenGraphInput`, `PendingBoundary`, `PRE_HYDRATION_GUARD`, `previewEndpoint`, `PreviewEndpointOptions`, `PublicDirCache`, `QueryClient`, `QueryClientOptions`, `QueryHandle`, `QueryOptions`, `QueryState`, `QueryStatus`, `redirect`, `REDIRECT_HEADER`, `RedirectOptions`, `registerBlocker`, `RenderAdapter`, `RenderAdapterConformanceError`, `RenderAdapterConformanceFixture`, `RenderAssemblyCache`, `RenderedPage`, `renderPage`, `RenderPageInput`, `RenderPageOptions`, `renderPageResult`, `RenderProps`, `resolveDynamicBoundaries`, `resolveMeta`, `resolveNavigate`, `resolvePublicPath`, `resolveStaticBoundaries`, `RETAIN_HEADER`, `revalidate`, `REVALIDATE_HEADER`, `revalidateEndpoint`, `RevalidateEndpointOptions`, `RevalidateResult`, `ROOT_ATTRIBUTE`, `ROUTE_GLOBAL`, `RouteEntry`, `RouteMatch`, `RouteModule`, `RoutePattern`, `RouterState`, `RouteSearch`, `ScriptDescriptor`, `searchOf`, `SearchOf`, `searchOfChain`, `serializeData`, `serializeSearch`, `servePublicDir`, `ServePublicDirOptions`, `SERVER_FN_MODULE`, `SERVER_ONLY_MODULE`, `ServerOnly`, `setBlockerController`, `setBrowserNavigate`, `setSsrModuleLoader`, `ssrModuleLoader`, `SsrModuleLoader`, `startDynamicBoundaries`, `StaticBoundary`, `StaticBoundaryCache`, `StaticBoundaryImportEdge`, `StaticBoundaryRoot`, `StaticCtx`, `StaticPath`, `StaticPaths`, `StaticRoutes`, `STATUS_HEADER`, `statusPage`, `StatusPageOptions`, `Submission`, `SubmitOptions`, `unsafeInlineScript`, `UnsafeScriptDescriptor`, `withISR`
|
|
10379
11697
|
|
|
10380
11698
|
## @nifrajs/web-preact
|
|
10381
11699
|
|