theokit 0.18.0 → 0.19.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.
Files changed (35) hide show
  1. package/dist/agent-Y4W4X46A.js +15 -0
  2. package/dist/{build-5PSDDMFB.js → build-ESXLJKYY.js} +2 -2
  3. package/dist/{chunk-DEO2VAJE.js → chunk-7NTXG7SI.js} +6 -113
  4. package/dist/chunk-7NTXG7SI.js.map +1 -0
  5. package/dist/chunk-DMC6HYUR.js +141 -0
  6. package/dist/chunk-DMC6HYUR.js.map +1 -0
  7. package/dist/{chunk-XVFMSNDE.js → chunk-DXF64KS5.js} +8 -138
  8. package/dist/chunk-DXF64KS5.js.map +1 -0
  9. package/dist/{chunk-CC5WOQUV.js → chunk-ULFNEG27.js} +5 -3
  10. package/dist/{chunk-CC5WOQUV.js.map → chunk-ULFNEG27.js.map} +1 -1
  11. package/dist/{chunk-XWS4RZCE.js → chunk-W4YO6S4I.js} +110 -1
  12. package/dist/chunk-W4YO6S4I.js.map +1 -0
  13. package/dist/{agent-TZ5JZUJ7.js → chunk-ZYMFKYLM.js} +5 -4
  14. package/dist/{agent-TZ5JZUJ7.js.map → chunk-ZYMFKYLM.js.map} +1 -1
  15. package/dist/cli/index.js +16 -4
  16. package/dist/cli/index.js.map +1 -1
  17. package/dist/{dev-A7NESJ7S.js → dev-D7PKQUL2.js} +4 -3
  18. package/dist/{dev-A7NESJ7S.js.map → dev-D7PKQUL2.js.map} +1 -1
  19. package/dist/index.js +2 -2
  20. package/dist/mcp-3C4CMHP4.js +77 -0
  21. package/dist/mcp-3C4CMHP4.js.map +1 -0
  22. package/dist/server/index.d.ts +31 -1
  23. package/dist/server/index.js +30 -1
  24. package/dist/server/index.js.map +1 -1
  25. package/dist/{start-WGOKQEUW.js → start-5UDUXYKC.js} +3 -2
  26. package/dist/{start-WGOKQEUW.js.map → start-5UDUXYKC.js.map} +1 -1
  27. package/dist/vite-plugin/index.js +2 -2
  28. package/dist/{vite-plugin-DBS2USI4.js → vite-plugin-GXRWNESN.js} +4 -3
  29. package/dist/vite-plugin-GXRWNESN.js.map +1 -0
  30. package/package.json +1 -1
  31. package/dist/chunk-DEO2VAJE.js.map +0 -1
  32. package/dist/chunk-XVFMSNDE.js.map +0 -1
  33. package/dist/chunk-XWS4RZCE.js.map +0 -1
  34. /package/dist/{vite-plugin-DBS2USI4.js.map → agent-Y4W4X46A.js.map} +0 -0
  35. /package/dist/{build-5PSDDMFB.js.map → build-ESXLJKYY.js.map} +0 -0
@@ -0,0 +1,141 @@
1
+ #!/usr/bin/env node
2
+ import "tsx/esm";
3
+
4
+ // src/server/agent/mcp-app-resources.ts
5
+ function buildResourceDescriptors(resources) {
6
+ return resources.map((r) => ({
7
+ uri: r.uri,
8
+ name: r.name,
9
+ mimeType: r.mimeType,
10
+ ...r.description !== void 0 ? { description: r.description } : {}
11
+ }));
12
+ }
13
+ function readAppResource(resources, uri) {
14
+ const found = resources.find((r) => r.uri === uri);
15
+ if (!found) return null;
16
+ return { contents: [{ uri: found.uri, mimeType: "text/html", text: found.html }] };
17
+ }
18
+ function isAppResource(v) {
19
+ if (typeof v !== "object" || v === null) return false;
20
+ const r = v;
21
+ return typeof r.uri === "string" && r.uri.startsWith("ui://") && r.mimeType === "text/html" && typeof r.html === "string";
22
+ }
23
+ function extractAppResources(mod) {
24
+ const raw = mod?.appResources;
25
+ if (!Array.isArray(raw)) return [];
26
+ return raw.filter(isAppResource);
27
+ }
28
+
29
+ // src/server/agent/mcp-handler.ts
30
+ import {
31
+ buildMcpToolDescriptors,
32
+ compileAgentModule,
33
+ mcpServerInfo
34
+ } from "@theokit/agents";
35
+ var MCP_PATH = /^\/api\/agents\/([^/]+)\/mcp$/;
36
+ function isMcpPath(urlPath) {
37
+ const match = MCP_PATH.exec(urlPath);
38
+ return match ? decodeURIComponent(match[1]) : null;
39
+ }
40
+ function isJsonRpcRequest(body) {
41
+ return typeof body === "object" && body !== null && body.jsonrpc === "2.0" && typeof body.method === "string";
42
+ }
43
+ function jsonResponse(payload) {
44
+ return new Response(JSON.stringify(payload), {
45
+ status: 200,
46
+ headers: { "content-type": "application/json; charset=utf-8" }
47
+ });
48
+ }
49
+ function toEntry(name, mod) {
50
+ const compiled = compileAgentModule(mod, `mcp server for "${name}"`);
51
+ return {
52
+ name,
53
+ route: `/api/agents/${name}`,
54
+ stream: compiled.stream,
55
+ mainLoop: { method: "", strategy: "" },
56
+ guards: [],
57
+ interceptors: [],
58
+ tools: compiled.tools.map((t) => ({
59
+ name: t.name,
60
+ description: t.description,
61
+ approval: false,
62
+ trace: false,
63
+ audit: false
64
+ })),
65
+ subAgents: []
66
+ };
67
+ }
68
+ function handleMcpJsonRpc(mod, name, body, appResources = []) {
69
+ if (!isJsonRpcRequest(body)) {
70
+ return jsonResponse({
71
+ jsonrpc: "2.0",
72
+ id: null,
73
+ error: { code: -32600, message: "Invalid Request" }
74
+ });
75
+ }
76
+ const { id, method, params } = body;
77
+ try {
78
+ const entry = toEntry(name, mod);
79
+ if (method === "initialize") {
80
+ const info = mcpServerInfo(entry);
81
+ const capabilities = { tools: {} };
82
+ if (appResources.length > 0) capabilities.resources = {};
83
+ return jsonResponse({
84
+ jsonrpc: "2.0",
85
+ id,
86
+ result: {
87
+ protocolVersion: info.protocolVersion,
88
+ capabilities,
89
+ serverInfo: { name: info.name, version: info.version }
90
+ }
91
+ });
92
+ }
93
+ if (method === "tools/list") {
94
+ return jsonResponse({ jsonrpc: "2.0", id, result: { tools: buildMcpToolDescriptors(entry) } });
95
+ }
96
+ if (method === "resources/list") {
97
+ return jsonResponse({
98
+ jsonrpc: "2.0",
99
+ id,
100
+ result: { resources: buildResourceDescriptors(appResources) }
101
+ });
102
+ }
103
+ if (method === "resources/read") {
104
+ const uri = params?.uri;
105
+ if (typeof uri !== "string") {
106
+ return jsonResponse({
107
+ jsonrpc: "2.0",
108
+ id,
109
+ error: { code: -32602, message: "resources/read requires a string `uri` param." }
110
+ });
111
+ }
112
+ const contents = readAppResource(appResources, uri);
113
+ if (contents === null) {
114
+ return jsonResponse({
115
+ jsonrpc: "2.0",
116
+ id,
117
+ error: { code: -32602, message: `Resource not found: ${uri}` }
118
+ });
119
+ }
120
+ return jsonResponse({ jsonrpc: "2.0", id, result: contents });
121
+ }
122
+ return jsonResponse({
123
+ jsonrpc: "2.0",
124
+ id,
125
+ error: { code: -32601, message: `Method not found: ${method}` }
126
+ });
127
+ } catch (err) {
128
+ return jsonResponse({
129
+ jsonrpc: "2.0",
130
+ id,
131
+ error: { code: -32603, message: err instanceof Error ? err.message : "Internal error" }
132
+ });
133
+ }
134
+ }
135
+
136
+ export {
137
+ extractAppResources,
138
+ isMcpPath,
139
+ handleMcpJsonRpc
140
+ };
141
+ //# sourceMappingURL=chunk-DMC6HYUR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server/agent/mcp-app-resources.ts","../src/server/agent/mcp-handler.ts"],"sourcesContent":["/**\n * M30 (ADR-0041) — MCP Apps: `ui://` HTML resources for the MCP server (M16).\n *\n * A tool can declare a `ui://` HTML resource; the MCP server advertises it via `resources/list` and\n * serves the HTML via `resources/read`. The client renders it in a SANDBOXED iframe (see\n * `mcp-app-host.ts`). Pure data transforms here — no LLM, no runtime (ADR-0040 § D2 home concern).\n *\n * Security: only the `ui://` scheme is accepted (an app UI resource), never `http(s)://` — the HTML\n * is rendered sandboxed on the client, and the scheme gate keeps a tool from smuggling a remote URL\n * into the app surface.\n */\n\n/** A declared `ui://` app resource. */\nexport interface AppResource {\n uri: string\n name: string\n mimeType: 'text/html'\n html: string\n description?: string\n}\n\n/** Input to {@link defineAppResource}. */\nexport interface AppResourceInput {\n /** MUST start with `ui://`. */\n uri: string\n name: string\n html: string\n description?: string\n}\n\n/** An MCP `resources/list` descriptor (no HTML body — that comes from `resources/read`). */\nexport interface McpResourceDescriptor {\n uri: string\n name: string\n mimeType: 'text/html'\n description?: string\n}\n\n/** An MCP `resources/read` result. */\nexport interface McpResourceContents {\n contents: { uri: string; mimeType: 'text/html'; text: string }[]\n}\n\n/**\n * Declare a `ui://` HTML app resource. Fails fast if the uri is not a `ui://` scheme or the HTML is\n * empty (error-handling.md) — a misconfigured resource is caught at definition time.\n */\nexport function defineAppResource(input: AppResourceInput): AppResource {\n if (!input.uri.startsWith('ui://')) {\n throw new Error(\n `defineAppResource: uri must use the ui:// scheme (an app UI resource). Got: ${JSON.stringify(input.uri)}`,\n )\n }\n if (input.html.length === 0) {\n throw new Error(`defineAppResource(${JSON.stringify(input.uri)}): html must be non-empty.`)\n }\n return {\n uri: input.uri,\n name: input.name,\n mimeType: 'text/html',\n html: input.html,\n ...(input.description !== undefined ? { description: input.description } : {}),\n }\n}\n\n/** Map app resources to MCP `resources/list` descriptors (the HTML body is omitted from the list). */\nexport function buildResourceDescriptors(\n resources: readonly AppResource[],\n): McpResourceDescriptor[] {\n return resources.map((r) => ({\n uri: r.uri,\n name: r.name,\n mimeType: r.mimeType,\n ...(r.description !== undefined ? { description: r.description } : {}),\n }))\n}\n\n/** Serve the HTML for `uri` as an MCP `resources/read` result, or `null` when unknown. */\nexport function readAppResource(\n resources: readonly AppResource[],\n uri: string,\n): McpResourceContents | null {\n const found = resources.find((r) => r.uri === uri)\n if (!found) return null\n return { contents: [{ uri: found.uri, mimeType: 'text/html', text: found.html }] }\n}\n\n/** True when `v` is a well-formed {@link AppResource} (from `defineAppResource`). */\nfunction isAppResource(v: unknown): v is AppResource {\n if (typeof v !== 'object' || v === null) return false\n const r = v as Record<string, unknown>\n return (\n typeof r.uri === 'string' &&\n r.uri.startsWith('ui://') &&\n r.mimeType === 'text/html' &&\n typeof r.html === 'string'\n )\n}\n\n/**\n * M30 wiring — extract the App resources an agent module declares via a named `appResources` export\n * (`export const appResources = [defineAppResource(...)]`). Returns only the well-formed entries; a\n * module without the export (or with a malformed one) yields `[]`. This is how per-agent `ui://`\n * resources reach the MCP server's `resources/list` + `resources/read` without a runtime dependency\n * from `@theokit/agents` on this theo-side type (the module exports them; the serving path reads them).\n */\nexport function extractAppResources(mod: unknown): AppResource[] {\n const raw = (mod as { appResources?: unknown } | null | undefined)?.appResources\n if (!Array.isArray(raw)) return []\n return raw.filter(isAppResource)\n}\n","/**\n * M16 (theokit-ai-first) — serve an agent as an MCP server over HTTP at `/api/agents/<name>/mcp`.\n *\n * Answers the two core MCP methods over JSON-RPC 2.0: `initialize` (server info + capabilities) and\n * `tools/list` (the agent's tools as MCP descriptors, via `buildMcpToolDescriptors`). M30 adds\n * `resources/list` + `resources/read` for `ui://` App resources. Unknown methods return `-32601`\n * (method not found). Web Standards Response (G8). The stdio transport + full method set stay\n * SDK-side (sdk-runtime.md); this exposes the agent over the app's own HTTP route.\n */\nimport {\n type AgentManifestEntry,\n buildMcpToolDescriptors,\n compileAgentModule,\n mcpServerInfo,\n} from '@theokit/agents'\n\nimport { type AppResource, buildResourceDescriptors, readAppResource } from './mcp-app-resources.js'\n\nconst MCP_PATH = /^\\/api\\/agents\\/([^/]+)\\/mcp$/\n\n/** Return the agent name when `urlPath` is the MCP endpoint, else `null`. */\nexport function isMcpPath(urlPath: string): string | null {\n const match = MCP_PATH.exec(urlPath)\n return match ? decodeURIComponent(match[1]) : null\n}\n\ninterface JsonRpcRequest {\n jsonrpc: '2.0'\n id: number | string | null\n method: string\n params?: unknown\n}\n\nfunction isJsonRpcRequest(body: unknown): body is JsonRpcRequest {\n return (\n typeof body === 'object' &&\n body !== null &&\n (body as { jsonrpc?: unknown }).jsonrpc === '2.0' &&\n typeof (body as { method?: unknown }).method === 'string'\n )\n}\n\nfunction jsonResponse(payload: unknown): Response {\n return new Response(JSON.stringify(payload), {\n status: 200,\n headers: { 'content-type': 'application/json; charset=utf-8' },\n })\n}\n\n/** Minimal manifest entry (the subset the MCP generators read) from a compiled agent. */\nfunction toEntry(name: string, mod: unknown): AgentManifestEntry {\n const compiled = compileAgentModule(mod, `mcp server for \"${name}\"`)\n return {\n name,\n route: `/api/agents/${name}`,\n stream: compiled.stream,\n mainLoop: { method: '', strategy: '' },\n guards: [],\n interceptors: [],\n tools: compiled.tools.map((t) => ({\n name: t.name,\n description: t.description,\n approval: false,\n trace: false,\n audit: false,\n })),\n subAgents: [],\n }\n}\n\n/**\n * Handle one MCP JSON-RPC request for an agent module. Always returns a 200 JSON-RPC envelope.\n *\n * M30 — `appResources` (optional) are the agent's declared `ui://` App resources; when present the\n * server advertises `capabilities.resources` and answers `resources/list` + `resources/read`.\n */\nexport function handleMcpJsonRpc(\n mod: unknown,\n name: string,\n body: unknown,\n appResources: readonly AppResource[] = [],\n): Response {\n if (!isJsonRpcRequest(body)) {\n return jsonResponse({\n jsonrpc: '2.0',\n id: null,\n error: { code: -32600, message: 'Invalid Request' },\n })\n }\n const { id, method, params } = body\n try {\n const entry = toEntry(name, mod)\n if (method === 'initialize') {\n const info = mcpServerInfo(entry)\n const capabilities: Record<string, unknown> = { tools: {} }\n if (appResources.length > 0) capabilities.resources = {}\n return jsonResponse({\n jsonrpc: '2.0',\n id,\n result: {\n protocolVersion: info.protocolVersion,\n capabilities,\n serverInfo: { name: info.name, version: info.version },\n },\n })\n }\n if (method === 'tools/list') {\n return jsonResponse({ jsonrpc: '2.0', id, result: { tools: buildMcpToolDescriptors(entry) } })\n }\n if (method === 'resources/list') {\n return jsonResponse({\n jsonrpc: '2.0',\n id,\n result: { resources: buildResourceDescriptors(appResources) },\n })\n }\n if (method === 'resources/read') {\n const uri = (params as { uri?: unknown } | undefined)?.uri\n if (typeof uri !== 'string') {\n return jsonResponse({\n jsonrpc: '2.0',\n id,\n error: { code: -32602, message: 'resources/read requires a string `uri` param.' },\n })\n }\n const contents = readAppResource(appResources, uri)\n if (contents === null) {\n return jsonResponse({\n jsonrpc: '2.0',\n id,\n error: { code: -32602, message: `Resource not found: ${uri}` },\n })\n }\n return jsonResponse({ jsonrpc: '2.0', id, result: contents })\n }\n return jsonResponse({\n jsonrpc: '2.0',\n id,\n error: { code: -32601, message: `Method not found: ${method}` },\n })\n } catch (err) {\n return jsonResponse({\n jsonrpc: '2.0',\n id,\n error: { code: -32603, message: err instanceof Error ? err.message : 'Internal error' },\n })\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,5 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import "tsx/esm";
3
+ import {
4
+ extractAppResources,
5
+ handleMcpJsonRpc,
6
+ isMcpPath
7
+ } from "./chunk-DMC6HYUR.js";
3
8
  import {
4
9
  getApprovalRegistry
5
10
  } from "./chunk-M6NMS5LR.js";
@@ -165,143 +170,9 @@ function handleListApprovals(registry) {
165
170
  });
166
171
  }
167
172
 
168
- // src/server/agent/mcp-handler.ts
169
- import {
170
- buildMcpToolDescriptors,
171
- compileAgentModule as compileAgentModule2,
172
- mcpServerInfo
173
- } from "@theokit/agents";
174
-
175
- // src/server/agent/mcp-app-resources.ts
176
- function buildResourceDescriptors(resources) {
177
- return resources.map((r) => ({
178
- uri: r.uri,
179
- name: r.name,
180
- mimeType: r.mimeType,
181
- ...r.description !== void 0 ? { description: r.description } : {}
182
- }));
183
- }
184
- function readAppResource(resources, uri) {
185
- const found = resources.find((r) => r.uri === uri);
186
- if (!found) return null;
187
- return { contents: [{ uri: found.uri, mimeType: "text/html", text: found.html }] };
188
- }
189
- function isAppResource(v) {
190
- if (typeof v !== "object" || v === null) return false;
191
- const r = v;
192
- return typeof r.uri === "string" && r.uri.startsWith("ui://") && r.mimeType === "text/html" && typeof r.html === "string";
193
- }
194
- function extractAppResources(mod) {
195
- const raw = mod?.appResources;
196
- if (!Array.isArray(raw)) return [];
197
- return raw.filter(isAppResource);
198
- }
199
-
200
- // src/server/agent/mcp-handler.ts
201
- var MCP_PATH = /^\/api\/agents\/([^/]+)\/mcp$/;
202
- function isMcpPath(urlPath) {
203
- const match = MCP_PATH.exec(urlPath);
204
- return match ? decodeURIComponent(match[1]) : null;
205
- }
206
- function isJsonRpcRequest(body) {
207
- return typeof body === "object" && body !== null && body.jsonrpc === "2.0" && typeof body.method === "string";
208
- }
209
- function jsonResponse(payload) {
210
- return new Response(JSON.stringify(payload), {
211
- status: 200,
212
- headers: { "content-type": "application/json; charset=utf-8" }
213
- });
214
- }
215
- function toEntry(name, mod) {
216
- const compiled = compileAgentModule2(mod, `mcp server for "${name}"`);
217
- return {
218
- name,
219
- route: `/api/agents/${name}`,
220
- stream: compiled.stream,
221
- mainLoop: { method: "", strategy: "" },
222
- guards: [],
223
- interceptors: [],
224
- tools: compiled.tools.map((t) => ({
225
- name: t.name,
226
- description: t.description,
227
- approval: false,
228
- trace: false,
229
- audit: false
230
- })),
231
- subAgents: []
232
- };
233
- }
234
- function handleMcpJsonRpc(mod, name, body, appResources = []) {
235
- if (!isJsonRpcRequest(body)) {
236
- return jsonResponse({
237
- jsonrpc: "2.0",
238
- id: null,
239
- error: { code: -32600, message: "Invalid Request" }
240
- });
241
- }
242
- const { id, method, params } = body;
243
- try {
244
- const entry = toEntry(name, mod);
245
- if (method === "initialize") {
246
- const info = mcpServerInfo(entry);
247
- const capabilities = { tools: {} };
248
- if (appResources.length > 0) capabilities.resources = {};
249
- return jsonResponse({
250
- jsonrpc: "2.0",
251
- id,
252
- result: {
253
- protocolVersion: info.protocolVersion,
254
- capabilities,
255
- serverInfo: { name: info.name, version: info.version }
256
- }
257
- });
258
- }
259
- if (method === "tools/list") {
260
- return jsonResponse({ jsonrpc: "2.0", id, result: { tools: buildMcpToolDescriptors(entry) } });
261
- }
262
- if (method === "resources/list") {
263
- return jsonResponse({
264
- jsonrpc: "2.0",
265
- id,
266
- result: { resources: buildResourceDescriptors(appResources) }
267
- });
268
- }
269
- if (method === "resources/read") {
270
- const uri = params?.uri;
271
- if (typeof uri !== "string") {
272
- return jsonResponse({
273
- jsonrpc: "2.0",
274
- id,
275
- error: { code: -32602, message: "resources/read requires a string `uri` param." }
276
- });
277
- }
278
- const contents = readAppResource(appResources, uri);
279
- if (contents === null) {
280
- return jsonResponse({
281
- jsonrpc: "2.0",
282
- id,
283
- error: { code: -32602, message: `Resource not found: ${uri}` }
284
- });
285
- }
286
- return jsonResponse({ jsonrpc: "2.0", id, result: contents });
287
- }
288
- return jsonResponse({
289
- jsonrpc: "2.0",
290
- id,
291
- error: { code: -32601, message: `Method not found: ${method}` }
292
- });
293
- } catch (err) {
294
- return jsonResponse({
295
- jsonrpc: "2.0",
296
- id,
297
- error: { code: -32603, message: err instanceof Error ? err.message : "Internal error" }
298
- });
299
- }
300
- }
301
-
302
173
  // src/server/agent/mount-agent.ts
303
174
  import {
304
- compileAgentModule as compileAgentModule3,
175
+ compileAgentModule as compileAgentModule2,
305
176
  resolveEnabledSkills,
306
177
  streamAgentUIMessages
307
178
  } from "@theokit/agents";
@@ -370,7 +241,7 @@ async function mountAgent(mod, request, apiKey, source = "agent module", csrfMod
370
241
  return jsonError2(403, "CSRF_FAILED", `CSRF check failed: ${csrf.reason}`);
371
242
  }
372
243
  }
373
- const compiled = compileAgentModule3(mod, source);
244
+ const compiled = compileAgentModule2(mod, source);
374
245
  if (compiled.skillsResolver) {
375
246
  const enabled = await resolveEnabledSkills(compiled.skillsResolver, compiled.runContext ?? {});
376
247
  if (enabled !== void 0) compiled.skills = { enabled, autoInject: true };
@@ -504,10 +375,9 @@ export {
504
375
  isApprovalPath,
505
376
  handleAgentApproval,
506
377
  isListApprovalsPath,
507
- isMcpPath,
508
378
  mountAgent,
509
379
  serveAgentAuxRoute,
510
380
  incomingMessageToWebRequest,
511
381
  writeWebResponseToServerResponse
512
382
  };
513
- //# sourceMappingURL=chunk-XVFMSNDE.js.map
383
+ //# sourceMappingURL=chunk-DXF64KS5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server/transformer.ts","../src/server/agent/agent-card-handler.ts","../src/server/agent/approve-agent.ts","../src/server/agent/list-approvals-handler.ts","../src/server/agent/mount-agent.ts","../src/server/define/ui-message-stream-response.ts","../src/server/agent/serve-aux-routes.ts","../src/server/http/node-web-adapter.ts"],"sourcesContent":["import superjson from 'superjson'\n\n/**\n * T5.2 — pluggable response/request transformer.\n *\n * `superjson` is the default, preserving Date/Map/Set/BigInt/etc.\n * `json` is the lightweight option (plain JSON.stringify/parse).\n * Users can supply a custom object implementing this contract.\n */\nexport interface TheoTransformer {\n name: string\n serialize: (value: unknown) => string\n deserialize: (raw: string) => unknown\n}\n\nexport const superjsonTransformer: TheoTransformer = {\n name: 'superjson',\n serialize: (v) => JSON.stringify(superjson.serialize(v)),\n deserialize: (raw) => {\n const parsed = JSON.parse(raw) as Parameters<typeof superjson.deserialize>[0]\n return superjson.deserialize(parsed)\n },\n}\n\nexport const jsonTransformer: TheoTransformer = {\n name: 'json',\n serialize: (v) => JSON.stringify(v),\n deserialize: (raw) => JSON.parse(raw) as unknown,\n}\n\nconst BUILT_INS: Record<string, TheoTransformer> = {\n superjson: superjsonTransformer,\n json: jsonTransformer,\n}\n\nexport function resolveTransformer(\n selector: 'json' | 'superjson' | TheoTransformer,\n): TheoTransformer {\n if (typeof selector === 'string') {\n // selector is 'json' | 'superjson' literal — both keys exist in\n // BUILT_INS by construction. Type system guarantees a hit; we keep\n // a defensive fallback that the compiler cannot see is unreachable\n // at runtime, just in case someone adds a new literal to the union\n // but forgets to register the built-in.\n const built = BUILT_INS[selector]\n // Defensive: the public union ensures `built` is defined, but if a\n // future contributor extends the union without registering the impl,\n // the cast keeps the failure mode loud.\n if ((built as TheoTransformer | undefined) === undefined) {\n throw new Error(\n `Unknown transformer \"${selector}\". Built-in options: ${Object.keys(BUILT_INS).join(', ')}.`,\n )\n }\n return built\n }\n if (\n typeof selector !== 'object' ||\n typeof selector.serialize !== 'function' ||\n typeof selector.deserialize !== 'function'\n ) {\n throw new Error(\n `Custom transformer must have serialize and deserialize functions. Got: ${JSON.stringify(selector)}`,\n )\n }\n return selector\n}\n","/**\n * M15 (theokit-ai-first) — serve the A2A agent card at `/.well-known/<name>/agent-card.json`.\n *\n * `buildAgentCard` (@theokit/agents) is the pure generator; this handler compiles a loaded agent\n * module to its tools + streaming capability, builds the card, and returns it as a Web-Standard\n * JSON `Response` (G8). The dev middleware + prod handler branch to this before the agent POST route.\n */\nimport {\n type AgentManifestEntry,\n buildAgentCard,\n compileAgentModule,\n} from '@theokit/agents'\n\nconst WELL_KNOWN = /^\\/\\.well-known\\/([^/]+)\\/agent-card\\.json$/\n\n/** Return the agent name when `urlPath` is a well-known card path, else `null`. */\nexport function isAgentCardPath(urlPath: string): string | null {\n const match = WELL_KNOWN.exec(urlPath)\n return match ? decodeURIComponent(match[1]) : null\n}\n\n/** Build a minimal manifest entry (the subset `buildAgentCard` reads) from a compiled agent. */\nfunction toManifestEntry(name: string, route: string, mod: unknown): AgentManifestEntry {\n const compiled = compileAgentModule(mod, `agent card for \"${name}\"`)\n return {\n name,\n route,\n stream: compiled.stream,\n mainLoop: { method: '', strategy: '' },\n guards: [],\n interceptors: [],\n tools: compiled.tools.map((t) => ({\n name: t.name,\n description: t.description,\n approval: false,\n trace: false,\n audit: false,\n })),\n subAgents: [],\n }\n}\n\n/**\n * Serve the A2A card for a loaded agent module. Returns 200 with the card JSON, or 500 with an\n * error body if the module is not a valid agent (fail-clear, not a silent empty card).\n */\nexport function handleAgentCard(mod: unknown, name: string, route: string, baseUrl: string): Response {\n try {\n const card = buildAgentCard(toManifestEntry(name, route, mod), { baseUrl })\n return new Response(JSON.stringify(card), {\n status: 200,\n headers: { 'content-type': 'application/json; charset=utf-8' },\n })\n } catch (err) {\n return new Response(\n JSON.stringify({ error: { code: 'AGENT_CARD_FAILED', message: err instanceof Error ? err.message : 'card build failed' } }),\n { status: 500, headers: { 'content-type': 'application/json; charset=utf-8' } },\n )\n }\n}\n","/**\n * M4 (theokit-ai-first) — the HITL approve endpoint: `POST /api/agents/<name>/approve/<approvalId>`.\n *\n * The counterpart to `mountAgent`'s HITL pause. While a gated tool holds the SDK run paused (the\n * awaited `pre_tool_call` hook), the client POSTs here with `{ approved }`; this resolves the\n * pending approval in the shared registry, which un-pauses the run (allow) or vetoes the tool (deny).\n *\n * Web-Standard `Request` → `Response`, one wiring point shared by dev (vite middleware) and prod\n * (built server) so the two never drift (EC-4 parity with `mountAgent`). The registry is INJECTED —\n * dev/prod pass the process singleton (`getApprovalRegistry`), tests pass a fresh instance.\n */\nimport { validateCsrfRequest, type CsrfMode } from '../security/csrf.js'\n\nimport type { ApprovalDecision, ApprovalRegistry } from './approval-registry.js'\n\n/** The path segment separating the agent name from the approval id. */\nconst APPROVE_SEGMENT = '/approve/'\n\n/**\n * Extract the `<approvalId>` from a `/api/agents/<name>/approve/<approvalId>` path.\n * Returns `null` when the path has no `/approve/` segment or an empty / nested id.\n */\nexport function parseApprovalId(urlPath: string): string | null {\n const at = urlPath.indexOf(APPROVE_SEGMENT)\n if (at === -1) return null\n const id = urlPath.slice(at + APPROVE_SEGMENT.length)\n return id.length > 0 && !id.includes('/') ? id : null\n}\n\n/** True when `urlPath` targets a HITL approve endpoint (used by dev/prod routing to branch early). */\nexport function isApprovalPath(urlPath: string): boolean {\n return urlPath.includes(APPROVE_SEGMENT)\n}\n\nfunction jsonError(status: number, code: string, message: string): Response {\n return new Response(JSON.stringify({ error: { code, message } }), {\n status,\n headers: { 'content-type': 'application/json' },\n })\n}\n\n/**\n * M20 — cap on the serialized custom payload (16 KiB). A payload is a small structured note\n * (edited args, a reviewer comment), not a data channel — an oversized one is rejected fail-fast\n * rather than silently truncated (Rule 8).\n */\nconst MAX_PAYLOAD_BYTES = 16 * 1024\n\n/**\n * Extract an {@link ApprovalDecision} from an untrusted body; `null` when the shape is wrong.\n *\n * M20 — accepts an optional `reason` (string) and `payload` (object, capped at\n * {@link MAX_PAYLOAD_BYTES}). Backward-compatible: `{ approved }` and `{ approved, reason }` parse\n * unchanged. A non-object or oversized `payload` is rejected (returns `null` → the route 400s).\n *\n * @public\n */\nexport function parseApprovalBody(body: unknown): ApprovalDecision | null {\n if (typeof body !== 'object' || body === null) return null\n const b = body as Record<string, unknown>\n if (typeof b.approved !== 'boolean') return null\n const decision: ApprovalDecision = { approved: b.approved }\n if (b.reason !== undefined) {\n if (typeof b.reason !== 'string') return null\n decision.reason = b.reason\n }\n if (b.payload !== undefined) {\n if (typeof b.payload !== 'object' || b.payload === null || Array.isArray(b.payload)) return null\n if (JSON.stringify(b.payload).length > MAX_PAYLOAD_BYTES) return null\n decision.payload = b.payload\n }\n return decision\n}\n\n/**\n * Resolve a pending HITL approval. CSRF-guarded like `mountAgent` (the custom `X-Theo-Action`\n * header + Origin match) — a cross-origin POST must not approve a paused tool. Returns:\n * 403 CSRF_FAILED — strict CSRF check failed\n * 400 BAD_REQUEST — no `/approve/<id>` in the path, or body lacks a boolean `approved`\n * 404 NOT_PENDING — the id is unknown or already settled (idempotent double-submit)\n * 200 { resolved:true } — the approval was settled by this call\n */\nexport async function handleAgentApproval(\n request: Request,\n urlPath: string,\n registry: ApprovalRegistry,\n csrfMode: CsrfMode = 'strict',\n): Promise<Response> {\n if (csrfMode !== 'off') {\n const csrf = validateCsrfRequest(request)\n if (!csrf.valid && csrfMode === 'strict') {\n return jsonError(403, 'CSRF_FAILED', `CSRF check failed: ${csrf.reason}`)\n }\n }\n\n const approvalId = parseApprovalId(urlPath)\n if (approvalId === null) {\n return jsonError(400, 'BAD_REQUEST', 'Approval path must be /api/agents/<name>/approve/<id>.')\n }\n\n let body: unknown = null\n try {\n body = await request.json()\n } catch {\n /* invalid/empty JSON → handled below as a 400 */\n }\n const parsed = parseApprovalBody(body)\n if (parsed === null) {\n return jsonError(400, 'BAD_REQUEST', 'Request body must contain a boolean `approved`.')\n }\n\n const resolved = registry.resolve(approvalId, parsed)\n if (!resolved) {\n return jsonError(404, 'NOT_PENDING', `No pending approval for id '${approvalId}'.`)\n }\n return new Response(JSON.stringify({ resolved: true }), {\n status: 200,\n headers: { 'content-type': 'application/json' },\n })\n}\n","/**\n * M14 (theokit-ai-first) — GET /api/agents/<name>/approvals: list pending HITL approvals.\n *\n * Serves `ApprovalRegistry.list()` as JSON. Single-process contract (ADR 0038) — the list is\n * process-wide; the `<name>` segment is accepted for a future per-agent/durable store but the\n * in-process registry lists all pending approvals. Web Standards Response (G8).\n */\nimport type { ApprovalRegistry } from './approval-registry.js'\n\nconst LIST_PATH = /^\\/api\\/agents\\/([^/]+)\\/approvals$/\n\n/** Return the agent name when `urlPath` is the approvals-listing path, else `null`. */\nexport function isListApprovalsPath(urlPath: string): string | null {\n const match = LIST_PATH.exec(urlPath)\n return match ? decodeURIComponent(match[1]) : null\n}\n\n/** Serve the currently-pending approvals as `{ approvals: [...] }` JSON. */\nexport function handleListApprovals(registry: ApprovalRegistry): Response {\n return new Response(JSON.stringify({ approvals: registry.list() }), {\n status: 200,\n headers: { 'content-type': 'application/json; charset=utf-8' },\n })\n}\n","/**\n * M2 (theokit-ai-first) — mount a scanned `agents/<name>.ts` module as an SSE endpoint.\n *\n * The SINGLE wiring point shared by dev (vite middleware) and prod (built server), so the\n * two never drift (EC-4). Web-Standard `Request` → `Response`: parse the chat body, compile\n * the module (`compileAgentModule`, converges both surfaces), stream via the M0/M1 canonical\n * protocol (`streamAgentUIMessages` → `uiMessageStreamResponse`).\n *\n * Request body — accepts the `@ai-sdk/react` `useChat` shape (`{ id, messages: UIMessage[] }`,\n * the typed-client path) AND a simple `{ message, sessionId? }` shape (M0/M1-style clients).\n */\nimport {\n compileAgentModule,\n resolveEnabledSkills,\n streamAgentUIMessages,\n type HumanInTheLoopOptions,\n} from '@theokit/agents'\n\nimport { uiMessageStreamResponse } from '../define/ui-message-stream-response.js'\nimport { validateCsrfRequest, type CsrfMode } from '../security/csrf.js'\n\nimport { getApprovalRegistry } from './approval-registry.js'\n\n/** The message + session extracted from a chat request, or `null` when the body is invalid. */\nexport interface AgentRequestInput {\n message: string\n sessionId: string\n}\n\n/** Extract the text of a `{ type: 'text', text: string }` part from an untrusted value. */\nfunction partText(part: unknown): string {\n if (typeof part !== 'object' || part === null) return ''\n const p = part as Record<string, unknown>\n return p.type === 'text' && typeof p.text === 'string' ? p.text : ''\n}\n\nfunction jsonError(status: number, code: string, message: string): Response {\n return new Response(JSON.stringify({ error: { code, message } }), {\n status,\n headers: { 'content-type': 'application/json' },\n })\n}\n\n/**\n * Extract `{ message, sessionId }` from a chat request body. Returns `null` when neither the\n * ai-sdk `messages` shape nor the simple `message` shape yields non-empty user text.\n */\nexport function parseAgentRequestBody(body: unknown): AgentRequestInput | null {\n if (typeof body !== 'object' || body === null) return null\n const b = body as Record<string, unknown>\n\n // ai-sdk useChat shape: { id, messages: UIMessage[] } — take the last message's text parts.\n if (Array.isArray(b.messages) && b.messages.length > 0) {\n const last = b.messages[b.messages.length - 1] as Record<string, unknown>\n const parts = Array.isArray(last.parts) ? last.parts : []\n const text = parts.map(partText).join('')\n if (text.length === 0) return null\n const sessionId = typeof b.id === 'string' && b.id.length > 0 ? b.id : crypto.randomUUID()\n return { message: text, sessionId }\n }\n\n // Simple shape: { message, sessionId? }.\n if (typeof b.message === 'string' && b.message.length > 0) {\n const sessionId =\n typeof b.sessionId === 'string' && b.sessionId.length > 0 ? b.sessionId : crypto.randomUUID()\n return { message: b.message, sessionId }\n }\n\n return null\n}\n\n/**\n * Mount a loaded agent module as a `Response`. `apiKey` is resolved by the caller\n * (`resolveProvider`). `source` labels a fail-fast `AgentDefinitionError` (the file path).\n */\nexport async function mountAgent(\n mod: unknown,\n request: Request,\n apiKey: string,\n source = 'agent module',\n csrfMode: CsrfMode = 'strict',\n): Promise<Response> {\n // Enforce CSRF BEFORE any work — an agent run spends real LLM tokens, so a cross-origin\n // POST must be rejected before it reaches the SDK (parity with actions/routes). The custom\n // `X-Theo-Action` header + Origin match is the same defense `executeRoute`/`executeAction`\n // apply; the `useAgent` client sends the header. `off` skips; `warn` never blocks.\n if (csrfMode !== 'off') {\n const csrf = validateCsrfRequest(request)\n if (!csrf.valid && csrfMode === 'strict') {\n return jsonError(403, 'CSRF_FAILED', `CSRF check failed: ${csrf.reason}`)\n }\n }\n\n const compiled = compileAgentModule(mod, source)\n\n // M13 — resolve a per-request skills selector (from `defineAgent({ skills: (ctx) => [...] })`)\n // against the M7 run-context, setting `skills.enabled` before the SDK runs. `undefined` ⇒ the\n // SDK enables every discovered skill. `compiled` is fresh per request, so mutation is safe.\n if (compiled.skillsResolver) {\n const enabled = await resolveEnabledSkills(compiled.skillsResolver, compiled.runContext ?? {})\n if (enabled !== undefined) compiled.skills = { enabled, autoInject: true }\n }\n\n let body: unknown = null\n try {\n body = await request.json()\n } catch {\n /* invalid/empty JSON → handled below as a 400 */\n }\n\n const input = parseAgentRequestBody(body)\n if (input === null) {\n return jsonError(400, 'BAD_REQUEST', 'Request must contain a non-empty message or messages[].')\n }\n\n // When the agent has @HumanInTheLoop-gated tools (M4), wire the pause: the plugin's `awaitApproval`\n // registers a pending approval in the shared registry (the Promise that PAUSES the run); the\n // approve route (`handleAgentApproval`) resolves it. No gated tools ⇒ the M2 stream path unchanged.\n const gated = compiled.hitl\n const registry = getApprovalRegistry()\n const hitl =\n gated && gated.size > 0\n ? {\n gated,\n awaitApproval: (approvalId: string, opts: HumanInTheLoopOptions, toolName: string) =>\n registry.register(approvalId, {\n timeoutMs: opts.timeout ?? 300_000,\n onTimeout: opts.onTimeout ?? 'abort',\n // M14 — surface toolName + question in GET /approvals (the plugin forwards c.name).\n toolName,\n question: opts.question,\n // M20 — carry the declared custom-payload schema into GET /approvals.\n ...(opts.payloadSchema !== undefined ? { payloadSchema: opts.payloadSchema } : {}),\n }),\n }\n : undefined\n\n return uiMessageStreamResponse(\n streamAgentUIMessages(compiled, apiKey, { ...input, hitl, signal: request.signal }),\n )\n}\n","import type { UIMessageChunk } from 'ai'\n\n/**\n * M0 (theokit-ai-first) — serialize a stream of ai-sdk `UIMessageChunk`s into a\n * Web-Standards `Response` on the UIMessageStream wire so `@ai-sdk/react`'s\n * `useChat` consumes it WITHOUT a custom adapter.\n *\n * Wire contract (must match ai-sdk's consumer transport exactly):\n * - `content-type: text/event-stream`\n * - `x-vercel-ai-ui-message-stream: v1` — the version marker `useChat` checks\n * - each chunk framed as `data: ${JSON.stringify(chunk)}\\n\\n`\n * - a terminal `data: [DONE]\\n\\n` after the last chunk (ignored by the parser)\n *\n * Web Standards only — `Response` + `ReadableStream` (G8, no node:http). The\n * headers commit before the stream starts.\n *\n * Fail-clear (error-handling.md): if the source iterable throws mid-stream, the\n * `[DONE]` terminal is still flushed and the stream is closed — never left\n * hanging. (The translator upstream already closes gracefully; this is defense\n * in depth for any other chunk source.)\n */\nconst UI_MESSAGE_STREAM_HEADERS = {\n 'content-type': 'text/event-stream',\n 'x-vercel-ai-ui-message-stream': 'v1',\n} as const\n\nconst DONE_FRAME = 'data: [DONE]\\n\\n'\n\nfunction encode(text: string): Uint8Array {\n return new TextEncoder().encode(text)\n}\n\nexport function uiMessageStreamResponse(chunks: AsyncIterable<UIMessageChunk>): Response {\n const stream = new ReadableStream<Uint8Array>({\n async start(controller) {\n try {\n for await (const chunk of chunks) {\n controller.enqueue(encode(`data: ${JSON.stringify(chunk)}\\n\\n`))\n }\n } catch {\n // The source iterable aborted mid-stream. The upstream translator owns\n // error semantics (it surfaces failures as chunks + closes gracefully);\n // this transport's sole guarantee is a terminated stream — fall through\n // to the DONE terminal rather than re-throw and error an open stream.\n } finally {\n controller.enqueue(encode(DONE_FRAME))\n controller.close()\n }\n },\n })\n return new Response(stream, { headers: UI_MESSAGE_STREAM_HEADERS })\n}\n","/**\n * M15/M16 follow-up — shared dispatcher for the agent AUXILIARY routes that BOTH dev (vite\n * middleware) and prod (`theokit start` handler) must serve identically. Before this, these routes\n * were wired only into the dev middleware, so a built/deployed app served none of them (agent cards,\n * MCP, pending-approvals listing all 404'd in production).\n *\n * Single source of truth (DRY): one Web-Request→Response dispatcher, two callers. It handles the\n * routes that derive purely from the agent module + shared registry:\n * - **M15** `GET /.well-known/<name>/agent-card.json` → {@link handleAgentCard}\n * - **M14** `GET /api/agents/<name>/approvals` → {@link handleListApprovals}\n * - **M16** `POST /api/agents/<name>/mcp` → {@link handleMcpJsonRpc}\n *\n * Channels (M27) are NOT here: a channel webhook needs app-supplied `validators` + `onMessage`, so\n * the app wires `handleChannelWebhook` in its own route (it cannot be auto-derived from the module).\n * The HITL approve route stays in each caller (it carries caller-specific rate-limiting/CSRF plumbing).\n */\nimport type { AgentNode } from '../scan/agent-scan.js'\n\nimport { isAgentCardPath, handleAgentCard } from './agent-card-handler.js'\nimport { getApprovalRegistry } from './approval-registry.js'\nimport { isListApprovalsPath, handleListApprovals } from './list-approvals-handler.js'\nimport { extractAppResources } from './mcp-app-resources.js'\nimport { isMcpPath, handleMcpJsonRpc } from './mcp-handler.js'\n\n/** Dependencies the aux dispatcher needs from its caller (dev or prod). */\nexport interface AuxRouteDeps {\n /** Discovered agents (from `scanAgents`). */\n agents: readonly AgentNode[]\n /** Load an agent module from its file path (dev: vite loader; prod: dynamic import). */\n loadModule: (filePath: string) => Promise<unknown>\n /** Absolute base URL (`http(s)://host`) for the agent-card endpoint URLs. */\n baseUrl: string\n}\n\n/**\n * Serve an agent auxiliary route. Returns a `Response` when `urlPath` matches an aux route (card /\n * list-approvals / mcp) and the method + agent resolve; returns `null` to fall through (not an aux\n * route, wrong method, or unknown agent — the caller then owns the 404/next).\n */\nexport async function serveAgentAuxRoute(\n request: Request,\n urlPath: string,\n deps: AuxRouteDeps,\n): Promise<Response | null> {\n const method = request.method.toUpperCase()\n\n // M15 — A2A agent card at `/.well-known/<name>/agent-card.json` (GET).\n const cardName = isAgentCardPath(urlPath)\n if (cardName !== null) {\n if (method !== 'GET') return null\n const agent = deps.agents.find((a) => a.name === cardName)\n if (!agent) return null\n const mod = await deps.loadModule(agent.filePath)\n return handleAgentCard(mod, agent.name, agent.agentPath, deps.baseUrl)\n }\n\n // M14 — GET /api/agents/<name>/approvals (pending HITL approvals).\n if (isListApprovalsPath(urlPath)) {\n if (method !== 'GET') return null\n return handleListApprovals(getApprovalRegistry())\n }\n\n // M16 — POST /api/agents/<name>/mcp (JSON-RPC MCP server).\n const mcpName = isMcpPath(urlPath)\n if (mcpName !== null) {\n if (method !== 'POST') return null\n const agent = deps.agents.find((a) => a.name === mcpName)\n if (!agent) return null\n let body: unknown = null\n try {\n body = await request.json()\n } catch {\n /* malformed/empty JSON → handleMcpJsonRpc returns a -32600 envelope */\n }\n const mod = await deps.loadModule(agent.filePath)\n // M30 — pass the agent's declared `ui://` App resources (named `appResources` export) so the\n // MCP server advertises + serves them via resources/list + resources/read.\n return handleMcpJsonRpc(mod, agent.name, body, extractAppResources(mod))\n }\n\n return null\n}\n","/**\n * T5a.2 Phase G slice 5/N — Node adapter shim for the Web request handler.\n *\n * Bridges Node's `IncomingMessage` + `ServerResponse` shape to the\n * Web-Standards `executeWebRequest` (Phase A → G slices 1-4). Per\n * ADR-0028 R3a, the Node adapter is the ONLY place IncomingMessage ↔\n * Request conversion happens — every other layer of `server/` flows\n * through Web `Request`/`Response`.\n *\n * **Two conversions:**\n *\n * 1. `incomingMessageToWebRequest(req)` — Node → Web. Reads\n * `req.method`, `req.url`, `req.headers`, and (for POST/PUT/etc.)\n * drains the Node Readable body into a Web `ReadableStream`. The\n * request URL is resolved to absolute form using `req.headers.host`\n * (Web Request guarantees absolute URL).\n *\n * 2. `writeWebResponseToServerResponse(response, res)` — Web → Node.\n * Sets status code + status text, copies headers (including all\n * `Set-Cookie` values via `getSetCookie()`), then drains the Web\n * `ReadableStream` body into the Node ServerResponse.\n *\n * Plus the convenience composer `executeWebRequestFromNode(req, res,\n * routeModule, opts?)` that wires both ends — exactly what api-middleware\n * (and the prod CLI start path) need to migrate from the legacy\n * `executeRoute` to `executeWebRequest` without touching call sites.\n *\n * Per `docs/plans/t5a2-incoming-message-to-request-shape-refactor-plan.md`\n * v1.0 § Phase G slice 5/N (closes the executor bridge surface).\n */\nimport type { IncomingMessage, ServerResponse } from 'node:http'\nimport { Readable } from 'node:stream'\n\nimport { executeWebRequest, type ExecuteWebRequestOptions } from '../web-handler.js'\n\n/**\n * Build a Web `Request` from a Node `IncomingMessage`. The Web Request\n * spec requires an absolute URL; we synthesize one from\n * `req.headers.host` (or fall back to `localhost` for test doubles).\n *\n * For methods with a body (POST/PUT/PATCH/DELETE), the Node Readable\n * stream is wrapped as a Web ReadableStream via `Readable.toWeb()` so\n * downstream consumers can call `request.json()` / `request.formData()`\n * / `request.text()` natively.\n *\n * EC-1: Node sometimes provides headers as `string | string[]`. Web\n * `Headers` collapses to single-comma-joined strings — we do the join\n * manually for repeated headers because `Headers.append` would create\n * multi-value entries which behave differently on `.get()`.\n */\nexport function incomingMessageToWebRequest(req: IncomingMessage): Request {\n const host = pickHeaderString(req.headers.host) ?? 'localhost'\n const url = `http://${host}${req.url ?? '/'}`\n\n const headers = new Headers()\n for (const [key, value] of Object.entries(req.headers)) {\n if (value === undefined) continue\n if (Array.isArray(value)) {\n headers.set(key, value.join(', '))\n } else {\n headers.set(key, value)\n }\n }\n\n const method = (req.method ?? 'GET').toUpperCase()\n const hasBody = method !== 'GET' && method !== 'HEAD'\n\n if (!hasBody) {\n return new Request(url, { method, headers })\n }\n\n // Drain Node's Readable into a Web ReadableStream. `Readable.toWeb` is\n // available in Node 18+ (theokit's engines.node floor is 22+, so safe).\n const webStream = Readable.toWeb(req) as ReadableStream\n return new Request(url, {\n method,\n headers,\n body: webStream,\n // EC-2: Node 18+ requires `duplex: 'half'` when body is a stream.\n // The `RequestInit` type omits it (Web spec gap); cast accordingly.\n ...({ duplex: 'half' } as { duplex: 'half' }),\n })\n}\n\n/**\n * Write a Web `Response` into a Node `ServerResponse`. Mirrors the Node\n * `res.writeHead` + `res.end` pattern.\n *\n * Set-Cookie is the only multi-value header the Web spec exposes via\n * `getSetCookie()`. We append each entry individually so Node emits\n * separate `Set-Cookie:` lines per the HTTP spec.\n *\n * If the Response body is a `ReadableStream`, it's piped chunk-by-chunk\n * to `res`. Empty body (null) → just close.\n */\nexport async function writeWebResponseToServerResponse(\n response: Response,\n res: ServerResponse,\n): Promise<void> {\n // Status + headers FIRST (writeHead locks them).\n // EC-3: Set-Cookie needs special handling (writeHead's plain object\n // shape conflicts with multi-value headers; we set them via setHeader\n // BEFORE writeHead so the array form is preserved).\n const setCookies = response.headers.getSetCookie()\n if (setCookies.length > 0) {\n res.setHeader('Set-Cookie', setCookies)\n }\n const otherHeaders: Record<string, string> = {}\n for (const [key, value] of response.headers.entries()) {\n if (key.toLowerCase() === 'set-cookie') continue\n otherHeaders[key] = value\n }\n res.writeHead(response.status, response.statusText, otherHeaders)\n\n // Body — drain ReadableStream OR just end() for null body.\n if (response.body === null) {\n res.end()\n return\n }\n const reader = response.body.getReader()\n try {\n for (;;) {\n const { done, value } = await reader.read()\n if (done) break\n // Node's res.write accepts Uint8Array natively (no conversion needed).\n res.write(value)\n }\n res.end()\n } finally {\n reader.releaseLock()\n }\n}\n\n/**\n * Convenience composer — full request lifecycle Node → Web → Node.\n *\n * Use case: existing api-middleware (and the prod CLI start path)\n * receive Node `(req, res)` from `http.createServer`. To migrate to the\n * Web-Standards executor without rewriting every call site, wrap with\n * this composer:\n *\n * import * as users from './app/users/route.js'\n * await executeWebRequestFromNode(req, res, users, { csrfMode: 'strict' })\n *\n * The Web request is built, dispatched through executeWebRequest, and\n * the Response is drained back into `res`. Caller does NOT need to call\n * `res.end()` afterwards — this composer handles it.\n */\nexport async function executeWebRequestFromNode(\n req: IncomingMessage,\n res: ServerResponse,\n routeModule: Parameters<typeof executeWebRequest>[1],\n opts?: ExecuteWebRequestOptions,\n): Promise<void> {\n const webRequest = incomingMessageToWebRequest(req)\n const webResponse = await executeWebRequest(webRequest, routeModule, opts)\n await writeWebResponseToServerResponse(webResponse, res)\n}\n\n/** Pick the first usable string from Node's `string | string[] | undefined` headers. */\nfunction pickHeaderString(value: string | string[] | undefined): string | undefined {\n if (typeof value === 'string') return value\n if (Array.isArray(value)) {\n for (const v of value) if (typeof v === 'string' && v.length > 0) return v\n }\n return undefined\n}\n"],"mappings":"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","names":["compileAgentModule","jsonError","compileAgentModule"]}
@@ -6,12 +6,14 @@ import {
6
6
  isAgentCardPath,
7
7
  isApprovalPath,
8
8
  isListApprovalsPath,
9
- isMcpPath,
10
9
  mountAgent,
11
10
  resolveTransformer,
12
11
  serveAgentAuxRoute,
13
12
  writeWebResponseToServerResponse
14
- } from "./chunk-XVFMSNDE.js";
13
+ } from "./chunk-DXF64KS5.js";
14
+ import {
15
+ isMcpPath
16
+ } from "./chunk-DMC6HYUR.js";
15
17
  import {
16
18
  getApprovalRegistry,
17
19
  resolveProvider
@@ -2085,4 +2087,4 @@ export {
2085
2087
  theoPluginAsync,
2086
2088
  theoPlugin
2087
2089
  };
2088
- //# sourceMappingURL=chunk-CC5WOQUV.js.map
2090
+ //# sourceMappingURL=chunk-ULFNEG27.js.map