theokit 0.48.13 → 0.50.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 (327) hide show
  1. package/README.md +1 -0
  2. package/dist/{actions-virtual-module-YQXRSSMW.js → actions-virtual-module-5WBVSDOM.js} +22 -12
  3. package/dist/actions-virtual-module-5WBVSDOM.js.map +1 -0
  4. package/dist/{actions-virtual-module-LB4NGONI.js → actions-virtual-module-ZYLMNW6K.js} +13 -8
  5. package/dist/{actions-virtual-module-LB4NGONI.js.map → actions-virtual-module-ZYLMNW6K.js.map} +1 -1
  6. package/dist/adapters/agent-mount.d.ts +127 -0
  7. package/dist/adapters/agent-mount.js +24 -0
  8. package/dist/adapters/security-headers.d.ts +132 -0
  9. package/dist/adapters/security-headers.js +64 -0
  10. package/dist/adapters/security-headers.js.map +1 -0
  11. package/dist/adapters/web-shim.d.ts +100 -13
  12. package/dist/adapters/web-shim.js +158 -54
  13. package/dist/adapters/web-shim.js.map +1 -1
  14. package/dist/agent-GKUEL6OH.js +15 -0
  15. package/dist/agent-scan-BZa-pagG.d.ts +16 -0
  16. package/dist/{app-typed-client-GHO3EWZK.js → app-typed-client-4LAIEGFX.js} +23 -13
  17. package/dist/app-typed-client-4LAIEGFX.js.map +1 -0
  18. package/dist/{app-typed-client-G3J5G7E5.js → app-typed-client-DQM3Y6YY.js} +14 -9
  19. package/dist/app-typed-client-DQM3Y6YY.js.map +1 -0
  20. package/dist/aws-lambda-VKMYUMP2.js +261 -0
  21. package/dist/aws-lambda-VKMYUMP2.js.map +1 -0
  22. package/dist/{build-WU6AKKIB.js → build-FLX6VF7Q.js} +71 -26
  23. package/dist/build-FLX6VF7Q.js.map +1 -0
  24. package/dist/{bun-33RD6K7O.js → bun-L7PP6ID5.js} +105 -13
  25. package/dist/bun-L7PP6ID5.js.map +1 -0
  26. package/dist/{check-45NKUVSQ.js → check-GIPZBFTX.js} +2 -2
  27. package/dist/{chunk-KD5G3YXI.js → chunk-2AMLGJJA.js} +35 -9
  28. package/dist/chunk-2AMLGJJA.js.map +1 -0
  29. package/dist/chunk-3PBAN2YE.js +146 -0
  30. package/dist/chunk-3PBAN2YE.js.map +1 -0
  31. package/dist/{chunk-HBU2GIMZ.js → chunk-3QPVEJ7D.js} +15 -9
  32. package/dist/chunk-3QPVEJ7D.js.map +1 -0
  33. package/dist/{chunk-47CINLWF.js → chunk-44J2ANQC.js} +2 -2
  34. package/dist/{chunk-IEES3CHD.js → chunk-47MM2JUK.js} +8 -2
  35. package/dist/chunk-47MM2JUK.js.map +1 -0
  36. package/dist/chunk-4X6H2BXP.js +108 -0
  37. package/dist/chunk-4X6H2BXP.js.map +1 -0
  38. package/dist/{chunk-A7JBF5FO.js → chunk-5K4TDLRG.js} +8 -5
  39. package/dist/chunk-5K4TDLRG.js.map +1 -0
  40. package/dist/chunk-5YPXXSYY.js +181 -0
  41. package/dist/chunk-5YPXXSYY.js.map +1 -0
  42. package/dist/{chunk-YGAXV5HR.js → chunk-6J4JWHDJ.js} +191 -112
  43. package/dist/chunk-6J4JWHDJ.js.map +1 -0
  44. package/dist/chunk-72DMJBXI.js +424 -0
  45. package/dist/chunk-72DMJBXI.js.map +1 -0
  46. package/dist/chunk-7PM6K5EV.js +513 -0
  47. package/dist/chunk-7PM6K5EV.js.map +1 -0
  48. package/dist/{chunk-MTEWLGVY.js → chunk-BPYMC7SU.js} +4 -48
  49. package/dist/chunk-BPYMC7SU.js.map +1 -0
  50. package/dist/chunk-BU6RJPPJ.js +421 -0
  51. package/dist/chunk-BU6RJPPJ.js.map +1 -0
  52. package/dist/{chunk-FB2HBNIC.js → chunk-BX6EUYHU.js} +6 -2
  53. package/dist/chunk-BX6EUYHU.js.map +1 -0
  54. package/dist/{chunk-BIVCP6X5.js → chunk-C62IZEJI.js} +465 -202
  55. package/dist/chunk-C62IZEJI.js.map +1 -0
  56. package/dist/chunk-D4VP2QPR.js +16 -0
  57. package/dist/chunk-D4VP2QPR.js.map +1 -0
  58. package/dist/{chunk-J5MXCGKA.js → chunk-DHAD2O3S.js} +6 -6
  59. package/dist/chunk-DHAD2O3S.js.map +1 -0
  60. package/dist/chunk-E43VJ3E5.js +188 -0
  61. package/dist/chunk-E43VJ3E5.js.map +1 -0
  62. package/dist/chunk-EVZKNA2W.js +110 -0
  63. package/dist/chunk-EVZKNA2W.js.map +1 -0
  64. package/dist/chunk-FD4ZDTQ6.js +181 -0
  65. package/dist/chunk-FD4ZDTQ6.js.map +1 -0
  66. package/dist/chunk-FDOOBTXJ.js +17 -0
  67. package/dist/chunk-FDOOBTXJ.js.map +1 -0
  68. package/dist/chunk-FH3SQR6P.js +275 -0
  69. package/dist/chunk-FH3SQR6P.js.map +1 -0
  70. package/dist/chunk-HJHGTFEJ.js +23 -0
  71. package/dist/chunk-HJHGTFEJ.js.map +1 -0
  72. package/dist/{chunk-LXAESF4Y.js → chunk-HK4AZBKX.js} +7 -4
  73. package/dist/chunk-HK4AZBKX.js.map +1 -0
  74. package/dist/{chunk-T5C46IIU.js → chunk-HWBRS4DZ.js} +28 -269
  75. package/dist/chunk-HWBRS4DZ.js.map +1 -0
  76. package/dist/chunk-IRQGAC4L.js +52 -0
  77. package/dist/chunk-IRQGAC4L.js.map +1 -0
  78. package/dist/{chunk-FNTLKHZ7.js → chunk-JDN5SAAD.js} +7 -4
  79. package/dist/chunk-JDN5SAAD.js.map +1 -0
  80. package/dist/{chunk-GXEX4CBH.js → chunk-JIKNR5LX.js} +673 -484
  81. package/dist/chunk-JIKNR5LX.js.map +1 -0
  82. package/dist/{chunk-GRI4XHBJ.js → chunk-JWRCZIA4.js} +266 -108
  83. package/dist/chunk-JWRCZIA4.js.map +1 -0
  84. package/dist/{chunk-E576KYYT.js → chunk-KI4DOTN4.js} +25 -2
  85. package/dist/chunk-KI4DOTN4.js.map +1 -0
  86. package/dist/{chunk-ZB7D62OA.js → chunk-KUZVRJ7M.js} +3 -3
  87. package/dist/chunk-L4VFNFDL.js +248 -0
  88. package/dist/chunk-L4VFNFDL.js.map +1 -0
  89. package/dist/chunk-M2WC5MF7.js +127 -0
  90. package/dist/chunk-M2WC5MF7.js.map +1 -0
  91. package/dist/{chunk-O3JIAU3V.js → chunk-MCTC6HSE.js} +157 -103
  92. package/dist/chunk-MCTC6HSE.js.map +1 -0
  93. package/dist/{chunk-PXFXSFJL.js → chunk-NZ5JU6D3.js} +9 -9
  94. package/dist/{chunk-YRBR424R.js → chunk-OAUI273L.js} +338 -165
  95. package/dist/chunk-OAUI273L.js.map +1 -0
  96. package/dist/chunk-OGLS76RN.js +43 -0
  97. package/dist/chunk-OGLS76RN.js.map +1 -0
  98. package/dist/{chunk-7LVM22VG.js → chunk-OQCRCXCP.js} +6 -6
  99. package/dist/chunk-OQCRCXCP.js.map +1 -0
  100. package/dist/{chunk-OLGPYOLO.js → chunk-P6OS7652.js} +5 -2
  101. package/dist/chunk-P6OS7652.js.map +1 -0
  102. package/dist/chunk-Q5L5EGWZ.js +26 -0
  103. package/dist/chunk-Q5L5EGWZ.js.map +1 -0
  104. package/dist/{chunk-S433N3CT.js → chunk-QTHVHNJJ.js} +6 -36
  105. package/dist/chunk-QTHVHNJJ.js.map +1 -0
  106. package/dist/chunk-RPET332G.js +84 -0
  107. package/dist/chunk-RPET332G.js.map +1 -0
  108. package/dist/{chunk-646CA6RV.js → chunk-RQW5YMH7.js} +12 -4
  109. package/dist/chunk-RQW5YMH7.js.map +1 -0
  110. package/dist/{chunk-XALU5LCU.js → chunk-RWNYIU6A.js} +550 -146
  111. package/dist/chunk-RWNYIU6A.js.map +1 -0
  112. package/dist/chunk-SL7YUHPV.js +111 -0
  113. package/dist/chunk-SL7YUHPV.js.map +1 -0
  114. package/dist/chunk-U5PWXS3J.js +39 -0
  115. package/dist/chunk-U5PWXS3J.js.map +1 -0
  116. package/dist/chunk-ULDCFL2O.js +273 -0
  117. package/dist/chunk-ULDCFL2O.js.map +1 -0
  118. package/dist/{chunk-RWNSW4FM.js → chunk-UMNXCU3K.js} +12 -6
  119. package/dist/{chunk-RWNSW4FM.js.map → chunk-UMNXCU3K.js.map} +1 -1
  120. package/dist/chunk-VI7ZANB3.js +193 -0
  121. package/dist/chunk-VI7ZANB3.js.map +1 -0
  122. package/dist/chunk-VQPHPQ5L.js +14 -0
  123. package/dist/chunk-VQPHPQ5L.js.map +1 -0
  124. package/dist/chunk-WNJTJRM6.js +147 -0
  125. package/dist/chunk-WNJTJRM6.js.map +1 -0
  126. package/dist/chunk-WOBSEO75.js +790 -0
  127. package/dist/chunk-WOBSEO75.js.map +1 -0
  128. package/dist/{chunk-BMHS4WAN.js → chunk-XS7EX55U.js} +156 -42
  129. package/dist/chunk-XS7EX55U.js.map +1 -0
  130. package/dist/chunk-YN4W7LCX.js +31 -0
  131. package/dist/chunk-YN4W7LCX.js.map +1 -0
  132. package/dist/chunk-YSJOZEI6.js +1 -0
  133. package/dist/{chunk-JA2ZAT5Q.js → chunk-Z4PJMZLM.js} +2 -2
  134. package/dist/chunk-Z4PJMZLM.js.map +1 -0
  135. package/dist/{chunk-7VPQHEAJ.js → chunk-ZNZISJDZ.js} +6 -2
  136. package/dist/chunk-ZNZISJDZ.js.map +1 -0
  137. package/dist/chunk-ZWN3AODA.js +11 -0
  138. package/dist/chunk-ZWN3AODA.js.map +1 -0
  139. package/dist/cli/index.js +25 -10
  140. package/dist/cli/index.js.map +1 -1
  141. package/dist/client/core.d.ts +1 -1
  142. package/dist/client/core.js +2 -0
  143. package/dist/client/core.js.map +1 -1
  144. package/dist/client/index.d.ts +44 -10
  145. package/dist/client/index.js +35 -0
  146. package/dist/client/index.js.map +1 -1
  147. package/dist/cloudflare-SIG42OIW.js +335 -0
  148. package/dist/cloudflare-SIG42OIW.js.map +1 -0
  149. package/dist/config-support-WQHQIJTA.js +104 -0
  150. package/dist/config-support-WQHQIJTA.js.map +1 -0
  151. package/dist/{csrf-BBrEZSBW.d.ts → csrf-Dgot9qSM.d.ts} +1 -1
  152. package/dist/deno-deploy-LQAYOOPW.js +196 -0
  153. package/dist/deno-deploy-LQAYOOPW.js.map +1 -0
  154. package/dist/{dev-MUWJAZRD.js → dev-ANDSEVLB.js} +28 -18
  155. package/dist/dev-ANDSEVLB.js.map +1 -0
  156. package/dist/{dev-emit-GWD6IXV7.js → dev-emit-BFNMDCPB.js} +5 -5
  157. package/dist/{dev-emit-NBT6JD7R.js → dev-emit-MVAJAFGX.js} +5 -3
  158. package/dist/dev-emit-MVAJAFGX.js.map +1 -0
  159. package/dist/engine-singleton-X4R7AZBJ.js +315 -0
  160. package/dist/engine-singleton-X4R7AZBJ.js.map +1 -0
  161. package/dist/{generate-Y3GWM57K.js → generate-EN6EDITF.js} +43 -4
  162. package/dist/generate-EN6EDITF.js.map +1 -0
  163. package/dist/index-CzxtQcnp.d.ts +1058 -0
  164. package/dist/index.d.ts +4 -0
  165. package/dist/index.js +24 -13
  166. package/dist/index.js.map +1 -1
  167. package/dist/{info-XW7HGUPH.js → info-Y55RWS42.js} +8 -6
  168. package/dist/{info-XW7HGUPH.js.map → info-Y55RWS42.js.map} +1 -1
  169. package/dist/{internal-api-V5L65YSJ.js → internal-api-IP35YU3G.js} +22 -12
  170. package/dist/{internal-api-WEOSTMSN.js → internal-api-OPU456AT.js} +30 -16
  171. package/dist/internal-api-OPU456AT.js.map +1 -0
  172. package/dist/load-config-4ATXQUN3.js +16 -0
  173. package/dist/match-DmGgxjIU.d.ts +44 -0
  174. package/dist/{mcp-ULUFJNSZ.js → mcp-5LLNAGKA.js} +7 -7
  175. package/dist/netlify-C2IRCZKI.js +245 -0
  176. package/dist/netlify-C2IRCZKI.js.map +1 -0
  177. package/dist/node-OSVPYQ3D.js +10 -0
  178. package/dist/nonce-BXt7Qu_C.d.ts +31 -0
  179. package/dist/observability-bootstrap-MZMSOE66.js +15 -0
  180. package/dist/{openapi-HZXR335W.js → openapi-VFPEZSRI.js} +13 -11
  181. package/dist/{openapi-HZXR335W.js.map → openapi-VFPEZSRI.js.map} +1 -1
  182. package/dist/{plugin-runner-BFEcgtmJ.d.ts → plugin-runner-BVMOSxvb.d.ts} +1 -1
  183. package/dist/{plugin-types-D69-lJZ9.d.ts → plugin-types-BUVfUQ0V.d.ts} +13 -1
  184. package/dist/preview-GHPT2EQ5.js +23 -0
  185. package/dist/preview-GHPT2EQ5.js.map +1 -0
  186. package/dist/provider-resolver-Dx6QuWrw.d.ts +128 -0
  187. package/dist/registry-KBZDCFVQ.js +23 -0
  188. package/dist/route-config-Cm_ZMA1C.d.ts +72 -0
  189. package/dist/route-policy-BxOycCDq.d.ts +65 -0
  190. package/dist/router/element-scroll-restoration.d.ts +28 -0
  191. package/dist/router/element-scroll-restoration.js +96 -0
  192. package/dist/router/element-scroll-restoration.js.map +1 -0
  193. package/dist/{routes-OLNQX7CT.js → routes-BPLU3ISV.js} +11 -9
  194. package/dist/{routes-OLNQX7CT.js.map → routes-BPLU3ISV.js.map} +1 -1
  195. package/dist/{scan-7MJC6PYU.js → scan-YJEE4KQK.js} +2 -2
  196. package/dist/{schema-ZO3OSWVG.js → schema-SOAD43RQ.js} +7 -5
  197. package/dist/schemas-4AXHQMV3.js +25 -0
  198. package/dist/schemas-4AXHQMV3.js.map +1 -0
  199. package/dist/security-headers-Ccj7ncNx.d.ts +129 -0
  200. package/dist/server/agent/index.d.ts +2 -90
  201. package/dist/server/agent/index.js +1 -1
  202. package/dist/server/auth/index.d.ts +2 -21
  203. package/dist/server/auth/index.js +3 -2
  204. package/dist/server/cron/index.js +4 -3
  205. package/dist/server/define/index.d.ts +51 -57
  206. package/dist/server/define/index.js +10 -1
  207. package/dist/server/http/index.d.ts +7 -5
  208. package/dist/server/http/index.js +56 -12
  209. package/dist/server/index.d.ts +47 -439
  210. package/dist/server/index.js +119 -201
  211. package/dist/server/index.js.map +1 -1
  212. package/dist/server/jobs/index.js +4 -3
  213. package/dist/server/observability/index.d.ts +109 -35
  214. package/dist/server/observability/index.js +10 -7
  215. package/dist/server/plugins/index.d.ts +3 -3
  216. package/dist/server/scan/index.d.ts +47 -12
  217. package/dist/server/scan/index.js +13 -4
  218. package/dist/server/security/index.d.ts +61 -103
  219. package/dist/server/security/index.js +15 -6
  220. package/dist/server/webhook/index.d.ts +90 -3
  221. package/dist/server/webhook/index.js +12 -2
  222. package/dist/server-boundary-6B4ZQUY7.js +148 -0
  223. package/dist/server-boundary-6B4ZQUY7.js.map +1 -0
  224. package/dist/server-boundary-7VZQRPPX.js +133 -0
  225. package/dist/server-boundary-7VZQRPPX.js.map +1 -0
  226. package/dist/{services-typed-client-PSAGRPFF.js → services-typed-client-XGT5SUUN.js} +2 -2
  227. package/dist/{start-KR2JJR7K.js → start-UZDMOT7I.js} +342 -111
  228. package/dist/start-UZDMOT7I.js.map +1 -0
  229. package/dist/{static-M2W4HUWS.js → static-SVDWIOXJ.js} +24 -13
  230. package/dist/static-SVDWIOXJ.js.map +1 -0
  231. package/dist/{theo-cloud-XAHWOUFK.js → theo-cloud-3ET4G5T6.js} +9 -2
  232. package/dist/theo-cloud-3ET4G5T6.js.map +1 -0
  233. package/dist/vercel-BMCQKCWE.js +277 -0
  234. package/dist/vercel-BMCQKCWE.js.map +1 -0
  235. package/dist/vite-plugin/index.js +24 -13
  236. package/dist/vite-plugin-VKCT2LF2.js +42 -0
  237. package/dist/vite-plugin-VKCT2LF2.js.map +1 -0
  238. package/package.json +19 -6
  239. package/dist/actions-virtual-module-YQXRSSMW.js.map +0 -1
  240. package/dist/agent-7JJW3TPB.js +0 -15
  241. package/dist/app-typed-client-G3J5G7E5.js.map +0 -1
  242. package/dist/app-typed-client-GHO3EWZK.js.map +0 -1
  243. package/dist/aws-lambda-CYNDGU5O.js +0 -172
  244. package/dist/aws-lambda-CYNDGU5O.js.map +0 -1
  245. package/dist/build-WU6AKKIB.js.map +0 -1
  246. package/dist/bun-33RD6K7O.js.map +0 -1
  247. package/dist/chunk-646CA6RV.js.map +0 -1
  248. package/dist/chunk-6E5WKMDS.js +0 -67
  249. package/dist/chunk-6E5WKMDS.js.map +0 -1
  250. package/dist/chunk-6GGWS7J3.js +0 -91
  251. package/dist/chunk-6GGWS7J3.js.map +0 -1
  252. package/dist/chunk-7LVM22VG.js.map +0 -1
  253. package/dist/chunk-7VPQHEAJ.js.map +0 -1
  254. package/dist/chunk-A7JBF5FO.js.map +0 -1
  255. package/dist/chunk-AM3QABW5.js +0 -161
  256. package/dist/chunk-AM3QABW5.js.map +0 -1
  257. package/dist/chunk-BIVCP6X5.js.map +0 -1
  258. package/dist/chunk-BMHS4WAN.js.map +0 -1
  259. package/dist/chunk-E576KYYT.js.map +0 -1
  260. package/dist/chunk-FB2HBNIC.js.map +0 -1
  261. package/dist/chunk-FNTLKHZ7.js.map +0 -1
  262. package/dist/chunk-GRI4XHBJ.js.map +0 -1
  263. package/dist/chunk-GVW5EKEU.js +0 -422
  264. package/dist/chunk-GVW5EKEU.js.map +0 -1
  265. package/dist/chunk-GXEX4CBH.js.map +0 -1
  266. package/dist/chunk-HBU2GIMZ.js.map +0 -1
  267. package/dist/chunk-IEES3CHD.js.map +0 -1
  268. package/dist/chunk-J5MXCGKA.js.map +0 -1
  269. package/dist/chunk-JA2ZAT5Q.js.map +0 -1
  270. package/dist/chunk-KD5G3YXI.js.map +0 -1
  271. package/dist/chunk-LNVMHQ2Z.js +0 -54
  272. package/dist/chunk-LNVMHQ2Z.js.map +0 -1
  273. package/dist/chunk-LXAESF4Y.js.map +0 -1
  274. package/dist/chunk-MTEWLGVY.js.map +0 -1
  275. package/dist/chunk-O3JIAU3V.js.map +0 -1
  276. package/dist/chunk-OJLL4YD6.js +0 -403
  277. package/dist/chunk-OJLL4YD6.js.map +0 -1
  278. package/dist/chunk-OLGPYOLO.js.map +0 -1
  279. package/dist/chunk-S433N3CT.js.map +0 -1
  280. package/dist/chunk-T5C46IIU.js.map +0 -1
  281. package/dist/chunk-U267AOWS.js +0 -28
  282. package/dist/chunk-U267AOWS.js.map +0 -1
  283. package/dist/chunk-UW2TEAGR.js +0 -77
  284. package/dist/chunk-UW2TEAGR.js.map +0 -1
  285. package/dist/chunk-WPJOTQA5.js +0 -1
  286. package/dist/chunk-XALU5LCU.js.map +0 -1
  287. package/dist/chunk-XR74JD4M.js +0 -457
  288. package/dist/chunk-XR74JD4M.js.map +0 -1
  289. package/dist/chunk-YGAXV5HR.js.map +0 -1
  290. package/dist/chunk-YRBR424R.js.map +0 -1
  291. package/dist/cloudflare-KYUWCEPL.js +0 -122
  292. package/dist/cloudflare-KYUWCEPL.js.map +0 -1
  293. package/dist/deno-deploy-CCTB7HGS.js +0 -107
  294. package/dist/deno-deploy-CCTB7HGS.js.map +0 -1
  295. package/dist/dev-MUWJAZRD.js.map +0 -1
  296. package/dist/dev-emit-NBT6JD7R.js.map +0 -1
  297. package/dist/generate-Y3GWM57K.js.map +0 -1
  298. package/dist/index-BEtEv6ZH.d.ts +0 -575
  299. package/dist/load-config-VKD6LKWU.js +0 -14
  300. package/dist/match-CfbEFRG4.d.ts +0 -26
  301. package/dist/netlify-AFMDNKT4.js +0 -150
  302. package/dist/netlify-AFMDNKT4.js.map +0 -1
  303. package/dist/node-ZJQEJSP3.js +0 -10
  304. package/dist/registry-GKR3EWRW.js +0 -23
  305. package/dist/start-KR2JJR7K.js.map +0 -1
  306. package/dist/static-M2W4HUWS.js.map +0 -1
  307. package/dist/theo-cloud-XAHWOUFK.js.map +0 -1
  308. package/dist/vercel-SRS2DH6O.js +0 -133
  309. package/dist/vercel-SRS2DH6O.js.map +0 -1
  310. package/dist/vite-plugin-VPJFD4HK.js +0 -36
  311. /package/dist/{chunk-WPJOTQA5.js.map → adapters/agent-mount.js.map} +0 -0
  312. /package/dist/{agent-7JJW3TPB.js.map → agent-GKUEL6OH.js.map} +0 -0
  313. /package/dist/{check-45NKUVSQ.js.map → check-GIPZBFTX.js.map} +0 -0
  314. /package/dist/{chunk-47CINLWF.js.map → chunk-44J2ANQC.js.map} +0 -0
  315. /package/dist/{chunk-ZB7D62OA.js.map → chunk-KUZVRJ7M.js.map} +0 -0
  316. /package/dist/{chunk-PXFXSFJL.js.map → chunk-NZ5JU6D3.js.map} +0 -0
  317. /package/dist/{internal-api-WEOSTMSN.js.map → chunk-YSJOZEI6.js.map} +0 -0
  318. /package/dist/{dev-emit-GWD6IXV7.js.map → dev-emit-BFNMDCPB.js.map} +0 -0
  319. /package/dist/{internal-api-V5L65YSJ.js.map → internal-api-IP35YU3G.js.map} +0 -0
  320. /package/dist/{load-config-VKD6LKWU.js.map → load-config-4ATXQUN3.js.map} +0 -0
  321. /package/dist/{mcp-ULUFJNSZ.js.map → mcp-5LLNAGKA.js.map} +0 -0
  322. /package/dist/{node-ZJQEJSP3.js.map → node-OSVPYQ3D.js.map} +0 -0
  323. /package/dist/{scan-7MJC6PYU.js.map → observability-bootstrap-MZMSOE66.js.map} +0 -0
  324. /package/dist/{registry-GKR3EWRW.js.map → registry-KBZDCFVQ.js.map} +0 -0
  325. /package/dist/{schema-ZO3OSWVG.js.map → scan-YJEE4KQK.js.map} +0 -0
  326. /package/dist/{vite-plugin-VPJFD4HK.js.map → schema-SOAD43RQ.js.map} +0 -0
  327. /package/dist/{services-typed-client-PSAGRPFF.js.map → services-typed-client-XGT5SUUN.js.map} +0 -0
@@ -0,0 +1,315 @@
1
+ #!/usr/bin/env node
2
+ import "tsx/esm";
3
+
4
+ // src/cache/constants.ts
5
+ var THEO_T_PREFIX = "_THEO_T_";
6
+
7
+ // src/cache/cache-engine.ts
8
+ function createCacheEngine(opts) {
9
+ const { storage, defaults = {}, onError } = opts;
10
+ const inFlight = /* @__PURE__ */ new Map();
11
+ const bgInFlight = /* @__PURE__ */ new Set();
12
+ const undefinedLoaderWarned = /* @__PURE__ */ new Set();
13
+ async function getOrCompute(key, fn, options) {
14
+ const pending = inFlight.get(key);
15
+ if (pending) {
16
+ const value = await pending;
17
+ return { value, status: "miss" };
18
+ }
19
+ if (options.maxAge === 0) {
20
+ return claimAndRun(
21
+ key,
22
+ fn,
23
+ options,
24
+ /* skipWrite */
25
+ true
26
+ );
27
+ }
28
+ return claimAndRun(key, fn, options, false);
29
+ }
30
+ function claimAndRun(key, fn, options, skipWrite) {
31
+ let resolveOuter;
32
+ let rejectOuter;
33
+ const outerPromise = new Promise((resolve, reject) => {
34
+ resolveOuter = resolve;
35
+ rejectOuter = reject;
36
+ });
37
+ void outerPromise.catch(() => {
38
+ });
39
+ inFlight.set(key, outerPromise);
40
+ const work = (async () => {
41
+ try {
42
+ if (!skipWrite) {
43
+ const cached = await tryReadCached(key, options);
44
+ if (cached) {
45
+ resolveOuter(cached.value);
46
+ if (cached.status === "stale") {
47
+ scheduleBackgroundRevalidate(key, fn, options);
48
+ }
49
+ return cached;
50
+ }
51
+ }
52
+ const value = await runLoader(key, fn, options, skipWrite);
53
+ resolveOuter(value);
54
+ return { value, status: "miss" };
55
+ } catch (err) {
56
+ rejectOuter(err);
57
+ throw err;
58
+ } finally {
59
+ inFlight.delete(key);
60
+ }
61
+ })();
62
+ return work;
63
+ }
64
+ async function tryReadCached(key, options) {
65
+ let entry;
66
+ try {
67
+ entry = await storage.get(key);
68
+ } catch (err) {
69
+ onError?.(err, { phase: "get", key });
70
+ return void 0;
71
+ }
72
+ if (!entry) return void 0;
73
+ if (options.cacheVersion !== void 0 && entry.cacheVersion !== options.cacheVersion) {
74
+ return void 0;
75
+ }
76
+ if (typeof entry.body !== "string") return void 0;
77
+ let parsed;
78
+ try {
79
+ parsed = JSON.parse(entry.body);
80
+ } catch (err) {
81
+ onError?.(err, { phase: "get", key });
82
+ return void 0;
83
+ }
84
+ if (options.validate) {
85
+ try {
86
+ if (!options.validate(parsed)) return void 0;
87
+ } catch (err) {
88
+ onError?.(err, { phase: "get", key });
89
+ return void 0;
90
+ }
91
+ }
92
+ const age = Math.max(0, (Date.now() - entry.storedAt) / 1e3);
93
+ if (age <= entry.maxAge) {
94
+ const value = options.transform ? options.transform(parsed) : parsed;
95
+ return { value, status: "hit" };
96
+ }
97
+ if (age <= entry.maxAge + entry.swr) {
98
+ const value = options.transform ? options.transform(parsed) : parsed;
99
+ return { value, status: "stale" };
100
+ }
101
+ return void 0;
102
+ }
103
+ async function runLoader(key, fn, options, skipWrite = false) {
104
+ const raw = await fn();
105
+ const value = options.transform ? options.transform(raw) : raw;
106
+ if (skipWrite) return value;
107
+ if (options.skipCacheWhen?.(value)) return value;
108
+ if (options.validate) {
109
+ try {
110
+ if (!options.validate(value)) return value;
111
+ } catch (err) {
112
+ onError?.(err, { phase: "set", key });
113
+ return value;
114
+ }
115
+ }
116
+ if (value === void 0) {
117
+ if (!undefinedLoaderWarned.has(key)) {
118
+ undefinedLoaderWarned.add(key);
119
+ console.warn(`[theokit:cache] loader returned undefined for key "${key}"; entry not cached`);
120
+ }
121
+ return value;
122
+ }
123
+ try {
124
+ const entry = {
125
+ body: JSON.stringify(value),
126
+ status: 200,
127
+ headers: [],
128
+ storedAt: Date.now(),
129
+ maxAge: options.maxAge,
130
+ swr: options.swr ?? 0,
131
+ tags: options.tags ?? [],
132
+ cacheVersion: options.cacheVersion
133
+ };
134
+ await storage.set(key, entry);
135
+ } catch (err) {
136
+ onError?.(err, { phase: "set", key });
137
+ }
138
+ return value;
139
+ }
140
+ function scheduleBackgroundRevalidate(key, fn, options) {
141
+ if (bgInFlight.has(key)) return;
142
+ bgInFlight.add(key);
143
+ void runLoader(key, fn, options).catch((err) => {
144
+ onError?.(err, { phase: "revalidate", key });
145
+ }).finally(() => {
146
+ bgInFlight.delete(key);
147
+ });
148
+ }
149
+ return {
150
+ storage,
151
+ defaults,
152
+ getOrCompute,
153
+ async tryReadCached(key, opts2) {
154
+ const result = await tryReadCached(key, {
155
+ ...opts2,
156
+ maxAge: 0
157
+ // unused by tryReadCached
158
+ });
159
+ if (!result) return void 0;
160
+ return result;
161
+ },
162
+ async set(key, entry) {
163
+ await storage.set(key, entry);
164
+ },
165
+ async invalidate(key) {
166
+ inFlight.delete(key);
167
+ return storage.delete(key);
168
+ },
169
+ async invalidateTag(tag) {
170
+ return storage.deleteByTag(tag);
171
+ },
172
+ async revalidatePath(path, type) {
173
+ const tag = THEO_T_PREFIX + path + (type ? "/" + type : "");
174
+ return storage.deleteByTag(tag);
175
+ }
176
+ };
177
+ }
178
+
179
+ // src/cache/in-memory-adapter.ts
180
+ var InMemoryCacheAdapter = class {
181
+ name = "memory";
182
+ #entries = /* @__PURE__ */ new Map();
183
+ #tagIndex = /* @__PURE__ */ new Map();
184
+ #maxEntries;
185
+ constructor(opts = {}) {
186
+ this.#maxEntries = opts.maxEntries ?? 1e3;
187
+ }
188
+ async get(key) {
189
+ const entry = this.#entries.get(key);
190
+ if (entry === void 0) return void 0;
191
+ this.#entries.delete(key);
192
+ this.#entries.set(key, entry);
193
+ return entry;
194
+ }
195
+ async set(key, entry) {
196
+ const existing = this.#entries.get(key);
197
+ if (existing) {
198
+ this.#removeKeyFromTagIndex(key, existing.tags);
199
+ this.#entries.delete(key);
200
+ } else if (this.#entries.size >= this.#maxEntries) {
201
+ const oldestIter = this.#entries.keys().next();
202
+ if (!oldestIter.done) {
203
+ const oldestKey = oldestIter.value;
204
+ const oldestEntry = this.#entries.get(oldestKey);
205
+ if (oldestEntry) {
206
+ this.#removeKeyFromTagIndex(oldestKey, oldestEntry.tags);
207
+ }
208
+ this.#entries.delete(oldestKey);
209
+ }
210
+ }
211
+ this.#entries.set(key, entry);
212
+ for (const tag of entry.tags) {
213
+ let bucket = this.#tagIndex.get(tag);
214
+ if (!bucket) {
215
+ bucket = /* @__PURE__ */ new Set();
216
+ this.#tagIndex.set(tag, bucket);
217
+ }
218
+ bucket.add(key);
219
+ }
220
+ }
221
+ async delete(key) {
222
+ const entry = this.#entries.get(key);
223
+ if (!entry) return false;
224
+ this.#removeKeyFromTagIndex(key, entry.tags);
225
+ this.#entries.delete(key);
226
+ return true;
227
+ }
228
+ async deleteByTag(tag) {
229
+ const bucket = this.#tagIndex.get(tag);
230
+ if (!bucket || bucket.size === 0) return 0;
231
+ const keys = [...bucket];
232
+ for (const key of keys) {
233
+ const entry = this.#entries.get(key);
234
+ if (entry) {
235
+ this.#unindexFromOtherTags(key, entry.tags, tag);
236
+ }
237
+ this.#entries.delete(key);
238
+ }
239
+ this.#tagIndex.delete(tag);
240
+ return keys.length;
241
+ }
242
+ async size() {
243
+ return this.#entries.size;
244
+ }
245
+ async clear() {
246
+ this.#entries.clear();
247
+ this.#tagIndex.clear();
248
+ }
249
+ async *keys(prefix) {
250
+ for (const key of this.#entries.keys()) {
251
+ if (prefix && !key.startsWith(prefix)) continue;
252
+ yield key;
253
+ }
254
+ }
255
+ #removeKeyFromTagIndex(key, tags) {
256
+ for (const tag of tags) {
257
+ const bucket = this.#tagIndex.get(tag);
258
+ if (!bucket) continue;
259
+ bucket.delete(key);
260
+ if (bucket.size === 0) this.#tagIndex.delete(tag);
261
+ }
262
+ }
263
+ #unindexFromOtherTags(key, tags, skipTag) {
264
+ for (const otherTag of tags) {
265
+ if (otherTag === skipTag) continue;
266
+ const otherBucket = this.#tagIndex.get(otherTag);
267
+ if (!otherBucket) continue;
268
+ otherBucket.delete(key);
269
+ if (otherBucket.size === 0) this.#tagIndex.delete(otherTag);
270
+ }
271
+ }
272
+ };
273
+
274
+ // src/cache/engine-singleton.ts
275
+ var _engine;
276
+ function initCacheEngine(config, hooks = {}) {
277
+ if (_engine) {
278
+ throw new Error(
279
+ "Cache engine already initialized \u2014 call _resetCacheEngine() in tests, or check init order in production."
280
+ );
281
+ }
282
+ if (!config.enabled) {
283
+ throw new Error(
284
+ "initCacheEngine: config.enabled is false. Skip this call entirely when cache is disabled."
285
+ );
286
+ }
287
+ const adapter = config.storage === "memory" ? new InMemoryCacheAdapter({ maxEntries: config.maxEntries }) : config.storage;
288
+ _engine = createCacheEngine({
289
+ storage: adapter,
290
+ defaults: config.defaults,
291
+ onError: hooks.onError
292
+ });
293
+ return _engine;
294
+ }
295
+ function getCacheEngine() {
296
+ if (!_engine) {
297
+ throw new Error(
298
+ "Cache engine not initialized. Ensure theo.config.ts has `cache.enabled: true` and the framework bootstrap called initCacheEngine."
299
+ );
300
+ }
301
+ return _engine;
302
+ }
303
+ function isCacheEngineInitialized() {
304
+ return _engine !== void 0;
305
+ }
306
+ function _resetCacheEngine() {
307
+ _engine = void 0;
308
+ }
309
+ export {
310
+ _resetCacheEngine,
311
+ getCacheEngine,
312
+ initCacheEngine,
313
+ isCacheEngineInitialized
314
+ };
315
+ //# sourceMappingURL=engine-singleton-X4R7AZBJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cache/constants.ts","../src/cache/cache-engine.ts","../src/cache/in-memory-adapter.ts","../src/cache/engine-singleton.ts"],"sourcesContent":["/**\n * Single source of truth for cache subsystem constants.\n * Limits mirror Next.js (NEXT_CACHE_TAG_MAX_LENGTH / NEXT_CACHE_TAG_MAX_ITEMS)\n * — see reference doc §3.2 and ADR D6 of caching-and-revalidation-plan.md.\n */\n\nexport const CACHE_TAG_MAX_LENGTH = 256\nexport const CACHE_TAG_MAX_ITEMS = 128\nexport const THEO_T_PREFIX = '_THEO_T_'\n\nexport const DEFAULT_MAX_AGE = 1\nexport const DEFAULT_SWR_MULTIPLIER = 60\n","import { THEO_T_PREFIX } from './constants.js'\nimport type { CacheEntry, CacheStorageAdapter } from './storage-adapter.js'\n\nexport type CacheStatus = 'hit' | 'stale' | 'miss'\n\n/**\n * Process-wide fallbacks for the options a cache wrapper takes per call site.\n *\n * The engine reads none of them: `getOrCompute` and `tryReadCached` always\n * receive explicit values. They are carried here because the engine is the one\n * object every wrapper (`defineCachedRoute`) already holds, and a wrapper with\n * no declared value has nowhere else to look. Per-call-site options always win.\n *\n * Shaped to accept `NormalizedCacheConfig['defaults']` whole (#352): every field\n * the config schema declares is honoured, none is dropped on the way in.\n */\nexport interface CacheDefaults {\n /** seconds; fallback for a wrapper that declares no `maxAge`. */\n maxAge?: number\n /** seconds; fallback stale-while-revalidate window. */\n swr?: number\n /** whether responses with status >= 400 may be cached. */\n cacheErrors?: boolean\n /** version stamp applied to entries written without an explicit one. */\n cacheVersion?: string\n}\n\nexport interface CacheEngineOptions {\n storage: CacheStorageAdapter\n defaults?: CacheDefaults\n onError?: (err: unknown, ctx: { phase: 'get' | 'set' | 'revalidate'; key: string }) => void\n}\n\nexport interface GetOrComputeOptions<T> {\n maxAge: number\n swr?: number\n tags?: string[]\n cacheVersion?: string\n transform?: (raw: T) => T\n validate?: (raw: T) => boolean\n /**\n * When `true`, the value is returned but NOT written to cache.\n * Used by route middleware to bypass cache for uncacheable responses\n * (Set-Cookie, oversized body, status >= 400 with cacheErrors=false).\n */\n skipCacheWhen?: (raw: T) => boolean\n}\n\nexport interface CacheEngine {\n getOrCompute<T>(\n key: string,\n fn: () => Promise<T>,\n opts: GetOrComputeOptions<T>,\n ): Promise<{ value: T; status: CacheStatus }>\n\n /**\n * Public canonical cache read (T4.2 of architecture-review-remediation-plan,\n * PV-5 DRY consolidation). Returns the parsed value + status (`hit` | `stale`)\n * for callers that DON'T want to bind a loader function (e.g., HTTP route\n * middleware that may want to bypass on miss instead of running a loader).\n *\n * Returns undefined when:\n * - Entry not present in storage\n * - `opts.cacheVersion` mismatch with entry\n * - Body is not a JSON string (parse failed)\n * - `opts.validate` returns false (or throws — caller's onError invoked)\n * - Entry is fully expired (past maxAge + swr)\n */\n tryReadCached<T>(\n key: string,\n opts: { cacheVersion?: string; validate?: (v: T) => boolean },\n ): Promise<{ value: T; status: 'hit' | 'stale' } | undefined>\n\n set(key: string, entry: CacheEntry): Promise<void>\n invalidate(key: string): Promise<boolean>\n invalidateTag(tag: string): Promise<number>\n revalidatePath(path: string, type?: 'layout' | 'page'): Promise<number>\n\n /** Storage adapter passthrough (read-only access for diagnostics). */\n readonly storage: CacheStorageAdapter\n\n /**\n * Process-wide defaults the wrappers fall back to. Normalized to `{}` when the\n * factory received none, so a caller never has to guard the access.\n */\n readonly defaults: CacheDefaults\n}\n\n/**\n * Build a cache engine wrapping a storage adapter.\n *\n * Implements:\n * - SWR (fresh / stale / expired branching) — Astro `memory-provider.ts:423`-style.\n * - In-flight dedupe via `Map<key, Promise>` — Next.js `pendingRevalidates` pattern.\n * - Tag-based invalidation via adapter's deleteByTag.\n * - Path-as-tag encoding (revalidatePath sugar) — Next.js `revalidate.ts:105`.\n *\n * EC-8: Math.max(0, age) guards clock skew.\n * EC-9: validate callback wrapped in try/catch.\n * EC-10: loader returning undefined skips cache write + warns once.\n *\n * NOTE on max-lines-per-function disable below: createCacheEngine is a factory\n * closure that owns the in-flight/bg/warned maps. Splitting would force the\n * helpers across modules and re-introduce the shared mutable state through\n * parameter lists.\n */\n// eslint-disable-next-line max-lines-per-function\nexport function createCacheEngine(opts: CacheEngineOptions): CacheEngine {\n const { storage, defaults = {}, onError } = opts\n const inFlight = new Map<string, Promise<unknown>>()\n const bgInFlight = new Set<string>()\n const undefinedLoaderWarned = new Set<string>()\n\n async function getOrCompute<T>(\n key: string,\n fn: () => Promise<T>,\n options: GetOrComputeOptions<T>,\n ): Promise<{ value: T; status: CacheStatus }> {\n // Dedupe: concurrent first-miss shares the loader promise\n const pending = inFlight.get(key)\n if (pending) {\n const value = (await pending) as T\n return { value, status: 'miss' }\n }\n\n // maxAge=0 → always miss, never cache\n if (options.maxAge === 0) {\n return claimAndRun(key, fn, options, /* skipWrite */ true)\n }\n\n // Atomically claim the in-flight slot BEFORE any await (dedupe race fix).\n return claimAndRun(key, fn, options, false)\n }\n\n /**\n * Claims the in-flight slot synchronously, then performs the get/loader work\n * inside. Concurrent callers awaiting the same key share this slot.\n */\n function claimAndRun<T>(\n key: string,\n fn: () => Promise<T>,\n options: GetOrComputeOptions<T>,\n skipWrite: boolean,\n ): Promise<{ value: T; status: CacheStatus }> {\n let resolveOuter!: (v: T) => void\n let rejectOuter!: (e: unknown) => void\n const outerPromise = new Promise<T>((resolve, reject) => {\n resolveOuter = resolve\n rejectOuter = reject\n })\n // Prevent unhandled-rejection when no concurrent awaiter exists\n void outerPromise.catch(() => {\n /* swallow — the leader handles via work promise */\n })\n inFlight.set(key, outerPromise)\n\n const work = (async (): Promise<{ value: T; status: CacheStatus }> => {\n try {\n if (!skipWrite) {\n const cached = await tryReadCached<T>(key, options)\n if (cached) {\n // HIT or STALE — value already resolved\n resolveOuter(cached.value)\n if (cached.status === 'stale') {\n scheduleBackgroundRevalidate(key, fn, options)\n }\n return cached\n }\n }\n // Miss path: run loader\n const value = await runLoader(key, fn, options, skipWrite)\n resolveOuter(value)\n return { value, status: 'miss' as const }\n } catch (err) {\n rejectOuter(err)\n throw err\n } finally {\n inFlight.delete(key)\n }\n })()\n\n return work\n }\n\n // One inline staleness machine; each guard (version check, parse, validate,\n // age, swr window) is one short branch. Extracting per-step would dilute,\n // not clarify.\n // eslint-disable-next-line complexity\n async function tryReadCached<T>(\n key: string,\n options: GetOrComputeOptions<T>,\n ): Promise<{ value: T; status: CacheStatus } | undefined> {\n let entry: CacheEntry | undefined\n try {\n entry = await storage.get(key)\n } catch (err) {\n onError?.(err, { phase: 'get', key })\n return undefined\n }\n if (!entry) return undefined\n if (options.cacheVersion !== undefined && entry.cacheVersion !== options.cacheVersion) {\n return undefined\n }\n if (typeof entry.body !== 'string') return undefined\n let parsed: T\n try {\n parsed = JSON.parse(entry.body) as T\n } catch (err) {\n onError?.(err, { phase: 'get', key })\n return undefined\n }\n // EC-9: validate wrapped in try/catch\n if (options.validate) {\n try {\n if (!options.validate(parsed)) return undefined\n } catch (err) {\n onError?.(err, { phase: 'get', key })\n return undefined\n }\n }\n // EC-8: clamp age to non-negative (clock skew)\n const age = Math.max(0, (Date.now() - entry.storedAt) / 1000)\n if (age <= entry.maxAge) {\n const value = options.transform ? options.transform(parsed) : parsed\n return { value, status: 'hit' }\n }\n if (age <= entry.maxAge + entry.swr) {\n const value = options.transform ? options.transform(parsed) : parsed\n return { value, status: 'stale' }\n }\n return undefined\n }\n\n // runLoader always returns `value` by design: loader output is the caller's\n // contract; every branch short-circuits a *write*, never the return path.\n // eslint-disable-next-line sonarjs/no-invariant-returns, complexity\n async function runLoader<T>(\n key: string,\n fn: () => Promise<T>,\n options: GetOrComputeOptions<T>,\n skipWrite = false,\n ): Promise<T> {\n const raw = await fn()\n const value = options.transform ? options.transform(raw) : raw\n\n if (skipWrite) return value\n\n // skipCacheWhen sentinel — caller-controlled skip-write\n if (options.skipCacheWhen?.(value)) return value\n\n // EC-9: validate during write\n if (options.validate) {\n try {\n if (!options.validate(value)) return value\n } catch (err) {\n onError?.(err, { phase: 'set', key })\n return value\n }\n }\n\n // EC-10: undefined return → warn-once + skip cache\n if (value === undefined) {\n if (!undefinedLoaderWarned.has(key)) {\n undefinedLoaderWarned.add(key)\n console.warn(`[theokit:cache] loader returned undefined for key \"${key}\"; entry not cached`)\n }\n return value\n }\n\n try {\n const entry: CacheEntry = {\n body: JSON.stringify(value),\n status: 200,\n headers: [],\n storedAt: Date.now(),\n maxAge: options.maxAge,\n swr: options.swr ?? 0,\n tags: options.tags ?? [],\n cacheVersion: options.cacheVersion,\n }\n await storage.set(key, entry)\n } catch (err) {\n onError?.(err, { phase: 'set', key })\n }\n return value\n }\n\n function scheduleBackgroundRevalidate<T>(\n key: string,\n fn: () => Promise<T>,\n options: GetOrComputeOptions<T>,\n ): void {\n if (bgInFlight.has(key)) return\n bgInFlight.add(key)\n void runLoader(key, fn, options)\n .catch((err: unknown) => {\n onError?.(err, { phase: 'revalidate', key })\n })\n .finally(() => {\n bgInFlight.delete(key)\n })\n }\n\n return {\n storage,\n defaults,\n\n getOrCompute,\n\n async tryReadCached<T>(\n key: string,\n opts: { cacheVersion?: string; validate?: (v: T) => boolean },\n ): Promise<{ value: T; status: 'hit' | 'stale' } | undefined> {\n // Delegate to internal impl (which uses the broader GetOrComputeOptions\n // type). tryReadCached never returns status: 'miss' — that codepath\n // returns undefined. Narrow the type via assertion.\n const result = await tryReadCached<T>(key, {\n ...opts,\n maxAge: 0, // unused by tryReadCached\n })\n if (!result) return undefined\n return result as { value: T; status: 'hit' | 'stale' }\n },\n\n async set(key, entry) {\n await storage.set(key, entry)\n },\n\n async invalidate(key) {\n // Best-effort: clear in-flight too so next request starts fresh\n inFlight.delete(key)\n return storage.delete(key)\n },\n\n async invalidateTag(tag) {\n return storage.deleteByTag(tag)\n },\n\n async revalidatePath(path, type) {\n const tag = THEO_T_PREFIX + path + (type ? '/' + type : '')\n return storage.deleteByTag(tag)\n },\n }\n}\n","import type { CacheEntry, CacheStorageAdapter } from './storage-adapter.js'\n\nexport interface InMemoryCacheAdapterOptions {\n /** Maximum number of entries before LRU eviction. Default 1000. */\n maxEntries?: number\n}\n\n/**\n * In-memory cache adapter with LRU eviction + reverse tag index.\n *\n * Uses Map insertion-order for O(1) LRU (Astro LRUMap pattern).\n * Reverse index `tagIndex: Map<tag, Set<key>>` makes deleteByTag O(matched-keys).\n *\n * Invariants:\n * - `entries.size <= maxEntries` post-set.\n * - `tagIndex[tag].has(key)` ↔ `entries.get(key)?.tags.includes(tag)`.\n *\n * eslint-disable @typescript-eslint/require-await — the CacheStorageAdapter\n * interface is intentionally async so Redis/file/external adapters fit. The\n * in-memory variant returns immediately but keeps the async signature to\n * satisfy the contract.\n */\n/* eslint-disable @typescript-eslint/require-await */\nexport class InMemoryCacheAdapter implements CacheStorageAdapter {\n readonly name = 'memory'\n readonly #entries = new Map<string, CacheEntry>()\n readonly #tagIndex = new Map<string, Set<string>>()\n readonly #maxEntries: number\n\n constructor(opts: InMemoryCacheAdapterOptions = {}) {\n this.#maxEntries = opts.maxEntries ?? 1000\n }\n\n async get(key: string): Promise<CacheEntry | undefined> {\n const entry = this.#entries.get(key)\n if (entry === undefined) return undefined\n // LRU bump\n this.#entries.delete(key)\n this.#entries.set(key, entry)\n return entry\n }\n\n async set(key: string, entry: CacheEntry): Promise<void> {\n // Overwrite case: clean old tags first\n const existing = this.#entries.get(key)\n if (existing) {\n this.#removeKeyFromTagIndex(key, existing.tags)\n this.#entries.delete(key)\n } else if (this.#entries.size >= this.#maxEntries) {\n // LRU eviction\n const oldestIter = this.#entries.keys().next()\n if (!oldestIter.done) {\n const oldestKey = oldestIter.value\n const oldestEntry = this.#entries.get(oldestKey)\n if (oldestEntry) {\n this.#removeKeyFromTagIndex(oldestKey, oldestEntry.tags)\n }\n this.#entries.delete(oldestKey)\n }\n }\n this.#entries.set(key, entry)\n for (const tag of entry.tags) {\n let bucket = this.#tagIndex.get(tag)\n if (!bucket) {\n bucket = new Set()\n this.#tagIndex.set(tag, bucket)\n }\n bucket.add(key)\n }\n }\n\n async delete(key: string): Promise<boolean> {\n const entry = this.#entries.get(key)\n if (!entry) return false\n this.#removeKeyFromTagIndex(key, entry.tags)\n this.#entries.delete(key)\n return true\n }\n\n async deleteByTag(tag: string): Promise<number> {\n const bucket = this.#tagIndex.get(tag)\n if (!bucket || bucket.size === 0) return 0\n const keys = [...bucket]\n for (const key of keys) {\n const entry = this.#entries.get(key)\n if (entry) {\n this.#unindexFromOtherTags(key, entry.tags, tag)\n }\n this.#entries.delete(key)\n }\n this.#tagIndex.delete(tag)\n return keys.length\n }\n\n async size(): Promise<number> {\n return this.#entries.size\n }\n\n async clear(): Promise<void> {\n this.#entries.clear()\n this.#tagIndex.clear()\n }\n\n async *keys(prefix?: string): AsyncIterableIterator<string> {\n for (const key of this.#entries.keys()) {\n if (prefix && !key.startsWith(prefix)) continue\n yield key\n }\n }\n\n #removeKeyFromTagIndex(key: string, tags: string[]): void {\n for (const tag of tags) {\n const bucket = this.#tagIndex.get(tag)\n if (!bucket) continue\n bucket.delete(key)\n if (bucket.size === 0) this.#tagIndex.delete(tag)\n }\n }\n\n #unindexFromOtherTags(key: string, tags: string[], skipTag: string): void {\n for (const otherTag of tags) {\n if (otherTag === skipTag) continue\n const otherBucket = this.#tagIndex.get(otherTag)\n if (!otherBucket) continue\n otherBucket.delete(key)\n if (otherBucket.size === 0) this.#tagIndex.delete(otherTag)\n }\n }\n}\n","import type { CacheEngine, CacheEngineOptions } from './cache-engine.js'\nimport { createCacheEngine } from './cache-engine.js'\nimport { InMemoryCacheAdapter } from './in-memory-adapter.js'\nimport type { CacheStorageAdapter } from './storage-adapter.js'\n\nexport interface NormalizedCacheConfig {\n enabled: boolean\n storage: 'memory' | CacheStorageAdapter\n maxEntries: number\n defaults: {\n maxAge: number\n swr?: number\n cacheErrors: boolean\n }\n}\n\nlet _engine: CacheEngine | undefined\n\n/**\n * Initialize the singleton cache engine for this process.\n * Throws if called twice; tests should call `_resetCacheEngine()` between.\n */\nexport function initCacheEngine(\n config: NormalizedCacheConfig,\n hooks: Pick<CacheEngineOptions, 'onError'> = {},\n): CacheEngine {\n if (_engine) {\n throw new Error(\n 'Cache engine already initialized — call _resetCacheEngine() in tests, or check init order in production.',\n )\n }\n if (!config.enabled) {\n throw new Error(\n 'initCacheEngine: config.enabled is false. Skip this call entirely when cache is disabled.',\n )\n }\n const adapter =\n config.storage === 'memory'\n ? new InMemoryCacheAdapter({ maxEntries: config.maxEntries })\n : config.storage\n _engine = createCacheEngine({\n storage: adapter,\n defaults: config.defaults,\n onError: hooks.onError,\n })\n return _engine\n}\n\n/**\n * Resolve the singleton cache engine.\n * Throws a clear error if not initialized — usually means the framework\n * bootstrap missed calling initCacheEngine, or cache.enabled is false.\n */\nexport function getCacheEngine(): CacheEngine {\n if (!_engine) {\n throw new Error(\n 'Cache engine not initialized. Ensure theo.config.ts has `cache.enabled: true` and the framework bootstrap called initCacheEngine.',\n )\n }\n return _engine\n}\n\n/**\n * Whether `initCacheEngine` has already run in this process.\n *\n * Exists so a caller can be idempotent WITHOUT wrapping `initCacheEngine` in a\n * `catch`. A boot legitimately reaches this state more than once — HMR, a second\n * server started in one process, an integration test booting twice in one worker\n * — and catching the throw to absorb that would swallow the genuine\n * double-initialisation bug the throw exists to report.\n */\nexport function isCacheEngineInitialized(): boolean {\n return _engine !== undefined\n}\n\n/**\n * Test-only: clear the singleton so the next test can re-init.\n * Production code MUST NOT call this.\n */\nexport function _resetCacheEngine(): void {\n _engine = undefined\n}\n"],"mappings":"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","names":["opts"]}
@@ -5,6 +5,24 @@ import "tsx/esm";
5
5
  import { existsSync as existsSync2, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
6
6
  import { resolve as resolve2, dirname as dirname2 } from "path";
7
7
 
8
+ // src/cli/commands/generate-policy-placeholder.ts
9
+ var UNDECIDED_POLICY_IDENT = "undecidedPolicy";
10
+ function undecidedPolicyDeclaration(routePath, what) {
11
+ return [
12
+ `// TODO(policy): every route declares who may call it (ADR 0001). Generated as a REFUSAL`,
13
+ `// rather than 'public', because the generator cannot know your access model \u2014`,
14
+ `// ${what}.`,
15
+ `// Replace this with 'public' if the route is genuinely open, or with a check such as`,
16
+ `// \`({ subject, params }) => requireOwner(subject, ownerOf(params.id))\`, then delete the const.`,
17
+ `const ${UNDECIDED_POLICY_IDENT} = (): AccessDecision => ({`,
18
+ ` allowed: false,`,
19
+ ` reason:`,
20
+ ` '${routePath} still carries the policy the generator wrote, which refuses everyone. ' +`,
21
+ ` 'Declare who may call this route (ADR 0001).',`,
22
+ `})`
23
+ ];
24
+ }
25
+
8
26
  // src/cli/commands/generate-resource.ts
9
27
  import { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
10
28
  import { resolve, dirname } from "path";
@@ -80,16 +98,23 @@ function generateSchemaEntry(resourceName, fields) {
80
98
  function generateRouteIndex(resourceName, fields) {
81
99
  const bodyFields = fields.map((f) => ` ${f.name}: ${f.zodType},`).join("\n");
82
100
  return [
83
- `import { route } from 'theokit/server/define'`,
101
+ `import { route, type AccessDecision } from 'theokit/server/define'`,
84
102
  `import { z } from 'zod'`,
85
103
  `import { db } from '../../db/index.js'`,
86
104
  `import { ${resourceName} } from '../../db/schema.js'`,
87
105
  ``,
106
+ ...undecidedPolicyDeclaration(
107
+ `server/routes/${resourceName}/index.ts`,
108
+ "these methods read and write a table"
109
+ ),
110
+ ``,
88
111
  `export const GET = route()`,
112
+ ` .policy(${UNDECIDED_POLICY_IDENT})`,
89
113
  ` .handler(() => db.select().from(${resourceName}).all())`,
90
114
  ` .build()`,
91
115
  ``,
92
116
  `export const POST = route()`,
117
+ ` .policy(${UNDECIDED_POLICY_IDENT})`,
93
118
  ` .body(`,
94
119
  ` z.object({`,
95
120
  bodyFields,
@@ -107,13 +132,19 @@ function generateRouteIndex(resourceName, fields) {
107
132
  function generateRouteId(resourceName, fields) {
108
133
  const updateFields = fields.map((f) => ` ${f.name}: ${f.zodType}.optional(),`).join("\n");
109
134
  return [
110
- `import { route } from 'theokit/server/define'`,
135
+ `import { route, type AccessDecision } from 'theokit/server/define'`,
111
136
  `import { z } from 'zod'`,
112
137
  `import { db } from '../../db/index.js'`,
113
138
  `import { ${resourceName} } from '../../db/schema.js'`,
114
139
  `import { eq } from 'drizzle-orm'`,
115
140
  ``,
141
+ ...undecidedPolicyDeclaration(
142
+ `server/routes/${resourceName}/[id].ts`,
143
+ "these methods read, update and delete rows of a table"
144
+ ),
145
+ ``,
116
146
  `export const GET = route()`,
147
+ ` .policy(${UNDECIDED_POLICY_IDENT})`,
117
148
  ` .params(z.object({ id: z.coerce.number() }))`,
118
149
  ` .handler(({ params }) => {`,
119
150
  ` const item = db.select().from(${resourceName}).where(eq(${resourceName}.id, params.id)).get()`,
@@ -123,6 +154,7 @@ function generateRouteId(resourceName, fields) {
123
154
  ` .build()`,
124
155
  ``,
125
156
  `export const PUT = route()`,
157
+ ` .policy(${UNDECIDED_POLICY_IDENT})`,
126
158
  ` .params(z.object({ id: z.coerce.number() }))`,
127
159
  ` .body(`,
128
160
  ` z.object({`,
@@ -137,6 +169,7 @@ function generateRouteId(resourceName, fields) {
137
169
  ` .build()`,
138
170
  ``,
139
171
  `export const DELETE = route()`,
172
+ ` .policy(${UNDECIDED_POLICY_IDENT})`,
140
173
  ` .params(z.object({ id: z.coerce.number() }))`,
141
174
  ` .status(204)`,
142
175
  ` .handler(({ params }) => {`,
@@ -255,10 +288,16 @@ function toCamelCase(name) {
255
288
  }
256
289
  function generateRouteTemplate(name) {
257
290
  return [
258
- `import { route } from 'theokit/server'`,
291
+ `import { route, type AccessDecision } from 'theokit/server'`,
259
292
  `import { z } from 'zod'`,
260
293
  ``,
294
+ ...undecidedPolicyDeclaration(
295
+ `server/routes/${name}.ts`,
296
+ "a stub today is a real handler tomorrow"
297
+ ),
298
+ ``,
261
299
  `export const GET = route()`,
300
+ ` .policy(${UNDECIDED_POLICY_IDENT})`,
262
301
  ` .handler(({ ctx }) => {`,
263
302
  ` return { message: 'TODO: implement ${name} GET' }`,
264
303
  ` })`,
@@ -630,4 +669,4 @@ export {
630
669
  generate,
631
670
  generateCommand
632
671
  };
633
- //# sourceMappingURL=generate-Y3GWM57K.js.map
672
+ //# sourceMappingURL=generate-EN6EDITF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/generate.ts","../src/cli/commands/generate-policy-placeholder.ts","../src/cli/commands/generate-resource.ts","../src/cli/commands/generate-types.ts"],"sourcesContent":["import { existsSync, mkdirSync, writeFileSync } from 'node:fs'\nimport { resolve, dirname } from 'node:path'\n\nimport {\n UNDECIDED_POLICY_IDENT,\n undecidedPolicyDeclaration,\n} from './generate-policy-placeholder.js'\nimport { generateResource } from './generate-resource.js'\nimport {\n VALID_TYPES,\n type GeneratorType,\n type GenerateOptions,\n type GenerateResult,\n} from './generate-types.js'\n\nexport {}\n\nfunction toKebabCase(name: string): boolean {\n return /^[a-z][a-z0-9/-]*$/.test(name)\n}\n\n/**\n * Reserved JS identifier names that conflict with object prototype machinery\n * or would shadow built-in module shapes if used as action/route names.\n * Mirrors action-scan's RESERVED_NAMES (T1.4).\n */\nconst RESERVED_BASENAMES = new Set([\n 'index',\n 'constructor',\n '__proto__',\n 'prototype',\n 'hasOwnProperty',\n])\n\n/**\n * Validate that a name segment doesn't hit the reserved-identifier list.\n * Checks the BASENAME (last `/` segment) — nested `admin/constructor` still\n * rejected because the file `constructor.ts` would be the conflict.\n */\nfunction hasReservedSegment(name: string): boolean {\n const basename = name.includes('/') ? (name.split('/').pop() ?? name) : name\n return RESERVED_BASENAMES.has(basename)\n}\n\n/**\n * EC-4: validate that resolving `targetSubpath` under `cwd` stays inside `cwd`.\n * Returns `true` when path is safe (stays inside), `false` when it escapes via\n * `..`, absolute path, null byte, or similar traversal vector.\n */\nfunction isPathInside(cwd: string, targetSubpath: string): boolean {\n if (targetSubpath.includes('\\x00')) return false\n if (targetSubpath.startsWith('/') || targetSubpath.startsWith('\\\\')) return false\n const resolved = resolve(cwd, targetSubpath)\n const cwdResolved = resolve(cwd)\n const sep = process.platform === 'win32' ? '\\\\' : '/'\n return resolved === cwdResolved || resolved.startsWith(cwdResolved + sep)\n}\n\nfunction toPascalCase(name: string): string {\n return name\n .split(/[-/]/)\n .map((s) => s.charAt(0).toUpperCase() + s.slice(1))\n .join('')\n}\n\nfunction toCamelCase(name: string): string {\n const pascal = toPascalCase(name)\n return pascal.charAt(0).toLowerCase() + pascal.slice(1)\n}\n\nfunction generateRouteTemplate(name: string): string {\n return [\n `import { route, type AccessDecision } from 'theokit/server'`,\n `import { z } from 'zod'`,\n ``,\n ...undecidedPolicyDeclaration(\n `server/routes/${name}.ts`,\n 'a stub today is a real handler tomorrow',\n ),\n ``,\n `export const GET = route()`,\n ` .policy(${UNDECIDED_POLICY_IDENT})`,\n ` .handler(({ ctx }) => {`,\n ` return { message: 'TODO: implement ${name} GET' }`,\n ` })`,\n ` .build()`,\n ``,\n ].join('\\n')\n}\n\nfunction generateControllerTemplate(name: string): string {\n const className = toPascalCase(name) + 'Controller'\n const baseName = name.split('/').pop() ?? name\n return [\n `// AUTO-GENERATED by \\`theokit generate controller ${name}\\``,\n `import { Controller, Get } from '@theokit/http'`,\n ``,\n `@Controller('${baseName}')`,\n `export class ${className} {`,\n ` @Get()`,\n ` findAll(): string {`,\n ` return 'This action returns all ${baseName}'`,\n ` }`,\n `}`,\n ``,\n ].join('\\n')\n}\n\nfunction generateActionTemplate(name: string): string {\n const camel = toCamelCase(name)\n return [\n `import { action } from 'theokit/server'`,\n `import { z } from 'zod'`,\n ``,\n `export const ${camel} = action()`,\n ` .input(z.object({}))`,\n ` .handler(({ input, ctx }) => {`,\n ` return { message: 'TODO: implement ${name}' }`,\n ` })`,\n ` .build()`,\n ``,\n ].join('\\n')\n}\n\n/**\n * Co-located test template for `theokit generate action <name>` (T5.2 +\n * plan Q4 scenario 1: roundtrip serialize). Skeleton uses vitest BDD shape\n * per testing.md.\n */\nfunction generateAgentTemplate(name: string): string {\n return [\n `import { AgentBuilder } from '@theokit/agents'`,\n `import { z } from 'zod'`,\n ``,\n `// Zero-config: this file is auto-served at POST /api/agents/${name}.`,\n `// Add tools with tool('name')...build() and chain them via .tool(...).`,\n `export default AgentBuilder.create()`,\n ` .input(z.object({ message: z.string() }))`,\n ` .model('openai/gpt-4o-mini')`,\n ` .system('You are a helpful ${name} assistant.')`,\n ` .build()`,\n ``,\n ].join('\\n')\n}\n\nfunction generateToolboxTemplate(name: string): string {\n const camel = toCamelCase(name)\n return [\n `import { tool } from 'theokit/server'`,\n `import { z } from 'zod'`,\n ``,\n `export const ${camel}Hello = tool('${name}_hello')`,\n ` .describe('Say hello')`,\n ` .input(z.object({ name: z.string() }))`,\n ` .execute(({ name }) => \\`Hello, \\${name}!\\`)`,\n ` .build()`,\n ``,\n ].join('\\n')\n}\n\nfunction generateWorkflowTemplate(name: string): string {\n const camel = toCamelCase(name)\n return [\n `import { Workflow, fn } from '@theokit/sdk/workflow'`,\n ``,\n `/**`,\n ` * A minimal workflow — a typed, multi-step pipeline (@theokit/sdk). Each \\`fn(...)\\` step is a pure`,\n ` * function; a step can also run an agent via \\`agentStep(name, agent, mapInput)\\`. Import + run it from`,\n ` * a route, action, cron job, or tool:`,\n ` *`,\n ` * const run = await ${camel}Workflow.run({ name: 'Ada' })`,\n ` * console.log(run.status, run.output) // 'completed' 'Hello, Ada!'`,\n ` */`,\n `export const ${camel}Workflow = Workflow.create({ name: '${name}' })`,\n ` .then(fn('normalize', (input: { name: string }) => ({ name: input.name.trim() })))`,\n ` .then(fn('greet', (step: { name: string }) => \\`Hello, \\${step.name}!\\`))`,\n ` .commit()`,\n ``,\n ].join('\\n')\n}\n\nfunction generateEvalTemplate(name: string): string {\n const camel = toCamelCase(name)\n return [\n `import { Eval, Scorers } from '@theokit/sdk/eval'`,\n ``,\n `/**`,\n ` * An eval for your agent (@theokit/sdk) — runs the model over a dataset and scores each output.`,\n ` * To score the REAL agent, mirror its config: point \\`agent.model\\` (and, ideally, a \\`systemPrompt\\`)`,\n ` * at the same values your \\`agents/chat.ts\\` uses. Run it (needs a provider key in the environment):`,\n ` *`,\n ` * const run = await ${camel}Eval.run()`,\n ` * console.log(run.aggregate.meanScore)`,\n ` */`,\n `export const ${camel}Eval = Eval.create({`,\n ` name: '${name}',`,\n ` dataset: [{ input: 'Say ok', expected: 'ok' }],`,\n ` scorers: [Scorers.containsExpected({ caseSensitive: false })],`,\n ` // Mirror your agent: same model (+ systemPrompt) so this evaluates the agent your users talk to.`,\n ` agent: { apiKey: process.env.OPENROUTER_API_KEY ?? '', model: { id: 'openai/gpt-4o-mini' } },`,\n `})`,\n ``,\n ].join('\\n')\n}\n\nfunction generateSandboxTemplate(name: string): string {\n const camel = toCamelCase(name)\n const base = name.split('/').pop() ?? name\n const snake = base.replace(/-/g, '_')\n return [\n `import { tool } from 'theokit/server'`,\n `import { LocalSandbox } from '@theokit/sdk/sandbox'`,\n `import { z } from 'zod'`,\n ``,\n `/**`,\n ` * A sandbox-backed agent tool. \\`LocalSandbox\\` (@theokit/sdk) runs a shell command with a timeout +`,\n ` * output cap, isolated from your app process — so the agent can run commands SAFELY. This IS an agent`,\n ` * capability: connect it to your agent with \\`.tool(...)\\`:`,\n ` *`,\n ` * // agents/chat.ts`,\n ` * import { ${camel}Tool } from './sandbox/${base}.js'`,\n ` * AgentBuilder.create().model(...).tool(${camel}Tool).build()`,\n ` */`,\n `export const ${camel}Tool = tool('${snake}')`,\n ` .describe('Run a shell command in an isolated sandbox and return its output.')`,\n ` .input(z.object({ command: z.string().describe('The shell command to run, e.g. \"ls -la\"') }))`,\n ` .execute(async ({ command }) => {`,\n ` const sandbox = new LocalSandbox({ timeoutMs: 5_000 })`,\n ` const { stdout, stderr, exitCode } = await sandbox.execute(command)`,\n ` return exitCode === 0 ? stdout : \\`exit \\${exitCode}: \\${stderr}\\``,\n ` })`,\n ` .build()`,\n ``,\n ].join('\\n')\n}\n\nfunction generateScheduleTemplate(name: string): string {\n const base = name.split('/').pop() ?? name\n return [\n `import { defineCron } from 'theokit/server/cron'`,\n ``,\n `/**`,\n ` * A scheduled agent run — a first-class TheoKit cron. \\`theokit build\\` discovers it automatically and`,\n ` * translates the schedule to your deploy target's native cron (Vercel / Cloudflare / AWS). No manual`,\n ` * scheduler to start. The handler is where you invoke your agent — POST to \\`/api/agents/chat\\`, or use`,\n ` * \\`@theokit/sdk\\`'s \\`Agent\\` with the same model + system prompt as \\`agents/chat.ts\\`.`,\n ` *`,\n ` * Schedules are UTC (https://crontab.guru). \\`signal\\` aborts when the scheduler stops.`,\n ` */`,\n `export default defineCron('${base}', {`,\n ` schedule: '0 9 * * *', // every day at 09:00 UTC`,\n ` async handler({ traceId, scheduledAt, signal }) {`,\n ` void signal`,\n ` // Invoke your agent here — e.g. fetch your own \\`/api/agents/chat\\` endpoint, or call the SDK Agent.`,\n ` console.log(\\`[${base}] fired at \\${scheduledAt.toISOString()} (trace \\${traceId})\\`)`,\n ` },`,\n `})`,\n ``,\n ].join('\\n')\n}\n\nfunction generateMemoryTemplate(_name: string): string {\n return [\n `/**`,\n ` * Conversation memory — nothing to wire.`,\n ` *`,\n ` * Since @theokit/sdk 4.0, every agent session persists AUTOMATICALLY to a native Claude-shaped`,\n ` * transcript. TheoKit roots it at your app under \\`.data/agent-sessions/projects/<cwd>/<agentId>.jsonl\\`,`,\n ` * keyed by the conversation's session id — a same-session follow-up request resumes prior turns with`,\n ` * zero setup. There is no storage adapter to construct or pass to the agent anymore.`,\n ` *`,\n ` * Keep these transcripts out of git — add \\`.data/\\` to your \\`.gitignore\\`.`,\n ` *`,\n ` * Advanced: to change WHERE sessions are written (e.g. \\`~/.claude\\` so the Claude Code CLI can`,\n ` * \\`--continue\\` them), set the SDK's \\`local.baseDir\\` where you create the agent. Most apps never need to.`,\n ` */`,\n `export {}`,\n ``,\n ].join('\\n')\n}\n\nfunction resolveTemplate(\n cwd: string,\n type: GeneratorType,\n name: string,\n): { filePath: string; content: string } | null {\n switch (type) {\n // Agent-capability generators. These live UNDER `agents/` — they are facets of the agent domain,\n // not standalone top-level concerns — and the folder-semantic scanner treats each as composition\n // (never a phantom route).\n case 'workflow':\n return {\n filePath: resolve(cwd, 'agents/workflows', `${name}.ts`),\n content: generateWorkflowTemplate(name),\n }\n case 'eval':\n return {\n filePath: resolve(cwd, 'agents/evals', `${name}.ts`),\n content: generateEvalTemplate(name),\n }\n case 'sandbox':\n return {\n filePath: resolve(cwd, 'agents/sandbox', `${name}.ts`),\n content: generateSandboxTemplate(name),\n }\n case 'schedule':\n return {\n filePath: resolve(cwd, 'agents/schedules', `${name}.ts`),\n content: generateScheduleTemplate(name),\n }\n case 'memory':\n return {\n filePath: resolve(cwd, 'agents/memory', `${name}.ts`),\n content: generateMemoryTemplate(name),\n }\n case 'route':\n return {\n filePath: resolve(cwd, 'server/routes', `${name}.ts`),\n content: generateRouteTemplate(name),\n }\n case 'action':\n return {\n filePath: resolve(cwd, 'server/actions', `${name}.ts`),\n content: generateActionTemplate(name),\n }\n case 'page':\n return { filePath: resolve(cwd, `app/${name}/page.tsx`), content: generatePageTemplate(name) }\n case 'ws':\n return {\n filePath: resolve(cwd, 'server/ws', `${name}.ts`),\n content: generateWsTemplate(name),\n }\n case 'controller':\n return {\n filePath: resolve(cwd, 'server/controllers', `${name}.controller.ts`),\n content: generateControllerTemplate(name),\n }\n case 'agent':\n return {\n filePath: resolve(cwd, 'server/agents', `${name}.agent.ts`),\n content: generateAgentTemplate(name),\n }\n case 'toolbox':\n return {\n filePath: resolve(cwd, 'server/toolboxes', `${name}.tools.ts`),\n content: generateToolboxTemplate(name),\n }\n default:\n return null\n }\n}\n\nfunction generateActionTestTemplate(name: string): string {\n const camel = toCamelCase(name)\n return [\n `import { describe, it, expect } from 'vitest'`,\n ``,\n `import { ${camel} } from './${name.split('/').pop()}.js'`,\n ``,\n `describe('${name} action', () => {`,\n ` it('should accept a valid input shape', () => {`,\n ` expect(${camel}.input).toBeDefined()`,\n ` expect(typeof ${camel}.handler).toBe('function')`,\n ` })`,\n ``,\n ` it('should reject invalid input via zod schema', () => {`,\n ` const parsed = ${camel}.input.safeParse({ __invalid: true })`,\n ` // Empty object schema accepts {}; tighten this assertion when adding fields.`,\n ` expect(parsed.success).toBe(true)`,\n ` })`,\n `})`,\n ``,\n ].join('\\n')\n}\n\nfunction generatePageTemplate(name: string): string {\n const pascal = toPascalCase(name)\n return [`export default function ${pascal}Page() {`, ` return <h1>${pascal}</h1>`, `}`, ``].join(\n '\\n',\n )\n}\n\nfunction generateWsTemplate(_name: string): string {\n return [\n `import { defineWebSocket } from 'theokit/server'`,\n ``,\n `export default defineWebSocket({`,\n ` onMessage(ws, data) {`,\n ` ws.send(\\`echo: \\${data}\\`)`,\n ` },`,\n `})`,\n ``,\n ].join('\\n')\n}\n\n/**\n * Programmatic generate. Returns a structured result instead of throwing —\n * Studio (`theokit_generate` tool) consumes this directly. The CLI wrapper\n * below maps the structured result to console output + exit code semantics.\n */\n// eslint-disable-next-line @typescript-eslint/require-await\nexport async function generate(opts: GenerateOptions): Promise<GenerateResult> {\n const { cwd, type, name } = opts\n\n if (!existsSync(resolve(cwd, 'theo.config.ts')) && !existsSync(resolve(cwd, 'theo.config.js'))) {\n return {\n status: 'not_a_project',\n message: 'Not a Theo project. cwd has no theo.config.ts or theo.config.js',\n }\n }\n\n if (!VALID_TYPES.includes(type as GeneratorType)) {\n return {\n status: 'invalid_kind',\n message: `Invalid generator type \"${type}\". Available: ${VALID_TYPES.join(', ')}`,\n }\n }\n\n if (!name || !toKebabCase(name)) {\n return {\n status: 'invalid_name',\n message: `Invalid name \"${name}\". Use kebab-case: lowercase letters, numbers, hyphens.`,\n }\n }\n\n // EC-2-related: reject reserved JS identifier basenames (would shadow\n // built-in prototype machinery in virtual module emit or scan).\n if (hasReservedSegment(name)) {\n return {\n status: 'invalid_name',\n message: `Reserved name \"${name}\" — basename collides with built-in identifier (index/constructor/__proto__/prototype/hasOwnProperty).`,\n }\n }\n\n // Resource generates multiple files — handle separately\n if (type === 'resource') {\n return generateResource(cwd, name, opts.fields ?? [])\n }\n\n const resolved = resolveTemplate(cwd, type as GeneratorType, name)\n if (resolved === null) {\n return { status: 'invalid_kind', message: `Unknown type: ${type}` }\n }\n const { filePath, content } = resolved\n\n // EC-4: confirm the resolved filePath stays inside cwd. `toKebabCase`\n // already rejects most traversal vectors but a defense-in-depth check\n // against `..` slipping in via valid-looking segments is cheap.\n const relativeFromCwd = filePath.startsWith(resolve(cwd))\n ? filePath.slice(resolve(cwd).length + 1)\n : filePath\n if (!isPathInside(cwd, relativeFromCwd)) {\n return {\n status: 'invalid_name',\n message: `Path traversal denied: \"${name}\" would escape project root.`,\n }\n }\n\n if (existsSync(filePath)) {\n return { status: 'already_exists', filePath, kind: type as GeneratorType, name }\n }\n\n mkdirSync(dirname(filePath), { recursive: true })\n writeFileSync(filePath, content)\n\n // T5.2 + plan Q4: emit co-located test file alongside actions (only\n // for action type; routes/pages/ws keep prior single-file behavior).\n // Skip if existing test file present (preserve user-customized tests).\n if (type === 'action') {\n const testPath = filePath.replace(/\\.ts$/, '.test.ts')\n if (!existsSync(testPath)) {\n writeFileSync(testPath, generateActionTestTemplate(name))\n }\n }\n\n return { status: 'created', filePath, kind: type as GeneratorType, name }\n}\n\n/**\n * CLI entry point — preserves the original surface (throws + console.log).\n * Wraps the programmatic `generate` function.\n */\nexport async function generateCommand(\n type: string,\n name: string,\n fields?: string[],\n): Promise<void> {\n const result = await generate({ cwd: process.cwd(), type, name, fields })\n switch (result.status) {\n case 'not_a_project':\n throw new Error('Not a Theo project. Run this from a project root with theo.config.ts')\n case 'invalid_kind':\n throw new Error(result.message ?? 'Invalid kind')\n case 'invalid_name':\n throw new Error(\n `Invalid name \"${name}\". Use kebab-case: lowercase letters, numbers, hyphens. Example: my-route`,\n )\n case 'already_exists':\n console.log(`\\n ⚠ ${result.filePath} already exists. Skipping.\\n`)\n return\n case 'created':\n console.log(`\\n ✓ Created ${type}: ${result.filePath}\\n`)\n return\n }\n}\n","/**\n * The access policy a generated route carries until its author decides one.\n *\n * ADR 0001 made an undeclared `policy` a build error because \"a route that nobody had thought\n * about was indistinguishable from a route deliberately left open\". The generators then wrote\n * `'public'` — including on five methods that read and write a database table — so a generated\n * file was the not-thought-about case wearing the deliberate value, which is the precise state\n * the gate exists to make impossible (usetheokit/theokit#416). `theo build` accepted it, because\n * `assertEveryMethodDeclaresPolicy` asks whether a policy was declared, not which one.\n *\n * A generated route now REFUSES. The author still has to write the answer down — the gate's whole\n * purpose — but the value standing in until they do is the safe one rather than the open one.\n *\n * ## Why an AccessDecision and not `() => false`\n *\n * `evaluateRoutePolicy` maps a bare `false` to \"access denied by route policy\", which tells the\n * reader nothing about where to go. The contract already says a denial \"carries its reason so the\n * caller can say it\", so the refusal names its own file: the first `curl` against a forgotten\n * route prints the path to edit.\n *\n * ## Why a named const rather than a lambda per method\n *\n * Five methods would mean five copies, and deleting four of them is the kind of chore that leaves\n * the fifth behind. One const is one thing to replace, and `grep -rn undecidedPolicy` counts the\n * routes still awaiting a decision — which is the number ADR 0001 wanted to make greppable, and\n * which `grep -c \"policy('public')\"` could not give once generated placeholders were mixed in with\n * real decisions.\n */\n\n/** The identifier the generated methods reference. Exported so callers cannot misspell it. */\nexport const UNDECIDED_POLICY_IDENT = 'undecidedPolicy'\n\n/**\n * Lines declaring the placeholder, to splice into a generated module.\n *\n * @param routePath - the generated file's own path, repo-relative, so the refusal can name it\n * @param what - what the route does, in one clause, for the TODO comment\n */\nexport function undecidedPolicyDeclaration(routePath: string, what: string): string[] {\n return [\n `// TODO(policy): every route declares who may call it (ADR 0001). Generated as a REFUSAL`,\n `// rather than 'public', because the generator cannot know your access model —`,\n `// ${what}.`,\n `// Replace this with 'public' if the route is genuinely open, or with a check such as`,\n `// \\`({ subject, params }) => requireOwner(subject, ownerOf(params.id))\\`, then delete the const.`,\n `const ${UNDECIDED_POLICY_IDENT} = (): AccessDecision => ({`,\n ` allowed: false,`,\n ` reason:`,\n ` '${routePath} still carries the policy the generator wrote, which refuses everyone. ' +`,\n ` 'Declare who may call this route (ADR 0001).',`,\n `})`,\n ]\n}\n","import { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { resolve, dirname } from 'node:path'\n\nimport {\n UNDECIDED_POLICY_IDENT,\n undecidedPolicyDeclaration,\n} from './generate-policy-placeholder.js'\nimport type { GenerateResult } from './generate-types.js'\n\n// --- Field parsing ---\n\nconst ALLOWED_FIELD_TYPES = new Set(['string', 'text', 'number', 'boolean'])\nconst RESERVED_FIELDS = new Set(['id', 'createdAt', 'created_at'])\n\ninterface ResourceField {\n name: string\n type: 'string' | 'text' | 'number' | 'boolean'\n drizzleColumn: string\n zodType: string\n}\n\nfunction parseResourceFields(args: string[]): ResourceField[] {\n if (args.length === 0) {\n throw new Error(\n 'Resource requires at least one field. Example: theokit generate resource posts title:string',\n )\n }\n return args.map((arg) => {\n const parts = arg.split(':')\n if (parts.length !== 2 || !parts[0] || !parts[1]) {\n throw new Error(`Invalid field \"${arg}\". Use name:type format (e.g. title:string)`)\n }\n const [name, type] = parts\n if (!ALLOWED_FIELD_TYPES.has(type)) {\n throw new Error(\n `Unknown field type \"${type}\" in \"${arg}\". Valid types: ${[...ALLOWED_FIELD_TYPES].join(', ')}`,\n )\n }\n if (RESERVED_FIELDS.has(name)) {\n throw new Error(`Field \"${name}\" is reserved (auto-generated by the framework)`)\n }\n const fieldType = type as ResourceField['type']\n return {\n name,\n type: fieldType,\n drizzleColumn: mapDrizzleColumn(name, fieldType),\n zodType: mapZodType(fieldType),\n }\n })\n}\n\n// --- Column / type mapping ---\n\nfunction mapDrizzleColumn(name: string, type: ResourceField['type']): string {\n switch (type) {\n case 'string':\n case 'text':\n return `text('${name}').notNull()`\n case 'number':\n return `integer('${name}').notNull()`\n case 'boolean':\n return `integer('${name}', { mode: 'boolean' }).notNull().default(false)`\n }\n}\n\nfunction mapZodType(type: ResourceField['type']): string {\n switch (type) {\n case 'string':\n case 'text':\n return 'z.string()'\n case 'number':\n return 'z.number()'\n case 'boolean':\n return 'z.boolean()'\n }\n}\n\n// --- Template generators ---\n\nfunction generateSchemaEntry(resourceName: string, fields: ResourceField[]): string {\n const cols = [\n ` id: integer('id').primaryKey({ autoIncrement: true }),`,\n ...fields.map((f) => ` ${f.name}: ${f.drizzleColumn},`),\n ` createdAt: text('created_at')`,\n ` .notNull()`,\n ` .$defaultFn(() => new Date().toISOString().split('T')[0]),`,\n ]\n return [\n ``,\n `export const ${resourceName} = sqliteTable('${resourceName}', {`,\n ...cols,\n `})`,\n ``,\n ].join('\\n')\n}\n\nfunction generateRouteIndex(resourceName: string, fields: ResourceField[]): string {\n const bodyFields = fields.map((f) => ` ${f.name}: ${f.zodType},`).join('\\n')\n return [\n `import { route, type AccessDecision } from 'theokit/server/define'`,\n `import { z } from 'zod'`,\n `import { db } from '../../db/index.js'`,\n `import { ${resourceName} } from '../../db/schema.js'`,\n ``,\n ...undecidedPolicyDeclaration(\n `server/routes/${resourceName}/index.ts`,\n 'these methods read and write a table',\n ),\n ``,\n `export const GET = route()`,\n ` .policy(${UNDECIDED_POLICY_IDENT})`,\n ` .handler(() => db.select().from(${resourceName}).all())`,\n ` .build()`,\n ``,\n `export const POST = route()`,\n ` .policy(${UNDECIDED_POLICY_IDENT})`,\n ` .body(`,\n ` z.object({`,\n bodyFields,\n ` }),`,\n ` )`,\n ` .status(201)`,\n ` .handler(({ body }) => {`,\n ` const result = db.insert(${resourceName}).values(body).returning().get()`,\n ` return result`,\n ` })`,\n ` .build()`,\n ``,\n ].join('\\n')\n}\n\nfunction generateRouteId(resourceName: string, fields: ResourceField[]): string {\n const updateFields = fields.map((f) => ` ${f.name}: ${f.zodType}.optional(),`).join('\\n')\n return [\n `import { route, type AccessDecision } from 'theokit/server/define'`,\n `import { z } from 'zod'`,\n `import { db } from '../../db/index.js'`,\n `import { ${resourceName} } from '../../db/schema.js'`,\n `import { eq } from 'drizzle-orm'`,\n ``,\n ...undecidedPolicyDeclaration(\n `server/routes/${resourceName}/[id].ts`,\n 'these methods read, update and delete rows of a table',\n ),\n ``,\n `export const GET = route()`,\n ` .policy(${UNDECIDED_POLICY_IDENT})`,\n ` .params(z.object({ id: z.coerce.number() }))`,\n ` .handler(({ params }) => {`,\n ` const item = db.select().from(${resourceName}).where(eq(${resourceName}.id, params.id)).get()`,\n ` if (!item) return new Response(JSON.stringify({ error: 'Not found' }), { status: 404 })`,\n ` return item`,\n ` })`,\n ` .build()`,\n ``,\n `export const PUT = route()`,\n ` .policy(${UNDECIDED_POLICY_IDENT})`,\n ` .params(z.object({ id: z.coerce.number() }))`,\n ` .body(`,\n ` z.object({`,\n updateFields,\n ` }),`,\n ` )`,\n ` .handler(({ params, body }) => {`,\n ` const result = db.update(${resourceName}).set(body).where(eq(${resourceName}.id, params.id)).returning().get()`,\n ` if (!result) return new Response(JSON.stringify({ error: 'Not found' }), { status: 404 })`,\n ` return result`,\n ` })`,\n ` .build()`,\n ``,\n `export const DELETE = route()`,\n ` .policy(${UNDECIDED_POLICY_IDENT})`,\n ` .params(z.object({ id: z.coerce.number() }))`,\n ` .status(204)`,\n ` .handler(({ params }) => {`,\n ` db.delete(${resourceName}).where(eq(${resourceName}.id, params.id)).run()`,\n ` })`,\n ` .build()`,\n ``,\n ].join('\\n')\n}\n\nfunction generateTestTemplate(resourceName: string): string {\n return [\n `import { describe, it, expect } from 'vitest'`,\n ``,\n `describe('${resourceName} API', () => {`,\n ` it('should have a schema defined', async () => {`,\n ` const schema = await import('../server/db/schema.js')`,\n ` expect(schema.${resourceName}).toBeDefined()`,\n ` })`,\n ``,\n ` it('should have route handlers', async () => {`,\n ` const index = await import('../server/routes/${resourceName}/index.js')`,\n ` expect(index.GET).toBeDefined()`,\n ` expect(index.POST).toBeDefined()`,\n ` })`,\n `})`,\n ``,\n ].join('\\n')\n}\n\n// --- Orchestrator ---\n\nexport function generateResource(cwd: string, name: string, fieldArgs: string[]): GenerateResult {\n let fields: ResourceField[]\n try {\n fields = parseResourceFields(fieldArgs)\n } catch (err) {\n return { status: 'invalid_name', message: err instanceof Error ? err.message : String(err) }\n }\n\n const schemaPath = resolve(cwd, 'server/db/schema.ts')\n const routeIndexPath = resolve(cwd, `server/routes/${name}/index.ts`)\n const routeIdPath = resolve(cwd, `server/routes/${name}/[id].ts`)\n const testPath = resolve(cwd, `tests/${name}.test.ts`)\n\n if (!existsSync(schemaPath)) {\n return {\n status: 'not_a_project',\n message:\n 'server/db/schema.ts not found. Run this from a TheoKit project with database setup.',\n }\n }\n\n if (existsSync(routeIndexPath)) {\n return { status: 'already_exists', filePath: routeIndexPath, kind: 'resource', name }\n }\n\n const existingSchema = readFileSync(schemaPath, 'utf-8')\n if (existingSchema.includes(`export const ${name} =`)) {\n return {\n status: 'already_exists',\n filePath: schemaPath,\n kind: 'resource',\n name,\n message: `Table \"${name}\" already exists in schema.ts`,\n }\n }\n\n // 1. Append schema entry\n appendFileSync(schemaPath, generateSchemaEntry(name, fields))\n\n // 2. Create route files\n mkdirSync(dirname(routeIndexPath), { recursive: true })\n writeFileSync(routeIndexPath, generateRouteIndex(name, fields))\n writeFileSync(routeIdPath, generateRouteId(name, fields))\n\n // 3. Create test file\n mkdirSync(dirname(testPath), { recursive: true })\n if (!existsSync(testPath)) {\n writeFileSync(testPath, generateTestTemplate(name))\n }\n\n return { status: 'created', filePath: routeIndexPath, kind: 'resource', name }\n}\n","/**\n * Shared types for the `theokit generate` CLI command family.\n *\n * Extracted to break the circular dependency between generate.ts ↔ generate-resource.ts\n * (architecture-remediation plan T1.1, 2026-06-12).\n */\n\nexport const VALID_TYPES = [\n 'route',\n 'action',\n 'page',\n 'ws',\n 'controller',\n 'agent',\n 'toolbox',\n 'workflow',\n 'eval',\n 'sandbox',\n 'schedule',\n 'memory',\n 'resource',\n] as const\nexport type GeneratorType = (typeof VALID_TYPES)[number]\n\nexport interface GenerateOptions {\n cwd: string\n type: string\n name: string\n fields?: string[]\n}\n\nexport type GenerateStatus =\n | 'created'\n | 'already_exists'\n | 'invalid_kind'\n | 'invalid_name'\n | 'not_a_project'\n\nexport interface GenerateResult {\n status: GenerateStatus\n filePath?: string\n kind?: GeneratorType\n name?: string\n message?: string\n}\n"],"mappings":"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","names":["existsSync","mkdirSync","writeFileSync","resolve","dirname","resolve","existsSync","mkdirSync","dirname","writeFileSync"]}