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,283 @@
1
+ /**
2
+ * Dimension query language for the Runs panel (console §9.11).
3
+ *
4
+ * Expression form: `flow = X AND cache = miss AND duration > 1s`
5
+ * — analysis by dimension, not free-text search.
6
+ */
7
+
8
+ import type {
9
+ DimensionQuery,
10
+ QueryClause,
11
+ QueryOp,
12
+ RunRecord,
13
+ } from "./types.ts";
14
+
15
+ const OPS: readonly QueryOp[] = ["!=", ">=", "<=", "=", ">", "<"];
16
+
17
+ /**
18
+ * Parse a dimension query expression into clauses.
19
+ * Invalid tokens yield an empty query (never throw from the URL).
20
+ *
21
+ * @param expr - Expression string
22
+ */
23
+ export function parseDimensionQuery(expr: string | undefined | null): DimensionQuery {
24
+ if (!expr || !expr.trim()) return { clauses: [] };
25
+ const parts = expr.split(/\s+AND\s+/i).map((p) => p.trim()).filter(Boolean);
26
+ const clauses: QueryClause[] = [];
27
+ for (const part of parts) {
28
+ const clause = parseClause(part);
29
+ if (clause) clauses.push(clause);
30
+ }
31
+ return { clauses };
32
+ }
33
+
34
+ /**
35
+ * Serialise clauses back to expression syntax.
36
+ *
37
+ * @param query - Parsed query
38
+ */
39
+ export function serializeDimensionQuery(query: DimensionQuery): string {
40
+ return query.clauses.map(formatClause).join(" AND ");
41
+ }
42
+
43
+ /**
44
+ * Append one clause (or replace same dimension).
45
+ *
46
+ * @param query - Current query
47
+ * @param clause - Clause to add
48
+ */
49
+ export function upsertClause(
50
+ query: DimensionQuery,
51
+ clause: QueryClause,
52
+ ): DimensionQuery {
53
+ const rest = query.clauses.filter((c) => c.dimension !== clause.dimension);
54
+ return { clauses: [...rest, clause] };
55
+ }
56
+
57
+ /**
58
+ * Remove a dimension from the query.
59
+ *
60
+ * @param query - Current query
61
+ * @param dimension - Dimension name
62
+ */
63
+ export function removeClause(
64
+ query: DimensionQuery,
65
+ dimension: string,
66
+ ): DimensionQuery {
67
+ return {
68
+ clauses: query.clauses.filter((c) => c.dimension !== dimension),
69
+ };
70
+ }
71
+
72
+ /**
73
+ * Whether a run matches every clause.
74
+ *
75
+ * @param run - Wide-event projection
76
+ * @param query - Dimension query
77
+ */
78
+ export function matchesDimensionQuery(
79
+ run: RunRecord,
80
+ query: DimensionQuery,
81
+ ): boolean {
82
+ for (const clause of query.clauses) {
83
+ if (!matchClause(run, clause)) return false;
84
+ }
85
+ return true;
86
+ }
87
+
88
+ /**
89
+ * Filter a population by the dimension query.
90
+ *
91
+ * @param runs - All runs
92
+ * @param query - Dimension query
93
+ */
94
+ export function filterRuns(
95
+ runs: readonly RunRecord[],
96
+ query: DimensionQuery,
97
+ ): RunRecord[] {
98
+ if (query.clauses.length === 0) return [...runs];
99
+ return runs.filter((r) => matchesDimensionQuery(r, query));
100
+ }
101
+
102
+ /**
103
+ * Format a single clause for display / URL.
104
+ *
105
+ * @param clause - Clause
106
+ */
107
+ export function formatClause(clause: QueryClause): string {
108
+ const v = formatValue(clause.dimension, clause.value);
109
+ return `${clause.dimension} ${clause.op} ${v}`;
110
+ }
111
+
112
+ /**
113
+ * Common dimensions offered by the builder (others remain typed).
114
+ */
115
+ export const BUILDER_DIMENSIONS = [
116
+ "flow",
117
+ "unit",
118
+ "trigger",
119
+ "plane",
120
+ "tenant",
121
+ "principal",
122
+ "cache",
123
+ "replica",
124
+ "error",
125
+ "buildVersion",
126
+ "promptVersion",
127
+ "duration",
128
+ ] as const;
129
+
130
+ function parseClause(raw: string): QueryClause | null {
131
+ let op: QueryOp | null = null;
132
+ let opAt = -1;
133
+ for (const candidate of OPS) {
134
+ const idx = raw.indexOf(` ${candidate} `);
135
+ if (idx === -1) continue;
136
+ // Prefer longer ops already ordered first.
137
+ op = candidate;
138
+ opAt = idx;
139
+ break;
140
+ }
141
+ if (op === null || opAt < 0) return null;
142
+ const dimension = raw.slice(0, opAt).trim();
143
+ const valueRaw = raw.slice(opAt + op.length + 2).trim();
144
+ if (!dimension || !valueRaw) return null;
145
+ const value = parseValue(dimension, valueRaw);
146
+ if (value === undefined) return null;
147
+ return { dimension, op, value };
148
+ }
149
+
150
+ function parseValue(
151
+ dimension: string,
152
+ raw: string,
153
+ ): string | number | boolean | undefined {
154
+ if (dimension === "duration" || dimension === "duration_ms") {
155
+ return parseDurationMs(raw);
156
+ }
157
+ if (raw === "true") return true;
158
+ if (raw === "false") return false;
159
+ if (
160
+ (raw.startsWith('"') && raw.endsWith('"')) ||
161
+ (raw.startsWith("'") && raw.endsWith("'"))
162
+ ) {
163
+ return raw.slice(1, -1);
164
+ }
165
+ if (/^-?\d+(\.\d+)?$/.test(raw)) return Number(raw);
166
+ return raw;
167
+ }
168
+
169
+ /**
170
+ * Parse a duration literal (`1s`, `200ms`, `2m`, bare number = ms).
171
+ *
172
+ * @param raw - Literal
173
+ */
174
+ export function parseDurationMs(raw: string): number | undefined {
175
+ const m = /^(-?\d+(?:\.\d+)?)\s*(ms|s|m)?$/i.exec(raw.trim());
176
+ if (!m) return undefined;
177
+ const n = Number(m[1]);
178
+ const unit = (m[2] ?? "ms").toLowerCase();
179
+ if (unit === "ms") return n;
180
+ if (unit === "s") return n * 1000;
181
+ if (unit === "m") return n * 60_000;
182
+ return undefined;
183
+ }
184
+
185
+ function formatValue(dimension: string, value: string | number | boolean): string {
186
+ if (dimension === "duration" || dimension === "duration_ms") {
187
+ const ms = typeof value === "number" ? value : Number(value);
188
+ if (!Number.isFinite(ms)) return String(value);
189
+ if (ms >= 60_000 && ms % 60_000 === 0) return `${ms / 60_000}m`;
190
+ if (ms >= 1000 && ms % 1000 === 0) return `${ms / 1000}s`;
191
+ return `${ms}ms`;
192
+ }
193
+ if (typeof value === "string" && /\s/.test(value)) return `"${value}"`;
194
+ return String(value);
195
+ }
196
+
197
+ function matchClause(run: RunRecord, clause: QueryClause): boolean {
198
+ const left = dimensionValue(run, clause.dimension);
199
+ if (left === undefined || left === null) {
200
+ return clause.op === "!=";
201
+ }
202
+ const right = clause.value;
203
+ if (clause.op === "=") return compareEq(left, right);
204
+ if (clause.op === "!=") return !compareEq(left, right);
205
+ const ln = toNumber(left);
206
+ const rn = toNumber(right);
207
+ if (ln === undefined || rn === undefined) return false;
208
+ if (clause.op === ">") return ln > rn;
209
+ if (clause.op === "<") return ln < rn;
210
+ if (clause.op === ">=") return ln >= rn;
211
+ if (clause.op === "<=") return ln <= rn;
212
+ return false;
213
+ }
214
+
215
+ /**
216
+ * Resolve a dimension from top-level fields or `dimensions`.
217
+ *
218
+ * @param run - Run record
219
+ * @param name - Dimension name
220
+ */
221
+ export function dimensionValue(
222
+ run: RunRecord,
223
+ name: string,
224
+ ): string | number | boolean | null | undefined {
225
+ switch (name) {
226
+ case "flow":
227
+ return run.flow;
228
+ case "unit":
229
+ return run.unit ?? null;
230
+ case "trigger":
231
+ return run.trigger;
232
+ case "plane":
233
+ return run.plane;
234
+ case "tenant":
235
+ return run.tenant ?? null;
236
+ case "principal":
237
+ return run.principal ?? null;
238
+ case "cache":
239
+ return run.cache;
240
+ case "replica":
241
+ return run.replica ?? null;
242
+ case "replicaLagMs":
243
+ case "replica_lag_ms":
244
+ return run.replicaLagMs ?? null;
245
+ case "error":
246
+ case "error_code":
247
+ return run.error ?? null;
248
+ case "buildVersion":
249
+ case "build_version":
250
+ return run.buildVersion ?? null;
251
+ case "promptVersion":
252
+ case "prompt_version":
253
+ return run.promptVersion ?? null;
254
+ case "cost":
255
+ return run.cost ?? null;
256
+ case "duration":
257
+ case "duration_ms":
258
+ return run.durationMs;
259
+ case "gates":
260
+ return run.gates.join(",");
261
+ default:
262
+ return run.dimensions[name];
263
+ }
264
+ }
265
+
266
+ function compareEq(
267
+ left: string | number | boolean,
268
+ right: string | number | boolean,
269
+ ): boolean {
270
+ if (typeof left === "number" || typeof right === "number") {
271
+ const ln = toNumber(left);
272
+ const rn = toNumber(right);
273
+ if (ln !== undefined && rn !== undefined) return ln === rn;
274
+ }
275
+ return String(left) === String(right);
276
+ }
277
+
278
+ function toNumber(v: string | number | boolean): number | undefined {
279
+ if (typeof v === "number" && Number.isFinite(v)) return v;
280
+ if (typeof v === "boolean") return undefined;
281
+ const n = Number(v);
282
+ return Number.isFinite(n) ? n : undefined;
283
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Runs URL search state tests (console §9.11).
3
+ */
4
+
5
+ import { describe, expect, test } from "bun:test";
6
+ import {
7
+ dimensionQueryOf,
8
+ durationRangeOf,
9
+ parseRunsSearch,
10
+ serializeRunsSearch,
11
+ setDurationRange,
12
+ setWhere,
13
+ } from "./search.ts";
14
+ import { parseDimensionQuery } from "./query.ts";
15
+
16
+ describe("runs search", () => {
17
+ test("round-trips where + group + brush + run", () => {
18
+ const search = parseRunsSearch({
19
+ where: "cache = miss AND duration > 1s",
20
+ group: "tenant",
21
+ run: "run_1",
22
+ durMin: "1000",
23
+ durMax: "5000",
24
+ });
25
+ expect(dimensionQueryOf(search).clauses).toHaveLength(2);
26
+ expect(durationRangeOf(search)).toEqual({ minMs: 1000, maxMs: 5000 });
27
+ expect(serializeRunsSearch(search)).toEqual({
28
+ where: "cache = miss AND duration > 1s",
29
+ group: "tenant",
30
+ run: "run_1",
31
+ durMin: 1000,
32
+ durMax: 5000,
33
+ });
34
+ });
35
+
36
+ test("setWhere / setDurationRange helpers", () => {
37
+ let s = parseRunsSearch({});
38
+ s = setWhere(s, parseDimensionQuery("flow = book"));
39
+ s = setDurationRange(s, { minMs: 10, maxMs: 20 });
40
+ expect(s.where).toBe("flow = book");
41
+ expect(s.durMin).toBe(10);
42
+ s = setDurationRange(s, null);
43
+ expect(s.durMin).toBeUndefined();
44
+ });
45
+ });
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Typed search params for the Runs panel (console §7 · §9.11).
3
+ *
4
+ * Population query, group-by, duration brush, and open run all live in the URL.
5
+ */
6
+
7
+ import { z } from "zod";
8
+ import {
9
+ parseDimensionQuery,
10
+ serializeDimensionQuery,
11
+ } from "./query.ts";
12
+ import type { DimensionQuery, DurationRange } from "./types.ts";
13
+
14
+ /** Zod schema for Runs URL search params. */
15
+ export const RunsSearchSchema = z.object({
16
+ /** Dimension query expression (`flow = X AND cache = miss`). */
17
+ where: z.string().optional(),
18
+ /** Group-by dimension. */
19
+ group: z.string().optional(),
20
+ /** Open run id for the flat detail record. */
21
+ run: z.string().optional(),
22
+ /** Duration brush lower bound (ms). */
23
+ durMin: z.coerce.number().optional(),
24
+ /** Duration brush upper bound (ms). */
25
+ durMax: z.coerce.number().optional(),
26
+ });
27
+
28
+ /** Parsed, typed Runs search state. */
29
+ export type RunsSearch = z.infer<typeof RunsSearchSchema>;
30
+
31
+ /**
32
+ * Parse unknown search params into a typed {@link RunsSearch}.
33
+ *
34
+ * @param raw - Router search object
35
+ */
36
+ export function parseRunsSearch(raw: unknown): RunsSearch {
37
+ const result = RunsSearchSchema.safeParse(raw ?? {});
38
+ if (result.success) return result.data;
39
+ return RunsSearchSchema.parse({});
40
+ }
41
+
42
+ /**
43
+ * Serialise typed search into a plain object for TanStack Router.
44
+ *
45
+ * @param search - Typed search
46
+ */
47
+ export function serializeRunsSearch(
48
+ search: RunsSearch,
49
+ ): Record<string, string | number> {
50
+ const out: Record<string, string | number> = {};
51
+ if (search.where) out.where = search.where;
52
+ if (search.group) out.group = search.group;
53
+ if (search.run) out.run = search.run;
54
+ if (search.durMin !== undefined) out.durMin = search.durMin;
55
+ if (search.durMax !== undefined) out.durMax = search.durMax;
56
+ return out;
57
+ }
58
+
59
+ /**
60
+ * Dimension query derived from search.
61
+ *
62
+ * @param search - Typed search
63
+ */
64
+ export function dimensionQueryOf(search: RunsSearch): DimensionQuery {
65
+ return parseDimensionQuery(search.where);
66
+ }
67
+
68
+ /**
69
+ * Duration range when both bounds are present.
70
+ *
71
+ * @param search - Typed search
72
+ */
73
+ export function durationRangeOf(search: RunsSearch): DurationRange | null {
74
+ if (search.durMin === undefined || search.durMax === undefined) return null;
75
+ return {
76
+ minMs: Math.min(search.durMin, search.durMax),
77
+ maxMs: Math.max(search.durMin, search.durMax),
78
+ };
79
+ }
80
+
81
+ /**
82
+ * Set the dimension query expression from a parsed query.
83
+ *
84
+ * @param prev - Current search
85
+ * @param query - Dimension query
86
+ */
87
+ export function setWhere(
88
+ prev: RunsSearch,
89
+ query: DimensionQuery,
90
+ ): RunsSearch {
91
+ const where = serializeDimensionQuery(query);
92
+ return { ...prev, where: where || undefined };
93
+ }
94
+
95
+ /**
96
+ * Set or clear the group-by dimension.
97
+ *
98
+ * @param prev - Current search
99
+ * @param dimension - Dimension or null to clear
100
+ */
101
+ export function setGroup(
102
+ prev: RunsSearch,
103
+ dimension: string | null,
104
+ ): RunsSearch {
105
+ return { ...prev, group: dimension ?? undefined };
106
+ }
107
+
108
+ /**
109
+ * Open a run's flat detail record.
110
+ *
111
+ * @param prev - Current search
112
+ * @param runId - Run id
113
+ */
114
+ export function openRun(prev: RunsSearch, runId: string): RunsSearch {
115
+ return { ...prev, run: runId };
116
+ }
117
+
118
+ /**
119
+ * Close the detail view; stay on the Runs panel.
120
+ *
121
+ * @param prev - Current search
122
+ */
123
+ export function closeRun(prev: RunsSearch): RunsSearch {
124
+ return { ...prev, run: undefined };
125
+ }
126
+
127
+ /**
128
+ * Set the duration brush (outlier population), or clear with null.
129
+ *
130
+ * @param prev - Current search
131
+ * @param range - Selected range
132
+ */
133
+ export function setDurationRange(
134
+ prev: RunsSearch,
135
+ range: DurationRange | null,
136
+ ): RunsSearch {
137
+ if (!range) {
138
+ return { ...prev, durMin: undefined, durMax: undefined };
139
+ }
140
+ return { ...prev, durMin: range.minMs, durMax: range.maxMs };
141
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Runs ↔ Traces cross-link tests (console §9.11).
3
+ */
4
+
5
+ import { describe, expect, test } from "bun:test";
6
+ import { RUNS_CHAIN_FIXTURE } from "./fixture.ts";
7
+ import {
8
+ rootIdOf,
9
+ runsHrefForSpan,
10
+ shouldOfferTracesLink,
11
+ spanCountInTrace,
12
+ tracesHrefForRun,
13
+ } from "./trace-link.ts";
14
+
15
+ describe("trace cross-link", () => {
16
+ test("multi-span chain offers Traces link", () => {
17
+ expect(rootIdOf(RUNS_CHAIN_FIXTURE, "run-fulfill")).toBe("run-create-ok");
18
+ expect(spanCountInTrace(RUNS_CHAIN_FIXTURE, "run-create-ok")).toBe(2);
19
+ expect(shouldOfferTracesLink(RUNS_CHAIN_FIXTURE, "run-fulfill")).toBe(
20
+ true,
21
+ );
22
+ expect(shouldOfferTracesLink(RUNS_CHAIN_FIXTURE, "run-create-fail")).toBe(
23
+ false,
24
+ );
25
+ expect(tracesHrefForRun(RUNS_CHAIN_FIXTURE, "run-fulfill")).toBe(
26
+ "/traces?trace=run-create-ok&span=run-fulfill",
27
+ );
28
+ expect(runsHrefForSpan("run-create-ok")).toBe("/runs?run=run-create-ok");
29
+ });
30
+ });
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Cross-links between Runs (population) and Traces (causal chain).
3
+ */
4
+
5
+ import type { RunRecord } from "./types.ts";
6
+
7
+ /**
8
+ * Walk parentId links to the root of a run's causal chain.
9
+ *
10
+ * @param runs - Population (must include ancestors)
11
+ * @param runId - Starting run id
12
+ */
13
+ export function rootIdOf(
14
+ runs: readonly RunRecord[],
15
+ runId: string,
16
+ ): string {
17
+ const byId = new Map(runs.map((r) => [r.id, r]));
18
+ let cursor = byId.get(runId);
19
+ if (!cursor) return runId;
20
+ const seen = new Set<string>();
21
+ while (cursor.parentId && byId.has(cursor.parentId)) {
22
+ if (seen.has(cursor.id)) break;
23
+ seen.add(cursor.id);
24
+ cursor = byId.get(cursor.parentId)!;
25
+ }
26
+ return cursor.id;
27
+ }
28
+
29
+ /**
30
+ * Count spans in the connected component rooted at {@link rootId}.
31
+ *
32
+ * @param runs - Population
33
+ * @param rootId - Trace root id
34
+ */
35
+ export function spanCountInTrace(
36
+ runs: readonly RunRecord[],
37
+ rootId: string,
38
+ ): number {
39
+ const byId = new Map(runs.map((r) => [r.id, r]));
40
+ if (!byId.has(rootId)) return 0;
41
+ const childrenOf = new Map<string, string[]>();
42
+ for (const r of runs) {
43
+ if (!r.parentId || !byId.has(r.parentId)) continue;
44
+ const list = childrenOf.get(r.parentId) ?? [];
45
+ list.push(r.id);
46
+ childrenOf.set(r.parentId, list);
47
+ }
48
+ let count = 0;
49
+ const stack = [rootId];
50
+ const seen = new Set<string>();
51
+ while (stack.length > 0) {
52
+ const id = stack.pop()!;
53
+ if (seen.has(id)) continue;
54
+ seen.add(id);
55
+ count += 1;
56
+ for (const child of childrenOf.get(id) ?? []) stack.push(child);
57
+ }
58
+ return count;
59
+ }
60
+
61
+ /**
62
+ * Whether opening this run should offer "Open in Traces"
63
+ * (trace has more than one span).
64
+ *
65
+ * @param runs - Population
66
+ * @param runId - Selected run
67
+ */
68
+ export function shouldOfferTracesLink(
69
+ runs: readonly RunRecord[],
70
+ runId: string,
71
+ ): boolean {
72
+ const root = rootIdOf(runs, runId);
73
+ return spanCountInTrace(runs, root) > 1;
74
+ }
75
+
76
+ /**
77
+ * Build the Traces panel href for a run.
78
+ *
79
+ * @param runs - Population
80
+ * @param runId - Selected run (becomes focus span)
81
+ */
82
+ export function tracesHrefForRun(
83
+ runs: readonly RunRecord[],
84
+ runId: string,
85
+ ): string {
86
+ const root = rootIdOf(runs, runId);
87
+ const params = new URLSearchParams({ trace: root, span: runId });
88
+ return `/traces?${params.toString()}`;
89
+ }
90
+
91
+ /**
92
+ * Build the Runs panel href for a span.
93
+ *
94
+ * @param runId - Span / run id
95
+ */
96
+ export function runsHrefForSpan(runId: string): string {
97
+ const params = new URLSearchParams({ run: runId });
98
+ return `/runs?${params.toString()}`;
99
+ }