theokit 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/dist/{actions-virtual-module-SQDY3V5X.js → actions-virtual-module-3CDQTWOC.js} +6 -6
  2. package/dist/{actions-virtual-module-PNPRCEOS.js → actions-virtual-module-EIPXX4ZB.js} +3 -3
  3. package/dist/adapters/web-shim.d.ts +67 -0
  4. package/dist/adapters/ws-shim.d.ts +55 -0
  5. package/dist/agent-events-DosDXkSV.d.ts +94 -0
  6. package/dist/agents-typed-client-SAWAAH7K.js +142 -0
  7. package/dist/agents-typed-client-SAWAAH7K.js.map +1 -0
  8. package/dist/agents-typed-client-UTEQUA63.js +143 -0
  9. package/dist/agents-typed-client-UTEQUA63.js.map +1 -0
  10. package/dist/{app-typed-client-5GYEOYP3.js → app-typed-client-7PBFWZUE.js} +3 -3
  11. package/dist/{app-typed-client-QG7BVZYW.js → app-typed-client-CSOK7NPC.js} +6 -6
  12. package/dist/audit-log-BQWM5YLG.d.ts +60 -0
  13. package/dist/body-parser-web-FV5HWCY3.js +71 -0
  14. package/dist/body-parser-web-FV5HWCY3.js.map +1 -0
  15. package/dist/boot/index.d.ts +39 -0
  16. package/dist/{build-QFRLSEZ4.js → build-HXND27XG.js} +11 -11
  17. package/dist/{chunk-223EFY5X.js → chunk-2J7XU3PW.js} +68 -27
  18. package/dist/chunk-2J7XU3PW.js.map +1 -0
  19. package/dist/{chunk-RESN62GB.js → chunk-2KZQPDYR.js} +5 -48
  20. package/dist/chunk-2KZQPDYR.js.map +1 -0
  21. package/dist/chunk-3S3BNW5K.js +445 -0
  22. package/dist/chunk-3S3BNW5K.js.map +1 -0
  23. package/dist/{chunk-6FYD34NX.js → chunk-BQDGES7C.js} +28 -28
  24. package/dist/{chunk-6FYD34NX.js.map → chunk-BQDGES7C.js.map} +1 -1
  25. package/dist/chunk-EXP56GFQ.js +52 -0
  26. package/dist/chunk-EXP56GFQ.js.map +1 -0
  27. package/dist/chunk-F4YUPDJ2.js +115 -0
  28. package/dist/chunk-F4YUPDJ2.js.map +1 -0
  29. package/dist/{chunk-NAZ4E2GT.js → chunk-KXA37ONC.js} +2 -2
  30. package/dist/chunk-NHJMZCAS.js +32 -0
  31. package/dist/chunk-NHJMZCAS.js.map +1 -0
  32. package/dist/{chunk-43D6XNDR.js → chunk-O62MW4MT.js} +91 -18
  33. package/dist/chunk-O62MW4MT.js.map +1 -0
  34. package/dist/chunk-RSVN727G.js +1 -0
  35. package/dist/{chunk-7CBRKNQA.js → chunk-RYTZYFSD.js} +198 -6
  36. package/dist/chunk-RYTZYFSD.js.map +1 -0
  37. package/dist/chunk-UNLA45FY.js +235 -0
  38. package/dist/chunk-UNLA45FY.js.map +1 -0
  39. package/dist/{chunk-GFMQJHXX.js → chunk-WR4F4EEZ.js} +1082 -1074
  40. package/dist/chunk-WR4F4EEZ.js.map +1 -0
  41. package/dist/{chunk-AD74EAK3.js → chunk-ZSTZXR2D.js} +1 -30
  42. package/dist/chunk-ZSTZXR2D.js.map +1 -0
  43. package/dist/cli/index.js +5 -5
  44. package/dist/client/index.d.ts +418 -0
  45. package/dist/client/index.js +84 -3
  46. package/dist/client/index.js.map +1 -1
  47. package/dist/csrf-BBrEZSBW.d.ts +107 -0
  48. package/dist/csrf-readiness-store-CjIoub3U.d.ts +43 -0
  49. package/dist/define-websocket-CdK94O-D.d.ts +64 -0
  50. package/dist/{dev-GBXOTXUP.js → dev-OWW4XVIH.js} +10 -10
  51. package/dist/{dev-emit-FEFEDLZF.js → dev-emit-5MDSBP5D.js} +3 -3
  52. package/dist/{dev-emit-O4EGOSNV.js → dev-emit-QH2YGZXN.js} +2 -2
  53. package/dist/devtools/entry.d.ts +5 -0
  54. package/dist/error-envelope-BsNzzAV5.d.ts +62 -0
  55. package/dist/health-route-C0hk64_U.d.ts +57 -0
  56. package/dist/index-B40qUSrQ.d.ts +575 -0
  57. package/dist/index.d.ts +361 -0
  58. package/dist/index.js +6 -4
  59. package/dist/index.js.map +1 -1
  60. package/dist/internal-api-4YTJDITC.js +83 -0
  61. package/dist/internal-api-EFKZWIYZ.js +66 -0
  62. package/dist/internal-api-EFKZWIYZ.js.map +1 -0
  63. package/dist/job-backend-CgC8Xf33.d.ts +68 -0
  64. package/dist/match-CfbEFRG4.d.ts +26 -0
  65. package/dist/{openapi-VR6AFBLJ.js → openapi-FHY6HC6I.js} +7 -7
  66. package/dist/plugin-runner-BGBkzgi0.d.ts +95 -0
  67. package/dist/plugin-types-DNJGxr4Z.d.ts +79 -0
  68. package/dist/rate-limit-BdNDZ3vt.d.ts +58 -0
  69. package/dist/rate-limit-store-BEJnhWdw.d.ts +72 -0
  70. package/dist/react-query/index.d.ts +33 -0
  71. package/dist/{registry-Q2TZQLUH.js → registry-34LL7NF4.js} +1 -1
  72. package/dist/{routes-LRYOIIAI.js → routes-EW7TP7NJ.js} +2 -2
  73. package/dist/schema-BpH6ivDY.d.ts +74 -0
  74. package/dist/server/agent/index.d.ts +229 -0
  75. package/dist/server/agent/index.js +2 -1
  76. package/dist/server/auth/index.d.ts +419 -0
  77. package/dist/server/cost/index.d.ts +177 -0
  78. package/dist/server/cron/index.d.ts +208 -0
  79. package/dist/server/define/index.d.ts +313 -0
  80. package/dist/server/define/index.js +4 -2
  81. package/dist/server/http/index.d.ts +11 -0
  82. package/dist/server/index.d.ts +848 -0
  83. package/dist/server/index.js +9 -294
  84. package/dist/server/index.js.map +1 -1
  85. package/dist/server/jobs/index.d.ts +348 -0
  86. package/dist/server/observability/index.d.ts +324 -0
  87. package/dist/server/plugins/index.d.ts +17 -0
  88. package/dist/server/rate-limit/index.d.ts +105 -0
  89. package/dist/server/realtime/index.d.ts +15 -0
  90. package/dist/server/scan/index.d.ts +126 -0
  91. package/dist/server/scan/index.js +1 -1
  92. package/dist/server/security/index.d.ts +193 -0
  93. package/dist/server/storage/index.d.ts +22 -0
  94. package/dist/server/webhook/index.d.ts +148 -0
  95. package/dist/{start-3ZHAXSJE.js → start-KIQ5TTLR.js} +76 -13
  96. package/dist/start-KIQ5TTLR.js.map +1 -0
  97. package/dist/storage-manager-C4jsO0Tp.d.ts +89 -0
  98. package/dist/storage-types-DsDTCPbp.d.ts +96 -0
  99. package/dist/vite-plugin/index.d.ts +115 -0
  100. package/dist/vite-plugin/index.js +6 -4
  101. package/dist/{vite-plugin-WO72VLYR.js → vite-plugin-RK66K26Z.js} +7 -7
  102. package/dist/vite-plugin-RK66K26Z.js.map +1 -0
  103. package/package.json +4 -4
  104. package/dist/chunk-223EFY5X.js.map +0 -1
  105. package/dist/chunk-3LVRAGAZ.js +0 -73
  106. package/dist/chunk-3LVRAGAZ.js.map +0 -1
  107. package/dist/chunk-43D6XNDR.js.map +0 -1
  108. package/dist/chunk-7CBRKNQA.js.map +0 -1
  109. package/dist/chunk-AD74EAK3.js.map +0 -1
  110. package/dist/chunk-GFMQJHXX.js.map +0 -1
  111. package/dist/chunk-PBEH6NXR.js +0 -44
  112. package/dist/chunk-PBEH6NXR.js.map +0 -1
  113. package/dist/chunk-PIVX3DYW.js +0 -142
  114. package/dist/chunk-PIVX3DYW.js.map +0 -1
  115. package/dist/chunk-PPPR5DGR.js +0 -1
  116. package/dist/chunk-RESN62GB.js.map +0 -1
  117. package/dist/start-3ZHAXSJE.js.map +0 -1
  118. /package/dist/{actions-virtual-module-SQDY3V5X.js.map → actions-virtual-module-3CDQTWOC.js.map} +0 -0
  119. /package/dist/{actions-virtual-module-PNPRCEOS.js.map → actions-virtual-module-EIPXX4ZB.js.map} +0 -0
  120. /package/dist/{app-typed-client-5GYEOYP3.js.map → app-typed-client-7PBFWZUE.js.map} +0 -0
  121. /package/dist/{app-typed-client-QG7BVZYW.js.map → app-typed-client-CSOK7NPC.js.map} +0 -0
  122. /package/dist/{build-QFRLSEZ4.js.map → build-HXND27XG.js.map} +0 -0
  123. /package/dist/{chunk-NAZ4E2GT.js.map → chunk-KXA37ONC.js.map} +0 -0
  124. /package/dist/{chunk-PPPR5DGR.js.map → chunk-RSVN727G.js.map} +0 -0
  125. /package/dist/{dev-GBXOTXUP.js.map → dev-OWW4XVIH.js.map} +0 -0
  126. /package/dist/{dev-emit-FEFEDLZF.js.map → dev-emit-5MDSBP5D.js.map} +0 -0
  127. /package/dist/{dev-emit-O4EGOSNV.js.map → dev-emit-QH2YGZXN.js.map} +0 -0
  128. /package/dist/{vite-plugin-WO72VLYR.js.map → internal-api-4YTJDITC.js.map} +0 -0
  129. /package/dist/{openapi-VR6AFBLJ.js.map → openapi-FHY6HC6I.js.map} +0 -0
  130. /package/dist/{registry-Q2TZQLUH.js.map → registry-34LL7NF4.js.map} +0 -0
  131. /package/dist/{routes-LRYOIIAI.js.map → routes-EW7TP7NJ.js.map} +0 -0
@@ -1,44 +0,0 @@
1
- #!/usr/bin/env node
2
- import "tsx/esm";
3
-
4
- // src/server/transformer.ts
5
- import superjson from "superjson";
6
- var superjsonTransformer = {
7
- name: "superjson",
8
- serialize: (v) => JSON.stringify(superjson.serialize(v)),
9
- deserialize: (raw) => {
10
- const parsed = JSON.parse(raw);
11
- return superjson.deserialize(parsed);
12
- }
13
- };
14
- var jsonTransformer = {
15
- name: "json",
16
- serialize: (v) => JSON.stringify(v),
17
- deserialize: (raw) => JSON.parse(raw)
18
- };
19
- var BUILT_INS = {
20
- superjson: superjsonTransformer,
21
- json: jsonTransformer
22
- };
23
- function resolveTransformer(selector) {
24
- if (typeof selector === "string") {
25
- const built = BUILT_INS[selector];
26
- if (built === void 0) {
27
- throw new Error(
28
- `Unknown transformer "${selector}". Built-in options: ${Object.keys(BUILT_INS).join(", ")}.`
29
- );
30
- }
31
- return built;
32
- }
33
- if (typeof selector !== "object" || typeof selector.serialize !== "function" || typeof selector.deserialize !== "function") {
34
- throw new Error(
35
- `Custom transformer must have serialize and deserialize functions. Got: ${JSON.stringify(selector)}`
36
- );
37
- }
38
- return selector;
39
- }
40
-
41
- export {
42
- resolveTransformer
43
- };
44
- //# sourceMappingURL=chunk-PBEH6NXR.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/server/transformer.ts"],"sourcesContent":["import superjson from 'superjson'\n\n/**\n * T5.2 — pluggable response/request transformer.\n *\n * `superjson` is the default, preserving Date/Map/Set/BigInt/etc.\n * `json` is the lightweight option (plain JSON.stringify/parse).\n * Users can supply a custom object implementing this contract.\n */\nexport interface TheoTransformer {\n name: string\n serialize: (value: unknown) => string\n deserialize: (raw: string) => unknown\n}\n\nexport const superjsonTransformer: TheoTransformer = {\n name: 'superjson',\n serialize: (v) => JSON.stringify(superjson.serialize(v)),\n deserialize: (raw) => {\n const parsed = JSON.parse(raw) as Parameters<typeof superjson.deserialize>[0]\n return superjson.deserialize(parsed)\n },\n}\n\nexport const jsonTransformer: TheoTransformer = {\n name: 'json',\n serialize: (v) => JSON.stringify(v),\n deserialize: (raw) => JSON.parse(raw) as unknown,\n}\n\nconst BUILT_INS: Record<string, TheoTransformer> = {\n superjson: superjsonTransformer,\n json: jsonTransformer,\n}\n\nexport function resolveTransformer(\n selector: 'json' | 'superjson' | TheoTransformer,\n): TheoTransformer {\n if (typeof selector === 'string') {\n // selector is 'json' | 'superjson' literal — both keys exist in\n // BUILT_INS by construction. Type system guarantees a hit; we keep\n // a defensive fallback that the compiler cannot see is unreachable\n // at runtime, just in case someone adds a new literal to the union\n // but forgets to register the built-in.\n const built = BUILT_INS[selector]\n // Defensive: the public union ensures `built` is defined, but if a\n // future contributor extends the union without registering the impl,\n // the cast keeps the failure mode loud.\n if ((built as TheoTransformer | undefined) === undefined) {\n throw new Error(\n `Unknown transformer \"${selector}\". Built-in options: ${Object.keys(BUILT_INS).join(', ')}.`,\n )\n }\n return built\n }\n if (\n typeof selector !== 'object' ||\n typeof selector.serialize !== 'function' ||\n typeof selector.deserialize !== 'function'\n ) {\n throw new Error(\n `Custom transformer must have serialize and deserialize functions. Got: ${JSON.stringify(selector)}`,\n )\n }\n return selector\n}\n"],"mappings":";;;;AAAA,OAAO,eAAe;AAef,IAAM,uBAAwC;AAAA,EACnD,MAAM;AAAA,EACN,WAAW,CAAC,MAAM,KAAK,UAAU,UAAU,UAAU,CAAC,CAAC;AAAA,EACvD,aAAa,CAAC,QAAQ;AACpB,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,WAAO,UAAU,YAAY,MAAM;AAAA,EACrC;AACF;AAEO,IAAM,kBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,WAAW,CAAC,MAAM,KAAK,UAAU,CAAC;AAAA,EAClC,aAAa,CAAC,QAAQ,KAAK,MAAM,GAAG;AACtC;AAEA,IAAM,YAA6C;AAAA,EACjD,WAAW;AAAA,EACX,MAAM;AACR;AAEO,SAAS,mBACd,UACiB;AACjB,MAAI,OAAO,aAAa,UAAU;AAMhC,UAAM,QAAQ,UAAU,QAAQ;AAIhC,QAAK,UAA0C,QAAW;AACxD,YAAM,IAAI;AAAA,QACR,wBAAwB,QAAQ,wBAAwB,OAAO,KAAK,SAAS,EAAE,KAAK,IAAI,CAAC;AAAA,MAC3F;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,MACE,OAAO,aAAa,YACpB,OAAO,SAAS,cAAc,cAC9B,OAAO,SAAS,gBAAgB,YAChC;AACA,UAAM,IAAI;AAAA,MACR,0EAA0E,KAAK,UAAU,QAAQ,CAAC;AAAA,IACpG;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
@@ -1,142 +0,0 @@
1
- // src/config/load-env.ts
2
- import { lstatSync, readFileSync, realpathSync, statSync } from "fs";
3
- import { resolve } from "path";
4
- import dotenv from "dotenv";
5
- import { expand } from "dotenv-expand";
6
- var MAX_ENV_FILE_BYTES = 1048576;
7
- var cache = /* @__PURE__ */ new Map();
8
- function _resetEnvCache() {
9
- cache.clear();
10
- }
11
- function envFilesInPriorityOrder(mode) {
12
- const files = [`.env.${mode}.local`, `.env.local`, `.env.${mode}`, `.env`];
13
- if (mode === "test") {
14
- return files.filter((f) => f !== ".env.local");
15
- }
16
- return files;
17
- }
18
- function readEnvFile(path) {
19
- let stat;
20
- try {
21
- stat = statSync(path);
22
- } catch {
23
- return null;
24
- }
25
- if (!stat.isFile() && !stat.isFIFO()) return null;
26
- if (stat.size > MAX_ENV_FILE_BYTES) {
27
- console.warn(
28
- `[theokit] .env file at ${path} exceeds ${MAX_ENV_FILE_BYTES} bytes \u2014 skipping (likely a generated artifact, not a real env file)`
29
- );
30
- return null;
31
- }
32
- try {
33
- const lstat = lstatSync(path);
34
- if (lstat.isSymbolicLink()) {
35
- const real = realpathSync(path);
36
- console.info(`[theokit] .env at ${path} is a symlink \u2192 ${real}`);
37
- }
38
- } catch {
39
- }
40
- try {
41
- const content = readFileSync(path, "utf-8");
42
- return dotenv.parse(content);
43
- } catch {
44
- return null;
45
- }
46
- }
47
- function loadEnv(options = {}) {
48
- const cwd = options.cwd ?? process.cwd();
49
- const mode = options.mode ?? process.env.NODE_ENV ?? "development";
50
- const cacheKey = `${cwd}:${mode}`;
51
- if (!options.forceReload) {
52
- const cached = cache.get(cacheKey);
53
- if (cached) return cached;
54
- }
55
- const fileNames = envFilesInPriorityOrder(mode);
56
- const filePaths = fileNames.map((f) => resolve(cwd, f));
57
- const merged = {};
58
- const loadedFromFiles = [];
59
- for (const path of [...filePaths].reverse()) {
60
- const parsed = readEnvFile(path);
61
- if (parsed === null) continue;
62
- for (const [k, v] of Object.entries(parsed)) {
63
- merged[k] = v;
64
- }
65
- loadedFromFiles.unshift(path);
66
- }
67
- if (merged.NODE_ENV && process.env.__THEOKIT_USER_NODE_ENV === void 0) {
68
- process.env.__THEOKIT_USER_NODE_ENV = merged.NODE_ENV;
69
- }
70
- delete merged.NODE_ENV;
71
- const processEnvClone = {};
72
- for (const [k, v] of Object.entries(process.env)) {
73
- if (typeof v === "string") processEnvClone[k] = v;
74
- }
75
- try {
76
- expand({ parsed: merged, processEnv: processEnvClone });
77
- } catch (err) {
78
- if (err instanceof RangeError) {
79
- console.warn(
80
- `[theokit] .env expansion overflow (likely circular reference like A=\${B}, B=\${A}). Leaving values as literals.`
81
- );
82
- } else {
83
- throw err;
84
- }
85
- }
86
- const loaded = {};
87
- for (const [k, v] of Object.entries(merged)) {
88
- if (process.env[k] !== void 0) continue;
89
- process.env[k] = v;
90
- loaded[k] = v;
91
- }
92
- process.env.__THEOKIT_PROCESSED_ENV = "true";
93
- const result = { loaded, loadedFromFiles };
94
- cache.set(cacheKey, result);
95
- return result;
96
- }
97
-
98
- // src/server/transformer.ts
99
- import superjson from "superjson";
100
- var superjsonTransformer = {
101
- name: "superjson",
102
- serialize: (v) => JSON.stringify(superjson.serialize(v)),
103
- deserialize: (raw) => {
104
- const parsed = JSON.parse(raw);
105
- return superjson.deserialize(parsed);
106
- }
107
- };
108
- var jsonTransformer = {
109
- name: "json",
110
- serialize: (v) => JSON.stringify(v),
111
- deserialize: (raw) => JSON.parse(raw)
112
- };
113
- var BUILT_INS = {
114
- superjson: superjsonTransformer,
115
- json: jsonTransformer
116
- };
117
- function resolveTransformer(selector) {
118
- if (typeof selector === "string") {
119
- const built = BUILT_INS[selector];
120
- if (built === void 0) {
121
- throw new Error(
122
- `Unknown transformer "${selector}". Built-in options: ${Object.keys(BUILT_INS).join(", ")}.`
123
- );
124
- }
125
- return built;
126
- }
127
- if (typeof selector !== "object" || typeof selector.serialize !== "function" || typeof selector.deserialize !== "function") {
128
- throw new Error(
129
- `Custom transformer must have serialize and deserialize functions. Got: ${JSON.stringify(selector)}`
130
- );
131
- }
132
- return selector;
133
- }
134
-
135
- export {
136
- _resetEnvCache,
137
- loadEnv,
138
- superjsonTransformer,
139
- jsonTransformer,
140
- resolveTransformer
141
- };
142
- //# sourceMappingURL=chunk-PIVX3DYW.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/config/load-env.ts","../src/server/transformer.ts"],"sourcesContent":["/* eslint-disable security/detect-non-literal-fs-filename --\n * Reads `.env` files from a CLI-controlled `cwd`. File names are a fixed\n * literal set. Build-time + CLI tool; no HTTP input.\n */\n/**\n * `loadEnv()` — auto-loads `.env` files into `process.env` for server code.\n *\n * Implements the Next.js `loadEnvConfig` algorithm\n * (`referencias/next.js/packages/next-env/index.ts:114-180`) with TheoKit\n * adaptations:\n *\n * - EC-1: 1MB file-size cap (anti-OOM, anti-supply-chain).\n * - EC-2: `_resetEnvCache()` test-only side-door.\n * - EC-8: `dotenv-expand` circular-ref safe (lib-provided).\n * - EC-13: log when `.env` is a symlink (transparency).\n * - D6: real `process.env` wins over `.env`-file values.\n * - NODE_ENV stash: `.env`-set NODE_ENV NEVER overrides the real\n * `process.env.NODE_ENV`. Stashed in `__THEOKIT_USER_NODE_ENV` instead.\n */\n\nimport { lstatSync, readFileSync, realpathSync, statSync } from 'node:fs'\nimport { resolve } from 'node:path'\n\nimport dotenv from 'dotenv'\nimport { expand, type DotenvPopulateInput } from 'dotenv-expand'\n\nimport type { LoadEnvOptions, LoadEnvResult } from './load-env-types.js'\n\n/** EC-1: 1MB cap. Real `.env`s are < 10KB. */\nconst MAX_ENV_FILE_BYTES = 1_048_576\n\nconst cache = new Map<string, LoadEnvResult>()\n\n/** Test-only side-door for EC-2 — clear the module-level cache between vitest test files. */\nexport function _resetEnvCache(): void {\n cache.clear()\n}\n\nfunction envFilesInPriorityOrder(mode: string): string[] {\n // Top of list = highest priority. Will be read in REVERSE so first-in\n // wins via overwrite during merge.\n const files = [`.env.${mode}.local`, `.env.local`, `.env.${mode}`, `.env`]\n // Test mode skips `.env.local` per dotenv convention (avoid leaking dev\n // secrets into the test suite).\n if (mode === 'test') {\n return files.filter((f) => f !== '.env.local')\n }\n return files\n}\n\nfunction readEnvFile(path: string): Record<string, string> | null {\n let stat\n try {\n stat = statSync(path)\n } catch {\n return null // ENOENT / EACCES → skip\n }\n\n // Allow files + FIFOs (1Password/SOPS pipe support).\n if (!stat.isFile() && !stat.isFIFO()) return null\n\n // EC-1 — anti-OOM cap.\n if (stat.size > MAX_ENV_FILE_BYTES) {\n console.warn(\n `[theokit] .env file at ${path} exceeds ${MAX_ENV_FILE_BYTES} bytes — skipping (likely a generated artifact, not a real env file)`,\n )\n return null\n }\n\n // EC-13 — symlink transparency. Don't refuse; just log.\n try {\n const lstat = lstatSync(path)\n if (lstat.isSymbolicLink()) {\n const real = realpathSync(path)\n // eslint-disable-next-line no-console -- intentional transparency log on a build-time tool\n console.info(`[theokit] .env at ${path} is a symlink → ${real}`)\n }\n } catch {\n // lstat failure is non-fatal — fall through to read.\n }\n\n try {\n const content = readFileSync(path, 'utf-8')\n return dotenv.parse(content)\n } catch {\n return null\n }\n}\n\n// eslint-disable-next-line complexity -- canonical env-load algorithm (priority → expand → guards → apply); inlining branches is clearer than extracting micro-helpers\nexport function loadEnv(options: LoadEnvOptions = {}): LoadEnvResult {\n const cwd = options.cwd ?? process.cwd()\n const mode = options.mode ?? process.env.NODE_ENV ?? 'development'\n const cacheKey = `${cwd}:${mode}`\n\n if (!options.forceReload) {\n const cached = cache.get(cacheKey)\n if (cached) return cached\n }\n\n const fileNames = envFilesInPriorityOrder(mode)\n const filePaths = fileNames.map((f) => resolve(cwd, f))\n\n // Read in REVERSE — lower-priority files first, so higher-priority\n // (lower-index) overwrites during merge.\n const merged: Record<string, string> = {}\n const loadedFromFiles: string[] = []\n for (const path of [...filePaths].reverse()) {\n const parsed = readEnvFile(path)\n if (parsed === null) continue\n for (const [k, v] of Object.entries(parsed)) {\n merged[k] = v\n }\n loadedFromFiles.unshift(path) // keep priority order in result\n }\n\n // NODE_ENV stash — `.env`-set NODE_ENV never overrides real process.env.NODE_ENV.\n if (merged.NODE_ENV && process.env.__THEOKIT_USER_NODE_ENV === undefined) {\n process.env.__THEOKIT_USER_NODE_ENV = merged.NODE_ENV\n }\n delete merged.NODE_ENV // never propagate\n\n // EC-8 — dotenv-expand@11 stack-overflows on circular refs (A=${B}, B=${A}).\n // Wrap in try/catch — on overflow, leave the parsed map untouched (literal\n // values survive). Tested via test_loadEnv_circular_expand_no_loop_EC8.\n // Pass a CLONE of process.env (string-only, filtered) so expand can\n // reference real env without mutating it.\n const processEnvClone: DotenvPopulateInput = {}\n for (const [k, v] of Object.entries(process.env)) {\n if (typeof v === 'string') processEnvClone[k] = v\n }\n try {\n expand({ parsed: merged, processEnv: processEnvClone })\n } catch (err) {\n if (err instanceof RangeError) {\n console.warn(\n `[theokit] .env expansion overflow (likely circular reference like A=\\${B}, B=\\${A}). Leaving values as literals.`,\n )\n } else {\n throw err\n }\n }\n\n // Apply: D6 — real process.env wins over file values.\n const loaded: Record<string, string> = {}\n for (const [k, v] of Object.entries(merged)) {\n if (process.env[k] !== undefined) continue // real env wins\n process.env[k] = v\n loaded[k] = v\n }\n\n // Sentinel\n process.env.__THEOKIT_PROCESSED_ENV = 'true'\n\n const result: LoadEnvResult = { loaded, loadedFromFiles }\n cache.set(cacheKey, result)\n return result\n}\n","import superjson from 'superjson'\n\n/**\n * T5.2 — pluggable response/request transformer.\n *\n * `superjson` is the default, preserving Date/Map/Set/BigInt/etc.\n * `json` is the lightweight option (plain JSON.stringify/parse).\n * Users can supply a custom object implementing this contract.\n */\nexport interface TheoTransformer {\n name: string\n serialize: (value: unknown) => string\n deserialize: (raw: string) => unknown\n}\n\nexport const superjsonTransformer: TheoTransformer = {\n name: 'superjson',\n serialize: (v) => JSON.stringify(superjson.serialize(v)),\n deserialize: (raw) => {\n const parsed = JSON.parse(raw) as Parameters<typeof superjson.deserialize>[0]\n return superjson.deserialize(parsed)\n },\n}\n\nexport const jsonTransformer: TheoTransformer = {\n name: 'json',\n serialize: (v) => JSON.stringify(v),\n deserialize: (raw) => JSON.parse(raw) as unknown,\n}\n\nconst BUILT_INS: Record<string, TheoTransformer> = {\n superjson: superjsonTransformer,\n json: jsonTransformer,\n}\n\nexport function resolveTransformer(\n selector: 'json' | 'superjson' | TheoTransformer,\n): TheoTransformer {\n if (typeof selector === 'string') {\n // selector is 'json' | 'superjson' literal — both keys exist in\n // BUILT_INS by construction. Type system guarantees a hit; we keep\n // a defensive fallback that the compiler cannot see is unreachable\n // at runtime, just in case someone adds a new literal to the union\n // but forgets to register the built-in.\n const built = BUILT_INS[selector]\n // Defensive: the public union ensures `built` is defined, but if a\n // future contributor extends the union without registering the impl,\n // the cast keeps the failure mode loud.\n if ((built as TheoTransformer | undefined) === undefined) {\n throw new Error(\n `Unknown transformer \"${selector}\". Built-in options: ${Object.keys(BUILT_INS).join(', ')}.`,\n )\n }\n return built\n }\n if (\n typeof selector !== 'object' ||\n typeof selector.serialize !== 'function' ||\n typeof selector.deserialize !== 'function'\n ) {\n throw new Error(\n `Custom transformer must have serialize and deserialize functions. Got: ${JSON.stringify(selector)}`,\n )\n }\n return selector\n}\n"],"mappings":";AAoBA,SAAS,WAAW,cAAc,cAAc,gBAAgB;AAChE,SAAS,eAAe;AAExB,OAAO,YAAY;AACnB,SAAS,cAAwC;AAKjD,IAAM,qBAAqB;AAE3B,IAAM,QAAQ,oBAAI,IAA2B;AAGtC,SAAS,iBAAuB;AACrC,QAAM,MAAM;AACd;AAEA,SAAS,wBAAwB,MAAwB;AAGvD,QAAM,QAAQ,CAAC,QAAQ,IAAI,UAAU,cAAc,QAAQ,IAAI,IAAI,MAAM;AAGzE,MAAI,SAAS,QAAQ;AACnB,WAAO,MAAM,OAAO,CAAC,MAAM,MAAM,YAAY;AAAA,EAC/C;AACA,SAAO;AACT;AAEA,SAAS,YAAY,MAA6C;AAChE,MAAI;AACJ,MAAI;AACF,WAAO,SAAS,IAAI;AAAA,EACtB,QAAQ;AACN,WAAO;AAAA,EACT;AAGA,MAAI,CAAC,KAAK,OAAO,KAAK,CAAC,KAAK,OAAO,EAAG,QAAO;AAG7C,MAAI,KAAK,OAAO,oBAAoB;AAClC,YAAQ;AAAA,MACN,0BAA0B,IAAI,YAAY,kBAAkB;AAAA,IAC9D;AACA,WAAO;AAAA,EACT;AAGA,MAAI;AACF,UAAM,QAAQ,UAAU,IAAI;AAC5B,QAAI,MAAM,eAAe,GAAG;AAC1B,YAAM,OAAO,aAAa,IAAI;AAE9B,cAAQ,KAAK,qBAAqB,IAAI,wBAAmB,IAAI,EAAE;AAAA,IACjE;AAAA,EACF,QAAQ;AAAA,EAER;AAEA,MAAI;AACF,UAAM,UAAU,aAAa,MAAM,OAAO;AAC1C,WAAO,OAAO,MAAM,OAAO;AAAA,EAC7B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,QAAQ,UAA0B,CAAC,GAAkB;AACnE,QAAM,MAAM,QAAQ,OAAO,QAAQ,IAAI;AACvC,QAAM,OAAO,QAAQ,QAAQ,QAAQ,IAAI,YAAY;AACrD,QAAM,WAAW,GAAG,GAAG,IAAI,IAAI;AAE/B,MAAI,CAAC,QAAQ,aAAa;AACxB,UAAM,SAAS,MAAM,IAAI,QAAQ;AACjC,QAAI,OAAQ,QAAO;AAAA,EACrB;AAEA,QAAM,YAAY,wBAAwB,IAAI;AAC9C,QAAM,YAAY,UAAU,IAAI,CAAC,MAAM,QAAQ,KAAK,CAAC,CAAC;AAItD,QAAM,SAAiC,CAAC;AACxC,QAAM,kBAA4B,CAAC;AACnC,aAAW,QAAQ,CAAC,GAAG,SAAS,EAAE,QAAQ,GAAG;AAC3C,UAAM,SAAS,YAAY,IAAI;AAC/B,QAAI,WAAW,KAAM;AACrB,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC3C,aAAO,CAAC,IAAI;AAAA,IACd;AACA,oBAAgB,QAAQ,IAAI;AAAA,EAC9B;AAGA,MAAI,OAAO,YAAY,QAAQ,IAAI,4BAA4B,QAAW;AACxE,YAAQ,IAAI,0BAA0B,OAAO;AAAA,EAC/C;AACA,SAAO,OAAO;AAOd,QAAM,kBAAuC,CAAC;AAC9C,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,QAAQ,GAAG,GAAG;AAChD,QAAI,OAAO,MAAM,SAAU,iBAAgB,CAAC,IAAI;AAAA,EAClD;AACA,MAAI;AACF,WAAO,EAAE,QAAQ,QAAQ,YAAY,gBAAgB,CAAC;AAAA,EACxD,SAAS,KAAK;AACZ,QAAI,eAAe,YAAY;AAC7B,cAAQ;AAAA,QACN;AAAA,MACF;AAAA,IACF,OAAO;AACL,YAAM;AAAA,IACR;AAAA,EACF;AAGA,QAAM,SAAiC,CAAC;AACxC,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC3C,QAAI,QAAQ,IAAI,CAAC,MAAM,OAAW;AAClC,YAAQ,IAAI,CAAC,IAAI;AACjB,WAAO,CAAC,IAAI;AAAA,EACd;AAGA,UAAQ,IAAI,0BAA0B;AAEtC,QAAM,SAAwB,EAAE,QAAQ,gBAAgB;AACxD,QAAM,IAAI,UAAU,MAAM;AAC1B,SAAO;AACT;;;AC7JA,OAAO,eAAe;AAef,IAAM,uBAAwC;AAAA,EACnD,MAAM;AAAA,EACN,WAAW,CAAC,MAAM,KAAK,UAAU,UAAU,UAAU,CAAC,CAAC;AAAA,EACvD,aAAa,CAAC,QAAQ;AACpB,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,WAAO,UAAU,YAAY,MAAM;AAAA,EACrC;AACF;AAEO,IAAM,kBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,WAAW,CAAC,MAAM,KAAK,UAAU,CAAC;AAAA,EAClC,aAAa,CAAC,QAAQ,KAAK,MAAM,GAAG;AACtC;AAEA,IAAM,YAA6C;AAAA,EACjD,WAAW;AAAA,EACX,MAAM;AACR;AAEO,SAAS,mBACd,UACiB;AACjB,MAAI,OAAO,aAAa,UAAU;AAMhC,UAAM,QAAQ,UAAU,QAAQ;AAIhC,QAAK,UAA0C,QAAW;AACxD,YAAM,IAAI;AAAA,QACR,wBAAwB,QAAQ,wBAAwB,OAAO,KAAK,SAAS,EAAE,KAAK,IAAI,CAAC;AAAA,MAC3F;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,MACE,OAAO,aAAa,YACpB,OAAO,SAAS,cAAc,cAC9B,OAAO,SAAS,gBAAgB,YAChC;AACA,UAAM,IAAI;AAAA,MACR,0EAA0E,KAAK,UAAU,QAAQ,CAAC;AAAA,IACpG;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
@@ -1 +0,0 @@
1
- //# sourceMappingURL=chunk-PPPR5DGR.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/server/agent/stream-agent-run.ts","../src/server/agent/provider-resolver.ts","../src/server/agent/create-conversation-history.ts"],"sourcesContent":["import type { AgentEvent, AgentErrorEvent } from './agent-types.js'\n\n/**\n * Item #4 — `streamAgentRun`\n *\n * Adapter that consumes the `@theokit/sdk` `Run.stream()` async generator\n * (SDKMessage variants) and yields TheoKit `AgentEvent`s suitable for SSE\n * via `defineAgentEndpoint`. One line at the consumer side:\n *\n * ```ts\n * const run = await agent.send(message)\n * yield* streamAgentRun(run)\n * ```\n *\n * Mapping table (SDK → AgentEvent):\n *\n * | SDK message | AgentEvent yielded |\n * |---|---|\n * | assistant.content[].type==='text' | { type: 'message', content } |\n * | assistant.content[].type==='tool_use'| (none — covered by tool_call below) |\n * | tool_call(status='running') | { type: 'tool_call', name, args, id } |\n * | tool_call(status='completed') | { type: 'tool_result', name, data, id }|\n * | tool_call(status='error') | { type: 'error', message, id } |\n * | run.wait() status==='error' | { type: 'error', message } |\n * | run.wait() status==='cancelled' | (none — cancel ≠ error) |\n * | system / user / thinking / status / | (none — internal SDK telemetry) |\n * | task / request / object_delta | |\n *\n * Abort semantics: when the consumer calls `generator.return()` on the\n * outer `defineAgentEndpoint` generator, `streamAgentRun` exits the\n * `for await` loop and does NOT call `run.wait()`. Cleanup of in-flight\n * SDK resources is the SDK consumer's responsibility (`run.cancel()`).\n */\n\n/**\n * Local mirror of the SDK's `Run` interface — only the surfaces we consume.\n * The message contract is minimal (just `{ type: string }`) so the SDK's\n * `SDKMessage` discriminated union IS structurally assignable without any\n * cast at the consumer site (covariant — TS accepts the SDK's typed message\n * as the wider `{ type: string }`). Property access inside `streamAgentRun`\n * narrows via runtime type guards.\n *\n * `import type` from `@theokit/sdk` would couple TheoKit to the SDK at type-\n * resolution time even for consumers who never use the agent surface.\n */\nexport interface AgentRunLike {\n stream: () => AsyncIterable<{ type: string }>\n wait: () => Promise<AgentRunResult>\n}\n\n/**\n * Re-exported as a convenience for test fixtures. Production code typically\n * passes an SDK `Run` directly (structural match via `{ type: string }`).\n */\nexport type AgentRunStreamMessage =\n | {\n type: 'assistant'\n message: { role: 'assistant'; content: { type: string; text?: string }[] }\n }\n | {\n type: 'tool_call'\n name: string\n status: 'running' | 'completed' | 'error'\n args?: unknown\n result?: unknown\n call_id: string\n }\n | { type: string; [k: string]: unknown }\n\n/** Subset of the SDK `RunResult` we consume. */\nexport interface AgentRunResult {\n status: 'finished' | 'error' | 'cancelled'\n error?: { message: string; code?: string; cause?: unknown }\n}\n\n/**\n * EC-1 (edge case review): tool result may be a Date, bigint, circular ref,\n * etc. `JSON.stringify` in `encodeSSE` would throw — uncaught inside the\n * outer generator — and `defineAgentEndpoint` would replace the legitimate\n * `tool_result` with a generic `error`. Coerce here so the wire stays honest.\n */\nfunction safeJsonStringify(value: unknown): string {\n try {\n return JSON.stringify(value)\n } catch {\n return '[Unserializable]'\n }\n}\n\n/**\n * EC-3 (edge case review): SDK types `args?: unknown`. A raw `as` cast hides\n * the possibility that `msg.args` is an array, primitive, or `null` (null\n * survives `??`). Type-guard BEFORE narrowing to `Record<string, unknown>`.\n */\nfunction safeArgs(args: unknown): Record<string, unknown> {\n if (typeof args === 'object' && args !== null && !Array.isArray(args)) {\n return args as Record<string, unknown>\n }\n return {}\n}\n\n/**\n * Yield AgentEvents derived from the SDK Run lifecycle.\n *\n * Consumer pattern:\n *\n * ```ts\n * export const POST = defineAgentEndpoint({\n * async *handler({ body }) {\n * const agent = await Agent.create({ apiKey, model, tools: [...] })\n * try {\n * const run = await agent.send(body.message)\n * yield* streamAgentRun(run)\n * } finally {\n * try { await agent.dispose() } catch (e) { console.warn(e) }\n * }\n * },\n * })\n * ```\n *\n * @public\n */\ninterface AssistantLike {\n type: 'assistant'\n message: { role: 'assistant'; content: { type: string; text?: string }[] }\n}\ninterface ToolCallLike {\n type: 'tool_call'\n name: string\n status: 'running' | 'completed' | 'error'\n args?: unknown\n result?: unknown\n call_id: string\n}\n\nfunction isAssistant(msg: { type: string }): msg is AssistantLike {\n // Wide cast to `unknown` first so runtime null guard survives ESLint\n // narrowing complaints — the SDK contract permits `null` even when its\n // TS type does not.\n const m = msg as unknown as {\n type: string\n message?: { content?: unknown } | null\n }\n return (\n m.type === 'assistant' &&\n m.message != null &&\n typeof m.message === 'object' &&\n Array.isArray(m.message.content)\n )\n}\nfunction isToolCall(msg: { type: string }): msg is ToolCallLike {\n const t = msg as unknown as {\n type: string\n name?: unknown\n status?: unknown\n call_id?: unknown\n }\n return (\n t.type === 'tool_call' &&\n typeof t.name === 'string' &&\n typeof t.call_id === 'string' &&\n (t.status === 'running' || t.status === 'completed' || t.status === 'error')\n )\n}\n\n/**\n * Phase 4 — Production-Readiness #3: structural mirror of SDK's AgentRunError.\n *\n * EC-6 (SHOULD TEST): we only require `code: string` to discriminate.\n * Provider, retriable, retryAfterMs, requestId are all optional — SDK error\n * paths may omit them (e.g., aborted before request, tool runtime error).\n */\ninterface AgentRunErrorLike {\n message: string\n code: string\n provider?: string\n retriable?: boolean\n retryAfterMs?: number\n requestId?: string\n /**\n * EC-15 (DOCUMENT) + invariant: `providerError` is QUARANTINED. We read it\n * for type-narrowing but NEVER serialize into the AgentEvent — leaking the\n * raw provider response could leak API keys, internal endpoints, or PII.\n * Only sanitized fields above flow to the SSE wire. `error.message` is\n * trusted to not contain secrets (SDK's responsibility per the v1.1.0\n * release contract).\n */\n providerError?: unknown\n}\n\n/**\n * EC-6 (SHOULD TEST): minimal type guard — only requires `code: string`.\n * Does NOT require `'provider' in err` because the SDK throws AgentRunErrors\n * without `provider` in local error paths (timeout, tool runtime error,\n * aborted-before-call).\n */\nfunction isAgentRunError(err: unknown): err is AgentRunErrorLike {\n if (!(err instanceof Error)) return false\n const e = err as { code?: unknown }\n return 'code' in e && typeof e.code === 'string'\n}\n\n/**\n * Map an SDK error to the AgentErrorEvent shape. Pure function — easy to test.\n *\n * Backward compat (D4): non-AgentRunError throws yield only `message` field\n * (legacy shape); discriminated fields stay `undefined`.\n *\n * Return type is the specific `AgentErrorEvent` (not the union) for ergonomic\n * call-site access — `errorToEvent(err).code` works without narrowing.\n */\nexport function errorToEvent(err: unknown, id?: string): AgentErrorEvent {\n if (isAgentRunError(err)) {\n const event: AgentErrorEvent = {\n type: 'error',\n message: err.message,\n code: err.code,\n }\n if (err.provider !== undefined) event.provider = err.provider\n if (err.retriable !== undefined) event.retriable = err.retriable\n if (err.retryAfterMs !== undefined) event.retryAfterMs = err.retryAfterMs\n if (id !== undefined) event.id = id\n return event\n }\n // Fallback for non-AgentRunError throws (plain Error, string, plain object with message)\n let message: string\n if (err instanceof Error) {\n message = err.message\n } else if (typeof err === 'string') {\n message = err\n } else if (err !== null && typeof err === 'object' && 'message' in err) {\n const candidate: unknown = (err as Record<string, unknown>).message\n // Plain object with `message: string` — common for SDK status:error payloads\n message = typeof candidate === 'string' ? candidate : '[object Object]'\n } else if (err === null || err === undefined) {\n message = String(err)\n } else {\n message = '[non-stringifiable error]'\n }\n const event: AgentErrorEvent = { type: 'error', message }\n if (id !== undefined) event.id = id\n return event\n}\n\nfunction yieldFromToolCall(msg: ToolCallLike): AgentEvent {\n if (msg.status === 'running') {\n return {\n type: 'tool_call',\n name: msg.name,\n args: safeArgs(msg.args),\n id: msg.call_id,\n }\n }\n if (msg.status === 'completed') {\n const data = typeof msg.result === 'string' ? msg.result : safeJsonStringify(msg.result)\n return {\n type: 'tool_result',\n name: msg.name,\n data,\n id: msg.call_id,\n }\n }\n // status === 'error' — exhaustive by type\n const message = typeof msg.result === 'string' ? msg.result : `Tool ${msg.name} failed`\n return { type: 'error', message, id: msg.call_id }\n}\n\nexport async function* streamAgentRun(\n run: AgentRunLike,\n): AsyncGenerator<AgentEvent, void, unknown> {\n for await (const msg of run.stream()) {\n if (isAssistant(msg)) {\n for (const block of msg.message.content) {\n if (block.type === 'text' && typeof block.text === 'string' && block.text.length > 0) {\n yield { type: 'message', content: block.text }\n }\n }\n } else if (isToolCall(msg)) {\n yield yieldFromToolCall(msg)\n }\n // SDK-internal variants (system, user, thinking, status, task,\n // request, object_delta) are intentionally not yielded.\n }\n\n const result = await run.wait()\n if (result.status === 'error' && result.error !== undefined) {\n yield errorToEvent(result.error)\n }\n}\n","/**\n * Provider Resolver — Strategy + Registry pattern (FAANG-grade).\n *\n * Inspiração: Dapr Conversation Registry (`dapr/pkg/components/conversation/registry.go`)\n * + Encore Manager provider array (`encore/runtimes/go/pubsub/manager_internal.go`).\n *\n * Princípio: provider routing é responsabilidade do FRAMEWORK, não do consumer.\n * Consumer template usa `model: { id: 'gpt-4o-mini' }` puro — sem conditionals.\n *\n * Wire protocol: OpenAI Chat Completions (universal — implementado por todos\n * os providers: OpenRouter, Groq, Mistral, Together, Anthropic via proxy, etc).\n *\n * Resolução por prioridade (FIRST match wins):\n * 1. OPENROUTER_API_KEY → baseUrl=openrouter.ai (gateway multi-modelo)\n * 2. OPENAI_API_KEY → baseUrl=api.openai.com\n * 3. ANTHROPIC_API_KEY → direct Anthropic (Messages API, não OpenAI-compat)\n *\n * Escape hatch: `options.apiKey` explícito SOBREPÕE auto-resolution\n * (consumer pode forçar provider específico se quiser).\n */\n\n/**\n * Provider configuration descriptor — Registry entry shape.\n *\n * @public\n */\nexport interface ProviderDescriptor {\n /** Stable name used internally — não exposto no wire. */\n name: string\n /** Environment variable that holds the API key for this provider. */\n envKey: string\n /** Base URL for the provider's OpenAI-compatible (or native) API. */\n baseUrl: string\n /** Resolution priority (lower = higher priority). FIRST match wins. */\n priority: number\n}\n\n/**\n * Resolved provider configuration — output of `resolveProvider()`.\n *\n * @public\n */\nexport interface ResolvedProvider {\n name: string\n apiKey: string\n baseUrl: string\n}\n\n/**\n * Default provider registry. Order = priority (first = highest).\n *\n * Adding a new provider:\n * 1. Append entry below (or register via `registerProvider()`).\n * 2. Set `envKey` matching the user's env var convention.\n * 3. Set `baseUrl` to the OpenAI-compat endpoint (or native if not compat).\n * 4. Provider name used in telemetry/logs only — never wire-exposed.\n */\nconst DEFAULT_REGISTRY: ProviderDescriptor[] = [\n {\n name: 'openrouter',\n envKey: 'OPENROUTER_API_KEY',\n baseUrl: 'https://openrouter.ai/api/v1',\n priority: 1,\n },\n {\n name: 'openai',\n envKey: 'OPENAI_API_KEY',\n baseUrl: 'https://api.openai.com/v1',\n priority: 2,\n },\n {\n name: 'anthropic',\n envKey: 'ANTHROPIC_API_KEY',\n baseUrl: 'https://api.anthropic.com',\n priority: 3,\n },\n]\n\n/**\n * Runtime registry — copy of DEFAULT_REGISTRY mutable via registerProvider().\n * Sorted by priority on every resolve (stable, O(n log n) — n <= ~10 providers).\n */\nconst registry: ProviderDescriptor[] = [...DEFAULT_REGISTRY]\n\n/**\n * Register a new provider (Registry pattern — runtime extension point).\n * Useful for self-hosted endpoints or custom providers without touching theokit src.\n *\n * @example\n * registerProvider({\n * name: 'self-hosted',\n * envKey: 'SELF_HOSTED_API_KEY',\n * baseUrl: 'https://llm.internal.acme.com/v1',\n * priority: 0, // highest priority\n * })\n *\n * @public\n */\nexport function registerProvider(descriptor: ProviderDescriptor): void {\n // Idempotent — replace existing by name.\n const idx = registry.findIndex((p) => p.name === descriptor.name)\n if (idx >= 0) registry[idx] = descriptor\n else registry.push(descriptor)\n}\n\n/**\n * Reset registry to DEFAULT_REGISTRY (test-only / dev escape hatch).\n *\n * @public\n */\nexport function resetProviderRegistry(): void {\n registry.length = 0\n registry.push(...DEFAULT_REGISTRY)\n}\n\n/**\n * Get current registry snapshot (read-only — inspection).\n *\n * @public\n */\nexport function listProviders(): readonly ProviderDescriptor[] {\n return [...registry].sort((a, b) => a.priority - b.priority)\n}\n\n/**\n * Resolve provider from env vars by priority. FIRST env var found wins.\n *\n * @returns ResolvedProvider with apiKey + baseUrl + name\n * @throws Error if NO provider env var is set (actionable message)\n *\n * @public\n */\nexport function resolveProvider(): ResolvedProvider {\n const sorted = [...registry].sort((a, b) => a.priority - b.priority)\n for (const desc of sorted) {\n const apiKey = process.env[desc.envKey]\n if (apiKey && apiKey.length > 0) {\n return {\n name: desc.name,\n apiKey,\n baseUrl: desc.baseUrl,\n }\n }\n }\n // No env var found — emit actionable error.\n const envKeys = sorted.map((p) => p.envKey).join(' OR ')\n throw new Error(\n `No LLM provider API key found in environment. Set one of: ${envKeys}. ` +\n `Get a free OpenRouter key at https://openrouter.ai/keys (recommended — one key, many models).`,\n )\n}\n\n/**\n * Try to resolve — does NOT throw. Returns null if no provider available.\n * Useful for graceful degradation (e.g., mock mode).\n *\n * @public\n */\nexport function tryResolveProvider(): ResolvedProvider | null {\n try {\n return resolveProvider()\n } catch {\n return null\n }\n}\n","/**\n * Item #5 — `createConversationHistory`\n *\n * Orchestrator that resolves a stable `agentId` from (explicit → session →\n * cookie → fresh UUID), then returns an `@theokit/sdk` `Agent` via\n * `Agent.getOrCreate(agentId, options)`. Conversation turns auto-persist in\n * `<cwd>/.theokit/agents/<agentId>/messages.jsonl` — SDK owns the storage\n * (ADR D1). `MemorySettings` (facts recall layer) is opt-in passthrough via\n * `options.memory` (ADR D2).\n *\n * Security: agentId from cookie/explicit is attacker-controlled. The SDK\n * uses it as a filesystem path component AND we serialize it into Set-Cookie.\n * EC-1 enforces a strict regex `^[a-zA-Z0-9_-]{1,128}$` at every entry point;\n * invalid values fall through (treated as \"missing\") rather than throw.\n */\n\nimport { tryResolveProvider } from './provider-resolver.js'\n\n// ──────────────────────────────────────────────────────────────────────────\n// Structural types — mirrors of SDK shapes we don't want to hard-import\n// (the SDK is an OPTIONAL peer per item #4's stance).\n// ──────────────────────────────────────────────────────────────────────────\n\n/**\n * Minimum surface of an SDK Agent that consumers care about post-creation.\n * Structural match — any object with `send` + `dispose` of compatible\n * shape works. `send` returns a `SdkRunLike` (a Run-shaped object) that\n * `streamAgentRun` can consume. Permissive `unknown` for now; consumers\n * who want stricter types can cast to the SDK's own types.\n *\n * **T5.2 (architecture-cleanup) — DP-7 decision: KEEP (Opt B).** The 5 duck-typed\n * mirrors below were flagged as \"over-engineered\" by the 2026-05-27 architecture\n * review. Decision: KEEP them because `@theokit/sdk` is `devDependency` (not\n * required at runtime for consumers that don't use agent features). Removing\n * the mirrors would force a hard runtime dep on the SDK, breaking consumers\n * who build TheoKit apps without the agent layer.\n *\n * @kept Defensive duck-type. Do NOT replace with direct SDK type imports unless\n * `@theokit/sdk` is promoted from devDependency to dependency. If promoting,\n * ALSO drop the mirrors (Opt A from the architecture-cleanup plan T5.2).\n */\nexport interface SdkRunLike {\n stream: () => AsyncIterable<{ type: string }>\n wait: () => Promise<{ status: 'finished' | 'error' | 'cancelled'; error?: { message: string } }>\n}\n\nexport interface SdkAgent {\n send: (message: string, options?: unknown) => Promise<SdkRunLike>\n dispose: () => Promise<void>\n}\n\n/**\n * Phase 2 — structural duck-type of `@theokit/sdk`'s `ConversationStorageAdapter`.\n *\n * D2 (decoupling): we mirror the SDK's shape locally rather than hard-import\n * the SDK type. This lets consumers pass any object matching the structural\n * contract (own implementation, SDK's `FileSystemConversationStorage`,\n * `InMemoryConversationStorage`, or a Postgres/Redis recipe).\n *\n * EC-5 (SHOULD TEST — sync drift detection): the SDK type MUST be assignable\n * to this interface AND vice-versa. A contract test asserts both directions.\n *\n * `unknown` for the message payload avoids coupling to the SDK's `SDKMessage`\n * shape. Real consumers cast at the call site if they need stricter types.\n */\nexport interface ConversationStorageLike {\n getMessages(conversationId: string): Promise<readonly unknown[]>\n appendMessage(conversationId: string, message: unknown): Promise<void>\n deleteConversation(conversationId: string): Promise<void>\n listConversationIds?(opts?: { limit?: number }): Promise<readonly string[] | undefined>\n dispose?(): Promise<void>\n}\n\n/**\n * Minimum surface of `AgentOptions` accepted by `Agent.getOrCreate`. Forward-\n * compatible: callers pass whatever the SDK supports (memory, tools, etc.).\n *\n * Phase 2 adds typed `conversationStorage` slot. The index signature still\n * passes everything else opaquely.\n */\nexport interface SdkAgentOptions {\n apiKey?: string\n model?: { id: string }\n tools?: readonly unknown[]\n memory?: Record<string, unknown>\n /**\n * Phase 2 (Production-Readiness #1) — pluggable conversation persistence.\n * Default (when omitted): SDK falls back to `FileSystemConversationStorage`.\n * Required for serverless / multi-host deploys.\n */\n conversationStorage?: ConversationStorageLike\n [key: string]: unknown\n}\n\ninterface SdkModule {\n Agent: {\n getOrCreate: (agentId: string, options: SdkAgentOptions) => Promise<SdkAgent>\n }\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Public API\n// ──────────────────────────────────────────────────────────────────────────\n\nexport interface ConversationHistoryArgs {\n /** Request — for reading the conversation cookie. */\n request: Request | { headers?: { cookie?: string } | Headers }\n /**\n * Response-like surface that accepts a `Set-Cookie` header. The primitive\n * appends a Set-Cookie line when issuing a new conversation id. If absent,\n * the primitive still reads the existing cookie but cannot issue a new\n * one — useful for read-only contexts.\n */\n response?: { headers: Headers }\n /** Explicit override — wins over session/cookie/uuid (ADR D3 step 1). */\n agentId?: string\n /** Auth session containing a `conversationId` field — ADR D3 step 2. */\n session?: { conversationId?: string } | null\n /** SDK AgentOptions forwarded to Agent.getOrCreate. apiKey + model required. */\n options: SdkAgentOptions\n /** Cookie name override. Default: 'theo_conversation'. */\n cookieName?: string\n /** Cookie max-age in seconds. Default + min: 30 days. Non-positive coerced to default (EC-4). */\n cookieMaxAge?: number\n}\n\nexport interface ConversationHistoryResult {\n /** The SDK Agent, ready to receive `agent.send(message)`. */\n agent: SdkAgent\n /** The resolved conversation id (useful for logging / debugging). */\n conversationId: string\n /** True when the id was newly generated (no prior cookie / session). */\n isNew: boolean\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Test seam — allows unit tests to swap the SDK without dynamic import flake.\n// Underscore-prefixed: NOT part of the public contract.\n// ──────────────────────────────────────────────────────────────────────────\n\nlet sdkOverride: SdkModule | null | undefined = undefined\n\n/** @internal */\nexport function __setSdkForTests(sdk: SdkModule | null): void {\n sdkOverride = sdk\n}\n\n/** @internal */\nexport function __resetSdkForTests(): void {\n sdkOverride = undefined\n}\n\nasync function loadSdk(): Promise<SdkModule> {\n // EC-2 (edge case review — MUST FIX): the SDK is an optional peer; if the\n // consumer never installed it, `import('@theokit/sdk')` throws\n // ERR_MODULE_NOT_FOUND. Re-throw with an actionable message.\n if (sdkOverride === null) {\n throw new Error(\n 'createConversationHistory requires @theokit/sdk. Install: pnpm add @theokit/sdk',\n )\n }\n if (sdkOverride !== undefined) return sdkOverride\n try {\n // Use `createRequire` — Node's CJS-style require resolves against the\n // process's actual node_modules tree, bypassing Vite's SSR import-\n // analysis pipeline. The dynamic ESM `import()` path got intercepted\n // by Vite's `vite:import-analysis` plugin and failed to find the SDK\n // even when it was installed; createRequire goes straight to Node.\n //\n // The SDK ships dual ESM+CJS (per its tsup build), so `require` yields\n // the same module the ESM `import` would.\n const { createRequire } = await import('node:module')\n const requireFn = createRequire(import.meta.url)\n const spec = '@theokit/sdk'\n const mod = requireFn(spec) as unknown as SdkModule\n return mod\n } catch (cause) {\n throw new Error(\n 'createConversationHistory requires @theokit/sdk. Install: pnpm add @theokit/sdk',\n { cause },\n )\n }\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Implementation\n// ──────────────────────────────────────────────────────────────────────────\n\nconst DEFAULT_COOKIE_NAME = 'theo_conversation'\nconst DEFAULT_COOKIE_MAX_AGE = 60 * 60 * 24 * 30 // 30 days\n\n/**\n * EC-1 (edge case review — MUST FIX): the agentId becomes a filesystem path\n * component (`<cwd>/.theokit/agents/<agentId>/messages.jsonl`) inside the SDK\n * AND is serialized into a Set-Cookie header. The SDK does NOT validate the\n * char set. An attacker setting `Cookie: theo_conversation=../../../etc/passwd`\n * could trigger arbitrary-path writes; an `agentId` with CRLF would inject\n * HTTP headers. The same regex kills both attacks.\n */\nconst AGENT_ID_REGEX = /^[a-zA-Z0-9_-]{1,128}$/\n\nfunction isValidAgentId(s: string | undefined | null): s is string {\n return typeof s === 'string' && AGENT_ID_REGEX.test(s)\n}\n\n/**\n * Minimal RFC 6265 cookie parser. Returns the FIRST occurrence of `name`\n * (EC-5 — pins first-wins behavior).\n */\nfunction readCookieValue(\n request: ConversationHistoryArgs['request'],\n name: string,\n): string | undefined {\n let raw: string | undefined\n const h = request.headers\n if (h === undefined) return undefined\n if (typeof (h as Headers).get === 'function') {\n raw = (h as Headers).get('cookie') ?? undefined\n } else {\n raw = (h as { cookie?: string }).cookie\n }\n if (raw === undefined || raw.length === 0) return undefined\n const pairs = raw.split(/[;,]/)\n for (const pair of pairs) {\n const eq = pair.indexOf('=')\n if (eq < 0) continue\n const k = pair.slice(0, eq).trim()\n if (k === name) return pair.slice(eq + 1).trim()\n }\n return undefined\n}\n\ninterface SerializeCookieOptions {\n httpOnly?: boolean\n sameSite?: 'lax' | 'strict' | 'none'\n maxAge?: number\n path?: string\n}\n\nfunction serializeCookie(name: string, value: string, options: SerializeCookieOptions): string {\n const parts: string[] = [`${name}=${value}`]\n if (options.path !== undefined) parts.push(`Path=${options.path}`)\n if (options.maxAge !== undefined) parts.push(`Max-Age=${options.maxAge}`)\n if (options.sameSite !== undefined) {\n const v = options.sameSite.charAt(0).toUpperCase() + options.sameSite.slice(1)\n parts.push(`SameSite=${v}`)\n }\n if (options.httpOnly === true) parts.push('HttpOnly')\n return parts.join('; ')\n}\n\nexport async function createConversationHistory(\n args: ConversationHistoryArgs,\n): Promise<ConversationHistoryResult> {\n const cookieName = args.cookieName ?? DEFAULT_COOKIE_NAME\n // EC-4 (edge case review — SHOULD TEST): coerce non-positive to default.\n // The `??` operator alone would let `0` through, producing `Max-Age=0`\n // which means \"delete cookie immediately\" — almost certainly not intent.\n const rawMaxAge = args.cookieMaxAge\n const cookieMaxAge =\n typeof rawMaxAge === 'number' && rawMaxAge > 0 ? rawMaxAge : DEFAULT_COOKIE_MAX_AGE\n\n // 1. Resolve agentId per ADR D3 — sources are validated; invalid values\n // fall through (treated as \"missing\") rather than throw.\n let conversationId: string | undefined\n let isNew = false\n const cookieOnRequest = readCookieValue(args.request, cookieName)\n\n if (isValidAgentId(args.agentId)) {\n conversationId = args.agentId\n } else if (args.session !== null && args.session !== undefined) {\n const sId = args.session.conversationId\n if (isValidAgentId(sId)) conversationId = sId\n }\n if (conversationId === undefined && isValidAgentId(cookieOnRequest)) {\n conversationId = cookieOnRequest\n }\n\n if (conversationId === undefined) {\n conversationId = crypto.randomUUID()\n isNew = true\n }\n\n // Issue (or refresh) the cookie when:\n // 1. The id was newly generated (no source had it), OR\n // 2. The request's cookie does NOT match the resolved id (explicit\n // `agentId` override, session-derived id, etc.). Without this,\n // callers that pre-probe the id (e.g. to build agentId-scoped tools)\n // and pass it via `agentId` would never get a Set-Cookie even on\n // first visit. Net effect: every response with a `response` slot\n // ensures the browser ends up with a cookie that matches the\n // resolved id.\n const shouldIssueCookie = isNew || cookieOnRequest !== conversationId\n if (shouldIssueCookie && args.response !== undefined) {\n const cookie = serializeCookie(cookieName, conversationId, {\n httpOnly: true,\n sameSite: 'lax',\n maxAge: cookieMaxAge,\n path: '/',\n })\n args.response.headers.append('set-cookie', cookie)\n }\n\n // 2. Auto-resolve provider via Strategy pattern (FAANG-grade — zero\n // conditionals no consumer). If `options.apiKey` ausente, lê env vars\n // priorizadas (OPENROUTER > OPENAI > ANTHROPIC) e injeta apiKey +\n // providers.baseUrl. Consumer override: passar `options.apiKey` explícito\n // SOBREPÕE o auto-resolve (escape hatch). Ver `provider-resolver.ts` +\n // Dapr Conversation Registry pattern (`referencias/dapr/pkg/components/conversation/`).\n const resolvedOptions = autoResolveProviderIfNeeded(args.options)\n\n // 3. Resolve the agent via SDK.\n const sdk = await loadSdk()\n const agent = await sdk.Agent.getOrCreate(conversationId, resolvedOptions)\n\n return { agent, conversationId, isNew }\n}\n\n/**\n * Auto-inject provider config (apiKey + baseUrl) via Strategy pattern when\n * consumer didn't pass apiKey explicit. Idempotent — se apiKey já set, noop.\n *\n * Output shape:\n * {\n * ...originalOptions,\n * apiKey: env, // resolved from process.env\n * providers: { routes: [{ capability: 'chat', provider: name, ... }] }\n * }\n */\nfunction autoResolveProviderIfNeeded(options: SdkAgentOptions): SdkAgentOptions {\n // Escape hatch — consumer override wins.\n if (typeof options.apiKey === 'string' && options.apiKey.length > 0) {\n return options\n }\n // Auto-resolve via Strategy registry.\n //\n // Finding A workaround (sdk-residual-behavior-2026-05-28): SDK silently\n // returns canned \"Hello! How can I assist you today?\" content when no\n // apiKey AND no provider env vars are present. Fail-fast HERE with an\n // actionable error — template's try/catch yields `{type:'error'}` SSE\n // event so consumer sees what's wrong.\n const resolved = tryResolveProvider()\n if (resolved === null) {\n throw new Error(\n 'No LLM provider API key found in environment. ' +\n 'Set OPENROUTER_API_KEY (recommended — gateway to many models) OR ' +\n 'OPENAI_API_KEY OR ANTHROPIC_API_KEY in your .env. ' +\n 'Get a free OpenRouter key at https://openrouter.ai/keys. ' +\n '(Pass `options.apiKey` explicitly to bypass auto-resolution.)',\n )\n }\n // Inject apiKey + provider routing. SDK ProviderRoutingSettings shape.\n // Note: we use `chat` capability since this is the conversation primitive;\n // SDK may extend to embeddings/etc — those routes are separate concerns.\n return {\n ...options,\n apiKey: resolved.apiKey,\n providers: {\n routes: [{ capability: 'chat', provider: resolved.name, baseUrl: resolved.baseUrl }],\n },\n }\n}\n"],"mappings":"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","names":["event"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/cli/commands/start/index.ts","../src/server/define/health-route.ts","../src/cli/commands/start/bootstrap-stages.ts","../src/cli/commands/start/graceful-shutdown.ts","../src/cli/commands/start/manifest-loader.ts","../src/cli/commands/start/request-handler.ts","../src/cli/commands/start/handlers.ts","../src/server/http/static.ts","../src/cli/commands/start/ssr-setup.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 { defineHealthRoute } from '../../../server/define/health-route.js'\nimport { createPluginRunnerFromConfig } from '../../../server/plugins/load-plugins.js'\nimport { createRateLimiter } from '../../../server/rate-limit/rate-limit.js'\nimport { createProductionLoader } from '../../../server/scan/module-loader.js'\nimport { resolveTransformer } from '../../../server/transformer.js'\nimport { preflightNodeAndBindings } from '../../preflight-node-version.js'\n\nimport {\n configureAgentRegistryFromConfig,\n configureStorageManagerFromConfig,\n} from './bootstrap-stages.js'\nimport { installGracefulShutdown } from './graceful-shutdown.js'\nimport type { RequestHandlerCtx } from './handlers.js'\nimport { loadRoutesAndActions } from './manifest-loader.js'\nimport { createRequestHandler } from './request-handler.js'\nimport { 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 await configureAgentRegistryFromConfig(config.agents?.registry)\n await configureStorageManagerFromConfig(config.storage)\n\n const distDir = resolve(cwd, '.theokit')\n const clientDir = resolve(distDir, 'client')\n const serverDir = resolve(cwd, 'server')\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 const port = options.port ?? config.port\n const pluginRunner = await createPluginRunnerFromConfig(config.plugins)\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 } = loadRoutesAndActions(distDir, serverDir)\n\n // Rate limiter (legacy flat form only — per-route variant is handled in\n // api-middleware integration path, not this fallback).\n const flatRateLimit =\n config.rateLimit && 'windowMs' in config.rateLimit && 'max' in config.rateLimit\n ? config.rateLimit\n : undefined\n const rateLimiter = flatRateLimit ? createRateLimiter(flatRateLimit) : 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 loadModule,\n serverDir,\n pluginRunner,\n transformer,\n csrfMode: config.security?.csrf ?? 'strict',\n disallowed: config.security?.disallowed,\n rateLimiter,\n }),\n securityHeadersConfig: config.security?.headers ?? {},\n ssrRender: ssr.render,\n ssrRenderStreaming: ssr.renderStreaming,\n ssrStreamingEnabled: ssr.streamingEnabled,\n htmlHead: ssr.htmlHead,\n htmlTail: ssr.htmlTail,\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 server.listen(port, () => {\n console.log(`\\n Theo production server`)\n console.log(` → http://localhost:${String(port)}\\n`)\n })\n\n installGracefulShutdown(server)\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 — mirroring nitro's\n * `/_nitro/*` reserved-namespace pattern (knowledge-base/references/nitro/src/\n * runtime/internal/routes/dev-tasks.ts). 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 // \"NUNCA engula exceções\"). 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","/**\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 * `docs/plans/architecture-cleanup-plan.md` T4.2 Deferred sub-tasks.\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 // eslint-disable-next-line security/detect-non-literal-fs-filename -- distDir is from `theokit start`'s own caller-controlled config; the suffix is from a const literal array\n if (existsSync(path)) return path\n }\n return null\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 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 { 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 { 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\nexport interface LoadedRoutes {\n routes: ServerRouteNode[]\n actions: ActionNode[]\n wsRoutes: WebSocketRouteNode[]\n}\n\nexport function loadRoutesAndActions(distDir: string, serverDir: string): LoadedRoutes {\n const manifestPath = join(distDir, 'manifest.json')\n\n if (existsSync(manifestPath)) {\n const manifest = loadManifest(distDir, serverDir)\n return {\n routes: manifest.routes,\n actions: manifest.actions,\n wsRoutes: manifest.websockets,\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 }\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 { randomUUID } from 'node:crypto'\nimport type { IncomingMessage, ServerResponse } from 'node:http'\n\nimport { generateNonce } from '../../../server/auth/nonce.js'\nimport { type ReservedRoutes, serveReservedRoute } from '../../../server/define/health-route.js'\nimport { sendError } from '../../../server/http/send-response.js'\nimport { buildSecurityHeaders } from '../../../server/security/security-headers.js'\n\nimport {\n tryServeAction,\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\nexport interface RequestHandlerContext {\n buildCtx: (\n req: IncomingMessage,\n res: ServerResponse,\n requestId: string,\n startTime: number,\n ) => RequestHandlerCtx\n securityHeadersConfig: Parameters<typeof buildSecurityHeaders>[0]\n ssrRender: SsrRender | null\n ssrRenderStreaming: SsrRenderStreaming | null\n ssrStreamingEnabled: boolean\n htmlHead: string\n htmlTail: 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\nfunction buildSsrHtml(\n ctx: RequestHandlerContext,\n result: string | SsrRenderResult,\n nonce: string,\n): string {\n if (typeof result === 'string') {\n return ctx.htmlHead + result + 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 return ctx.htmlHead + rendered.html + hydrationScript + ctx.htmlTail\n }\n return ctx.htmlHead + 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 })\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))\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 const requestId = randomUUID()\n const start = Date.now()\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 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","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport { extname } from 'node:path'\n\nimport { executeAction } from '../../../server/http/action-execute.js'\nimport { executeRoute } from '../../../server/http/execute.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 { 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 * 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 // Runtime infra\n loadModule: LoadModule\n serverDir: string\n pluginRunner: PluginRunner | undefined\n transformer: TheoTransformer | undefined\n csrfMode: CsrfMode\n disallowed: DisallowedConfig | undefined\n rateLimiter:\n | ((req: IncomingMessage) => { limited: boolean; headers: Record<string, string> })\n | null\n}\n\n/** Apply rate limit; return true if request was limited (response sent). */\nfunction applyRateLimit(c: RequestHandlerCtx, method: string): boolean {\n if (!c.rateLimiter) return false\n const check = 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 (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/** 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 (applyRateLimit(c, c.req.method ?? 'GET')) return true\n\n const match = matchRoute(c.url, c.cachedRoutes)\n if (!match) {\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, BUT before any fs\n * call we resolve to absolute and reject with 403 if the resolved path\n * escapes `clientDir` (see EC-1 guard at line below). The guard is\n * authoritative; the rule cannot see it.\n */\nimport { existsSync, readFileSync, statSync } from 'node:fs'\nimport type { IncomingMessage, ServerResponse } from 'node:http'\nimport { resolve, extname } 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)\n const filePath = resolve(clientDir, '.' + urlPath)\n if (!filePath.startsWith(clientDir)) {\n res.writeHead(403)\n res.end('Forbidden')\n return true\n }\n\n if (!existsSync(filePath)) return false\n\n const stat = statSync(filePath)\n if (!stat.isFile()) return false\n\n const ext = extname(filePath)\n const contentType = MIME_TYPES[ext] ?? 'application/octet-stream'\n const content = readFileSync(filePath)\n\n res.writeHead(200, {\n 'Content-Type': contentType,\n 'Content-Length': content.length,\n })\n res.end(content)\n return true\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 type { ServerResponse } from 'node:http'\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?: { signal?: AbortSignal; nonce?: string },\n) => Promise<RenderStreamingResult>\n\nexport interface 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 rootDivMatch = /<div id=[\"']root[\"'][^>]*>/.exec(opts.indexHtml)\n if (rootDivMatch) {\n const splitIdx = opts.indexHtml.indexOf(rootDivMatch[0]) + rootDivMatch[0].length\n htmlHead = opts.indexHtml.slice(0, splitIdx)\n htmlTail = opts.indexHtml.slice(splitIdx)\n }\n\n return { enabled, streamingEnabled, render, renderStreaming, htmlHead, htmlTail }\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","existsSync","existsSync","extname","existsSync","resolve","extname","resolve","existsSync","readFileSync","join"]}