@voltro/cli 0.28.0 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (354) hide show
  1. package/CHANGELOG.md +655 -0
  2. package/THIRD-PARTY-NOTICES.md +90 -4
  3. package/dist/{apiBuild-eUM32r1u.js → apiBuild-BceikpQf.js} +3 -3
  4. package/dist/apiBuild-CxvR1Dwt.js +2 -0
  5. package/dist/bin.js +3 -3
  6. package/dist/checkCommand-BMr-X48w.js +2427 -0
  7. package/dist/checkCommand-BOk9y264.js +2 -0
  8. package/dist/cliRuntime-Oh517vCV.js +96 -0
  9. package/dist/{commands-CSkrUI1h.js → commands-D4Y1-Nlu.js} +8575 -9366
  10. package/dist/{dbCommand-CpYgmSw4.js → dbCommand-C7hbl5pk.js} +345 -266
  11. package/dist/dbCommand-D8nhyppR.js +2 -0
  12. package/dist/{dev-DlBWWnJQ.js → dev-Cr-teYsz.js} +1 -1
  13. package/dist/{dev-CEZwJhmb.js → dev-DmnkH-wr.js} +2939 -1832
  14. package/dist/fileConventions-Cof68_BL.js +33 -0
  15. package/dist/{frameworkTableAssembly-BwHU9Euq.js → frameworkTableAssembly-BzAajuUv.js} +115 -99
  16. package/dist/frameworkTableAssembly-DU0aOxjL.js +2 -0
  17. package/dist/index.d.ts +7 -2
  18. package/dist/index.js +1 -1
  19. package/dist/{inspect-CUCCzw2I.js → inspect-BUUjt773.js} +349 -192
  20. package/dist/inspect-mmBuRXmy.js +2 -0
  21. package/dist/{inspectMetrics-BU90mvJN.js → inspectMetrics-BeJdP_3b.js} +1068 -978
  22. package/dist/{manifestBuild-BnzAxp2O.js → manifestBuild-BLrVuSlM.js} +1 -1
  23. package/dist/manifestBuild-Dj8Jjoto.js +2 -0
  24. package/dist/sdkgen-CqpOq_fy.js +582 -0
  25. package/dist/serveCommand-Ciq_wIY8.js +1577 -0
  26. package/dist/serveEntry.js +2 -2
  27. package/dist/{start-BGXIf6zT.js → start-ocqB1seX.js} +283 -270
  28. package/dist/startEntry.js +2 -2
  29. package/package.json +17 -17
  30. package/templates/AGENTS.core.md +50 -0
  31. package/templates/AGENTS.md +54 -2
  32. package/templates/agent-docs/_index.md +4 -2
  33. package/templates/agent-docs/_manifest.json +26 -5
  34. package/templates/agent-docs/ai.md +191 -0
  35. package/templates/agent-docs/cli.md +143 -6
  36. package/templates/agent-docs/configuration.md +32 -0
  37. package/templates/agent-docs/data.md +282 -0
  38. package/templates/agent-docs/database/migrations.md +47 -0
  39. package/templates/agent-docs/database/misc.md +57 -0
  40. package/templates/agent-docs/database/schema.md +3 -1
  41. package/templates/agent-docs/internationalization.md +169 -8
  42. package/templates/agent-docs/local-first-mobile.md +426 -0
  43. package/templates/agent-docs/routing.md +94 -3
  44. package/templates/agent-docs/schema-driven-ui.md +12 -0
  45. package/templates/agent-docs/security.md +17 -0
  46. package/templates/agent-docs/templates/apibackends.md +210 -1
  47. package/templates/agent-docs/templates/appshells.md +144 -1
  48. package/templates/agent-docs/templates/mobile.md +60 -0
  49. package/templates/agent-docs/templates/overview.md +17 -7
  50. package/templates/agent-docs/whats-new.md +238 -158
  51. package/templates/agent-docs/workflows.md +376 -0
  52. package/templates/apps/api-ai/package.json +7 -7
  53. package/templates/apps/api-auth/package.json +8 -8
  54. package/templates/apps/api-backend/package.json +7 -7
  55. package/templates/apps/api-backend-deactivation/package.json +7 -7
  56. package/templates/apps/api-backend-mail/package.json +8 -8
  57. package/templates/apps/api-backend-mariadb/package.json +9 -9
  58. package/templates/apps/api-backend-sqlite/.env.example +19 -0
  59. package/templates/apps/api-backend-sqlite/README.md +38 -0
  60. package/templates/apps/api-backend-sqlite/app.config.ts +35 -0
  61. package/templates/apps/api-backend-sqlite/database/schema.ts +54 -0
  62. package/templates/apps/api-backend-sqlite/mutations/notes.create.mutation.server.ts +19 -0
  63. package/templates/apps/api-backend-sqlite/mutations/notes.create.mutation.ts +37 -0
  64. package/templates/apps/api-backend-sqlite/package.json +30 -0
  65. package/templates/apps/api-backend-sqlite/queries/notes.query.server.ts +14 -0
  66. package/templates/apps/api-backend-sqlite/queries/notes.query.ts +20 -0
  67. package/templates/apps/api-backend-sqlite/template.json +6 -0
  68. package/templates/apps/api-backend-sqlite/tests/notes.create.test.ts +50 -0
  69. package/templates/apps/api-backend-sqlite/tsconfig.json +5 -0
  70. package/templates/apps/api-backend-storage/package.json +8 -8
  71. package/templates/apps/api-cms/README.md +104 -0
  72. package/templates/apps/api-cms/actions/content.get.action.server.ts +27 -0
  73. package/templates/apps/api-cms/actions/content.get.action.ts +19 -0
  74. package/templates/apps/api-cms/actions/content.types.action.server.ts +26 -0
  75. package/templates/apps/api-cms/actions/content.types.action.ts +40 -0
  76. package/templates/apps/api-cms/actions/me.action.server.ts +18 -0
  77. package/templates/apps/api-cms/actions/me.action.ts +16 -0
  78. package/templates/apps/api-cms/app.config.ts +61 -0
  79. package/templates/apps/api-cms/content/blogPost.contentType.ts +39 -0
  80. package/templates/apps/api-cms/content/index.ts +18 -0
  81. package/templates/apps/api-cms/content/page.contentType.ts +24 -0
  82. package/templates/apps/api-cms/database/schema.ts +64 -0
  83. package/templates/apps/api-cms/mutations/content.publish.mutation.server.ts +19 -0
  84. package/templates/apps/api-cms/mutations/content.publish.mutation.ts +15 -0
  85. package/templates/apps/api-cms/mutations/content.saveDraft.mutation.server.ts +36 -0
  86. package/templates/apps/api-cms/mutations/content.saveDraft.mutation.ts +32 -0
  87. package/templates/apps/api-cms/mutations/content.unpublish.mutation.server.ts +19 -0
  88. package/templates/apps/api-cms/mutations/content.unpublish.mutation.ts +11 -0
  89. package/templates/apps/api-cms/package.json +32 -0
  90. package/templates/apps/api-cms/queries/content.list.query.server.ts +0 -0
  91. package/templates/apps/api-cms/queries/content.list.query.ts +27 -0
  92. package/templates/apps/api-cms/template.json +6 -0
  93. package/templates/apps/api-cms/tests/content.descriptors.test.ts +64 -0
  94. package/templates/apps/api-cms/tests/content.write.test.ts +85 -0
  95. package/templates/apps/api-cms/tsconfig.json +5 -0
  96. package/templates/apps/api-collab/README.md +70 -0
  97. package/templates/apps/api-collab/app.config.ts +28 -0
  98. package/templates/apps/api-collab/database/schema.ts +63 -0
  99. package/templates/apps/api-collab/mutations/documents.create.mutation.server.ts +19 -0
  100. package/templates/apps/api-collab/mutations/documents.create.mutation.ts +36 -0
  101. package/templates/apps/api-collab/mutations/documents.setBody.mutation.server.ts +20 -0
  102. package/templates/apps/api-collab/mutations/documents.setBody.mutation.ts +30 -0
  103. package/templates/apps/api-collab/package.json +30 -0
  104. package/templates/apps/api-collab/queries/documents.query.server.ts +16 -0
  105. package/templates/apps/api-collab/queries/documents.query.ts +23 -0
  106. package/templates/apps/api-collab/template.json +6 -0
  107. package/templates/apps/api-collab/tests/documents.setBody.test.ts +89 -0
  108. package/templates/apps/api-collab/tsconfig.json +5 -0
  109. package/templates/apps/api-data-advanced/package.json +8 -8
  110. package/templates/apps/api-durable/package.json +8 -8
  111. package/templates/apps/api-feature-flags/package.json +9 -9
  112. package/templates/apps/api-governance/package.json +8 -8
  113. package/templates/apps/api-kv/package.json +8 -8
  114. package/templates/apps/api-moderation/package.json +8 -8
  115. package/templates/apps/api-observability/package.json +8 -8
  116. package/templates/apps/api-ratelimit/package.json +8 -8
  117. package/templates/apps/api-rbac/package.json +8 -8
  118. package/templates/apps/api-rest/package.json +7 -7
  119. package/templates/apps/api-saas/package.json +11 -11
  120. package/templates/apps/api-saas-starter/README.md +103 -0
  121. package/templates/apps/api-saas-starter/actions/me.action.server.ts +18 -0
  122. package/templates/apps/api-saas-starter/actions/me.action.ts +20 -0
  123. package/templates/apps/api-saas-starter/app.config.ts +87 -0
  124. package/templates/apps/api-saas-starter/database/schema.ts +57 -0
  125. package/templates/apps/api-saas-starter/mutations/invites.create.mutation.server.ts +26 -0
  126. package/templates/apps/api-saas-starter/mutations/invites.create.mutation.ts +18 -0
  127. package/templates/apps/api-saas-starter/mutations/projects.create.mutation.server.ts +29 -0
  128. package/templates/apps/api-saas-starter/mutations/projects.create.mutation.ts +18 -0
  129. package/templates/apps/api-saas-starter/package.json +32 -0
  130. package/templates/apps/api-saas-starter/queries/invites.list.query.server.ts +14 -0
  131. package/templates/apps/api-saas-starter/queries/invites.list.query.ts +17 -0
  132. package/templates/apps/api-saas-starter/queries/projects.list.query.server.ts +14 -0
  133. package/templates/apps/api-saas-starter/queries/projects.list.query.ts +18 -0
  134. package/templates/apps/api-saas-starter/template.json +6 -0
  135. package/templates/apps/api-saas-starter/tests/projects.create.test.ts +62 -0
  136. package/templates/apps/api-saas-starter/tests/session.test.ts +33 -0
  137. package/templates/apps/api-saas-starter/tsconfig.json +5 -0
  138. package/templates/apps/api-search/package.json +8 -8
  139. package/templates/apps/api-status/README.md +88 -0
  140. package/templates/apps/api-status/app.config.ts +36 -0
  141. package/templates/apps/api-status/authz.ts +33 -0
  142. package/templates/apps/api-status/database/schema.ts +70 -0
  143. package/templates/apps/api-status/mutations/components.create.mutation.server.ts +19 -0
  144. package/templates/apps/api-status/mutations/components.create.mutation.ts +16 -0
  145. package/templates/apps/api-status/mutations/incidents.create.mutation.server.ts +25 -0
  146. package/templates/apps/api-status/mutations/incidents.create.mutation.ts +22 -0
  147. package/templates/apps/api-status/mutations/incidents.resolve.mutation.server.ts +24 -0
  148. package/templates/apps/api-status/mutations/incidents.resolve.mutation.ts +19 -0
  149. package/templates/apps/api-status/mutations/incidents.update.mutation.server.ts +26 -0
  150. package/templates/apps/api-status/mutations/incidents.update.mutation.ts +21 -0
  151. package/templates/apps/api-status/package.json +30 -0
  152. package/templates/apps/api-status/queries/components.list.query.server.ts +14 -0
  153. package/templates/apps/api-status/queries/components.list.query.ts +13 -0
  154. package/templates/apps/api-status/queries/incidents.live.query.server.ts +14 -0
  155. package/templates/apps/api-status/queries/incidents.live.query.ts +20 -0
  156. package/templates/apps/api-status/queries/updates.list.query.server.ts +14 -0
  157. package/templates/apps/api-status/queries/updates.list.query.ts +17 -0
  158. package/templates/apps/api-status/template.json +6 -0
  159. package/templates/apps/api-status/tests/status.test.ts +70 -0
  160. package/templates/apps/api-status/tsconfig.json +5 -0
  161. package/templates/apps/api-versioning/package.json +8 -8
  162. package/templates/apps/api-webhooks/package.json +9 -9
  163. package/templates/apps/changelog/package.json +6 -6
  164. package/templates/apps/edge-functions/package.json +2 -2
  165. package/templates/apps/frontend-admin/app.config.ts +1 -1
  166. package/templates/apps/frontend-admin/package.json +8 -8
  167. package/templates/apps/frontend-admin/src/locales/index.ts +1 -1
  168. package/templates/apps/frontend-app/app.config.ts +1 -1
  169. package/templates/apps/frontend-app/package.json +8 -8
  170. package/templates/apps/frontend-app/src/locales/index.ts +1 -1
  171. package/templates/apps/frontend-app/src/pages/layout.tsx +1 -1
  172. package/templates/apps/frontend-app/src/pages/page.tsx +1 -1
  173. package/templates/apps/frontend-auth/README.md +78 -0
  174. package/templates/apps/frontend-auth/app.config.ts +34 -0
  175. package/templates/apps/frontend-auth/package.json +32 -0
  176. package/templates/apps/frontend-auth/src/components/AuthShell.tsx +35 -0
  177. package/templates/apps/frontend-auth/src/components/PasswordStrength.tsx +33 -0
  178. package/templates/apps/frontend-auth/src/config.ts +11 -0
  179. package/templates/apps/frontend-auth/src/globals.css +105 -0
  180. package/templates/apps/frontend-auth/src/globals.d.ts +6 -0
  181. package/templates/apps/frontend-auth/src/lib/auth.ts +34 -0
  182. package/templates/apps/frontend-auth/src/lib/redirect.test.ts +24 -0
  183. package/templates/apps/frontend-auth/src/lib/redirect.ts +29 -0
  184. package/templates/apps/frontend-auth/src/locales/de.ts +66 -0
  185. package/templates/apps/frontend-auth/src/locales/en.ts +76 -0
  186. package/templates/apps/frontend-auth/src/locales/index.ts +14 -0
  187. package/templates/apps/frontend-auth/src/pages/forgot/page.tsx +51 -0
  188. package/templates/apps/frontend-auth/src/pages/layout.tsx +12 -0
  189. package/templates/apps/frontend-auth/src/pages/login/page.test.tsx +53 -0
  190. package/templates/apps/frontend-auth/src/pages/login/page.tsx +67 -0
  191. package/templates/apps/frontend-auth/src/pages/logout/page.tsx +28 -0
  192. package/templates/apps/frontend-auth/src/pages/magic/page.tsx +51 -0
  193. package/templates/apps/frontend-auth/src/pages/page.tsx +26 -0
  194. package/templates/apps/frontend-auth/src/pages/reset/page.test.tsx +51 -0
  195. package/templates/apps/frontend-auth/src/pages/reset/page.tsx +63 -0
  196. package/templates/apps/frontend-auth/src/pages/signup/page.tsx +60 -0
  197. package/templates/apps/frontend-auth/src/pages/verify/page.tsx +50 -0
  198. package/templates/apps/frontend-auth/template.json +6 -0
  199. package/templates/apps/frontend-auth/tsconfig.json +5 -0
  200. package/templates/apps/frontend-blank/app.config.ts +1 -1
  201. package/templates/apps/frontend-blank/package.json +7 -7
  202. package/templates/apps/frontend-blank/src/locales/index.ts +1 -1
  203. package/templates/apps/frontend-blank/src/pages/layout.tsx +1 -1
  204. package/templates/apps/frontend-blank/src/pages/page.tsx +1 -1
  205. package/templates/apps/frontend-cms/README.md +47 -0
  206. package/templates/apps/frontend-cms/app.config.ts +37 -0
  207. package/templates/apps/frontend-cms/package.json +33 -0
  208. package/templates/apps/frontend-cms/src/config.ts +8 -0
  209. package/templates/apps/frontend-cms/src/globals.css +105 -0
  210. package/templates/apps/frontend-cms/src/globals.d.ts +6 -0
  211. package/templates/apps/frontend-cms/src/lib/api.ts +58 -0
  212. package/templates/apps/frontend-cms/src/locales/de.ts +50 -0
  213. package/templates/apps/frontend-cms/src/locales/en.ts +55 -0
  214. package/templates/apps/frontend-cms/src/locales/index.ts +14 -0
  215. package/templates/apps/frontend-cms/src/pages/(app)/error.tsx +18 -0
  216. package/templates/apps/frontend-cms/src/pages/(app)/layout.test.tsx +31 -0
  217. package/templates/apps/frontend-cms/src/pages/(app)/layout.tsx +62 -0
  218. package/templates/apps/frontend-cms/src/pages/(app)/not-found.tsx +14 -0
  219. package/templates/apps/frontend-cms/src/pages/(app)/page.test.tsx +110 -0
  220. package/templates/apps/frontend-cms/src/pages/(app)/page.tsx +159 -0
  221. package/templates/apps/frontend-cms/src/pages/layout.tsx +12 -0
  222. package/templates/apps/frontend-cms/src/pages/login/page.test.tsx +58 -0
  223. package/templates/apps/frontend-cms/src/pages/login/page.tsx +93 -0
  224. package/templates/apps/frontend-cms/template.json +6 -0
  225. package/templates/apps/frontend-cms/tsconfig.json +5 -0
  226. package/templates/apps/frontend-collab/README.md +80 -0
  227. package/templates/apps/frontend-collab/app.config.ts +38 -0
  228. package/templates/apps/frontend-collab/package.json +33 -0
  229. package/templates/apps/frontend-collab/src/locales/de.ts +29 -0
  230. package/templates/apps/frontend-collab/src/locales/en.ts +31 -0
  231. package/templates/apps/frontend-collab/src/locales/index.ts +15 -0
  232. package/templates/apps/frontend-collab/src/pages/layout.tsx +39 -0
  233. package/templates/apps/frontend-collab/src/pages/page.test.tsx +150 -0
  234. package/templates/apps/frontend-collab/src/pages/page.tsx +186 -0
  235. package/templates/apps/frontend-collab/template.json +6 -0
  236. package/templates/apps/frontend-collab/tsconfig.json +11 -0
  237. package/templates/apps/frontend-contact/package.json +7 -7
  238. package/templates/apps/frontend-dashboard/app.config.ts +1 -1
  239. package/templates/apps/frontend-dashboard/package.json +7 -7
  240. package/templates/apps/frontend-dashboard/src/locales/index.ts +1 -1
  241. package/templates/apps/frontend-docs/package.json +7 -7
  242. package/templates/apps/frontend-i18n/package.json +6 -6
  243. package/templates/apps/frontend-landing/package.json +7 -7
  244. package/templates/apps/frontend-portal/README.md +71 -0
  245. package/templates/apps/frontend-portal/app.config.ts +37 -0
  246. package/templates/apps/frontend-portal/package.json +32 -0
  247. package/templates/apps/frontend-portal/src/config.ts +8 -0
  248. package/templates/apps/frontend-portal/src/globals.css +93 -0
  249. package/templates/apps/frontend-portal/src/globals.d.ts +6 -0
  250. package/templates/apps/frontend-portal/src/lib/api.ts +62 -0
  251. package/templates/apps/frontend-portal/src/locales/de.ts +86 -0
  252. package/templates/apps/frontend-portal/src/locales/en.ts +93 -0
  253. package/templates/apps/frontend-portal/src/locales/index.ts +14 -0
  254. package/templates/apps/frontend-portal/src/pages/(portal)/api-keys/page.test.tsx +71 -0
  255. package/templates/apps/frontend-portal/src/pages/(portal)/api-keys/page.tsx +124 -0
  256. package/templates/apps/frontend-portal/src/pages/(portal)/billing/page.test.tsx +86 -0
  257. package/templates/apps/frontend-portal/src/pages/(portal)/billing/page.tsx +97 -0
  258. package/templates/apps/frontend-portal/src/pages/(portal)/error.tsx +19 -0
  259. package/templates/apps/frontend-portal/src/pages/(portal)/invoices/page.tsx +45 -0
  260. package/templates/apps/frontend-portal/src/pages/(portal)/layout.test.tsx +31 -0
  261. package/templates/apps/frontend-portal/src/pages/(portal)/layout.tsx +63 -0
  262. package/templates/apps/frontend-portal/src/pages/(portal)/not-found.tsx +15 -0
  263. package/templates/apps/frontend-portal/src/pages/(portal)/page.tsx +39 -0
  264. package/templates/apps/frontend-portal/src/pages/(portal)/profile/page.tsx +79 -0
  265. package/templates/apps/frontend-portal/src/pages/layout.tsx +12 -0
  266. package/templates/apps/frontend-portal/src/pages/login/page.test.tsx +58 -0
  267. package/templates/apps/frontend-portal/src/pages/login/page.tsx +96 -0
  268. package/templates/apps/frontend-portal/template.json +6 -0
  269. package/templates/apps/frontend-portal/tsconfig.json +5 -0
  270. package/templates/apps/frontend-saas/README.md +73 -0
  271. package/templates/apps/frontend-saas/app.config.ts +46 -0
  272. package/templates/apps/frontend-saas/package.json +32 -0
  273. package/templates/apps/frontend-saas/src/config.ts +8 -0
  274. package/templates/apps/frontend-saas/src/globals.css +85 -0
  275. package/templates/apps/frontend-saas/src/globals.d.ts +6 -0
  276. package/templates/apps/frontend-saas/src/lib/api.ts +47 -0
  277. package/templates/apps/frontend-saas/src/locales/de.ts +72 -0
  278. package/templates/apps/frontend-saas/src/locales/en.ts +81 -0
  279. package/templates/apps/frontend-saas/src/locales/index.ts +14 -0
  280. package/templates/apps/frontend-saas/src/pages/(marketing)/layout.tsx +30 -0
  281. package/templates/apps/frontend-saas/src/pages/(marketing)/login/page.test.tsx +58 -0
  282. package/templates/apps/frontend-saas/src/pages/(marketing)/login/page.tsx +96 -0
  283. package/templates/apps/frontend-saas/src/pages/(marketing)/page.tsx +27 -0
  284. package/templates/apps/frontend-saas/src/pages/dashboard/billing/page.tsx +72 -0
  285. package/templates/apps/frontend-saas/src/pages/dashboard/error.tsx +20 -0
  286. package/templates/apps/frontend-saas/src/pages/dashboard/layout.test.tsx +32 -0
  287. package/templates/apps/frontend-saas/src/pages/dashboard/layout.tsx +69 -0
  288. package/templates/apps/frontend-saas/src/pages/dashboard/not-found.tsx +17 -0
  289. package/templates/apps/frontend-saas/src/pages/dashboard/page.test.tsx +113 -0
  290. package/templates/apps/frontend-saas/src/pages/dashboard/page.tsx +76 -0
  291. package/templates/apps/frontend-saas/src/pages/dashboard/team/page.tsx +73 -0
  292. package/templates/apps/frontend-saas/src/pages/layout.tsx +12 -0
  293. package/templates/apps/frontend-saas/template.json +6 -0
  294. package/templates/apps/frontend-saas/tsconfig.json +5 -0
  295. package/templates/apps/frontend-spa/app.config.ts +1 -1
  296. package/templates/apps/frontend-spa/package.json +7 -7
  297. package/templates/apps/frontend-spa/src/locales/index.ts +1 -1
  298. package/templates/apps/frontend-spa/src/pages/layout.tsx +1 -1
  299. package/templates/apps/frontend-spa/src/pages/page.tsx +1 -1
  300. package/templates/apps/frontend-ssr/app.config.ts +1 -1
  301. package/templates/apps/frontend-ssr/package.json +7 -7
  302. package/templates/apps/frontend-ssr/src/locales/index.ts +1 -1
  303. package/templates/apps/frontend-ssr/src/pages/layout.tsx +1 -1
  304. package/templates/apps/frontend-ssr/src/pages/page.tsx +1 -1
  305. package/templates/apps/frontend-ssr-api/app.config.ts +1 -1
  306. package/templates/apps/frontend-ssr-api/package.json +8 -8
  307. package/templates/apps/frontend-ssr-api/src/locales/index.ts +1 -1
  308. package/templates/apps/frontend-ssr-api/src/pages/layout.tsx +1 -1
  309. package/templates/apps/frontend-static-blog/package.json +6 -6
  310. package/templates/apps/frontend-status/README.md +51 -0
  311. package/templates/apps/frontend-status/app.config.ts +39 -0
  312. package/templates/apps/frontend-status/package.json +32 -0
  313. package/templates/apps/frontend-status/src/config.ts +7 -0
  314. package/templates/apps/frontend-status/src/globals.css +70 -0
  315. package/templates/apps/frontend-status/src/globals.d.ts +6 -0
  316. package/templates/apps/frontend-status/src/lib/status.ts +81 -0
  317. package/templates/apps/frontend-status/src/locales/de.ts +41 -0
  318. package/templates/apps/frontend-status/src/locales/en.ts +45 -0
  319. package/templates/apps/frontend-status/src/locales/index.ts +13 -0
  320. package/templates/apps/frontend-status/src/pages/layout.tsx +27 -0
  321. package/templates/apps/frontend-status/src/pages/page.test.tsx +123 -0
  322. package/templates/apps/frontend-status/src/pages/page.tsx +136 -0
  323. package/templates/apps/frontend-status/template.json +6 -0
  324. package/templates/apps/frontend-status/tsconfig.json +11 -0
  325. package/templates/apps/mobile-app/README.md +58 -0
  326. package/templates/apps/mobile-app/app.config.ts +33 -0
  327. package/templates/apps/mobile-app/babel.config.js +5 -0
  328. package/templates/apps/mobile-app/metro.config.js +20 -0
  329. package/templates/apps/mobile-app/package.json +33 -0
  330. package/templates/apps/mobile-app/src/app/_layout.tsx +61 -0
  331. package/templates/apps/mobile-app/src/app/index.tsx +62 -0
  332. package/templates/apps/mobile-app/src/app/orders/[id].tsx +19 -0
  333. package/templates/apps/mobile-app/src/app/settings.tsx +51 -0
  334. package/templates/apps/mobile-app/src/client.ts +74 -0
  335. package/templates/apps/mobile-app/src/lib/deeplinks.ts +39 -0
  336. package/templates/apps/mobile-app/src/lib/notifications.ts +31 -0
  337. package/templates/apps/mobile-app/src/lib/sync.ts +29 -0
  338. package/templates/apps/mobile-app/src/persistence.ts +38 -0
  339. package/templates/apps/mobile-app/template.json +6 -0
  340. package/templates/apps/mobile-app/tests/deeplinks.test.ts +32 -0
  341. package/templates/apps/mobile-app/tests/notifications.test.ts +26 -0
  342. package/templates/apps/mobile-app/tests/sync.test.ts +34 -0
  343. package/templates/apps/mobile-app/tsconfig.json +10 -0
  344. package/templates/apps/mobile-app/voltro.mobile.ts +11 -0
  345. package/templates/baselines/compose/docker-compose.prod.yml +15 -0
  346. package/templates/baselines/compose-mariadb/docker-compose.prod.yml +15 -0
  347. package/templates/patches/@effect__cluster@0.60.0.patch +6 -6
  348. package/dist/apiBuild-DgBS9ayv.js +0 -2
  349. package/dist/dbCommand-DvguqlzF.js +0 -2
  350. package/dist/fileConventions-3bffWssN.js +0 -30
  351. package/dist/frameworkTableAssembly-lrjZtk0G.js +0 -2
  352. package/dist/inspect-gt8bq-Tz.js +0 -2
  353. package/dist/manifestBuild-ifczArzr.js +0 -2
  354. package/dist/serveCommand-ZTn-dPFa.js +0 -1425
@@ -114,13 +114,29 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
114
114
  error: "cross-site write rejected",
115
115
  reason: `a state-changing inspect request may not come from origin "${i}" — only same-machine (loopback) origins may write`
116
116
  }, n);
117
- }, f = (e) => {
117
+ }, f = (e = process.env.VOLTRO_INSPECT_ALLOWED_HOSTS) => (e ?? "").split(/[,\s]+/).map((e) => e.trim().toLowerCase()).filter((e) => e.length > 0), p = (e) => {
118
+ if (e === void 0) return "";
119
+ let t = e.trim();
120
+ if (t === "") return "";
121
+ if (t.startsWith("[")) {
122
+ let e = t.indexOf("]");
123
+ return (e === -1 ? t.slice(1) : t.slice(1, e)).toLowerCase();
124
+ }
125
+ let n = t.indexOf(":");
126
+ return (n === -1 ? t : t.slice(0, n)).toLowerCase();
127
+ }, m = (e) => /^\d{1,3}(?:\.\d{1,3}){3}$/.test(e) || e.includes(":"), h = (e, t = f()) => {
128
+ let n = p(e);
129
+ return n === "" || n === "localhost" || n.endsWith(".localhost") || m(n) ? !0 : t.includes(n);
130
+ }, g = (e, t = {}, n) => h(e, n) ? null : s(403, {
131
+ error: "forbidden host",
132
+ reason: `the dev inspect surface refuses a request with Host "${e ?? ""}" — a DNS-rebinding guard. Only loopback names, IP literals, and hosts listed in VOLTRO_INSPECT_ALLOWED_HOSTS may reach it.`
133
+ }, t), _ = (e) => {
118
134
  let t = e.indexOf("?");
119
135
  return t === -1 ? e : e.slice(0, t);
120
- }, p = (e) => {
136
+ }, v = (e) => {
121
137
  let t = e.indexOf("?");
122
138
  return t === -1 ? new URLSearchParams() : new URLSearchParams(e.slice(t + 1));
123
- }, m = (e) => e === "/_voltro/inspect" || e.startsWith("/_voltro/inspect/"), h = [
139
+ }, y = (e) => e === "/_voltro/inspect" || e.startsWith("/_voltro/inspect/"), b = [
124
140
  "text",
125
141
  "textarea",
126
142
  "number",
@@ -136,7 +152,7 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
136
152
  "file",
137
153
  "hidden",
138
154
  "custom"
139
- ], g = (e, t, n = [], r = []) => ({
155
+ ], x = (e, t, n = [], r = []) => ({
140
156
  version: 2,
141
157
  scopes: [...new Set(r.flatMap((e) => e.declaredScopes ?? []))].sort(),
142
158
  procedures: [...e].sort((e, t) => e.tag.localeCompare(t.tag)).map((e) => ({
@@ -151,7 +167,7 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
151
167
  ...e.exposeAsTool === void 0 ? {} : { exposeAsTool: e.exposeAsTool }
152
168
  })),
153
169
  workflows: [...t].sort((e, t) => e.tag.localeCompare(t.tag)).map((e) => ({ name: e.tag })),
154
- widgets: h,
170
+ widgets: b,
155
171
  tables: [...n].filter((e) => !e.isFrameworkTable).sort((e, t) => e.name.localeCompare(t.name)).map((e) => ({
156
172
  name: e.name,
157
173
  reactive: e.isReactive,
@@ -164,9 +180,9 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
164
180
  ...e.oneOf === void 0 ? {} : { enum: e.oneOf }
165
181
  }))
166
182
  }))
167
- }), _ = (e, t, n = {}, i = {}) => {
168
- let o = f(e);
169
- if (!m(o)) return null;
183
+ }), S = (e, t, n = {}, i = {}) => {
184
+ let o = _(e);
185
+ if (!y(o)) return null;
170
186
  let c = l(n.origin ?? n.Origin), u = (i.method ?? "GET").toUpperCase();
171
187
  if (u === "OPTIONS") return {
172
188
  status: 204,
@@ -196,7 +212,7 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
196
212
  if (o === "/_voltro/inspect/manifest") {
197
213
  if (t.kind !== "api") return s(404, { error: "manifest endpoint is api-only" }, c);
198
214
  let e = t.inspectTables?.().tables ?? [];
199
- return s(200, g(t.rpc, t.workflows, e, t.plugins?.().plugins ?? []), c);
215
+ return s(200, x(t.rpc, t.workflows, e, t.plugins?.().plugins ?? []), c);
200
216
  }
201
217
  return o === "/_voltro/inspect/metrics" ? t.metrics === void 0 ? s(200, [], c) : s(200, t.metrics(), c) : o === "/_voltro/inspect/subscriptions" ? t.kind === "api" ? t.subscriptions === void 0 ? s(200, {
202
218
  subscriptions: [],
@@ -240,7 +256,7 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
240
256
  error: "unknown inspect endpoint",
241
257
  path: o
242
258
  }, c);
243
- }, v = async (e, t, n, i = {}) => {
259
+ }, C = async (e, t, n, i = {}) => {
244
260
  let o = l(t.origin ?? t.Origin);
245
261
  if (r()) return s(503, { error: "inspect disabled (VOLTRO_INSPECT=off)" }, o);
246
262
  let c = (i.method ?? "POST").toUpperCase();
@@ -275,80 +291,80 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
275
291
  n !== "cookie" && (h[n] = t);
276
292
  }
277
293
  return s(200, await p(f.input, h), o);
278
- }, y = async (e, t, i, o, c = {}) => {
279
- let u = f(e);
280
- if (!m(u) || !u.startsWith("/_voltro/inspect/webhooks/")) return null;
281
- let p = l(i.origin ?? i.Origin);
294
+ }, w = async (e, t, i, o, c = {}) => {
295
+ let u = _(e);
296
+ if (!y(u) || !u.startsWith("/_voltro/inspect/webhooks/")) return null;
297
+ let f = l(i.origin ?? i.Origin);
282
298
  if ((c.method ?? "POST").toUpperCase() !== "POST") return null;
283
- if (r()) return s(503, { error: "inspect disabled (VOLTRO_INSPECT=off)" }, p);
284
- let h = (c.authResolver ?? a)(i, c.method ?? "POST");
285
- if (!h.ok) return s(401, {
299
+ if (r()) return s(503, { error: "inspect disabled (VOLTRO_INSPECT=off)" }, f);
300
+ let p = (c.authResolver ?? a)(i, c.method ?? "POST");
301
+ if (!p.ok) return s(401, {
286
302
  error: "unauthorized",
287
- reason: h.reason
288
- }, p);
289
- let g = d(c.method, i, p);
290
- if (g) return g;
291
- if (t.kind !== "api") return s(404, { error: "webhook actions are api-only" }, p);
292
- if (!t.webhookActions) return s(404, { error: "webhook actions not configured — is @voltro/plugin-webhooks active?" }, p);
293
- let _;
303
+ reason: p.reason
304
+ }, f);
305
+ let m = d(c.method, i, f);
306
+ if (m) return m;
307
+ if (t.kind !== "api") return s(404, { error: "webhook actions are api-only" }, f);
308
+ if (!t.webhookActions) return s(404, { error: "webhook actions not configured — is @voltro/plugin-webhooks active?" }, f);
309
+ let h;
294
310
  try {
295
- _ = JSON.parse(o || "{}");
311
+ h = JSON.parse(o || "{}");
296
312
  } catch {
297
- return s(400, { error: "body must be JSON" }, p);
313
+ return s(400, { error: "body must be JSON" }, f);
298
314
  }
299
- let v = u.slice(`${n}/webhooks/`.length);
315
+ let g = u.slice(`${n}/webhooks/`.length);
300
316
  try {
301
- switch (v) {
317
+ switch (g) {
302
318
  case "subscribe": {
303
- let e = _;
304
- return typeof e.event != "string" || e.event.length === 0 ? s(400, { error: "event required" }, p) : typeof e.url != "string" || e.url.length === 0 ? s(400, { error: "url required" }, p) : s(200, await t.webhookActions.subscribe(e), p);
319
+ let e = h;
320
+ return typeof e.event != "string" || e.event.length === 0 ? s(400, { error: "event required" }, f) : typeof e.url != "string" || e.url.length === 0 ? s(400, { error: "url required" }, f) : s(200, await t.webhookActions.subscribe(e), f);
305
321
  }
306
322
  case "pause": {
307
- let e = _.targetId;
308
- return typeof e != "string" || e.length === 0 ? s(400, { error: "targetId required" }, p) : (await t.webhookActions.pause(e), s(200, { ok: !0 }, p));
323
+ let e = h.targetId;
324
+ return typeof e != "string" || e.length === 0 ? s(400, { error: "targetId required" }, f) : (await t.webhookActions.pause(e), s(200, { ok: !0 }, f));
309
325
  }
310
326
  case "resume": {
311
- let e = _.targetId;
312
- return typeof e != "string" || e.length === 0 ? s(400, { error: "targetId required" }, p) : (await t.webhookActions.resume(e), s(200, { ok: !0 }, p));
327
+ let e = h.targetId;
328
+ return typeof e != "string" || e.length === 0 ? s(400, { error: "targetId required" }, f) : (await t.webhookActions.resume(e), s(200, { ok: !0 }, f));
313
329
  }
314
330
  case "delete": {
315
- let e = _.targetId;
316
- return typeof e != "string" || e.length === 0 ? s(400, { error: "targetId required" }, p) : (await t.webhookActions.delete(e), s(200, { ok: !0 }, p));
331
+ let e = h.targetId;
332
+ return typeof e != "string" || e.length === 0 ? s(400, { error: "targetId required" }, f) : (await t.webhookActions.delete(e), s(200, { ok: !0 }, f));
317
333
  }
318
334
  case "rotateSecret": {
319
- let e = _.targetId;
320
- return typeof e != "string" || e.length === 0 ? s(400, { error: "targetId required" }, p) : s(200, await t.webhookActions.rotateSecret(e), p);
335
+ let e = h.targetId;
336
+ return typeof e != "string" || e.length === 0 ? s(400, { error: "targetId required" }, f) : s(200, await t.webhookActions.rotateSecret(e), f);
321
337
  }
322
338
  case "replay": {
323
- let e = _.deliveryId;
324
- return typeof e != "string" || e.length === 0 ? s(400, { error: "deliveryId required" }, p) : (await t.webhookActions.replay(e), s(200, { ok: !0 }, p));
339
+ let e = h.deliveryId;
340
+ return typeof e != "string" || e.length === 0 ? s(400, { error: "deliveryId required" }, f) : (await t.webhookActions.replay(e), s(200, { ok: !0 }, f));
325
341
  }
326
342
  case "repinVersion": {
327
- let e = _.targetId, n = _.version;
328
- return typeof e != "string" || e.length === 0 ? s(400, { error: "targetId required" }, p) : typeof n != "number" || !Number.isInteger(n) || n < 1 ? s(400, { error: "version must be a positive integer" }, p) : (await t.webhookActions.updateTargetPayloadVersion(e, n), s(200, { ok: !0 }, p));
343
+ let e = h.targetId, n = h.version;
344
+ return typeof e != "string" || e.length === 0 ? s(400, { error: "targetId required" }, f) : typeof n != "number" || !Number.isInteger(n) || n < 1 ? s(400, { error: "version must be a positive integer" }, f) : (await t.webhookActions.updateTargetPayloadVersion(e, n), s(200, { ok: !0 }, f));
329
345
  }
330
- default: return s(404, { error: `unknown webhook action: ${v}` }, p);
346
+ default: return s(404, { error: `unknown webhook action: ${g}` }, f);
331
347
  }
332
348
  } catch (e) {
333
349
  return s(500, {
334
350
  error: "webhook action failed",
335
351
  message: e?.message ?? String(e)
336
- }, p);
352
+ }, f);
337
353
  }
338
- }, b = async (e, t, i, o, c = {}) => {
339
- let u = f(e);
340
- if (!m(u)) return null;
341
- let d = l(i.origin ?? i.Origin), p = (c.method ?? "POST").toUpperCase();
342
- if (p !== "POST") return null;
354
+ }, T = async (e, t, i, o, c = {}) => {
355
+ let u = _(e);
356
+ if (!y(u)) return null;
357
+ let d = l(i.origin ?? i.Origin), f = (c.method ?? "POST").toUpperCase();
358
+ if (f !== "POST") return null;
343
359
  if (r()) return s(503, { error: "inspect disabled (VOLTRO_INSPECT=off)" }, d);
344
- let h = (c.authResolver ?? a)(i, p);
345
- if (!h.ok) return s(401, {
360
+ let p = (c.authResolver ?? a)(i, f);
361
+ if (!p.ok) return s(401, {
346
362
  error: "unauthorized",
347
- reason: h.reason
363
+ reason: p.reason
348
364
  }, d);
349
365
  if (t.kind !== "api") return s(404, { error: "framework-action endpoints are api-only" }, d);
350
- let g = `${n}/seeds/run`, _ = `${n}/migrations/rollback`, v = `${n}/migrations/squash`, y = `${n}/migrations/restore-snapshot`;
351
- if (u !== g && u !== _ && u !== v && u !== y && u !== "/_voltro/inspect/migrations/compare-env") return null;
366
+ let m = `${n}/seeds/run`, h = `${n}/migrations/rollback`, g = `${n}/migrations/squash`, v = `${n}/migrations/restore-snapshot`;
367
+ if (u !== m && u !== h && u !== g && u !== v && u !== "/_voltro/inspect/migrations/compare-env") return null;
352
368
  let b;
353
369
  try {
354
370
  b = JSON.parse(o || "{}");
@@ -356,9 +372,9 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
356
372
  return s(400, { error: "body must be JSON" }, d);
357
373
  }
358
374
  try {
359
- if (u === g) return typeof b.id != "string" || b.id.length === 0 ? s(400, { error: "body.id must be a non-empty string" }, d) : t.runSeed ? s(200, await t.runSeed(b.id), d) : s(404, { error: "runSeed not configured" }, d);
360
- if (u === _) return typeof b.id != "string" || b.id.length === 0 ? s(400, { error: "body.id must be a non-empty string" }, d) : t.rollbackMigration ? s(200, await t.rollbackMigration(b.id), d) : s(404, { error: "rollbackMigration not configured" }, d);
361
- if (u === v) {
375
+ if (u === m) return typeof b.id != "string" || b.id.length === 0 ? s(400, { error: "body.id must be a non-empty string" }, d) : t.runSeed ? s(200, await t.runSeed(b.id), d) : s(404, { error: "runSeed not configured" }, d);
376
+ if (u === h) return typeof b.id != "string" || b.id.length === 0 ? s(400, { error: "body.id must be a non-empty string" }, d) : t.rollbackMigration ? s(200, await t.rollbackMigration(b.id), d) : s(404, { error: "rollbackMigration not configured" }, d);
377
+ if (u === g) {
362
378
  if (typeof b.before != "string" || b.before.length === 0) return s(400, { error: "body.before must be a non-empty ISO date string" }, d);
363
379
  if (!t.squashMigrationHistory) return s(404, { error: "squashMigrationHistory not configured" }, d);
364
380
  let e = typeof b.note == "string" ? b.note : void 0;
@@ -367,7 +383,7 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
367
383
  note: e
368
384
  }), d);
369
385
  }
370
- return u === y ? typeof b.planId != "string" || b.planId.length === 0 ? s(400, { error: "body.planId must be a non-empty string" }, d) : t.restoreSnapshot ? s(200, await t.restoreSnapshot({ planId: b.planId }), d) : s(404, { error: "restoreSnapshot not configured" }, d) : typeof b.url != "string" || b.url.length === 0 ? s(400, { error: "body.url must be a non-empty URL string" }, d) : t.compareCrossEnv ? (await t.compareCrossEnv({
386
+ return u === v ? typeof b.planId != "string" || b.planId.length === 0 ? s(400, { error: "body.planId must be a non-empty string" }, d) : t.restoreSnapshot ? s(200, await t.restoreSnapshot({ planId: b.planId }), d) : s(404, { error: "restoreSnapshot not configured" }, d) : typeof b.url != "string" || b.url.length === 0 ? s(400, { error: "body.url must be a non-empty URL string" }, d) : t.compareCrossEnv ? (await t.compareCrossEnv({
371
387
  url: b.url,
372
388
  label: typeof b.label == "string" ? b.label : void 0,
373
389
  token: typeof b.token == "string" ? b.token : void 0
@@ -378,8 +394,8 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
378
394
  message: e?.message ?? String(e)
379
395
  }, d);
380
396
  }
381
- }, x = async (e, t, n, i = {}) => {
382
- if (f(e) !== "/_voltro/inspect/data/rows") return null;
397
+ }, E = async (e, t, n, i = {}) => {
398
+ if (_(e) !== "/_voltro/inspect/data/rows") return null;
383
399
  let o = l(n.origin ?? n.Origin), c = (i.method ?? "GET").toUpperCase();
384
400
  if (c !== "GET") return s(405, {
385
401
  error: "method not allowed",
@@ -393,23 +409,23 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
393
409
  }, o);
394
410
  if (t.kind !== "api") return s(404, { error: "data viewer is api-only" }, o);
395
411
  if (t.inspectRows === void 0) return s(404, { error: "inspectRows not configured" }, o);
396
- let d = C(e), p = d.get("table");
397
- if (!p) return s(400, { error: "query.table is required" }, o);
398
- let m = w(d.get("offset")) ?? 0, h = w(d.get("limit")) ?? 50, g = {}, _ = d.get("q");
399
- if (_) {
400
- if (_.length > 8192) return s(400, { error: "query.q too large" }, o);
412
+ let d = O(e), f = d.get("table");
413
+ if (!f) return s(400, { error: "query.table is required" }, o);
414
+ let p = k(d.get("offset")) ?? 0, m = k(d.get("limit")) ?? 50, h = {}, g = d.get("q");
415
+ if (g) {
416
+ if (g.length > 8192) return s(400, { error: "query.q too large" }, o);
401
417
  try {
402
- g = JSON.parse(Buffer.from(_, "base64url").toString("utf8"));
418
+ h = JSON.parse(Buffer.from(g, "base64url").toString("utf8"));
403
419
  } catch {
404
420
  return s(400, { error: "query.q is not valid base64url JSON" }, o);
405
421
  }
406
422
  }
407
423
  try {
408
424
  return s(200, await t.inspectRows({
409
- table: p,
410
- offset: m,
411
- limit: h,
412
- ...g
425
+ table: f,
426
+ offset: p,
427
+ limit: m,
428
+ ...h
413
429
  }), o);
414
430
  } catch (e) {
415
431
  return e?.name === "InspectQueryError" ? s(400, {
@@ -420,39 +436,39 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
420
436
  message: e?.message ?? String(e)
421
437
  }, o);
422
438
  }
423
- }, S = async (t, n, i, o = {}) => {
424
- if (f(t) !== "/_voltro/inspect/provenance") return null;
439
+ }, D = async (t, n, i, o = {}) => {
440
+ if (_(t) !== "/_voltro/inspect/provenance") return null;
425
441
  let c = l(i.origin ?? i.Origin), u = (o.method ?? "GET").toUpperCase();
426
442
  if (u !== "GET") return s(405, {
427
443
  error: "method not allowed",
428
444
  expected: "GET"
429
445
  }, c);
430
446
  if (r()) return s(503, { error: "inspect disabled (VOLTRO_INSPECT=off)" }, c);
431
- let p = (o.authResolver ?? a)(i, u);
432
- if (!p.ok) return s(401, {
447
+ let f = (o.authResolver ?? a)(i, u);
448
+ if (!f.ok) return s(401, {
433
449
  error: "unauthorized",
434
- reason: p.reason
450
+ reason: f.reason
435
451
  }, c);
436
- let m = d(o.method, i, c);
437
- if (m) return m;
452
+ let p = d(o.method, i, c);
453
+ if (p) return p;
438
454
  if (n.kind !== "api") return s(404, { error: "provenance is api-only" }, c);
439
455
  if (n.inspectRows === void 0) return s(404, { error: "inspectRows not configured" }, c);
440
- let h = C(t), g = h.get("table"), _ = h.get("id"), v = h.get("column") ?? void 0;
441
- if (!g || !_) return s(400, { error: "query.table and query.id are required" }, c);
456
+ let m = O(t), h = m.get("table"), g = m.get("id"), v = m.get("column") ?? void 0;
457
+ if (!h || !g) return s(400, { error: "query.table and query.id are required" }, c);
442
458
  try {
443
459
  let t = (await n.inspectRows({
444
- table: g,
460
+ table: h,
445
461
  limit: 1,
446
462
  filter: {
447
463
  kind: "leaf",
448
464
  column: "id",
449
465
  op: "eq",
450
- value: _
466
+ value: g
451
467
  }
452
468
  })).rows[0];
453
469
  return s(200, e(t, {
454
- table: g,
455
- id: _,
470
+ table: h,
471
+ id: g,
456
472
  ...v === void 0 ? {} : { column: v }
457
473
  }), c);
458
474
  } catch (e) {
@@ -464,15 +480,15 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
464
480
  message: e?.message ?? String(e)
465
481
  }, c);
466
482
  }
467
- }, C = (e) => {
483
+ }, O = (e) => {
468
484
  let t = e.indexOf("?");
469
485
  return t < 0 ? new URLSearchParams() : new URLSearchParams(e.slice(t + 1));
470
- }, w = (e) => {
486
+ }, k = (e) => {
471
487
  if (e === null || e === "") return;
472
488
  let t = Number(e);
473
489
  return Number.isFinite(t) && t >= 0 ? Math.floor(t) : void 0;
474
- }, T = async (e, t, n, i = {}) => {
475
- if (f(e) !== "/_voltro/inspect/workflows/runs") return null;
490
+ }, A = async (e, t, n, i = {}) => {
491
+ if (_(e) !== "/_voltro/inspect/workflows/runs") return null;
476
492
  let o = l(n.origin ?? n.Origin), c = (i.method ?? "GET").toUpperCase();
477
493
  if (c !== "GET") return s(405, {
478
494
  error: "method not allowed",
@@ -491,14 +507,19 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
491
507
  offset: 0,
492
508
  limit: 50
493
509
  }, o);
494
- let d = C(e);
510
+ let d = O(e);
495
511
  try {
496
- let e = d.get("deadLettered") === "1" || d.get("deadLettered") === "true";
512
+ let e = d.get("deadLettered") === "1" || d.get("deadLettered") === "true", n = (d.get("statuses") ?? "").split(",").map((e) => e.trim()).filter((e) => e !== "");
497
513
  return s(200, await t.inspectWorkflowRuns({
498
514
  ...d.get("tag") === null ? {} : { tag: d.get("tag") },
499
- ...e ? { deadLettered: !0 } : d.get("status") === null ? {} : { status: d.get("status") },
500
- offset: w(d.get("offset")) ?? 0,
501
- limit: w(d.get("limit")) ?? 50
515
+ ...e ? { deadLettered: !0 } : d.get("status") === null ? n.length > 0 ? { statuses: n } : {} : { status: d.get("status") },
516
+ ...d.get("q") === null ? {} : { tagContains: d.get("q") },
517
+ ...d.get("source") === null ? {} : { source: d.get("source") },
518
+ ...d.get("idPrefix") === null ? {} : { idPrefix: d.get("idPrefix") },
519
+ ...d.get("from") === null ? {} : { startedAfter: d.get("from") },
520
+ ...d.get("to") === null ? {} : { startedBefore: d.get("to") },
521
+ offset: k(d.get("offset")) ?? 0,
522
+ limit: k(d.get("limit")) ?? 50
502
523
  }), o);
503
524
  } catch (e) {
504
525
  return s(500, {
@@ -506,32 +527,66 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
506
527
  message: e?.message ?? String(e)
507
528
  }, o);
508
529
  }
509
- }, E = async (e, t, n, i, o = {}) => {
510
- let c = f(e).match(/^\/_voltro\/inspect\/workflows\/start\/([^/]+)$/);
530
+ }, j = async (e, t, n, i = {}) => {
531
+ if (_(e) !== "/_voltro/inspect/workflows/stats") return null;
532
+ let o = l(n.origin ?? n.Origin), c = (i.method ?? "GET").toUpperCase();
533
+ if (c !== "GET") return s(405, {
534
+ error: "method not allowed",
535
+ expected: "GET"
536
+ }, o);
537
+ if (r()) return s(503, { error: "inspect disabled (VOLTRO_INSPECT=off)" }, o);
538
+ let u = (i.authResolver ?? a)(n, c);
539
+ if (!u.ok) return s(401, {
540
+ error: "unauthorized",
541
+ reason: u.reason
542
+ }, o);
543
+ if (t.kind !== "api") return s(404, { error: "workflows endpoint is api-only" }, o);
544
+ if (t.inspectWorkflowRunStats === void 0) return s(200, {
545
+ windowHours: 24,
546
+ bucketMinutes: 30,
547
+ buckets: [],
548
+ byTag: [],
549
+ total: 0,
550
+ truncated: !1
551
+ }, o);
552
+ let d = O(e);
553
+ try {
554
+ return s(200, await t.inspectWorkflowRunStats({
555
+ ...d.get("tag") === null ? {} : { tag: d.get("tag") },
556
+ ...k(d.get("hours")) === void 0 ? {} : { hours: k(d.get("hours")) }
557
+ }), o);
558
+ } catch (e) {
559
+ return s(500, {
560
+ error: "workflow-stats query failed",
561
+ message: e?.message ?? String(e)
562
+ }, o);
563
+ }
564
+ }, M = async (e, t, n, i, o = {}) => {
565
+ let c = _(e).match(/^\/_voltro\/inspect\/workflows\/start\/([^/]+)$/);
511
566
  if (!c) return null;
512
- let u = decodeURIComponent(c[1] ?? ""), d = l(n.origin ?? n.Origin), p = (o.method ?? "POST").toUpperCase();
513
- if (p !== "POST") return s(405, {
567
+ let u = decodeURIComponent(c[1] ?? ""), d = l(n.origin ?? n.Origin), f = (o.method ?? "POST").toUpperCase();
568
+ if (f !== "POST") return s(405, {
514
569
  error: "method not allowed",
515
570
  expected: "POST"
516
571
  }, d);
517
572
  if (r()) return s(503, { error: "inspect disabled (VOLTRO_INSPECT=off)" }, d);
518
- let m = (o.authResolver ?? a)(n, p);
519
- if (!m.ok) return s(401, {
573
+ let p = (o.authResolver ?? a)(n, f);
574
+ if (!p.ok) return s(401, {
520
575
  error: "unauthorized",
521
- reason: m.reason
576
+ reason: p.reason
522
577
  }, d);
523
578
  if (t.kind !== "api") return s(404, { error: "workflow start is api-only" }, d);
524
579
  if (t.inspectStartWorkflow === void 0) return s(404, { error: "inspectStartWorkflow not configured" }, d);
525
- let h = {};
580
+ let m = {};
526
581
  if (i.length > 0) try {
527
- h = JSON.parse(i).payload ?? {};
582
+ m = JSON.parse(i).payload ?? {};
528
583
  } catch {
529
584
  return s(400, { error: "start requires JSON body `{ payload?: unknown }`" }, d);
530
585
  }
531
586
  try {
532
587
  return s(200, await t.inspectStartWorkflow({
533
588
  name: u,
534
- payload: h
589
+ payload: m
535
590
  }), d);
536
591
  } catch (e) {
537
592
  return s(500, {
@@ -539,8 +594,8 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
539
594
  message: e?.message ?? String(e)
540
595
  }, d);
541
596
  }
542
- }, D = async (e, t, n, i = {}) => {
543
- let o = f(e);
597
+ }, N = async (e, t, n, i = {}) => {
598
+ let o = _(e);
544
599
  if (!o.startsWith("/_voltro/inspect/schedules")) return null;
545
600
  let c = l(n.origin ?? n.Origin);
546
601
  if (r()) return s(503, { error: "inspect disabled (VOLTRO_INSPECT=off)" }, c);
@@ -549,17 +604,17 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
549
604
  error: "unauthorized",
550
605
  reason: u.reason
551
606
  }, c);
552
- let p = d(i.method, n, c);
553
- if (p) return p;
607
+ let f = d(i.method, n, c);
608
+ if (f) return f;
554
609
  if (t.kind !== "api") return s(404, { error: "schedules are api-only" }, c);
555
- let m = (i.method ?? "GET").toUpperCase(), h = o.match(/^\/_voltro\/inspect\/schedules\/([^/]+)\/fire$/);
556
- if (h) {
557
- if (m !== "POST") return s(405, {
610
+ let p = (i.method ?? "GET").toUpperCase(), m = o.match(/^\/_voltro\/inspect\/schedules\/([^/]+)\/fire$/);
611
+ if (m) {
612
+ if (p !== "POST") return s(405, {
558
613
  error: "method not allowed",
559
614
  expected: "POST"
560
615
  }, c);
561
616
  if (!t.inspectFireSchedule) return s(404, { error: "inspectFireSchedule not configured" }, c);
562
- let n = decodeURIComponent(h[1] ?? ""), r = C(e).get("trigger") === "external" ? "external" : "manual";
617
+ let n = decodeURIComponent(m[1] ?? ""), r = O(e).get("trigger") === "external" ? "external" : "manual";
563
618
  try {
564
619
  return s(200, await t.inspectFireSchedule({
565
620
  name: n,
@@ -573,7 +628,7 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
573
628
  }
574
629
  }
575
630
  if (o === "/_voltro/inspect/schedules/runs") {
576
- if (m !== "GET") return s(405, {
631
+ if (p !== "GET") return s(405, {
577
632
  error: "method not allowed",
578
633
  expected: "GET"
579
634
  }, c);
@@ -583,12 +638,12 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
583
638
  offset: 0,
584
639
  limit: 50
585
640
  }, c);
586
- let n = C(e);
641
+ let n = O(e);
587
642
  try {
588
643
  return s(200, await t.inspectScheduleRuns({
589
644
  ...n.get("name") === null ? {} : { name: n.get("name") },
590
- offset: w(n.get("offset")) ?? 0,
591
- limit: w(n.get("limit")) ?? 50
645
+ offset: k(n.get("offset")) ?? 0,
646
+ limit: k(n.get("limit")) ?? 50
592
647
  }), c);
593
648
  } catch (e) {
594
649
  return s(500, {
@@ -597,7 +652,7 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
597
652
  }, c);
598
653
  }
599
654
  }
600
- return o === "/_voltro/inspect/schedules" ? m === "GET" ? t.inspectSchedules ? s(200, t.inspectSchedules(), c) : s(200, {
655
+ return o === "/_voltro/inspect/schedules" ? p === "GET" ? t.inspectSchedules ? s(200, t.inspectSchedules(), c) : s(200, {
601
656
  schedules: [],
602
657
  coordination: "single"
603
658
  }, c) : s(405, {
@@ -607,8 +662,8 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
607
662
  error: "unknown schedules endpoint",
608
663
  path: o
609
664
  }, c);
610
- }, O = async (e, t, n, i = {}) => {
611
- if (f(e) !== "/_voltro/inspect/cluster") return null;
665
+ }, P = async (e, t, n, i = {}) => {
666
+ if (_(e) !== "/_voltro/inspect/cluster") return null;
612
667
  let o = l(n.origin ?? n.Origin);
613
668
  if (r()) return s(503, { error: "inspect disabled (VOLTRO_INSPECT=off)" }, o);
614
669
  let c = (i.authResolver ?? a)(n, i.method ?? "POST");
@@ -655,8 +710,8 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
655
710
  message: e?.message ?? String(e)
656
711
  }, o);
657
712
  }
658
- }, k = async (e, t, n, i = {}) => {
659
- let o = f(e).match(/^\/_voltro\/inspect\/workflows\/runs\/([^/]+)\/steps$/);
713
+ }, F = async (e, t, n, i = {}) => {
714
+ let o = _(e).match(/^\/_voltro\/inspect\/workflows\/runs\/([^/]+)\/steps$/);
660
715
  if (!o) return null;
661
716
  let c = decodeURIComponent(o[1] ?? ""), u = l(n.origin ?? n.Origin), d = (i.method ?? "GET").toUpperCase();
662
717
  if (d !== "GET") return s(405, {
@@ -664,10 +719,10 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
664
719
  expected: "GET"
665
720
  }, u);
666
721
  if (r()) return s(503, { error: "inspect disabled (VOLTRO_INSPECT=off)" }, u);
667
- let p = (i.authResolver ?? a)(n, d);
668
- if (!p.ok) return s(401, {
722
+ let f = (i.authResolver ?? a)(n, d);
723
+ if (!f.ok) return s(401, {
669
724
  error: "unauthorized",
670
- reason: p.reason
725
+ reason: f.reason
671
726
  }, u);
672
727
  if (t.kind !== "api") return s(404, { error: "workflow steps are api-only" }, u);
673
728
  if (t.inspectWorkflowRunSteps === void 0) return s(200, { steps: [] }, u);
@@ -679,8 +734,8 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
679
734
  message: e?.message ?? String(e)
680
735
  }, u);
681
736
  }
682
- }, A = async (e, t, n, i = {}) => {
683
- let o = f(e).match(/^\/_voltro\/inspect\/workflows\/runs\/([^/]+)\/events$/);
737
+ }, I = async (e, t, n, i = {}) => {
738
+ let o = _(e).match(/^\/_voltro\/inspect\/workflows\/runs\/([^/]+)\/events$/);
684
739
  if (!o) return null;
685
740
  let c = decodeURIComponent(o[1] ?? ""), u = l(n.origin ?? n.Origin), d = (i.method ?? "GET").toUpperCase();
686
741
  if (d !== "GET") return s(405, {
@@ -688,10 +743,10 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
688
743
  expected: "GET"
689
744
  }, u);
690
745
  if (r()) return s(503, { error: "inspect disabled (VOLTRO_INSPECT=off)" }, u);
691
- let p = (i.authResolver ?? a)(n, d);
692
- if (!p.ok) return s(401, {
746
+ let f = (i.authResolver ?? a)(n, d);
747
+ if (!f.ok) return s(401, {
693
748
  error: "unauthorized",
694
- reason: p.reason
749
+ reason: f.reason
695
750
  }, u);
696
751
  if (t.kind !== "api") return s(404, { error: "workflow events are api-only" }, u);
697
752
  if (t.inspectWorkflowRunEvents === void 0) return s(200, { events: [] }, u);
@@ -703,8 +758,8 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
703
758
  message: e?.message ?? String(e)
704
759
  }, u);
705
760
  }
706
- }, j = async (e, t, n, i = {}) => {
707
- if (f(t) !== "/_voltro/inspect/workflows/events") return null;
761
+ }, L = async (e, t, n, i = {}) => {
762
+ if (_(t) !== "/_voltro/inspect/workflows/events") return null;
708
763
  let o = l(n.origin ?? n.Origin), c = (i.method ?? "GET").toUpperCase();
709
764
  if (c !== "GET") return s(405, {
710
765
  error: "method not allowed",
@@ -723,12 +778,12 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
723
778
  offset: 0,
724
779
  limit: 100
725
780
  }, o);
726
- let d = p(t), m = d.get("name") ?? void 0, h = Number(d.get("offset") ?? "0"), g = Number(d.get("limit") ?? "100");
781
+ let d = v(t), f = d.get("name") ?? void 0, p = Number(d.get("offset") ?? "0"), m = Number(d.get("limit") ?? "100");
727
782
  try {
728
783
  return s(200, await e.inspectWorkflowDomainEvents({
729
- ...m !== void 0 && m !== "" ? { name: m } : {},
730
- offset: Number.isFinite(h) ? h : 0,
731
- limit: Number.isFinite(g) ? g : 100
784
+ ...f !== void 0 && f !== "" ? { name: f } : {},
785
+ offset: Number.isFinite(p) ? p : 0,
786
+ limit: Number.isFinite(m) ? m : 100
732
787
  }), o);
733
788
  } catch (e) {
734
789
  return s(500, {
@@ -736,8 +791,8 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
736
791
  message: e?.message ?? String(e)
737
792
  }, o);
738
793
  }
739
- }, M = async (e, t, n, i = {}) => {
740
- let o = f(t).match(/^\/_voltro\/inspect\/workflows\/events\/([^/]+)\/deliveries$/);
794
+ }, R = async (e, t, n, i = {}) => {
795
+ let o = _(t).match(/^\/_voltro\/inspect\/workflows\/events\/([^/]+)\/deliveries$/);
741
796
  if (!o) return null;
742
797
  let c = decodeURIComponent(o[1] ?? ""), u = l(n.origin ?? n.Origin), d = (i.method ?? "GET").toUpperCase();
743
798
  if (d !== "GET") return s(405, {
@@ -745,10 +800,10 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
745
800
  expected: "GET"
746
801
  }, u);
747
802
  if (r()) return s(503, { error: "inspect disabled (VOLTRO_INSPECT=off)" }, u);
748
- let p = (i.authResolver ?? a)(n, d);
749
- if (!p.ok) return s(401, {
803
+ let f = (i.authResolver ?? a)(n, d);
804
+ if (!f.ok) return s(401, {
750
805
  error: "unauthorized",
751
- reason: p.reason
806
+ reason: f.reason
752
807
  }, u);
753
808
  if (e.kind !== "api") return s(404, { error: "workflow event deliveries are api-only" }, u);
754
809
  if (e.inspectWorkflowEventDeliveries === void 0) return s(200, { deliveries: [] }, u);
@@ -760,8 +815,8 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
760
815
  message: e?.message ?? String(e)
761
816
  }, u);
762
817
  }
763
- }, N = async (e, t, n, i = {}) => {
764
- if (f(e) !== "/_voltro/inspect/workflows/children") return null;
818
+ }, z = async (e, t, n, i = {}) => {
819
+ if (_(e) !== "/_voltro/inspect/workflows/children") return null;
765
820
  let o = l(n.origin ?? n.Origin), c = (i.method ?? "GET").toUpperCase();
766
821
  if (c !== "GET") return s(405, {
767
822
  error: "method not allowed",
@@ -774,7 +829,7 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
774
829
  reason: u.reason
775
830
  }, o);
776
831
  if (t.kind !== "api") return s(404, { error: "workflow children are api-only" }, o);
777
- let d = C(e).get("parentExecutionId");
832
+ let d = O(e).get("parentExecutionId");
778
833
  if (d === null || d === "") return s(400, { error: "parentExecutionId query param required" }, o);
779
834
  if (t.inspectWorkflowChildren === void 0) return s(200, {
780
835
  runs: [],
@@ -790,22 +845,22 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
790
845
  message: e?.message ?? String(e)
791
846
  }, o);
792
847
  }
793
- }, P = async (e, t, n, i, o = {}) => {
794
- let c = f(e).match(/^\/_voltro\/inspect\/workflows\/runs\/([^/]+)\/(cancel|retry|suspend|resume|signal|update|discard|redrive)$/);
848
+ }, B = async (e, t, n, i, o = {}) => {
849
+ let c = _(e).match(/^\/_voltro\/inspect\/workflows\/runs\/([^/]+)\/(cancel|retry|suspend|resume-from-step|resume|signal|update|discard|redrive)$/);
795
850
  if (!c) return null;
796
- let u = decodeURIComponent(c[1] ?? ""), d = c[2], p = l(n.origin ?? n.Origin), m = (o.method ?? "POST").toUpperCase();
797
- if (m !== "POST") return s(405, {
851
+ let u = decodeURIComponent(c[1] ?? ""), d = c[2], f = l(n.origin ?? n.Origin), p = (o.method ?? "POST").toUpperCase();
852
+ if (p !== "POST") return s(405, {
798
853
  error: "method not allowed",
799
854
  expected: "POST"
800
- }, p);
801
- if (r()) return s(503, { error: "inspect disabled (VOLTRO_INSPECT=off)" }, p);
802
- let h = (o.authResolver ?? a)(n, m);
803
- if (!h.ok) return s(401, {
855
+ }, f);
856
+ if (r()) return s(503, { error: "inspect disabled (VOLTRO_INSPECT=off)" }, f);
857
+ let m = (o.authResolver ?? a)(n, p);
858
+ if (!m.ok) return s(401, {
804
859
  error: "unauthorized",
805
- reason: h.reason
806
- }, p);
807
- if (t.kind !== "api") return s(404, { error: "workflow actions are api-only" }, p);
808
- let g = {
860
+ reason: m.reason
861
+ }, f);
862
+ if (t.kind !== "api") return s(404, { error: "workflow actions are api-only" }, f);
863
+ let h = {
809
864
  cancel: t.inspectCancelWorkflowRun,
810
865
  retry: t.inspectRetryWorkflowRun,
811
866
  suspend: t.inspectSuspendWorkflowRun,
@@ -813,38 +868,43 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
813
868
  signal: t.inspectSignalWorkflowRun,
814
869
  update: t.inspectUpdateWorkflowRun,
815
870
  discard: t.inspectDiscardWorkflowRun,
816
- redrive: t.inspectRedriveWorkflowRun
871
+ redrive: t.inspectRedriveWorkflowRun,
872
+ "resume-from-step": t.inspectResumeWorkflowRunFromStep
817
873
  }[d];
818
- if (!g) return s(404, { error: `inspect${d[0]?.toUpperCase() ?? ""}${d.slice(1)}WorkflowRun not configured` }, p);
819
- let _, v, y, b, x, S;
874
+ if (!h) return s(404, { error: d === "resume-from-step" ? "inspectResumeWorkflowRunFromStep not configured" : `inspect${d[0]?.toUpperCase() ?? ""}${d.slice(1)}WorkflowRun not configured` }, f);
875
+ let g, v, y, b, x, S, C;
820
876
  if (i.length > 0) try {
821
877
  let e = JSON.parse(i);
822
- d === "retry" && (_ = e.payloadOverride), d === "signal" && (typeof e.signalName == "string" && e.signalName.length > 0 && (v = e.signalName), y = e.payload), d === "update" && (typeof e.updateName == "string" && e.updateName.length > 0 && (b = e.updateName), x = e.payload, typeof e.timeoutMs == "number" && Number.isFinite(e.timeoutMs) && (S = e.timeoutMs));
878
+ d === "retry" && (g = e.payloadOverride), d === "resume-from-step" && typeof e.step == "string" && e.step.length > 0 && (C = e.step), d === "signal" && (typeof e.signalName == "string" && e.signalName.length > 0 && (v = e.signalName), y = e.payload), d === "update" && (typeof e.updateName == "string" && e.updateName.length > 0 && (b = e.updateName), x = e.payload, typeof e.timeoutMs == "number" && Number.isFinite(e.timeoutMs) && (S = e.timeoutMs));
823
879
  } catch {}
824
- if (d === "signal" && v === void 0) return s(400, { error: "signal requires JSON body `{ signalName: string, payload?: unknown }`" }, p);
825
- if (d === "update" && b === void 0) return s(400, { error: "update requires JSON body `{ updateName: string, payload?: unknown, timeoutMs?: number }`" }, p);
880
+ if (d === "signal" && v === void 0) return s(400, { error: "signal requires JSON body `{ signalName: string, payload?: unknown }`" }, f);
881
+ if (d === "update" && b === void 0) return s(400, { error: "update requires JSON body `{ updateName: string, payload?: unknown, timeoutMs?: number }`" }, f);
882
+ if (d === "resume-from-step" && C === void 0) return s(400, { error: "resume-from-step requires JSON body `{ step: string }` (the step name to rewind to)" }, f);
826
883
  try {
827
- return s(200, d === "retry" && _ !== void 0 ? await g({
884
+ return s(200, d === "retry" && g !== void 0 ? await h({
828
885
  runId: u,
829
- payloadOverride: _
830
- }) : d === "signal" ? await g({
886
+ payloadOverride: g
887
+ }) : d === "signal" ? await h({
831
888
  runId: u,
832
889
  signalName: v,
833
890
  payload: y
834
- }) : d === "update" ? await g({
891
+ }) : d === "update" ? await h({
835
892
  runId: u,
836
893
  updateName: b,
837
894
  payload: x,
838
895
  ...S === void 0 ? {} : { timeoutMs: S }
839
- }) : await g({ runId: u }), p);
896
+ }) : d === "resume-from-step" ? await h({
897
+ runId: u,
898
+ step: C
899
+ }) : await h({ runId: u }), f);
840
900
  } catch (e) {
841
901
  return s(500, {
842
902
  error: `${d} failed`,
843
903
  message: e?.message ?? String(e)
844
- }, p);
904
+ }, f);
845
905
  }
846
- }, F = async (e, t, n, i, o = {}) => {
847
- if (f(e) !== "/_voltro/inspect/data/import" || (o.method ?? "POST").toUpperCase() !== "POST") return null;
906
+ }, V = async (e, t, n, i, o = {}) => {
907
+ if (_(e) !== "/_voltro/inspect/data/import" || (o.method ?? "POST").toUpperCase() !== "POST") return null;
848
908
  let c = l(n.origin ?? n.Origin);
849
909
  if (r()) return s(503, { error: "inspect disabled (VOLTRO_INSPECT=off)" }, c);
850
910
  let u = (o.authResolver ?? a)(n, "POST");
@@ -852,23 +912,23 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
852
912
  error: "unauthorized",
853
913
  reason: u.reason
854
914
  }, c);
855
- let p = d(o.method, n, c);
856
- if (p) return p;
915
+ let f = d(o.method, n, c);
916
+ if (f) return f;
857
917
  if (t.kind !== "api") return s(404, { error: "data import is api-only" }, c);
858
918
  if (!t.inspectImport) return s(404, { error: "inspectImport not configured" }, c);
859
- let m;
919
+ let p;
860
920
  try {
861
- m = JSON.parse(i || "{}");
921
+ p = JSON.parse(i || "{}");
862
922
  } catch {
863
923
  return s(400, { error: "body must be JSON" }, c);
864
924
  }
865
- if (typeof m.bundleDir != "string" || !m.bundleDir) return s(400, { error: "body.bundleDir (string) is required" }, c);
925
+ if (typeof p.bundleDir != "string" || !p.bundleDir) return s(400, { error: "body.bundleDir (string) is required" }, c);
866
926
  try {
867
927
  return s(200, await t.inspectImport({
868
- bundleDir: m.bundleDir,
869
- ...m.mode === "upsert" || m.mode === "append" || m.mode === "replace" ? { mode: m.mode } : {},
870
- ...m.onConflict === "skip" || m.onConflict === "fail" ? { onConflict: m.onConflict } : {},
871
- ...typeof m.atomic == "boolean" ? { atomic: m.atomic } : {}
928
+ bundleDir: p.bundleDir,
929
+ ...p.mode === "upsert" || p.mode === "append" || p.mode === "replace" ? { mode: p.mode } : {},
930
+ ...p.onConflict === "skip" || p.onConflict === "fail" ? { onConflict: p.onConflict } : {},
931
+ ...typeof p.atomic == "boolean" ? { atomic: p.atomic } : {}
872
932
  }), c);
873
933
  } catch (e) {
874
934
  return s(500, {
@@ -876,17 +936,17 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
876
936
  message: e?.message ?? String(e)
877
937
  }, c);
878
938
  }
879
- }, I = async (e, t, n, i, o = {}) => {
880
- let c = f(e);
939
+ }, H = async (e, t, n, i, o = {}) => {
940
+ let c = _(e);
881
941
  if (!c.startsWith("/_voltro/inspect/data/rows")) return null;
882
942
  let u = (o.method ?? "POST").toUpperCase();
883
943
  if (u === "GET" && c === "/_voltro/inspect/data/rows") return null;
884
944
  let d = l(n.origin ?? n.Origin);
885
945
  if (r()) return s(503, { error: "inspect disabled (VOLTRO_INSPECT=off)" }, d);
886
- let p = (o.authResolver ?? a)(n, u);
887
- if (!p.ok) return s(401, {
946
+ let f = (o.authResolver ?? a)(n, u);
947
+ if (!f.ok) return s(401, {
888
948
  error: "unauthorized",
889
- reason: p.reason
949
+ reason: f.reason
890
950
  }, d);
891
951
  if (t.kind !== "api") return s(404, { error: "data viewer is api-only" }, d);
892
952
  if (u === "POST" && c === "/_voltro/inspect/data/rows") {
@@ -910,12 +970,12 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
910
970
  }, d);
911
971
  }
912
972
  }
913
- let m = c.match(/^\/_voltro\/inspect\/data\/rows\/([^/]+)$/);
914
- if (!m) return null;
915
- let h = decodeURIComponent(m[1] ?? "");
916
- if (!h) return s(400, { error: "row id is required in URL" }, d);
917
- let g = C(e).get("table") ?? "";
918
- if (!g) return s(400, { error: "query.table is required" }, d);
973
+ let p = c.match(/^\/_voltro\/inspect\/data\/rows\/([^/]+)$/);
974
+ if (!p) return null;
975
+ let m = decodeURIComponent(p[1] ?? "");
976
+ if (!m) return s(400, { error: "row id is required in URL" }, d);
977
+ let h = O(e).get("table") ?? "";
978
+ if (!h) return s(400, { error: "query.table is required" }, d);
919
979
  if (u === "PATCH") {
920
980
  if (!t.inspectUpdateRow) return s(404, { error: "inspectUpdateRow not configured" }, d);
921
981
  let e;
@@ -927,8 +987,8 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
927
987
  if (!e.patch || typeof e.patch != "object") return s(400, { error: "body.patch must be an object" }, d);
928
988
  try {
929
989
  return s(200, await t.inspectUpdateRow({
930
- table: g,
931
- id: h,
990
+ table: h,
991
+ id: m,
932
992
  patch: e.patch
933
993
  }), d);
934
994
  } catch (e) {
@@ -942,8 +1002,8 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
942
1002
  if (!t.inspectDeleteRow) return s(404, { error: "inspectDeleteRow not configured" }, d);
943
1003
  try {
944
1004
  return s(200, await t.inspectDeleteRow({
945
- table: g,
946
- id: h
1005
+ table: h,
1006
+ id: m
947
1007
  }), d);
948
1008
  } catch (e) {
949
1009
  return s(500, {
@@ -956,6 +1016,103 @@ var n = "/_voltro/inspect", r = () => process.env.VOLTRO_INSPECT === "off", i =
956
1016
  error: "method not allowed",
957
1017
  expected: "POST | PATCH | DELETE"
958
1018
  }, d);
1019
+ }, U = async (e, t, i, o, c = {}) => {
1020
+ let u = _(e), d = `${n}/workflows/flow-control`;
1021
+ if (u !== d && !u.startsWith(`${d}/`)) return null;
1022
+ let f = l(i.origin ?? i.Origin), p = (c.method ?? "GET").toUpperCase();
1023
+ if (r()) return s(503, { error: "inspect disabled (VOLTRO_INSPECT=off)" }, f);
1024
+ let m = (c.authResolver ?? a)(i, p);
1025
+ if (!m.ok) return s(401, {
1026
+ error: "unauthorized",
1027
+ reason: m.reason
1028
+ }, f);
1029
+ if (t.kind !== "api") return s(404, { error: "flow control is api-only" }, f);
1030
+ if (u === `${d}/inferences`) {
1031
+ if (p !== "GET") return s(405, {
1032
+ error: "method not allowed",
1033
+ expected: "GET"
1034
+ }, f);
1035
+ if (t.inspectInferences === void 0) return s(404, { error: "inspectInferences not configured" }, f);
1036
+ let n = O(e).get("limit"), r = n === null ? void 0 : Number(n);
1037
+ try {
1038
+ return s(200, await t.inspectInferences(r !== void 0 && Number.isFinite(r) ? { limit: r } : {}), f);
1039
+ } catch (e) {
1040
+ return s(500, {
1041
+ error: "inference queue read failed",
1042
+ message: e?.message ?? String(e)
1043
+ }, f);
1044
+ }
1045
+ }
1046
+ if (u === d) {
1047
+ if (p !== "GET") return s(405, {
1048
+ error: "method not allowed",
1049
+ expected: "GET"
1050
+ }, f);
1051
+ if (t.inspectFlowControl === void 0) return s(404, { error: "inspectFlowControl not configured" }, f);
1052
+ let n = O(e).get("limit"), r = n === null ? void 0 : Number(n);
1053
+ try {
1054
+ return s(200, await t.inspectFlowControl(r !== void 0 && Number.isFinite(r) ? { limit: r } : {}), f);
1055
+ } catch (e) {
1056
+ return s(500, {
1057
+ error: "flow control read failed",
1058
+ message: e?.message ?? String(e)
1059
+ }, f);
1060
+ }
1061
+ }
1062
+ if (p !== "POST") return s(405, {
1063
+ error: "method not allowed",
1064
+ expected: "POST"
1065
+ }, f);
1066
+ let h = {};
1067
+ if (o.length > 0) try {
1068
+ h = JSON.parse(o);
1069
+ } catch {
1070
+ return s(400, { error: "expected a JSON body" }, f);
1071
+ }
1072
+ let g = u.slice(d.length + 1);
1073
+ try {
1074
+ if (g === "pause") return t.inspectPauseWorkflow === void 0 ? s(404, { error: "inspectPauseWorkflow not configured" }, f) : h.workflow ? s(200, await t.inspectPauseWorkflow({
1075
+ workflow: h.workflow,
1076
+ ...h.reason === void 0 ? {} : { reason: h.reason }
1077
+ }), f) : s(400, { error: "body.workflow is required" }, f);
1078
+ if (g === "resume") return t.inspectResumeWorkflow === void 0 ? s(404, { error: "inspectResumeWorkflow not configured" }, f) : h.workflow ? s(200, await t.inspectResumeWorkflow({ workflow: h.workflow }), f) : s(400, { error: "body.workflow is required" }, f);
1079
+ if (g === "discard") return t.inspectDiscardIntent === void 0 ? s(404, { error: "inspectDiscardIntent not configured" }, f) : h.intentId ? s(200, await t.inspectDiscardIntent({ intentId: h.intentId }), f) : s(400, { error: "body.intentId is required" }, f);
1080
+ if (g === "bulk") {
1081
+ if (t.inspectBulkWorkflowRuns === void 0) return s(404, { error: "inspectBulkWorkflowRuns not configured" }, f);
1082
+ if (h.op !== "cancel" && h.op !== "replay") return s(400, { error: "body.op must be 'cancel' or 'replay'" }, f);
1083
+ if (typeof h.limit != "number") return s(400, { error: "body.limit is required — a bulk operation has no unbounded form, the cap IS the blast radius. The response reports `truncated` when more matched." }, f);
1084
+ try {
1085
+ return s(200, await t.inspectBulkWorkflowRuns({
1086
+ op: h.op,
1087
+ limit: h.limit,
1088
+ ...h.reason === void 0 ? {} : { reason: h.reason },
1089
+ ...h.mode === void 0 ? {} : { mode: h.mode },
1090
+ ...h.dryRun === void 0 ? {} : { dryRun: h.dryRun },
1091
+ ...h.workflow === void 0 ? {} : { workflow: h.workflow },
1092
+ ...h.status === void 0 ? {} : { status: h.status },
1093
+ ...h.startedAfter === void 0 ? {} : { startedAfter: h.startedAfter },
1094
+ ...h.startedBefore === void 0 ? {} : { startedBefore: h.startedBefore }
1095
+ }), f);
1096
+ } catch (e) {
1097
+ if (e?.name === "BulkRequestError") return s(400, { error: e.message }, f);
1098
+ throw e;
1099
+ }
1100
+ }
1101
+ } catch (e) {
1102
+ return s(500, {
1103
+ error: "flow control action failed",
1104
+ message: e?.message ?? String(e)
1105
+ }, f);
1106
+ }
1107
+ return s(404, {
1108
+ error: `unknown flow-control action '${g}'`,
1109
+ expected: [
1110
+ "pause",
1111
+ "resume",
1112
+ "discard",
1113
+ "bulk"
1114
+ ]
1115
+ }, f);
959
1116
  };
960
1117
  //#endregion
961
- export { E as C, c as D, r as E, o as O, T as S, u as T, N as _, a, A as b, x as c, v as d, S as f, P as g, y as h, d as i, I as l, D as m, h as n, O as o, _ as p, g as r, F as s, n as t, b as u, j as v, l as w, k as x, M as y };
1118
+ export { c as A, F as C, h as D, l as E, g as M, o as N, u as O, j as S, M as T, B as _, a, R as b, E as c, T as d, C as f, w as g, N as h, d as i, f as j, r as k, H as l, S as m, b as n, P as o, D as p, x as r, V as s, n as t, U as u, z as v, A as w, I as x, L as y };