Problem
A real framework consumer, ScriptedAlchemy/cargo-hauler, has to duplicate a route schema because Agent Bundle's static CLI argv extraction cannot consume the same imported schema that MCP/runtime validation uses.
Concrete example: cargo-hauler/src/cli/status.tsx contains an inline z.object(...) solely because the compiler reports AB4814 when the route imports the canonical statusInputSchema from src/lib/protocol-schemas.ts. A test then exists to pin the duplicate CLI schema to the protocol schema.
Meanwhile src/mcp/hauler/tools/hauler_status.tsx can simply do:
export const inputSchema = statusInputSchema;
export const resultSchema = statusResultSchema;
The framework therefore turns one logical operation contract into two authored schemas plus a compatibility test.
This conflicts with #592's intended architecture: route discovery should produce one Application IR contract that downstream MCP, CLI, browser, test, and host projections consume.
Direction
Extend static route-contract extraction so local, statically analyzable schema imports are resolved rather than requiring the schema AST to be written inline in the route module.
This should be intentionally bounded. Do not execute arbitrary user modules during discovery.
A useful supported subset:
- relative imports only;
- exported
z.object, z.enum, arrays/unions/optional/default/describe and other already-supported schema AST forms;
- const references whose initializer is itself statically analyzable;
- one or more local hops with cycle detection;
- deterministic diagnostics naming the unresolved symbol/path when analysis crosses the supported boundary.
The compiler should canonicalize the result into Application IR once. CLI argv projection, MCP JSON Schema, generated route types, Workbench, and tests should consume that same normalized schema representation.
Longer-term API
The important contract is not "make AB4814 more permissive". It is:
source schema
↓
canonical RouteContract IR
├─ MCP input/output schema
├─ CLI argv grammar
├─ generated route/client types
├─ Workbench editor
└─ projection tests
The same mechanism should cover imported resultSchema, and should become the basis for the typed MCP App client requested separately rather than making Apps hand-copy protocol shapes.
Acceptance
Consumer evidence
Problem
A real framework consumer,
ScriptedAlchemy/cargo-hauler, has to duplicate a route schema because Agent Bundle's static CLI argv extraction cannot consume the same imported schema that MCP/runtime validation uses.Concrete example:
cargo-hauler/src/cli/status.tsxcontains an inlinez.object(...)solely because the compiler reportsAB4814when the route imports the canonicalstatusInputSchemafromsrc/lib/protocol-schemas.ts. A test then exists to pin the duplicate CLI schema to the protocol schema.Meanwhile
src/mcp/hauler/tools/hauler_status.tsxcan simply do:The framework therefore turns one logical operation contract into two authored schemas plus a compatibility test.
This conflicts with #592's intended architecture: route discovery should produce one Application IR contract that downstream MCP, CLI, browser, test, and host projections consume.
Direction
Extend static route-contract extraction so local, statically analyzable schema imports are resolved rather than requiring the schema AST to be written inline in the route module.
This should be intentionally bounded. Do not execute arbitrary user modules during discovery.
A useful supported subset:
z.object,z.enum, arrays/unions/optional/default/describe and other already-supported schema AST forms;The compiler should canonicalize the result into Application IR once. CLI argv projection, MCP JSON Schema, generated route types, Workbench, and tests should consume that same normalized schema representation.
Longer-term API
The important contract is not "make AB4814 more permissive". It is:
The same mechanism should cover imported
resultSchema, and should become the basis for the typed MCP App client requested separately rather than making Apps hand-copy protocol shapes.Acceptance
import { statusInputSchema } from '../../lib/protocol-schemas.js'and export it asinputSchemawhen the imported schema is statically analyzable.Consumer evidence
ScriptedAlchemy/cargo-hauler/src/cli/status.tsxScriptedAlchemy/cargo-hauler/src/mcp/hauler/tools/hauler_status.tsx