okengine 0.1.4

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 (674) hide show
  1. package/AGENTS.md +91 -0
  2. package/README.md +327 -0
  3. package/docs/spec/complete-example.md +1188 -0
  4. package/docs/spec/console.md +739 -0
  5. package/docs/spec/four-applications.md +1188 -0
  6. package/docs/spec/unified-theory.md +489 -0
  7. package/package.json +152 -0
  8. package/spec/manifest.v1.schema.json +624 -0
  9. package/src/auth/api-keys.ts +168 -0
  10. package/src/auth/attenuation.ts +116 -0
  11. package/src/auth/auth.test.ts +273 -0
  12. package/src/auth/cross-plane.ts +98 -0
  13. package/src/auth/index.ts +112 -0
  14. package/src/auth/invites.ts +66 -0
  15. package/src/auth/invoke-as.ts +49 -0
  16. package/src/auth/operator.ts +178 -0
  17. package/src/auth/planes.ts +102 -0
  18. package/src/auth/plugin.ts +44 -0
  19. package/src/auth/roles.ts +84 -0
  20. package/src/auth/sessions.ts +418 -0
  21. package/src/auth/tables.ts +131 -0
  22. package/src/cli/args.ts +50 -0
  23. package/src/cli/branch.ts +75 -0
  24. package/src/cli/build.ts +86 -0
  25. package/src/cli/client-add.test.ts +140 -0
  26. package/src/cli/client-add.ts +164 -0
  27. package/src/cli/completion.test.ts +58 -0
  28. package/src/cli/completion.ts +296 -0
  29. package/src/cli/dev-app-runner.ts +77 -0
  30. package/src/cli/dev.test.ts +435 -0
  31. package/src/cli/dev.ts +594 -0
  32. package/src/cli/doc-drift.test.ts +146 -0
  33. package/src/cli/doc-drift.ts +397 -0
  34. package/src/cli/docker-cli.test.ts +221 -0
  35. package/src/cli/docker.ts +127 -0
  36. package/src/cli/doctor-diff-examples.ts +92 -0
  37. package/src/cli/doctor-diff.test.ts +91 -0
  38. package/src/cli/doctor-diff.ts +274 -0
  39. package/src/cli/doctor-pii.test.ts +98 -0
  40. package/src/cli/doctor-pii.ts +151 -0
  41. package/src/cli/doctor.test.ts +150 -0
  42. package/src/cli/doctor.ts +223 -0
  43. package/src/cli/eval.ts +122 -0
  44. package/src/cli/exit.ts +19 -0
  45. package/src/cli/gates-list.test.ts +47 -0
  46. package/src/cli/gates-list.ts +84 -0
  47. package/src/cli/images.ts +277 -0
  48. package/src/cli/index.ts +99 -0
  49. package/src/cli/json-out.test.ts +129 -0
  50. package/src/cli/load-config.ts +71 -0
  51. package/src/cli/mcp-from-console.ts +50 -0
  52. package/src/cli/privacy-erase.ts +73 -0
  53. package/src/cli/registry.ts +455 -0
  54. package/src/cli/safe-defaults.test.ts +92 -0
  55. package/src/cli/schema.ts +196 -0
  56. package/src/cli/stack.ts +82 -0
  57. package/src/cli/start.ts +106 -0
  58. package/src/cli/upgrade.ts +105 -0
  59. package/src/cli/vault-cmd.ts +140 -0
  60. package/src/client/budget-entry.ts +34 -0
  61. package/src/client/budget.test.ts +17 -0
  62. package/src/client/create.test.ts +159 -0
  63. package/src/client/create.ts +152 -0
  64. package/src/client/errors.ts +60 -0
  65. package/src/client/index.ts +35 -0
  66. package/src/client/notes-contract.test.ts +289 -0
  67. package/src/client/transport.test.ts +123 -0
  68. package/src/client/transport.ts +254 -0
  69. package/src/client/types.ts +282 -0
  70. package/src/compiler/aot.test.ts +248 -0
  71. package/src/compiler/aot.ts +182 -0
  72. package/src/compiler/differential.test.ts +241 -0
  73. package/src/compiler/dynamic.ts +54 -0
  74. package/src/compiler/effects-infer.ts +541 -0
  75. package/src/compiler/emit.ts +40 -0
  76. package/src/compiler/extract.test.ts +177 -0
  77. package/src/compiler/extract.ts +1368 -0
  78. package/src/compiler/fixtures/raw/raw-unannotated.ts +28 -0
  79. package/src/compiler/fixtures/skyport/oke.config.ts +24 -0
  80. package/src/compiler/fixtures/skyport/src/ai.ts +15 -0
  81. package/src/compiler/fixtures/skyport/src/app.ts +10 -0
  82. package/src/compiler/fixtures/skyport/src/channels.ts +6 -0
  83. package/src/compiler/fixtures/skyport/src/core.ts +3 -0
  84. package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +57 -0
  85. package/src/compiler/fixtures/skyport/src/flows/bookings/signals.ts +11 -0
  86. package/src/compiler/fixtures/skyport/src/flows/payments/index.ts +14 -0
  87. package/src/compiler/fixtures/skyport/src/flows/support/index.ts +20 -0
  88. package/src/compiler/fixtures/skyport/src/gates.ts +14 -0
  89. package/src/compiler/fixtures/skyport/src/journeys.ts +9 -0
  90. package/src/compiler/fixtures/skyport/src/schema.ts +3 -0
  91. package/src/compiler/fixtures/skyport/src/vault.ts +6 -0
  92. package/src/compiler/fixtures/skyport.expected.json +241 -0
  93. package/src/compiler/fixtures/triggers/five-triggers.ts +69 -0
  94. package/src/compiler/http-parse.ts +214 -0
  95. package/src/compiler/index.ts +67 -0
  96. package/src/compiler/response.ts +89 -0
  97. package/src/compiler/sucrose.ts +238 -0
  98. package/src/config/index.ts +167 -0
  99. package/src/console/budget.test.ts +73 -0
  100. package/src/console/index.ts +30 -0
  101. package/src/console/server/access.test.ts +370 -0
  102. package/src/console/server/access.ts +777 -0
  103. package/src/console/server/ai.test.ts +172 -0
  104. package/src/console/server/ai.ts +632 -0
  105. package/src/console/server/app.ts +294 -0
  106. package/src/console/server/auth-rate.test.ts +81 -0
  107. package/src/console/server/auth-rate.ts +72 -0
  108. package/src/console/server/bind.ts +25 -0
  109. package/src/console/server/channels.test.ts +179 -0
  110. package/src/console/server/channels.ts +469 -0
  111. package/src/console/server/claim.test.ts +66 -0
  112. package/src/console/server/claim.ts +134 -0
  113. package/src/console/server/clock.test.ts +239 -0
  114. package/src/console/server/clock.ts +390 -0
  115. package/src/console/server/console.test.ts +338 -0
  116. package/src/console/server/diff.test.ts +299 -0
  117. package/src/console/server/diff.ts +352 -0
  118. package/src/console/server/dry-run.audit.test.ts +118 -0
  119. package/src/console/server/flows-invoke.test.ts +148 -0
  120. package/src/console/server/flows.ts +3633 -0
  121. package/src/console/server/gates.test.ts +360 -0
  122. package/src/console/server/gates.ts +869 -0
  123. package/src/console/server/index.ts +141 -0
  124. package/src/console/server/live.test.ts +30 -0
  125. package/src/console/server/live.ts +109 -0
  126. package/src/console/server/plugin.ts +50 -0
  127. package/src/console/server/plugins.test.ts +131 -0
  128. package/src/console/server/plugins.ts +429 -0
  129. package/src/console/server/runs-pii.ts +98 -0
  130. package/src/console/server/security-headers.ts +97 -0
  131. package/src/console/server/security.gate.test.ts +286 -0
  132. package/src/console/server/serve.ts +319 -0
  133. package/src/console/server/signals.test.ts +88 -0
  134. package/src/console/server/signals.ts +282 -0
  135. package/src/console/server/state.ts +982 -0
  136. package/src/console/server/store.test.ts +233 -0
  137. package/src/console/server/store.ts +861 -0
  138. package/src/console/server/structural.ts +95 -0
  139. package/src/console/server/vault.test.ts +251 -0
  140. package/src/console/server/vault.ts +430 -0
  141. package/src/console/ui/access/AccessA11yView.tsx +237 -0
  142. package/src/console/ui/access/a11y.test.tsx +122 -0
  143. package/src/console/ui/access/acknowledgement.test.ts +13 -0
  144. package/src/console/ui/access/acknowledgement.ts +35 -0
  145. package/src/console/ui/access/blast-radius.test.ts +26 -0
  146. package/src/console/ui/access/blast-radius.ts +40 -0
  147. package/src/console/ui/access/confirmation.test.ts +38 -0
  148. package/src/console/ui/access/confirmation.ts +36 -0
  149. package/src/console/ui/access/fixture.ts +203 -0
  150. package/src/console/ui/access/grantable.test.ts +17 -0
  151. package/src/console/ui/access/grantable.ts +36 -0
  152. package/src/console/ui/access/hygiene.test.ts +12 -0
  153. package/src/console/ui/access/hygiene.ts +39 -0
  154. package/src/console/ui/access/index.ts +54 -0
  155. package/src/console/ui/access/provenance.test.ts +12 -0
  156. package/src/console/ui/access/provenance.ts +29 -0
  157. package/src/console/ui/access/search.test.ts +17 -0
  158. package/src/console/ui/access/search.ts +72 -0
  159. package/src/console/ui/access/types.ts +111 -0
  160. package/src/console/ui/ai/AiA11yView.tsx +265 -0
  161. package/src/console/ui/ai/a11y.test.tsx +99 -0
  162. package/src/console/ui/ai/findings.ts +41 -0
  163. package/src/console/ui/ai/fixture.ts +182 -0
  164. package/src/console/ui/ai/format.ts +90 -0
  165. package/src/console/ui/ai/group.test.ts +37 -0
  166. package/src/console/ui/ai/group.ts +88 -0
  167. package/src/console/ui/ai/index.ts +66 -0
  168. package/src/console/ui/ai/promotion.test.ts +77 -0
  169. package/src/console/ui/ai/promotion.ts +150 -0
  170. package/src/console/ui/ai/search.test.ts +40 -0
  171. package/src/console/ui/ai/search.ts +89 -0
  172. package/src/console/ui/ai/types.ts +139 -0
  173. package/src/console/ui/architecture/ArchitectureA11yView.tsx +163 -0
  174. package/src/console/ui/architecture/a11y.test.tsx +97 -0
  175. package/src/console/ui/architecture/boundary.ts +42 -0
  176. package/src/console/ui/architecture/declared.ts +165 -0
  177. package/src/console/ui/architecture/fixture.ts +74 -0
  178. package/src/console/ui/architecture/index.ts +84 -0
  179. package/src/console/ui/architecture/layers.ts +64 -0
  180. package/src/console/ui/architecture/layout.ts +68 -0
  181. package/src/console/ui/architecture/pathologies.ts +260 -0
  182. package/src/console/ui/architecture/search.ts +145 -0
  183. package/src/console/ui/architecture/traffic.ts +102 -0
  184. package/src/console/ui/architecture/types.ts +144 -0
  185. package/src/console/ui/architecture/view.test.ts +165 -0
  186. package/src/console/ui/architecture/view.ts +516 -0
  187. package/src/console/ui/channels/ChannelsA11yView.tsx +180 -0
  188. package/src/console/ui/channels/a11y.test.tsx +96 -0
  189. package/src/console/ui/channels/confirmation.test.ts +37 -0
  190. package/src/console/ui/channels/confirmation.ts +27 -0
  191. package/src/console/ui/channels/fallback.test.ts +15 -0
  192. package/src/console/ui/channels/fallback.ts +20 -0
  193. package/src/console/ui/channels/findings.ts +38 -0
  194. package/src/console/ui/channels/fixture.ts +134 -0
  195. package/src/console/ui/channels/group.ts +25 -0
  196. package/src/console/ui/channels/index.ts +57 -0
  197. package/src/console/ui/channels/locale.test.ts +17 -0
  198. package/src/console/ui/channels/locale.ts +31 -0
  199. package/src/console/ui/channels/mask.test.ts +14 -0
  200. package/src/console/ui/channels/mask.ts +12 -0
  201. package/src/console/ui/channels/search.ts +58 -0
  202. package/src/console/ui/channels/taxonomy.test.ts +17 -0
  203. package/src/console/ui/channels/taxonomy.ts +49 -0
  204. package/src/console/ui/channels/types.ts +117 -0
  205. package/src/console/ui/clock/ClockA11yView.tsx +182 -0
  206. package/src/console/ui/clock/a11y.test.tsx +99 -0
  207. package/src/console/ui/clock/confirmation.test.ts +32 -0
  208. package/src/console/ui/clock/confirmation.ts +34 -0
  209. package/src/console/ui/clock/findings.ts +40 -0
  210. package/src/console/ui/clock/fixture.ts +111 -0
  211. package/src/console/ui/clock/health.test.ts +25 -0
  212. package/src/console/ui/clock/health.ts +61 -0
  213. package/src/console/ui/clock/index.ts +49 -0
  214. package/src/console/ui/clock/search.test.ts +39 -0
  215. package/src/console/ui/clock/search.ts +76 -0
  216. package/src/console/ui/clock/timeline.test.ts +44 -0
  217. package/src/console/ui/clock/timeline.ts +41 -0
  218. package/src/console/ui/clock/types.ts +78 -0
  219. package/src/console/ui/clock/waiting-on.test.ts +34 -0
  220. package/src/console/ui/clock/waiting-on.ts +83 -0
  221. package/src/console/ui/confirmation.unify.test.ts +92 -0
  222. package/src/console/ui/diff/DiffA11yView.tsx +85 -0
  223. package/src/console/ui/diff/a11y.test.tsx +99 -0
  224. package/src/console/ui/diff/fixture.ts +85 -0
  225. package/src/console/ui/diff/group.test.ts +58 -0
  226. package/src/console/ui/diff/group.ts +97 -0
  227. package/src/console/ui/diff/index.ts +38 -0
  228. package/src/console/ui/diff/search.test.ts +32 -0
  229. package/src/console/ui/diff/search.ts +75 -0
  230. package/src/console/ui/diff/summary.ts +74 -0
  231. package/src/console/ui/diff/types.ts +48 -0
  232. package/src/console/ui/dist/assets/index-B71Yl_SS.js +10 -0
  233. package/src/console/ui/dist/assets/panel-access-Dd37LU2c.js +64 -0
  234. package/src/console/ui/dist/assets/panel-ai-CC7LR6-J.js +1 -0
  235. package/src/console/ui/dist/assets/panel-architecture-B5b3iKCz.js +1 -0
  236. package/src/console/ui/dist/assets/panel-channels-CeNjTKXp.js +1 -0
  237. package/src/console/ui/dist/assets/panel-clock-DgFTLoHV.js +1 -0
  238. package/src/console/ui/dist/assets/panel-diff-DxehccqB.js +1 -0
  239. package/src/console/ui/dist/assets/panel-flows-BtrVn-Eg.js +45 -0
  240. package/src/console/ui/dist/assets/panel-gates-Z9MKRGdH.js +1 -0
  241. package/src/console/ui/dist/assets/panel-overview-Bd48d9km.js +1 -0
  242. package/src/console/ui/dist/assets/panel-plugins-DWd0TowH.js +1 -0
  243. package/src/console/ui/dist/assets/panel-runs-BwsWqKeB.js +1 -0
  244. package/src/console/ui/dist/assets/panel-signals-9najbZY2.js +1 -0
  245. package/src/console/ui/dist/assets/panel-store-OHkP2pDp.js +1 -0
  246. package/src/console/ui/dist/assets/panel-traces-tn2JoY8U.js +1 -0
  247. package/src/console/ui/dist/assets/panel-vault-BbfWdox0.js +1 -0
  248. package/src/console/ui/dist/assets/rolldown-runtime-CNC7AqOf.js +1 -0
  249. package/src/console/ui/dist/assets/style-Cnl7WLya.css +3 -0
  250. package/src/console/ui/dist/index.html +14 -0
  251. package/src/console/ui/flows/FlowsA11yView.tsx +155 -0
  252. package/src/console/ui/flows/a11y.test.tsx +105 -0
  253. package/src/console/ui/flows/buffer.test.ts +91 -0
  254. package/src/console/ui/flows/buffer.ts +118 -0
  255. package/src/console/ui/flows/confirmation.ts +131 -0
  256. package/src/console/ui/flows/contract.test.ts +89 -0
  257. package/src/console/ui/flows/contract.ts +353 -0
  258. package/src/console/ui/flows/fixture.ts +81 -0
  259. package/src/console/ui/flows/graph.test.ts +101 -0
  260. package/src/console/ui/flows/graph.ts +549 -0
  261. package/src/console/ui/flows/index.ts +87 -0
  262. package/src/console/ui/flows/save-as-test.test.ts +47 -0
  263. package/src/console/ui/flows/save-as-test.ts +99 -0
  264. package/src/console/ui/flows/search.ts +255 -0
  265. package/src/console/ui/flows/tiers.ts +140 -0
  266. package/src/console/ui/gates/GatesA11yView.tsx +192 -0
  267. package/src/console/ui/gates/a11y.test.tsx +116 -0
  268. package/src/console/ui/gates/audit.test.ts +40 -0
  269. package/src/console/ui/gates/audit.ts +63 -0
  270. package/src/console/ui/gates/denial.test.ts +36 -0
  271. package/src/console/ui/gates/denial.ts +51 -0
  272. package/src/console/ui/gates/findings.ts +19 -0
  273. package/src/console/ui/gates/fixture.ts +189 -0
  274. package/src/console/ui/gates/group.test.ts +30 -0
  275. package/src/console/ui/gates/group.ts +102 -0
  276. package/src/console/ui/gates/index.ts +47 -0
  277. package/src/console/ui/gates/search.test.ts +49 -0
  278. package/src/console/ui/gates/search.ts +115 -0
  279. package/src/console/ui/gates/types.ts +121 -0
  280. package/src/console/ui/overview/OverviewA11yView.tsx +152 -0
  281. package/src/console/ui/overview/a11y.test.tsx +113 -0
  282. package/src/console/ui/overview/busiest.ts +26 -0
  283. package/src/console/ui/overview/compose.ts +133 -0
  284. package/src/console/ui/overview/cost.test.ts +39 -0
  285. package/src/console/ui/overview/cost.ts +138 -0
  286. package/src/console/ui/overview/fixture.ts +161 -0
  287. package/src/console/ui/overview/golden.ts +57 -0
  288. package/src/console/ui/overview/index.ts +59 -0
  289. package/src/console/ui/overview/rank.test.ts +136 -0
  290. package/src/console/ui/overview/rank.ts +210 -0
  291. package/src/console/ui/overview/slo.test.ts +73 -0
  292. package/src/console/ui/overview/slo.ts +229 -0
  293. package/src/console/ui/overview/types.ts +121 -0
  294. package/src/console/ui/overview/verdict.ts +131 -0
  295. package/src/console/ui/plugins/PluginsA11yView.tsx +227 -0
  296. package/src/console/ui/plugins/a11y.test.tsx +97 -0
  297. package/src/console/ui/plugins/command.test.ts +22 -0
  298. package/src/console/ui/plugins/command.ts +27 -0
  299. package/src/console/ui/plugins/findings.ts +39 -0
  300. package/src/console/ui/plugins/fixture.ts +233 -0
  301. package/src/console/ui/plugins/group.test.ts +38 -0
  302. package/src/console/ui/plugins/group.ts +67 -0
  303. package/src/console/ui/plugins/index.ts +40 -0
  304. package/src/console/ui/plugins/search.ts +67 -0
  305. package/src/console/ui/plugins/types.ts +115 -0
  306. package/src/console/ui/runs/RunsA11yView.tsx +267 -0
  307. package/src/console/ui/runs/a11y.test.tsx +99 -0
  308. package/src/console/ui/runs/explain.test.ts +23 -0
  309. package/src/console/ui/runs/explain.ts +32 -0
  310. package/src/console/ui/runs/fixture.ts +189 -0
  311. package/src/console/ui/runs/group.test.ts +24 -0
  312. package/src/console/ui/runs/group.ts +85 -0
  313. package/src/console/ui/runs/histogram.test.ts +31 -0
  314. package/src/console/ui/runs/histogram.ts +85 -0
  315. package/src/console/ui/runs/index.ts +75 -0
  316. package/src/console/ui/runs/project.ts +122 -0
  317. package/src/console/ui/runs/query.test.ts +50 -0
  318. package/src/console/ui/runs/query.ts +283 -0
  319. package/src/console/ui/runs/search.test.ts +45 -0
  320. package/src/console/ui/runs/search.ts +141 -0
  321. package/src/console/ui/runs/trace-link.test.ts +30 -0
  322. package/src/console/ui/runs/trace-link.ts +99 -0
  323. package/src/console/ui/runs/types.ts +137 -0
  324. package/src/console/ui/shell/App.tsx +56 -0
  325. package/src/console/ui/shell/client.ts +1715 -0
  326. package/src/console/ui/shell/components/ui.tsx +110 -0
  327. package/src/console/ui/shell/index.html +12 -0
  328. package/src/console/ui/shell/layout/Shell.tsx +95 -0
  329. package/src/console/ui/shell/main.tsx +281 -0
  330. package/src/console/ui/shell/panels/Access.tsx +5 -0
  331. package/src/console/ui/shell/panels/Ai.tsx +5 -0
  332. package/src/console/ui/shell/panels/Architecture.tsx +5 -0
  333. package/src/console/ui/shell/panels/Channels.tsx +5 -0
  334. package/src/console/ui/shell/panels/Clock.tsx +5 -0
  335. package/src/console/ui/shell/panels/Diff.tsx +5 -0
  336. package/src/console/ui/shell/panels/Flows.tsx +5 -0
  337. package/src/console/ui/shell/panels/Gates.tsx +5 -0
  338. package/src/console/ui/shell/panels/Overview.tsx +6 -0
  339. package/src/console/ui/shell/panels/Plugins.tsx +5 -0
  340. package/src/console/ui/shell/panels/Runs.tsx +5 -0
  341. package/src/console/ui/shell/panels/Signals.tsx +5 -0
  342. package/src/console/ui/shell/panels/Store.tsx +5 -0
  343. package/src/console/ui/shell/panels/Traces.tsx +5 -0
  344. package/src/console/ui/shell/panels/Vault.tsx +5 -0
  345. package/src/console/ui/shell/panels/access/AccessPanel.tsx +813 -0
  346. package/src/console/ui/shell/panels/ai/AiPanel.tsx +563 -0
  347. package/src/console/ui/shell/panels/architecture/ArchitecturePanel.tsx +377 -0
  348. package/src/console/ui/shell/panels/channels/ChannelsPanel.tsx +454 -0
  349. package/src/console/ui/shell/panels/clock/ClockPanel.tsx +479 -0
  350. package/src/console/ui/shell/panels/diff/DiffPanel.tsx +275 -0
  351. package/src/console/ui/shell/panels/flows/ContractEditor.tsx +301 -0
  352. package/src/console/ui/shell/panels/flows/FlowDrawer.tsx +350 -0
  353. package/src/console/ui/shell/panels/flows/FlowsPanel.tsx +502 -0
  354. package/src/console/ui/shell/panels/gates/GatesPanel.tsx +482 -0
  355. package/src/console/ui/shell/panels/overview/OverviewPanel.tsx +428 -0
  356. package/src/console/ui/shell/panels/plugins/PluginsPanel.tsx +413 -0
  357. package/src/console/ui/shell/panels/runs/RunsPanel.tsx +649 -0
  358. package/src/console/ui/shell/panels/signals/SignalsPanel.tsx +840 -0
  359. package/src/console/ui/shell/panels/store/StorePanel.tsx +787 -0
  360. package/src/console/ui/shell/panels/traces/TracesPanel.tsx +539 -0
  361. package/src/console/ui/shell/panels/vault/VaultPanel.tsx +449 -0
  362. package/src/console/ui/shell/plugin/Sandbox.tsx +29 -0
  363. package/src/console/ui/shell/setup/Wizard.tsx +189 -0
  364. package/src/console/ui/shell/styles.css +75 -0
  365. package/src/console/ui/signals/SignalsA11yView.tsx +276 -0
  366. package/src/console/ui/signals/a11y.test.tsx +99 -0
  367. package/src/console/ui/signals/confirmation.test.ts +39 -0
  368. package/src/console/ui/signals/confirmation.ts +63 -0
  369. package/src/console/ui/signals/dry-run.test.ts +18 -0
  370. package/src/console/ui/signals/dry-run.ts +36 -0
  371. package/src/console/ui/signals/durable.test.ts +22 -0
  372. package/src/console/ui/signals/durable.ts +41 -0
  373. package/src/console/ui/signals/findings.ts +33 -0
  374. package/src/console/ui/signals/fixture.ts +242 -0
  375. package/src/console/ui/signals/group.test.ts +32 -0
  376. package/src/console/ui/signals/group.ts +49 -0
  377. package/src/console/ui/signals/index.ts +52 -0
  378. package/src/console/ui/signals/monitor.test.ts +30 -0
  379. package/src/console/ui/signals/monitor.ts +79 -0
  380. package/src/console/ui/signals/schema-form.test.ts +34 -0
  381. package/src/console/ui/signals/schema-form.ts +112 -0
  382. package/src/console/ui/signals/search.ts +102 -0
  383. package/src/console/ui/signals/types.ts +71 -0
  384. package/src/console/ui/store/StoreA11yView.tsx +199 -0
  385. package/src/console/ui/store/a11y.test.tsx +99 -0
  386. package/src/console/ui/store/cache-view.test.ts +13 -0
  387. package/src/console/ui/store/cache-view.ts +36 -0
  388. package/src/console/ui/store/confirmation.test.ts +38 -0
  389. package/src/console/ui/store/confirmation.ts +55 -0
  390. package/src/console/ui/store/dry-run.test.ts +15 -0
  391. package/src/console/ui/store/dry-run.ts +29 -0
  392. package/src/console/ui/store/fixture.ts +163 -0
  393. package/src/console/ui/store/group.test.ts +21 -0
  394. package/src/console/ui/store/group.ts +41 -0
  395. package/src/console/ui/store/index.ts +40 -0
  396. package/src/console/ui/store/search.ts +78 -0
  397. package/src/console/ui/store/types.ts +65 -0
  398. package/src/console/ui/store/will-not-fire.test.ts +19 -0
  399. package/src/console/ui/store/will-not-fire.ts +40 -0
  400. package/src/console/ui/traces/TracesA11yView.tsx +200 -0
  401. package/src/console/ui/traces/a11y.test.tsx +97 -0
  402. package/src/console/ui/traces/chain.test.ts +61 -0
  403. package/src/console/ui/traces/chain.ts +144 -0
  404. package/src/console/ui/traces/critical-path.test.ts +24 -0
  405. package/src/console/ui/traces/critical-path.ts +59 -0
  406. package/src/console/ui/traces/filter.test.ts +78 -0
  407. package/src/console/ui/traces/filter.ts +112 -0
  408. package/src/console/ui/traces/fixture.ts +126 -0
  409. package/src/console/ui/traces/fold.test.ts +67 -0
  410. package/src/console/ui/traces/fold.ts +170 -0
  411. package/src/console/ui/traces/index.ts +64 -0
  412. package/src/console/ui/traces/mini.ts +65 -0
  413. package/src/console/ui/traces/replay.test.ts +24 -0
  414. package/src/console/ui/traces/replay.ts +35 -0
  415. package/src/console/ui/traces/sampling.test.ts +26 -0
  416. package/src/console/ui/traces/sampling.ts +66 -0
  417. package/src/console/ui/traces/search.ts +148 -0
  418. package/src/console/ui/traces/tier.ts +72 -0
  419. package/src/console/ui/traces/types.ts +125 -0
  420. package/src/console/ui/tsconfig.json +20 -0
  421. package/src/console/ui/vault/VaultA11yView.tsx +177 -0
  422. package/src/console/ui/vault/a11y.test.tsx +97 -0
  423. package/src/console/ui/vault/blast-radius.test.ts +35 -0
  424. package/src/console/ui/vault/blast-radius.ts +55 -0
  425. package/src/console/ui/vault/confirmation.test.ts +41 -0
  426. package/src/console/ui/vault/confirmation.ts +39 -0
  427. package/src/console/ui/vault/dormant.test.ts +37 -0
  428. package/src/console/ui/vault/dormant.ts +28 -0
  429. package/src/console/ui/vault/export-safe.test.ts +30 -0
  430. package/src/console/ui/vault/export-safe.ts +65 -0
  431. package/src/console/ui/vault/fixture.ts +75 -0
  432. package/src/console/ui/vault/group.test.ts +25 -0
  433. package/src/console/ui/vault/group.ts +50 -0
  434. package/src/console/ui/vault/index.ts +45 -0
  435. package/src/console/ui/vault/search.ts +62 -0
  436. package/src/console/ui/vault/types.ts +57 -0
  437. package/src/console/ui/vite.config.ts +84 -0
  438. package/src/console/xss.gate.test.ts +118 -0
  439. package/src/docker/compose.ts +226 -0
  440. package/src/docker/credentials.ts +25 -0
  441. package/src/docker/derive.ts +83 -0
  442. package/src/docker/docker.test.ts +185 -0
  443. package/src/docker/dockerfile.integration.test.ts +170 -0
  444. package/src/docker/dockerfile.ts +39 -0
  445. package/src/docker/helpers.ts +103 -0
  446. package/src/docker/index.ts +52 -0
  447. package/src/docker/pin.ts +90 -0
  448. package/src/docker/recipes/index.ts +33 -0
  449. package/src/docker/recipes/postgres.ts +18 -0
  450. package/src/docker/recipes/redis.ts +18 -0
  451. package/src/docker/stack.integration.test.ts +140 -0
  452. package/src/docker/stack.ts +62 -0
  453. package/src/docker/types.ts +134 -0
  454. package/src/drivers/ai-anthropic.ts +128 -0
  455. package/src/drivers/ai-mock.ts +82 -0
  456. package/src/drivers/ai-openai-compatible.ts +139 -0
  457. package/src/drivers/ai-providers.test.ts +163 -0
  458. package/src/drivers/ai-types.ts +83 -0
  459. package/src/drivers/bun-native-completeness.test.ts +155 -0
  460. package/src/drivers/channel-console.ts +118 -0
  461. package/src/drivers/channel-fcm.ts +96 -0
  462. package/src/drivers/channel-resend.ts +27 -0
  463. package/src/drivers/channel-smtp.ts +33 -0
  464. package/src/drivers/channel-types.ts +160 -0
  465. package/src/drivers/channel-unifonic.ts +79 -0
  466. package/src/drivers/channel-wa-cloud.ts +84 -0
  467. package/src/drivers/channel-webpush.ts +317 -0
  468. package/src/drivers/conformance.test.ts +89 -0
  469. package/src/drivers/conformance.ts +162 -0
  470. package/src/drivers/fs.ts +73 -0
  471. package/src/drivers/index.ts +194 -0
  472. package/src/drivers/kv-lua.ts +222 -0
  473. package/src/drivers/memory.ts +472 -0
  474. package/src/drivers/pgvector.ts +130 -0
  475. package/src/drivers/postgres.ts +221 -0
  476. package/src/drivers/redis.ts +254 -0
  477. package/src/drivers/s3.ts +129 -0
  478. package/src/drivers/signal-engine.ts +690 -0
  479. package/src/drivers/signal-memory.ts +27 -0
  480. package/src/drivers/signal-nats.ts +131 -0
  481. package/src/drivers/signal-postgres.ts +1089 -0
  482. package/src/drivers/signal-redis.ts +275 -0
  483. package/src/drivers/signal-types.ts +328 -0
  484. package/src/drivers/sqlite.ts +53 -0
  485. package/src/drivers/types.ts +334 -0
  486. package/src/drivers/vault-dotenv-parse.ts +56 -0
  487. package/src/drivers/vault-env.ts +101 -0
  488. package/src/drivers/vault-infisical.ts +61 -0
  489. package/src/drivers/vault-managed.ts +42 -0
  490. package/src/drivers/vault-memory.ts +38 -0
  491. package/src/drivers/vault-openbao.ts +80 -0
  492. package/src/drivers/vault-sops.ts +252 -0
  493. package/src/drivers/vault-types.ts +84 -0
  494. package/src/elements/ai/declare.ts +206 -0
  495. package/src/elements/ai/eval.ts +113 -0
  496. package/src/elements/ai/pii.ts +108 -0
  497. package/src/elements/ai/runtime.ts +540 -0
  498. package/src/elements/ai/schema.ts +194 -0
  499. package/src/elements/ai.test.ts +393 -0
  500. package/src/elements/ai.ts +56 -0
  501. package/src/elements/channel/consent.ts +81 -0
  502. package/src/elements/channel/costs.test.ts +62 -0
  503. package/src/elements/channel/costs.ts +130 -0
  504. package/src/elements/channel/declare.ts +141 -0
  505. package/src/elements/channel/email-auth.test.ts +47 -0
  506. package/src/elements/channel/email-auth.ts +109 -0
  507. package/src/elements/channel/locale.ts +97 -0
  508. package/src/elements/channel/mask.test.ts +19 -0
  509. package/src/elements/channel/mask.ts +60 -0
  510. package/src/elements/channel/mime.ts +23 -0
  511. package/src/elements/channel/outcomes.test.ts +40 -0
  512. package/src/elements/channel/outcomes.ts +126 -0
  513. package/src/elements/channel/receipts.ts +121 -0
  514. package/src/elements/channel/runtime.ts +500 -0
  515. package/src/elements/channel/suppression.ts +136 -0
  516. package/src/elements/channel.test.ts +232 -0
  517. package/src/elements/channel.ts +109 -0
  518. package/src/elements/clock/actions.ts +170 -0
  519. package/src/elements/clock/declare.ts +58 -0
  520. package/src/elements/clock/dst.ts +197 -0
  521. package/src/elements/clock/durable.ts +140 -0
  522. package/src/elements/clock/duration.ts +29 -0
  523. package/src/elements/clock/health.test.ts +103 -0
  524. package/src/elements/clock/health.ts +112 -0
  525. package/src/elements/clock/leader.ts +127 -0
  526. package/src/elements/clock/reconcile.ts +241 -0
  527. package/src/elements/clock/runtime.ts +243 -0
  528. package/src/elements/clock/schedule.ts +262 -0
  529. package/src/elements/clock/time-travel.ts +53 -0
  530. package/src/elements/clock.test.ts +365 -0
  531. package/src/elements/clock.ts +80 -0
  532. package/src/elements/gate/declare.ts +134 -0
  533. package/src/elements/gate/permissions.ts +104 -0
  534. package/src/elements/gate/runtime.ts +177 -0
  535. package/src/elements/gate/strategies.ts +388 -0
  536. package/src/elements/gate.test.ts +145 -0
  537. package/src/elements/gate.ts +41 -0
  538. package/src/elements/index.ts +169 -0
  539. package/src/elements/signal/chaos-child.ts +47 -0
  540. package/src/elements/signal/declare.ts +77 -0
  541. package/src/elements/signal/dry-run-replay.test.ts +95 -0
  542. package/src/elements/signal/dry-run-write-isolation.test.ts +94 -0
  543. package/src/elements/signal/reconcile.test.ts +23 -0
  544. package/src/elements/signal/reconcile.ts +122 -0
  545. package/src/elements/signal/runtime.ts +94 -0
  546. package/src/elements/signal.test.ts +457 -0
  547. package/src/elements/signal.ts +26 -0
  548. package/src/elements/store/cache.ts +197 -0
  549. package/src/elements/store/classify.ts +125 -0
  550. package/src/elements/store/declare.ts +200 -0
  551. package/src/elements/store/files-policy.test.ts +31 -0
  552. package/src/elements/store/files-policy.ts +70 -0
  553. package/src/elements/store/replica.ts +68 -0
  554. package/src/elements/store/runtime.ts +393 -0
  555. package/src/elements/store/sql-condition.ts +205 -0
  556. package/src/elements/store/sql-session.ts +579 -0
  557. package/src/elements/store/table.ts +282 -0
  558. package/src/elements/store.test.ts +370 -0
  559. package/src/elements/store.ts +99 -0
  560. package/src/elements/vault/declare.ts +143 -0
  561. package/src/elements/vault/fingerprint.ts +30 -0
  562. package/src/elements/vault/redact.ts +52 -0
  563. package/src/elements/vault/runtime.ts +461 -0
  564. package/src/elements/vault.test.ts +296 -0
  565. package/src/elements/vault.ts +44 -0
  566. package/src/index.ts +183 -0
  567. package/src/kernel/adopt-routes.ts +194 -0
  568. package/src/kernel/app.ts +1068 -0
  569. package/src/kernel/auth-resolve.ts +93 -0
  570. package/src/kernel/boot.test.ts +173 -0
  571. package/src/kernel/boot.ts +439 -0
  572. package/src/kernel/budget-entry.ts +55 -0
  573. package/src/kernel/budget.test.ts +19 -0
  574. package/src/kernel/call.test.ts +83 -0
  575. package/src/kernel/capability.ts +113 -0
  576. package/src/kernel/dry-run.test.ts +64 -0
  577. package/src/kernel/dry-run.ts +171 -0
  578. package/src/kernel/effects.test.ts +89 -0
  579. package/src/kernel/effects.ts +140 -0
  580. package/src/kernel/errors.registry.test.ts +39 -0
  581. package/src/kernel/errors.ts +225 -0
  582. package/src/kernel/flow.test.ts +154 -0
  583. package/src/kernel/flow.ts +290 -0
  584. package/src/kernel/fx.test.ts +245 -0
  585. package/src/kernel/fx.ts +996 -0
  586. package/src/kernel/hook-timing.test.ts +72 -0
  587. package/src/kernel/hook-timing.ts +190 -0
  588. package/src/kernel/hooks.test.ts +181 -0
  589. package/src/kernel/hooks.ts +275 -0
  590. package/src/kernel/index.ts +278 -0
  591. package/src/kernel/journal.ts +405 -0
  592. package/src/kernel/journey.ts +75 -0
  593. package/src/kernel/on.ts +74 -0
  594. package/src/kernel/pipeline.test.ts +349 -0
  595. package/src/kernel/pipeline.ts +245 -0
  596. package/src/kernel/plug.ts +82 -0
  597. package/src/kernel/plugin/capabilities.test.ts +84 -0
  598. package/src/kernel/plugin/conflicts.test.ts +106 -0
  599. package/src/kernel/plugin/decorate.test.ts +111 -0
  600. package/src/kernel/plugin/scoping.test.ts +138 -0
  601. package/src/kernel/plugin.ts +485 -0
  602. package/src/kernel/rate-limit.ts +25 -0
  603. package/src/kernel/registry.ts +398 -0
  604. package/src/kernel/router.test.ts +114 -0
  605. package/src/kernel/router.ts +556 -0
  606. package/src/kernel/routing-budget.test.ts +19 -0
  607. package/src/kernel/run-telemetry.ts +70 -0
  608. package/src/kernel/triggers.ts +324 -0
  609. package/src/kernel/unit.ts +88 -0
  610. package/src/manifest/diff.test.ts +866 -0
  611. package/src/manifest/diff.ts +1670 -0
  612. package/src/manifest/fixtures/base.manifest.json +112 -0
  613. package/src/manifest/fixtures/skyport.excerpt.json +51 -0
  614. package/src/manifest/fixtures/skyport.manifest.json +153 -0
  615. package/src/manifest/index.ts +27 -0
  616. package/src/manifest/types.ts +358 -0
  617. package/src/manifest/undeclared.test.ts +82 -0
  618. package/src/manifest/undeclared.ts +65 -0
  619. package/src/manifest/validate.test.ts +105 -0
  620. package/src/manifest/validate.ts +174 -0
  621. package/src/mcp/authorization.ts +340 -0
  622. package/src/mcp/confirmation.ts +174 -0
  623. package/src/mcp/data.ts +90 -0
  624. package/src/mcp/index.ts +80 -0
  625. package/src/mcp/injection.gate.test.ts +176 -0
  626. package/src/mcp/mcp.test.ts +348 -0
  627. package/src/mcp/protocol.ts +172 -0
  628. package/src/mcp/server.ts +283 -0
  629. package/src/mcp/session.ts +139 -0
  630. package/src/mcp/tools.ts +391 -0
  631. package/src/plugins/catalogue.test.ts +48 -0
  632. package/src/plugins/catalogue.ts +113 -0
  633. package/src/plugins/node-import-scan.test.ts +28 -0
  634. package/src/plugins/node-import-scan.ts +98 -0
  635. package/src/plugins/supply-chain.test.ts +48 -0
  636. package/src/plugins/supply-chain.ts +460 -0
  637. package/src/release/index.ts +30 -0
  638. package/src/release/limits.ts +20 -0
  639. package/src/release/measure.ts +443 -0
  640. package/src/release/publish.ts +56 -0
  641. package/src/runs/bench.test.ts +93 -0
  642. package/src/runs/collect.ts +144 -0
  643. package/src/runs/drivers/clickhouse.ts +108 -0
  644. package/src/runs/drivers/files.ts +201 -0
  645. package/src/runs/drivers/memory.ts +94 -0
  646. package/src/runs/drivers/postgres.ts +110 -0
  647. package/src/runs/duckdb.ts +99 -0
  648. package/src/runs/index.ts +82 -0
  649. package/src/runs/outlier.ts +180 -0
  650. package/src/runs/parquet.ts +210 -0
  651. package/src/runs/privacy.ts +49 -0
  652. package/src/runs/runs.test.ts +324 -0
  653. package/src/runs/runtime.ts +229 -0
  654. package/src/runs/shred.ts +243 -0
  655. package/src/runs/telemetry.ts +10 -0
  656. package/src/runs/types.ts +179 -0
  657. package/src/runtime/bun.ts +140 -0
  658. package/src/runtime/cold-start.bench.ts +20 -0
  659. package/src/runtime/index.ts +46 -0
  660. package/src/runtime/primitives.ts +242 -0
  661. package/src/runtime/security.test.ts +170 -0
  662. package/src/runtime/security.ts +168 -0
  663. package/src/runtime/serve.test.ts +223 -0
  664. package/src/runtime/types.ts +217 -0
  665. package/src/runtime/web-standard.ts +77 -0
  666. package/src/test/create-test-app.test.ts +161 -0
  667. package/src/test/create-test-app.ts +533 -0
  668. package/src/test/index.ts +21 -0
  669. package/src/test/provisions.integration.test.ts +174 -0
  670. package/src/upgrade/codemods.test.ts +58 -0
  671. package/src/upgrade/codemods.ts +83 -0
  672. package/src/validation/index.ts +23 -0
  673. package/src/validation/standard-schema.test.ts +96 -0
  674. package/src/validation/standard-schema.ts +316 -0
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Dynamic (`aot: false`) parse/validate path.
3
+ *
4
+ * Always materialises the full request context — no `new Function()`, no
5
+ * dead-code elimination. Required on eval-restricted runtimes (the
6
+ * documented Cloudflare / edge pain that makes AoT an optimisation, never
7
+ * a requirement). Produces byte-identical responses to {@link compileAot}.
8
+ */
9
+
10
+ import type { SchemaInput } from "../validation/standard-schema.ts";
11
+ import {
12
+ compileAot,
13
+ createInterpretedParseValidate,
14
+ type CompiledRoute,
15
+ type CompileRouteOptions,
16
+ } from "./aot.ts";
17
+ import { FULL_INFERENCE } from "./http-parse.ts";
18
+ import { dynamicInference } from "./sucrose.ts";
19
+
20
+ /**
21
+ * Compile a route with the dynamic fallback (full context every request).
22
+ *
23
+ * @param options - Route metadata
24
+ */
25
+ export function compileDynamic(options: CompileRouteOptions): CompiledRoute {
26
+ const inference = dynamicInference();
27
+ return {
28
+ inference,
29
+ parseValidate: createInterpretedParseValidate(inference, options.schema),
30
+ aot: false,
31
+ };
32
+ }
33
+
34
+ /**
35
+ * Compile with AoT when `aot` is true (default), else dynamic.
36
+ *
37
+ * @param options - Route metadata
38
+ * @param aot - When `false`, force the dynamic path
39
+ */
40
+ export function compileRoute(
41
+ options: CompileRouteOptions,
42
+ aot: boolean = true,
43
+ ): CompiledRoute {
44
+ if (!aot) return compileDynamic(options);
45
+ return compileAot(options);
46
+ }
47
+
48
+ /**
49
+ * Full inference constant (tests / diagnostics).
50
+ */
51
+ export { FULL_INFERENCE };
52
+
53
+ /** @internal re-export schema type for consumers */
54
+ export type { SchemaInput };
@@ -0,0 +1,541 @@
1
+ /**
2
+ * Effect inference v1 — through the `fx` door only.
3
+ *
4
+ * Deep static analysis is a later optimisation. `fx.raw` requires an
5
+ * explicit `effects` annotation on the flow; unannotated raw access marks
6
+ * the flow cache-ineligible rather than silently guessing.
7
+ */
8
+
9
+ import type {
10
+ Effects,
11
+ PromptRef,
12
+ ResourceRef,
13
+ SecretRef,
14
+ SignalRef,
15
+ TemplateRef,
16
+ FlowRef,
17
+ } from "../manifest/types.ts";
18
+
19
+ /** Minimal ESTree-shaped nodes produced by oxc-parser. */
20
+ export interface AstNode {
21
+ readonly type: string;
22
+ readonly start?: number;
23
+ readonly end?: number;
24
+ readonly [key: string]: unknown;
25
+ }
26
+
27
+ /** CallExpression node. */
28
+ export interface CallExpression extends AstNode {
29
+ readonly type: "CallExpression";
30
+ readonly callee: AstNode;
31
+ readonly arguments: readonly AstNode[];
32
+ }
33
+
34
+ /** Identifier node. */
35
+ export interface Identifier extends AstNode {
36
+ readonly type: "Identifier";
37
+ readonly name: string;
38
+ }
39
+
40
+ /** Literal node. */
41
+ export interface Literal extends AstNode {
42
+ readonly type: "Literal";
43
+ readonly value: string | number | boolean | null;
44
+ }
45
+
46
+ /** Binding known to the extractor (stores, signals, prompts, …). */
47
+ export interface InferBinding {
48
+ /** Kind of binding. */
49
+ readonly kind:
50
+ | "store"
51
+ | "signal"
52
+ | "prompt"
53
+ | "secret"
54
+ | "template"
55
+ | "flow"
56
+ | "embed"
57
+ | "unknown";
58
+ /** Resolved resource / name. */
59
+ readonly ref: string;
60
+ /** Store facet when kind is `store`. */
61
+ readonly facet?: "sql" | "kv" | "files" | "index";
62
+ /** Prompt version when kind is `prompt`. */
63
+ readonly version?: number;
64
+ }
65
+
66
+ /** Options for {@link inferEffects}. */
67
+ export interface InferEffectsOptions {
68
+ /** The `do` handler AST node (function / arrow). */
69
+ readonly doNode: AstNode;
70
+ /** Local name → binding (from the project scope). */
71
+ readonly bindings: ReadonlyMap<string, InferBinding>;
72
+ /**
73
+ * True when the flow options already declare an `effects` object.
74
+ * Required for `fx.raw` to stay cache-eligible.
75
+ */
76
+ readonly hasExplicitEffects: boolean;
77
+ }
78
+
79
+ /** Result of effect inference for one flow body. */
80
+ export interface InferredEffects {
81
+ /** Inferred effect set. */
82
+ readonly effects: Effects;
83
+ /** Named durable steps from `fx.step("…")`. */
84
+ readonly steps: string[];
85
+ /** True when the body calls `fx.raw`. */
86
+ readonly usesRaw: boolean;
87
+ /**
88
+ * True when `fx.raw` appears without an explicit effects annotation —
89
+ * the flow must opt out of auto-caching.
90
+ */
91
+ readonly cacheIneligible: boolean;
92
+ /** True when any `fx.ask` was seen (implies nondeterministic). */
93
+ readonly nondeterministic: boolean;
94
+ /** True when the body references `fx.auth.userId`. */
95
+ readonly readsUserId: boolean;
96
+ }
97
+
98
+ const READ_METHODS = new Set([
99
+ "select",
100
+ "get",
101
+ "findById",
102
+ "exists",
103
+ "findMany",
104
+ "findFirst",
105
+ "find",
106
+ ]);
107
+
108
+ const WRITE_METHODS = new Set([
109
+ "insert",
110
+ "set",
111
+ "delete",
112
+ "increment",
113
+ "update",
114
+ "upsert",
115
+ "log",
116
+ ]);
117
+
118
+ /** Methods whose first argument is a table / collection identifier. */
119
+ const TABLE_ARG_METHODS = new Set([
120
+ "insert",
121
+ "from",
122
+ "findById",
123
+ "exists",
124
+ "update",
125
+ "increment",
126
+ "delete",
127
+ ]);
128
+
129
+ /**
130
+ * Infer effects for a flow `do` body by walking `fx.*` call sites.
131
+ *
132
+ * @param options - Handler AST, bindings, and annotation flag
133
+ */
134
+ export function inferEffects(options: InferEffectsOptions): InferredEffects {
135
+ const reads = new Set<ResourceRef>();
136
+ const writes = new Set<ResourceRef>();
137
+ const emits = new Set<SignalRef>();
138
+ const sends = new Set<TemplateRef>();
139
+ const asks = new Set<PromptRef>();
140
+ const secrets = new Set<SecretRef>();
141
+ const calls = new Set<FlowRef>();
142
+ const steps: string[] = [];
143
+ let usesRaw = false;
144
+
145
+ for (const call of collectCallExpressions(options.doNode)) {
146
+ const chain = fxMemberChain(call);
147
+ if (!chain) continue;
148
+
149
+ if (chain.rootMethod === "raw") {
150
+ usesRaw = true;
151
+ continue;
152
+ }
153
+
154
+ if (chain.rootMethod === "step" && call === chain.rootCall) {
155
+ const name = stringArg(call.arguments[0]);
156
+ if (name !== undefined && !steps.includes(name)) steps.push(name);
157
+ continue;
158
+ }
159
+
160
+ if (chain.rootMethod === "emit" && call === chain.rootCall) {
161
+ const ref = resolveNamed(call.arguments[0], options.bindings, "signal");
162
+ if (ref) emits.add(ref);
163
+ continue;
164
+ }
165
+
166
+ if (chain.rootMethod === "send" && call === chain.rootCall) {
167
+ const ref = resolveNamed(call.arguments[0], options.bindings, "template");
168
+ if (ref) sends.add(ref);
169
+ continue;
170
+ }
171
+
172
+ if (chain.rootMethod === "ask" && call === chain.rootCall) {
173
+ const ref = resolvePrompt(call.arguments[0], options.bindings);
174
+ if (ref) asks.add(ref);
175
+ continue;
176
+ }
177
+
178
+ if (chain.rootMethod === "vault" && call === chain.rootCall) {
179
+ const ref = resolveNamed(call.arguments[0], options.bindings, "secret");
180
+ if (ref) secrets.add(ref);
181
+ continue;
182
+ }
183
+
184
+ if (chain.rootMethod === "call" && call === chain.rootCall) {
185
+ const ref = resolveNamed(call.arguments[0], options.bindings, "flow");
186
+ if (ref) calls.add(ref);
187
+ continue;
188
+ }
189
+
190
+ if (chain.rootMethod === "search" && call === chain.rootCall) {
191
+ const ref = resolveNamed(call.arguments[0], options.bindings, "embed");
192
+ if (ref) {
193
+ reads.add((ref.includes(":") ? ref : `index:${ref}`) as ResourceRef);
194
+ }
195
+ continue;
196
+ }
197
+
198
+ if (chain.rootMethod === "store") {
199
+ const resolved = storeResourceFromCall(call, options.bindings);
200
+ if (!resolved) continue;
201
+ const op = classifyStoreMethods(resolved.methods);
202
+ if (op === "none") continue;
203
+ // Skip incomplete chains (`select` before `.from`, `insert` before table) —
204
+ // the sibling call that carries the table arg records the real resource.
205
+ const leaf = resolved.methods[resolved.methods.length - 1]!;
206
+ const hasTable = tableFromStoreChain(call) !== undefined;
207
+ if (
208
+ !hasTable &&
209
+ (leaf === "select" || leaf === "insert" || leaf === "update")
210
+ ) {
211
+ continue;
212
+ }
213
+ // Intermediate chain links that only forward (where/values/returning)
214
+ // still carry read/write from earlier methods — record once we have a table
215
+ // or a terminal key-based op.
216
+ if (
217
+ !hasTable &&
218
+ (leaf === "where" || leaf === "values" || leaf === "returning")
219
+ ) {
220
+ continue;
221
+ }
222
+ if (op === "read" || op === "both") reads.add(resolved.resource);
223
+ if (op === "write" || op === "both") writes.add(resolved.resource);
224
+ }
225
+ }
226
+
227
+ const effects: Effects = {};
228
+ if (reads.size > 0) effects.reads = sortUnique([...reads]);
229
+ if (writes.size > 0) effects.writes = sortUnique([...writes]);
230
+ if (emits.size > 0) effects.emits = sortUnique([...emits]);
231
+ if (sends.size > 0) effects.sends = sortUnique([...sends]);
232
+ if (asks.size > 0) effects.asks = sortUnique([...asks]);
233
+ if (secrets.size > 0) effects.secrets = sortUnique([...secrets]);
234
+ if (calls.size > 0) effects.calls = sortUnique([...calls]);
235
+
236
+ return {
237
+ effects,
238
+ steps,
239
+ usesRaw,
240
+ cacheIneligible: usesRaw && !options.hasExplicitEffects,
241
+ nondeterministic: asks.size > 0,
242
+ readsUserId: containsAuthUserId(options.doNode),
243
+ };
244
+ }
245
+
246
+ /**
247
+ * Walk an AST and collect every CallExpression.
248
+ *
249
+ * @param root - Root node
250
+ */
251
+ export function collectCallExpressions(root: AstNode): CallExpression[] {
252
+ const out: CallExpression[] = [];
253
+ walk(root, (node) => {
254
+ if (node.type === "CallExpression") out.push(node as CallExpression);
255
+ });
256
+ return out;
257
+ }
258
+
259
+ /**
260
+ * Generic AST walk.
261
+ *
262
+ * @param node - Current node
263
+ * @param visit - Visitor
264
+ */
265
+ export function walk(node: unknown, visit: (node: AstNode) => void): void {
266
+ if (node === null || typeof node !== "object") return;
267
+ const n = node as AstNode;
268
+ if (typeof n.type === "string") visit(n);
269
+ for (const value of Object.values(n)) {
270
+ if (Array.isArray(value)) {
271
+ for (const item of value) walk(item, visit);
272
+ } else if (value !== null && typeof value === "object") {
273
+ walk(value, visit);
274
+ }
275
+ }
276
+ }
277
+
278
+ interface FxChain {
279
+ rootMethod: string;
280
+ methods: string[];
281
+ rootCall: CallExpression;
282
+ }
283
+
284
+ /**
285
+ * If `call` is part of an `fx.method…` chain, return the root method and
286
+ * the full method path from root to this call.
287
+ *
288
+ * @param call - Call expression
289
+ */
290
+ export function fxMemberChain(call: CallExpression): FxChain | null {
291
+ let current: CallExpression | null = call;
292
+ const methods: string[] = [];
293
+ let rootCall: CallExpression | null = null;
294
+ let rootMethod: string | null = null;
295
+
296
+ while (current) {
297
+ const callee = current.callee;
298
+ if (callee.type !== "MemberExpression") return null;
299
+ const member = callee as AstNode & {
300
+ object: AstNode;
301
+ property: AstNode;
302
+ computed?: boolean;
303
+ };
304
+ if (member.computed) return null;
305
+ if (member.property.type !== "Identifier") return null;
306
+ const prop = (member.property as Identifier).name;
307
+ methods.unshift(prop);
308
+
309
+ if (
310
+ member.object.type === "Identifier" &&
311
+ (member.object as Identifier).name === "fx"
312
+ ) {
313
+ rootCall = current;
314
+ rootMethod = prop;
315
+ break;
316
+ }
317
+
318
+ if (member.object.type === "CallExpression") {
319
+ current = member.object as CallExpression;
320
+ continue;
321
+ }
322
+
323
+ if (member.object.type === "MemberExpression") {
324
+ const inner = member.object as AstNode & {
325
+ object: AstNode;
326
+ property: AstNode;
327
+ };
328
+ if (
329
+ inner.object.type === "Identifier" &&
330
+ (inner.object as Identifier).name === "fx" &&
331
+ inner.property.type === "Identifier"
332
+ ) {
333
+ rootCall = current;
334
+ rootMethod = (inner.property as Identifier).name;
335
+ methods.unshift(rootMethod);
336
+ break;
337
+ }
338
+ }
339
+
340
+ return null;
341
+ }
342
+
343
+ if (!rootCall || !rootMethod) return null;
344
+ return { rootMethod, methods, rootCall };
345
+ }
346
+
347
+ /**
348
+ * Resolve the store resource for a call that is `fx.store(…).method(table?)`.
349
+ *
350
+ * @param call - Any call in an fx.store chain
351
+ * @param bindings - Scope bindings
352
+ */
353
+ export function storeResourceFromCall(
354
+ call: CallExpression,
355
+ bindings: ReadonlyMap<string, InferBinding>,
356
+ ): { resource: ResourceRef; methods: string[] } | undefined {
357
+ const chain = fxMemberChain(call);
358
+ if (!chain || chain.rootMethod !== "store") return undefined;
359
+
360
+ const storeArg = chain.rootCall.arguments[0];
361
+ const storeBinding = resolveBinding(storeArg, bindings);
362
+ const facet = storeBinding?.facet ?? "sql";
363
+
364
+ const table = tableFromStoreChain(call);
365
+
366
+ if (table) {
367
+ return {
368
+ resource: `${facet}:${table}` as ResourceRef,
369
+ methods: chain.methods,
370
+ };
371
+ }
372
+
373
+ if (storeBinding?.kind === "store") {
374
+ return { resource: storeBinding.ref as ResourceRef, methods: chain.methods };
375
+ }
376
+
377
+ const literal = stringArg(storeArg);
378
+ if (literal) {
379
+ return {
380
+ resource: (literal.includes(":")
381
+ ? literal
382
+ : `${facet}:${literal}`) as ResourceRef,
383
+ methods: chain.methods,
384
+ };
385
+ }
386
+
387
+ const id = identifierName(storeArg);
388
+ if (id) {
389
+ return { resource: `${facet}:${id}` as ResourceRef, methods: chain.methods };
390
+ }
391
+
392
+ return undefined;
393
+ }
394
+
395
+ /**
396
+ * Walk an `fx.store(…).a().b(table)` chain and return the table identifier.
397
+ *
398
+ * @param call - Any call in the chain
399
+ */
400
+ function tableFromStoreChain(call: CallExpression): string | undefined {
401
+ let current: AstNode | undefined = call;
402
+ while (current && current.type === "CallExpression") {
403
+ const c = current as CallExpression;
404
+ const link = fxMemberChain(c);
405
+ if (!link || link.rootMethod !== "store") break;
406
+ const leaf = link.methods[link.methods.length - 1]!;
407
+ if (TABLE_ARG_METHODS.has(leaf)) {
408
+ const table = identifierName(c.arguments[0]);
409
+ if (table) return table;
410
+ }
411
+ const callee = c.callee;
412
+ if (callee.type === "MemberExpression") {
413
+ current = (callee as AstNode & { object: AstNode }).object;
414
+ continue;
415
+ }
416
+ break;
417
+ }
418
+ return undefined;
419
+ }
420
+
421
+ function classifyStoreMethods(
422
+ methods: string[],
423
+ ): "read" | "write" | "both" | "none" {
424
+ const ops = methods.slice(1);
425
+ let read = false;
426
+ let write = false;
427
+ for (const m of ops) {
428
+ if (READ_METHODS.has(m)) read = true;
429
+ if (WRITE_METHODS.has(m)) write = true;
430
+ }
431
+ if (!read && !write) return "none";
432
+ if (read && write) return "both";
433
+ return read ? "read" : "write";
434
+ }
435
+
436
+ function sortUnique<T extends string>(values: T[]): T[] {
437
+ return [...new Set(values)].sort();
438
+ }
439
+
440
+ function resolveBinding(
441
+ node: AstNode | undefined,
442
+ bindings: ReadonlyMap<string, InferBinding>,
443
+ ): InferBinding | undefined {
444
+ const name = identifierName(node);
445
+ if (!name) return undefined;
446
+ return bindings.get(name);
447
+ }
448
+
449
+ function resolveNamed(
450
+ node: AstNode | undefined,
451
+ bindings: ReadonlyMap<string, InferBinding>,
452
+ kind: InferBinding["kind"],
453
+ ): string | undefined {
454
+ const lit = stringArg(node);
455
+ if (lit) return lit;
456
+ const binding = resolveBinding(node, bindings);
457
+ if (binding && (binding.kind === kind || binding.kind === "unknown")) {
458
+ return binding.ref;
459
+ }
460
+ return identifierName(node);
461
+ }
462
+
463
+ function resolvePrompt(
464
+ node: AstNode | undefined,
465
+ bindings: ReadonlyMap<string, InferBinding>,
466
+ ): PromptRef | undefined {
467
+ const lit = stringArg(node);
468
+ if (lit) return lit;
469
+ const binding = resolveBinding(node, bindings);
470
+ if (binding?.kind === "prompt") {
471
+ if (binding.version !== undefined) {
472
+ return `${binding.ref}@${binding.version}`;
473
+ }
474
+ return binding.ref;
475
+ }
476
+ return identifierName(node);
477
+ }
478
+
479
+ /**
480
+ * String literal argument.
481
+ *
482
+ * @param node - AST node
483
+ */
484
+ export function stringArg(node: AstNode | undefined): string | undefined {
485
+ if (!node) return undefined;
486
+ if (node.type === "Literal" && typeof (node as Literal).value === "string") {
487
+ return (node as Literal).value as string;
488
+ }
489
+ if (node.type === "TemplateLiteral") {
490
+ const quasis = (node as AstNode & { quasis?: AstNode[] }).quasis;
491
+ const exprs = (node as AstNode & { expressions?: AstNode[] }).expressions;
492
+ if (quasis?.length === 1 && (exprs?.length ?? 0) === 0) {
493
+ const cooked = (
494
+ quasis[0] as AstNode & { value?: { cooked?: string } }
495
+ ).value?.cooked;
496
+ if (typeof cooked === "string") return cooked;
497
+ }
498
+ }
499
+ return undefined;
500
+ }
501
+
502
+ /**
503
+ * Identifier name.
504
+ *
505
+ * @param node - AST node
506
+ */
507
+ export function identifierName(node: AstNode | undefined): string | undefined {
508
+ if (!node) return undefined;
509
+ if (node.type === "Identifier") return (node as Identifier).name;
510
+ return undefined;
511
+ }
512
+
513
+ function containsAuthUserId(root: AstNode): boolean {
514
+ let found = false;
515
+ walk(root, (node) => {
516
+ if (found) return;
517
+ if (node.type !== "MemberExpression") return;
518
+ const member = node as AstNode & {
519
+ object: AstNode;
520
+ property: AstNode;
521
+ computed?: boolean;
522
+ };
523
+ if (member.computed) return;
524
+ if (member.property.type !== "Identifier") return;
525
+ if ((member.property as Identifier).name !== "userId") return;
526
+ if (member.object.type !== "MemberExpression") return;
527
+ const auth = member.object as AstNode & {
528
+ object: AstNode;
529
+ property: AstNode;
530
+ };
531
+ if (auth.property.type !== "Identifier") return;
532
+ if ((auth.property as Identifier).name !== "auth") return;
533
+ if (
534
+ auth.object.type === "Identifier" &&
535
+ (auth.object as Identifier).name === "fx"
536
+ ) {
537
+ found = true;
538
+ }
539
+ });
540
+ return found;
541
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Write a Manifest to `manifest.oke.json` (or a caller-chosen path).
3
+ */
4
+
5
+ import type { Manifest } from "../manifest/types.ts";
6
+ import { serializeManifest } from "../manifest/validate.ts";
7
+
8
+ /** Default Manifest artefact filename. */
9
+ export const MANIFEST_FILENAME = "manifest.oke.json";
10
+
11
+ /** Options for {@link emitManifest}. */
12
+ export interface EmitManifestOptions {
13
+ /** Destination file path. */
14
+ readonly path: string;
15
+ /** Manifest document to write. */
16
+ readonly manifest: Manifest;
17
+ }
18
+
19
+ /**
20
+ * Serialise and write a Manifest as stable JSON.
21
+ *
22
+ * @param options - Path and document
23
+ * @returns Absolute path written
24
+ */
25
+ export async function emitManifest(
26
+ options: EmitManifestOptions,
27
+ ): Promise<string> {
28
+ const text = serializeManifest(options.manifest);
29
+ await Bun.write(options.path, text);
30
+ return options.path;
31
+ }
32
+
33
+ /**
34
+ * Resolve `manifest.oke.json` under a directory.
35
+ *
36
+ * @param dir - Output directory
37
+ */
38
+ export function manifestPathIn(dir: string): string {
39
+ return `${dir.replace(/\/$/, "")}/${MANIFEST_FILENAME}`;
40
+ }