theokit 0.21.0 → 0.22.1

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.
Files changed (37) hide show
  1. package/dist/{agent-76WK2CZJ.js → agent-7IGDT55V.js} +2 -2
  2. package/dist/{build-TBV4KVXI.js → build-G7WWVZTL.js} +2 -2
  3. package/dist/chunk-2CVV6CNN.js +174 -0
  4. package/dist/chunk-2CVV6CNN.js.map +1 -0
  5. package/dist/{chunk-3WOODHXK.js → chunk-AYZCGJXA.js} +12 -6
  6. package/dist/chunk-AYZCGJXA.js.map +1 -0
  7. package/dist/{chunk-7PFHQ56Q.js → chunk-BLL5LY7R.js} +39 -15
  8. package/dist/chunk-BLL5LY7R.js.map +1 -0
  9. package/dist/{chunk-23T4CO4M.js → chunk-JITNAZXE.js} +2 -2
  10. package/dist/{chunk-DXF64KS5.js → chunk-LGVVX3BV.js} +30 -12
  11. package/dist/chunk-LGVVX3BV.js.map +1 -0
  12. package/dist/{chunk-W4YO6S4I.js → chunk-W4XWVTN4.js} +112 -67
  13. package/dist/chunk-W4XWVTN4.js.map +1 -0
  14. package/dist/cli/index.js +5 -5
  15. package/dist/{dev-NHHTXOA4.js → dev-SHAN56K5.js} +4 -4
  16. package/dist/index.js +2 -2
  17. package/dist/{mcp-HP5RVOOZ.js → mcp-P4MHP3VA.js} +4 -4
  18. package/dist/{mcp-HP5RVOOZ.js.map → mcp-P4MHP3VA.js.map} +1 -1
  19. package/dist/server/index.d.ts +162 -1
  20. package/dist/server/index.js +60 -3
  21. package/dist/server/index.js.map +1 -1
  22. package/dist/{start-ILT6E25Q.js → start-RD5WQMIH.js} +6 -4
  23. package/dist/{start-ILT6E25Q.js.map → start-RD5WQMIH.js.map} +1 -1
  24. package/dist/vite-plugin/index.js +2 -2
  25. package/dist/{vite-plugin-3UDOJGO5.js → vite-plugin-A7WGYEMD.js} +4 -4
  26. package/package.json +1 -1
  27. package/dist/chunk-3WOODHXK.js.map +0 -1
  28. package/dist/chunk-7PFHQ56Q.js.map +0 -1
  29. package/dist/chunk-DMC6HYUR.js +0 -141
  30. package/dist/chunk-DMC6HYUR.js.map +0 -1
  31. package/dist/chunk-DXF64KS5.js.map +0 -1
  32. package/dist/chunk-W4YO6S4I.js.map +0 -1
  33. /package/dist/{agent-76WK2CZJ.js.map → agent-7IGDT55V.js.map} +0 -0
  34. /package/dist/{build-TBV4KVXI.js.map → build-G7WWVZTL.js.map} +0 -0
  35. /package/dist/{chunk-23T4CO4M.js.map → chunk-JITNAZXE.js.map} +0 -0
  36. /package/dist/{dev-NHHTXOA4.js.map → dev-SHAN56K5.js.map} +0 -0
  37. /package/dist/{vite-plugin-3UDOJGO5.js.map → vite-plugin-A7WGYEMD.js.map} +0 -0
@@ -8,9 +8,9 @@ import {
8
8
  } from "./chunk-HNBWZKIQ.js";
9
9
  import {
10
10
  theoPluginAsync
11
- } from "./chunk-3WOODHXK.js";
12
- import "./chunk-DXF64KS5.js";
13
- import "./chunk-DMC6HYUR.js";
11
+ } from "./chunk-AYZCGJXA.js";
12
+ import "./chunk-LGVVX3BV.js";
13
+ import "./chunk-2CVV6CNN.js";
14
14
  import "./chunk-M6NMS5LR.js";
15
15
  import "./chunk-IEES3CHD.js";
16
16
  import {
@@ -111,4 +111,4 @@ export {
111
111
  devCommand,
112
112
  startDevServer
113
113
  };
114
- //# sourceMappingURL=dev-NHHTXOA4.js.map
114
+ //# sourceMappingURL=dev-SHAN56K5.js.map
package/dist/index.js CHANGED
@@ -8,11 +8,11 @@ import {
8
8
  scanRoutes,
9
9
  theoConfigSchema,
10
10
  theoPlugin
11
- } from "./chunk-7PFHQ56Q.js";
11
+ } from "./chunk-BLL5LY7R.js";
12
12
  import "./chunk-D7ZH7DTG.js";
13
13
  import "./chunk-RSVN727G.js";
14
14
  import "./chunk-7BIM27LV.js";
15
- import "./chunk-W4YO6S4I.js";
15
+ import "./chunk-W4XWVTN4.js";
16
16
  import "./chunk-5QW7IQQU.js";
17
17
  import "./chunk-IAJ2JVEH.js";
18
18
  import "./chunk-VMEWD57H.js";
@@ -2,11 +2,11 @@
2
2
  import "tsx/esm";
3
3
  import {
4
4
  createAgentSsrLoader
5
- } from "./chunk-23T4CO4M.js";
5
+ } from "./chunk-JITNAZXE.js";
6
6
  import {
7
7
  extractAppResources,
8
8
  handleMcpJsonRpc
9
- } from "./chunk-DMC6HYUR.js";
9
+ } from "./chunk-2CVV6CNN.js";
10
10
  import "./chunk-M6NMS5LR.js";
11
11
  import "./chunk-GDN3PXFH.js";
12
12
  import {
@@ -31,7 +31,7 @@ async function handleMcpStdioLine(line, mod, name, appResources = []) {
31
31
  error: { code: -32700, message: "Parse error" }
32
32
  });
33
33
  }
34
- const response = handleMcpJsonRpc(mod, name, body, appResources);
34
+ const response = await handleMcpJsonRpc(mod, name, body, appResources);
35
35
  const payload = await response.json();
36
36
  return JSON.stringify(payload);
37
37
  }
@@ -75,4 +75,4 @@ async function mcpCommand(name, deps = {}) {
75
75
  export {
76
76
  mcpCommand
77
77
  };
78
- //# sourceMappingURL=mcp-HP5RVOOZ.js.map
78
+ //# sourceMappingURL=mcp-P4MHP3VA.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/commands/mcp.ts","../src/server/agent/mcp-stdio.ts"],"sourcesContent":["/**\n * `theokit mcp <agent>` — expose a scanned agent as an MCP server over stdio.\n *\n * The stdio sibling of the M16 HTTP route (`POST /api/agents/<name>/mcp`): a desktop MCP client\n * (e.g. Claude Desktop) spawns this command and speaks newline-delimited JSON-RPC over the pipe.\n * It reuses the framework's OWN `serveMcpStdio` / `handleMcpJsonRpc` (no LLM call, no runtime — a\n * TRANSPORT, like the HTTP route). `deps` is injectable so the routing is tested without Vite/stdin.\n */\nimport { createInterface } from 'node:readline'\n\nimport { extractAppResources } from '../../server/agent/mcp-app-resources.js'\nimport { type StdioStreams, serveMcpStdio } from '../../server/agent/mcp-stdio.js'\nimport { scanAgents } from '../../server/scan/agent-scan.js'\n\nimport { createAgentSsrLoader } from './agent.js'\n\nexport interface McpCommandDeps {\n projectRoot?: string\n /** Load a TS agent module; defaults to the framework's Vite SSR loader (same transpile as dev). */\n loadModule?: (filePath: string) => Promise<Record<string, unknown>>\n /** stdio streams; defaults to `readline(process.stdin)` + `process.stdout`. Injected in tests. */\n streams?: StdioStreams\n /** Agents dir name (config `agentsDir`); defaults to the loaded config's value (\"agents\"). Tests inject it. */\n agentsDir?: string\n}\n\nexport async function mcpCommand(name: string, deps: McpCommandDeps = {}): Promise<void> {\n const projectRoot = deps.projectRoot ?? process.cwd()\n // #95 follow-up — resolve agents dir from config (default \"agents\") so `agentsDir` is honored here too.\n const agentsDir =\n deps.agentsDir ??\n (await (await import('../../config/load-config.js')).loadConfig(projectRoot)).agentsDir\n const agent = scanAgents(projectRoot, agentsDir).find((a) => a.name === name)\n if (!agent) {\n const names = scanAgents(projectRoot, agentsDir)\n .map((a) => a.name)\n .join(', ')\n throw new Error(\n `theokit mcp: agent '${name}' not found. Available: ${names || '(none in agents/)'}`,\n )\n }\n\n let loadModule = deps.loadModule\n let dispose: (() => Promise<void>) | undefined\n if (!loadModule) {\n const loader = await createAgentSsrLoader(projectRoot)\n loadModule = loader.load\n dispose = loader.dispose\n }\n\n const streams =\n deps.streams ??\n ({\n lines: createInterface({ input: process.stdin }),\n write: (line: string) => process.stdout.write(line),\n } satisfies StdioStreams)\n\n try {\n const mod = await loadModule(agent.filePath)\n await serveMcpStdio(mod, agent.name, extractAppResources(mod), streams)\n } finally {\n if (dispose) await dispose()\n }\n}\n","/**\n * MCP stdio transport (M16 follow-up) — expose a TheoKit agent as an MCP server over stdin/stdout,\n * the sibling of the M16 HTTP route (`POST /api/agents/<name>/mcp`). A desktop MCP client (e.g.\n * Claude Desktop) spawns `theokit mcp <agent>` and speaks newline-delimited JSON-RPC over the pipe.\n *\n * This is a TRANSPORT over the framework's OWN {@link handleMcpJsonRpc} — it reuses the exact handler\n * the HTTP route uses; it calls no LLM, spawns no MCP client, and reimplements no runtime (G2 /\n * sdk-runtime.md). Distinct from the SDK's MCP CLIENT stdio (which spawns external MCP servers via\n * `mcpServers` command/args) — that stays SDK-side. Here TheoKit is the SERVER. The framework-side\n * placement of this server-exposure transport is recorded in ADR-0042 (refining ADR-0040's M16 note).\n */\nimport type { AppResource } from './mcp-app-resources.js'\nimport { handleMcpJsonRpc } from './mcp-handler.js'\n\n/**\n * Handle one newline-delimited JSON-RPC line. Returns the response line to write to stdout, or\n * `null` for a blank line (nothing to emit). A malformed JSON line yields a `-32700` (Parse error)\n * envelope — never throws, so the stdio loop never dies on bad input.\n */\nexport async function handleMcpStdioLine(\n line: string,\n mod: unknown,\n name: string,\n appResources: readonly AppResource[] = [],\n): Promise<string | null> {\n const trimmed = line.trim()\n if (trimmed.length === 0) return null\n let body: unknown\n try {\n body = JSON.parse(trimmed)\n } catch {\n return JSON.stringify({\n jsonrpc: '2.0',\n id: null,\n error: { code: -32700, message: 'Parse error' },\n })\n }\n const response = handleMcpJsonRpc(mod, name, body, appResources)\n const payload: unknown = await response.json()\n return JSON.stringify(payload)\n}\n\n/** A minimal readable line source (an async iterable of lines) + a writable sink. */\nexport interface StdioStreams {\n /** Async iterable of newline-delimited input lines (e.g. `readline.createInterface({ input })`). */\n lines: AsyncIterable<string>\n /** Write a response line (the caller appends no newline). */\n write: (line: string) => void\n}\n\n/**\n * Drive the MCP stdio server loop: for each input line, dispatch via {@link handleMcpStdioLine} and\n * write the response line (with a trailing `\\n`). Returns when the input stream ends (EOF).\n */\nexport async function serveMcpStdio(\n mod: unknown,\n name: string,\n appResources: readonly AppResource[],\n streams: StdioStreams,\n): Promise<void> {\n for await (const line of streams.lines) {\n const out = await handleMcpStdioLine(line, mod, name, appResources)\n if (out !== null) streams.write(`${out}\\n`)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAQA,SAAS,uBAAuB;;;ACWhC,eAAsB,mBACpB,MACA,KACA,MACA,eAAuC,CAAC,GAChB;AACxB,QAAM,UAAU,KAAK,KAAK;AAC1B,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,MAAI;AACJ,MAAI;AACF,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO,KAAK,UAAU;AAAA,MACpB,SAAS;AAAA,MACT,IAAI;AAAA,MACJ,OAAO,EAAE,MAAM,QAAQ,SAAS,cAAc;AAAA,IAChD,CAAC;AAAA,EACH;AACA,QAAM,WAAW,iBAAiB,KAAK,MAAM,MAAM,YAAY;AAC/D,QAAM,UAAmB,MAAM,SAAS,KAAK;AAC7C,SAAO,KAAK,UAAU,OAAO;AAC/B;AAcA,eAAsB,cACpB,KACA,MACA,cACA,SACe;AACf,mBAAiB,QAAQ,QAAQ,OAAO;AACtC,UAAM,MAAM,MAAM,mBAAmB,MAAM,KAAK,MAAM,YAAY;AAClE,QAAI,QAAQ,KAAM,SAAQ,MAAM,GAAG,GAAG;AAAA,CAAI;AAAA,EAC5C;AACF;;;ADtCA,eAAsB,WAAW,MAAc,OAAuB,CAAC,GAAkB;AACvF,QAAM,cAAc,KAAK,eAAe,QAAQ,IAAI;AAEpD,QAAM,YACJ,KAAK,cACJ,OAAO,MAAM,OAAO,2BAA6B,GAAG,WAAW,WAAW,GAAG;AAChF,QAAM,QAAQ,WAAW,aAAa,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AAC5E,MAAI,CAAC,OAAO;AACV,UAAM,QAAQ,WAAW,aAAa,SAAS,EAC5C,IAAI,CAAC,MAAM,EAAE,IAAI,EACjB,KAAK,IAAI;AACZ,UAAM,IAAI;AAAA,MACR,uBAAuB,IAAI,2BAA2B,SAAS,mBAAmB;AAAA,IACpF;AAAA,EACF;AAEA,MAAI,aAAa,KAAK;AACtB,MAAI;AACJ,MAAI,CAAC,YAAY;AACf,UAAM,SAAS,MAAM,qBAAqB,WAAW;AACrD,iBAAa,OAAO;AACpB,cAAU,OAAO;AAAA,EACnB;AAEA,QAAM,UACJ,KAAK,WACJ;AAAA,IACC,OAAO,gBAAgB,EAAE,OAAO,QAAQ,MAAM,CAAC;AAAA,IAC/C,OAAO,CAAC,SAAiB,QAAQ,OAAO,MAAM,IAAI;AAAA,EACpD;AAEF,MAAI;AACF,UAAM,MAAM,MAAM,WAAW,MAAM,QAAQ;AAC3C,UAAM,cAAc,KAAK,MAAM,MAAM,oBAAoB,GAAG,GAAG,OAAO;AAAA,EACxE,UAAE;AACA,QAAI,QAAS,OAAM,QAAQ;AAAA,EAC7B;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/cli/commands/mcp.ts","../src/server/agent/mcp-stdio.ts"],"sourcesContent":["/**\n * `theokit mcp <agent>` — expose a scanned agent as an MCP server over stdio.\n *\n * The stdio sibling of the M16 HTTP route (`POST /api/agents/<name>/mcp`): a desktop MCP client\n * (e.g. Claude Desktop) spawns this command and speaks newline-delimited JSON-RPC over the pipe.\n * It reuses the framework's OWN `serveMcpStdio` / `handleMcpJsonRpc` (no LLM call, no runtime — a\n * TRANSPORT, like the HTTP route). `deps` is injectable so the routing is tested without Vite/stdin.\n */\nimport { createInterface } from 'node:readline'\n\nimport { extractAppResources } from '../../server/agent/mcp-app-resources.js'\nimport { type StdioStreams, serveMcpStdio } from '../../server/agent/mcp-stdio.js'\nimport { scanAgents } from '../../server/scan/agent-scan.js'\n\nimport { createAgentSsrLoader } from './agent.js'\n\nexport interface McpCommandDeps {\n projectRoot?: string\n /** Load a TS agent module; defaults to the framework's Vite SSR loader (same transpile as dev). */\n loadModule?: (filePath: string) => Promise<Record<string, unknown>>\n /** stdio streams; defaults to `readline(process.stdin)` + `process.stdout`. Injected in tests. */\n streams?: StdioStreams\n /** Agents dir name (config `agentsDir`); defaults to the loaded config's value (\"agents\"). Tests inject it. */\n agentsDir?: string\n}\n\nexport async function mcpCommand(name: string, deps: McpCommandDeps = {}): Promise<void> {\n const projectRoot = deps.projectRoot ?? process.cwd()\n // #95 follow-up — resolve agents dir from config (default \"agents\") so `agentsDir` is honored here too.\n const agentsDir =\n deps.agentsDir ??\n (await (await import('../../config/load-config.js')).loadConfig(projectRoot)).agentsDir\n const agent = scanAgents(projectRoot, agentsDir).find((a) => a.name === name)\n if (!agent) {\n const names = scanAgents(projectRoot, agentsDir)\n .map((a) => a.name)\n .join(', ')\n throw new Error(\n `theokit mcp: agent '${name}' not found. Available: ${names || '(none in agents/)'}`,\n )\n }\n\n let loadModule = deps.loadModule\n let dispose: (() => Promise<void>) | undefined\n if (!loadModule) {\n const loader = await createAgentSsrLoader(projectRoot)\n loadModule = loader.load\n dispose = loader.dispose\n }\n\n const streams =\n deps.streams ??\n ({\n lines: createInterface({ input: process.stdin }),\n write: (line: string) => process.stdout.write(line),\n } satisfies StdioStreams)\n\n try {\n const mod = await loadModule(agent.filePath)\n await serveMcpStdio(mod, agent.name, extractAppResources(mod), streams)\n } finally {\n if (dispose) await dispose()\n }\n}\n","/**\n * MCP stdio transport (M16 follow-up) — expose a TheoKit agent as an MCP server over stdin/stdout,\n * the sibling of the M16 HTTP route (`POST /api/agents/<name>/mcp`). A desktop MCP client (e.g.\n * Claude Desktop) spawns `theokit mcp <agent>` and speaks newline-delimited JSON-RPC over the pipe.\n *\n * This is a TRANSPORT over the framework's OWN {@link handleMcpJsonRpc} — it reuses the exact handler\n * the HTTP route uses; it calls no LLM, spawns no MCP client, and reimplements no runtime (G2 /\n * sdk-runtime.md). Distinct from the SDK's MCP CLIENT stdio (which spawns external MCP servers via\n * `mcpServers` command/args) — that stays SDK-side. Here TheoKit is the SERVER. The framework-side\n * placement of this server-exposure transport is recorded in ADR-0042 (refining ADR-0040's M16 note).\n */\nimport type { AppResource } from './mcp-app-resources.js'\nimport { handleMcpJsonRpc } from './mcp-handler.js'\n\n/**\n * Handle one newline-delimited JSON-RPC line. Returns the response line to write to stdout, or\n * `null` for a blank line (nothing to emit). A malformed JSON line yields a `-32700` (Parse error)\n * envelope — never throws, so the stdio loop never dies on bad input.\n */\nexport async function handleMcpStdioLine(\n line: string,\n mod: unknown,\n name: string,\n appResources: readonly AppResource[] = [],\n): Promise<string | null> {\n const trimmed = line.trim()\n if (trimmed.length === 0) return null\n let body: unknown\n try {\n body = JSON.parse(trimmed)\n } catch {\n return JSON.stringify({\n jsonrpc: '2.0',\n id: null,\n error: { code: -32700, message: 'Parse error' },\n })\n }\n const response = await handleMcpJsonRpc(mod, name, body, appResources)\n const payload: unknown = await response.json()\n return JSON.stringify(payload)\n}\n\n/** A minimal readable line source (an async iterable of lines) + a writable sink. */\nexport interface StdioStreams {\n /** Async iterable of newline-delimited input lines (e.g. `readline.createInterface({ input })`). */\n lines: AsyncIterable<string>\n /** Write a response line (the caller appends no newline). */\n write: (line: string) => void\n}\n\n/**\n * Drive the MCP stdio server loop: for each input line, dispatch via {@link handleMcpStdioLine} and\n * write the response line (with a trailing `\\n`). Returns when the input stream ends (EOF).\n */\nexport async function serveMcpStdio(\n mod: unknown,\n name: string,\n appResources: readonly AppResource[],\n streams: StdioStreams,\n): Promise<void> {\n for await (const line of streams.lines) {\n const out = await handleMcpStdioLine(line, mod, name, appResources)\n if (out !== null) streams.write(`${out}\\n`)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAQA,SAAS,uBAAuB;;;ACWhC,eAAsB,mBACpB,MACA,KACA,MACA,eAAuC,CAAC,GAChB;AACxB,QAAM,UAAU,KAAK,KAAK;AAC1B,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,MAAI;AACJ,MAAI;AACF,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO,KAAK,UAAU;AAAA,MACpB,SAAS;AAAA,MACT,IAAI;AAAA,MACJ,OAAO,EAAE,MAAM,QAAQ,SAAS,cAAc;AAAA,IAChD,CAAC;AAAA,EACH;AACA,QAAM,WAAW,MAAM,iBAAiB,KAAK,MAAM,MAAM,YAAY;AACrE,QAAM,UAAmB,MAAM,SAAS,KAAK;AAC7C,SAAO,KAAK,UAAU,OAAO;AAC/B;AAcA,eAAsB,cACpB,KACA,MACA,cACA,SACe;AACf,mBAAiB,QAAQ,QAAQ,OAAO;AACtC,UAAM,MAAM,MAAM,mBAAmB,MAAM,KAAK,MAAM,YAAY;AAClE,QAAI,QAAQ,KAAM,SAAQ,MAAM,GAAG,GAAG;AAAA,CAAI;AAAA,EAC5C;AACF;;;ADtCA,eAAsB,WAAW,MAAc,OAAuB,CAAC,GAAkB;AACvF,QAAM,cAAc,KAAK,eAAe,QAAQ,IAAI;AAEpD,QAAM,YACJ,KAAK,cACJ,OAAO,MAAM,OAAO,2BAA6B,GAAG,WAAW,WAAW,GAAG;AAChF,QAAM,QAAQ,WAAW,aAAa,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AAC5E,MAAI,CAAC,OAAO;AACV,UAAM,QAAQ,WAAW,aAAa,SAAS,EAC5C,IAAI,CAAC,MAAM,EAAE,IAAI,EACjB,KAAK,IAAI;AACZ,UAAM,IAAI;AAAA,MACR,uBAAuB,IAAI,2BAA2B,SAAS,mBAAmB;AAAA,IACpF;AAAA,EACF;AAEA,MAAI,aAAa,KAAK;AACtB,MAAI;AACJ,MAAI,CAAC,YAAY;AACf,UAAM,SAAS,MAAM,qBAAqB,WAAW;AACrD,iBAAa,OAAO;AACpB,cAAU,OAAO;AAAA,EACnB;AAEA,QAAM,UACJ,KAAK,WACJ;AAAA,IACC,OAAO,gBAAgB,EAAE,OAAO,QAAQ,MAAM,CAAC;AAAA,IAC/C,OAAO,CAAC,SAAiB,QAAQ,OAAO,MAAM,IAAI;AAAA,EACpD;AAEF,MAAI;AACF,UAAM,MAAM,MAAM,WAAW,MAAM,QAAQ;AAC3C,UAAM,cAAc,KAAK,MAAM,MAAM,oBAAoB,GAAG,GAAG,OAAO;AAAA,EACxE,UAAE;AACA,QAAI,QAAS,OAAM,QAAQ;AAAA,EAC7B;AACF;","names":[]}
@@ -1115,6 +1115,167 @@ interface ExecuteWebRequestOptions {
1115
1115
  }
1116
1116
  declare function executeWebRequest(request: Request, routeModule: WebRouteModule, opts?: ExecuteWebRequestOptions): Promise<Response>;
1117
1117
 
1118
+ /**
1119
+ * M33 — the SINGLE route-input validation pipeline, shared by the HTTP path (`web-handler.ts`
1120
+ * `runHandler`) and the in-process caller (`in-process-caller.ts` `callProcedure`).
1121
+ *
1122
+ * Both surfaces validate the same three channels (`query`/`body`/`params`) against the same
1123
+ * `RouteConfig` Zod schemas. Extracting the logic here means there is ONE validation pipeline
1124
+ * (no duplication, no drift) — each caller only differs in how it MAPS a failure: the HTTP path
1125
+ * emits a 400 Response, the in-process path throws a typed error.
1126
+ */
1127
+
1128
+ /** The three request-input channels a route may declare a Zod schema for. */
1129
+ type RouteInputChannel = 'query' | 'body' | 'params';
1130
+ /**
1131
+ * The minimal structural shape the validator needs: the three optional channel schemas. Both
1132
+ * `RouteConfig` (the 5-arity generic contract) and `WebRouteHandlerConfig` (the Web runtime shape)
1133
+ * satisfy this — the validator depends only on the schemas, not the full route generic.
1134
+ */
1135
+ interface RouteInputSchemas {
1136
+ query?: z.ZodType;
1137
+ body?: z.ZodType;
1138
+ params?: z.ZodType;
1139
+ }
1140
+ /** Raw (pre-validation) channel values. A channel absent from the config passes through unchanged. */
1141
+ interface RawRouteInput {
1142
+ query?: unknown;
1143
+ body?: unknown;
1144
+ params?: unknown;
1145
+ }
1146
+ /** Discriminated result — each caller maps `ok:false` to its own surface (Response vs throw). */
1147
+ type RouteInputValidation = {
1148
+ ok: true;
1149
+ query: unknown;
1150
+ body: unknown;
1151
+ params: unknown;
1152
+ } | {
1153
+ ok: false;
1154
+ channel: RouteInputChannel;
1155
+ error: z.ZodError;
1156
+ };
1157
+ /**
1158
+ * Validate the three input channels against the route's declared Zod schemas. A channel with no
1159
+ * declared schema passes its raw value through. First failing channel short-circuits (query → body
1160
+ * → params order, matching `runHandler`).
1161
+ */
1162
+ declare function validateRouteInput(config: RouteInputSchemas, raw: RawRouteInput): RouteInputValidation;
1163
+
1164
+ /**
1165
+ * M33 Phase 1 — `callProcedure`, the in-process typed caller.
1166
+ *
1167
+ * The load-bearing seam for non-HTTP surfaces (TUI / Tauri / MCP-tools): invoke a route's shared
1168
+ * logic with STRUCTURED input, WITHOUT going through the HTTP transport (no URL/body parsing, no
1169
+ * middleware chain, no Response). It reuses the SAME Zod validation pipeline as the HTTP path
1170
+ * (`validateRouteInput`) so there is no drift, and reuses the SAME `config.response` server-fault
1171
+ * check. Failures throw typed errors (there is no HTTP status off-web).
1172
+ *
1173
+ * Prior art: tRPC `callProcedure` / `createCallerFactory`
1174
+ * (`.claude/knowledge-base/references/trpc/packages/server/src/unstable-core-do-not-import/router.ts:401,441`).
1175
+ *
1176
+ * Design (ADR-0044 / blueprint §5.4): the AUTHOR passes structured input `{query?, body?, params?}`
1177
+ * — never synthesizes a Request. A minimal in-process `Request` is provided to the handler ONLY so
1178
+ * handlers that read `request.headers`/`request.url` still work (opencode's proven pattern); the
1179
+ * input itself is NOT parsed from it.
1180
+ */
1181
+
1182
+ /** Structured input for an in-process procedure call — one object per declared channel. */
1183
+ type ProcedureInput = RawRouteInput;
1184
+ /**
1185
+ * Thrown when structured input fails the route's Zod validation. The in-process analog of the HTTP
1186
+ * 400 — carries the failing channel + the Zod issues (typed error, not a magic value; Rule 8).
1187
+ */
1188
+ declare class ProcedureInputError extends Error {
1189
+ readonly channel: RouteInputChannel;
1190
+ readonly issues: z.core.$ZodIssue[];
1191
+ constructor(channel: RouteInputChannel, error: z.ZodError);
1192
+ }
1193
+ /**
1194
+ * Thrown when the handler's plain-object return drifts from `config.response` — a SERVER fault
1195
+ * (the handler violated its own declared contract), mirroring the HTTP path's 500 as a throw.
1196
+ */
1197
+ declare class ProcedureOutputError extends Error {
1198
+ readonly issues: z.core.$ZodIssue[];
1199
+ constructor(error: z.ZodError);
1200
+ }
1201
+ /**
1202
+ * Invoke a route/procedure's handler in-process with structured, Zod-validated input.
1203
+ *
1204
+ * @param config the `RouteConfig` (what `route().build()` produces).
1205
+ * @param input structured `{query?, body?, params?}` — validated by the route's schemas.
1206
+ * @param ctx the typed run-context the handler receives (built by the CALLER — a TUI/Tauri/MCP
1207
+ * surface supplies its own ctx factory; there is no HTTP middleware chain here).
1208
+ * @returns the handler's result (validated against `config.response` when declared).
1209
+ * @throws ProcedureInputError on invalid structured input (the off-web analog of a 400).
1210
+ * @throws ProcedureOutputError on a handler output that drifts from `config.response` (server fault).
1211
+ */
1212
+ declare function callProcedure(config: RouteConfig<z.ZodType, z.ZodType, z.ZodType>, input?: ProcedureInput, ctx?: unknown): Promise<unknown>;
1213
+
1214
+ /**
1215
+ * M33 Phase 1 — the ctx reconciliation contract (ADR-0044 D4 / blueprint §5.2, §8.5).
1216
+ *
1217
+ * ## The problem the deep research verified against our own code
1218
+ *
1219
+ * At runtime (`execute.ts:122-165`) the handler's `ctx` is written by THREE sources, not one:
1220
+ *
1221
+ * 1. **the user `context.ts` factory** — via `runMiddlewareAndContext` (`execute.ts:131`). This is
1222
+ * the ONLY writer the author controls + declares a shape for. **This is the typed surface.**
1223
+ * 2. **plugin decorations** — `pluginRunner.applyDecorations(ctx)` (`execute.ts:124,136`). Plugins
1224
+ * add arbitrary keys (`decorateRequest`) whose types the route author does not see.
1225
+ * 3. **the jobs backend** — `ctx.queue` injected when `jobs.backend` is configured (`execute.ts:141-150`).
1226
+ *
1227
+ * A naive "infer `TCtx` from everything on `ctx`" would LIE — it cannot see writers (2) and (3), so
1228
+ * `ctx.queue` / plugin keys would be typed as present when they are not (or vice-versa). That is the
1229
+ * exact Hono/global-augmentation failure the blueprint refuted (§8.5). oRPC/tRPC avoid it only
1230
+ * because middleware is their SOLE ctx writer; TheoKit is multi-writer.
1231
+ *
1232
+ * ## The reconciliation (what this contract locks)
1233
+ *
1234
+ * The typed `TCtx` a route handler sees reflects **only writer (1)** — the user `context.ts` factory
1235
+ * (`ContextValue` below). Writers (2) and (3) are **explicitly untyped** on the route surface:
1236
+ *
1237
+ * - `ctx.queue` (jobs) is reached through the dedicated {@link JobsAugmentedCtx} helper, NOT the
1238
+ * inferred `TCtx` — a handler that needs the queue opts into the augmented type explicitly.
1239
+ * - plugin-decorated keys are `unknown` by design (a plugin is a cross-cutting, per-app concern;
1240
+ * typing them into every route's `TCtx` would couple routes to plugin internals — G5).
1241
+ *
1242
+ * This keeps the LOCKED 5-arity `RouteConfig` generic (`route-config-generic-arity.test.ts`, GAP-4)
1243
+ * intact — `TCtx` stays the single typed ctx slot; we only define WHICH writer it corresponds to,
1244
+ * so `runtime ⊇ type` holds honestly (the type is a sound subset of the runtime ctx, never a lie).
1245
+ *
1246
+ * Type-tests proving this live in `tests/ctx-reconciliation.test-d.ts`.
1247
+ */
1248
+ /**
1249
+ * The typed run-context a route handler sees = the return of the user `context.ts` factory.
1250
+ * `TValue` is inferred from that factory at the web adapter seam; it EXCLUDES plugin decorations and
1251
+ * `ctx.queue` (those are not part of the author-declared shape).
1252
+ */
1253
+ type ContextValue<TValue extends Record<string, unknown> = Record<string, unknown>> = TValue;
1254
+ /** The `ctx.queue` client shape injected by the jobs backend (writer 3). Reached explicitly. */
1255
+ interface QueueClientLike {
1256
+ enqueue(name: string, input: unknown): void | Promise<void>;
1257
+ }
1258
+ /**
1259
+ * Opt-in augmentation for handlers that read `ctx.queue`. A route that uses the jobs queue annotates
1260
+ * its ctx as `JobsAugmentedCtx<MyCtx>` — making the jobs dependency explicit in the type, instead of
1261
+ * silently assuming `ctx.queue` exists on every route (which would lie when `jobs.backend` is unset).
1262
+ */
1263
+ type JobsAugmentedCtx<TValue extends Record<string, unknown> = Record<string, unknown>> = TValue & {
1264
+ queue: QueueClientLike;
1265
+ };
1266
+ /**
1267
+ * The three runtime ctx writers, named for documentation + the type-test. This is the reconciliation
1268
+ * artifact the plan requires as a deliverable (not a footnote).
1269
+ */
1270
+ declare const CTX_WRITERS: {
1271
+ /** Writer 1 — user `context.ts` factory. THE typed surface (`TCtx`). execute.ts:131 */
1272
+ readonly contextFactory: "context.ts";
1273
+ /** Writer 2 — plugin `decorateRequest`. Untyped on the route surface. execute.ts:124,136 */
1274
+ readonly pluginDecorations: "pluginRunner.applyDecorations";
1275
+ /** Writer 3 — jobs backend `ctx.queue`. Reached via JobsAugmentedCtx, not TCtx. execute.ts:141-150 */
1276
+ readonly jobsQueue: "jobBackend";
1277
+ };
1278
+
1118
1279
  /**
1119
1280
  * Types for `loadEnv()` — env auto-load utility (Phase 1 of
1120
1281
  * docs/plans/framework-zero-config-polish-plan.md).
@@ -1156,4 +1317,4 @@ interface LoadEnvResult {
1156
1317
  declare function _resetEnvCache(): void;
1157
1318
  declare function loadEnv(options?: LoadEnvOptions): LoadEnvResult;
1158
1319
 
1159
- export { type AcpToolConfig, ActionError, type ActionErrorCode, ActionInputError, type ActionManifestEntry, type ActionResult, type AppResource, type AppResourceInput, type BodyParserOptions, DEFAULT_MAX_AGE as CACHE_DEFAULT_MAX_AGE, DEFAULT_MAX_ENTRY_SIZE as CACHE_DEFAULT_MAX_ENTRY_SIZE, DEFAULT_SWR_MULTIPLIER as CACHE_DEFAULT_SWR_MULTIPLIER, CACHE_TAG_MAX_ITEMS, CACHE_TAG_MAX_LENGTH, type CacheControlInput, type CacheEngine, type CacheEngineOptions, type CacheEntry, type CacheStatus, type CacheStorageAdapter, type CacheStore, type CacheStoreAdmin, type ValidationResult as CacheValidationResult, type CachedFunction, type CachedRouteConfig, type ChannelMessage, type ChannelWebhookConfig, type CodeModeApi, type CodeModeConfig, type CodeModePermission, CodeModePermissionDeniedError, type CompiledRouteRule, CustomTool, DEFAULT_EXCLUDED_QUERY_PARAMS, type DefineCachedFunctionOptions, FileTooLargeError, type GetOrComputeOptions, InMemoryCacheAdapter, type InMemoryCacheAdapterOptions, type KeyDerivationOptions, type LoadEnvOptions, type LoadEnvResult, type McpResourceContents, type McpResourceDescriptor, NodeAcpTransport, type NormalizedCacheConfig, type OpenApiDocsOptions, type ParsedBody, type RevalidateResult, type RouteCacheOptions, RouteConfig, type RouteRule, type RouteRules, type Sandbox, type SerializedActionResult, type SerializedResponse, type StdioStreams, THEO_T_PREFIX, type UniversalZodIssue, type UploadedFile, type VendorAgentClient, type VendorAgentToolConfig, VerifyFn, type WorkflowLike, type WorkflowToolConfig, _resetCacheEngine, _resetEnvCache, buildResourceDescriptors, compileRouteRules, createACPTool, createCacheEngine, createCodeMode, createOpenApiHandler, createVendorAgentTool, createWorkflowTool, defineAppResource, defineCachedFunction, defineCachedRoute, deriveKey as deriveCacheKey, deserializeResponse, executeWebRequest, extractAppResources, extractUniversalIssues, getCacheControlHeader, getCacheEngine, handleChannelWebhook, handleMcpStdioLine, initCacheEngine, isActionError, isChannelPath, isInputError, loadEnv, parseChannelPath, parseRequestBody, readAppResource, resolveRouteRule, revalidatePath, revalidateTag, serializeResponse, serveMcpStdio, updateTag, validateExpire as validateCacheExpire, validateMaxAge as validateCacheMaxAge, validateTags as validateCacheTags };
1320
+ export { type AcpToolConfig, ActionError, type ActionErrorCode, ActionInputError, type ActionManifestEntry, type ActionResult, type AppResource, type AppResourceInput, type BodyParserOptions, DEFAULT_MAX_AGE as CACHE_DEFAULT_MAX_AGE, DEFAULT_MAX_ENTRY_SIZE as CACHE_DEFAULT_MAX_ENTRY_SIZE, DEFAULT_SWR_MULTIPLIER as CACHE_DEFAULT_SWR_MULTIPLIER, CACHE_TAG_MAX_ITEMS, CACHE_TAG_MAX_LENGTH, CTX_WRITERS, type CacheControlInput, type CacheEngine, type CacheEngineOptions, type CacheEntry, type CacheStatus, type CacheStorageAdapter, type CacheStore, type CacheStoreAdmin, type ValidationResult as CacheValidationResult, type CachedFunction, type CachedRouteConfig, type ChannelMessage, type ChannelWebhookConfig, type CodeModeApi, type CodeModeConfig, type CodeModePermission, CodeModePermissionDeniedError, type CompiledRouteRule, type ContextValue, CustomTool, DEFAULT_EXCLUDED_QUERY_PARAMS, type DefineCachedFunctionOptions, FileTooLargeError, type GetOrComputeOptions, InMemoryCacheAdapter, type InMemoryCacheAdapterOptions, type JobsAugmentedCtx, type KeyDerivationOptions, type LoadEnvOptions, type LoadEnvResult, type McpResourceContents, type McpResourceDescriptor, NodeAcpTransport, type NormalizedCacheConfig, type OpenApiDocsOptions, type ParsedBody, type ProcedureInput, ProcedureInputError, ProcedureOutputError, type QueueClientLike, type RawRouteInput, type RevalidateResult, type RouteCacheOptions, RouteConfig, type RouteInputChannel, type RouteInputSchemas, type RouteInputValidation, type RouteRule, type RouteRules, type Sandbox, type SerializedActionResult, type SerializedResponse, type StdioStreams, THEO_T_PREFIX, type UniversalZodIssue, type UploadedFile, type VendorAgentClient, type VendorAgentToolConfig, VerifyFn, type WorkflowLike, type WorkflowToolConfig, _resetCacheEngine, _resetEnvCache, buildResourceDescriptors, callProcedure, compileRouteRules, createACPTool, createCacheEngine, createCodeMode, createOpenApiHandler, createVendorAgentTool, createWorkflowTool, defineAppResource, defineCachedFunction, defineCachedRoute, deriveKey as deriveCacheKey, deserializeResponse, executeWebRequest, extractAppResources, extractUniversalIssues, getCacheControlHeader, getCacheEngine, handleChannelWebhook, handleMcpStdioLine, initCacheEngine, isActionError, isChannelPath, isInputError, loadEnv, parseChannelPath, parseRequestBody, readAppResource, resolveRouteRule, revalidatePath, revalidateTag, serializeResponse, serveMcpStdio, updateTag, validateExpire as validateCacheExpire, validateMaxAge as validateCacheMaxAge, validateTags as validateCacheTags, validateRouteInput };
@@ -59,8 +59,9 @@ import {
59
59
  loadEnv,
60
60
  readAppResource,
61
61
  resolveTransformer,
62
- superjsonTransformer
63
- } from "../chunk-W4YO6S4I.js";
62
+ superjsonTransformer,
63
+ validateRouteInput
64
+ } from "../chunk-W4XWVTN4.js";
64
65
  import {
65
66
  findSuggestion,
66
67
  levenshtein
@@ -1328,7 +1329,7 @@ async function handleMcpStdioLine(line, mod, name, appResources = []) {
1328
1329
  error: { code: -32700, message: "Parse error" }
1329
1330
  });
1330
1331
  }
1331
- const response = handleMcpJsonRpc(mod, name, body, appResources);
1332
+ const response = await handleMcpJsonRpc(mod, name, body, appResources);
1332
1333
  const payload = await response.json();
1333
1334
  return JSON.stringify(payload);
1334
1335
  }
@@ -1349,6 +1350,57 @@ function deserializeResponse(serialized) {
1349
1350
  return superjson.deserialize(serialized);
1350
1351
  }
1351
1352
 
1353
+ // src/server/http/in-process-caller.ts
1354
+ var ProcedureInputError = class extends Error {
1355
+ channel;
1356
+ issues;
1357
+ constructor(channel, error) {
1358
+ super(`Invalid ${channel} for in-process procedure call: ${error.message}`);
1359
+ this.name = "ProcedureInputError";
1360
+ this.channel = channel;
1361
+ this.issues = error.issues;
1362
+ }
1363
+ };
1364
+ var ProcedureOutputError = class extends Error {
1365
+ issues;
1366
+ constructor(error) {
1367
+ super(`In-process procedure output failed its response schema: ${error.message}`);
1368
+ this.name = "ProcedureOutputError";
1369
+ this.issues = error.issues;
1370
+ }
1371
+ };
1372
+ function inProcessRequest() {
1373
+ return new Request("theo://in-process/procedure", { method: "POST" });
1374
+ }
1375
+ async function callProcedure(config, input = {}, ctx) {
1376
+ const validated = validateRouteInput(config, input);
1377
+ if (!validated.ok) throw new ProcedureInputError(validated.channel, validated.error);
1378
+ const result = await config.handler({
1379
+ query: validated.query,
1380
+ body: validated.body,
1381
+ params: validated.params,
1382
+ request: inProcessRequest(),
1383
+ ctx
1384
+ });
1385
+ const responseSchema = config.response;
1386
+ if (responseSchema !== void 0 && !(result instanceof Response)) {
1387
+ const parsed = responseSchema.safeParse(result);
1388
+ if (!parsed.success) throw new ProcedureOutputError(parsed.error);
1389
+ return parsed.data;
1390
+ }
1391
+ return result;
1392
+ }
1393
+
1394
+ // src/server/http/ctx-reconciliation.ts
1395
+ var CTX_WRITERS = {
1396
+ /** Writer 1 — user `context.ts` factory. THE typed surface (`TCtx`). execute.ts:131 */
1397
+ contextFactory: "context.ts",
1398
+ /** Writer 2 — plugin `decorateRequest`. Untyped on the route surface. execute.ts:124,136 */
1399
+ pluginDecorations: "pluginRunner.applyDecorations",
1400
+ /** Writer 3 — jobs backend `ctx.queue`. Reached via JobsAugmentedCtx, not TCtx. execute.ts:141-150 */
1401
+ jobsQueue: "jobBackend"
1402
+ };
1403
+
1352
1404
  // src/server/index.ts
1353
1405
  if (typeof globalThis !== "undefined") {
1354
1406
  const WARN_KEY = "__theokit_server_umbrella_warn_emitted__";
@@ -1379,6 +1431,7 @@ export {
1379
1431
  CSRF_READINESS_RESET_PATH,
1380
1432
  CSRF_WARN_CODE,
1381
1433
  CSRF_WARN_DOCS_URL,
1434
+ CTX_WRITERS,
1382
1435
  ChannelManager,
1383
1436
  CodeModePermissionDeniedError,
1384
1437
  ConsoleObservabilityAdapter,
@@ -1410,6 +1463,8 @@ export {
1410
1463
  NotFoundError,
1411
1464
  PluginRunner,
1412
1465
  PostgresJobBackend,
1466
+ ProcedureInputError,
1467
+ ProcedureOutputError,
1413
1468
  READY_PATH,
1414
1469
  STRIPPED_HEADERS,
1415
1470
  SpanImpl,
@@ -1434,6 +1489,7 @@ export {
1434
1489
  buildJobManifest,
1435
1490
  buildResourceDescriptors,
1436
1491
  buildSecurityHeaders,
1492
+ callProcedure,
1437
1493
  checkThrottle,
1438
1494
  clearOidcCache,
1439
1495
  compilePattern,
@@ -1590,6 +1646,7 @@ export {
1590
1646
  validateCronSchedule,
1591
1647
  validateCsrf,
1592
1648
  validateCsrfRequest,
1649
+ validateRouteInput,
1593
1650
  verifyBackupCode,
1594
1651
  verifyOAuthState,
1595
1652
  verifyTotp,