theokit 0.63.0 → 0.64.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{actions-virtual-module-AT6HNADR.js → actions-virtual-module-AD7HFFOF.js} +2 -2
- package/dist/{actions-virtual-module-XJ6J6T4C.js → actions-virtual-module-BKIT7HNS.js} +3 -3
- package/dist/{agent-G525PHCO.js → agent-PL3FR4HI.js} +2 -2
- package/dist/{app-typed-client-5B3IOU45.js → app-typed-client-AJRW3JJV.js} +2 -2
- package/dist/{app-typed-client-NTNYNJTW.js → app-typed-client-NOXQEEVF.js} +3 -3
- package/dist/{aws-lambda-2R77AV5F.js → aws-lambda-AN6CEBXO.js} +5 -4
- package/dist/aws-lambda-AN6CEBXO.js.map +1 -0
- package/dist/{build-CZAM7K6J.js → build-C7CVA5AK.js} +5 -5
- package/dist/{bun-DJ6QEFIP.js → bun-3FFL7CS4.js} +5 -4
- package/dist/bun-3FFL7CS4.js.map +1 -0
- package/dist/{chunk-USN554EK.js → chunk-2NARRZPP.js} +2 -2
- package/dist/{chunk-MIPHNT4J.js → chunk-2PF3TDM2.js} +7 -4
- package/dist/{chunk-MIPHNT4J.js.map → chunk-2PF3TDM2.js.map} +1 -1
- package/dist/{chunk-EB5TYC2Y.js → chunk-5AQRVWSU.js} +6 -6
- package/dist/{chunk-DRLYKXDD.js → chunk-6EV6FC7X.js} +3 -3
- package/dist/{chunk-Q3UE7WIM.js → chunk-A3EMTZR2.js} +1 -1
- package/dist/{chunk-Q3UE7WIM.js.map → chunk-A3EMTZR2.js.map} +1 -1
- package/dist/{chunk-F2LYXOHK.js → chunk-BQJBFHAY.js} +2 -2
- package/dist/{chunk-RQW5YMH7.js → chunk-ELXOGRY5.js} +11 -1
- package/dist/chunk-ELXOGRY5.js.map +1 -0
- package/dist/{chunk-HIYBU6NH.js → chunk-EW5IG7GA.js} +49 -15
- package/dist/chunk-EW5IG7GA.js.map +1 -0
- package/dist/{chunk-L4TB6FXQ.js → chunk-GDZOWQV7.js} +1 -1
- package/dist/chunk-GDZOWQV7.js.map +1 -0
- package/dist/{chunk-DVJRDY3H.js → chunk-JHUFPH7B.js} +8 -8
- package/dist/{chunk-VPX3MS5D.js → chunk-PALZUV6E.js} +5 -1
- package/dist/chunk-PALZUV6E.js.map +1 -0
- package/dist/cli/index.js +6 -6
- package/dist/{cloudflare-UYKOO6EP.js → cloudflare-VIQX4FVC.js} +5 -4
- package/dist/cloudflare-VIQX4FVC.js.map +1 -0
- package/dist/{deno-deploy-W2JWCYPT.js → deno-deploy-PTO7IE4G.js} +2 -2
- package/dist/{dev-GQ2CDBW2.js → dev-HPUCCB3E.js} +5 -5
- package/dist/index.js +2 -2
- package/dist/{internal-api-G25P4TP2.js → internal-api-TOUFX6VZ.js} +2 -2
- package/dist/{internal-api-UBBHEPVE.js → internal-api-TZTO4VMP.js} +3 -3
- package/dist/{mcp-W2UGY4II.js → mcp-AFLDYTK5.js} +2 -2
- package/dist/{netlify-BJQGPMGY.js → netlify-3VSNVURQ.js} +2 -2
- package/dist/{preview-3TLURUAL.js → preview-M3DWFVKB.js} +3 -3
- package/dist/{registry-PAJOMMVV.js → registry-RZHBBLIF.js} +7 -7
- package/dist/server/auth/index.d.ts +89 -1
- package/dist/server/auth/index.js +3 -1
- package/dist/server/index.d.ts +2 -1
- package/dist/server/index.js +4 -2
- package/dist/server/index.js.map +1 -1
- package/dist/server/webhook/index.js +1 -1
- package/dist/{server-boundary-A5JNZ4ND.js → server-boundary-FBHI5NZP.js} +2 -2
- package/dist/{server-boundary-JP6VHXAX.js → server-boundary-Z5LSU7ZW.js} +3 -3
- package/dist/{start-JEYOON64.js → start-QAPAZ2YC.js} +5 -5
- package/dist/{vercel-BEDGUVXX.js → vercel-BZ35DF3B.js} +5 -4
- package/dist/vercel-BZ35DF3B.js.map +1 -0
- package/dist/vite-plugin/index.js +2 -2
- package/dist/{vite-plugin-VLDOBVIS.js → vite-plugin-ZT2XNAGM.js} +5 -5
- package/package.json +3 -3
- package/dist/aws-lambda-2R77AV5F.js.map +0 -1
- package/dist/bun-DJ6QEFIP.js.map +0 -1
- package/dist/chunk-HIYBU6NH.js.map +0 -1
- package/dist/chunk-L4TB6FXQ.js.map +0 -1
- package/dist/chunk-RQW5YMH7.js.map +0 -1
- package/dist/chunk-VPX3MS5D.js.map +0 -1
- package/dist/cloudflare-UYKOO6EP.js.map +0 -1
- package/dist/vercel-BEDGUVXX.js.map +0 -1
- /package/dist/{actions-virtual-module-AT6HNADR.js.map → actions-virtual-module-AD7HFFOF.js.map} +0 -0
- /package/dist/{actions-virtual-module-XJ6J6T4C.js.map → actions-virtual-module-BKIT7HNS.js.map} +0 -0
- /package/dist/{agent-G525PHCO.js.map → agent-PL3FR4HI.js.map} +0 -0
- /package/dist/{app-typed-client-5B3IOU45.js.map → app-typed-client-AJRW3JJV.js.map} +0 -0
- /package/dist/{app-typed-client-NTNYNJTW.js.map → app-typed-client-NOXQEEVF.js.map} +0 -0
- /package/dist/{build-CZAM7K6J.js.map → build-C7CVA5AK.js.map} +0 -0
- /package/dist/{chunk-USN554EK.js.map → chunk-2NARRZPP.js.map} +0 -0
- /package/dist/{chunk-EB5TYC2Y.js.map → chunk-5AQRVWSU.js.map} +0 -0
- /package/dist/{chunk-DRLYKXDD.js.map → chunk-6EV6FC7X.js.map} +0 -0
- /package/dist/{chunk-F2LYXOHK.js.map → chunk-BQJBFHAY.js.map} +0 -0
- /package/dist/{chunk-DVJRDY3H.js.map → chunk-JHUFPH7B.js.map} +0 -0
- /package/dist/{deno-deploy-W2JWCYPT.js.map → deno-deploy-PTO7IE4G.js.map} +0 -0
- /package/dist/{dev-GQ2CDBW2.js.map → dev-HPUCCB3E.js.map} +0 -0
- /package/dist/{internal-api-G25P4TP2.js.map → internal-api-TOUFX6VZ.js.map} +0 -0
- /package/dist/{internal-api-UBBHEPVE.js.map → internal-api-TZTO4VMP.js.map} +0 -0
- /package/dist/{mcp-W2UGY4II.js.map → mcp-AFLDYTK5.js.map} +0 -0
- /package/dist/{netlify-BJQGPMGY.js.map → netlify-3VSNVURQ.js.map} +0 -0
- /package/dist/{preview-3TLURUAL.js.map → preview-M3DWFVKB.js.map} +0 -0
- /package/dist/{registry-PAJOMMVV.js.map → registry-RZHBBLIF.js.map} +0 -0
- /package/dist/{server-boundary-A5JNZ4ND.js.map → server-boundary-FBHI5NZP.js.map} +0 -0
- /package/dist/{server-boundary-JP6VHXAX.js.map → server-boundary-Z5LSU7ZW.js.map} +0 -0
- /package/dist/{start-JEYOON64.js.map → start-QAPAZ2YC.js.map} +0 -0
- /package/dist/{vite-plugin-VLDOBVIS.js.map → vite-plugin-ZT2XNAGM.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server/auth/auth.ts","../src/server/auth/crypto.ts","../src/server/auth/session.ts","../src/server/auth/authenticated-guard.ts","../src/server/_internal/encoding.ts","../src/server/auth/auth-totp.ts","../src/server/auth/auth-backup-codes.ts","../src/server/auth/auth-throttle.ts","../src/server/auth/oauth-pkce.ts","../src/server/auth/oauth-state.ts","../src/server/auth/oidc-discovery.ts"],"mappings":"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","names":["constantTimeEquals"]}
|
|
@@ -150,6 +150,22 @@ async function dispatchWebhook(def, request) {
|
|
|
150
150
|
});
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
+
// src/server/webhook/providers/configured-secret.ts
|
|
154
|
+
function configuredSecrets(value, option) {
|
|
155
|
+
const secrets = typeof value === "string" ? [value] : value;
|
|
156
|
+
if (secrets.length === 0) return { ok: false, reason: `no ${option} configured` };
|
|
157
|
+
for (let i = 0; i < secrets.length; i++) {
|
|
158
|
+
if (secrets[i].length === 0) {
|
|
159
|
+
const where = typeof value === "string" ? option : `${option}[${i}]`;
|
|
160
|
+
return { ok: false, reason: `${where} is empty` };
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return { ok: true, secrets };
|
|
164
|
+
}
|
|
165
|
+
function refusingVerifier(reason) {
|
|
166
|
+
return () => ({ ok: false, reason });
|
|
167
|
+
}
|
|
168
|
+
|
|
153
169
|
// src/server/webhook/providers/stripe.ts
|
|
154
170
|
function parseStripeHeader(header) {
|
|
155
171
|
const parts = header.split(",").map((p) => p.trim());
|
|
@@ -199,7 +215,9 @@ var fromHex = (hex) => {
|
|
|
199
215
|
};
|
|
200
216
|
function stripe(opts) {
|
|
201
217
|
const tolerance = opts.toleranceSeconds ?? 300;
|
|
202
|
-
const
|
|
218
|
+
const configured = configuredSecrets(opts.secret, "secret");
|
|
219
|
+
if (!configured.ok) return refusingVerifier(configured.reason);
|
|
220
|
+
const { secrets } = configured;
|
|
203
221
|
return async (req) => {
|
|
204
222
|
const header = req.headers.get("stripe-signature");
|
|
205
223
|
if (!header) {
|
|
@@ -235,7 +253,10 @@ function stripe(opts) {
|
|
|
235
253
|
|
|
236
254
|
// src/server/webhook/providers/hmac-sha256.ts
|
|
237
255
|
function verifyHmacSha256(opts) {
|
|
238
|
-
const { header,
|
|
256
|
+
const { header, decode } = opts;
|
|
257
|
+
const configured = configuredSecrets(opts.secrets, opts.option);
|
|
258
|
+
if (!configured.ok) return refusingVerifier(configured.reason);
|
|
259
|
+
const { secrets } = configured;
|
|
239
260
|
return async (req) => {
|
|
240
261
|
const value = req.headers.get(header);
|
|
241
262
|
if (!value) return { ok: false, reason: `missing ${header} header` };
|
|
@@ -277,13 +298,13 @@ function fromPrefixedHex(value) {
|
|
|
277
298
|
}
|
|
278
299
|
return { ok: true, bytes };
|
|
279
300
|
}
|
|
280
|
-
function verifyHubSignature256(secrets) {
|
|
281
|
-
return verifyHmacSha256({ header: HEADER, secrets, decode: fromPrefixedHex });
|
|
301
|
+
function verifyHubSignature256(secrets, option) {
|
|
302
|
+
return verifyHmacSha256({ header: HEADER, secrets, option, decode: fromPrefixedHex });
|
|
282
303
|
}
|
|
283
304
|
|
|
284
305
|
// src/server/webhook/providers/github.ts
|
|
285
306
|
function github(opts) {
|
|
286
|
-
return verifyHubSignature256(
|
|
307
|
+
return verifyHubSignature256(opts.secret, "secret");
|
|
287
308
|
}
|
|
288
309
|
|
|
289
310
|
// src/server/webhook/providers/slack.ts
|
|
@@ -300,7 +321,9 @@ function fromHex2(hex) {
|
|
|
300
321
|
}
|
|
301
322
|
function slack(opts) {
|
|
302
323
|
const tolerance = opts.toleranceSeconds ?? 300;
|
|
303
|
-
const
|
|
324
|
+
const configured = configuredSecrets(opts.signingSecret, "signingSecret");
|
|
325
|
+
if (!configured.ok) return refusingVerifier(configured.reason);
|
|
326
|
+
const signingSecret = configured.secrets[0];
|
|
304
327
|
return async (req) => {
|
|
305
328
|
const tsHeader = req.headers.get("x-slack-request-timestamp");
|
|
306
329
|
const sigHeader = req.headers.get("x-slack-signature");
|
|
@@ -354,8 +377,10 @@ function slack(opts) {
|
|
|
354
377
|
|
|
355
378
|
// src/server/webhook/providers/telegram.ts
|
|
356
379
|
function telegram(opts) {
|
|
380
|
+
const configured = configuredSecrets(opts.secretToken, "secretToken");
|
|
381
|
+
if (!configured.ok) return refusingVerifier(configured.reason);
|
|
357
382
|
const enc2 = new TextEncoder();
|
|
358
|
-
const expected = enc2.encode(
|
|
383
|
+
const expected = enc2.encode(configured.secrets[0]);
|
|
359
384
|
return (req) => {
|
|
360
385
|
const header = req.headers.get("x-telegram-bot-api-secret-token");
|
|
361
386
|
if (!header) {
|
|
@@ -379,7 +404,9 @@ function fromHex3(hex) {
|
|
|
379
404
|
return bytes;
|
|
380
405
|
}
|
|
381
406
|
function discord(opts) {
|
|
382
|
-
const
|
|
407
|
+
const configured = configuredSecrets(opts.publicKey, "publicKey");
|
|
408
|
+
if (!configured.ok) return refusingVerifier(configured.reason);
|
|
409
|
+
const keyBytes = fromHex3(configured.secrets[0]);
|
|
383
410
|
return async (req) => {
|
|
384
411
|
if (!keyBytes) return { ok: false, reason: "malformed public key hex" };
|
|
385
412
|
const sigHex = req.headers.get("x-signature-ed25519");
|
|
@@ -411,13 +438,16 @@ function discord(opts) {
|
|
|
411
438
|
|
|
412
439
|
// src/server/webhook/providers/whatsapp.ts
|
|
413
440
|
function whatsapp(opts) {
|
|
414
|
-
return verifyHubSignature256(
|
|
415
|
-
Array.isArray(opts.appSecret) ? opts.appSecret : [opts.appSecret]
|
|
416
|
-
);
|
|
441
|
+
return verifyHubSignature256(opts.appSecret, "appSecret");
|
|
417
442
|
}
|
|
418
443
|
function whatsappSubscribe(opts) {
|
|
444
|
+
const configured = configuredSecrets(opts.verifyToken, "verifyToken");
|
|
445
|
+
if (!configured.ok) {
|
|
446
|
+
const { reason } = configured;
|
|
447
|
+
return () => ({ ok: false, reason });
|
|
448
|
+
}
|
|
419
449
|
const encoder = new TextEncoder();
|
|
420
|
-
const expected = encoder.encode(
|
|
450
|
+
const expected = encoder.encode(configured.secrets[0]);
|
|
421
451
|
return (req) => {
|
|
422
452
|
const params = new URL(req.url).searchParams;
|
|
423
453
|
if (params.get("hub.mode") !== "subscribe") {
|
|
@@ -454,8 +484,12 @@ function fromBase64(value) {
|
|
|
454
484
|
}
|
|
455
485
|
}
|
|
456
486
|
function line(options) {
|
|
457
|
-
|
|
458
|
-
|
|
487
|
+
return verifyHmacSha256({
|
|
488
|
+
header: HEADER2,
|
|
489
|
+
secrets: options.channelSecret,
|
|
490
|
+
option: "channelSecret",
|
|
491
|
+
decode: fromBase64
|
|
492
|
+
});
|
|
459
493
|
}
|
|
460
494
|
|
|
461
495
|
export {
|
|
@@ -474,4 +508,4 @@ export {
|
|
|
474
508
|
whatsappSubscribe,
|
|
475
509
|
line
|
|
476
510
|
};
|
|
477
|
-
//# sourceMappingURL=chunk-
|
|
511
|
+
//# sourceMappingURL=chunk-EW5IG7GA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server/webhook/timing-safe-equal.ts","../src/server/webhook/raw-body.ts","../src/server/webhook/define-webhook.ts","../src/server/webhook/providers/configured-secret.ts","../src/server/webhook/providers/stripe.ts","../src/server/webhook/providers/hmac-sha256.ts","../src/server/webhook/providers/hub-signature-256.ts","../src/server/webhook/providers/github.ts","../src/server/webhook/providers/slack.ts","../src/server/webhook/providers/telegram.ts","../src/server/webhook/providers/discord.ts","../src/server/webhook/providers/whatsapp.ts","../src/server/webhook/providers/line.ts"],"mappings":"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","names":["result","PREFIX","fromHex","enc","enc","fromHex","HEADER"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/contracts/client-safe-error.ts","../src/server/http/send-response.ts","../src/server/http/node-request.ts","../src/server/http/controller-dispatch.ts","../src/server/security/csrf-warn-dispatch.ts","../src/server/observability/audit-log.ts","../src/server/security/csrf.ts"],"sourcesContent":["import type { TheoErrorEnvelope } from './error-envelope.js'\n\n/**\n * What an error is allowed to tell the caller.\n *\n * Most error codes describe something the caller did and can fix, so their message is the useful\n * part of the response. An *internal* failure is the opposite: its message describes the server —\n * a connection string, an upstream host, a stack of internal names — and the caller can act on\n * none of it. In production it is redacted; in development it is exactly what makes the framework\n * debuggable, so it stays.\n *\n * This lives in one place because it was previously stated in two and missing from a third. The\n * Node runner redacted, the Web error builder redacted, and an exception escaping a Web handler\n * took a hand-built path that did neither — same route, same failure, more disclosure depending\n * on which transport served it. That is the \"one contract, three transports\" rule in\n * `rules/three-target-parity.md` being broken by duplication rather than by design.\n */\n\n/** Both spellings the codebase uses for \"this is our fault, and the detail is ours too\". */\nconst INTERNAL_CODES: ReadonlySet<string> = new Set(['INTERNAL_ERROR', 'INTERNAL_SERVER_ERROR'])\n\nconst GENERIC_INTERNAL_MESSAGE = 'Internal server error'\n\nfunction redacts(code: string): boolean {\n return INTERNAL_CODES.has(code) && process.env.NODE_ENV === 'production'\n}\n\n/** The message this code may carry to the caller. */\nexport function clientSafeErrorMessage(code: string, message: string): string {\n return redacts(code) ? GENERIC_INTERNAL_MESSAGE : message\n}\n\n/**\n * The envelope this code may carry to the caller.\n *\n * When it redacts, `cause`, `meta` and `ext` go with the message rather than being filtered\n * field by field: they exist to describe the failure, and the whole point is that this failure is\n * not describable to the caller. Keeping the code is what lets a client branch on it.\n */\nexport function clientSafeErrorEnvelope(envelope: TheoErrorEnvelope): TheoErrorEnvelope {\n if (!redacts(envelope.code)) return envelope\n return { code: envelope.code, message: GENERIC_INTERNAL_MESSAGE }\n}\n","import type { ServerResponse } from 'node:http'\n\nimport { clientSafeErrorMessage } from '../../core/contracts/client-safe-error.js'\nimport type { TheoTransformer } from '../transformer.js'\n\n/**\n * Canonical HTTP response helpers (T5.1 extraction).\n *\n * Moved out of execute.ts so request-pipeline stages (execute-stages.ts,\n * handle-request-error.ts, etc.) can depend on these helpers without\n * creating a cycle through execute.ts.\n *\n * Public surface re-exported from execute.ts for backward compat — every\n * existing caller of `sendError` / `sendJson` continues to work via the\n * `theokit/server` barrel.\n */\n\nexport function sendJson(\n res: ServerResponse,\n data: unknown,\n status = 200,\n transformer?: TheoTransformer,\n): void {\n // T1.2 — transformer-aware serialization. Default (no transformer) uses\n // JSON.stringify direct for backward compat.\n const body = transformer ? transformer.serialize(data) : JSON.stringify(data)\n res.writeHead(status, {\n 'Content-Type': 'application/json',\n 'Content-Length': Buffer.byteLength(body),\n })\n res.end(body)\n}\n\n/** Render anything that would end the log line as a visible escape, so one call logs one line. */\nfunction oneLine(value: string): string {\n return value.replace(/[\\r\\n]/g, '\\\\n')\n}\n\nexport interface SendErrorOptions {\n custom404Html?: string\n custom500Html?: string\n}\n\n/**\n * Canonical error response.\n *\n * T6.3 (PV-17): the positional 7-param signature is preserved for backward\n * compat. New call sites should use the options-bag form:\n *\n * sendError(res, { code, message, status, issues?, requestId?, options? })\n *\n * Both shapes resolve to the same implementation.\n */\nexport interface SendErrorInput {\n code: string\n message: string\n status: number\n issues?: unknown[]\n requestId?: string\n options?: SendErrorOptions\n}\n\nexport function sendError(res: ServerResponse, input: SendErrorInput): void\n/* eslint-disable-next-line max-params -- T6.3: positional overload preserved\n for backward compat (callers across cli/server still use positional). The\n options-bag overload above is the recommended path. */\nexport function sendError(\n res: ServerResponse,\n code: string,\n message: string,\n status: number,\n issues?: unknown[],\n requestId?: string,\n options?: SendErrorOptions,\n): void\n/* eslint-disable-next-line max-params -- delegates to two surface overloads above; the parameter\n count mirrors the back-compat contract, not internal complexity. The `complexity` half of this\n suppression went away when the redaction rule stopped being restated inline. */\nexport function sendError(\n res: ServerResponse,\n codeOrInput: string | SendErrorInput,\n message?: string,\n status?: number,\n issues?: unknown[],\n requestId?: string,\n options?: SendErrorOptions,\n): void {\n let code: string\n if (typeof codeOrInput === 'string') {\n code = codeOrInput\n message = message ?? ''\n status = status ?? 500\n } else {\n code = codeOrInput.code\n message = codeOrInput.message\n status = codeOrInput.status\n issues = codeOrInput.issues\n requestId = codeOrInput.requestId\n options = codeOrInput.options\n }\n const errorMessage = clientSafeErrorMessage(code, message)\n\n if (code === 'INTERNAL_ERROR') {\n // One log entry per call, whatever the message contains. An exception message can be built\n // from request data and can therefore carry a newline; unescaped, that lets a caller append\n // whatever lines it likes to the log — including a plausible entry attributed to something\n // else (CodeQL `js/log-injection`).\n console.error(`[${oneLine(requestId ?? 'no-id')}] ${oneLine(message)}`)\n }\n\n if (status === 404 && options?.custom404Html) {\n const body = options.custom404Html\n res.writeHead(404, {\n 'Content-Type': 'text/html; charset=utf-8',\n 'Content-Length': Buffer.byteLength(body),\n })\n res.end(body)\n return\n }\n if (status === 500 && options?.custom500Html) {\n const body = options.custom500Html\n res.writeHead(500, {\n 'Content-Type': 'text/html; charset=utf-8',\n 'Content-Length': Buffer.byteLength(body),\n })\n res.end(body)\n return\n }\n\n sendJson(\n res,\n {\n error: {\n code,\n message: errorMessage,\n ...(requestId ? { requestId } : {}),\n ...(issues ? { issues } : {}),\n },\n },\n status,\n )\n}\n\n/**\n * T5a.2 Phase G slice 4/N — Web-Standards response helpers.\n *\n * Mirror of `sendJson` + `sendError` for the Web `Request`/`Response`\n * shape. Returns a native `Response` directly instead of mutating a\n * `ServerResponse`.\n *\n * v1.0 § Phase G.\n *\n * **Difference vs IncomingMessage path:**\n * - No `Content-Length` set explicitly — the runtime computes it from\n * the body when needed. CF Workers / Bun / Deno all do this; setting\n * it manually risks conflict if the body is a stream rather than a\n * fixed string.\n * - Custom 404/500 HTML options preserved (same opts shape).\n * - `requestId` flows into the response body's error envelope AND\n * surfaces as `x-request-id` header (parity with handleWebRequestError\n * Phase G slice 3/N).\n */\nexport function buildJsonResponse(\n data: unknown,\n status = 200,\n transformer?: TheoTransformer,\n): Response {\n const body = transformer ? transformer.serialize(data) : JSON.stringify(data)\n return new Response(body, {\n status,\n headers: { 'content-type': 'application/json' },\n })\n}\n\nexport function buildErrorResponse(input: SendErrorInput): Response {\n const { code, message, status, issues, requestId, options } = input\n const errorMessage = clientSafeErrorMessage(code, message)\n\n if (code === 'INTERNAL_ERROR') {\n // One log entry per call, whatever the message contains. An exception message can be built\n // from request data and can therefore carry a newline; unescaped, that lets a caller append\n // whatever lines it likes to the log — including a plausible entry attributed to something\n // else (CodeQL `js/log-injection`).\n console.error(`[${oneLine(requestId ?? 'no-id')}] ${oneLine(message)}`)\n }\n\n const headers: Record<string, string> = {}\n if (requestId !== undefined) headers['x-request-id'] = requestId\n\n if (status === 404 && options?.custom404Html !== undefined) {\n headers['content-type'] = 'text/html; charset=utf-8'\n return new Response(options.custom404Html, { status: 404, headers })\n }\n if (status === 500 && options?.custom500Html !== undefined) {\n headers['content-type'] = 'text/html; charset=utf-8'\n return new Response(options.custom500Html, { status: 500, headers })\n }\n\n headers['content-type'] = 'application/json'\n const body = JSON.stringify({\n error: {\n code,\n message: errorMessage,\n ...(requestId ? { requestId } : {}),\n ...(issues ? { issues } : {}),\n },\n })\n return new Response(body, { status, headers })\n}\n","/**\n * Pure Node `IncomingMessage` → Web `Request` converters.\n *\n * Kept free of any dependency on `web-handler.js` / `execute*.js` so the\n * executor (`execute.ts`) can build the handler-facing Web `Request` without\n * pulling the Web dispatch pipeline into its import graph (ADR-0028 R3a — the\n * Node adapter is the ONLY place IncomingMessage ↔ Request conversion lives;\n * these are the primitive converters it and the executor share).\n */\nimport type { IncomingMessage } from 'node:http'\nimport { Readable } from 'node:stream'\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\n/** Web Request requires an absolute URL; synthesize one from the Host header. */\nfunction synthesizeAbsoluteUrl(req: IncomingMessage): string {\n const host = pickHeaderString(req.headers.host) ?? 'localhost'\n return `http://${host}${req.url ?? '/'}`\n}\n\n/**\n * Collapse Node's `string | string[]` headers into a Web `Headers`. Repeated\n * headers are comma-joined (not `.append`ed) because `Headers.append` creates\n * multi-value entries that behave differently on `.get()` (EC-1).\n */\nfunction nodeHeadersToWeb(req: IncomingMessage): Headers {\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 return headers\n}\n\n/**\n * Build a Web `Request` from a Node `IncomingMessage`, body included. The Web\n * Request spec requires an absolute URL; we synthesize one from the Host header\n * (fallback `localhost` for test doubles).\n *\n * For methods with a body (POST/PUT/PATCH/DELETE), the Node Readable stream is\n * wrapped as a Web ReadableStream via `Readable.toWeb()` so downstream consumers\n * can call `request.json()` / `request.formData()` / `request.text()` natively.\n */\nexport function incomingMessageToWebRequest(req: IncomingMessage): Request {\n const url = synthesizeAbsoluteUrl(req)\n const headers = nodeHeadersToWeb(req)\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 * A Node request that has NOT been converted yet — method now, body only if someone claims it.\n *\n * theokit#400. `incomingMessageToWebRequest` drains the Node stream, and a stream drains once. A\n * dispatcher that converts in order to decide whether it owns a path has already spent the body on\n * every path it does not own: the next branch attaches to a readable that has already ended, waits\n * for an `'end'` that cannot fire twice, and the request hangs with no status at all.\n *\n * The fix is an ordering one, so the type encodes the ordering: a router reads `method` (free) and\n * calls `toRequest()` only after it has decided the request is its own. Passing the source instead\n * of a `Request` is what makes \"did you convert before deciding?\" answerable by reading a signature.\n *\n * `toRequest()` memoizes, because a second conversion of the same `IncomingMessage` yields a\n * Request whose body is an empty closed stream — a silent truncation, which is worse than the hang\n * it would replace.\n */\nexport interface WebRequestSource {\n /** Uppercase HTTP method. Available without touching the body. */\n readonly method: string\n /** Convert on demand. Idempotent: repeated calls return the same `Request`. */\n toRequest: () => Request\n}\n\n/** Wrap `req` as a {@link WebRequestSource} — the conversion is deferred and memoized. */\nexport function createWebRequestSource(req: IncomingMessage): WebRequestSource {\n let converted: Request | undefined\n return {\n method: (req.method ?? 'GET').toUpperCase(),\n toRequest: () => (converted ??= incomingMessageToWebRequest(req)),\n }\n}\n\n/**\n * Build the Web `Request` handed to a route handler as `ctx.request` in the\n * Node server path (dev + `theokit start`). Method + absolute URL + headers\n * only — NO body.\n *\n * Why no body: the Node executor parses the request body BEFORE the handler\n * runs and exposes the parsed value as `ctx.body` (the typed, documented body\n * API). By the time the handler is called the Node stream is already drained,\n * so re-wrapping it would yield an empty/closed stream. Handlers read the body\n * via `ctx.body`; `ctx.request` is for the Web-standard header/cookie/URL/method\n * surface (e.g. `createSessionManagerWeb.getSession(ctx.request)`).\n *\n * Per ADR-0028 R3a, handlers see a Web `Request` in every runtime — this closes\n * the gap where the Node path leaked the raw `IncomingMessage` (whose `.headers`\n * is a plain object, so `.headers.get(...)` threw for Web-standard consumers).\n */\nexport function incomingMessageToHandlerRequest(req: IncomingMessage): Request {\n return new Request(synthesizeAbsoluteUrl(req), {\n method: (req.method ?? 'GET').toUpperCase(),\n headers: nodeHeadersToWeb(req),\n })\n}\n","/* eslint-disable security/detect-non-literal-fs-filename --\n * Controller files are walked from the developer's `serverDir/controllers`\n * (a build-time config path), never from HTTP input. No injection vector.\n */\nimport { readdirSync, type Dirent } from 'node:fs'\nimport type { IncomingMessage, ServerResponse } from 'node:http'\nimport { join } from 'node:path'\n\nimport {\n CONTROLLER_PREFIX,\n createDecoratorHandler,\n getMeta,\n isControllerClass,\n Reflector,\n type ServeAgent,\n} from '@theokit/http'\n\nimport { dispatchCsrfWarn } from '../security/csrf-warn-dispatch.js'\nimport { enforceCsrf, type DisallowedConfig } from '../security/csrf.js'\n\nimport { incomingMessageToWebRequest } from './node-request.js'\nimport { sendError } from './send-response.js'\n\n/** A decorator controller constructor (`@Controller` class). */\ntype ControllerClass = new (...args: never[]) => object\n\n/** Loads a controller module by absolute path. In dev this is Vite's `ssrLoadModule`\n * (the Task 1.1 swc transform has already compiled the parameter decorators); tests\n * inject `@theokit/http`'s `loadControllerWithSwc`. */\nexport type ControllerModuleLoader = (absPath: string) => Promise<Record<string, unknown>>\n\n/** A built controller route table exposed as a pure Web-Standard handler. */\ninterface ControllerDispatcher {\n /** `null` = no controller route matched — the host owns the miss (404 / fall-through). */\n dispatch(request: Request): Promise<Response | null>\n /** Non-executing route probe — true when a controller route owns `method` + `pathname`. */\n matches(method: string, pathname: string): boolean\n /** True when the controller owning `pathname` declared `theokit:csrf-exempt`. */\n isCsrfExempt(pathname: string): boolean\n}\n\n// State-mutating methods get CSRF, mirroring the file-route pipeline (execute.ts).\nconst CSRF_PROTECTED_METHODS = new Set(['POST', 'PUT', 'PATCH', 'DELETE'])\n\n/**\n * A controller declaring that it authenticates by other means, so the CSRF gate has nothing to add.\n *\n * The case this exists for is a webhook. Stripe, GitHub and every other sender authenticate with an\n * HMAC over the request body — stronger than a header, and entirely unrelated to one. None of them\n * will ever send `X-Theo-Action`, so without this a webhook endpoint answers 403 to every real\n * delivery and the only escape is `csrf: 'warn'` for the whole application (theokit#535).\n *\n * DELIBERATELY separate from `theokit:public`. They answer different questions — \"may an\n * unauthenticated caller reach this?\" and \"does this route authenticate by other means?\" — and a\n * route can want the first without the second. Conflating them would lift the gate off every public\n * route in the ecosystem as a side effect of a webhook fix.\n *\n * Declared on the CONTROLLER, not the method: the granularity a webhook needs, and it avoids a\n * second path matcher alongside `handle.matches` that could drift from it.\n */\nconst CSRF_EXEMPT_METADATA = 'theokit:csrf-exempt'\n\n/**\n * Segment-wise, so `api/hooks` never matches `api/hooks-admin`.\n *\n * Split-and-filter rather than a trimming regex: `/^\\/+|\\/+$/` is quadratic on a pathname of\n * repeated slashes, and a pathname is attacker-supplied (sonarjs/slow-regex). Splitting is linear\n * and `filter(Boolean)` drops the empty segments the leading and trailing slashes produce, which is\n * all the trim was for.\n */\nfunction segments(value: string): string[] {\n return value.split('/').filter(Boolean)\n}\n\nfunction pathOwnedByPrefix(pathname: string, prefix: string): boolean {\n const want = segments(prefix)\n const got = segments(pathname)\n if (want.length === 0 || got.length < want.length) return false\n return want.every((segment, i) => got[i] === segment)\n}\n\n/** Recursively collect `*.controller.ts` files under `dir` (absolute paths). */\n/**\n * Every `*.controller.ts` under `dir`, recursively. Exported for theokit#123: the build emitter\n * must find exactly the same set the dev dispatcher does, and two independent walks would be two\n * definitions of \"a controller\" that drift.\n */\nexport function findControllerFiles(dir: string): string[] {\n const found: string[] = []\n const walk = (current: string): void => {\n let entries: Dirent[]\n try {\n entries = readdirSync(current, { withFileTypes: true })\n } catch {\n return // dir doesn't exist — no controllers\n }\n for (const entry of entries) {\n const full = join(current, entry.name)\n if (entry.isDirectory()) walk(full)\n // theokit#123 — `.mjs` alongside `.ts`. Dev walks the SOURCE tree; production walks the\n // COMPILED tree under `dist/controllers`, where the same files exist as `*.controller.mjs`.\n // One walk for both keeps a single definition of \"a controller file\"; two would drift, and a\n // file that counts in dev and not in production is exactly the dev/prod split this fixes.\n else if (entry.name.endsWith('.controller.ts') || entry.name.endsWith('.controller.mjs'))\n found.push(full)\n }\n }\n walk(dir)\n return found\n}\n\n/** A discovered controller: its source file + the loaded `@Controller` class. */\ninterface ControllerModule {\n filePath: string\n cls: ControllerClass\n /**\n * The module's full export namespace — theokit#124.\n *\n * Kept alongside the class because it is the ONLY place a `@Body(schema)` regains a name. The\n * schema on `WalkResult.bodySchema` is a runtime `z.ZodType` with no source identifier, but it is\n * the very object this module exported, so matching it back by reference identity recovers the\n * exported name the typed-client codegen needs to write `z.infer<typeof ...>`.\n *\n * Unused by the dispatch path, which needs only the class.\n */\n exports: Readonly<Record<string, unknown>>\n}\n\n/**\n * Load every `@Controller` class under `controllersDir` via the injected loader,\n * keeping each class paired with its source file (needed by the typed-client\n * codegen to emit `import type { X } from '<file>'`). Non-controller exports are\n * ignored (`isControllerClass` — reused from @theokit/http).\n */\nexport async function scanControllerModules(\n controllersDir: string,\n loadModule: ControllerModuleLoader,\n): Promise<ControllerModule[]> {\n const files = findControllerFiles(controllersDir)\n const modules: ControllerModule[] = []\n for (const filePath of files) {\n const mod = await loadModule(filePath)\n for (const exported of Object.values(mod)) {\n if (typeof exported === 'function' && isControllerClass(exported)) {\n modules.push({ filePath, cls: exported as ControllerClass, exports: mod })\n }\n }\n }\n return modules\n}\n\n/** Load every `@Controller` class under `controllersDir` (classes only). */\nasync function scanControllers(\n controllersDir: string,\n loadModule: ControllerModuleLoader,\n): Promise<ControllerClass[]> {\n const modules = await scanControllerModules(controllersDir, loadModule)\n return modules.map((m) => m.cls)\n}\n\n/**\n * Scan `controllersDir` and build a Web-Standard dispatcher over the decorator\n * controllers found. Returns `null` when the directory has no controllers, so\n * the host can skip the controller path entirely (zero cost for routes-only apps).\n *\n * Dispatch REUSES @theokit/http's `createDecoratorHandler` (match + `@Param`\n * binding + `@Body` validation + Response building) — never re-implemented (ADR-1).\n */\nexport async function createControllerDispatcher(opts: {\n controllersDir: string\n loadModule: ControllerModuleLoader\n /** M47 — serves `@Expose`-bound agent routes (theo supplies a `mountAgent`-backed impl). */\n serveAgent?: ServeAgent\n}): Promise<ControllerDispatcher | null> {\n const classes = await scanControllers(opts.controllersDir, opts.loadModule)\n if (classes.length === 0) return null\n // No `undeclaredRoutes` pass-through, deliberately (usetheokit/theokit#576). The handler defaults\n // to `'deny'`, and a theokit app cannot ship an undeclared controller anyway — `theokit build`\n // refuses one (#514). What this closes is `theokit dev`, which never runs that gate: an undeclared\n // route now answers 403 there, at the first request, instead of being served until the build\n // catches it. An escape here would only let an app defer a failure it cannot ship past.\n const handle = createDecoratorHandler({ controllers: classes, serveAgent: opts.serveAgent })\n const reflector = new Reflector()\n\n // Read once at construction: the metadata cannot change between requests, and re-walking every\n // class per request would put a reflection pass on the hot path for a value that never moves.\n const exemptPrefixes = classes\n // `Reflector`, not `Reflect.getMetadata`: the global is only typed where `reflect-metadata`\n // has been imported, and this module does not import it — the dts build fails on it (TS2339).\n // `@SetMetadata` writes through the same store, so the reader is the framework's own.\n .filter((cls) => reflector.getByKey<boolean>(CSRF_EXEMPT_METADATA, cls) === true)\n .map((cls) => {\n const meta = getMeta<{ prefix?: string }>(CONTROLLER_PREFIX, cls)\n return meta?.prefix ?? ''\n })\n .filter((prefix) => prefix !== '')\n\n return {\n dispatch: (request) => handle(request),\n matches: (method, pathname) => handle.matches(method, pathname),\n isCsrfExempt: (pathname) => exemptPrefixes.some((p) => pathOwnedByPrefix(pathname, p)),\n }\n}\n\n/**\n * Write a controller's Web `Response` to a Node response, byte for byte.\n *\n * The body used to be read with `await response.text()`, under a comment asserting that controllers\n * never stream. The comment was true of this path and hid the real problem: `text()` decodes as\n * UTF-8, so every byte >= 0x80 became `U+FFFD`. A payload of all 256 byte values arrived as 512\n * bytes; a 55 296-byte MPEG from `@theokit/plugin-voice` arrived as 76 790 bytes beginning\n * `ef bf bd`. Status 200, correct content-type, plausible length — invisible until someone opens\n * the file. File routes were never affected: `executeRoute` pumps the stream, so this was a silent\n * divergence between two paths meant to be at parity.\n *\n * `arrayBuffer()` fixes it without changing anything else. This path stays BUFFERED, exactly as\n * before — a controller returning a streamed body still has it collected here, so a plugin that\n * promises progressive delivery does not get it through a controller. That is a real limitation and\n * a separate change: making it stream alters when bytes reach the client, which is behaviour beyond\n * the corruption this repairs.\n */\nasync function writeControllerResponse(res: ServerResponse, response: Response): Promise<void> {\n const headersBag: Record<string, string> = {}\n for (const [k, v] of response.headers) {\n if (k.toLowerCase() !== 'set-cookie') headersBag[k] = v\n }\n const setCookies = response.headers.getSetCookie()\n if (setCookies.length > 0) res.setHeader('Set-Cookie', setCookies)\n res.writeHead(response.status, headersBag)\n // `Buffer.from(ArrayBuffer)` views the bytes as they are. Any string in between is a decode, and\n // a decode of arbitrary bytes is a loss.\n const body = response.body ? Buffer.from(await response.arrayBuffer()) : undefined\n res.end(body !== undefined && body.length > 0 ? body : undefined)\n}\n\n/**\n * The `api-middleware` fall-through in one call: scan `controllersDir`, build the\n * dispatcher, and serve the request. Builds a body-ful Web `Request` (`@Body`\n * needs the body; the raw stream is undrained at a route miss) and enforces CSRF\n * with the SAME gate file routes use (parity). Returns `true` when a controller\n * handled it (or CSRF blocked it), `false` when there are no controllers OR none\n * matched (the host continues to its own 404). Built per-miss so controller edits\n * reflect via HMR.\n */\nexport async function dispatchControllerRequest(args: {\n controllersDir: string\n loadModule: ControllerModuleLoader\n req: IncomingMessage\n res: ServerResponse\n csrfMode: 'off' | 'warn' | 'strict'\n disallowed?: DisallowedConfig\n requestId: string\n /** M47 — serves `@Expose`-bound agent routes (mountAgent-backed); omit for routes-only apps. */\n serveAgent?: ServeAgent\n}): Promise<boolean> {\n const { req, res, csrfMode, disallowed, requestId } = args\n const dispatcher = await createControllerDispatcher({\n controllersDir: args.controllersDir,\n loadModule: args.loadModule,\n serveAgent: args.serveAgent,\n })\n if (!dispatcher) return false\n\n const method = (req.method ?? 'GET').toUpperCase()\n const webRequest = incomingMessageToWebRequest(req)\n const pathname = new URL(webRequest.url).pathname\n\n // CSRF parity: enforce ONLY when a protected-method controller route actually\n // owns this path (probe with the non-executing matcher — never double-dispatch,\n // which would run the handler + its side effects). An unrouted path falls\n // through to the host's own 404, not a 403.\n if (\n CSRF_PROTECTED_METHODS.has(method) &&\n dispatcher.matches(method, pathname) &&\n !dispatcher.isCsrfExempt(pathname)\n ) {\n const decision = enforceCsrf(\n req,\n csrfMode,\n { warn: dispatchCsrfWarn, path: req.url },\n disallowed,\n )\n if (!decision.allow) {\n sendError(\n res,\n 'CSRF_INVALID',\n decision.reason ?? 'CSRF check failed',\n 403,\n undefined,\n requestId,\n )\n return true\n }\n }\n\n const response = await dispatcher.dispatch(webRequest)\n if (response === null) return false\n await writeControllerResponse(res, response)\n return true\n}\n","/**\n * Canonical CSRF warn dispatcher (T3.3 of architecture-review-remediation-plan).\n *\n * Consolidates the duplicated `warn: (payload) => { warnOnce(...) }` closure\n * that previously appeared in both `http/execute.ts` and\n * `http/action-execute.ts`. Resolves PV-10 (DRY).\n *\n * `warnOnce` dedupes by `event:method:path` so a request loop with 1000 POSTs\n * doesn't flood logs with identical warnings. Apps grep for `event\":\"csrf.warn\"`\n * (stable event shape — see [[enforcement-cutover.md]]).\n */\nimport { warnOnce } from '../observability/logger.js'\n\ninterface CsrfWarnPayload {\n event: string\n method: string\n path?: string\n reason: string\n code?: string\n docsUrl?: string\n warnOnce?: boolean\n}\n\n/**\n * Build the warn callback that `enforceCsrf` invokes for soft-mode warnings.\n * Returned function is suitable for the `warn` field of `enforceCsrf`'s options.\n */\nexport function dispatchCsrfWarn(payload: CsrfWarnPayload): void {\n const key = `${payload.event}:${payload.method}:${payload.path ?? ''}`\n warnOnce(key, payload as unknown as Record<string, unknown>)\n}\n","/**\n * T4.1 — Audit logging interface + default JSON stdout sink.\n *\n * Per ADR D4: define the interface; ship a zero-dep default; reserve\n * adapter shapes for Postgres, File, OpenTelemetry, Sentry as follow-up\n * packages. Persistence has heavy deps (`pg`, `better-sqlite3`); we\n * keep core dep-free and let users opt in.\n *\n * Compatibility:\n * - Node / Bun / Deno / Vercel — console.log is sync, captured.\n * - Edge runtimes (CF Workers, Vercel Edge) — console.log is captured\n * but may be rate-limited by the platform. For high-volume edge audit,\n * implement a custom sink writing to a queue / HTTP endpoint.\n */\n\nexport interface AuditEvent {\n /** Domain-qualified verb. Convention: `<domain>.<verb>` (e.g. csrf.warn, session.rotated). */\n action: string\n /** Who triggered the event. Anonymous = no auth at time of event. */\n actor?: { type: 'user' | 'system' | 'anonymous'; id?: string }\n /** What was operated on (optional). */\n resource?: { type: string; id?: string }\n /** Arbitrary event-specific metadata. JSON-serializable. */\n metadata?: Record<string, unknown>\n /** ISO 8601 timestamp. If absent, sink fills in `new Date().toISOString()`. */\n timestamp?: string\n /** Optional trace id (populated by middleware from `x-trace-id`). */\n traceId?: string\n}\n\nexport interface AuditLogger {\n log(event: AuditEvent): void | Promise<void>\n}\n\n/**\n * Default sink: one JSON line per event to stdout. Sync. Never throws.\n *\n * EC: circular refs / BigInt values fall back to a placeholder line so\n * the event is still observable (action + traceId) without crashing the\n * request lifecycle.\n */\nexport class JsonStdoutSink implements AuditLogger {\n log(event: AuditEvent): void {\n const enriched = {\n level: 'audit' as const,\n ...event,\n timestamp: event.timestamp ?? new Date().toISOString(),\n }\n try {\n // eslint-disable-next-line no-console -- JsonStdoutSink IS the audit output\n console.log(JSON.stringify(enriched, jsonReplacer))\n } catch {\n // eslint-disable-next-line no-console -- fallback when payload won't serialize\n console.log(\n `{\"level\":\"audit\",\"action\":${JSON.stringify(event.action)},\"timestamp\":${JSON.stringify(enriched.timestamp)},\"note\":\"payload could not be serialized\"}`,\n )\n }\n }\n}\n\n/**\n * Replacer that walks BigInt → string. Circular ref handling is via the\n * outer try/catch (JSON.stringify throws TypeError on cycles; we drop to\n * the fallback line). We don't implement custom cycle-breaking walker\n * because the audit payload is meant to be JSON — if user metadata has\n * a cycle, the right answer is to fix the caller, not silently lose\n * the structure.\n */\nfunction jsonReplacer(_key: string, value: unknown): unknown {\n if (typeof value === 'bigint') return value.toString()\n return value\n}\n\n/**\n * No-op logger. Returned when `config.audit` is unset. Zero overhead;\n * framework wiring sites null-check before calling.\n */\nexport function createNoOpLogger(): AuditLogger {\n return {\n log() {\n // intentionally empty\n },\n }\n}\n\n/**\n * T4.2 — Safe-emit wrapper. Used by framework wiring sites (csrf.ts,\n * rate-limit.ts, session.ts) so a logger throw NEVER propagates into\n * the request handler.\n */\nexport function safeAudit(logger: AuditLogger | undefined, event: AuditEvent): void {\n if (!logger) return\n try {\n const r = logger.log(event)\n // Discard the Promise — async sinks are fire-and-forget by design.\n if (r && typeof r.then === 'function') {\n r.catch(() => {\n // swallow async sink failures — audit must never crash the request\n })\n }\n } catch {\n // swallow sync sink failures — audit must never crash the request\n }\n}\n","import type { IncomingMessage } from 'node:http'\n\nimport type { AuditLogger } from '../observability/audit-log.js'\nimport { safeAudit } from '../observability/audit-log.js'\n\n/**\n * CSRF enforcement mode.\n *\n * - `off` — skip CSRF entirely. Use only when you have another defense\n * (e.g. you don't ship session cookies, all auth is bearer).\n * - `warn` — log a structured warning when the check would fail, but\n * still serve the request. Default for 0.2.0. Migration mode.\n * - `strict` — reject failing requests with 403 + code `CSRF_INVALID`.\n * Will become the default in 0.3.0.\n */\nexport type CsrfMode = 'off' | 'warn' | 'strict'\n\n/**\n * Per-request structured logger surface. Only `warn` is used by enforceCsrf;\n * we don't require a full Logger here so callers can pass a mock or the\n * console directly.\n */\nexport interface CsrfLogger {\n warn: (payload: CsrfWarnPayload) => void\n /** Optional path the request was destined for — used for log correlation. */\n path?: string\n}\n\n/**\n * T5.1 — Rails-inspired per-route escalation.\n *\n * `routes` accepts string (exact match) or RegExp entries. When a request\n * path matches AND the request would otherwise emit a warning, the\n * `behavior` field decides what happens:\n *\n * - `'warn'` → normal warn dispatch (no-op vs default)\n * - `'raise'` → escalate to 403 regardless of global `csrf` mode\n *\n * `'raise'` never downgrades: when global mode is `'off'`, validation is\n * skipped entirely and disallowed dispatch never runs.\n */\nexport interface DisallowedConfig {\n routes: (string | RegExp)[]\n behavior: 'warn' | 'raise'\n}\n\n/**\n * Test whether `path` matches any of the supplied patterns. String\n * patterns are EXACT (trailing slash matters — use RegExp for tolerance).\n *\n * EC-5: when a RegExp carries the `/g` flag, `.test()` mutates\n * `lastIndex` and the next invocation may miss. We reset `lastIndex`\n * before each test so the matcher is a pure function.\n */\nexport function matchDisallowed(path: string, patterns: readonly (string | RegExp)[]): boolean {\n for (const p of patterns) {\n if (typeof p === 'string') {\n if (path === p) return true\n } else if (p instanceof RegExp) {\n p.lastIndex = 0\n if (p.test(path)) return true\n }\n // Neither string nor RegExp: ignore silently (defensive — the public\n // type forbids it but runtime data may slip past).\n }\n return false\n}\n\n/**\n * T2.2 — Stable cutover identifier shipped with every csrf.warn payload.\n *\n * Convention borrowed from Vite's `deprecations.ts:74` — a `code` plus a\n * `docsUrl` lets users (a) grep their logs for a single stable identifier\n * to find every csrf.warn line, and (b) click through directly to the\n * migration guide. Strings are exported constants so the analyzer (T2.3)\n * and migration guide can reference the same source of truth.\n */\nexport const CSRF_WARN_CODE = 'CSRF_STRICT_CUTOVER' as const\nexport const CSRF_WARN_DOCS_URL = 'https://theokit.dev/upgrade/csrf-strict-cutover' as const\n\n/**\n * Pick a header value, choosing the first entry when an array (Node sets\n * arrays for headers that legitimately appear multiple times). Returns\n * `''` when the header is absent or empty — callers treat `''` as \"skip\".\n */\nfunction pickHeader(value: string | string[] | undefined): string {\n if (typeof value === 'string') return value\n if (Array.isArray(value) && value.length > 0) return value[0]\n return ''\n}\n\nexport interface CsrfWarnPayload {\n event: 'csrf.warn'\n method: string\n path: string | undefined\n reason: string\n /**\n * Stable identifier for the 0.2 → 0.3 CSRF strict cutover. Always\n * `'CSRF_STRICT_CUTOVER'`. Grep-able from prod logs.\n */\n code: string\n /**\n * Link to the section of the migration guide explaining how to clear\n * this specific warning class.\n */\n docsUrl: string\n}\n\n/**\n * T5a.2 Phase B (slice 1/6): pure header-only CSRF check extracted from\n * `validateCsrf(req: IncomingMessage)` so it can be re-used by the Web-\n * Standards `validateCsrfRequest(request: Request)` sibling. Per the T5a.2\n * plan v1.0 § Phase B, header-only leaves are first to migrate. This is\n * the dual-signature pattern (anti-pattern #2 avoidance): IncomingMessage\n * consumers unchanged; new Request consumers go through the same logic\n * via the shared helper.\n *\n * Pure logic — accepts pre-extracted header values as strings or null.\n */\nfunction isCsrfValidFromHeaders(opts: {\n csrfActionHeader: string | null\n origin: string | null\n host: string | null\n}): { valid: true } | { valid: false; reason: string } {\n // 1. Custom header must be present (primary defense — simple form posts\n // cannot set custom headers, browsers gate via CORS preflight)\n if (opts.csrfActionHeader !== '1') {\n return { valid: false, reason: 'Missing X-Theo-Action header' }\n }\n\n // 2. Origin matching (secondary defense)\n if (opts.origin === null || opts.origin === '') {\n // Browsers omit Origin for same-origin requests — treat as valid\n return { valid: true }\n }\n\n if (opts.host === null || opts.host === '') {\n return { valid: true }\n }\n\n try {\n const originHost = new URL(opts.origin).host\n if (originHost !== opts.host) {\n return { valid: false, reason: `Origin ${opts.origin} does not match host ${opts.host}` }\n }\n } catch {\n return { valid: false, reason: `Invalid origin: ${opts.origin}` }\n }\n\n return { valid: true }\n}\n\nexport function validateCsrf(\n req: IncomingMessage,\n): { valid: true } | { valid: false; reason: string } {\n // IncomingMessage adapter — normalize Node header shape to the pure\n // helper's input shape (string|null).\n const action = req.headers['x-theo-action']\n const origin = req.headers.origin\n const host = req.headers.host\n\n // RFC 6454: Origin is single-valued. A caller that synthesizes an\n // IncomingMessage — an adapter, a shim, a proxy library — can hand us an\n // array, and choosing one of two conflicting origins is a decision the\n // request never authorized. The disagreement IS the rejection.\n //\n // `node:http` itself joins a repeated Origin with `, ` rather than\n // producing an array, and that string already fails to parse as a URL\n // below. This branch covers the shape the type allows and `pickHeader`\n // used to resolve silently.\n if (Array.isArray(origin)) {\n return { valid: false, reason: 'Multiple Origin headers (RFC 6454 violation)' }\n }\n\n return isCsrfValidFromHeaders({\n csrfActionHeader: typeof action === 'string' ? action : null,\n origin: origin !== undefined ? origin || null : null,\n host: host !== undefined ? pickHeader(host) || null : null,\n })\n}\n\n/**\n * T5a.2 Phase B (slice 1/6) — Web-Standards-shaped CSRF validator.\n *\n * Mirror of `validateCsrf(req: IncomingMessage)` for the Web `Request`\n * shape. Consumes `request.headers.get(name)` (native Web `Headers` API)\n * instead of `req.headers[name]` (Node `IncomingMessage` indexer). Same\n * CSRF policy + same return shape — the difference is only the input\n * extraction.\n *\n * Used by `executeWebRequest` (T5a.2 Phase A) to enforce CSRF on the\n * Web-Standards request handler entry-point.\n */\nexport function validateCsrfRequest(\n request: Request,\n): { valid: true } | { valid: false; reason: string } {\n return isCsrfValidFromHeaders({\n csrfActionHeader: request.headers.get('x-theo-action'),\n origin: request.headers.get('origin'),\n host: request.headers.get('host'),\n })\n}\n\n/**\n * Enforce CSRF policy with mode-aware behavior. Wrapper over `validateCsrf`\n * that turns the boolean valid/invalid into a request-level allow decision,\n * gated by mode + structured warning in warn mode.\n *\n * Phase 5 — CSRF warn-first (EC-1).\n */\n/**\n * Dispatch the csrf.warn payload to both the structured logger and the\n * audit sink (when configured). Extracted from `enforceCsrf` to keep that\n * function's complexity within ceiling.\n */\nfunction dispatchCsrfWarn(\n req: IncomingMessage,\n reason: string,\n logger: CsrfLogger | undefined,\n auditLogger: AuditLogger | undefined,\n pathFallback = '',\n): void {\n const payload: CsrfWarnPayload = {\n event: 'csrf.warn',\n method: req.method ?? 'UNKNOWN',\n path: logger?.path ?? pathFallback,\n reason,\n code: CSRF_WARN_CODE,\n docsUrl: CSRF_WARN_DOCS_URL,\n }\n logger?.warn(payload)\n // `metadata` is typed as Record<string, unknown>; CsrfWarnPayload is a\n // structurally-equivalent shape but lacks the index signature.\n safeAudit(auditLogger, {\n action: 'csrf.warn',\n actor: { type: 'anonymous' },\n metadata: { ...payload },\n })\n}\n\nexport function enforceCsrf(\n req: IncomingMessage,\n mode: CsrfMode,\n logger?: CsrfLogger,\n disallowed?: DisallowedConfig,\n auditLogger?: AuditLogger,\n): { allow: boolean; reason?: string } {\n if (mode === 'off') {\n // `off` short-circuits before disallowed dispatch — users who set\n // csrf: 'off' globally have explicitly turned validation off, and\n // disallowed must never re-introduce it. The escape hatch is to\n // set csrf: 'warn' and use disallowed for surgical strict pockets.\n return { allow: true }\n }\n\n const check = validateCsrf(req)\n if (check.valid) {\n return { allow: true }\n }\n\n // T5.1 — disallowed dispatch: when the failing request matches a\n // disallowed pattern AND behavior is 'raise', escalate to 403 even if\n // global mode is 'warn'. Strict mode would 403 anyway, so the branch\n // is a no-op there.\n if (disallowed?.behavior === 'raise') {\n const path = logger?.path ?? req.url ?? ''\n if (matchDisallowed(path, disallowed.routes)) {\n return { allow: false, reason: check.reason }\n }\n }\n\n if (mode === 'warn') {\n // T2.1: emit via warnOnce by default — callers can override via the\n // injected logger.warn (tests, custom log routers).\n // T2.2: include the stable cutover code + docsUrl so logs are\n // grep-able and click-through-able.\n dispatchCsrfWarn(req, check.reason, logger, auditLogger)\n return { allow: true, reason: check.reason }\n }\n\n // strict — 403 the request, AND emit a warn payload so the dev (and\n // devtools UI) sees WHY it was blocked + the docsUrl to fix it.\n // Without this, strict-mode users get a silent 403 with no context.\n dispatchCsrfWarn(req, check.reason, logger, auditLogger)\n return { allow: false, reason: check.reason }\n}\n"],"mappings":"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","names":["dispatchCsrfWarn"]}
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
serveMatchedAuxRoute,
|
|
13
13
|
serveThroughPluginLifecycle,
|
|
14
14
|
setupSsrDevMiddleware
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-6EV6FC7X.js";
|
|
16
16
|
import {
|
|
17
17
|
resolveTheoRootDir
|
|
18
18
|
} from "./chunk-FDOOBTXJ.js";
|
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
mountAgent,
|
|
39
39
|
readAgentPolicy,
|
|
40
40
|
writeWebResponseToServerResponse
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-2NARRZPP.js";
|
|
42
42
|
import {
|
|
43
43
|
getApprovalRegistry,
|
|
44
44
|
resolveProvider
|
|
@@ -48,7 +48,7 @@ import {
|
|
|
48
48
|
dispatchControllerRequest,
|
|
49
49
|
incomingMessageToHandlerRequest,
|
|
50
50
|
sendError
|
|
51
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-GDZOWQV7.js";
|
|
52
52
|
import {
|
|
53
53
|
TRACE_HEADER,
|
|
54
54
|
createObservabilityPluginFromConfig,
|
|
@@ -2179,19 +2179,19 @@ async function theoPluginAsync(rootOrOptions) {
|
|
|
2179
2179
|
})
|
|
2180
2180
|
);
|
|
2181
2181
|
}
|
|
2182
|
-
const { appTypedClientPlugin } = await import("./app-typed-client-
|
|
2182
|
+
const { appTypedClientPlugin } = await import("./app-typed-client-NOXQEEVF.js");
|
|
2183
2183
|
const appClientPlugin = appTypedClientPlugin({
|
|
2184
2184
|
cwd: projectRoot,
|
|
2185
2185
|
serverDir: serverDirAbs,
|
|
2186
2186
|
distDir: resolve5(projectRoot, ".theokit")
|
|
2187
2187
|
});
|
|
2188
|
-
const { actionsVirtualModule } = await import("./actions-virtual-module-
|
|
2188
|
+
const { actionsVirtualModule } = await import("./actions-virtual-module-BKIT7HNS.js");
|
|
2189
2189
|
const actionsPlugin = actionsVirtualModule({
|
|
2190
2190
|
serverDir: serverDirAbs,
|
|
2191
2191
|
distDir: resolve5(projectRoot, ".theokit")
|
|
2192
2192
|
});
|
|
2193
2193
|
const { agentsTypedClientPlugin } = await import("./agents-typed-client-D4OA2TXB.js");
|
|
2194
|
-
const { generateManifest } = await import("./internal-api-
|
|
2194
|
+
const { generateManifest } = await import("./internal-api-TZTO4VMP.js");
|
|
2195
2195
|
const agentsClientPlugin = agentsTypedClientPlugin({
|
|
2196
2196
|
projectRoot,
|
|
2197
2197
|
agentsDir: agentsDirName,
|
|
@@ -2208,7 +2208,7 @@ async function theoPluginAsync(rootOrOptions) {
|
|
|
2208
2208
|
const controllerTransformPlugin = controllerSwcTransformPlugin({
|
|
2209
2209
|
serverDir: serverDirAbs
|
|
2210
2210
|
});
|
|
2211
|
-
const { serverOnlyImportBoundary } = await import("./server-boundary-
|
|
2211
|
+
const { serverOnlyImportBoundary } = await import("./server-boundary-Z5LSU7ZW.js");
|
|
2212
2212
|
const serverBoundaryPlugin = serverOnlyImportBoundary({
|
|
2213
2213
|
projectRoot,
|
|
2214
2214
|
serverDir: serverDirAbs
|
|
@@ -2383,4 +2383,4 @@ export {
|
|
|
2383
2383
|
theoPluginAsync,
|
|
2384
2384
|
theoPlugin
|
|
2385
2385
|
};
|
|
2386
|
-
//# sourceMappingURL=chunk-
|
|
2386
|
+
//# sourceMappingURL=chunk-JHUFPH7B.js.map
|
|
@@ -82,6 +82,9 @@ function deployedCsrfFragment(opts, home = "a deployed function") {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
// src/adapters/deployed-runtime-config.ts
|
|
85
|
+
function serverDirLiteral(opts) {
|
|
86
|
+
return JSON.stringify(opts.serverDir ?? "server");
|
|
87
|
+
}
|
|
85
88
|
var EMPTY = {
|
|
86
89
|
imports: [],
|
|
87
90
|
declarations: [],
|
|
@@ -180,9 +183,10 @@ function describeDeployedSecurityHeaders(limits) {
|
|
|
180
183
|
export {
|
|
181
184
|
deployedCorsFragment,
|
|
182
185
|
deployedCsrfFragment,
|
|
186
|
+
serverDirLiteral,
|
|
183
187
|
deployedRuntimeConfigFragment,
|
|
184
188
|
deployedTraceFragment,
|
|
185
189
|
renderSecurityHeadersConfigLiteral,
|
|
186
190
|
describeDeployedSecurityHeaders
|
|
187
191
|
};
|
|
188
|
-
//# sourceMappingURL=chunk-
|
|
192
|
+
//# sourceMappingURL=chunk-PALZUV6E.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/adapters/deployed-cors.ts","../src/adapters/deployed-csrf.ts","../src/adapters/deployed-runtime-config.ts","../src/adapters/deployed-trace.ts","../src/adapters/security-headers.ts"],"sourcesContent":["/**\n * The CORS configuration a deployed entry carries, baked at build time.\n *\n * ## The defect this closes\n *\n * `security.cors` reached exactly one consumer: Vite's `configureServer` hook. So an app that\n * worked cross-origin under `theokit dev` stopped working the moment anything else served it —\n * `theokit start` (fixed separately) and all six Web deploy targets (usetheokit/theokit#409). Same\n * config, same code, no error and no warning; the failure surfaces in a browser as a blocked fetch\n * on the deployed URL, three layers from the key that had quietly stopped being read.\n *\n * The pure half was written twice and called once: `createCorsWebHandler` — the Web mirror — had no\n * caller anywhere in the repository. Nothing here reimplements it.\n *\n * ## A callback origin is REFUSED, not silently dropped\n *\n * `corsSchema.origins` accepts `z.function(...)` alongside the string / RegExp / array shapes. A\n * deployed function has no `theo.config.ts` to read, and there is no literal for a closure — so a\n * build that baked only the serialisable shapes would produce an app whose CORS silently allowed\n * nothing, which is the exact class of failure this issue reports.\n *\n * `rules/three-target-parity.md` § 3 is explicit about the alternative: \"a target that cannot serve\n * a capability refuses by name. Silent degradation is the failure mode this rule exists to\n * prevent.\" So the build throws, naming the target, the key and the two ways forward.\n */\nimport type { TheoConfig } from '../config/schema.js'\n\ntype CorsConfig = NonNullable<NonNullable<TheoConfig['security']>['cors']>\n\n/**\n * The CORS slice of an adapter's build options.\n *\n * Narrow and named once, matching how `securityHeaders` and `DeployedCsrfOptions` already reach the\n * emitters: each renderer receives what it uses, and six signatures name one type instead of six\n * inline shapes that can drift.\n */\nexport interface DeployedCorsOptions {\n cors?: CorsConfig\n}\n\n/**\n * Thrown at BUILD time when the declared CORS cannot be carried to a deployed target.\n *\n * A build error is the point: the alternative is a deploy that looks configured and refuses every\n * cross-origin request, discovered by a browser rather than by the build.\n */\nexport class UnserializableCorsOriginError extends Error {\n constructor(target: string) {\n super(\n `security.cors.origins is a function, and the \\`${target}\\` target cannot carry it: a deployed ` +\n `function has no theo.config.ts to read, and a callback cannot be written into the emitted ` +\n `entry. Replace it with the origin, a RegExp, or an array of either — all of which travel — ` +\n `or build for \\`node\\` and run \\`theokit start\\`, which evaluates the callback at runtime.`,\n )\n this.name = 'UnserializableCorsOriginError'\n }\n}\n\n/** Source text for one origin matcher: a RegExp as a literal, anything else as JSON. */\nfunction renderOrigin(origin: unknown, target: string): string {\n if (typeof origin === 'function') throw new UnserializableCorsOriginError(target)\n if (origin instanceof RegExp) return String(origin)\n if (Array.isArray(origin)) return `[${origin.map((o) => renderOrigin(o, target)).join(', ')}]`\n return JSON.stringify(origin)\n}\n\n/**\n * Source text for the CORS config, or `undefined` when the app declared none.\n *\n * RegExp entries are emitted as regex literals for the reason `deployed-csrf.ts` gives at length:\n * `JSON.stringify` renders a RegExp as `{}`, and `matchesOrigin` checks `instanceof RegExp`, so a\n * JSON-rendered origin would sit in the emitted file looking configured and matching nothing.\n *\n * @throws UnserializableCorsOriginError when `origins` is a callback\n */\nexport function renderDeployedCorsLiteral(cors: CorsConfig | undefined, target: string): string {\n if (cors === undefined) return 'undefined'\n\n const parts = [`origins: ${renderOrigin(cors.origins, target)}`]\n if (cors.methods !== undefined) parts.push(`methods: ${JSON.stringify(cors.methods)}`)\n if (cors.allowedHeaders !== undefined)\n parts.push(`allowedHeaders: ${JSON.stringify(cors.allowedHeaders)}`)\n if (cors.exposedHeaders !== undefined)\n parts.push(`exposedHeaders: ${JSON.stringify(cors.exposedHeaders)}`)\n // Both carry schema defaults, so they are always present and always emitted — unlike the\n // optional fields above, whose absence is a real answer the handler already has one for.\n parts.push(\n `credentials: ${JSON.stringify(cors.credentials)}`,\n `maxAge: ${JSON.stringify(cors.maxAge)}`,\n )\n\n return `{ ${parts.join(', ')} }`\n}\n\n/**\n * The lines that declare the CORS handler in a generated entry.\n *\n * `null` when nothing was declared, which is what \"no cors block\" meant before and still means: no\n * headers, not permissive ones.\n */\nexport function deployedCorsFragment(cors: CorsConfig | undefined, target: string): string[] {\n return [\n `// #409 — the CORS the app declared, carried as a literal because a deployed function has no`,\n `// theo.config.ts to read. \\`null\\` when the app declared none: no headers, not permissive ones.`,\n `const CORS_CONFIG = ${renderDeployedCorsLiteral(cors, target)}`,\n `const CORS_HANDLER = CORS_CONFIG === undefined ? null : createCorsWebHandler(CORS_CONFIG)`,\n ``,\n `/** Answer a preflight before routing — an OPTIONS the router handles never gets a CORS answer. */`,\n `function corsPreflight(request) {`,\n ` return CORS_HANDLER === null ? null : CORS_HANDLER.handlePreflightRequest(request)`,\n `}`,\n ``,\n `/** Put the headers on whatever the app answered, including its 404s — a browser reads a 404`,\n ` * without them as a CORS failure rather than as the 404 it is. */`,\n `function withCors(request, response) {`,\n ` if (CORS_HANDLER !== null) CORS_HANDLER.applyCorsHeaders(request, response.headers)`,\n ` return response`,\n `}`,\n ]\n}\n","/**\n * The CSRF configuration a deployed entry carries, baked at build time.\n *\n * ## The defect this closes\n *\n * The six Web-standards adapter entries built `executeRoute`'s context from an eight-field\n * literal, and neither `csrfMode` nor `disallowed` was among the eight (usetheokit/theokit#410).\n * `executeRoute` defaults an absent mode to `'strict'`, so an app declaring\n * `security: { csrf: 'off' }` — or `'warn'` — got `'strict'` on every deploy target: a `POST` that\n * works under `theokit dev` and `theokit start` answers `403 CSRF_INVALID` on Vercel, naming a\n * mechanism the operator had switched off. The config still validated and the build still\n * succeeded; the behaviour simply changed.\n *\n * The deployed function has no `theo.config.ts` to read, which is why the value is carried as a\n * literal — the same shape `security.headers` already uses (`renderSecurityHeadersConfigLiteral`).\n *\n * ## Why this is not `JSON.stringify`\n *\n * `disallowed.routes` accepts RegExp entries (`config/schemas/security.ts`), and `JSON.stringify`\n * renders a RegExp as `{}`. That is not a formatting problem: `matchDisallowed` checks\n * `p instanceof RegExp`, so a `{}` matches nothing while reading, in the emitted file, as a rule\n * that is present and configured. Reaching for JSON here would reproduce this issue's own defect —\n * configuration that survives validation and quietly stops applying — one layer further down.\n */\nimport type { TheoConfig } from '../config/schema.js'\n\ntype SecurityConfig = NonNullable<TheoConfig['security']>\n\n/**\n * The two slices of `security` that reach `executeRoute`'s context.\n *\n * Narrow rather than the whole block, matching how `securityHeaders` is already passed: each\n * renderer receives what it uses and nothing else, so a headers change cannot reach the CSRF\n * literal and vice versa.\n */\nexport interface DeployedCsrfOptions {\n csrf?: SecurityConfig['csrf']\n disallowed?: SecurityConfig['disallowed']\n}\n\n/**\n * Source text for one route pattern.\n *\n * A RegExp is emitted as a regex literal so it arrives as a RegExp; a string goes through\n * `JSON.stringify`, which is the correct escaper for a JS string literal (quotes, backslashes,\n * control characters, line separators).\n */\nfunction renderRoutePattern(pattern: string | RegExp): string {\n return pattern instanceof RegExp ? String(pattern) : JSON.stringify(pattern)\n}\n\n/**\n * Source text for the CSRF slice of `executeRoute`'s context.\n *\n * Absent values are OMITTED rather than defaulted. `executeRoute` already defaults an absent\n * `csrfMode` to `'strict'`, and writing `'strict'` here would put that default in a second place\n * where the two can disagree — which is the class of drift the whole issue is about.\n *\n * @param security - the declared csrf slices, or `undefined` when the app declared no security block\n */\nexport function renderDeployedCsrfLiteral(security: DeployedCsrfOptions | undefined): string {\n if (security === undefined) return '{}'\n\n const parts: string[] = []\n if (security.csrf !== undefined) parts.push(`csrfMode: ${JSON.stringify(security.csrf)}`)\n\n const { disallowed } = security\n if (disallowed !== undefined) {\n const routes = disallowed.routes.map(renderRoutePattern).join(', ')\n parts.push(\n `disallowed: { routes: [${routes}], behavior: ${JSON.stringify(disallowed.behavior)} }`,\n )\n }\n\n // `{}` and not `{ }` when nothing was declared: the emitted file is read by people, and the\n // two-space version reads as though something was meant to be there.\n return parts.length === 0 ? '{}' : `{ ${parts.join(', ')} }`\n}\n\n/**\n * The lines that declare `CSRF_CONFIG` in a generated entry.\n *\n * One function rather than the same six lines pasted into each of the six adapters: that\n * duplication is how the eight-field context literal came to be wrong in six places at once, and\n * repeating the fix in the same shape would leave the next field with the same six places to be\n * forgotten in. It also keeps the two largest emitters under the `max-lines-per-function` ceiling,\n * which `vercel.ts` already extracts fragments to respect.\n *\n * @param opts - the declared csrf slices, passed straight through from the adapter's build options\n * @param home - what the target has instead of a config file, for the comment's second sentence\n */\nexport function deployedCsrfFragment(\n opts: DeployedCsrfOptions,\n home = 'a deployed function',\n): string[] {\n return [\n `// #410 — the CSRF mode and per-route escalation the app declared. Carried as a`,\n `// literal for the same reason as the headers above: ${home} has no theo.config.ts`,\n `// to read. Absent keys stay absent so executeRoute's own default ('strict') applies,`,\n `// rather than this file becoming a second place it can drift.`,\n `const CSRF_CONFIG = ${renderDeployedCsrfLiteral(opts)}`,\n ]\n}\n","/**\n * The configuration a deployed entry could not apply (usetheokit/theokit#425).\n *\n * ## Why this is not another literal renderer\n *\n * `deployed-csrf.ts` and `deployed-cors.ts` bake their values into the emitted source, which works\n * because `csrf` is an enum and `disallowed` is a `{ routes, behavior }` object — plain data, and a\n * deployed function has no `theo.config.ts` to read.\n *\n * The two concerns left over from #410 turn out to be different from each other, and the difference\n * is the whole design:\n *\n * - **`serialization` is plain data too.** The config field is `z.enum(['json', 'superjson'])`\n * (`config/schema.ts:147`) — a selector, not a transformer. `resolveTransformer` turns it into the\n * functions, and it already ships from `theokit/server`. So this half is a literal like the rest,\n * and the deployed entry resolves it exactly the way `theokit start` does\n * (`cli/commands/start/index.ts:108`), from the same string, through the same function.\n * - **`plugins` genuinely carries functions.** A plugin is constructed in `theo.config.ts` and there\n * is no literal for a closure, so this half needs the entry to import a module instead.\n *\n * ## Static import, not `import()` in the request path\n *\n * The tempting shortcut is `await import('../../theo.config.js')` inside the handler. It trades a\n * silent failure for a louder one on targets with no filesystem, and it moves configuration\n * resolution into every request on the targets that do have one.\n *\n * What this emits instead is a TOP-LEVEL import of a module the build already resolved and wrote\n * beside the entry — the same shape `renderBakedRoutes` uses for route modules (#369): decide on\n * the build machine, emit a static specifier. It is evaluated once at module load, the target's\n * bundler can see through it, and a plugin that needs an API the target lacks fails the build\n * rather than the first request.\n *\n * ## Why each half is optional\n *\n * An app that declares neither concern must produce the entry it produced before this existed.\n * Importing a module the build did not emit fails at load, and spreading an empty object costs an\n * allocation per request for nothing. So an empty request renders to nothing at all, and the\n * caller's `executeRoute` literal is unchanged.\n *\n * The halves are independent on purpose: an app that only picks `superjson` must not be made to\n * carry a plugins module, and an app with plugins and default JSON must not gain a transformer\n * lookup. Coupling them would have made the common case pay for the rare one.\n */\n\n/**\n * The option every Web-standards adapter grows to carry non-serialisable configuration.\n *\n * Composed into each adapter's option type the way `DeployedCsrfOptions` already is, so the six\n * targets cannot drift into six spellings of the same field.\n */\n/**\n * The project's `serverDir`, carried into every generated entrypoint (#RFC server-layout).\n *\n * Separate from the other option groups because it is not a runtime feature toggle: it is the\n * project's own layout, and an adapter that hardcodes `'server'` agrees with the default by\n * COINCIDENCE. The moment a project sets the option — the entire point of it existing — the\n * generated entrypoint resolves a directory that is not there, and only after deploy: the build\n * succeeds, the bundle is written, and routes 404 in production with nothing naming the cause.\n */\nexport interface DeployedServerDirOptions {\n /** Project-relative server directory. Absent ⇒ the schema default, `server`. */\n serverDir?: string\n}\n\n/**\n * The server directory as a quoted TypeScript literal, ready to interpolate into generated source.\n *\n * `JSON.stringify` rather than wrapping in quotes by hand: the value reaches this from user config,\n * so a directory containing a quote or a backslash would otherwise emit a syntax error into\n * somebody else's build — a worse failure than the one this fixes.\n */\nexport function serverDirLiteral(opts: DeployedServerDirOptions): string {\n return JSON.stringify(opts.serverDir ?? 'server')\n}\n\nexport interface DeployedRuntimeConfigOptions {\n /**\n * Specifier of the plugins module the build wrote beside the entry, or `undefined` when the app\n * declares no plugins and the build wrote none.\n */\n runtimeConfigModule?: string\n /**\n * The app's `serialization` selector, carried as a literal.\n *\n * `'json'` and `undefined` both mean the default, and neither emits anything: `executeRoute`\n * already falls back to `JSON.stringify`, and the `x-theo-transformer` header is deliberately\n * absent for the default so a client is told only when there is something to be told.\n */\n serialization?: 'json' | 'superjson'\n}\n\n/** The three places an entry has to grow to carry non-serialisable configuration. */\nexport interface DeployedRuntimeConfigFragment {\n /** Top-level imports. Empty when the build emitted no config module. */\n readonly imports: string[]\n /** Module-scope declarations — evaluated once, at load. Empty when there is nothing to carry. */\n readonly declarations: string[]\n /**\n * Spread into the entry's `executeRoute({ … })` literal, inside an async function.\n *\n * Empty string when there is nothing to carry, so the call site keeps the exact shape it had.\n */\n readonly executeRouteSpread: string\n}\n\nconst EMPTY: DeployedRuntimeConfigFragment = {\n imports: [],\n declarations: [],\n executeRouteSpread: '',\n}\n\n/**\n * What a deployed entry needs in order to apply `config.plugins` and `config.serialization`.\n *\n * @param moduleSpecifier - specifier of the runtime-config module the build emitted beside the\n * entry, or `undefined` when the app declared neither concern and the build emitted none.\n */\nexport function deployedRuntimeConfigFragment(\n options: DeployedRuntimeConfigOptions | undefined,\n): DeployedRuntimeConfigFragment {\n const pluginsModule = options?.runtimeConfigModule\n // 'json' is the default and emits nothing — see `serialization` above.\n const serialization = options?.serialization === 'superjson' ? 'superjson' : undefined\n if (pluginsModule === undefined && serialization === undefined) return EMPTY\n\n const imports: string[] = []\n const declarations: string[] = []\n const spread: string[] = []\n\n if (pluginsModule !== undefined) {\n imports.push(\n `import { createPluginRunnerFromConfig } from 'theokit/server'`,\n `// #425 — the app's own plugins, resolved on the build machine and written beside this entry.`,\n `// A closure has no literal, so this is an import rather than a baked value.`,\n `import theoRuntimeConfig from '${pluginsModule}'`,\n )\n declarations.push(\n `// Built ONCE, at module load. A runner rebuilt per request would re-run every plugin's`,\n `// \\`register\\`, which is where a plugin allocates the state its hooks then read.`,\n `const THEO_PLUGIN_RUNNER = createPluginRunnerFromConfig(theoRuntimeConfig.plugins)`,\n )\n // Awaited, not passed along: `createPluginRunnerFromConfig` is async because `register` is, and\n // a pending promise handed to `executeRoute` is a truthy object with none of the runner's\n // methods — every hook would silently not fire, which is this issue's own defect one layer in.\n spread.push(`pluginRunner: await THEO_PLUGIN_RUNNER`)\n }\n\n if (serialization !== undefined) {\n imports.push(`import { resolveTransformer } from 'theokit/server'`)\n declarations.push(\n `// #425 — a literal, because \\`config.serialization\\` is a SELECTOR and not a transformer.`,\n `// Same string, same function \\`theokit start\\` calls, so the deployed response and the local`,\n `// one cannot disagree about what the app asked for — including the \\`x-theo-transformer\\``,\n `// header, whose absence is what made this a data bug rather than a formatting one.`,\n `const THEO_TRANSFORMER = resolveTransformer('${serialization}')`,\n )\n spread.push(`transformer: THEO_TRANSFORMER`)\n }\n\n return { imports, declarations, executeRouteSpread: `${spread.join(', ')},` }\n}\n","/**\n * The request id a deployed entry uses, and the header it echoes back.\n *\n * ## The defect this closes\n *\n * Every generated entry minted a fresh `randomUUID()` per request and set no correlation header\n * at all on a success path (usetheokit/theokit#410). Both Node paths do the opposite: they resolve\n * an incoming `traceparent` / `x-request-id` through `extractTraceId` and echo the result under\n * both `x-request-id` and `x-trace-id` (`cli/commands/start/request-handler.ts`,\n * `vite-plugin/api-middleware.ts`).\n *\n * The consequence is that a trace crossing into a deployed function starts over. The caller's id\n * is discarded, and the response carries nothing to correlate against — so a request that fails in\n * production cannot be tied to the client that made it, which is the one situation the id exists\n * for.\n *\n * ## Why `setHeader` before the handler, rather than wrapping the response\n *\n * It is what the Node path does, and the shim reproduces Node's semantics exactly: `writeHead`\n * MERGES into the header map rather than replacing it (`web-shim.ts`), so a header set here\n * survives the handler's own `writeHead` and a handler that sets its own id still wins. Wrapping\n * the finished `Response` instead would have to mutate a response whose body is already streaming\n * (#382), and would miss the branches that return before the shim is built.\n */\n\n/**\n * Lines that resolve the request id and echo it, as generated source.\n *\n * @param requestVar - the name the entry gave the Web `Request` in scope\n * @param indent - leading whitespace, so the emitted file stays readable\n */\nexport function deployedTraceFragment(requestVar: string, indent: string): string[] {\n return [\n `${indent}// #410 — honour the caller's trace id instead of minting a new one, and echo it.`,\n `${indent}// \\`extractTraceIdFromRequest\\` validates the caller-controlled \\`x-request-id\\``,\n `${indent}// before trusting it, and falls back to a fresh UUID when neither header is present.`,\n `${indent}const requestId = extractTraceIdFromRequest(${requestVar})`,\n `${indent}res.setHeader('x-request-id', requestId)`,\n `${indent}res.setHeader(TRACE_HEADER, requestId)`,\n ]\n}\n","/**\n * The security headers a deployed target puts on its responses.\n *\n * `theokit start` applies the configured baseline to every response it writes\n * (`cli/commands/start/request-handler.ts`). None of the six Web-standards\n * deploy adapters applied any, so the same page carried a CSP,\n * `X-Frame-Options`, HSTS and `nosniff` under `theokit start` and none of them\n * once deployed (usetheokit/theokit#410, GHSA-87qq-fgcr-384x).\n *\n * This module is the seam that closes that half of the gap. It has two halves\n * and they live together on purpose: the code that writes the literal into a\n * generated entry and the code that reads it at request time have to agree on\n * one shape, and a shape stated in two files drifts.\n *\n * - **Build time** — {@link renderSecurityHeadersConfigLiteral} turns\n * `security.headers` into a JSON literal the adapter inlines. A deployed\n * runtime has no `theo.config.ts` to read, so the configuration travels as\n * data.\n * - **Request time** — the generated entry calls {@link buildSecurityHeaders}\n * on that literal and hands every response to {@link withSecurityHeaders}.\n * The same function `theokit start` calls, on the same input, so the two\n * cannot disagree about what the configuration means.\n *\n * ## The per-request nonce, and where it stops\n *\n * `buildSecurityHeaders` accepts a per-request `nonce` and substitutes it into\n * `script-src`. A nonce cannot survive a build-time literal — it is minted per\n * response — so a target reaches one only if it renders the HTML at request\n * time and can put the same value on the script tags it emits.\n *\n * Exactly one deploy path does: **Cloudflare with `ssrStreaming: true`**, whose\n * worker calls `renderStreamingWeb(request, { nonce })`, and that renderer\n * threads the value into `renderToReadableStream` and into the hydration script\n * (`router/entry-server.ts`). That branch mints a nonce per request and builds\n * its CSP from it. Everything else serves HTML written at build time, or no\n * HTML at all, and carries a **nonce-less CSP** — the same answer\n * `buildSecurityHeaders` already gives a prerendered route (EC-4), for the same\n * reason: a nonce in the header with no nonce on the tag blocks every inline\n * script.\n *\n * That asymmetry is real and is not smoothed over. It is stated in the emitted\n * entry, printed by the build through\n * {@link describeDeployedSecurityHeaders}, and written down in\n * `docs/surfaces/build-adapters.md`.\n */\nimport { generateNonce } from '../core/contracts/nonce.js'\nimport type { SecurityHeadersConfig } from '../core/contracts/security-headers.js'\nimport { buildSecurityHeaders } from '../core/contracts/security-headers.js'\n\n/**\n * Re-exported so a generated entry has ONE import for the whole concern.\n *\n * Reaching it through `theokit/server/security` would work and would also drag\n * that barrel's CSRF surface into a Worker bundle, for a function that is forty\n * lines of string concatenation. It is defined in `core/contracts/`, which is\n * the module every target may import from — `adapters → server` is not an edge\n * in the DAG, and the header policy was never server code.\n */\nexport { buildSecurityHeaders }\n\n/**\n * Re-exported for the same reason, and so the streamed Cloudflare worker mints\n * its nonce with the identical primitive `theokit start` uses\n * (`cli/commands/start/request-handler.ts`) rather than a second, hand-rolled\n * one. It is already runtime-portable: Web Crypto first, with a named error\n * when the runtime has none.\n */\nexport { generateNonce }\n\n/**\n * The `security.headers` block, as a literal a generated entry can carry.\n *\n * `{}` when the app declares none — which is not the same as \"no headers\".\n * `buildSecurityHeaders({})` returns the full default baseline, and `{}` is\n * exactly what `theokit start` passes when `security.headers` is absent\n * (`cli/commands/start/index.ts`). An app with no security block gets the same\n * baseline deployed as it gets locally.\n */\nexport function renderSecurityHeadersConfigLiteral(\n headers: SecurityHeadersConfig | undefined,\n): string {\n return JSON.stringify(headers ?? {})\n}\n\n/**\n * Put the headers on a response, without overruling the handler.\n *\n * `theokit start` sets the baseline BEFORE the route handler runs, so a handler\n * can override it with `res.setHeader` (last write wins, Node convention). On a\n * Web target the response arrives already built, so the equivalent of \"the\n * handler wins\" is to skip a header the response already carries: a route that\n * set its own `Content-Security-Policy` keeps it.\n *\n * Mutates and returns the same `Response` rather than constructing a\n * replacement, because these responses are handed to the runtime while their\n * body is still being written (#382) and re-wrapping the stream is exactly the\n * second buffering point that change removed.\n *\n * Mutation is safe for every response these entries produce: the Fetch spec\n * gives a locally constructed `Response` the `response` header guard, which\n * permits `set` for every name used here. The `immutable` guard belongs to\n * responses that came back from `fetch()`, and none of the six emitted handlers\n * returns one — each builds its response from `createWebShim`, from a `new\n * Response(...)`, or from the SSR renderer. The WebSocket upgrade, which is the\n * one response an adapter gets from its runtime rather than building, is\n * deliberately not routed through here.\n */\nexport function withSecurityHeaders(response: Response, headers: Record<string, string>): Response {\n for (const [key, value] of Object.entries(headers)) {\n if (!response.headers.has(key)) response.headers.set(key, value)\n }\n return response\n}\n\nexport interface DeployedSecurityHeaderLimits {\n target: string\n /** The app's `security.headers` block, or undefined when it declares none. */\n securityHeaders: SecurityHeadersConfig | undefined\n /**\n * Does the emitted handler render HTML at request time and mint a CSP nonce\n * for it? True only for Cloudflare with `ssrStreaming: true`.\n */\n mintsNonce: boolean\n /**\n * Is the HTML document served by a platform static host rather than by the\n * handler this build emits? True wherever the emitted handler answers\n * `/api/*` and returns 404 for everything else.\n */\n /**\n * Who puts the security headers on the HTML DOCUMENT — a different question from who serves it,\n * and the two used to be collapsed into one boolean (usetheokit/theokit#412).\n *\n * - `handler` — this target's own handler returns the document, so it carries the same baseline\n * every API response carries. No caveat.\n * - `platform-configured` — the platform's static host serves the document, AND this build emits\n * the configuration that puts the headers on it (`.vercel/output/config.json`, `netlify.toml`).\n * Still worth stating, because nothing here has seen a deployed response.\n * - `platform-unmanaged` — the platform serves it and this build owns no artifact that could\n * configure it. This is the real remaining gap, and it stays named.\n *\n * The two-value version reported `platform-configured` targets with the same message as\n * `platform-unmanaged` ones, telling an operator to go and do work the build had already done —\n * and a stale limitation reads exactly like a current one.\n */\n documentHeaders: 'handler' | 'platform-configured' | 'platform-unmanaged'\n}\n\n/**\n * What the build tells the operator, once, per target.\n *\n * Silent degradation is the failure mode `rules/three-target-parity.md` exists\n * to prevent. Two things degrade quietly here and both are named rather than\n * discovered in production: a CSP that refuses inline scripts on a deploy while\n * allowing them locally, and an HTML document that never passes through the\n * handler these headers are attached to.\n *\n * The header names are read from the map the entry will actually carry, not\n * from a list written next to it. A configuration that switches HSTS or the CSP\n * off would otherwise be announced as sending them.\n */\nexport function describeDeployedSecurityHeaders(limits: DeployedSecurityHeaderLimits): string {\n const headers = buildSecurityHeaders(limits.securityHeaders ?? {}, { production: true })\n const names = Object.keys(headers)\n if (names.length === 0) {\n return ` ! \\`${limits.target}\\` sends no security headers: the configuration switched every one of them off.`\n }\n\n const lines = [\n ` ✓ security headers on every response \\`${limits.target}\\` returns: ${names.join(', ')}.`,\n ]\n const sendsCsp = names.some((name) => name.startsWith('Content-Security-Policy'))\n if (sendsCsp && !limits.mintsNonce) {\n lines.push(\n ` - The CSP carries no nonce: this target serves HTML written at build time,`,\n ` so there is no per-request value to put on a script tag. An inline`,\n ` <script> is refused by \\`script-src 'self'\\` here, while the same page`,\n ` under \\`theokit start\\` gets a nonce and runs it. Move inline scripts to`,\n ` \\`<script src=\"...\">\\`, or set \\`security.headers.cspMode: 'report-only'\\``,\n ` while you migrate.`,\n )\n }\n if (limits.documentHeaders === 'platform-configured') {\n lines.push(\n ` - The HTML document is served by the platform's static host, and reaches`,\n ` the browser with these headers through config this build emits. That`,\n ` path is not verified by a deploy from here — the values come from the`,\n ` same function the handler uses, but no response has been read back.`,\n )\n }\n if (limits.documentHeaders === 'platform-unmanaged') {\n lines.push(\n ` - The HTML document does NOT pass through this handler — the platform's`,\n ` static host serves it — so these headers reach \\`/api/*\\` responses and`,\n ` not the page. This build emits no artifact that could configure it, so`,\n ` set the document's headers on the platform (usetheokit/theokit#412).`,\n )\n }\n return lines.join('\\n')\n}\n"],"mappings":"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","names":[]}
|
package/dist/cli/index.js
CHANGED
|
@@ -15,12 +15,12 @@ function cliVersion() {
|
|
|
15
15
|
// src/cli/index.ts
|
|
16
16
|
var cli = cac("theokit");
|
|
17
17
|
cli.command("dev", "Start development server").option("--port <port>", "Port number").action(async (options) => {
|
|
18
|
-
const { devCommand } = await import("../dev-
|
|
18
|
+
const { devCommand } = await import("../dev-HPUCCB3E.js");
|
|
19
19
|
await devCommand({ port: options.port ? Number(options.port) : void 0 });
|
|
20
20
|
});
|
|
21
21
|
cli.command("build", "Build for production").option("--target <target>", "Deploy target (node, vercel, cloudflare)").action(async (options) => {
|
|
22
22
|
try {
|
|
23
|
-
const { buildCommand } = await import("../build-
|
|
23
|
+
const { buildCommand } = await import("../build-C7CVA5AK.js");
|
|
24
24
|
await buildCommand({ target: options.target });
|
|
25
25
|
} catch (err) {
|
|
26
26
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -32,7 +32,7 @@ cli.command("build", "Build for production").option("--target <target>", "Deploy
|
|
|
32
32
|
});
|
|
33
33
|
cli.command("start", "Start production server").option("--port <port>", "Port number").action(async (options) => {
|
|
34
34
|
try {
|
|
35
|
-
const { startCommand } = await import("../start-
|
|
35
|
+
const { startCommand } = await import("../start-QAPAZ2YC.js");
|
|
36
36
|
await startCommand({ port: options.port ? Number(options.port) : void 0 });
|
|
37
37
|
} catch (err) {
|
|
38
38
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -44,7 +44,7 @@ cli.command("start", "Start production server").option("--port <port>", "Port nu
|
|
|
44
44
|
});
|
|
45
45
|
cli.command("preview", "Build for production, then serve it \u2014 one step (B-030)").option("--port <port>", "Port number").option("--target <target>", "Deploy target (node, vercel, cloudflare)").action(async (options) => {
|
|
46
46
|
try {
|
|
47
|
-
const { previewCommand } = await import("../preview-
|
|
47
|
+
const { previewCommand } = await import("../preview-M3DWFVKB.js");
|
|
48
48
|
await previewCommand({
|
|
49
49
|
port: options.port ? Number(options.port) : void 0,
|
|
50
50
|
target: options.target
|
|
@@ -77,7 +77,7 @@ cli.command(
|
|
|
77
77
|
"Run an agent in the terminal (stream + tool calls + approval)"
|
|
78
78
|
).action(async (name, message) => {
|
|
79
79
|
try {
|
|
80
|
-
const { agentCommand } = await import("../agent-
|
|
80
|
+
const { agentCommand } = await import("../agent-PL3FR4HI.js");
|
|
81
81
|
const { sawError } = await agentCommand(name, message);
|
|
82
82
|
if (sawError) process.exit(1);
|
|
83
83
|
} catch (err) {
|
|
@@ -108,7 +108,7 @@ cli.command("agent sessions gc", "Collect old transcripts for this project (dry
|
|
|
108
108
|
});
|
|
109
109
|
cli.command("mcp <agent>", "Serve an agent as an MCP server over stdio (for desktop MCP clients)").action(async (agent) => {
|
|
110
110
|
try {
|
|
111
|
-
const { mcpCommand } = await import("../mcp-
|
|
111
|
+
const { mcpCommand } = await import("../mcp-AFLDYTK5.js");
|
|
112
112
|
await mcpCommand(agent);
|
|
113
113
|
} catch (err) {
|
|
114
114
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -10,8 +10,9 @@ import {
|
|
|
10
10
|
deployedRuntimeConfigFragment,
|
|
11
11
|
deployedTraceFragment,
|
|
12
12
|
describeDeployedSecurityHeaders,
|
|
13
|
-
renderSecurityHeadersConfigLiteral
|
|
14
|
-
|
|
13
|
+
renderSecurityHeadersConfigLiteral,
|
|
14
|
+
serverDirLiteral
|
|
15
|
+
} from "./chunk-PALZUV6E.js";
|
|
15
16
|
import {
|
|
16
17
|
findRootDiv
|
|
17
18
|
} from "./chunk-3PWQQWT6.js";
|
|
@@ -148,7 +149,7 @@ function renderCloudflareWorkerEntry(opts = {}) {
|
|
|
148
149
|
``,
|
|
149
150
|
`// CR-006: server directory is a build-time literal \u2014 Workers cannot`,
|
|
150
151
|
`// call process.cwd() and resolving paths at runtime returned '/server'.`,
|
|
151
|
-
`const serverDir =
|
|
152
|
+
`const serverDir = ${serverDirLiteral(opts)}`,
|
|
152
153
|
``,
|
|
153
154
|
...routeRuntimeLines(routeModuleEntries, routeTableEntries),
|
|
154
155
|
`// #410 \u2014 the security baseline \`theokit start\` puts on every response, carried`,
|
|
@@ -332,4 +333,4 @@ export {
|
|
|
332
333
|
renderCloudflareWorkerEntry,
|
|
333
334
|
renderWranglerToml
|
|
334
335
|
};
|
|
335
|
-
//# sourceMappingURL=cloudflare-
|
|
336
|
+
//# sourceMappingURL=cloudflare-VIQX4FVC.js.map
|