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
package/src/cli/dev.ts ADDED
@@ -0,0 +1,594 @@
1
+ /**
2
+ * `oke dev` — watch · hot reload · Console :6533 · MCP :6535 · client types on save.
3
+ * `oke dev --stack` also boots generated compose.
4
+ */
5
+
6
+ import { watch } from "node:fs";
7
+ import { unlink } from "node:fs/promises";
8
+ import { tmpdir } from "node:os";
9
+ import { join, resolve } from "node:path";
10
+ import type { SessionStore } from "../auth/sessions.ts";
11
+ import type { ConsoleAppHandle } from "../console/server/app.ts";
12
+ import type { ConsoleState } from "../console/server/state.ts";
13
+ import {
14
+ deriveInfrastructure,
15
+ formatStackEnv,
16
+ writeDerivedFiles,
17
+ type DeriveOptions,
18
+ } from "../docker/index.ts";
19
+ import type { Manifest } from "../manifest/types.ts";
20
+ import type { McpContext } from "../mcp/tools.ts";
21
+ import {
22
+ APP_PORT,
23
+ CONSOLE_PORT,
24
+ MCP_PORT,
25
+ } from "../runtime/types.ts";
26
+ import { clientAdd } from "./client-add.ts";
27
+ import { loadManifest, loadOkeConfig, resolveImages } from "./load-config.ts";
28
+ import { mcpContextFromConsole } from "./mcp-from-console.ts";
29
+
30
+ /** Max wait for the `bun --hot` app child to bind a port. */
31
+ const APP_READY_TIMEOUT_MS = 30_000;
32
+
33
+ /** Stoppable surface handle. */
34
+ export interface DevSurfaceHandle {
35
+ readonly stop: () => void;
36
+ }
37
+
38
+ /** App surface returned by {@link DevOptions.startApp}. */
39
+ export interface DevAppHandle {
40
+ readonly stop: () => void;
41
+ /** Bound listen port (set when serve chooses an ephemeral port). */
42
+ readonly port?: number;
43
+ /** Base URL of the app server. */
44
+ readonly url?: URL;
45
+ }
46
+
47
+ /** Console surface returned by {@link DevOptions.serveConsole}. */
48
+ export interface DevConsoleHandle extends DevSurfaceHandle {
49
+ /**
50
+ * Live Console kernel — when present, MCP binds to this state
51
+ * (same Manifest / sessions / runs).
52
+ */
53
+ readonly console?: ConsoleAppHandle;
54
+ /** Bound listen port (may differ from the requested port when `0`). */
55
+ readonly port?: number;
56
+ }
57
+
58
+ /** MCP surface returned by {@link DevOptions.serveMcp}. */
59
+ export interface DevMcpHandle extends DevSurfaceHandle {
60
+ /** Bound listen port. */
61
+ readonly port?: number;
62
+ /** Base URL of the MCP server. */
63
+ readonly url?: URL;
64
+ }
65
+
66
+ /** Options for {@link DevOptions.serveMcp}. */
67
+ export interface DevServeMcpOptions {
68
+ readonly port: number;
69
+ readonly sessions: SessionStore;
70
+ readonly secret: string;
71
+ readonly context: McpContext;
72
+ readonly now?: () => number;
73
+ readonly hostname?: string;
74
+ }
75
+
76
+ /** Live `oke dev` session — returned when {@link DevOptions.keepAlive} is false. */
77
+ export interface DevSession {
78
+ readonly plan: DevPlan;
79
+ /** Stop app · Console · MCP · watcher. */
80
+ readonly stop: () => void;
81
+ readonly appPort: number;
82
+ readonly consolePort: number;
83
+ readonly mcpPort: number;
84
+ readonly mcpUrl: URL | null;
85
+ /** Shared with Console — mint `oke-mcp` tokens against this store/secret. */
86
+ readonly secret: string | null;
87
+ readonly sessions: SessionStore | null;
88
+ /** Same Console state MCP reads through (tests seed Manifest / runs here). */
89
+ readonly consoleState: ConsoleState | null;
90
+ }
91
+
92
+ /** Options for {@link runDev}. */
93
+ export interface DevOptions {
94
+ readonly cwd?: string;
95
+ readonly entry?: string;
96
+ readonly stack?: boolean | readonly string[];
97
+ readonly images?: Readonly<Record<string, string>>;
98
+ readonly credentials?: DeriveOptions["credentials"];
99
+ readonly write?: (text: string) => void;
100
+ /** Skip spawning the watcher / servers (unit tests). */
101
+ readonly dryRun?: boolean;
102
+ /**
103
+ * When false, return a {@link DevSession} after boot instead of hanging
104
+ * (integration tests). Default true for the CLI.
105
+ */
106
+ readonly keepAlive?: boolean;
107
+ /** Called once all surfaces are listening (before keep-alive). */
108
+ readonly onReady?: (session: DevSession) => void | Promise<void>;
109
+ /** Operator auth secret (shared by Console + MCP). */
110
+ readonly secret?: string;
111
+ /** Seed Manifest into Console (and therefore MCP). */
112
+ readonly manifest?: Manifest | null;
113
+ /** Suppress claim-code print (tests). */
114
+ readonly silentClaim?: boolean;
115
+ /** Port overrides (use `0` for ephemeral in tests). */
116
+ readonly appPort?: number;
117
+ readonly consolePort?: number;
118
+ readonly mcpPort?: number;
119
+ /**
120
+ * Boot compose stack (injectable).
121
+ *
122
+ * @param composeFiles - `-f` list excluding override if missing
123
+ * @param cwd - Project root
124
+ */
125
+ readonly composeUp?: (
126
+ composeFiles: readonly string[],
127
+ cwd: string,
128
+ ) => Promise<void>;
129
+ /**
130
+ * Regenerate client types (injectable).
131
+ *
132
+ * @param appUrl - App base URL
133
+ */
134
+ readonly regenClient?: (appUrl: string) => Promise<void>;
135
+ /** Serve Console (injectable). */
136
+ readonly serveConsole?: (port: number) => Promise<DevConsoleHandle>;
137
+ /**
138
+ * Serve MCP against the live Console context (injectable).
139
+ * Default: {@link serveMcp} on :6535.
140
+ */
141
+ readonly serveMcp?: (options: DevServeMcpOptions) => Promise<DevMcpHandle>;
142
+ /**
143
+ * Boot + serve the app entry (injectable).
144
+ * Default: spawn `bun --hot` on the shipped {@link ./dev-app-runner.ts}
145
+ * (import → `app.boot()` → `createBunRuntime().serve`) so Bun soft-reloads
146
+ * app code while preserving the listen socket.
147
+ */
148
+ readonly startApp?: (
149
+ entry: string,
150
+ env: Record<string, string>,
151
+ ) => Promise<DevAppHandle>;
152
+ }
153
+
154
+ /** Result of a dry-run / prepared / live-but-detached dev session. */
155
+ export interface DevPlan {
156
+ readonly entry: string;
157
+ readonly appPort: number;
158
+ readonly consolePort: number;
159
+ readonly mcpPort: number;
160
+ readonly stackRoles: readonly string[] | null;
161
+ readonly composeFiles: readonly string[] | null;
162
+ readonly stackEnv: Readonly<Record<string, string>> | null;
163
+ }
164
+
165
+ /** Result of {@link runDev}. */
166
+ export interface DevResult {
167
+ readonly code: number;
168
+ readonly plan?: DevPlan;
169
+ /** Present when {@link DevOptions.keepAlive} is false. */
170
+ readonly session?: DevSession;
171
+ }
172
+
173
+ /**
174
+ * Prepare (and optionally run) a dev session.
175
+ *
176
+ * @param options - Flags
177
+ */
178
+ export async function runDev(options: DevOptions = {}): Promise<DevResult> {
179
+ const write = options.write ?? ((t) => process.stdout.write(t));
180
+ const cwd = options.cwd ?? process.cwd();
181
+ const appPort = options.appPort ?? Number(Bun.env.PORT ?? APP_PORT);
182
+ const consolePort = options.consolePort ?? CONSOLE_PORT;
183
+ const mcpPort = options.mcpPort ?? MCP_PORT;
184
+ const keepAlive = options.keepAlive ?? true;
185
+
186
+ let entry = options.entry;
187
+ if (!entry) {
188
+ for (const c of ["src/app.ts", "src/index.ts", "index.ts", "app.ts"]) {
189
+ if (await Bun.file(resolve(cwd, c)).exists()) {
190
+ entry = c;
191
+ break;
192
+ }
193
+ }
194
+ }
195
+ if (!entry) {
196
+ console.error("oke dev: no entry found (src/app.ts)");
197
+ return { code: 1 };
198
+ }
199
+
200
+ let stackRoles: string[] | null = null;
201
+ let composeFiles: string[] | null = null;
202
+ let stackEnv: Record<string, string> | null = null;
203
+
204
+ if (options.stack) {
205
+ let images = options.images;
206
+ if (!images) {
207
+ try {
208
+ const loaded = await loadOkeConfig(cwd);
209
+ images = resolveImages(loaded.config);
210
+ } catch (err) {
211
+ console.error(err instanceof Error ? err.message : String(err));
212
+ return { code: 1 };
213
+ }
214
+ }
215
+ if (Array.isArray(options.stack)) {
216
+ const allow = new Set(options.stack);
217
+ images = Object.fromEntries(
218
+ Object.entries(images).filter(([role]) => allow.has(role)),
219
+ );
220
+ stackRoles = [...allow];
221
+ } else {
222
+ stackRoles = Object.keys(images);
223
+ }
224
+
225
+ const derived = deriveInfrastructure({
226
+ images,
227
+ app: "dev",
228
+ prod: false,
229
+ ...(options.credentials ? { credentials: options.credentials } : {}),
230
+ host: "127.0.0.1",
231
+ });
232
+ // Layer 4 is user-owned — include only if the file already exists.
233
+ const existingOverride = await Bun.file(
234
+ resolve(cwd, "compose.override.yml"),
235
+ ).exists();
236
+ composeFiles = derived.composeFiles.filter(
237
+ (f) => f !== "compose.override.yml" || existingOverride,
238
+ );
239
+ stackEnv = { ...derived.stackEnv };
240
+
241
+ if (!options.dryRun) {
242
+ await writeDerivedFiles(derived, cwd, { writeStackEnv: true });
243
+ // Ensure .env.stack is loaded for the app process
244
+ await Bun.write(resolve(cwd, ".env.stack"), formatStackEnv(stackEnv));
245
+ const up =
246
+ options.composeUp ??
247
+ (async (files, dir) => {
248
+ const args = ["compose", ...files.flatMap((f) => ["-f", f]), "up", "-d"];
249
+ const proc = Bun.spawn(["docker", ...args], {
250
+ cwd: dir,
251
+ stdout: "inherit",
252
+ stderr: "inherit",
253
+ env: { ...process.env, ...stackEnv! },
254
+ });
255
+ const code = await proc.exited;
256
+ if (code !== 0) {
257
+ throw new Error(`oke dev --stack: docker compose exited ${code}`);
258
+ }
259
+ });
260
+ await up(composeFiles, cwd);
261
+ write(`oke dev: stack up (${stackRoles.join(", ")})\n`);
262
+ }
263
+ }
264
+
265
+ const plan: DevPlan = {
266
+ entry: resolve(cwd, entry),
267
+ appPort,
268
+ consolePort,
269
+ mcpPort,
270
+ stackRoles,
271
+ composeFiles,
272
+ stackEnv,
273
+ };
274
+
275
+ write(
276
+ `oke dev: app :${appPort} · Console :${consolePort} · MCP :${mcpPort}\n`,
277
+ );
278
+ write("oke dev: watching — client types regenerate on save\n");
279
+
280
+ if (options.dryRun) return { code: 0, plan };
281
+
282
+ const env: Record<string, string> = {
283
+ ...(process.env as Record<string, string>),
284
+ NODE_ENV: "development",
285
+ PORT: String(appPort),
286
+ ...(stackEnv ?? {}),
287
+ };
288
+
289
+ const startApp =
290
+ options.startApp ??
291
+ ((entryPath, appEnv) => startAppHot(cwd, entryPath, appEnv));
292
+
293
+ const seedManifest =
294
+ options.manifest !== undefined
295
+ ? options.manifest
296
+ : await tryLoadProjectManifest(cwd);
297
+
298
+ const serveConsole =
299
+ options.serveConsole ??
300
+ (async (port) => {
301
+ const { serveConsole: serveConsoleKernel } = await import(
302
+ "../console/server/serve.ts"
303
+ );
304
+ const server = await serveConsoleKernel({
305
+ port,
306
+ hostname: "127.0.0.1",
307
+ cwd,
308
+ env: "dev",
309
+ silentClaim: options.silentClaim ?? false,
310
+ ...(options.secret !== undefined ? { secret: options.secret } : {}),
311
+ ...(seedManifest !== undefined && seedManifest !== null
312
+ ? { manifest: seedManifest }
313
+ : {}),
314
+ });
315
+ write(`oke Console http://127.0.0.1:${server.port}\n`);
316
+ return {
317
+ console: server.console,
318
+ port: server.port,
319
+ stop() {
320
+ server.stop(true);
321
+ },
322
+ };
323
+ });
324
+
325
+ const serveMcpSurface =
326
+ options.serveMcp ??
327
+ (async (mcpOptions) => {
328
+ const { serveMcp } = await import("../mcp/server.ts");
329
+ const server = await serveMcp({
330
+ port: mcpOptions.port,
331
+ hostname: mcpOptions.hostname ?? "127.0.0.1",
332
+ sessions: mcpOptions.sessions,
333
+ secret: mcpOptions.secret,
334
+ context: mcpOptions.context,
335
+ now: mcpOptions.now,
336
+ });
337
+ write(`oke MCP http://127.0.0.1:${server.port}\n`);
338
+ return {
339
+ port: server.port,
340
+ url: server.url,
341
+ stop() {
342
+ server.stop(true);
343
+ },
344
+ };
345
+ });
346
+
347
+ const regen =
348
+ options.regenClient ??
349
+ (async (appUrl) => {
350
+ try {
351
+ await clientAdd({
352
+ url: appUrl,
353
+ out: resolve(cwd, "oke-client.d.ts"),
354
+ });
355
+ write("oke dev: regenerated oke-client.d.ts\n");
356
+ } catch {
357
+ // App may not be ready yet — ignore until next save.
358
+ }
359
+ });
360
+
361
+ const app = await startApp(plan.entry, env);
362
+ const boundAppPort = app.port ?? appPort;
363
+ const consoleServer = await serveConsole(consolePort);
364
+ const boundConsolePort = consoleServer.port ?? consolePort;
365
+
366
+ let mcpServer: DevMcpHandle | null = null;
367
+ let consoleState: ConsoleState | null = null;
368
+ let secret: string | null = null;
369
+ let sessions: SessionStore | null = null;
370
+
371
+ if (consoleServer.console) {
372
+ const state = consoleServer.console.state;
373
+ consoleState = state;
374
+ secret = state.secret;
375
+ sessions = state.sessions;
376
+ mcpServer = await serveMcpSurface({
377
+ port: mcpPort,
378
+ sessions: state.sessions,
379
+ secret: state.secret,
380
+ context: mcpContextFromConsole(state),
381
+ now: state.now,
382
+ hostname: "127.0.0.1",
383
+ });
384
+ }
385
+
386
+ const boundMcpPort = mcpServer?.port ?? mcpPort;
387
+ const mcpUrl = mcpServer?.url ?? null;
388
+
389
+ const appUrl =
390
+ app.url?.origin ?? `http://127.0.0.1:${boundAppPort}`;
391
+ await regen(appUrl);
392
+
393
+ const watcher = watch(
394
+ resolve(cwd, "src"),
395
+ { recursive: true },
396
+ () => {
397
+ void regen(appUrl);
398
+ },
399
+ );
400
+
401
+ let stopped = false;
402
+ const stop = () => {
403
+ if (stopped) return;
404
+ stopped = true;
405
+ watcher.close();
406
+ app.stop();
407
+ consoleServer.stop();
408
+ mcpServer?.stop();
409
+ process.off("SIGINT", onSignal);
410
+ process.off("SIGTERM", onSignal);
411
+ };
412
+
413
+ const onSignal = () => {
414
+ stop();
415
+ process.exit(0);
416
+ };
417
+ process.on("SIGINT", onSignal);
418
+ process.on("SIGTERM", onSignal);
419
+
420
+ const session: DevSession = {
421
+ plan: {
422
+ ...plan,
423
+ appPort: boundAppPort,
424
+ consolePort: boundConsolePort,
425
+ mcpPort: boundMcpPort,
426
+ },
427
+ stop,
428
+ appPort: boundAppPort,
429
+ consolePort: boundConsolePort,
430
+ mcpPort: boundMcpPort,
431
+ mcpUrl,
432
+ secret,
433
+ sessions,
434
+ consoleState,
435
+ };
436
+
437
+ if (options.onReady) await options.onReady(session);
438
+
439
+ if (!keepAlive) {
440
+ return { code: 0, plan: session.plan, session };
441
+ }
442
+
443
+ // Keep the process alive.
444
+ await new Promise(() => {});
445
+ return { code: 0, plan: session.plan, session };
446
+ }
447
+
448
+ /**
449
+ * Load `oke.manifest.json` / `manifest.oke.json` when present.
450
+ *
451
+ * @param cwd - Project root
452
+ */
453
+ async function tryLoadProjectManifest(
454
+ cwd: string,
455
+ ): Promise<Manifest | null | undefined> {
456
+ for (const name of ["oke.manifest.json", "manifest.oke.json"]) {
457
+ const path = resolve(cwd, name);
458
+ if (await Bun.file(path).exists()) {
459
+ return loadManifest(path);
460
+ }
461
+ }
462
+ return undefined;
463
+ }
464
+
465
+ /**
466
+ * Default app boot: `bun --hot` on the shipped runner (socket-preserving).
467
+ *
468
+ * @param cwd - Project root
469
+ * @param entryPath - App entry (absolute or cwd-relative)
470
+ * @param appEnv - Env overlay (`PORT`, stack vars, …)
471
+ */
472
+ async function startAppHot(
473
+ cwd: string,
474
+ entryPath: string,
475
+ appEnv: Record<string, string>,
476
+ ): Promise<DevAppHandle> {
477
+ const absoluteEntry = resolve(cwd, entryPath);
478
+ const runner = resolve(import.meta.dir, "dev-app-runner.ts");
479
+ const readyPath = join(
480
+ tmpdir(),
481
+ `oke-dev-ready-${crypto.randomUUID()}.txt`,
482
+ );
483
+ const hostname = "127.0.0.1";
484
+ const env: Record<string, string> = {
485
+ ...appEnv,
486
+ OKE_ENTRY: absoluteEntry,
487
+ OKE_HOSTNAME: hostname,
488
+ OKE_READY_PATH: readyPath,
489
+ };
490
+
491
+ const proc = Bun.spawn(["bun", "--hot", runner], {
492
+ cwd,
493
+ env,
494
+ stdout: "inherit",
495
+ stderr: "inherit",
496
+ });
497
+
498
+ let stopped = false;
499
+ const stop = () => {
500
+ if (stopped) return;
501
+ stopped = true;
502
+ try {
503
+ proc.kill();
504
+ } catch {
505
+ // already exited
506
+ }
507
+ void unlink(readyPath).catch(() => {});
508
+ };
509
+
510
+ try {
511
+ const boundPort = await waitForAppReady(
512
+ readyPath,
513
+ proc,
514
+ APP_READY_TIMEOUT_MS,
515
+ );
516
+ // Child prints `oke app http://…` (again on each soft reload).
517
+ const url = new URL(`http://${hostname}:${boundPort}/`);
518
+ return { stop, port: boundPort, url };
519
+ } catch (err) {
520
+ stop();
521
+ throw err;
522
+ }
523
+ }
524
+
525
+ /**
526
+ * Poll the ready file until the app child binds a port (or exits).
527
+ *
528
+ * @param readyPath - Path the runner writes
529
+ * @param proc - Child process
530
+ * @param timeoutMs - Max wait
531
+ */
532
+ async function waitForAppReady(
533
+ readyPath: string,
534
+ proc: Bun.Subprocess,
535
+ timeoutMs: number,
536
+ ): Promise<number> {
537
+ const started = Date.now();
538
+ while (Date.now() - started < timeoutMs) {
539
+ const exitCode = proc.exitCode;
540
+ if (exitCode !== null) {
541
+ throw new Error(
542
+ `oke dev: app process exited before ready (code ${exitCode})`,
543
+ );
544
+ }
545
+ if (await Bun.file(readyPath).exists()) {
546
+ const text = (await Bun.file(readyPath).text()).trim();
547
+ const port = Number(text);
548
+ if (!Number.isFinite(port) || port <= 0) {
549
+ throw new Error(`oke dev: invalid ready port from app child: ${text}`);
550
+ }
551
+ return port;
552
+ }
553
+ await Bun.sleep(25);
554
+ }
555
+ throw new Error(
556
+ `oke dev: app did not become ready within ${timeoutMs}ms`,
557
+ );
558
+ }
559
+
560
+ /**
561
+ * CLI entry for `oke dev [--stack|-s [roles]]`.
562
+ *
563
+ * @param args - Args after `dev`
564
+ */
565
+ export async function devCli(args: readonly string[]): Promise<number> {
566
+ let stack: boolean | string[] | undefined;
567
+ let entry: string | undefined;
568
+ for (let i = 0; i < args.length; i++) {
569
+ const a = args[i]!;
570
+ if (a === "--stack" || a === "-s") {
571
+ const next = args[i + 1];
572
+ if (next && !next.startsWith("-") && /^[\w.,]+$/.test(next)) {
573
+ stack = next.split(",").map((s) => s.trim()).filter(Boolean);
574
+ i++;
575
+ } else {
576
+ stack = true;
577
+ }
578
+ } else if (a === "--entry" || a === "-e") entry = args[++i];
579
+ else if (a === "--help" || a === "-h") {
580
+ console.log(`oke dev [--stack|-s [roles]] [--entry|-e src/app.ts]
581
+
582
+ Watch · hot reload · Console :6533 · app :6530 · MCP :6535
583
+ Regenerates client types on every save.
584
+ --stack boots generated compose (partial roles: -s store.sql,signal).
585
+ `);
586
+ return 0;
587
+ }
588
+ }
589
+ const { code } = await runDev({
590
+ stack: stack === undefined ? undefined : stack,
591
+ entry,
592
+ });
593
+ return code;
594
+ }