You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(diagnostics): reallocate event preflight codes to AB4850/AB4851
AB4840-AB4842 are owned by the CLI surface projections of #596 (PR #616);
this branch's event-preflight export diagnostic moves to AB4850 and the
required-provider declaration diagnostic to AB4851 so the ranges stay
disjoint. Both codes are unused on main and on the #616 branch.
Co-authored-by: Zack Jackson <ScriptedAlchemy@users.noreply.github.com>
Copy file name to clipboardExpand all lines: .changeset/595-event-preflight-gates.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,4 +2,4 @@
2
2
"agent-bundle": patch
3
3
---
4
4
5
-
Allow an event route under `src/events/**` to declare a `preflight` gate — `export { default as preflight } from './<name>.js'`, a sync or async function that receives the frozen `{ canonical, host, signal, terminal }` context and returns `'execute'`, `{ outcome: 'continue' }`, or `{ outcome: 'deny', reason }` — which the generated hook entry runs on the canonical event before the rendered route runtime, React, or any application provider loads. `inspect`, `validate`, `build`, and `dev` report `AB4840` when `preflight` is declared inline, exported more than once, re-exported from a bare package or under a binding other than `default`, unresolvable, cyclic, or not a function, naming the route module and, once a re-export was found, its specifier. Allow an executed event route to declare the provider keys it requires (`config.providers: ['<key>', …]`) so only that subset resolves, in the existing deterministic key/source order with `processLifetime` seeded first; a route without a declaration still resolves every conventional provider, `[]` mounts `processLifetime` alone, and `AB4841` reports a malformed declaration, a duplicate key, the reserved `processLifetime`, or a key that matches no discovered `src/providers/*` module — unknown keys list the project's provider keys. Export `EventPreflight`, `EventPreflightContext`, `EventPreflightResult`, `validateEventPreflightResult`, and `eventFamilyAllowsPreflightDeny` from `agent-bundle`, `agent-bundle/api`, and `agent-bundle/routes`. Export the payload-free `EventTraceEvent` union, `createEventTracer`, and `installEventTraceObserver` for developer tooling. (#618)
5
+
Allow an event route under `src/events/**` to declare a `preflight` gate — `export { default as preflight } from './<name>.js'`, a sync or async function that receives the frozen `{ canonical, host, signal, terminal }` context and returns `'execute'`, `{ outcome: 'continue' }`, or `{ outcome: 'deny', reason }` — which the generated hook entry runs on the canonical event before the rendered route runtime, React, or any application provider loads. `inspect`, `validate`, `build`, and `dev` report `AB4850` when `preflight` is declared inline, exported more than once, re-exported from a bare package or under a binding other than `default`, unresolvable, cyclic, or not a function, naming the route module and, once a re-export was found, its specifier. Allow an executed event route to declare the provider keys it requires (`config.providers: ['<key>', …]`) so only that subset resolves, in the existing deterministic key/source order with `processLifetime` seeded first; a route without a declaration still resolves every conventional provider, `[]` mounts `processLifetime` alone, and `AB4851` reports a malformed declaration, a duplicate key, the reserved `processLifetime`, or a key that matches no discovered `src/providers/*` module — unknown keys list the project's provider keys. Export `EventPreflight`, `EventPreflightContext`, `EventPreflightResult`, `validateEventPreflightResult`, and `eventFamilyAllowsPreflightDeny` from `agent-bundle`, `agent-bundle/api`, and `agent-bundle/routes`. Export the payload-free `EventTraceEvent` union, `createEventTracer`, and `installEventTraceObserver` for developer tooling. (#618)
Copy file name to clipboardExpand all lines: docs/diagnostics.md
+5-5Lines changed: 5 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -30,7 +30,7 @@ even when no error diagnostic was reported.
30
30
|`AB4765`–`AB4766`| Artifact-hosted routed CLI: a target without the `cli` capability omits `bin/<name>.mjs`; a host-emitted file collides with it (see below). |
31
31
|`AB477x`| MCP App view compilation (`AB4770`: compile error with file, line, column and the bundler message; `AB4771`: compile warning; `AB4772`: emitted-size advisory; see below). |
32
32
|`AB490x`/`AB492x`| Conventional host components (#100 stage 2): rules `src/rules/*.mdc` (`AB4900`–`AB4908`) and commands `src/commands/*.md` (`AB4920`–`AB4928`), including per-host feature-set enforcement (`AB4907`/`AB4908`, `AB4927`/`AB4928`); see below. |
33
-
|`AB48xx`/`AB494x`| Route graph, state, layout (`AB4830`–`AB4832`), generated route declarations outside the TypeScript program (`AB4834`), route render budgets (`AB4835`), tool task support (`AB4836`), a route module that value-imports a compiler-carrying framework entry (`AB4837`), a CLI route `inputSchema` reference the static resolver cannot follow (`AB4838`) or that cycles (`AB4839`), an event route's `preflight` gate export (`AB4840`), an event route's declared provider keys (`AB4841`), and provider conventions (see below). |
33
+
|`AB48xx`/`AB494x`| Route graph, state, layout (`AB4830`–`AB4832`), generated route declarations outside the TypeScript program (`AB4834`), route render budgets (`AB4835`), tool task support (`AB4836`), a route module that value-imports a compiler-carrying framework entry (`AB4837`), a CLI route `inputSchema` reference the static resolver cannot follow (`AB4838`) or that cycles (`AB4839`), an event route's `preflight` gate export (`AB4850`), an event route's declared provider keys (`AB4851`), and provider conventions (see below). |
34
34
|`AB5000`| General CLI and adapter failures (see below). |
35
35
|`AB60xx`| Built-artifact validation, including schema documents and referenced files (`AB6005`: an emitted JavaScript module — a host-pack module or a package build `dist` bundle (`dist/bin/*.js`, the Flight workers, the `lib` entry), prebuilt payloads excepted — has an import that is neither a Node built-in nor a relative or `file:` specifier resolving to a listed regular file inside its tree, or a non-literal dynamic import; a `dist` finding names `dist/<path>`; `AB6011`/`AB6012`: a target's required pinned-schema document is missing or invalid; `AB6025`: a manifest-declared `logo` path is missing from the artifact or escapes the deploy tree; `AB6034`: emitted Skill Markdown has no instruction body; `AB6035`–`AB6038`: Agent Plugins portable validation, see below). |
36
36
|`AB6200`–`AB6202`| Workbench artifact inspection over published epochs: `AB6200` the epoch does not validate or its provenance is inconsistent, `AB6201` an epoch reference could not be released, `AB6202` unsafe runtime metadata (see below). |
@@ -1221,7 +1221,7 @@ the route names, never a second event route. A `preflight` declared inline in
1221
1221
the route module (`export const preflight = …`, `export function preflight`)
1222
1222
is rejected too: evaluating the route module evaluates its rendering and
1223
1223
provider imports, the very cost the gate exists to avoid. Every rejected form
1224
-
is `AB4840`, once per route on the route module; the route compiles without a
1224
+
is `AB4850`, once per route on the route module; the route compiles without a
1225
1225
gate beside the error, and because the diagnostic is an error the build fails
1226
1226
instead of silently taking the expensive path.
1227
1227
@@ -1239,7 +1239,7 @@ the generated `AgentBundleProviders` declares; `processLifetime` is not one of
1239
1239
them and must not be declared. The declaration is judged when the route graph
1240
1240
compiles: a declaration that is not an array of string literals, a key listed
1241
1241
twice, the reserved `processLifetime`, or a key naming no discovered provider
1242
-
module is `AB4841`, once per route with every defect in one message; a
1242
+
module is `AB4851`, once per route with every defect in one message; a
1243
1243
declaration with any defect selects nothing, so the build fails rather than
1244
1244
resolving a provider set the author did not write.
1245
1245
@@ -1285,8 +1285,8 @@ resolving a provider set the author did not write.
1285
1285
| `AB4837` | error | A route module of any kind except an App — a `src/cli/**` command, a `src/scripts/**` script, a tool, resource, or prompt route of a generated server, an event route — a layout, or a provider, or a module one of them reaches through relative value imports, imports `agent-bundle`, `agent-bundle/api`, `agent-bundle/config`, `agent-bundle/eval`, `agent-bundle/rstest`, `agent-bundle/test`, or `agent-bundle/test/browser` as a value (a static import whose binding is read at run time, `import 'agent-bundle/api'`, `import('agent-bundle/api')` with a literal specifier, or a non-type re-export). Those entries carry the compiler, and the generated executable is self-contained (#387): the bundler would inline the compiler and fail on the framework's runtime-relative module references (`Module not found: Can't resolve '../events'`), or the artifact validator would reject the inlined compiler's non-literal dynamic imports with `AB6005` — either way naming a generated file instead of the route (#558). Judged statically when the route graph compiles, so `inspect`, `validate`, `build`, and `dev` all report it, once per module, naming the route and the helper the import lives in. `import type`, `type`-qualified specifiers, and imports used only in type positions are elided by the bundler and never reported; routes of a server that is not generated (`custom`/`command`/`remote`, or an `AB4800` conflict) or of a CLI that is not generated (`conventional`, or an `AB4801` conflict) are never bundled, so they are not judged; likewise a layout that no bundled rendered route composes through (a worker imports only the layouts its routes reach: the tool, resource, and prompt routes of a generated server, the rendered `.tsx` commands of a generated CLI, and rendered `.tsx` scripts), and a provider in a project whose only executables are plain `.ts` scripts, which are bundled from their own source and mount none. Spawn the framework instead of importing it: serve an MCP App from a routed command with `spawnServeApp` from `agent-bundle/serve-app-command`, which runs `agent-bundle serve-app` as a child process; keep other framework calls in host processes (`package.json` scripts, a hand-written `.mjs` run from the checkout). The bundle-safe entries stay allowed: `agent-bundle/app` (the browser MCP App client, a leaf with no Zod, Node, or compiler import), `agent-bundle/routes`, `agent-bundle/launch-env`, `agent-bundle/meta`, `agent-bundle/mcp-apps`, `agent-bundle/mcp-entry`, `agent-bundle/cli-entry`, `agent-bundle/terminal-capability`, and `agent-bundle/serve-app-command`. |
1286
1286
| `AB4838` | error | A CLI route's `inputSchema` references a binding the static resolver cannot follow. The message is `CLI route <path> inputSchema: <chain> <reason>.` — the chain is the reference path from `inputSchema`, each step `<binding>`, or `<binding> (<module>)` when it crosses into another module (`inputSchema -> statusInputSchema (src/lib/protocol-schemas.ts) -> requestStatusSchema -> requestStatuses`), and the reason names the boundary: a specifier that `is not a relative module path`, one that `resolves outside the project` or `does not resolve to a module inside the project` (missing or unreadable), a target module that does not declare a top-level `export const <name>`, a binding that is not a top-level `const` (`let`/`var`, destructuring, a function, a class, a default or namespace import — the message says what it is), an identifier that `is neither a top-level const in this module nor a named import from a relative module`, or a dynamic initializer — one that is neither a method chain, an object or array literal, nor a static literal (`whose initializer is a call expression`, `a function expression`, `a template literal with substitutions`). Reported on the route module; the recovery names the supported forms — relative imports inside the project, `export const`, alias chains — then says to inspect again. Only CLI routes raise it, because only there the static contract is load-bearing: an MCP, script, or event route whose schema the resolver cannot follow compiles without a static contract, as an out-of-grammar inline schema does, and the runtime derives its MCP JSON Schema from the real zod object. A reference that resolves but whose schema leaves the grammar is `AB4814`. |
1287
1287
|`AB4839`| error | A CLI route's `inputSchema` reference chain is cyclic — `a` → `b` → `a`, within one module or across several: every visited `<module>#<binding>` is recorded and revisiting one stops the walk. The message is `CLI route <path> inputSchema: <chain> is a reference cycle.` and prints the cycle; it is reported on the route module, with the same recovery and the same CLI-only rule as `AB4838`. |
1288
-
| `AB4840` | error | An event route's `preflight` gate (#595) is not the one physically cheap form the compiler can bundle on its own. Rejected: `preflight` declared inline in the route module (`export const preflight = …`, `export function preflight`) or exported more than once; re-exported under a binding other than `default` (`export { gate as preflight } from './gate.js'`, `export { preflight } from './gate.js'`); re-exported from a non-relative specifier (a bare package such as `'@scope/gate'`); a relative target that is missing, unreadable, or part of a re-export cycle; a target default export that cannot be followed through an acyclic chain of relative default re-exports; or a target default export that is not a function the scan can see. The message names the route module and, once a re-export was found, its specifier. Judged statically when the route graph compiles, so `inspect`, `validate`, `build`, and `dev` all report it, once per route with the route module as `sourcePath`; the route compiles without a gate beside the error, and the build fails rather than silently taking the expensive rendered path. Write exactly `export { default as preflight } from './<name>.js'` in the route module, and make that module default-export one sync or async function receiving `{ canonical, host, signal, terminal }` and returning `'execute'`, `{ outcome: 'continue' }`, or `{ outcome: 'deny', reason }`. |
1289
-
|`AB4841`| error | An event route's static required-provider declaration (#595) does not select a known set of conventional providers: `config.providers` is not an array of provider-key strings; a key is declared more than once; a key is the reserved `processLifetime`; or a key matches no conventional provider the route graph discovered under `src/providers/`. The message names the route and every offending key. Declare each key exactly once, spelled as the camel-cased stem of its `src/providers/<name>.*` module, drop `processLifetime`, declare `[]` to mount `processLifetime` alone, or omit `config.providers` to preserve the all-provider compatibility default. |
1288
+
| `AB4850` | error | An event route's `preflight` gate (#595) is not the one physically cheap form the compiler can bundle on its own. Rejected: `preflight` declared inline in the route module (`export const preflight = …`, `export function preflight`) or exported more than once; re-exported under a binding other than `default` (`export { gate as preflight } from './gate.js'`, `export { preflight } from './gate.js'`); re-exported from a non-relative specifier (a bare package such as `'@scope/gate'`); a relative target that is missing, unreadable, or part of a re-export cycle; a target default export that cannot be followed through an acyclic chain of relative default re-exports; or a target default export that is not a function the scan can see. The message names the route module and, once a re-export was found, its specifier. Judged statically when the route graph compiles, so `inspect`, `validate`, `build`, and `dev` all report it, once per route with the route module as `sourcePath`; the route compiles without a gate beside the error, and the build fails rather than silently taking the expensive rendered path. Write exactly `export { default as preflight } from './<name>.js'` in the route module, and make that module default-export one sync or async function receiving `{ canonical, host, signal, terminal }` and returning `'execute'`, `{ outcome: 'continue' }`, or `{ outcome: 'deny', reason }`. |
1289
+
|`AB4851`| error | An event route's static required-provider declaration (#595) does not select a known set of conventional providers: `config.providers` is not an array of provider-key strings; a key is declared more than once; a key is the reserved `processLifetime`; or a key matches no conventional provider the route graph discovered under `src/providers/`. The message names the route and every offending key. Declare each key exactly once, spelled as the camel-cased stem of its `src/providers/<name>.*` module, drop `processLifetime`, declare `[]` to mount `processLifetime` alone, or omit `config.providers` to preserve the all-provider compatibility default. |
1290
1290
|`AB4940`| error | A conventional provider module has no default export or its default export is not a function. Default-export a factory receiving `{ invocation, plugin, signal }`. |
1291
1291
|`AB4941`| error | Two provider filenames derive the same camel-cased provider key. Rename one file so every provider key is unique. |
1292
1292
|`AB4942`| error | A provider filename derives the reserved `processLifetime` key. Rename the file so its camel-cased key does not collide with the framework-owned provider. |
`Event route module ${relativePath} re-exports preflight from ${JSON.stringify(declaration!.specifier)}, but that target is missing, unreadable, or cyclic.`,
`Event route module ${relativePath} re-exports preflight from ${JSON.stringify(declaration!.specifier)}, but its default export cannot be followed through an acyclic relative module chain.`,
0 commit comments