theokit 0.71.0 → 0.72.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{actions-virtual-module-2SM6YMTM.js → actions-virtual-module-EAKYEMGF.js} +4 -4
- package/dist/{actions-virtual-module-5LRBP6YK.js → actions-virtual-module-OHENNMQG.js} +6 -6
- package/dist/adapters/agent-mount.js +3 -3
- package/dist/{agent-4FXJXZFD.js → agent-VJTZ4DQ7.js} +2 -2
- package/dist/{app-typed-client-LIIPHLO6.js → app-typed-client-ILLQYTXP.js} +6 -6
- package/dist/{app-typed-client-JFPV4YLS.js → app-typed-client-LHH77QDB.js} +4 -4
- package/dist/{aws-lambda-MUGK4WNZ.js → aws-lambda-7AZNJGWU.js} +6 -4
- package/dist/{aws-lambda-MUGK4WNZ.js.map → aws-lambda-7AZNJGWU.js.map} +1 -1
- package/dist/{build-KCIH3HI6.js → build-23QF5FNQ.js} +7 -7
- package/dist/build-23QF5FNQ.js.map +1 -0
- package/dist/{bun-JWZ2UOLJ.js → bun-NKVHOFSJ.js} +6 -4
- package/dist/{bun-JWZ2UOLJ.js.map → bun-NKVHOFSJ.js.map} +1 -1
- package/dist/{chunk-KOG5K26V.js → chunk-2Z7TANA4.js} +2 -2
- package/dist/{chunk-V6VARIR3.js → chunk-4EQEJ4PH.js} +9 -9
- package/dist/{chunk-3NAKOWTX.js → chunk-6U67SO5U.js} +3 -3
- package/dist/{chunk-IGCOTLQI.js → chunk-C5CAL3DX.js} +136 -5
- package/dist/{chunk-IGCOTLQI.js.map → chunk-C5CAL3DX.js.map} +1 -1
- package/dist/{chunk-YWWMYEAC.js → chunk-CLSYYO5F.js} +2 -2
- package/dist/{chunk-OSBGZYXZ.js → chunk-D2R5SJEL.js} +16 -2
- package/dist/chunk-D2R5SJEL.js.map +1 -0
- package/dist/{chunk-JMN4COMK.js → chunk-D7STTNQN.js} +3 -3
- package/dist/{chunk-DSPEN7ZJ.js → chunk-DKX7LF5Q.js} +4 -4
- package/dist/{chunk-5XXXJ6DT.js → chunk-E2RC367T.js} +47 -8
- package/dist/chunk-E2RC367T.js.map +1 -0
- package/dist/{chunk-3DGIANAN.js → chunk-FJEKQ4FT.js} +1 -1
- package/dist/{chunk-3DGIANAN.js.map → chunk-FJEKQ4FT.js.map} +1 -1
- package/dist/{chunk-KI4DOTN4.js → chunk-G7U7FQVC.js} +3 -1
- package/dist/chunk-G7U7FQVC.js.map +1 -0
- package/dist/{chunk-6AGXDYVE.js → chunk-IB5VIXLR.js} +2 -2
- package/dist/{chunk-Q4NSUGMS.js → chunk-JJXBRY2U.js} +74 -6
- package/dist/chunk-JJXBRY2U.js.map +1 -0
- package/dist/{chunk-PGDBSK2L.js → chunk-L6UHMWXU.js} +2 -2
- package/dist/{chunk-MS4A7N77.js → chunk-PEL3MJLM.js} +2 -2
- package/dist/{chunk-TNI4MARH.js → chunk-SFGGRC35.js} +23 -6
- package/dist/chunk-SFGGRC35.js.map +1 -0
- package/dist/{chunk-4D4YVXHR.js → chunk-SYIQV4UH.js} +29 -2
- package/dist/{chunk-4D4YVXHR.js.map → chunk-SYIQV4UH.js.map} +1 -1
- package/dist/{chunk-FFS7IRZF.js → chunk-SZWGXHY3.js} +2 -2
- package/dist/{chunk-SX7ZAHNE.js → chunk-WBB3MEEN.js} +16 -2
- package/dist/chunk-WBB3MEEN.js.map +1 -0
- package/dist/{chunk-TMQ52AZR.js → chunk-X2LFNDJQ.js} +2 -2
- package/dist/{chunk-FWEXQ2BR.js → chunk-XLSJWKSP.js} +11 -11
- package/dist/{chunk-NZDGV4YJ.js → chunk-YCF3N4JS.js} +2 -2
- package/dist/cli/index.js +9 -9
- package/dist/{cloudflare-XO43ZIQF.js → cloudflare-4M4XVNUH.js} +5 -3
- package/dist/{cloudflare-XO43ZIQF.js.map → cloudflare-4M4XVNUH.js.map} +1 -1
- package/dist/{config-support-O4REYSK5.js → config-support-SB5NDQZB.js} +11 -5
- package/dist/{config-support-O4REYSK5.js.map → config-support-SB5NDQZB.js.map} +1 -1
- package/dist/{deno-deploy-EUQDK2RC.js → deno-deploy-IVACZ62D.js} +11 -5
- package/dist/deno-deploy-IVACZ62D.js.map +1 -0
- package/dist/{dev-CD4YU5FN.js → dev-JDJWMRLH.js} +9 -9
- package/dist/{index-inRdhi59.d.ts → index-CmkWlIDO.d.ts} +3 -1
- package/dist/index.d.ts +12 -2
- package/dist/index.js +7 -7
- package/dist/{info-2H7I55YN.js → info-SUX7QVA3.js} +4 -4
- package/dist/{internal-api-TMLSNYMP.js → internal-api-6XNLCNI5.js} +6 -6
- package/dist/{internal-api-WAKX6AZW.js → internal-api-VDYOXOT7.js} +4 -4
- package/dist/{load-config-VMKOV44Y.js → load-config-52H3EKAA.js} +4 -4
- package/dist/{mcp-HS26ZCU4.js → mcp-WJNCTM7M.js} +3 -3
- package/dist/{netlify-LEYEQZK6.js → netlify-3HEWV375.js} +6 -4
- package/dist/{netlify-LEYEQZK6.js.map → netlify-3HEWV375.js.map} +1 -1
- package/dist/{node-OSVPYQ3D.js → node-QUGTW6XV.js} +2 -2
- package/dist/{observability-bootstrap-YQKMEYW7.js → observability-bootstrap-FP6LMMJE.js} +3 -3
- package/dist/{openapi-N4CXRUNT.js → openapi-Q53YOBIU.js} +4 -4
- package/dist/{preview-YDJSRJ2K.js → preview-BARW75PN.js} +3 -3
- package/dist/{rate-limit-BdNDZ3vt.d.ts → rate-limit-fULgvzCz.d.ts} +11 -1
- package/dist/{rate-limit-store-BEJnhWdw.d.ts → rate-limit-store-n1wD4Yk4.d.ts} +48 -1
- package/dist/registry-SDBODRU6.js +23 -0
- package/dist/{routes-ECCDRHXZ.js → routes-FDF4SLOB.js} +4 -4
- package/dist/{schema-ND7GHPQK.js → schema-LHNWUR4V.js} +3 -3
- package/dist/{schemas-QCMSKQDK.js → schemas-2R2J64ZH.js} +2 -2
- package/dist/server/auth/index.d.ts +1 -1
- package/dist/server/http/index.d.ts +1 -1
- package/dist/server/http/index.js +5 -3
- package/dist/server/index.d.ts +4 -4
- package/dist/server/index.js +15 -7
- package/dist/server/index.js.map +1 -1
- package/dist/server/rate-limit/index.d.ts +96 -14
- package/dist/server/rate-limit/index.js +10 -4
- package/dist/server/storage/index.js +1 -1
- package/dist/{server-boundary-RX2AFU5U.js → server-boundary-AO6EELRF.js} +4 -4
- package/dist/{server-boundary-NZPP33G6.js → server-boundary-E5GFVPLB.js} +6 -6
- package/dist/{start-TYXS5I4M.js → start-4JTYXQQJ.js} +14 -11
- package/dist/start-4JTYXQQJ.js.map +1 -0
- package/dist/{static-7OJNB7D2.js → static-NQPLPAB6.js} +6 -2
- package/dist/{static-7OJNB7D2.js.map → static-NQPLPAB6.js.map} +1 -1
- package/dist/{theo-cloud-3ET4G5T6.js → theo-cloud-HMFNZ3FS.js} +3 -1
- package/dist/{theo-cloud-3ET4G5T6.js.map → theo-cloud-HMFNZ3FS.js.map} +1 -1
- package/dist/{vercel-HTAWCNAG.js → vercel-5PMYEEKF.js} +6 -4
- package/dist/{vercel-HTAWCNAG.js.map → vercel-5PMYEEKF.js.map} +1 -1
- package/dist/vite-plugin/index.d.ts +2 -2
- package/dist/vite-plugin/index.js +7 -7
- package/dist/{vite-plugin-DDILUFYY.js → vite-plugin-3ON45MQE.js} +8 -8
- package/package.json +3 -3
- package/dist/build-KCIH3HI6.js.map +0 -1
- package/dist/chunk-5XXXJ6DT.js.map +0 -1
- package/dist/chunk-KI4DOTN4.js.map +0 -1
- package/dist/chunk-OSBGZYXZ.js.map +0 -1
- package/dist/chunk-Q4NSUGMS.js.map +0 -1
- package/dist/chunk-SX7ZAHNE.js.map +0 -1
- package/dist/chunk-TNI4MARH.js.map +0 -1
- package/dist/deno-deploy-EUQDK2RC.js.map +0 -1
- package/dist/registry-4JHCZ6EF.js +0 -23
- package/dist/start-TYXS5I4M.js.map +0 -1
- /package/dist/{actions-virtual-module-2SM6YMTM.js.map → actions-virtual-module-EAKYEMGF.js.map} +0 -0
- /package/dist/{actions-virtual-module-5LRBP6YK.js.map → actions-virtual-module-OHENNMQG.js.map} +0 -0
- /package/dist/{agent-4FXJXZFD.js.map → agent-VJTZ4DQ7.js.map} +0 -0
- /package/dist/{app-typed-client-LIIPHLO6.js.map → app-typed-client-ILLQYTXP.js.map} +0 -0
- /package/dist/{app-typed-client-JFPV4YLS.js.map → app-typed-client-LHH77QDB.js.map} +0 -0
- /package/dist/{chunk-KOG5K26V.js.map → chunk-2Z7TANA4.js.map} +0 -0
- /package/dist/{chunk-V6VARIR3.js.map → chunk-4EQEJ4PH.js.map} +0 -0
- /package/dist/{chunk-3NAKOWTX.js.map → chunk-6U67SO5U.js.map} +0 -0
- /package/dist/{chunk-YWWMYEAC.js.map → chunk-CLSYYO5F.js.map} +0 -0
- /package/dist/{chunk-JMN4COMK.js.map → chunk-D7STTNQN.js.map} +0 -0
- /package/dist/{chunk-DSPEN7ZJ.js.map → chunk-DKX7LF5Q.js.map} +0 -0
- /package/dist/{chunk-6AGXDYVE.js.map → chunk-IB5VIXLR.js.map} +0 -0
- /package/dist/{chunk-PGDBSK2L.js.map → chunk-L6UHMWXU.js.map} +0 -0
- /package/dist/{chunk-MS4A7N77.js.map → chunk-PEL3MJLM.js.map} +0 -0
- /package/dist/{chunk-FFS7IRZF.js.map → chunk-SZWGXHY3.js.map} +0 -0
- /package/dist/{chunk-TMQ52AZR.js.map → chunk-X2LFNDJQ.js.map} +0 -0
- /package/dist/{chunk-FWEXQ2BR.js.map → chunk-XLSJWKSP.js.map} +0 -0
- /package/dist/{chunk-NZDGV4YJ.js.map → chunk-YCF3N4JS.js.map} +0 -0
- /package/dist/{dev-CD4YU5FN.js.map → dev-JDJWMRLH.js.map} +0 -0
- /package/dist/{info-2H7I55YN.js.map → info-SUX7QVA3.js.map} +0 -0
- /package/dist/{internal-api-TMLSNYMP.js.map → internal-api-6XNLCNI5.js.map} +0 -0
- /package/dist/{internal-api-WAKX6AZW.js.map → internal-api-VDYOXOT7.js.map} +0 -0
- /package/dist/{load-config-VMKOV44Y.js.map → load-config-52H3EKAA.js.map} +0 -0
- /package/dist/{mcp-HS26ZCU4.js.map → mcp-WJNCTM7M.js.map} +0 -0
- /package/dist/{node-OSVPYQ3D.js.map → node-QUGTW6XV.js.map} +0 -0
- /package/dist/{observability-bootstrap-YQKMEYW7.js.map → observability-bootstrap-FP6LMMJE.js.map} +0 -0
- /package/dist/{openapi-N4CXRUNT.js.map → openapi-Q53YOBIU.js.map} +0 -0
- /package/dist/{preview-YDJSRJ2K.js.map → preview-BARW75PN.js.map} +0 -0
- /package/dist/{registry-4JHCZ6EF.js.map → registry-SDBODRU6.js.map} +0 -0
- /package/dist/{routes-ECCDRHXZ.js.map → routes-FDF4SLOB.js.map} +0 -0
- /package/dist/{schema-ND7GHPQK.js.map → schema-LHNWUR4V.js.map} +0 -0
- /package/dist/{schemas-QCMSKQDK.js.map → schemas-2R2J64ZH.js.map} +0 -0
- /package/dist/{server-boundary-RX2AFU5U.js.map → server-boundary-AO6EELRF.js.map} +0 -0
- /package/dist/{server-boundary-NZPP33G6.js.map → server-boundary-E5GFVPLB.js.map} +0 -0
- /package/dist/{vite-plugin-DDILUFYY.js.map → vite-plugin-3ON45MQE.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/adapters/node.ts"],"sourcesContent":["/* eslint-disable security/detect-non-literal-fs-filename --\n * Node deploy adapter — derives all write paths from the trusted `cwd`\n * (CLI argument). The `.theokit/docker-compose.yml` + `.theokit/Caddyfile`\n * outputs use a fixed sub-path. Build-time tool — no HTTP input.\n */\nimport { writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\n\nimport { build as viteBuild } from 'vite'\n\nimport type { TheoConfig } from '../config/schema.js'\nimport { generateCaddyfile, generateComposeYaml, readManifest } from '../services/index.js'\n\nimport type { AdapterBuildContext, DeployAdapter } from './types.js'\n\nexport const nodeAdapter: DeployAdapter = {\n name: 'node',\n // #382 — no handler is emitted here: the bundle runs the framework's own\n // Node server, whose writer calls res.write() per chunk\n // (server/http/execute.ts, via node-web-adapter.ts).\n streamsResponses: true,\n // Read from `cli/commands/start/index.ts`: the executor context carries\n // rateLimiter, csrfMode, disallowed, transformer and pluginRunner, and\n // `request-handler.ts` applies the security headers and, since #409, the CORS\n // handler. `cors` used to be absent here for an honest reason -- `theokit start`\n // contained no CORS handling at all, and only the Vite dev server did, so an app\n // that worked cross-origin in development stopped working when this command served it.\n // #367 — `theokit start` has always served agents (`cli/commands/start/handlers.ts`\n // `tryServeAgent`); it was the ONLY thing that did. Declared here so the capability is stated\n // rather than inferred from the fact that it is the default target.\n servesAgents: true,\n appliesConfig: [\n 'rateLimit',\n 'csrf',\n 'disallowed',\n 'serialization',\n 'plugins',\n 'securityHeaders',\n 'cors',\n ],\n\n async build(config: TheoConfig, cwd: string, ctx?: AdapterBuildContext): Promise<void> {\n // T1.1 (architecture-cleanup) — Vite plugin composition is INJECTED via `ctx.makeVitePlugins`.\n // The CLI (which already imports both `adapters/*` and `vite-plugin/*`) composes the\n // Plugin[] and passes it in, eliminating the previous `adapters → vite-plugin` edge\n // (CRITICAL layering inversion per ADR-0001 v2; fixed by ADR-0001 v3).\n if (!ctx?.makeVitePlugins) {\n throw new Error(\n '[adapter-node] build requires ctx.makeVitePlugins (CLI must inject the Vite plugin factory). ' +\n 'This is a framework-internal invariant — see ADR-0001 v3.',\n )\n }\n\n // Client build — `await` per ADR-0001 v3.1: makeVitePlugins may return\n // a Promise (theokit build uses theoPluginAsync to wire the full chain\n // including @theo/actions virtual module).\n await viteBuild({\n root: cwd,\n plugins: await ctx.makeVitePlugins({ root: cwd, ssr: config.ssr }),\n build: {\n outDir: '.theokit/client',\n emptyOutDir: true,\n },\n logLevel: 'info',\n })\n\n // SSR build (only when ssr: true)\n if (config.ssr) {\n // eslint-disable-next-line no-console -- CLI build progress\n console.log('\\n Building SSR...\\n')\n await viteBuild({\n root: cwd,\n plugins: await ctx.makeVitePlugins({ root: cwd, ssr: true }),\n build: {\n ssr: true,\n outDir: '.theokit/server',\n emptyOutDir: true,\n rollupOptions: {\n input: '/@theo/entry-server',\n },\n },\n logLevel: 'info',\n })\n }\n\n // Wave 2 (T2.1) — when polyglot services are declared, emit a\n // TheoCloud-shaped docker-compose harness + Caddyfile (with W3C\n // traceparent propagation via Caddy 2.11+ `tracing` directive).\n // Empty manifest → no emission (Wave 1 BC preserved).\n const manifest = readManifest(cwd)\n if (manifest && manifest.services.length > 0) {\n const yaml = generateComposeYaml(manifest, { webPort: config.port })\n const caddyfile = generateCaddyfile(manifest, {\n port: config.port,\n webHost: 'web',\n })\n writeFileSync(join(cwd, '.theokit', 'docker-compose.yml'), yaml)\n writeFileSync(join(cwd, '.theokit', 'Caddyfile'), caddyfile)\n // eslint-disable-next-line no-console -- CLI build progress\n console.log(\n ` ✓ TheoCloud-shaped harness: .theokit/docker-compose.yml + .theokit/Caddyfile ` +\n `(${String(manifest.services.length)} service(s))`,\n )\n }\n },\n}\n"],"mappings":";;;;;;;;;AAKA,SAAS,qBAAqB;AAC9B,SAAS,YAAY;AAErB,SAAS,SAAS,iBAAiB;AAO5B,IAAM,cAA6B;AAAA,EACxC,MAAM;AAAA;AAAA;AAAA;AAAA,EAIN,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUlB,cAAc;AAAA,EACd,eAAe;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAEA,MAAM,MAAM,QAAoB,KAAa,KAA0C;AAKrF,QAAI,CAAC,KAAK,iBAAiB;AACzB,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AAKA,UAAM,UAAU;AAAA,MACd,MAAM;AAAA,MACN,SAAS,MAAM,IAAI,gBAAgB,EAAE,MAAM,KAAK,KAAK,OAAO,IAAI,CAAC;AAAA,MACjE,OAAO;AAAA,QACL,QAAQ;AAAA,QACR,aAAa;AAAA,MACf;AAAA,MACA,UAAU;AAAA,IACZ,CAAC;AAGD,QAAI,OAAO,KAAK;AAEd,cAAQ,IAAI,uBAAuB;AACnC,YAAM,UAAU;AAAA,QACd,MAAM;AAAA,QACN,SAAS,MAAM,IAAI,gBAAgB,EAAE,MAAM,KAAK,KAAK,KAAK,CAAC;AAAA,QAC3D,OAAO;AAAA,UACL,KAAK;AAAA,UACL,QAAQ;AAAA,UACR,aAAa;AAAA,UACb,eAAe;AAAA,YACb,OAAO;AAAA,UACT;AAAA,QACF;AAAA,QACA,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AAMA,UAAM,WAAW,aAAa,GAAG;AACjC,QAAI,YAAY,SAAS,SAAS,SAAS,GAAG;AAC5C,YAAM,OAAO,oBAAoB,UAAU,EAAE,SAAS,OAAO,KAAK,CAAC;AACnE,YAAM,YAAY,kBAAkB,UAAU;AAAA,QAC5C,MAAM,OAAO;AAAA,QACb,SAAS;AAAA,MACX,CAAC;AACD,oBAAc,KAAK,KAAK,YAAY,oBAAoB,GAAG,IAAI;AAC/D,oBAAc,KAAK,KAAK,YAAY,WAAW,GAAG,SAAS;AAE3D,cAAQ;AAAA,QACN,wFACM,OAAO,SAAS,SAAS,MAAM,CAAC;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config/schemas/rate-limit.ts","../src/config/schemas/upload.ts","../src/config/schemas/logging.ts","../src/config/schemas/cache.ts","../src/config/schemas/observability.ts","../src/config/schemas/security.ts","../src/config/schemas/header-safe.ts","../src/config/schemas/storage.ts"],"sourcesContent":["import { z } from 'zod'\n\n/**\n * Base bucket config — legacy shape preserved for backwards compatibility.\n */\nconst baseRateLimitSchema = z.object({\n windowMs: z.number().min(1),\n max: z.number().int().min(1),\n})\n\n/**\n * T2.2 — Per-route + per-user rate limit. The new shape adds `routes`\n * (path map), `keyBy`, and `cookieName`. The legacy flat shape is still\n * accepted via the union — see `createRouteRateLimiter` for normalization.\n */\nexport const rateLimitSchema = z.union([\n baseRateLimitSchema,\n z.object({\n default: baseRateLimitSchema.optional(),\n routes: z.record(z.string(), baseRateLimitSchema).optional(),\n keyBy: z\n .union([\n z.enum(['ip', 'session', 'user']),\n z.function({ input: z.tuple([z.unknown()]), output: z.string() }),\n ])\n .optional(),\n cookieName: z.string().min(1).optional(),\n /**\n * How many reverse proxies sit in front of the app, for `keyBy: 'ip'`. `false` (default)\n * trusts none; `true` means one; a number names a longer chain.\n *\n * Required for correct limiting behind Caddy/nginx/a load balancer — without it every visitor\n * keys on the proxy address and shares a single bucket. Off by default because\n * `x-forwarded-for` is client-writable.\n */\n trustProxy: z.union([z.boolean(), z.number().int().min(0)]).optional(),\n }),\n])\n","import { z } from 'zod'\n\nexport const uploadSchema = z.object({\n maxFileSize: z\n .number()\n .min(1)\n .default(10 * 1024 * 1024), // 10MB\n maxFiles: z.number().int().min(1).default(10),\n maxFieldSize: z\n .number()\n .min(1)\n .default(1 * 1024 * 1024), // 1MB\n})\n","import { z } from 'zod'\n\nexport const loggingSchema = z.object({\n level: z.enum(['debug', 'info', 'warn', 'error', 'silent']).default('info'),\n})\n","import { z } from 'zod'\n\n// `.finite()` was removed from the 4 numeric schemas below (agent-builder#319): in zod 4 it is a\n// no-op — `z.number()` already rejects `Infinity`, `-Infinity` and `NaN` by default. Measured before\n// removing, against the installed zod 4.4.3, and not assumed from the deprecation message: all five\n// cases (`Infinity`, `-Infinity`, `NaN`, `1.5`, `0`) give the SAME verdict with and without it.\n\n/**\n * Cache subsystem config (caching-and-revalidation-plan).\n * Default `cache: undefined` keeps the framework backward-compatible\n * (no engine initialized → no cache primitives available).\n *\n * Setting `cache: {}` opts in with all defaults.\n */\nconst routeRuleSchema = z.object({\n maxAge: z.number().nonnegative().optional(),\n swr: z.number().nonnegative().optional(),\n tags: z.array(z.string()).optional(),\n})\n\nexport const cacheSchema = z.object({\n enabled: z.boolean().default(true),\n /** 'memory' uses InMemoryCacheAdapter; otherwise pass a custom adapter instance. */\n storage: z.union([z.literal('memory'), z.custom<unknown>()]).default('memory'),\n maxEntries: z.number().int().positive().default(1000),\n defaults: z\n .object({\n maxAge: z.number().nonnegative().default(1),\n swr: z.number().nonnegative().optional(),\n cacheErrors: z.boolean().default(false),\n })\n .default({ maxAge: 1, cacheErrors: false }),\n keyDerivation: z\n .object({\n excludeQuery: z.array(z.string()).optional(),\n sortQuery: z.boolean().default(true),\n lowercaseHost: z.boolean().default(true),\n })\n .default({ sortQuery: true, lowercaseHost: true }),\n routeRules: z.record(z.string(), routeRuleSchema).optional(),\n})\n","import { z } from 'zod'\n\n/**\n * Observability subsystem config.\n *\n * `adapter-registry.ts` has documented `theo.config.ts > observability.provider`\n * as the first source in its resolution chain since it was written, and the key\n * did not exist in the schema — so the chain's highest-priority entry was\n * unreachable and every consumer fell through to the environment\n * (usetheokit/theokit#353).\n *\n * Default `observability: undefined` keeps telemetry off, which is what an\n * application that never asked for it should get.\n */\nexport const observabilitySchema = z.object({\n /** Set `false` to opt out even when the environment would enable an exporter. */\n enabled: z.boolean().default(true),\n /**\n * An `ObservabilityAdapter` instance. Validated structurally rather than by\n * shape, for the same reason `storage` and `plugins` are: the config layer\n * cannot import the adapter contract without inverting the module graph, and\n * the adapter is a live object rather than data.\n */\n provider: z.custom<unknown>().optional(),\n})\n","import { z } from 'zod'\n\nimport { headerSafeString } from './header-safe.js'\n\n/**\n * Phase 5 — CSRF warn-first (EC-1).\n *\n * 0.2.0 default: `warn`. Existing apps keep working but get structured\n * warnings about every state-mutating request that does not carry the\n * `X-Theo-Action: 1` header. 0.3.0 will flip the default to `strict`.\n *\n * Set explicitly to `strict` to opt into the future default early,\n * or `off` to disable CSRF entirely (only valid when you have another\n * defense — bearer auth, no session cookies, etc).\n */\n\n/**\n * Phase 6 — Default security headers (D4 / EC-2).\n *\n * 0.2.0 defaults:\n * - CSP in `report-only` mode (EC-2: don't break existing apps)\n * - X-Frame-Options: DENY · X-Content-Type-Options: nosniff\n * - Referrer-Policy: strict-origin-when-cross-origin\n * - HSTS in production only (no TLS on localhost)\n *\n * Users override individual headers, swap CSP to `enforce`, or disable\n * CSP entirely (`csp: false` / `cspMode: 'off'`).\n */\nexport const securityHeadersSchema = z.object({\n csp: z.union([headerSafeString, z.literal(false)]).optional(),\n // T6.1 — default flipped from 'report-only' to 'enforce' for 0.3.0.\n // Users who want the old behaviour set `cspMode: 'report-only'`\n // explicitly.\n cspMode: z.enum(['enforce', 'report-only', 'off']).default('enforce'),\n hsts: z.union([headerSafeString, z.literal(false)]).optional(),\n frameOptions: z.enum(['DENY', 'SAMEORIGIN']).default('DENY'),\n contentTypeOptions: z.literal('nosniff').default('nosniff'),\n referrerPolicy: headerSafeString.default('strict-origin-when-cross-origin'),\n /**\n * T1.1 — Permissions-Policy directive string. EC-3-refined: rejects CR/LF.\n * Pass `false` to suppress the header.\n */\n permissionsPolicy: z.union([headerSafeString, z.literal(false)]).optional(),\n})\n\n/**\n * T5.1 — Disallowed-routes escalation pattern (Rails-inspired).\n *\n * `routes` accepts string (exact match — trailing slash matters) or\n * RegExp entries. Matched routes that would otherwise emit `csrf.warn`\n * dispatch through `disallowedBehavior` instead:\n * - `'warn'` : no-op vs the default warn-mode behavior\n * - `'raise'` : escalate to 403, even when global `csrf` mode is 'warn'\n *\n * Use to roll out strict mode per-route (e.g., flip /api/auth/* first)\n * without committing the entire surface to strict at once.\n */\nconst disallowedConfigSchema = z.object({\n routes: z.array(z.union([z.string(), z.instanceof(RegExp)])),\n behavior: z.enum(['warn', 'raise']).default('raise'),\n})\n\n/**\n * T1.2 — CORS configuration.\n *\n * `origins` accepts a single value (`'*'`, string, RegExp, callback) OR an\n * array of (string | RegExp). The spec-violating `origins: '*'` +\n * `credentials: true` combination is rejected at parse time (browsers\n * ignore wildcards when credentials are sent).\n *\n * EC-3 — `allowedHeaders` and `exposedHeaders` entries go through the\n * header-safe refinement (CR/LF rejected — CWE-113 mitigation).\n */\nexport const corsSchema = z\n .object({\n origins: z.union([\n z.literal('*'),\n headerSafeString,\n z.instanceof(RegExp),\n z.array(z.union([headerSafeString, z.instanceof(RegExp)])),\n z.function({ input: z.tuple([z.string()]), output: z.boolean() }),\n ]),\n methods: z\n .array(z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'HEAD']))\n .optional(),\n allowedHeaders: z.array(headerSafeString).optional(),\n exposedHeaders: z.array(headerSafeString).optional(),\n credentials: z.boolean().default(false),\n maxAge: z.number().int().min(0).max(86400).default(600),\n })\n .refine((c) => !(c.origins === '*' && c.credentials), {\n message: 'CORS spec forbids origins:\"*\" with credentials:true — browsers ignore the wildcard',\n })\n\nexport const securitySchema = z.object({\n // T6.1 — default flipped from 'warn' to 'strict' for 0.3.0. Apps that\n // grep their warn-mode logs from 0.2.x already know which endpoints\n // break; opt back into 'warn' globally OR use disallowedRoutes for\n // surgical migration.\n csrf: z.enum(['off', 'warn', 'strict']).default('strict'),\n headers: securityHeadersSchema.optional(),\n /** T5.1 — per-route escalation (Rails disallowed_warnings pattern). */\n disallowed: disallowedConfigSchema.optional(),\n /** T1.2 — Cross-Origin Resource Sharing. Single global config; runs first in pipeline. */\n cors: corsSchema.optional(),\n /**\n * Permit binding a public network interface while write routes still declare `policy('public')`.\n *\n * Absent means `false`, and that is the point: `theo start` refuses that combination rather\n * than serving it, because an unauthenticated POST reachable from a network is an open endpoint\n * whether or not anyone meant it to be. See `cli/commands/start/public-exposure-gate.ts` for what\n * is refused and — equally important — what is not.\n *\n * Setting it to `true` is a decision, not a switch: the routes stay open, the startup log goes on\n * naming every one of them, and this line in `theo.config.ts` is what an auditor finds when they\n * ask who agreed to it.\n *\n * `.optional()` rather than `.default(false)`: a Zod default lands in the OUTPUT type, so every\n * caller constructing a `SecurityConfig` literal would have to name a field they do not care\n * about. The reader supplies the fallback (`?? false`), which keeps absent and false identical\n * where it matters and keeps the type unchanged for everyone else.\n */\n allowUnauthenticatedWrites: z.boolean().optional(),\n})\n","import { z } from 'zod'\n\n/**\n * EC-3 — CWE-113 HTTP Response Splitting mitigation.\n *\n * Every string that becomes a header value must reject CR/LF. Apps that\n * derive header values from untrusted input (feature flags, tenant config,\n * URL params) would otherwise let attackers inject Set-Cookie / Location\n * headers via `\\r\\n`. Apply this refinement to every header-bound string\n * field: permissionsPolicy, csp, hsts, referrerPolicy, CORS allow/expose.\n */\nexport const headerSafeString = z\n .string()\n .refine((s) => !/[\\r\\n]/.test(s), { message: 'Header value must not contain CR/LF' })\n","import { z } from 'zod'\n\n/**\n * StorageManager schemas (T1.1 / ADR-0007 D4).\n *\n * `theo.config.ts > storage` declares Postgres servers (credentials), the\n * databases on each server (TheoCloud / managed PG / self-host), and Redis\n * servers. The runtime `StorageManager` consumes this block; adapters\n * (PostgresJobBackend, PostgresConversationStorage, etc.) request pools by\n * database name and never see raw credentials at the call site.\n *\n * EC-1 (DOCUMENT in concept doc T4.1): Zod default strip-unknown mode\n * silently drops typo keys (`databasees` instead of `databases`). The\n * concept doc warns users to use exact names; runtime errors are still\n * actionable (`Database \"X\" not configured`).\n *\n * EC-2 (DEFERRED to use-time): `databases.X.server` references a key in\n * `servers`. Cross-field validation is intentionally NOT enforced at parse\n * time — `StorageManager.usePostgres()` throws an actionable error on the\n * first call with the dangling reference, matching Rails / Nitro behavior.\n */\nconst tlsConfigSchema = z.object({\n rejectUnauthorized: z.boolean().optional(),\n caCert: z.string().optional(),\n clientCert: z.string().optional(),\n clientKey: z.string().optional(),\n})\n\nconst serverConfigSchema = z.object({\n host: z.string().min(1),\n port: z.number().int().positive().max(65535).optional(),\n user: z.string().min(1),\n /** Password may be the empty string (some providers permit it). */\n password: z.string(),\n tls: tlsConfigSchema.optional(),\n})\n\nconst postgresPoolConfigSchema = z.object({\n min: z.number().int().nonnegative().optional(),\n max: z.number().int().positive().optional(),\n connectionTimeoutMillis: z.number().int().positive().optional(),\n idleTimeoutMillis: z.number().int().nonnegative().optional(),\n})\n\nconst postgresDatabaseConfigSchema = z.object({\n /** References a key in `storage.servers`. Resolved at `usePostgres()` call time. */\n server: z.string().min(1),\n database: z.string().min(1),\n pool: postgresPoolConfigSchema.optional(),\n})\n\nconst redisServerConfigSchema = serverConfigSchema.extend({\n db: z.number().int().nonnegative().optional(),\n maxRetriesPerRequest: z.number().int().nonnegative().optional(),\n})\n\nexport const storageSchema = z.object({\n servers: z.record(z.string(), serverConfigSchema).optional(),\n databases: z.record(z.string(), postgresDatabaseConfigSchema).optional(),\n redis: z.record(z.string(), redisServerConfigSchema).optional(),\n})\n\nexport type StorageConfig = z.infer<typeof storageSchema>\n"],"mappings":";;;;AAAA,SAAS,SAAS;AAKlB,IAAM,sBAAsB,EAAE,OAAO;AAAA,EACnC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC1B,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC;AAC7B,CAAC;AAOM,IAAM,kBAAkB,EAAE,MAAM;AAAA,EACrC;AAAA,EACA,EAAE,OAAO;AAAA,IACP,SAAS,oBAAoB,SAAS;AAAA,IACtC,QAAQ,EAAE,OAAO,EAAE,OAAO,GAAG,mBAAmB,EAAE,SAAS;AAAA,IAC3D,OAAO,EACJ,MAAM;AAAA,MACL,EAAE,KAAK,CAAC,MAAM,WAAW,MAAM,CAAC;AAAA,MAChC,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE,CAAC;AAAA,IAClE,CAAC,EACA,SAAS;AAAA,IACZ,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASvC,YAAY,EAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS;AAAA,EACvE,CAAC;AACH,CAAC;;;ACrCD,SAAS,KAAAA,UAAS;AAEX,IAAM,eAAeA,GAAE,OAAO;AAAA,EACnC,aAAaA,GACV,OAAO,EACP,IAAI,CAAC,EACL,QAAQ,KAAK,OAAO,IAAI;AAAA;AAAA,EAC3B,UAAUA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,QAAQ,EAAE;AAAA,EAC5C,cAAcA,GACX,OAAO,EACP,IAAI,CAAC,EACL,QAAQ,IAAI,OAAO,IAAI;AAAA;AAC5B,CAAC;;;ACZD,SAAS,KAAAC,UAAS;AAEX,IAAM,gBAAgBA,GAAE,OAAO;AAAA,EACpC,OAAOA,GAAE,KAAK,CAAC,SAAS,QAAQ,QAAQ,SAAS,QAAQ,CAAC,EAAE,QAAQ,MAAM;AAC5E,CAAC;;;ACJD,SAAS,KAAAC,UAAS;AAclB,IAAM,kBAAkBA,GAAE,OAAO;AAAA,EAC/B,QAAQA,GAAE,OAAO,EAAE,YAAY,EAAE,SAAS;AAAA,EAC1C,KAAKA,GAAE,OAAO,EAAE,YAAY,EAAE,SAAS;AAAA,EACvC,MAAMA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS;AACrC,CAAC;AAEM,IAAM,cAAcA,GAAE,OAAO;AAAA,EAClC,SAASA,GAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA;AAAA,EAEjC,SAASA,GAAE,MAAM,CAACA,GAAE,QAAQ,QAAQ,GAAGA,GAAE,OAAgB,CAAC,CAAC,EAAE,QAAQ,QAAQ;AAAA,EAC7E,YAAYA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,GAAI;AAAA,EACpD,UAAUA,GACP,OAAO;AAAA,IACN,QAAQA,GAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,CAAC;AAAA,IAC1C,KAAKA,GAAE,OAAO,EAAE,YAAY,EAAE,SAAS;AAAA,IACvC,aAAaA,GAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EACxC,CAAC,EACA,QAAQ,EAAE,QAAQ,GAAG,aAAa,MAAM,CAAC;AAAA,EAC5C,eAAeA,GACZ,OAAO;AAAA,IACN,cAAcA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS;AAAA,IAC3C,WAAWA,GAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,IACnC,eAAeA,GAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EACzC,CAAC,EACA,QAAQ,EAAE,WAAW,MAAM,eAAe,KAAK,CAAC;AAAA,EACnD,YAAYA,GAAE,OAAOA,GAAE,OAAO,GAAG,eAAe,EAAE,SAAS;AAC7D,CAAC;;;ACxCD,SAAS,KAAAC,UAAS;AAcX,IAAM,sBAAsBA,GAAE,OAAO;AAAA;AAAA,EAE1C,SAASA,GAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjC,UAAUA,GAAE,OAAgB,EAAE,SAAS;AACzC,CAAC;;;ACxBD,SAAS,KAAAC,UAAS;;;ACAlB,SAAS,KAAAC,UAAS;AAWX,IAAM,mBAAmBA,GAC7B,OAAO,EACP,OAAO,CAAC,MAAM,CAAC,SAAS,KAAK,CAAC,GAAG,EAAE,SAAS,sCAAsC,CAAC;;;ADe/E,IAAM,wBAAwBC,GAAE,OAAO;AAAA,EAC5C,KAAKA,GAAE,MAAM,CAAC,kBAAkBA,GAAE,QAAQ,KAAK,CAAC,CAAC,EAAE,SAAS;AAAA;AAAA;AAAA;AAAA,EAI5D,SAASA,GAAE,KAAK,CAAC,WAAW,eAAe,KAAK,CAAC,EAAE,QAAQ,SAAS;AAAA,EACpE,MAAMA,GAAE,MAAM,CAAC,kBAAkBA,GAAE,QAAQ,KAAK,CAAC,CAAC,EAAE,SAAS;AAAA,EAC7D,cAAcA,GAAE,KAAK,CAAC,QAAQ,YAAY,CAAC,EAAE,QAAQ,MAAM;AAAA,EAC3D,oBAAoBA,GAAE,QAAQ,SAAS,EAAE,QAAQ,SAAS;AAAA,EAC1D,gBAAgB,iBAAiB,QAAQ,iCAAiC;AAAA;AAAA;AAAA;AAAA;AAAA,EAK1E,mBAAmBA,GAAE,MAAM,CAAC,kBAAkBA,GAAE,QAAQ,KAAK,CAAC,CAAC,EAAE,SAAS;AAC5E,CAAC;AAcD,IAAM,yBAAyBA,GAAE,OAAO;AAAA,EACtC,QAAQA,GAAE,MAAMA,GAAE,MAAM,CAACA,GAAE,OAAO,GAAGA,GAAE,WAAW,MAAM,CAAC,CAAC,CAAC;AAAA,EAC3D,UAAUA,GAAE,KAAK,CAAC,QAAQ,OAAO,CAAC,EAAE,QAAQ,OAAO;AACrD,CAAC;AAaM,IAAM,aAAaA,GACvB,OAAO;AAAA,EACN,SAASA,GAAE,MAAM;AAAA,IACfA,GAAE,QAAQ,GAAG;AAAA,IACb;AAAA,IACAA,GAAE,WAAW,MAAM;AAAA,IACnBA,GAAE,MAAMA,GAAE,MAAM,CAAC,kBAAkBA,GAAE,WAAW,MAAM,CAAC,CAAC,CAAC;AAAA,IACzDA,GAAE,SAAS,EAAE,OAAOA,GAAE,MAAM,CAACA,GAAE,OAAO,CAAC,CAAC,GAAG,QAAQA,GAAE,QAAQ,EAAE,CAAC;AAAA,EAClE,CAAC;AAAA,EACD,SAASA,GACN,MAAMA,GAAE,KAAK,CAAC,OAAO,QAAQ,OAAO,SAAS,UAAU,WAAW,MAAM,CAAC,CAAC,EAC1E,SAAS;AAAA,EACZ,gBAAgBA,GAAE,MAAM,gBAAgB,EAAE,SAAS;AAAA,EACnD,gBAAgBA,GAAE,MAAM,gBAAgB,EAAE,SAAS;AAAA,EACnD,aAAaA,GAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EACtC,QAAQA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,KAAK,EAAE,QAAQ,GAAG;AACxD,CAAC,EACA,OAAO,CAAC,MAAM,EAAE,EAAE,YAAY,OAAO,EAAE,cAAc;AAAA,EACpD,SAAS;AACX,CAAC;AAEI,IAAM,iBAAiBA,GAAE,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,EAKrC,MAAMA,GAAE,KAAK,CAAC,OAAO,QAAQ,QAAQ,CAAC,EAAE,QAAQ,QAAQ;AAAA,EACxD,SAAS,sBAAsB,SAAS;AAAA;AAAA,EAExC,YAAY,uBAAuB,SAAS;AAAA;AAAA,EAE5C,MAAM,WAAW,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkB1B,4BAA4BA,GAAE,QAAQ,EAAE,SAAS;AACnD,CAAC;;;AE3HD,SAAS,KAAAC,UAAS;AAqBlB,IAAM,kBAAkBA,GAAE,OAAO;AAAA,EAC/B,oBAAoBA,GAAE,QAAQ,EAAE,SAAS;AAAA,EACzC,QAAQA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,YAAYA,GAAE,OAAO,EAAE,SAAS;AAAA,EAChC,WAAWA,GAAE,OAAO,EAAE,SAAS;AACjC,CAAC;AAED,IAAM,qBAAqBA,GAAE,OAAO;AAAA,EAClC,MAAMA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACtB,MAAMA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,KAAK,EAAE,SAAS;AAAA,EACtD,MAAMA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA;AAAA,EAEtB,UAAUA,GAAE,OAAO;AAAA,EACnB,KAAK,gBAAgB,SAAS;AAChC,CAAC;AAED,IAAM,2BAA2BA,GAAE,OAAO;AAAA,EACxC,KAAKA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS;AAAA,EAC7C,KAAKA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAAA,EAC1C,yBAAyBA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAAA,EAC9D,mBAAmBA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS;AAC7D,CAAC;AAED,IAAM,+BAA+BA,GAAE,OAAO;AAAA;AAAA,EAE5C,QAAQA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACxB,UAAUA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC1B,MAAM,yBAAyB,SAAS;AAC1C,CAAC;AAED,IAAM,0BAA0B,mBAAmB,OAAO;AAAA,EACxD,IAAIA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS;AAAA,EAC5C,sBAAsBA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS;AAChE,CAAC;AAEM,IAAM,gBAAgBA,GAAE,OAAO;AAAA,EACpC,SAASA,GAAE,OAAOA,GAAE,OAAO,GAAG,kBAAkB,EAAE,SAAS;AAAA,EAC3D,WAAWA,GAAE,OAAOA,GAAE,OAAO,GAAG,4BAA4B,EAAE,SAAS;AAAA,EACvE,OAAOA,GAAE,OAAOA,GAAE,OAAO,GAAG,uBAAuB,EAAE,SAAS;AAChE,CAAC;","names":["z","z","z","z","z","z","z","z"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server/rate-limit/client-ip.ts","../src/server/rate-limit/rate-limit-per-route.ts","../src/server/rate-limit/rate-limited-guard.ts"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server/agent/mount-agent.ts","../src/server/agent/agent-access.ts","../src/server/agent/build-agent-streamer.ts","../src/server/agent/approval-registry.ts","../src/config/schemas/rate-limit.ts","../src/config/schemas/upload.ts","../src/config/schemas/logging.ts","../src/config/schemas/cache.ts","../src/config/schemas/observability.ts","../src/config/schemas/security.ts","../src/config/schemas/header-safe.ts","../src/config/schemas/storage.ts","../src/server/observability-bootstrap.ts","../src/server/agent/hitl-pause-spans.ts","../src/server/agent/observe-agent-run.ts","../src/server/agent/observe-served-run.ts","../src/server/agent/durable-ui-message-stream-response.ts","../src/server/agent/run-event-cache.ts"],"mappings":"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","names":["compileLoadedAgentModule","resolveEnabledSkills","streamAgentUIMessages","z","z","z","z","z","z","z","z","compileLoadedAgentModule","resolveEnabledSkills","streamAgentUIMessages"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server/rate-limit/rate-limit-store.ts","../src/server/rate-limit/rate-limit.ts"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/adapters/deno-deploy.ts"],"sourcesContent":["/* eslint-disable security/detect-non-literal-fs-filename --\n * Deno Deploy adapter. Writes to `cwd/.theokit/deno-deploy/`. Build-time.\n */\nimport { mkdirSync, writeFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\n\nimport type { TheoConfig } from '../config/schema.js'\nimport { assertServicesUnsupported, readManifest } from '../services/index.js'\n\nimport { deployedAgentsFragment, scannedFromLoaderCache } from './deployed-agents.js'\nimport { planDeployedPlugins } from './deployed-plugins-module.js'\nimport { deployedEntryPreamble } from './deployed-preamble.js'\nimport { deployedRateLimitFragment, rateLimitCheckFragment } from './deployed-rate-limit.js'\nimport {\n agentsDirLiteral,\n deployedRuntimeConfigFragment,\n serverDirLiteral,\n} from './deployed-runtime-config.js'\nimport { deployedTraceFragment } from './deployed-trace.js'\nimport { nodeAdapter } from './node.js'\nimport { describeDeployedSecurityHeaders } from './security-headers.js'\nimport type { AdapterBuildContext, DeployAdapter, DeployedEntryOptions } from './types.js'\n\nexport interface DenoBuildDeps {\n runNodeBuild?: (config: TheoConfig, cwd: string, ctx?: AdapterBuildContext) => Promise<void>\n writeEntry?: (path: string, content: string) => void\n ensureDir?: (path: string) => void\n}\n\n/**\n * The framework imports this entry opens with, as `npm:` specifiers.\n *\n * Extracted from `renderDenoEntry` when adding the configured-directory literal pushed it past the\n * per-function line budget. A cohesive block — every line is one import of the same package family\n * — so lifting it keeps the budget a signal about the renderer rather than about its preamble.\n */\nconst FRAMEWORK_IMPORTS: readonly string[] = [\n `// Use npm: specifier so Deno resolves theokit from the user's package.json`,\n `// equivalent (works in both local 'deno run' and Deno Deploy).`,\n `import { scanServerRoutes, matchRoute, executeRoute, createProductionLoader, scanWebSocketRoutes, extractTraceIdFromRequest, TRACE_HEADER, createCorsWebHandler } from 'npm:theokit/server'`,\n `import { createWebShim } from 'npm:theokit/adapters/web-shim'`,\n `import { buildSecurityHeaders, withSecurityHeaders } from 'npm:theokit/adapters/security-headers'`,\n `// T3.3 — WS bridge for Deno runtime`,\n `import { createDenoWsBridge } from 'npm:theokit/adapters/ws-shim'`,\n]\n\n/** The target's name, in the five places that spell it. Adding a sixth tripped the duplicate-literal gate. */\n/* The name in the places a gate does NOT read. `assertServicesUnsupported` keeps the literal:\n * `services-other-adapters-reject.test.ts:30` requires each adapter to name ITSELF there, so a\n * copy-paste carrying another adapter's name cannot hide behind a constant. */\nconst TARGET = 'deno-deploy'\n\nexport function renderDenoEntry(port: number, opts: DeployedEntryOptions = {}): string {\n const runtimeConfig = deployedRuntimeConfigFragment(opts)\n const agentsFragment = deployedAgentsFragment(scannedFromLoaderCache(agentsDirLiteral(opts)), {\n notFound: 'notFound()',\n importPrefix: 'npm:',\n // B-185 — bound only when the runtime-config fragment declared the const, which is\n // exactly when a plugins module was emitted. Referencing it otherwise would emit an\n // identifier the entry never declares.\n pluginRunnerExpr:\n opts.runtimeConfigModule === undefined ? undefined : 'await THEO_PLUGIN_RUNNER',\n })\n return [\n `// Generated by Theo — Deno Deploy Adapter`,\n `// Deploy: deployctl deploy --project=<name> .theokit/deno/server.ts`,\n `// Requires Deno >= 1.40 (Deno.serve + npm: specifier support)`,\n ``,\n `// Runtime guard`,\n `if (typeof Deno === 'undefined') {`,\n ` throw new Error('TheoDenoDeployAdapter must run inside Deno.')`,\n `}`,\n ``,\n ...FRAMEWORK_IMPORTS,\n ``,\n `const port = Number(Deno.env.get('PORT') ?? '${port}')`,\n `const cwd = Deno.cwd()`,\n `const serverDir = cwd + '/' + ${serverDirLiteral(opts)}`,\n `let routesCache = null`,\n `let wsRoutesCache = null`,\n `let loaderCache = null`,\n ``,\n `// #410 — the security baseline \\`theokit start\\` puts on every response,`,\n `// carried here as a literal because the deployed isolate has no`,\n `// theo.config.ts to read. Non-API paths 404 here and are served by Deno`,\n `// Deploy's static asset handler, so this covers the API and not the`,\n `// document (usetheokit/theokit#412).`,\n ...deployedEntryPreamble(runtimeConfig, agentsFragment, opts, TARGET),\n ``,\n `function notFound() {`,\n ` return new Response(JSON.stringify({ error: { code: 'NOT_FOUND' } }), {`,\n ` status: 404,`,\n ` headers: { 'Content-Type': 'application/json' },`,\n ` })`,\n `}`,\n ``,\n // B-027 — `npm:`, like every other specifier this target emits (`:37-43`). A bare one does\n // not resolve on Deno Deploy, and the harness asserts the prefix is here before rewriting it.\n ...(opts.rateLimit === undefined\n ? []\n : [\n `import { createRateLimiterWeb } from 'npm:theokit/server'`,\n `import { resolveClientIpFromRequest } from 'npm:theokit/server/rate-limit'`,\n ``,\n ]),\n ...deployedRateLimitFragment(\n opts.rateLimit,\n TARGET,\n // `info.remoteAddr` is the runtime's own answer. A `UnixAddr` has no `hostname`, so the\n // optional chain is what keeps the read from throwing there rather than a guess.\n `info?.remoteAddr?.hostname ?? resolveClientIpFromRequest(request, TRUST_PROXY)`,\n 'request, info',\n ),\n ``,\n // The serve handler's SECOND parameter is bound here for the first time: `Deno.serve` has\n // always passed it and the emitted entry discarded it.\n `Deno.serve({ port }, async (request, info) => {`,\n ` // #409 — the preflight is answered BEFORE anything routes: an OPTIONS the router`,\n ` // handles is an OPTIONS the browser never gets a CORS answer to.`,\n ` const preflight = corsPreflight(request)`,\n ` if (preflight !== null) return withSecurityHeaders(preflight, SECURITY_HEADERS)`,\n ...rateLimitCheckFragment(opts.rateLimit, ' ', 'request, info'),\n ``,\n ` // LCR0103 — the upgrade branch sits BELOW the limiter, and the order is the point.`,\n ` // It used to sit above, under the comment \"a 101 carries no document and no script,`,\n ` // so the security baseline does not apply to it\". That is true of the security`,\n ` // HEADERS — a document concern — and false of the limiter, which is a resource`,\n ` // concern: a long-lived socket is the most expensive thing this entry hands out, so`,\n ` // the upgrade is the path that most needs a budget, not the one that may skip it.`,\n ` // T3.3 — Detect WebSocket upgrade and delegate to the Deno bridge.`,\n ` // A 101 carries no document and no script, so the security baseline does`,\n ` // not apply to it.`,\n ` if (request.headers.get('upgrade')?.toLowerCase() === 'websocket') {`,\n ` if (!wsRoutesCache) wsRoutesCache = scanWebSocketRoutes(serverDir)`,\n ` if (wsRoutesCache.length === 0) return notFound()`,\n ` const denoWs = createDenoWsBridge({`,\n ` onOpen: () => {},`,\n ` onMessage: (ws, data) => { ws.send(data) },`,\n ` onClose: () => {},`,\n ` }, Deno)`,\n ` return denoWs.handle(request)`,\n ` }`,\n ` return withCors(request, withSecurityHeaders(await handleRequest(request), SECURITY_HEADERS))`,\n `})`,\n ``,\n `async function handleRequest(request) {`,\n ` const url = new URL(request.url)`,\n ``,\n ` if (!url.pathname.startsWith('/api/')${agentsFragment.hostBypass}) {`,\n ` // Static + SPA fallback are served by Deno Deploy's static asset handler.`,\n ` return notFound()`,\n ` }`,\n ``,\n ` if (!routesCache) routesCache = scanServerRoutes(serverDir)`,\n ` if (!loaderCache) loaderCache = createProductionLoader()`,\n ``,\n ...agentsFragment.branch,\n ``,\n ` const match = matchRoute(url.pathname, routesCache)`,\n ` if (!match) return notFound()`,\n ``,\n ` const { req, res, toResponse } = createWebShim(request)`,\n ...deployedTraceFragment('request', ' '),\n ` const method = request.method.toUpperCase()`,\n ` // #382 — not awaited: toResponse() settles at the headers and carries a`,\n ` // live body, so Deno.serve streams while the handler writes.`,\n ` return toResponse(executeRoute({ route: match.route, method, params: match.params, req, res, loadModule: loaderCache, serverDir, requestId, ...CSRF_CONFIG, ${runtimeConfig.executeRouteSpread} }))`,\n `}`,\n ``,\n `console.log('Theo (Deno Deploy) listening on :' + port)`,\n ].join('\\n')\n}\n\nexport async function buildDeno(\n config: TheoConfig,\n cwd: string,\n deps: DenoBuildDeps = {},\n ctx?: AdapterBuildContext,\n): Promise<void> {\n // Wave 2 (T2.2) — reject polyglot services on this adapter.\n assertServicesUnsupported('deno-deploy', readManifest(cwd))\n\n const runNodeBuild = deps.runNodeBuild ?? nodeAdapter.build.bind(nodeAdapter)\n await runNodeBuild(config, cwd, ctx)\n\n const outputDir = resolve(cwd, '.theokit/deno')\n const ensureDir = deps.ensureDir ?? ((p: string) => mkdirSync(p, { recursive: true }))\n ensureDir(outputDir)\n\n const pluginsPlan = planDeployedPlugins(config.plugins, denoDeployAdapter.name)\n const entry = renderDenoEntry(config.port, {\n securityHeaders: config.security?.headers,\n csrf: config.security?.csrf,\n disallowed: config.security?.disallowed,\n cors: config.security?.cors,\n // #425 — a selector, not a transformer, so it rides as a literal like the values above.\n serialization: config.serialization,\n // #425 — the ONE concern that is not a literal. A closure cannot be baked, so a plugin\n // declared by module specifier is imported by the emitted module instead; a constructed one\n // is refused by name at build time rather than dropped in silence.\n runtimeConfigModule: pluginsPlan?.moduleSpecifier,\n // #95 — the configured directories, which `build.ts:210` already threads into the Vite\n // plugins. Without these two lines the literals above fall to their defaults and a project\n // with a custom dir deploys an entry that resolves a directory it does not have.\n serverDir: config.serverDir,\n agentsDir: config.agentsDir,\n })\n const write =\n deps.writeEntry ??\n ((p, c) => {\n writeFileSync(p, c)\n })\n if (pluginsPlan !== undefined) {\n // Beside the entry, so the emitted import is a sibling. Written through the same seam as\n // the entry so a test that captures one captures both (#425).\n write(resolve(outputDir, 'theo.plugins.mjs'), pluginsPlan.source)\n }\n write(resolve(outputDir, 'server.ts'), entry)\n\n // eslint-disable-next-line no-console -- CLI build progress\n console.log('\\n ✓ Deno Deploy output → .theokit/deno/server.ts')\n // eslint-disable-next-line no-console -- CLI build progress\n console.log(\n `${describeDeployedSecurityHeaders({\n target: TARGET,\n securityHeaders: config.security?.headers,\n mintsNonce: false,\n documentHeaders: 'platform-unmanaged',\n })}\\n`,\n )\n}\n\nexport const denoDeployAdapter: DeployAdapter = {\n name: 'deno-deploy',\n streamsResponses: true,\n // #409 / #410 — the generated entry calls `executeRoute` with routes, loader\n // and serverDir only. CSRF, route policy, file middleware and Zod validation\n // still run because they live inside `executeRoute`; none of the remaining\n // configurable concerns reach it. Declared explicitly rather than omitted so\n // the gap is a statement in the source and not an absence.\n //\n // `securityHeaders` IS applied -- to every response this isolate returns. The\n // document comes from Deno Deploy's static asset handler and does not pass\n // through it (usetheokit/theokit#412).\n servesAgents: true,\n appliesConfig: ['securityHeaders', 'csrf', 'disallowed', 'cors', 'serialization', 'plugins'],\n build(config, cwd, ctx) {\n return buildDeno(config, cwd, {}, ctx)\n },\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import "tsx/esm";
|
|
3
|
-
|
|
4
|
-
// src/adapters/registry.ts
|
|
5
|
-
var adapterRegistry = {
|
|
6
|
-
node: async () => (await import("./node-OSVPYQ3D.js")).nodeAdapter,
|
|
7
|
-
vercel: async () => (await import("./vercel-HTAWCNAG.js")).vercelAdapter,
|
|
8
|
-
cloudflare: async () => (await import("./cloudflare-XO43ZIQF.js")).cloudflareAdapter,
|
|
9
|
-
static: async () => (await import("./static-7OJNB7D2.js")).staticAdapter,
|
|
10
|
-
bun: async () => (await import("./bun-JWZ2UOLJ.js")).bunAdapter,
|
|
11
|
-
"deno-deploy": async () => (await import("./deno-deploy-EUQDK2RC.js")).denoDeployAdapter,
|
|
12
|
-
netlify: async () => (await import("./netlify-LEYEQZK6.js")).netlifyAdapter,
|
|
13
|
-
"aws-lambda": async () => (await import("./aws-lambda-MUGK4WNZ.js")).awsLambdaAdapter,
|
|
14
|
-
"theo-cloud": async () => (await import("./theo-cloud-3ET4G5T6.js")).theoCloudAdapter
|
|
15
|
-
};
|
|
16
|
-
async function resolveAdapter(target) {
|
|
17
|
-
const factory = adapterRegistry[target];
|
|
18
|
-
return factory();
|
|
19
|
-
}
|
|
20
|
-
export {
|
|
21
|
-
resolveAdapter
|
|
22
|
-
};
|
|
23
|
-
//# sourceMappingURL=registry-4JHCZ6EF.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/commands/start/index.ts","../src/server/cron/cron-runtime-node.ts","../src/server/define/health-route.ts","../src/server/rate-limit/client-ip.ts","../src/server/rate-limit/rate-limit-per-route.ts","../src/cli/commands/start/assert-sdk-compatible.ts","../src/server/agent/sdk-compat.ts","../src/cli/commands/start/bootstrap-stages.ts","../src/cli/commands/start/cron-bootstrap.ts","../src/cli/commands/start/graceful-shutdown.ts","../src/cli/commands/start/manifest-loader.ts","../src/cli/commands/start/public-exposure-gate.ts","../src/cli/commands/start/handlers.ts","../src/server/http/static.ts","../src/cli/commands/start/ssr-setup.ts","../src/cli/commands/start/request-handler.ts","../src/cli/commands/start/resolve-listen-host.ts","../src/cli/commands/start/websocket-handler.ts"],"sourcesContent":["/**\n * theokit start — production server orchestration spine.\n *\n * T4.2 (architecture-cleanup, ADR-0017): stages extracted to sibling modules.\n * - start-bootstrap-stages.ts — config/registry/storage bootstrap + resolveSsrEntry\n * - start-manifest-loader.ts — manifest.json or scan fallback\n * - start-ssr-setup.ts — SSR entry-server + HTML template split\n * - start-handlers.ts — branch handlers (action/route/static/404)\n * - start-request-handler.ts — request lifecycle wiring\n * - start-websocket-handler.ts — WS upgrade (opt-in)\n * - start-graceful-shutdown.ts — SIGTERM/SIGINT drain\n */\n\nimport { existsSync, readFileSync } from 'node:fs'\nimport { createServer } from 'node:http'\nimport { join, resolve } from 'node:path'\n\nimport { loadConfig } from '../../../config/load-config.js'\nimport { loadEnv } from '../../../config/load-env.js'\nimport { resolvePluginSpecifiers } from '../../../config/resolve-plugin-specifiers.js'\nimport { initCacheEngineFromConfig } from '../../../server/cache-bootstrap.js'\nimport { createCronScheduler } from '../../../server/cron/cron-runtime-node.js'\nimport { defineHealthRoute } from '../../../server/define/health-route.js'\nimport { createCorsHandler } from '../../../server/http/cors.js'\nimport { createObservabilityPluginFromConfig } from '../../../server/observability-bootstrap.js'\nimport { createPluginRunnerFromConfig } from '../../../server/plugins/load-plugins.js'\nimport { createRouteRateLimiter } from '../../../server/rate-limit/rate-limit-per-route.js'\nimport { createProductionLoader } from '../../../server/scan/module-loader.js'\nimport { resolveTransformer } from '../../../server/transformer.js'\nimport { preflightNodeAndBindings } from '../../preflight-node-version.js'\nimport { CONTROLLER_MANIFEST_FILE } from '../build/emit-controllers.js'\n\nimport { assertSdkCompatible } from './assert-sdk-compatible.js'\nimport {\n configureAgentRegistryFromConfig,\n configureStorageManagerFromConfig,\n} from './bootstrap-stages.js'\nimport { loadCronDefinitions } from './cron-bootstrap.js'\nimport { installGracefulShutdown } from './graceful-shutdown.js'\nimport type { RequestHandlerCtx } from './handlers.js'\nimport { loadRoutesAndActions } from './manifest-loader.js'\nimport { assessPublicExposure } from './public-exposure-gate.js'\nimport { createRequestHandler } from './request-handler.js'\nimport { describeListenTarget, resolveListenTarget } from './resolve-listen-host.js'\nimport { loadAssetsMap, setupSsr } from './ssr-setup.js'\nimport { attachWebSocketHandler } from './websocket-handler.js'\n\n// Backwards-compat: external test fixtures may import resolveSsrEntry from here.\nexport { resolveSsrEntry } from './bootstrap-stages.js'\n\ninterface StartOptions {\n port?: number\n}\n\nexport async function startCommand(options: StartOptions): Promise<void> {\n const cwd = process.cwd()\n // Preflight (FIRST — BEFORE anything that touches native bindings).\n preflightNodeAndBindings(cwd)\n loadEnv({ cwd, mode: 'production' })\n const config = await loadConfig(cwd)\n\n // M48 — fail fast if the installed @theokit/sdk is present but incompatible (before serving any\n // request). Absent SDK stays silent here (an api-only app is valid); the request path guards it lazily.\n assertSdkCompatible()\n\n await configureAgentRegistryFromConfig(config.agents?.registry)\n await configureStorageManagerFromConfig(config.storage)\n // #352 — without this, `revalidateTag` / `revalidatePath` / `updateTag` throw\n // in every application: they resolve the engine from a singleton nothing\n // initialized.\n await initCacheEngineFromConfig(config.cache)\n\n const distDir = resolve(cwd, '.theokit')\n const clientDir = resolve(distDir, 'client')\n // B-035 — the route-to-chunks map `theokit build` emits. Read ONCE: it is a build artifact,\n // so a per-request read would be a syscall per request for a value that cannot change.\n // A build that predates the map, or a malformed one, serves without preloads rather than\n // failing to boot — the page is correct either way and only loses one round trip.\n const assetsMap = loadAssetsMap(resolve(clientDir, 'assets-map.json'))\n // theokit#123 — compiled controllers, when `theokit build` emitted any.\n //\n // Keyed on the MANIFEST rather than on the directory existing: a stale `dist/controllers` left by\n // an earlier build whose sources were since deleted would otherwise keep serving routes the app\n // no longer declares. `theokit build` writes the manifest only when it compiles something, and\n // `cleanOutDir` removes both, so the manifest is the authoritative \"this build has controllers\".\n const controllersDistDir = existsSync(resolve(distDir, CONTROLLER_MANIFEST_FILE))\n ? resolve(distDir, 'controllers')\n : undefined\n // #95 — honor config `serverDir` (default \"server\") in production start, matching dev.\n const serverDir = resolve(cwd, config.serverDir)\n\n if (!existsSync(clientDir)) {\n throw new Error('No build found. Run `theo build` first.')\n }\n\n const indexHtml = readFileSync(join(clientDir, 'index.html'), 'utf-8')\n const loadModule = createProductionLoader()\n // `PORT` is what every container platform injects, and `theo start` read only\n // the config — so an image told to listen on the platform's port listened on\n // 3000 instead, and the platform's health check found nothing\n // (usetheokit/theokit#402). Explicit flag beats environment beats config: the\n // flag is a person typing now, the environment is where the process was put.\n const envPort = Number.parseInt(process.env.PORT ?? '', 10)\n const port = options.port ?? (Number.isInteger(envPort) ? envPort : undefined) ?? config.port\n // #353 — observability is registered FIRST when configured, so its span brackets\n // the user's own hooks. The honest cost of one ordered list: its `onResponse`\n // also runs first, so the span closes just before the tail of the chain. Head\n // coverage matters more — auth and rate-limit hooks live there.\n const observabilityPlugin = createObservabilityPluginFromConfig(config.observability, process.env)\n // #425 — a `plugins` entry MAY be a module specifier, so the same declaration the build bakes\n // into a deployed entry is the one this server registers. Constructed plugins pass through.\n const declaredPlugins = await resolvePluginSpecifiers(config.plugins ?? [], cwd)\n const pluginRunner = await createPluginRunnerFromConfig(\n observabilityPlugin === undefined ? declaredPlugins : [observabilityPlugin, ...declaredPlugins],\n )\n const transformer = resolveTransformer(config.serialization)\n\n const custom404Path = join(clientDir, '404.html')\n const custom500Path = join(clientDir, '500.html')\n const custom404Html = existsSync(custom404Path) ? readFileSync(custom404Path, 'utf-8') : null\n const custom500Html = existsSync(custom500Path) ? readFileSync(custom500Path, 'utf-8') : null\n\n const {\n routes: cachedRoutes,\n actions: cachedActions,\n wsRoutes: cachedWsRoutes,\n agents: cachedAgents,\n } = loadRoutesAndActions(distDir, serverDir, config.agentsDir, cwd)\n\n // `createRouteRateLimiter` accepts BOTH config shapes — it detects the legacy flat form and\n // treats it as the default bucket — so one call covers everything the schema allows.\n //\n // The previous code built a limiter only for the flat shape, on the belief that the per-route\n // variant was handled by an api-middleware path. No such path runs under `theokit start`, so a\n // per-route config produced `null` here and `handlers.ts` skipped limiting on every request. The\n // app booted clean, the config validated, and nothing was ever limited — see\n // usetheokit/theokit#321. A config that validates and then does nothing is worse than one that\n // fails loudly, because the operator has no reason to look.\n const rateLimiter = config.rateLimit ? createRouteRateLimiter(config.rateLimit) : null\n\n const ssr = await setupSsr({\n distDir,\n indexHtml,\n ssrConfigEnabled: config.ssr,\n ssrStreamingConfig: config.ssrStreaming,\n })\n\n const server = createServer(\n createRequestHandler({\n buildCtx: (req, res, requestId, startTime): RequestHandlerCtx => ({\n req,\n res,\n url: req.url ?? '/',\n requestId,\n startTime,\n clientDir,\n custom404Html,\n cachedRoutes,\n cachedActions,\n cachedAgents,\n loadModule,\n serverDir,\n projectRoot: cwd,\n controllersDistDir,\n pluginRunner,\n transformer,\n csrfMode: config.security?.csrf ?? 'strict',\n disallowed: config.security?.disallowed,\n rateLimiter,\n }),\n securityHeadersConfig: config.security?.headers ?? {},\n // #409 — built once at startup, like the security headers beside it. Declaring `cors` and\n // being served by this command used to mean no CORS at all, which reads in a browser as a\n // blocked fetch and in the config as a setting that is present and validated.\n corsHandler: config.security?.cors ? createCorsHandler(config.security.cors) : null,\n ssrRender: ssr.render,\n ssrRenderStreaming: ssr.renderStreaming,\n ssrStreamingEnabled: ssr.streamingEnabled,\n htmlHead: ssr.htmlHead,\n htmlTail: ssr.htmlTail,\n assetsMap,\n indexHtml,\n custom500Html,\n // M7-2: serve a built-in liveness route on the Node listener. Readiness\n // probe wiring from theo.config.ts is a documented follow-up (see the M7\n // implementation summary § Scope note).\n reservedRoutes: { health: defineHealthRoute() },\n }),\n )\n\n await attachWebSocketHandler(server, cachedWsRoutes, loadModule)\n\n // theokit#324: `theokit build --target node` announces an in-process\n // scheduler here. Drive it, or the announcement is false.\n const cronDefinitions = await loadCronDefinitions(resolve(distDir, 'crons.json'), cwd, loadModule)\n if (cronDefinitions.length > 0) {\n createCronScheduler(cronDefinitions).start()\n }\n\n // `config.host` was never passed here, and `listen(port)` with no address binds\n // every interface — so the server listened wider than its own configuration,\n // whose default says `localhost`. Passing it broke containers, where `localhost`\n // means nobody, so `HOST` now gets a say (usetheokit/theokit#402).\n const listenTarget = resolveListenTarget(config.host)\n\n // Deciding WHERE to listen settled reachability; this settles consequence. The refusal happens\n // BEFORE `listen` because a server that binds and then complains has already accepted the first\n // request — the log entry would arrive after the exposure it describes.\n const exposure = assessPublicExposure({\n routes: cachedRoutes,\n target: listenTarget,\n allowUnauthenticatedWrites: config.security?.allowUnauthenticatedWrites ?? false,\n // `cachedRoutes` comes from the file-route scan and never describes controllers. Without this\n // the gate reads an empty table as \"nothing is exposed\" and binds a public interface in silence,\n // while a controller marked `theokit:public` on a POST sits on it (theokit#543).\n hasControllers: controllersDistDir !== undefined,\n })\n if (exposure.kind === 'refused') {\n console.error(`\\n ${exposure.message}\\n`)\n // Non-zero: an orchestrator restarting this container must see a failure, not a clean exit that\n // reads as \"the process decided to stop\" (docs/adr/0002 — an abnormal ending is never reported\n // as normal).\n process.exitCode = 1\n return\n }\n if (exposure.kind === 'unverified') {\n console.warn(`\\n ${exposure.message}\\n`)\n }\n\n server.listen(port, listenTarget.host, () => {\n console.log(`\\n Theo production server`)\n // The line states the bound address, because it used to print `localhost`\n // either way — so a container serving everyone and one serving nobody were\n // indistinguishable in the log.\n console.log(`${describeListenTarget(listenTarget, port)}\\n`)\n if (exposure.kind === 'allowed-by-override') {\n // The override permits the exposure; it does not make it quiet. Each start names what is\n // open, so `allowUnauthenticatedWrites: true` cannot be forgotten in a config nobody reopens.\n const n = exposure.exposures.length\n console.warn(\n ` security.allowUnauthenticatedWrites is on — ${String(n)} unauthenticated write ${n === 1 ? 'route is' : 'routes are'} reachable:`,\n )\n for (const e of exposure.exposures) console.warn(` ${e.method} ${e.routePath}`)\n console.warn('')\n }\n if (cronDefinitions.length > 0) {\n console.log(` Crons: ${String(cronDefinitions.length)} scheduled in-process\\n`)\n }\n })\n\n installGracefulShutdown(server)\n}\n","import { CronExpressionParser } from 'cron-parser'\n\nimport { generateNewTraceContext } from '../observability/trace-context-propagation.js'\n\nimport type { CronContext, CronDefinition } from './cron-types.js'\n\n/**\n * In-memory cron scheduler for `theokit dev` (T1.4).\n *\n * Algorithm:\n * - For each cron, compute `nextFireAt = cron-parser.next()`.\n * - Schedule a `setTimeout(handler, nextFireAt - now)`.\n * - After handler invocation (sync return or Promise scheduled), recompute\n * next fire from CURRENT time (drift-free vs scheduled time).\n *\n * Per-cron isolation (EC-109):\n * - Each cron's handler invocation is fire-and-forget (`void` scheduled).\n * A hanging handler does NOT block the scheduler loop nor other crons.\n * - `concurrency: 'forbid'` (default) tracks an in-flight flag per-cron;\n * subsequent ticks skip + warn while the in-flight flag is set.\n * - `concurrency: 'allow'` runs handlers concurrently — caller's responsibility.\n *\n * Production deploys use platform-native triggers (T1.5 adapter translators);\n * this scheduler exists only for local dev iteration.\n */\n\nexport interface CronScheduler {\n start(): void\n stop(): void\n}\n\ninterface CronJobState {\n readonly def: CronDefinition\n inFlight: boolean\n timer: NodeJS.Timeout | null\n abortController: AbortController | null\n}\n\nexport function createCronScheduler(definitions: readonly CronDefinition[]): CronScheduler {\n const states: CronJobState[] = definitions.map((def) => ({\n def,\n inFlight: false,\n timer: null,\n abortController: null,\n }))\n\n let started = false\n\n const fireAndReschedule = (state: CronJobState, scheduledAt: Date): void => {\n state.timer = null\n\n if (state.inFlight && state.def.concurrency === 'forbid') {\n console.warn(\n `[theokit:cron] \"${state.def.name}\" skipped tick at ${scheduledAt.toISOString()} ` +\n '— previous handler still running (concurrency: forbid).',\n )\n scheduleNext(state)\n return\n }\n\n state.inFlight = true\n state.abortController = new AbortController()\n const traceCtx = generateNewTraceContext()\n const ctx: CronContext = {\n traceId: traceCtx.trace_id,\n scheduledAt,\n signal: state.abortController.signal,\n }\n\n // Fire-and-forget: EC-109 — never await here so a hanging handler\n // can't block the scheduler loop or other crons.\n void Promise.resolve()\n .then(() => state.def.handler(ctx))\n .catch((err: unknown) => {\n console.error(\n `[theokit:cron] \"${state.def.name}\" handler error:`,\n err instanceof Error ? err.message : err,\n )\n })\n .finally(() => {\n state.inFlight = false\n })\n\n scheduleNext(state)\n }\n\n const scheduleNext = (state: CronJobState): void => {\n if (!started) return\n const interval = CronExpressionParser.parse(state.def.schedule, {\n tz: 'UTC',\n currentDate: new Date(),\n })\n const next = interval.next().toDate()\n const delayMs = Math.max(0, next.getTime() - Date.now())\n state.timer = setTimeout(() => {\n fireAndReschedule(state, next)\n }, delayMs)\n // setTimeout returns a Timeout object; in Node, .unref() is available but\n // we DO want this to keep the event loop alive in dev — explicit no-unref.\n }\n\n return {\n start(): void {\n if (started) return\n started = true\n for (const state of states) {\n scheduleNext(state)\n }\n },\n stop(): void {\n started = false\n for (const state of states) {\n if (state.timer) {\n clearTimeout(state.timer)\n state.timer = null\n }\n state.abortController?.abort()\n state.abortController = null\n }\n },\n }\n}\n","/**\n * M7-2 — health/ready reserved routes for the convention/filesystem-route\n * server. Liveness (`/__theo/health`, always 200) and readiness\n * (`/__theo/ready`, 200/503 from a probe) are registered on a reserved\n * namespace BEFORE the user-route catch-all + 404 branch, which is why a user\n * route can never shadow them. Liveness and readiness are kept\n * separate by design: liveness says \"the process is up\", readiness says\n * \"dependencies are up\".\n *\n * @public\n */\n\n/** Reserved path for the liveness endpoint. */\nexport const HEALTH_PATH = '/__theo/health'\n/** Reserved path for the readiness endpoint. */\nexport const READY_PATH = '/__theo/ready'\n\n/** Config produced by {@link defineHealthRoute}. */\nexport interface HealthRouteConfig {\n readonly kind: 'health'\n /** Returns the liveness body (auto-serialized to JSON). Default: `{ status: 'ok' }`. */\n readonly handler: () => unknown\n}\n\n/** Config produced by {@link defineReadyRoute}. */\nexport interface ReadyRouteConfig {\n readonly kind: 'ready'\n /** Resolves `true` when dependencies are ready. A throw/reject is treated as not-ready (503). */\n readonly probe: () => boolean | Promise<boolean>\n}\n\n/** The reserved-route registry consulted by {@link serveReservedRoute}. */\nexport interface ReservedRoutes {\n readonly health?: HealthRouteConfig\n readonly ready?: ReadyRouteConfig\n}\n\n/** A reserved-route response: an HTTP status + a JSON-serializable body. */\nexport interface ReservedResponse {\n readonly status: number\n readonly body: unknown\n}\n\n/**\n * Define the liveness route. The default handler returns `{ status: 'ok' }`.\n * Liveness is always 200 — it asserts the process is up, not that dependencies are.\n */\nexport function defineHealthRoute(\n handler: () => unknown = () => ({ status: 'ok' }),\n): HealthRouteConfig {\n return { kind: 'health', handler }\n}\n\n/**\n * Define the readiness route. The `probe` decides 200 (ready) vs 503 (not-ready).\n * A probe that throws/rejects is treated as not-ready (503) — never a 500 crash.\n */\nexport function defineReadyRoute(probe: () => boolean | Promise<boolean>): ReadyRouteConfig {\n return { kind: 'ready', probe }\n}\n\n/**\n * Pure dispatcher: map a request pathname to a reserved-route response, or\n * `null` when the path is not reserved (so the user catch-all + 404 take over).\n * Liveness defaults to 200 `{status:'ok'}`; readiness without a probe is\n * trivially ready (200). Registered BEFORE the user catch-all by the caller.\n */\nexport async function serveReservedRoute(\n pathname: string,\n routes: ReservedRoutes = {},\n): Promise<ReservedResponse | null> {\n if (pathname === HEALTH_PATH) {\n const handler = routes.health?.handler ?? (() => ({ status: 'ok' }))\n return { status: 200, body: handler() }\n }\n if (pathname === READY_PATH) {\n const probe = routes.ready?.probe\n if (probe === undefined) {\n return { status: 200, body: { status: 'ready' } }\n }\n try {\n const ready = await probe()\n return ready\n ? { status: 200, body: { status: 'ready' } }\n : { status: 503, body: { status: 'not-ready' } }\n } catch (err) {\n // 503 (the dependency is not ready) but NEVER swallow the cause — a\n // readiness probe failing silently is invisible to ops (project rule:\n // \"NEVER swallow exceptions\"). Log the cause, keep the 503 contract.\n console.error('[theo] readiness probe threw — treating as not-ready', err)\n return { status: 503, body: { status: 'not-ready' } }\n }\n }\n return null\n}\n","import type { IncomingMessage } from 'node:http'\n\n/**\n * Resolves the address a rate-limit bucket should be keyed on.\n *\n * ## Why this is not just `req.socket.remoteAddress`\n *\n * Behind any reverse proxy — Caddy, nginx, a load balancer, an ingress controller — the socket\n * address is the PROXY's, identical for every visitor on the internet. Keying buckets on it gives\n * the whole world one shared budget, so the first few requests each minute exhaust it and everyone\n * else is refused. That is worse than no limiting: a limit meant to stop one abusive client becomes\n * a denial of service any single client can trigger for everybody.\n *\n * ## Why it is opt-in\n *\n * `x-forwarded-for` is a request header, and a request header is whatever the client typed. Reading\n * it without being told to would let anyone bypass the limiter by rotating a forged value — a\n * one-line `curl -H`. So the default is to trust nothing and use the socket.\n *\n * ## Why the RIGHTMOST entry\n *\n * Each proxy APPENDS the address that connected to it. A client that sends `x-forwarded-for: 1.2.3.4`\n * through one proxy produces `1.2.3.4, <real client>` — the forgery lands on the left, and the entry\n * the trusted proxy wrote is last. Counting from the right therefore skips exactly the hops the\n * operator vouched for, and everything a client can influence stays to the left of where we look.\n *\n * This mirrors the `'trusted-proxy'` policy in `adapters/web-shim.ts`, which documents the same rule\n * for the Web-Request runtimes.\n */\n\n/**\n * How many proxies sit in front of the app.\n *\n * `false` (the default) trusts nothing and uses the socket address. `true` means one trusted proxy.\n * A number names the hop count for a longer chain — a CDN in front of your own proxy is `2`.\n */\nexport type TrustProxy = boolean | number\n\n/** `true` is shorthand for a single proxy; `false` for none. A number passes through. */\nfunction hopCount(trustProxy: TrustProxy): number {\n if (trustProxy === true) return 1\n if (trustProxy === false) return 0\n return trustProxy\n}\n\n/** Reads a header that Node may hand back as an array. */\nfunction headerValue(req: IncomingMessage, name: string): string | undefined {\n const raw = req.headers[name]\n if (Array.isArray(raw)) return raw[raw.length - 1]\n return raw\n}\n\n/**\n * The forwarded-header half of the decision, with no runtime in it.\n *\n * Extracted (usetheokit/theokit#612) so the Node path and the Web path cannot drift: a `Request`\n * has the same headers and no socket, and the arithmetic on those headers is the part that is easy\n * to get subtly wrong twice. What the two runtimes genuinely disagree about — where the fallback\n * address comes from — stays with each caller.\n *\n * @param header the raw `x-forwarded-for` value, if present\n * @param realIpHeader the raw `x-real-ip` value, if present\n * @param trustProxy how many proxies the operator vouched for\n * @returns the address to key on, or `undefined` when no trusted entry could be read\n *\n * Module-private: the two exported resolvers below are the whole surface, and a caller holding\n * the raw header arithmetic would be re-deciding the part that is easy to get wrong.\n */\nfunction addressFromForwardedHeaders(\n header: string | undefined,\n realIpHeader: string | undefined,\n trustProxy: TrustProxy,\n): string | undefined {\n const hops = hopCount(trustProxy)\n if (hops < 1) return undefined\n\n if (header) {\n const entries = header\n .split(',')\n .map((entry) => entry.trim())\n .filter(Boolean)\n\n // Count in from the right by the number of hops the operator vouched for. A chain shorter than\n // configured means a request did NOT come through the expected proxies — a direct hit on the\n // app's port, say — so we report nothing rather than reading an entry the client could have\n // written.\n const index = entries.length - hops\n if (index >= 0 && index < entries.length) return entries[index]\n }\n\n // `x-real-ip` carries a single address and is written by the proxy, not appended to, so there is\n // no hop arithmetic to do. Only consulted when a proxy is trusted at all.\n const realIp = realIpHeader?.trim()\n return realIp === undefined || realIp === '' ? undefined : realIp\n}\n\nexport function resolveClientIp(req: IncomingMessage, trustProxy: TrustProxy = false): string {\n // `req.socket` is typed as always-present in Node typings; the optional chain keeps the fallback\n // reachable for test doubles built as plain object literals.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- defensive for test doubles\n const socketAddress = req.socket?.remoteAddress ?? 'unknown'\n\n return (\n addressFromForwardedHeaders(\n headerValue(req, 'x-forwarded-for'),\n headerValue(req, 'x-real-ip'),\n trustProxy,\n ) ?? socketAddress\n )\n}\n\n/**\n * The Web-`Request` twin of {@link resolveClientIp}.\n *\n * There is no socket to fall back to, so the answer is `undefined` when no trusted proxy wrote an\n * address. A caller MUST treat that as \"cannot identify\" rather than substituting a constant:\n * bucketing every visitor under one placeholder turns a rate limiter into a shared budget the first\n * caller each window exhausts for the whole internet.\n */\nexport function resolveClientIpFromRequest(\n request: Request,\n trustProxy: TrustProxy = false,\n): string | undefined {\n return addressFromForwardedHeaders(\n request.headers.get('x-forwarded-for') ?? undefined,\n request.headers.get('x-real-ip') ?? undefined,\n trustProxy,\n )\n}\n","// T5a.1d — Web Crypto migration. The last node:crypto consumer in server/.\n// `createHash('sha256')` is sync but Web Crypto's `subtle.digest('SHA-256', ...)`\n// is async. This propagates through hashFragment → deriveKey → the factory's\n// returned checker, which is why the checker is async. `theokit start` awaits it\n// (usetheokit/theokit#321 — before that fix this factory had no production consumer at all, and a\n// per-route config silently disabled rate limiting outright). IncomingMessage stays as a type-only\n// import (TS-erased; runtime-clean).\nimport type { IncomingMessage } from 'node:http'\n\nimport { parseCookieHeader } from '../http/cookies.js'\n\nimport { resolveClientIp, type TrustProxy } from './client-ip.js'\nimport { InMemoryStore, type RateLimitStore } from './rate-limit-store.js'\nimport type { RateLimitConfig, RateLimitResult } from './rate-limit.js'\n\n/**\n * T2.2 — Per-route + per-user rate limiting.\n *\n * Layered on top of `rate-limit-store.ts`. The route map allows\n * declarative policies (\"strict /api/login, loose everything else\")\n * driven by config, not handler-decorated. `keyBy` selects what\n * identifier the limiter buckets on.\n *\n * ADR D2: per-route via path matching, NOT per-handler decorator.\n * Operators can tune policies without touching route definitions.\n */\n\nexport type KeyByMode = 'ip' | 'session' | 'user' | ((req: IncomingMessage) => string)\n\nexport interface RouteRateLimitConfig {\n /** Fallback config used when no per-route entry matches. */\n default?: RateLimitConfig\n /** Map of path pattern → config. Exact-string keys (RegExp via API). */\n routes?: Record<string, RateLimitConfig>\n /** Same as `routes` but each entry is a [pattern, config] tuple, RegExp allowed. */\n routePatterns?: readonly [string | RegExp, RateLimitConfig][]\n /** Bucket identifier strategy. Default 'ip'. */\n keyBy?: KeyByMode\n /** Cookie name used by keyBy='session'. Defaults to 'theo_session'. */\n cookieName?: string\n /** Optional shared store (for multi-route correlation). Default per-limiter InMemoryStore. */\n store?: RateLimitStore\n /**\n * How many reverse proxies sit in front of the app, for `keyBy: 'ip'`. Default `false` — trust\n * none and key on the socket address.\n *\n * Set this whenever the app is behind Caddy, nginx, a load balancer or an ingress controller:\n * without it every visitor keys on the proxy's address and shares one bucket, so a handful of\n * requests exhausts the budget for the entire internet. With it, the client address is read from\n * `x-forwarded-for` counting in from the right, past exactly the hops declared here.\n *\n * Leaving it off by default is deliberate — `x-forwarded-for` is client-writable, and honouring it\n * uninvited turns the limiter into a one-header bypass. See `client-ip.ts`.\n */\n trustProxy?: TrustProxy\n}\n\n/**\n * Normalize a path for matching: strip query string, drop trailing slash\n * unless root. EC-5: `/api/login` and `/api/login/` collapse to the same\n * canonical form so attackers can't bypass strict limits.\n */\nfunction normalizePath(input: string): string {\n const noQuery = input.split('?')[0]\n if (noQuery.length > 1 && noQuery.endsWith('/')) return noQuery.slice(0, -1)\n return noQuery\n}\n\n/**\n * Test whether `path` matches `pattern`. String patterns are compared\n * after trailing-slash normalization (EC-5). RegExp uses `.test` after\n * resetting `lastIndex` (defensive against `/g` flag).\n */\nexport function matchRoutePattern(path: string, pattern: string | RegExp): boolean {\n const canonical = normalizePath(path)\n if (typeof pattern === 'string') {\n return canonical === normalizePath(pattern)\n }\n pattern.lastIndex = 0\n return pattern.test(canonical)\n}\n\n/**\n * Hash a string with SHA-256 and return the first 16 base64url chars.\n * Used by `keyBy='session'` so the raw cookie value never lands in a\n * rate-limit key (which may flow into audit logs).\n *\n * T5a.1d — async via Web Crypto subtle.digest (no node:crypto). The\n * base64url encoding is done manually because btoa+url-safe transform is\n * available everywhere but `digest('base64url')` is Node-only.\n */\nasync function hashFragment(input: string): Promise<string> {\n const buf = await globalThis.crypto.subtle.digest('SHA-256', new TextEncoder().encode(input))\n const bytes = new Uint8Array(buf)\n let bin = ''\n for (const b of bytes) bin += String.fromCharCode(b)\n // eslint-disable-next-line sonarjs/slow-regex -- input is fixed-length 44 chars (SHA-256 base64), trailing '=' padding ≤ 2 chars, no ReDoS surface\n const b64url = btoa(bin).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')\n return b64url.slice(0, 16)\n}\n\n// T3.2 DRY consolidation: cookie parsing moved to ../http/cookies.ts.\n// The canonical `parseCookieHeader` returns a Map for O(1) lookup; this\n// wrapper preserves the original `readCookie(req, name)` signature so the\n// rest of the file stays untouched.\nfunction readCookie(req: IncomingMessage, name: string): string | undefined {\n return parseCookieHeader(req.headers.cookie ?? undefined).get(name)\n}\n\n/**\n * Build the rate-limit bucket key for the request based on `keyBy`.\n *\n * EC-6: session mode reads the configured `cookieName`. With the wrong\n * cookie name (e.g., default 'theo_session' but app uses 'app_session'),\n * we fall back to IP so anonymous users still get rate-limited rather\n * than sharing an empty bucket.\n */\nexport async function deriveKey(\n req: IncomingMessage,\n keyBy: KeyByMode,\n cookieName: string,\n trustProxy: TrustProxy = false,\n): Promise<string> {\n if (typeof keyBy === 'function') return keyBy(req)\n // Behind a proxy the socket address is the proxy's, the same for every visitor. `resolveClientIp`\n // returns it unchanged unless the operator declared how many proxies to trust — see its comment\n // for why reading `x-forwarded-for` uninvited would hand out a one-header bypass.\n const ip = resolveClientIp(req, trustProxy)\n switch (keyBy) {\n case 'session': {\n const cookie = readCookie(req, cookieName)\n return cookie ? `session:${await hashFragment(cookie)}` : `ip:${ip}`\n }\n case 'user': {\n const userId = (req as unknown as { user?: { id?: string } }).user?.id\n return userId ? `user:${userId}` : `ip:${ip}`\n }\n case 'ip':\n default:\n return `ip:${ip}`\n }\n}\n\n/**\n * Per-route rate limiter factory. Returns a sync checker compatible with\n * the existing api-middleware shape.\n *\n * Backwards-compatibility (ADR D2): a flat `{ windowMs, max }` config is\n * accepted and treated as `default` (no per-route variants).\n */\nexport function createRouteRateLimiter(config: RouteRateLimitConfig | RateLimitConfig) {\n // Detect legacy flat shape\n const isFlat =\n 'windowMs' in config && 'max' in config && !('default' in config) && !('routes' in config)\n const cfg: RouteRateLimitConfig = isFlat ? { default: config } : config\n\n const store = cfg.store ?? new InMemoryStore()\n // CR-005: validate store shape ONCE at construction. The previous\n // implementation ran `instanceof InMemoryStore` on every request and\n // threw at request-time if a non-InMemoryStore was passed — which\n // turned a clear config error into a runtime 500 on the first request.\n if (!(store instanceof InMemoryStore)) {\n throw new Error(\n 'createRouteRateLimiter: async RateLimitStore implementations require a dedicated async middleware path. ' +\n 'Use the InMemoryStore default for the sync facade.',\n )\n }\n const inMemoryStore = store\n const keyBy = cfg.keyBy ?? 'ip'\n const cookieName = cfg.cookieName ?? 'theo_session'\n const trustProxy = cfg.trustProxy ?? false\n\n // Build a pre-compiled list of (pattern, config) tuples for matching.\n const patternList: [string | RegExp, RateLimitConfig][] = []\n if (cfg.routes) {\n for (const [pattern, c] of Object.entries(cfg.routes)) patternList.push([pattern, c])\n }\n if (cfg.routePatterns) {\n for (const tuple of cfg.routePatterns) patternList.push(tuple)\n }\n\n return async function checkRouteRateLimit(req: IncomingMessage): Promise<RateLimitResult> {\n const url = req.url ?? ''\n let matched: RateLimitConfig | undefined\n for (const [pattern, c] of patternList) {\n if (matchRoutePattern(url, pattern)) {\n matched = c\n break\n }\n }\n const effective = matched ?? cfg.default\n if (!effective) {\n // No route match + no default → not limited.\n return { limited: false, headers: {} }\n }\n\n // Bucket key includes normalized path so /api/login and /api/login/\n // collapse to the same bucket (EC-5).\n const bucketSuffix = typeof matched === 'undefined' ? '*default*' : normalizePath(url)\n const key = `${await deriveKey(req, keyBy, cookieName, trustProxy)}|${bucketSuffix}`\n const state = inMemoryStore.incrSync(key, effective.windowMs)\n\n if (state.count > effective.max) {\n const retryAfter = Math.ceil((state.resetAt - Date.now()) / 1000)\n return {\n limited: true,\n headers: {\n 'X-RateLimit-Limit': String(effective.max),\n 'X-RateLimit-Remaining': '0',\n 'Retry-After': String(retryAfter),\n },\n }\n }\n return {\n limited: false,\n headers: {\n 'X-RateLimit-Limit': String(effective.max),\n 'X-RateLimit-Remaining': String(Math.max(0, effective.max - state.count)),\n },\n }\n }\n}\n\n/**\n * T5a.2 Phase D slice 1/3 — Web-Standards rate-limiter inputs context.\n *\n * Web `Request` has no equivalent of `req.socket.remoteAddress` (Node\n * runtime concept) or `req.user` (set by upstream middleware). The\n * Web-shaped rate-limiter requires the caller to pass these explicitly:\n *\n * - `clientIp` — resolved per-runtime (Node: `socket.remoteAddress`;\n * CF Workers: `request.headers.get('cf-connecting-ip')`; Vercel:\n * `x-forwarded-for` first hop; Bun/Deno: adapter-specific).\n * - `userId` — resolved by auth middleware (Phase D slice 3/3 ships\n * the Web-shaped session helper).\n *\n * Defaults: `clientIp = 'unknown'`, `userId = undefined` (matches the\n * IncomingMessage path's fallback semantics).\n */\nexport interface DeriveKeyRequestContext {\n clientIp?: string\n userId?: string\n}\n\n/**\n * T5a.2 Phase D slice 1/3 — Web-Standards-shaped key derivation.\n *\n * Mirror of `deriveKey(req: IncomingMessage, keyBy, cookieName)` for the\n * Web `Request` shape. Same `'ip' | 'session' | 'user'` enum cases (the\n * `function` callback case is IncomingMessage-only because the existing\n * `KeyByMode` callback type is Node-shaped; Web callers use the enum\n * cases or call a future `KeyByModeWeb` shape — out of T5a.2 Phase D scope).\n *\n * Uses `getCookieFromRequest` (Phase B slice 6/6) for session-mode cookie\n * lookup. Cookie parsing has the same CR-009 percent-encoding safety.\n */\nexport async function deriveKeyFromRequest(\n request: Request,\n keyBy: Exclude<KeyByMode, (req: IncomingMessage) => string>,\n cookieName: string,\n ctx: DeriveKeyRequestContext = {},\n): Promise<string> {\n const ip = ctx.clientIp ?? 'unknown'\n switch (keyBy) {\n case 'session': {\n // Reuse the Web cookie helper extracted in Phase B slice 6/6 so\n // CR-009 percent-encoding sanity stays consistent across paths.\n const { getCookieFromRequest } = await import('../http/cookies.js')\n const cookie = getCookieFromRequest(request, cookieName)\n return cookie ? `session:${await hashFragment(cookie)}` : `ip:${ip}`\n }\n case 'user': {\n return ctx.userId ? `user:${ctx.userId}` : `ip:${ip}`\n }\n case 'ip':\n default:\n return `ip:${ip}`\n }\n}\n\n/**\n * T5a.2 Phase D slice 1/3 — Web-Standards rate-limiter factory.\n *\n * Mirror of `createRouteRateLimiter(config)` returning a checker that\n * accepts `(request: Request, ctx?: DeriveKeyRequestContext)` instead of\n * `(req: IncomingMessage)`. Same `RouteRateLimitConfig` accepted; same\n * `keyBy` enum cases; same `InMemoryStore` constraint (CR-005 guard).\n *\n * Same returned `RateLimitResult` shape (headers + limited boolean).\n *\n * Web `Request` has no `req.url` path-only property — uses\n * `new URL(request.url).pathname + search` to derive the URL the way the\n * IncomingMessage path's `req.url ?? ''` would.\n */\nexport function createRouteRateLimiterWeb(config: RouteRateLimitConfig | RateLimitConfig) {\n const isFlat =\n 'windowMs' in config && 'max' in config && !('default' in config) && !('routes' in config)\n const cfg: RouteRateLimitConfig = isFlat ? { default: config } : config\n\n const store = cfg.store ?? new InMemoryStore()\n if (!(store instanceof InMemoryStore)) {\n throw new Error(\n 'createRouteRateLimiterWeb: async RateLimitStore implementations require a dedicated async middleware path. ' +\n 'Use the InMemoryStore default for the Web facade.',\n )\n }\n const inMemoryStore = store\n const keyBy = (cfg.keyBy ?? 'ip') as Exclude<KeyByMode, (req: IncomingMessage) => string>\n const cookieName = cfg.cookieName ?? 'theo_session'\n\n const patternList: [string | RegExp, RateLimitConfig][] = []\n if (cfg.routes) {\n for (const [pattern, c] of Object.entries(cfg.routes)) patternList.push([pattern, c])\n }\n if (cfg.routePatterns) {\n for (const tuple of cfg.routePatterns) patternList.push(tuple)\n }\n\n return async function checkRouteRateLimitWeb(\n request: Request,\n ctx: DeriveKeyRequestContext = {},\n ): Promise<RateLimitResult> {\n // Web Request guarantees absolute URL — extract path+query for pattern\n // matching (mirror of IncomingMessage's `req.url ?? ''`).\n const parsed = new URL(request.url)\n const url = `${parsed.pathname}${parsed.search}`\n let matched: RateLimitConfig | undefined\n for (const [pattern, c] of patternList) {\n if (matchRoutePattern(url, pattern)) {\n matched = c\n break\n }\n }\n const effective = matched ?? cfg.default\n if (!effective) {\n return { limited: false, headers: {} }\n }\n\n const bucketSuffix = typeof matched === 'undefined' ? '*default*' : normalizePath(url)\n const key = `${await deriveKeyFromRequest(request, keyBy, cookieName, ctx)}|${bucketSuffix}`\n const state = inMemoryStore.incrSync(key, effective.windowMs)\n\n if (state.count > effective.max) {\n const retryAfter = Math.ceil((state.resetAt - Date.now()) / 1000)\n return {\n limited: true,\n headers: {\n 'X-RateLimit-Limit': String(effective.max),\n 'X-RateLimit-Remaining': '0',\n 'Retry-After': String(retryAfter),\n },\n }\n }\n return {\n limited: false,\n headers: {\n 'X-RateLimit-Limit': String(effective.max),\n 'X-RateLimit-Remaining': String(Math.max(0, effective.max - state.count)),\n },\n }\n }\n}\n","/**\n * M48 (ecosystem-integration-guarantee) T3.2 — boot-time SDK compatibility fail-fast.\n *\n * The agent runtime is `@theokit/sdk` (G2). Today a missing / mis-versioned SDK is invisible until\n * the FIRST agent request, where `sdk-adapter.ts` yields a lazy `SDK_NOT_INSTALLED` stream event.\n * This runs at `theokit start` boot instead: if the installed SDK is present but outside the\n * supported range it throws a typed error naming found-vs-required; if it is absent (a legitimately\n * api-only app — the SDK is an OPTIONAL peer) it stays silent unless the caller marks it required.\n *\n * CLI/adapter layer → `node:*` is allowed here (unlike `server/`). The version range check itself is\n * the pure `server/agent/sdk-compat.ts` helper (one source of truth with the contract-test drift guard).\n */\nimport { readFileSync } from 'node:fs'\nimport { createRequire } from 'node:module'\n\nimport { SUPPORTED_SDK_RANGE, satisfiesSdkRange } from '../../../server/agent/sdk-compat.js'\n\n/** Typed error surfaced at boot when the installed `@theokit/sdk` is incompatible or absent-but-required. */\nexport class SdkIncompatibleError extends Error {\n readonly code = 'SDK_INCOMPATIBLE' as const\n readonly found: string | undefined\n readonly required: string\n constructor(found: string | undefined, required: string) {\n super(\n found === undefined\n ? `@theokit/sdk is required but not installed — run: pnpm add @theokit/sdk@${required}`\n : `@theokit/sdk ${found} does not satisfy the required range ${required} — run: pnpm add @theokit/sdk@${required}`,\n )\n this.name = 'SdkIncompatibleError'\n this.found = found\n this.required = required\n }\n}\n\n/** Resolve the version of the ACTUALLY-installed `@theokit/sdk`, or `undefined` when absent. */\nfunction defaultResolveSdkVersion(): string | undefined {\n try {\n const require = createRequire(import.meta.url)\n const pkgPath = require.resolve('@theokit/sdk/package.json')\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as { version?: string }\n return typeof pkg.version === 'string' ? pkg.version : undefined\n } catch {\n return undefined\n }\n}\n\n/**\n * Fail fast at boot when the installed `@theokit/sdk` is incompatible.\n *\n * - present + in range → returns (silent)\n * - present + out of range → throws {@link SdkIncompatibleError} (found + required)\n * - absent + `required !== true` → returns (api-only app; the request path still guards lazily)\n * - absent + `required === true` → throws {@link SdkIncompatibleError}\n *\n * `resolveVersion` is injectable for tests (DIP); production uses {@link defaultResolveSdkVersion}.\n */\nexport function assertSdkCompatible(opts?: {\n required?: boolean\n resolveVersion?: () => string | undefined\n}): void {\n const version = (opts?.resolveVersion ?? defaultResolveSdkVersion)()\n if (version === undefined) {\n if (opts?.required === true) throw new SdkIncompatibleError(undefined, SUPPORTED_SDK_RANGE)\n return\n }\n if (!satisfiesSdkRange(version, SUPPORTED_SDK_RANGE)) {\n throw new SdkIncompatibleError(version, SUPPORTED_SDK_RANGE)\n }\n}\n","/**\n * M48 (ecosystem-integration-guarantee) — the supported `@theokit/sdk` version range + a pure,\n * dependency-free `||`-aware caret semver check. Shared by the contract test's version-drift guard\n * (`tests/integration/contract-sdk-seam.test.ts`) and the boot-time fail-fast\n * (`cli/commands/start/assert-sdk-compatible.ts`) — one source of truth for \"which SDK theokit runs on\".\n *\n * Web-Standards discipline (G8/R3a): `server/` code uses no `node:*`. This is pure string logic.\n * Rule 9 (Don't Reinvent) trade-off (ADR D1): a small inline caret checker instead of a `semver`\n * dependency, matching the theo-ui seam's existing precedent (`contract-usetheo-ui-vite-plugin.test.ts`).\n */\n\n/** The single source of truth for the supported SDK range. Mirrors the `package.json` peer floor. */\nexport const SUPPORTED_SDK_RANGE = '^4.0.1 || ^5.0.0'\n\n// Bounded semver: three `\\d+` tuples + an optional `-tag.N` prerelease. No nested quantifiers →\n// no catastrophic backtracking; the security/detect-unsafe-regex heuristic false-positives here.\n// eslint-disable-next-line security/detect-unsafe-regex -- bounded \\d+ groups anchored by `.`/`$`, no backtracking\nconst SEMVER_RE = /^(\\d+)\\.(\\d+)\\.(\\d+)(?:-([a-z]+)\\.(\\d+))?$/\n\ninterface Semver {\n major: string\n minor: string\n patch: string\n tag: string | undefined\n pre: string | undefined\n}\n\nfunction parseSemver(value: string): Semver | null {\n const m = SEMVER_RE.exec(value)\n if (!m) return null\n return { major: m[1], minor: m[2], patch: m[3], tag: m[4], pre: m[5] }\n}\n\n/**\n * Return `true` when `version` satisfies `range`, where `range` is a `||`-joined series of caret\n * pins (e.g. `^4.0.1` or `^0.14.0 || ^1.0.0`). A version satisfies the range when it satisfies ANY\n * clause. Covers the semver subset the monorepo uses (caret pins, optional `-tag.N` prerelease);\n * no range-sets or build metadata.\n */\nexport function satisfiesSdkRange(version: string, range: string): boolean {\n return range\n .split('||')\n .map((clause) => clause.trim())\n .some((clause) => satisfiesSingleCaret(version, clause))\n}\n\nfunction satisfiesSingleCaret(version: string, range: string): boolean {\n if (!range.startsWith('^')) return false\n const pin = parseSemver(range.slice(1))\n const ver = parseSemver(version)\n if (!pin || !ver) return false\n if (pin.tag !== undefined) return satisfiesPrereleaseCaret(ver, pin)\n if (ver.tag !== undefined) return false // a prerelease never satisfies a stable caret pin\n return satisfiesStableCaret(ver, pin)\n}\n\nfunction satisfiesPrereleaseCaret(ver: Semver, pin: Semver): boolean {\n // Prerelease pin: same X.Y.Z + same tag + prerelease number >= pin's.\n if (pin.major !== ver.major || pin.minor !== ver.minor || pin.patch !== ver.patch) return false\n if (ver.tag !== pin.tag) return false\n return Number(ver.pre ?? '0') >= Number(pin.pre ?? '0')\n}\n\nfunction satisfiesStableCaret(ver: Semver, pin: Semver): boolean {\n if (pin.major !== ver.major) return false\n if (pin.major === '0') {\n // 0.X.Y caret: minor must match exactly; patch can be >=.\n if (pin.minor !== ver.minor) return false\n return Number(ver.patch) >= Number(pin.patch)\n }\n // >= 1.0.0 caret: minor can be >=, patch anything within the same/greater minor.\n if (Number(ver.minor) > Number(pin.minor)) return true\n if (Number(ver.minor) === Number(pin.minor)) return Number(ver.patch) >= Number(pin.patch)\n return false\n}\n","/**\n * Bootstrap stages extracted from `start.ts` per T4.2 (architecture-cleanup, ADR-0017).\n *\n * The full goal of T4.2 is a ≤30-LOC `startCommand` spine + 6-8 stage files. This\n * file ships the first batch: the configure-from-config bootstrap helpers + the\n * SSR entry resolver. They are stand-alone, side-effect-free at module load, and\n * already individually testable.\n *\n * Remaining stages (request-handler extraction, graceful-shutdown extraction,\n * signal-handlers extraction) are deferred to a follow-up sprint — see plan\n * ks.\n */\n\nimport { existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\n\nimport { warnOnce } from '../../../server/observability/logger.js'\n\ninterface SdkAgentRegistry {\n configure?: (opts: { maxAgents?: number; idleTimeoutMs?: number }) => void\n}\ninterface SdkModule {\n Agent?: { registry?: SdkAgentRegistry }\n}\n\n/**\n * Configure SDK's Agent.registry from `theo.config.ts > agents.registry`.\n * Lazy at boot; EC-3 sync flag flip prevents race under concurrent boot.\n * Silent no-op when registry config is absent or SDK is uninstalled.\n */\nexport async function configureAgentRegistryFromConfig(\n registryConfig: { maxAgents: number; idleTimeoutMs: number } | undefined,\n): Promise<void> {\n if (registryConfig === undefined) return\n try {\n const sdk = (await import('@theokit/sdk').catch(() => null)) as SdkModule | null\n const sdkConfigure = sdk?.Agent?.registry?.configure\n if (sdkConfigure === undefined) return\n const { configureAgentRegistryOnce } =\n await import('../../../server/agent/configure-agent-registry.js')\n configureAgentRegistryOnce(\n {\n configure: (opts) => {\n sdkConfigure(opts)\n },\n },\n registryConfig,\n )\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n warnOnce('bootstrap.agent_registry_skip', {\n event: 'bootstrap.agent_registry_skip',\n message: msg,\n })\n }\n}\n\n/**\n * Configure the StorageManager from `theo.config.ts > storage` (ADR-0007).\n * Manager enforces configure-once internally (D3); this helper bridges the\n * config to the singleton with actionable error handling.\n */\nexport async function configureStorageManagerFromConfig(storageConfig: unknown): Promise<void> {\n if (storageConfig === undefined || storageConfig === null) return\n try {\n const { getStorageManager } = await import('../../../server/storage/storage-manager.js')\n const { storageSchema } = await import('../../../config/schema.js')\n // Re-validate at boot so a malformed config from a non-Zod source\n // (test fixtures, dynamic configs) surfaces a clear error early.\n const parsed = storageSchema.parse(storageConfig)\n getStorageManager().configure(parsed)\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n warnOnce('bootstrap.storage_skip', {\n event: 'bootstrap.storage_skip',\n message: msg,\n })\n }\n}\n\nconst SSR_EXTENSIONS = ['.mjs', '.js'] as const\n\n/**\n * Resolve the SSR entry-server module path. tsup may emit `.mjs` or `.js`\n * depending on output format. Try `.mjs` first (modern default) then fall\n * back to `.js`. Returns null when neither exists — SSR stays disabled.\n *\n * Exported so unit tests can pin the resolution order without booting the\n * full CLI.\n */\nexport function resolveSsrEntry(distDir: string): string | null {\n for (const ext of SSR_EXTENSIONS) {\n const path = resolve(distDir, `server/entry-server${ext}`)\n\n if (existsSync(path)) return path\n }\n return null\n}\n","import { existsSync, readFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\n\nimport type { CronManifest } from '../../../server/cron/cron-manifest.js'\nimport type { CronDefinition } from '../../../server/cron/cron-types.js'\n\n/**\n * Reads the cron manifest `theokit build` writes and re-loads each handler so\n * `theokit start` can drive the in-process scheduler.\n *\n * The build prints \"Cron → in-process scheduler (theokit start)\" for\n * `target: node`, but nothing on the serving side ever read `dist/crons.json`\n * — the crons were declared, validated, written, and then never ran\n * (theokit#324).\n *\n * The manifest names WHICH files hold a cron; the definition itself is taken\n * from the module, which is the source `defineCron` produced. Trusting the\n * manifest's copy of the schedule would let a stale build silently run a cron\n * on the wrong cadence.\n */\nexport async function loadCronDefinitions(\n manifestPath: string,\n projectRoot: string,\n loadModule: (filePath: string) => unknown,\n): Promise<CronDefinition[]> {\n if (!existsSync(manifestPath)) return []\n\n const manifest = JSON.parse(readFileSync(manifestPath, 'utf-8')) as CronManifest\n const definitions: CronDefinition[] = []\n\n for (const entry of manifest.crons) {\n const filePath = resolve(projectRoot, entry.filePath)\n const mod = (await loadModule(filePath)) as { default?: unknown }\n const exported = mod.default\n\n if (!isCronDefinition(exported)) {\n throw new Error(\n `Cron \"${entry.name}\" declared in \"${entry.filePath}\" is missing a valid default export. ` +\n 'Expected `export default defineCron(name, { schedule, handler })`. ' +\n 'Re-run `theokit build` if the file changed since the last build.',\n )\n }\n\n definitions.push(exported)\n }\n\n return definitions\n}\n\nfunction isCronDefinition(value: unknown): value is CronDefinition {\n if (typeof value !== 'object' || value === null) return false\n const candidate = value as Record<string, unknown>\n return (\n typeof candidate.name === 'string' &&\n typeof candidate.schedule === 'string' &&\n typeof candidate.handler === 'function'\n )\n}\n","/**\n * Graceful shutdown stage for `theokit start` (T4.2 architecture-cleanup,\n * ADR-0007 D6 — SIGTERM evicts agents + drains StorageManager).\n *\n * EC-13: SIGTERM evicts agents IMMEDIATELY (no per-request drain). In-flight\n * requests get aborted mid-stream — acceptable because the platform LB\n * removed this pod from rotation BEFORE sending SIGTERM (K8s preStop hook +\n * terminationGracePeriodSeconds; same on Vercel/CF/Render).\n *\n * Re-entry guard: multiple SIGTERMs in quick succession run shutdown ONCE.\n */\n\nimport type { Server as HttpServer } from 'node:http'\n\nimport { warnOnce } from '../../../server/observability/logger.js'\n\nexport function installGracefulShutdown(server: HttpServer): void {\n let shuttingDown = false\n const shutdown = (signal: NodeJS.Signals): void => {\n if (shuttingDown) return\n shuttingDown = true\n console.log(`\\n [theokit] ${signal} received — evicting agents`)\n void (async () => {\n // Lazy-import SDK only at shutdown time to avoid forcing the dep on\n // apps that don't use agents at all.\n try {\n const sdk = (await import('@theokit/sdk').catch(() => null)) as {\n Agent?: { registry?: { evictAll?: () => Promise<void> } }\n } | null\n if (sdk?.Agent?.registry?.evictAll !== undefined) {\n await sdk.Agent.registry.evictAll()\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n warnOnce('shutdown.evict_error', {\n event: 'shutdown.evict_error',\n message: msg,\n })\n }\n // T3.1 — drain the StorageManager AFTER agent eviction. Order matters:\n // agents may still hold open pool refs while evicting; closing pools\n // first would break in-flight queries.\n try {\n const { getStorageManager } = await import('../../../server/storage/storage-manager.js')\n const manager = getStorageManager()\n await manager.dispose()\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n warnOnce('shutdown.dispose_error', {\n event: 'shutdown.dispose_error',\n message: msg,\n })\n }\n // #353 — flush telemetry LAST, so the spans covering eviction and the\n // storage drain are in the batch that leaves. Without this the exporter's\n // final buffer dies with the process, and the most interesting spans a\n // deploy produces — the ones from the shutdown itself — are the ones\n // guaranteed never to arrive.\n try {\n const { getObservabilityAdapter } =\n await import('../../../server/observability-bootstrap.js')\n await getObservabilityAdapter()?.shutdown()\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n warnOnce('shutdown.observability_error', {\n event: 'shutdown.observability_error',\n message: msg,\n })\n }\n console.log(` [theokit] shutdown complete`)\n server.close(() => {\n process.exit(0)\n })\n setTimeout(() => {\n warnOnce('shutdown.forced_exit', {\n event: 'shutdown.forced_exit',\n message: 'forced exit after 25s timeout',\n })\n process.exit(0)\n }, 25_000).unref()\n })()\n }\n process.on('SIGTERM', () => {\n shutdown('SIGTERM')\n })\n process.on('SIGINT', () => {\n shutdown('SIGINT')\n })\n}\n","/**\n * Manifest loading stage for `theokit start` (T4.2 architecture-cleanup).\n *\n * Loads pre-built manifest from `.theokit/manifest.json` if present; otherwise\n * scans server/ for routes/actions/ws at startup with a structured warn.\n */\n\nimport { existsSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\n\nimport { warnOnce } from '../../../server/observability/logger.js'\nimport type { ActionNode } from '../../../server/scan/action-scan.js'\nimport { scanServerActions } from '../../../server/scan/action-scan.js'\nimport type { AgentNode } from '../../../server/scan/agent-scan.js'\nimport { scanAgents } from '../../../server/scan/agent-scan.js'\nimport { loadManifest } from '../../../server/scan/manifest.js'\nimport type { ServerRouteNode } from '../../../server/scan/match.js'\nimport { scanServerRoutes } from '../../../server/scan/scan.js'\nimport type { WebSocketRouteNode } from '../../../server/scan/ws-scan.js'\nimport { scanWebSocketRoutes } from '../../../server/scan/ws-scan.js'\n\ninterface LoadedRoutes {\n routes: ServerRouteNode[]\n actions: ActionNode[]\n wsRoutes: WebSocketRouteNode[]\n agents: AgentNode[]\n}\n\nexport function loadRoutesAndActions(\n distDir: string,\n serverDir: string,\n // #95 follow-up — agents dir name (config `agentsDir`, default \"agents\") for the live-scan fallback.\n agentsDir = 'agents',\n // #871 — the app root, so agent paths decode against what encoded them.\n projectRoot: string = dirname(serverDir),\n): LoadedRoutes {\n const manifestPath = join(distDir, 'manifest.json')\n\n if (existsSync(manifestPath)) {\n const manifest = loadManifest(distDir, serverDir, projectRoot)\n return {\n routes: manifest.routes,\n actions: manifest.actions,\n wsRoutes: manifest.websockets,\n agents: manifest.agents,\n }\n }\n warnOnce('bootstrap.manifest_not_found', {\n event: 'bootstrap.manifest_not_found',\n message:\n 'No manifest found, scanning routes at startup. Run \"theo build\" to generate manifest.',\n serverDir,\n })\n return {\n routes: scanServerRoutes(serverDir),\n actions: scanServerActions(serverDir),\n wsRoutes: scanWebSocketRoutes(serverDir),\n // Agents live at <projectRoot>/<agentsDir>; projectRoot = serverDir's parent for the canonical layout.\n agents: scanAgents(projectRoot, agentsDir),\n }\n}\n","/**\n * Refuse to put unauthenticated write routes on a public network interface.\n *\n * `resolve-listen-host.ts` settled WHICH address gets bound and made the log say so. This settles\n * whether that address should be bound at all, given what is behind it. The two are deliberately\n * separate: one is about reachability, this one is about consequence.\n *\n * The gap it closes has a shape worth naming. ADR 0001 made every route declare who may call it and\n * stopped absence from meaning open — a real improvement, and an incomplete one, because `'public'`\n * is a declaration too. A route table where every entry says `policy('public')` passes the build\n * gate perfectly and is, in substance, a table nobody protected. Nothing downstream could tell the\n * two apart, since the policy value never left the module; `detectRoutePolicyKinds` is what made it\n * legible at scan time, and this is the first thing to act on it.\n *\n * ## What it refuses, and what it does not\n *\n * Refused: a non-loopback bind while at least one POST / PUT / PATCH / DELETE declares the literal\n * `'public'`. Those are the requests that spend money, mutate state, or send mail on the operator's\n * behalf, and an unauthenticated one reachable from a network is the shape of an open relay.\n *\n * NOT refused: public GET / HEAD / OPTIONS. Public read endpoints are ordinary — health checks,\n * catalogues, landing APIs — and a gate that fired on them would be switched off within a day. A\n * gate with a stated edge is worth more than a gate nobody runs. That means this does NOT protect\n * against a public GET that leaks data; that is authorization work the policy function must do, and\n * saying so here is cheaper than letting an operator infer a guarantee that was never offered.\n *\n * ## Why absence is not safety\n *\n * A manifest built before this existed carries no `publicMethods`, and reading that silence as\n * \"nothing is public\" would be the same defect the gate exists to prevent, one field over. The\n * verdict is `unverified`: the server still starts (an upgrade must not break a running deploy),\n * and the operator is told plainly that the check did not run and what to do about it.\n */\nimport type { ServerRouteNode } from '../../../server/scan/match.js'\n\nimport type { ListenTarget } from './resolve-listen-host.js'\n\n/**\n * Methods that change something. The rest are readable requests, out of scope by the reasoning in\n * the module docblock.\n */\nconst MUTATING_METHODS = new Set(['POST', 'PUT', 'PATCH', 'DELETE'])\n\n/** Addresses that reach only this machine. */\nconst LOOPBACK_HOSTS = new Set(['localhost', '127.0.0.1', '::1'])\n\n/** One unauthenticated write, named so the operator can go and look at it. */\nexport interface Exposure {\n readonly routePath: string\n readonly method: string\n}\n\nexport type ExposureVerdict =\n /** Bound to the loopback — nothing outside this machine can reach it, so there is nothing to judge. */\n | { readonly kind: 'not-exposed' }\n /** Public bind, and every mutating route is guarded. */\n | { readonly kind: 'allowed' }\n /** Public bind with unauthenticated writes, permitted by an explicit written decision. */\n | { readonly kind: 'allowed-by-override'; readonly exposures: readonly Exposure[] }\n /** Public bind with unauthenticated writes and no override. The server must not start. */\n | { readonly kind: 'refused'; readonly exposures: readonly Exposure[]; readonly message: string }\n /** Public bind, and the route table cannot answer the question. Starts, says so. */\n | { readonly kind: 'unverified'; readonly message: string }\n\nexport interface ExposureAssessment {\n readonly routes: readonly ServerRouteNode[]\n readonly target: ListenTarget\n /** `security.allowUnauthenticatedWrites` from theo.config.ts — an explicit, written decision. */\n readonly allowUnauthenticatedWrites: boolean\n /**\n * Whether this build emitted compiled controllers, which `routes` does not describe.\n *\n * The caller already knows: `start` resolves `dist/controllers.json` to decide whether to serve\n * them at all. Passing the fact in is what lets an empty `routes` mean two different things —\n * \"this app serves nothing\", which is safe to bind, and \"this app serves through controllers the\n * manifest does not list\", which is not judged here at all.\n *\n * `undefined` is read as unknown, not as false. Distinguishing them is the point of the field, and\n * a caller that has not been updated should not be answered with confidence it did not supply.\n */\n readonly hasControllers?: boolean\n}\n\n/** Does this address reach anything beyond this machine? */\nfunction isPubliclyBound(host: string): boolean {\n return !LOOPBACK_HOSTS.has(host.toLowerCase())\n}\n\nfunction unauthenticatedWrites(routes: readonly ServerRouteNode[]): Exposure[] {\n const found: Exposure[] = []\n for (const route of routes) {\n for (const method of route.publicMethods ?? []) {\n if (MUTATING_METHODS.has(method)) found.push({ routePath: route.routePath, method })\n }\n }\n return found\n}\n\n/**\n * Why the gate cannot judge this route table, or `null` when it can.\n *\n * Two different absences reach here, and telling them apart matters because the operator's next\n * move differs. Returning a REASON rather than a boolean is what keeps the message honest: a\n * warning that prescribes `theo build` to someone whose build is fine teaches them to ignore it.\n *\n * - `stale-manifest` — routes exist and declare mutating methods, but none carries `publicMethods`.\n * The signature of a manifest built before this check existed. Regenerating it answers the\n * question.\n *\n * - `empty-table` — the manifest describes no routes at all. Regenerating it changes nothing: the\n * scan behind that array reads `server/routes/`, and an app serving through controllers has none\n * (usetheokit/theokit#543). Measured on a nine-controller app: sixteen routes served, `routes: []`\n * written.\n *\n * This one was silently `allowed` until 2026-08-28. `.some()` on an empty array is false for both\n * questions above, so the gate concluded there was nothing to expose and bound a public interface\n * without a word — while a controller declaring `@SetMetadata('theokit:public', true)` on a POST\n * sat on it. Absence of a description is not absence of exposure, which is the sentence this whole\n * file is written around.\n */\nfunction whyCannotAnswer(\n routes: readonly ServerRouteNode[],\n hasControllers: boolean | undefined,\n): 'stale-manifest' | 'empty-table' | null {\n if (routes.length === 0) {\n // An app that serves nothing is safe to bind anywhere, and warning about it is the kind of\n // noise that gets a gate switched off. Only an empty table that is NOT the whole story warrants\n // a word — controllers present, or a caller that did not say.\n return hasControllers === false ? null : 'empty-table'\n }\n if (routes.some((r) => r.publicMethods !== undefined)) return null\n return routes.some((r) => (r.methods ?? []).some((m) => MUTATING_METHODS.has(m)))\n ? 'stale-manifest'\n : null\n}\n\nfunction unverifiedMessage(reason: 'stale-manifest' | 'empty-table', host: string): string {\n const head = `Binding ${host} without checking whether its write routes are authenticated.`\n return reason === 'stale-manifest'\n ? [\n head,\n ' This manifest predates the check and records no policy kinds. Run `theo build` to',\n ' regenerate it; until then the server starts, and this warning is the whole of what',\n ' is known about the exposure.',\n ].join('\\n')\n : [\n head,\n ' The manifest describes no routes, so there is nothing here to judge. If this app serves',\n ' through controllers, that is expected and rebuilding will not change it — the route scan',\n ' reads `server/routes/` only (usetheokit/theokit#543). Whatever your controllers mark',\n ' `theokit:public` on a POST/PUT/PATCH/DELETE is reachable from this address, and this',\n ' warning is the whole of what is known about it.',\n ].join('\\n')\n}\n\nfunction refusalMessage(exposures: readonly Exposure[], host: string): string {\n const list = exposures.map((e) => ` ${e.method} ${e.routePath}`).join('\\n')\n return [\n exposures.length === 1\n ? `Refusing to bind ${host}: 1 write route accepts unauthenticated requests.`\n : `Refusing to bind ${host}: ${String(exposures.length)} write routes accept unauthenticated requests.`,\n '',\n list,\n '',\n \" Each declares `policy('public')`, so anyone who can reach this address can call it.\",\n ' On a loopback bind that is a demo; on this one it is an open endpoint.',\n '',\n ' Resolve it one of two ways:',\n ' • give each route a real policy — `policy(({ subject }) => subject !== null)`, or',\n ' `requireOwner(subject, record.ownerId)` from `theokit/server/define`. A plugin hook',\n ' establishes `ctx.subject`; the policy reads it.',\n ' • decide otherwise, in writing: `security: { allowUnauthenticatedWrites: true }` in',\n ' theo.config.ts. The routes stay open and the startup log keeps saying so.',\n ].join('\\n')\n}\n\n/**\n * Judge a route table against the address about to be bound.\n *\n * Pure — it reads, it decides, it returns. The caller prints and exits, which keeps this testable\n * without a process and keeps the exit policy in one place.\n */\nexport function assessPublicExposure(input: ExposureAssessment): ExposureVerdict {\n if (!isPubliclyBound(input.target.host)) return { kind: 'not-exposed' }\n\n const blind = whyCannotAnswer(input.routes, input.hasControllers)\n if (blind !== null) {\n return { kind: 'unverified', message: unverifiedMessage(blind, input.target.host) }\n }\n\n const exposures = unauthenticatedWrites(input.routes)\n if (exposures.length === 0) return { kind: 'allowed' }\n if (input.allowUnauthenticatedWrites) return { kind: 'allowed-by-override', exposures }\n\n return { kind: 'refused', exposures, message: refusalMessage(exposures, input.target.host) }\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport { extname } from 'node:path'\nimport { pathToFileURL } from 'node:url'\n\nimport type { RouteSubject } from '../../../core/contracts/route-policy.js'\nimport { readAgentPolicy } from '../../../server/agent/agent-access.js'\nimport { getApprovalRegistry } from '../../../server/agent/approval-registry.js'\nimport {\n handleAgentApproval,\n isApprovalPath,\n parseApprovalAgentName,\n} from '../../../server/agent/approve-agent.js'\nimport { mountAgent } from '../../../server/agent/mount-agent.js'\nimport { resolveProvider } from '../../../server/agent/provider-resolver.js'\nimport { matchAgentAuxRoute, serveMatchedAuxRoute } from '../../../server/agent/serve-aux-routes.js'\nimport { executeAction } from '../../../server/http/action-execute.js'\nimport { dispatchControllerRequest } from '../../../server/http/controller-dispatch.js'\nimport { executeRoute } from '../../../server/http/execute.js'\nimport { createWebRequestSource } from '../../../server/http/node-request.js'\nimport { writeWebResponseToServerResponse } from '../../../server/http/node-web-adapter.js'\nimport { serveThroughPluginLifecycle } from '../../../server/http/plugin-lifecycle.js'\nimport { createAgentSubjectResolver } from '../../../server/http/resolve-agent-subject.js'\nimport { sendError } from '../../../server/http/send-response.js'\nimport { serveStaticFile } from '../../../server/http/static.js'\nimport { logRequest } from '../../../server/observability/logger.js'\nimport { findSuggestion } from '../../../server/observability/suggest.js'\nimport type { PluginRunner } from '../../../server/plugins/plugin-runner.js'\nimport type { ActionNode } from '../../../server/scan/action-scan.js'\nimport type { AgentNode } from '../../../server/scan/agent-scan.js'\nimport { matchRoute } from '../../../server/scan/match.js'\nimport type { ServerRouteNode } from '../../../server/scan/match.js'\nimport type { LoadModule } from '../../../server/scan/module-loader.js'\nimport type { CsrfMode, DisallowedConfig } from '../../../server/security/csrf.js'\nimport type { TheoTransformer } from '../../../server/transformer.js'\n\n/**\n * Load a controller module that `theokit build` already compiled — theokit#123.\n *\n * A plain dynamic `import()`, deliberately: production must not need `@swc/core`. That peer is a\n * native binary the app would otherwise carry solely to re-do work the build already did, and a\n * missing optional peer would degrade into a runtime 404 instead of a build failure.\n */\nasync function loadCompiledController(absPath: string): Promise<Record<string, unknown>> {\n return (await import(pathToFileURL(absPath).href)) as Record<string, unknown>\n}\n\n/** Response header carrying the per-request correlation id. */\nconst X_REQUEST_ID = 'x-request-id'\n\n/**\n * T6.1 (PV-7 SRP): start.ts request orchestrator decomposed into 5 focused\n * per-branch handlers. Each handler returns `true` if it handled the\n * request (response sent) so the orchestrator can stop iterating.\n *\n * The original 455-LOC monolith closed over 14+ locals; the shared shape\n * `RequestHandlerCtx` makes the dependencies explicit + reviewable.\n */\nexport interface RequestHandlerCtx {\n req: IncomingMessage\n res: ServerResponse\n url: string\n requestId: string\n startTime: number\n // Pre-loaded build artifacts\n clientDir: string\n custom404Html: string | null\n // Manifest-resolved tables\n cachedRoutes: ServerRouteNode[]\n cachedActions: ActionNode[]\n cachedAgents: AgentNode[]\n // Runtime infra\n loadModule: LoadModule\n serverDir: string\n /** App root (= `process.cwd()` at `theokit start`); mountAgent points `.theokit/` discovery here. */\n projectRoot: string\n /**\n * theokit#123 — absolute path to the COMPILED controllers emitted by `theokit build`\n * (`<distDir>/controllers`), or `undefined` when the build produced none.\n *\n * `undefined` is the routes-only app, and it must stay free: no scan, no import, no cost.\n */\n controllersDistDir: string | undefined\n pluginRunner: PluginRunner | undefined\n transformer: TheoTransformer | undefined\n csrfMode: CsrfMode\n disallowed: DisallowedConfig | undefined\n /**\n * Async because the per-route limiter hashes the session cookie with Web Crypto when\n * `keyBy: 'session'`, and `subtle.digest` is promise-based.\n */\n rateLimiter:\n | ((req: IncomingMessage) => Promise<{ limited: boolean; headers: Record<string, string> }>)\n | null\n}\n\n/**\n * The caller's identity, from the application's own `server/context.ts` — the seam every\n * `route()` already reads and no agent URL ever reached (usetheokit/theokit#365).\n *\n * Memoized per request by `createAgentSubjectResolver` and invoked only on a path this process is\n * about to answer, and only when that path's agent declares a policy.\n */\nfunction agentSubjectResolver(c: RequestHandlerCtx): () => Promise<RouteSubject | null> {\n return createAgentSubjectResolver({\n req: c.req,\n res: c.res,\n loadModule: c.loadModule,\n serverDir: c.serverDir,\n pluginRunner: c.pluginRunner,\n })\n}\n\n/** Apply rate limit; return true if request was limited (response sent). */\nasync function applyRateLimit(c: RequestHandlerCtx, method: string): Promise<boolean> {\n if (!c.rateLimiter) return false\n const check = await c.rateLimiter(c.req)\n for (const [k, v] of Object.entries(check.headers)) c.res.setHeader(k, v)\n if (check.limited) {\n sendError(c.res, 'RATE_LIMITED', 'Too many requests', 429, undefined, c.requestId)\n logRequest({\n method,\n url: c.url,\n status: 429,\n duration: Date.now() - c.startTime,\n requestId: c.requestId,\n })\n return true\n }\n return false\n}\n\n/** Branch 1: action routes (`/api/__actions/{file}/{exportName}`). */\nexport async function tryServeAction(c: RequestHandlerCtx): Promise<boolean> {\n if (!c.url.startsWith('/api/__actions/')) return false\n c.res.setHeader(X_REQUEST_ID, c.requestId)\n\n if (await applyRateLimit(c, c.req.method ?? 'POST')) return true\n\n const pathAfterPrefix = c.url.slice('/api/__actions/'.length).split('?')[0]\n const segments = pathAfterPrefix.split('/').filter(Boolean)\n if (segments.length < 2) {\n sendError(\n c.res,\n 'BAD_REQUEST',\n 'Action URL must be /api/__actions/{file}/{exportName}',\n 400,\n undefined,\n c.requestId,\n )\n logRequest({\n method: c.req.method ?? 'POST',\n url: c.url,\n status: 400,\n duration: Date.now() - c.startTime,\n requestId: c.requestId,\n })\n return true\n }\n const exportName = segments[segments.length - 1]\n const actionPath = segments.slice(0, -1).join('/')\n const action = c.cachedActions.find((a) => a.actionPath === actionPath)\n if (!action) {\n const actionPaths = c.cachedActions.map((a) => a.actionPath)\n const suggestion = findSuggestion(actionPath, actionPaths)\n const msg = suggestion\n ? `Action \"${actionPath}\" not found. Did you mean: ${suggestion}?`\n : `Action \"${actionPath}\" not found`\n sendError(c.res, 'NOT_FOUND', msg, 404, undefined, c.requestId)\n logRequest({\n method: c.req.method ?? 'POST',\n url: c.url,\n status: 404,\n duration: Date.now() - c.startTime,\n requestId: c.requestId,\n })\n return true\n }\n await executeAction(\n action.filePath,\n exportName,\n c.req,\n c.res,\n c.loadModule,\n c.serverDir,\n c.requestId,\n c.pluginRunner,\n c.csrfMode,\n c.disallowed,\n )\n logRequest({\n method: c.req.method ?? 'POST',\n url: c.url,\n status: c.res.statusCode,\n duration: Date.now() - c.startTime,\n requestId: c.requestId,\n })\n return true\n}\n\n/**\n * Branch 1.4: agent AUXILIARY routes served identically in dev + prod (M15/M16 follow-up) — agent\n * cards (`/.well-known/<name>/agent-card.json`), MCP (`/api/agents/<name>/mcp`), the pending-approvals\n * listing, the durable run stream and the two thread routes. Before this, they were dev-only, so a\n * built/deployed app 404'd them.\n *\n * theokit#400 — this branch runs for EVERY url, so it must decide ownership without converting the\n * request: `incomingMessageToWebRequest` drains the Node body stream, and a POST with a JSON body to\n * an ordinary `/api` file route then reached `parseJsonBody` with a readable that had already ended\n * and waited forever for an `'end'` that had already fired — no status, no timeout, no response.\n * `matchAgentAuxRoute` is handed a method and a url and cannot convert anything, so the ordering is\n * now a property of the signature rather than of this comment.\n *\n * usetheokit/theokit#405 — and having a match separate from the answer is what lets the plugin\n * lifecycle run here at all. It did not, in either surface: six endpoints answered without\n * `onRequest`/`onResponse`/`onError`, so an app embedding TheoKit could not observe them and the\n * observability plugin emitted no `http.request` span for the two that spend tokens. The same\n * bracket the plain agent turn uses now wraps this one, from the same function.\n */\nexport async function tryServeAgentAux(c: RequestHandlerCtx): Promise<boolean> {\n const urlPath = c.url.split('?')[0]\n const deps = {\n agents: c.cachedAgents,\n loadModule: c.loadModule,\n baseUrl: `http://${c.req.headers.host ?? 'localhost'}`,\n // M34 (#97) — the MCP aux route drives the agent (spends tokens); enforce CSRF like the run route.\n csrfMode: c.csrfMode,\n // M39 — the thread follow-up route drives the agent; resolve the key on demand.\n // theokit#328 — the thread route drives an agent, so its key follows the model too.\n resolveApiKey: (model: string | undefined, plugins?: readonly unknown[]) =>\n resolveProvider(model, { plugins }).apiKey,\n // usetheokit/theokit#365 — who is asking. Memoized and LAZY: built here, invoked only inside\n // `serveMatchedAuxRoute` and only when the matched agent declares a policy, so the application's\n // `createContext` never runs for a url this branch declines.\n resolveSubject: agentSubjectResolver(c),\n }\n\n const method = (c.req.method ?? 'GET').toUpperCase()\n const route = await matchAgentAuxRoute(method, urlPath, deps)\n if (route === null) return false\n\n c.res.setHeader(X_REQUEST_ID, c.requestId)\n await serveThroughPluginLifecycle(\n {\n source: createWebRequestSource(c.req),\n res: c.res,\n requestId: c.requestId,\n pluginRunner: c.pluginRunner,\n failureMessage: 'Agent aux handler failed',\n },\n async (request) => {\n await writeWebResponseToServerResponse(\n await serveMatchedAuxRoute(route, request, deps),\n c.res,\n )\n },\n )\n logRequest({\n method,\n url: c.url,\n status: c.res.statusCode,\n duration: Date.now() - c.startTime,\n requestId: c.requestId,\n })\n return true\n}\n\n/**\n * Branch 1.5: agent convention routes (`/api/agents/<name>`, M2). Runs BEFORE the generic `/api/*`\n * branch so a scanned `agents/<name>.ts` owns its path (parity with dev). Loads the module, resolves\n * the provider apiKey (fail-fast), and streams the M0/M1 UIMessageStream via `mountAgent`.\n */\nexport async function tryServeAgent(c: RequestHandlerCtx): Promise<boolean> {\n if (!c.url.startsWith('/api/agents/')) return false\n const urlPath = c.url.split('?')[0]\n\n // HITL approve route (`/api/agents/<name>/approve/<id>`, M4) — resolve the pending approval.\n // Handled BEFORE the agent-path exact match (the approve path never equals an `agentPath`).\n if (isApprovalPath(urlPath)) {\n c.res.setHeader(X_REQUEST_ID, c.requestId)\n if (await applyRateLimit(c, c.req.method ?? 'POST')) return true\n const method = (c.req.method ?? 'POST').toUpperCase()\n if (method !== 'POST') {\n sendError(\n c.res,\n 'METHOD_NOT_ALLOWED',\n 'Approve endpoints accept POST',\n 405,\n undefined,\n c.requestId,\n )\n logRequest({\n method,\n url: c.url,\n status: 405,\n duration: Date.now() - c.startTime,\n requestId: c.requestId,\n })\n return true\n }\n // usetheokit/theokit#405 — the approve route settles a human decision and answered with no\n // plugin lifecycle at all, so a hook that fires for every other route never fired for this one\n // and no `http.request` span was emitted for it. Same bracket as the turn below.\n await serveThroughPluginLifecycle(\n {\n source: createWebRequestSource(c.req),\n res: c.res,\n requestId: c.requestId,\n pluginRunner: c.pluginRunner,\n failureMessage: 'Approve handler failed',\n },\n async (request) => {\n // usetheokit/theokit#365 — the approve route settles a paused tool, so it answers to the\n // named agent's declared policy. The resolver is memoized and lazy: `handleAgentApproval`\n // invokes it only when the agent declares one.\n const approveAgent = c.cachedAgents.find((a) => a.name === parseApprovalAgentName(urlPath))\n const policy =\n approveAgent === undefined\n ? undefined\n : readAgentPolicy(await c.loadModule(approveAgent.filePath), approveAgent.filePath)\n const response = await handleAgentApproval(\n request,\n urlPath,\n getApprovalRegistry(),\n c.csrfMode,\n { policy, resolveSubject: agentSubjectResolver(c) },\n )\n await writeWebResponseToServerResponse(response, c.res)\n },\n )\n logRequest({\n method,\n url: c.url,\n status: c.res.statusCode,\n duration: Date.now() - c.startTime,\n requestId: c.requestId,\n })\n return true\n }\n\n const agent = c.cachedAgents.find((a) => a.agentPath === urlPath)\n if (!agent) return false // fall through to the generic /api/* branch (may 404 there)\n\n c.res.setHeader(X_REQUEST_ID, c.requestId)\n if (await applyRateLimit(c, c.req.method ?? 'POST')) return true\n\n const method = (c.req.method ?? 'POST').toUpperCase()\n if (method !== 'POST') {\n sendError(\n c.res,\n 'METHOD_NOT_ALLOWED',\n 'Agent endpoints accept POST',\n 405,\n undefined,\n c.requestId,\n )\n logRequest({\n method,\n url: c.url,\n status: 405,\n duration: Date.now() - c.startTime,\n requestId: c.requestId,\n })\n return true\n }\n\n await serveAgentTurn(c, agent, method)\n return true\n}\n\n/**\n * Serves one agent turn through the plugin lifecycle.\n *\n * Extracted from `tryServeAgent` so that function stays what its name says — a router over the\n * agent paths — while the turn itself, which is what grew a lifecycle, reads in one piece.\n */\nasync function serveAgentTurn(\n c: RequestHandlerCtx,\n agent: { filePath: string; name: string },\n method: string,\n): Promise<void> {\n // theokit#324 — the plugin lifecycle runs here too.\n //\n // This branch used to mount the agent without ever consulting the runner, so `onRequest`,\n // `onResponse` and `onError` fired for every OTHER route and never for an agent turn — leaving an\n // app embedding TheoKit with no supported place to observe or bound agent state. Reported with a repro\n // by a consumer who found it by instrumenting a hook and watching it stay silent — the failure is\n // invisible by construction, since a hook that never runs looks exactly like one with nothing to\n // say.\n //\n // The bracket itself moved to `serveThroughPluginLifecycle` when the aux and approve branches\n // needed the same one (usetheokit/theokit#405): this shape was copied twice and drifted five\n // ways, which is the argument for having one of it.\n const resolveSubject = agentSubjectResolver(c)\n\n await serveThroughPluginLifecycle(\n {\n source: createWebRequestSource(c.req),\n res: c.res,\n requestId: c.requestId,\n pluginRunner: c.pluginRunner,\n failureMessage: 'Agent handler failed',\n },\n async (request) => {\n const mod = await c.loadModule(agent.filePath)\n // theokit#326 — resolve against the model the agent declares, not by env priority.\n const apiKey = (model: string | undefined, plugins?: readonly unknown[]): string =>\n resolveProvider(model, { plugins }).apiKey\n const response = await mountAgent(mod, request, apiKey, {\n source: agent.filePath,\n csrfMode: c.csrfMode,\n projectRoot: c.projectRoot,\n // usetheokit/theokit#365 — the policy is read off `mod` inside `mountAgent`; what this\n // caller owes is the identity to judge it against. usetheokit/theokit#406 — and it is the\n // same value the run's spans are labelled with, so `source` above never reaches telemetry.\n agentName: agent.name,\n resolveSubject,\n })\n await writeWebResponseToServerResponse(response, c.res)\n },\n )\n logRequest({\n method,\n url: c.url,\n status: c.res.statusCode,\n duration: Date.now() - c.startTime,\n requestId: c.requestId,\n })\n}\n\n/** Branch 2: API routes (`/api/*` excluding actions). */\nexport async function tryServeApiRoute(c: RequestHandlerCtx): Promise<boolean> {\n if (!c.url.startsWith('/api/')) return false\n c.res.setHeader(X_REQUEST_ID, c.requestId)\n\n if (await applyRateLimit(c, c.req.method ?? 'GET')) return true\n\n const match = matchRoute(c.url, c.cachedRoutes)\n if (!match) {\n // theokit#123 — controller fall-through, mirroring the dev `api-middleware` arm.\n //\n // Before this, `theokit dev` served a decorator controller and `theokit start` 404'd it: the\n // production path has no Vite/swc transform, so an uncompiled `.controller.ts` could not load.\n // `theokit build` now emits compiled modules and this branch serves them, so the SAME app\n // answers the same routes in both. Reached only after a file-route miss, so file routes keep\n // precedence exactly as in dev.\n if (c.controllersDistDir !== undefined) {\n const handled = await dispatchControllerRequest({\n controllersDir: c.controllersDistDir,\n loadModule: loadCompiledController,\n req: c.req,\n res: c.res,\n csrfMode: c.csrfMode,\n disallowed: c.disallowed,\n requestId: c.requestId,\n // #607 — the runner this branch never received. Without it a `@Controller` route ran no\n // plugin hook at all in production: not `onRequest`, not `preHandler`, not `onResponse`,\n // not `onError`. The file-route branch below has always passed it.\n pluginRunner: c.pluginRunner,\n })\n if (handled) return true\n }\n const urlPath = c.url.split('?')[0]\n const routePaths = c.cachedRoutes.map((r) => r.routePath)\n const suggestion = findSuggestion(urlPath, routePaths)\n const msg = suggestion\n ? `API route not found: ${urlPath}. Did you mean: ${suggestion}?`\n : 'API route not found'\n sendError(c.res, 'NOT_FOUND', msg, 404, undefined, c.requestId)\n logRequest({\n method: c.req.method ?? 'GET',\n url: c.url,\n status: 404,\n duration: Date.now() - c.startTime,\n requestId: c.requestId,\n })\n return true\n }\n const method = (c.req.method ?? 'GET').toUpperCase()\n // T3.1 (ADR-0016) — context object replaces 12 positional args\n await executeRoute({\n route: match.route,\n method,\n params: match.params,\n req: c.req,\n res: c.res,\n loadModule: c.loadModule,\n serverDir: c.serverDir,\n requestId: c.requestId,\n pluginRunner: c.pluginRunner,\n transformer: c.transformer,\n csrfMode: c.csrfMode,\n disallowed: c.disallowed,\n })\n logRequest({\n method,\n url: c.url,\n status: c.res.statusCode,\n duration: Date.now() - c.startTime,\n requestId: c.requestId,\n })\n return true\n}\n\n/** Branch 3: static files (returns true if a static asset was served). */\nexport function tryServeStatic(c: RequestHandlerCtx): boolean {\n return serveStaticFile(c.req, c.res, c.clientDir)\n}\n\n/** Branch 4: custom 404 for URLs that look like missing assets. */\nexport function tryServeCustom404(c: RequestHandlerCtx): boolean {\n const urlPath = c.url.split('?')[0]\n if (c.custom404Html && extname(urlPath)) {\n c.res.writeHead(404, { 'Content-Type': 'text/html' })\n c.res.end(c.custom404Html)\n return true\n }\n return false\n}\n","/* eslint-disable security/detect-non-literal-fs-filename --\n * Static-file server. The URL path IS user-controlled, so every fs call here is guarded twice\n * before it runs: a string check that rejects a URL walking out with `..` (403), and then a\n * `realpath` check that asks the filesystem whether the target actually lives under `clientDir`.\n *\n * The second guard is not decoration. This header used to claim the string check alone was\n * authoritative, and #428 disproved it: `path.resolve` never touches the disk, so a symlink inside\n * `clientDir` sailed through it and the server returned a file from anywhere on the host. Both\n * guards are now required for that claim to hold.\n */\nimport { closeSync, fstatSync, openSync, readFileSync, realpathSync } from 'node:fs'\nimport type { IncomingMessage, ServerResponse } from 'node:http'\nimport { resolve, extname, sep } from 'node:path'\n\nconst MIME_TYPES: Record<string, string> = {\n '.html': 'text/html',\n '.js': 'application/javascript',\n '.mjs': 'application/javascript',\n '.css': 'text/css',\n '.json': 'application/json',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.svg': 'image/svg+xml',\n '.ico': 'image/x-icon',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n '.ttf': 'font/ttf',\n '.txt': 'text/plain',\n '.map': 'application/json',\n}\n\nexport function serveStaticFile(\n req: IncomingMessage,\n res: ServerResponse,\n clientDir: string,\n): boolean {\n const urlPath = (req.url ?? '/').split('?')[0]\n\n // Path traversal prevention (EC-1) — rejects a URL that walks out with `..`.\n // `sep` matters: without it `/srv/client-backup` passes as \"inside\" `/srv/client`.\n const filePath = resolve(clientDir, '.' + urlPath)\n if (filePath !== clientDir && !filePath.startsWith(clientDir + sep)) {\n res.writeHead(403)\n res.end('Forbidden')\n return true\n }\n\n // #428 — the check above is string arithmetic; `resolve` never touches the disk, so it cannot\n // see that an entry inside `clientDir` IS a file somewhere else. Ask the filesystem instead.\n // Symlinks are not banned — one that stays inside the served tree is ordinary and still served;\n // only the ones that leave are refused, and they are refused as \"not here\" rather than 403 so\n // the response does not confirm what lies outside.\n let realPath: string\n let realRoot: string\n try {\n realPath = realpathSync(filePath)\n realRoot = realpathSync(clientDir)\n } catch {\n return false // missing, unreadable, or a broken link — all \"not served\"\n }\n if (realPath !== realRoot && !realPath.startsWith(realRoot + sep)) return false\n\n // One descriptor for the type check and the bytes: re-opening by path between them is what\n // lets the file that was checked differ from the file that is served (CodeQL js/file-system-race).\n let fd: number\n try {\n fd = openSync(realPath, 'r')\n } catch {\n return false\n }\n try {\n if (!fstatSync(fd).isFile()) return false\n\n const ext = extname(filePath)\n const contentType = MIME_TYPES[ext] ?? 'application/octet-stream'\n const content = readFileSync(fd)\n\n res.writeHead(200, {\n 'Content-Type': contentType,\n 'Content-Length': content.length,\n })\n res.end(content)\n return true\n } finally {\n closeSync(fd)\n }\n}\n","/**\n * SSR setup stage for `theokit start` (T4.2 architecture-cleanup).\n *\n * Loads the SSR entry-server module if configured + builds template split\n * around the React root div. Returns null renderers when SSR is disabled.\n */\n\nimport { readFileSync } from 'node:fs'\nimport type { ServerResponse } from 'node:http'\n\nimport { findRootDiv } from '../../../core/contracts/find-root-div.js'\nimport { parseAssetsMap } from '../../../core/contracts/module-preloads.js'\n\nimport { resolveSsrEntry } from './bootstrap-stages.js'\n\nexport interface SsrRenderResult {\n html: string\n hydrationData: {\n loaderData?: unknown\n actionData?: unknown\n errors?: unknown\n }\n}\n\nexport type RenderStreamingResult = { redirect: Response } | { streaming: true } | undefined\n\nexport type SsrRender = (\n url: string,\n options?: { nonce?: string },\n) => Promise<SsrRenderResult | { redirect: Response } | string>\n\nexport type SsrRenderStreaming = (\n url: string,\n response: ServerResponse,\n options?: {\n signal?: AbortSignal\n nonce?: string\n /**\n * The template up to and including `<div id=\"root\">`, written before React\n * produces a byte. Without it the streamed response is React's output alone\n * — no `<html>`, no `<head>` (usetheokit/theokit#343).\n */\n htmlHead?: string\n /** The template after `</div>`, written after the hydration data script. */\n htmlTail?: string\n },\n) => Promise<RenderStreamingResult>\n\ninterface SsrSetupResult {\n enabled: boolean\n streamingEnabled: boolean\n render: SsrRender | null\n renderStreaming: SsrRenderStreaming | null\n htmlHead: string\n htmlTail: string\n}\n\nexport function isSsrRenderResult(value: unknown): value is SsrRenderResult {\n if (typeof value !== 'object' || value === null) return false\n if (!('html' in value)) return false\n const html = (value as Record<string, unknown>).html\n if (typeof html !== 'string') return false\n return true\n}\n\ninterface SsrEntryServer {\n render: SsrRender\n renderStreaming?: SsrRenderStreaming\n}\n\nexport async function setupSsr(opts: {\n distDir: string\n indexHtml: string\n ssrConfigEnabled: boolean\n ssrStreamingConfig: boolean | undefined\n}): Promise<SsrSetupResult> {\n const ssrServerPath: string | null = opts.ssrConfigEnabled ? resolveSsrEntry(opts.distDir) : null\n const enabled = ssrServerPath !== null\n const streamingEnabled = enabled && Boolean(opts.ssrStreamingConfig)\n\n if (ssrServerPath === null) {\n return {\n enabled: false,\n streamingEnabled: false,\n render: null,\n renderStreaming: null,\n htmlHead: '',\n htmlTail: '',\n }\n }\n\n const mod = (await import(ssrServerPath)) as SsrEntryServer\n const render = mod.render\n const renderStreaming = typeof mod.renderStreaming === 'function' ? mod.renderStreaming : null\n\n // Split HTML template on root div\n let htmlHead = ''\n let htmlTail = ''\n const rootDiv = findRootDiv(opts.indexHtml)\n if (rootDiv) {\n htmlHead = opts.indexHtml.slice(0, rootDiv.insertAt)\n htmlTail = opts.indexHtml.slice(rootDiv.insertAt)\n }\n\n return { enabled, streamingEnabled, render, renderStreaming, htmlHead, htmlTail }\n}\n\n/**\n * Read the route-to-chunks map `theokit build` emits (B-035).\n *\n * Returns `undefined` — never throws — when the file is absent or unreadable. A server that\n * refused to boot because a build predated this feature would turn a missing optimisation into an\n * outage, and the document is correct without it: it simply learns about its chunks one round trip\n * later, which is exactly the state this feature improves on.\n */\nexport function loadAssetsMap(path: string): Record<string, string[]> | undefined {\n try {\n return parseAssetsMap(readFileSync(path, 'utf8'))\n } catch {\n return undefined\n }\n}\n","/**\n * Inline request handler for `theokit start` (T4.2 architecture-cleanup).\n *\n * Wires the per-request flow: security headers → action/route/static branches\n * → SSR fallback → CSR fallback → 500 page.\n *\n * Refactored: CC reduced from 33 to ≤10 per function\n * (architecture-remediation T2.1, 2026-06-12).\n */\n\nimport type { IncomingMessage, ServerResponse } from 'node:http'\n\nimport { injectModulePreloads } from '../../../core/contracts/module-preloads.js'\nimport { generateNonce } from '../../../server/auth/nonce.js'\nimport { type ReservedRoutes, serveReservedRoute } from '../../../server/define/health-route.js'\nimport type { CorsHandler } from '../../../server/http/cors.js'\nimport { sendError } from '../../../server/http/send-response.js'\nimport { TRACE_HEADER, extractTraceId } from '../../../server/http/trace-context.js'\nimport { buildSecurityHeaders } from '../../../server/security/security-headers.js'\nimport { extractHeadTags, injectIntoHead } from '../../../vite-plugin/hoist-head-tags.js'\nimport { applyNonceToInlineScripts } from '../../../vite-plugin/ssr-dev-middleware.js'\n\nimport {\n tryServeAction,\n tryServeAgent,\n tryServeAgentAux,\n tryServeApiRoute,\n tryServeCustom404,\n tryServeStatic,\n type RequestHandlerCtx,\n} from './handlers.js'\nimport {\n isSsrRenderResult,\n type SsrRender,\n type SsrRenderResult,\n type SsrRenderStreaming,\n} from './ssr-setup.js'\n\ninterface RequestHandlerContext {\n buildCtx: (\n req: IncomingMessage,\n res: ServerResponse,\n requestId: string,\n startTime: number,\n ) => RequestHandlerCtx\n securityHeadersConfig: Parameters<typeof buildSecurityHeaders>[0]\n /**\n * #409 — `security.cors` had exactly one consumer, Vite's `configureServer` hook, so an app that\n * worked cross-origin under `theokit dev` stopped working the moment this command served it:\n * same config, same code, no error and no warning. `null` when the app declared no `cors` block,\n * which is what it meant before and still means — no headers, not permissive ones.\n */\n corsHandler: CorsHandler | null\n ssrRender: SsrRender | null\n ssrRenderStreaming: SsrRenderStreaming | null\n ssrStreamingEnabled: boolean\n htmlHead: string\n htmlTail: string\n /**\n * B-035 — the route-to-chunks relation `theokit build` emits, read ONCE at startup and never\n * per request: it is a build artifact and cannot change while the server runs. Absent when the\n * build predates the map, which serves without preloads rather than failing the request.\n */\n assetsMap?: Record<string, string[]>\n indexHtml: string\n custom500Html: string | null\n /** M7-2: reserved health/ready routes served before the user catch-all. */\n reservedRoutes?: ReservedRoutes\n}\n\n/**\n * M7-2: serve a reserved `/__theo/*` route (health/ready) before any user\n * branch. Returns true when the request was handled.\n */\nasync function tryServeReserved(\n ctx: RequestHandlerContext,\n url: string,\n res: ServerResponse,\n): Promise<boolean> {\n const pathname = new URL(url, 'http://localhost').pathname\n const reserved = await serveReservedRoute(pathname, ctx.reservedRoutes ?? {})\n if (reserved === null) return false\n const payload = JSON.stringify(reserved.body)\n res.writeHead(reserved.status, {\n 'Content-Type': 'application/json',\n 'Content-Length': Buffer.byteLength(payload),\n })\n res.end(payload)\n return true\n}\n\nfunction asSsrRenderResult(value: SsrRenderResult): SsrRenderResult {\n return value\n}\n\nfunction isRedirectResult(result: unknown): result is { redirect: Response } {\n return result !== null && typeof result === 'object' && 'redirect' in result\n}\n\nfunction sendRedirect(res: ServerResponse, result: { redirect: Response }): void {\n res.writeHead(302, { Location: result.redirect.headers.get('location') ?? '/' })\n res.end()\n}\n\nfunction send500(res: ServerResponse, custom500Html: string | null): void {\n if (!res.headersSent) {\n res.writeHead(500, { 'Content-Type': 'text/html' })\n }\n if (!res.writableEnded) {\n res.end(custom500Html ?? '<h1>500 — Server Error</h1>')\n }\n}\n\n/**\n * Moves the route's `<title>`/`<meta>`/`<link>` from the rendered body into the head.\n *\n * `ctx.htmlHead` is the template up to and including `<div id=\"root\">`, so it still contains the\n * `</head>` this injects before. Without it, a route's metadata ships inside the body and only\n * reaches the head after hydration — which never happens for a crawler that does not run\n * JavaScript, and those are exactly the ones that render social cards.\n *\n * The dev middleware does the same thing; both paths have to, or previews work in one and not the\n * other, which is worse than neither.\n */\nexport function withHoistedHead(\n htmlHead: string,\n ssrHtml: string,\n nonce: string,\n): { head: string; body: string } {\n const { html, headTags } = extractHeadTags(ssrHtml)\n\n // The nonce is stamped onto the template's own inline scripts here, per request, because the\n // nonce differs per request while `ctx.htmlHead` is computed once at startup. Without it, a CSP\n // with a nonce blocks anything the template inlines — including the theme-init script that\n // applications put in `<head>` specifically to avoid a flash of the wrong theme on load.\n const head = applyNonceToInlineScripts(injectIntoHead(htmlHead, headTags), nonce)\n return { head, body: html }\n}\n\nexport function buildSsrHtml(\n ctx: RequestHandlerContext,\n result: string | SsrRenderResult,\n nonce: string,\n url: string,\n): string {\n if (typeof result === 'string') {\n const { head, body } = withHoistedHead(ctx.htmlHead, result, nonce)\n return injectModulePreloads(head, ctx.assetsMap, url) + body + ctx.htmlTail\n }\n if (isSsrRenderResult(result)) {\n const rendered = asSsrRenderResult(result)\n const dataJson = JSON.stringify(rendered.hydrationData).replace(/</g, '\\\\u003c')\n const hydrationScript = `<script${\n nonce ? ` nonce=\"${nonce}\"` : ''\n }>window.__staticRouterHydrationData=${dataJson}</script>`\n const { head, body } = withHoistedHead(ctx.htmlHead, rendered.html, nonce)\n return injectModulePreloads(head, ctx.assetsMap, url) + body + hydrationScript + ctx.htmlTail\n }\n return applyNonceToInlineScripts(ctx.htmlHead, nonce) + ctx.htmlTail\n}\n\nasync function handleSsrStreaming(\n ctx: RequestHandlerContext,\n req: IncomingMessage,\n res: ServerResponse,\n url: string,\n nonce: string,\n): Promise<boolean> {\n if (!ctx.ssrStreamingEnabled || !ctx.ssrRenderStreaming) return false\n\n const controller = new AbortController()\n const onClose = (): void => {\n controller.abort()\n }\n req.on('close', onClose)\n try {\n const result = await ctx.ssrRenderStreaming(url, res, {\n signal: controller.signal,\n nonce,\n // #343 — the streamed response carried neither of these, so `ssrStreaming: true`\n // served a bare React tree: no `<head>`, no client entry, no hydration data.\n //\n // `applyNonceToInlineScripts` and not `withHoistedHead`: hoisting reads the\n // RENDERED body for head elements, and nothing is rendered yet when the head\n // has to flush. Metadata hoisting under streaming is the same defect on a\n // different surface, and it is M9's, not this one's.\n // B-035, found by the independent code-review audit: the preloads were wired into\n // `buildSsrHtml`, which serves the SYNCHRONOUS path only, while this branch is dispatched\n // FIRST — so `ssrStreaming: true` turned the feature off on Node while the Cloudflare\n // worker injected on its equivalent branch. The exclusion argued just above is about\n // METADATA hoisting, which needs the rendered body; a `modulepreload` link needs nothing\n // from it, so that argument does not reach here.\n htmlHead: injectModulePreloads(\n applyNonceToInlineScripts(ctx.htmlHead, nonce),\n ctx.assetsMap,\n url,\n ),\n htmlTail: ctx.htmlTail,\n })\n if (isRedirectResult(result)) sendRedirect(res, result)\n return true\n } catch (streamErr) {\n console.error('[SSR Stream Error]', (streamErr as Error).message)\n send500(res, ctx.custom500Html)\n return true\n } finally {\n req.removeListener('close', onClose)\n }\n}\n\nasync function handleSsrSync(\n ctx: RequestHandlerContext,\n res: ServerResponse,\n url: string,\n nonce: string,\n): Promise<boolean> {\n if (!ctx.ssrRender) return false\n\n try {\n const result = await ctx.ssrRender(url, { nonce })\n if (isRedirectResult(result)) {\n sendRedirect(res, result)\n return true\n }\n res.writeHead(200, { 'Content-Type': 'text/html' })\n res.end(buildSsrHtml(ctx, result, nonce, url))\n return true\n } catch (ssrErr) {\n console.error('[SSR Error] Falling back to CSR:', (ssrErr as Error).message)\n return false\n }\n}\n\nfunction handleFatalError(ctx: RequestHandlerContext, res: ServerResponse, err: unknown): void {\n if (ctx.custom500Html && !res.headersSent) {\n res.writeHead(500, { 'Content-Type': 'text/html' })\n res.end(ctx.custom500Html)\n } else if (!res.headersSent) {\n sendError(res, 'INTERNAL_ERROR', (err as Error).message, 500)\n } else {\n res.end()\n }\n}\n\nexport function createRequestHandler(\n ctx: RequestHandlerContext,\n): (req: IncomingMessage, res: ServerResponse) => void {\n return (req: IncomingMessage, res: ServerResponse) => {\n void (async () => {\n const url = req.url ?? '/'\n // #353 — production minted a fresh UUID on every request and discarded the\n // incoming W3C `traceparent`, so a trace crossing into this server started\n // over and no span could continue it. `theo dev` has honoured the header on\n // `/api/*` since Phase 7 (`vite-plugin/api-middleware.ts:368`); this is the\n // same resolution on the path a deploy actually serves.\n //\n // The tier-2 fallback (`x-request-id`) is caller-controlled and validated\n // inside `extractTraceId` before it is trusted — it ends up in the logs.\n const requestId = extractTraceId(req)\n const start = Date.now()\n // Echoed under both names, matching dev: `x-request-id` is what existing\n // consumers read, `x-trace-id` is the canonical one.\n res.setHeader('x-request-id', requestId)\n res.setHeader(TRACE_HEADER, requestId)\n\n // Preflight before anything else, and it answers rather than routing — the same order the\n // dev middleware uses (`vite-plugin/api-middleware.ts`), because an OPTIONS the router\n // handles is an OPTIONS the browser never gets a CORS answer to.\n if (ctx.corsHandler?.handlePreflight(req, res) === true) return\n ctx.corsHandler?.applyHeaders(req, res)\n\n const nonce = generateNonce()\n const securityHeaders = buildSecurityHeaders(\n ctx.securityHeadersConfig,\n { production: true },\n { nonce },\n )\n for (const [k, v] of Object.entries(securityHeaders)) {\n res.setHeader(k, v)\n }\n\n const handlerCtx = ctx.buildCtx(req, res, requestId, start)\n\n try {\n if (await tryServeReserved(ctx, url, res)) return\n if (await tryServeAction(handlerCtx)) return\n if (await tryServeAgentAux(handlerCtx)) return\n if (await tryServeAgent(handlerCtx)) return\n if (await tryServeApiRoute(handlerCtx)) return\n if (tryServeStatic(handlerCtx)) return\n if (tryServeCustom404(handlerCtx)) return\n\n if (await handleSsrStreaming(ctx, req, res, url, nonce)) return\n if (await handleSsrSync(ctx, res, url, nonce)) return\n\n // CSR fallback\n res.writeHead(200, { 'Content-Type': 'text/html' })\n res.end(ctx.indexHtml)\n } catch (err) {\n handleFatalError(ctx, res, err)\n }\n })()\n }\n}\n","/**\n * Resolve the address `server.listen` should bind, and say which it is.\n *\n * `config.host` was declared, defaulted to `'localhost'`, documented as the way to\n * open a server to the LAN, and never passed to `listen`. Node with no address\n * binds EVERY interface, so the production server listened wider than its\n * configuration said — and its default said the narrow thing.\n *\n * Fixing that broke containers, which is the second half of this story\n * (usetheokit/theokit#402). Inside a container `localhost` means *nobody*: the\n * image starts, prints a URL, and refuses every request including its own. So the\n * environment gets a say. `HOST` is the variable every container platform already\n * sets or expects to set, and honouring it costs the operator nothing to discover.\n *\n * Precedence, narrowest authority last: explicit config beats `HOST`, because a\n * value written into the project is a decision and an environment variable is a\n * deployment detail. Absent both, the loopback — binding every interface is a\n * decision someone should have to write down.\n *\n * The second export exists because the log lied. `theo start` printed `localhost`\n * whether it bound the loopback or every interface, so a container that serves\n * everyone and a container that serves nobody produced byte-identical output.\n * That is `docs/adr/0002-an-abnormal-ending-is-never-reported-as-normal.md` in the\n * startup path: the observable state must distinguish the two.\n */\n\nexport interface ListenTarget {\n /** The address handed to `server.listen`. */\n readonly host: string\n /** Where the value came from, so the log can say so rather than guess. */\n readonly source: 'config' | 'env' | 'default'\n}\n\nexport function resolveListenTarget(\n host: string | boolean | undefined,\n env: string | undefined = process.env.HOST,\n): ListenTarget {\n if (host === true) return { host: '0.0.0.0', source: 'config' }\n if (typeof host === 'string' && host !== '') return { host, source: 'config' }\n // `host: false` is an explicit \"do not open me up\" and outranks the environment.\n if (host !== false && env !== undefined && env !== '') return { host: env, source: 'env' }\n return { host: 'localhost', source: 'default' }\n}\n\n/**\n * The line `theo start` prints, given what it actually bound.\n *\n * `0.0.0.0` is not a URL a human can open, so the loopback is offered — but the\n * bound address is stated beside it, because \"every interface\" and \"this machine\n * only\" are the two states an operator most needs to tell apart, and they were\n * indistinguishable.\n */\nexport function describeListenTarget(target: ListenTarget, port: number): string {\n const url = target.host === '0.0.0.0' || target.host === '::' ? 'localhost' : target.host\n const bound =\n target.host === '0.0.0.0' || target.host === '::'\n ? `bound to ${target.host} (every interface)`\n : `bound to ${target.host} only`\n return ` → http://${url}:${String(port)} [${bound}${provenance(target.source)}]`\n}\n\n/** Where the address came from, and — when nobody chose it — what to write to change it. */\nfunction provenance(source: ListenTarget['source']): string {\n if (source === 'env') return ' from HOST'\n if (source === 'config') return ''\n return ' — set `host: true` in theo.config.ts or HOST=0.0.0.0 to reach it from outside this machine'\n}\n","/**\n * WebSocket upgrade handler for `theokit start` (T4.2 architecture-cleanup).\n *\n * Wires `server.on('upgrade')` for declared WS routes. Opt-in: only attached\n * when `wsRoutes.length > 0`. Lazy-imports `ws` package — throws an actionable\n * error when wsRoutes declared but `ws` not installed.\n */\n\nimport type { Server as HttpServer } from 'node:http'\n\nimport type * as WsLib from 'ws'\n\nimport type { WebSocketHandler } from '../../../server/define/define-websocket.js'\nimport type { LoadModule } from '../../../server/scan/module-loader.js'\nimport type { WebSocketRouteNode } from '../../../server/scan/ws-scan.js'\n\nexport async function attachWebSocketHandler(\n server: HttpServer,\n wsRoutes: WebSocketRouteNode[],\n loadModule: LoadModule,\n): Promise<void> {\n if (wsRoutes.length === 0) return\n\n let WebSocketServerCtor: typeof WsLib.WebSocketServer\n try {\n const wsModule = await import('ws')\n WebSocketServerCtor = wsModule.WebSocketServer\n } catch {\n throw new Error('WebSocket routes found but \"ws\" package is not installed. Run: npm install ws')\n }\n\n const wss = new WebSocketServerCtor({ noServer: true })\n\n server.on('upgrade', (request, socket, head) => {\n void (async () => {\n const url = request.url ?? '/'\n if (!url.startsWith('/ws/')) {\n socket.destroy()\n return\n }\n\n const wsPath = url.split('?')[0]\n const match = wsRoutes.find((r) => r.wsPath === wsPath)\n if (!match) {\n socket.destroy()\n return\n }\n\n try {\n const mod = await loadModule(match.filePath)\n const handler = ((mod as { default?: unknown }).default ?? mod) as WebSocketHandler\n\n wss.handleUpgrade(request, socket, head, (ws) => {\n handler.onOpen?.(ws, request)\n ws.on('message', (data: Buffer) => {\n handler.onMessage?.(ws, data.toString())\n })\n ws.on('close', (code: number, reason: Buffer) => {\n handler.onClose?.(ws, code, reason)\n })\n ws.on('error', (err: Error) => {\n handler.onError?.(ws, err)\n })\n })\n } catch {\n socket.destroy()\n }\n })()\n })\n}\n"],"mappings":"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","names":["existsSync","readFileSync","join","resolve","require","existsSync","readFileSync","resolve","existsSync","existsSync","extname","readFileSync","resolve","method","extname","readFileSync","readFileSync","resolve","existsSync","readFileSync","join"]}
|
/package/dist/{actions-virtual-module-2SM6YMTM.js.map → actions-virtual-module-EAKYEMGF.js.map}
RENAMED
|
File without changes
|
/package/dist/{actions-virtual-module-5LRBP6YK.js.map → actions-virtual-module-OHENNMQG.js.map}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|