@pikku/cli 0.12.93 → 0.12.99

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 (346) hide show
  1. package/console-app/assets/abnfDiagram-VRR7QNED-CytV-CG1.js +1 -0
  2. package/console-app/assets/arc-C5PvmnaA.js +1 -0
  3. package/console-app/assets/architecture-TIHT7OUA-C1_ScvPX.js +1 -0
  4. package/console-app/assets/architectureDiagram-ZJ3FMSHR-CJ2xb7C-.js +36 -0
  5. package/console-app/assets/array-BifhSqXX.js +1 -0
  6. package/console-app/assets/blockDiagram-677ZJIJ3-CCecrBrk.js +132 -0
  7. package/console-app/assets/c4Diagram-LMCZKHZV-CBnpukvQ.js +10 -0
  8. package/console-app/assets/channel-CwDOkXGI.js +1 -0
  9. package/console-app/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
  10. package/console-app/assets/chunk-32BRIVSS-D8qWWZRQ.js +1 -0
  11. package/console-app/assets/chunk-52WLFC77-BEpXHMsp.js +10 -0
  12. package/console-app/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
  13. package/console-app/assets/chunk-7BUUIJ7U-Bb538aSH.js +1 -0
  14. package/console-app/assets/chunk-C7G6YPKG-DsHUMkOp.js +1 -0
  15. package/console-app/assets/chunk-EX3LRPZG-mM7TjVx9.js +231 -0
  16. package/console-app/assets/chunk-FWX5IMBZ-CndRAn18.js +2 -0
  17. package/console-app/assets/chunk-HOUHSVGY-D1kT8umn.js +1 -0
  18. package/console-app/assets/chunk-ICXQ74PX-CeSaGyro.js +2 -0
  19. package/console-app/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
  20. package/console-app/assets/chunk-KEIR6QF5-DNzq6p3w.js +161 -0
  21. package/console-app/assets/chunk-MOJQB5TN-CaZOCHYr.js +88 -0
  22. package/console-app/assets/chunk-OGEWGWER-CnB1CsPt.js +1 -0
  23. package/console-app/assets/chunk-PUDLZKDR-BbGulHJm.js +156 -0
  24. package/console-app/assets/chunk-Q4XR5HBZ-BywwzeeR.js +70 -0
  25. package/console-app/assets/chunk-RYQCIY6F-CV0R1Adv.js +1 -0
  26. package/console-app/assets/chunk-V7JOEXUC-DGFaAWzB.js +206 -0
  27. package/console-app/assets/chunk-VAUOI2AC-DxPUd8Yb.js +1 -0
  28. package/console-app/assets/chunk-VR4S4FIN-D4-UaW_J.js +1 -0
  29. package/console-app/assets/chunk-WYO6CB5R-D_TFN0d9.js +127 -0
  30. package/console-app/assets/chunk-XXDRQBXY-BzVuweA_.js +1 -0
  31. package/console-app/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
  32. package/console-app/assets/chunk-ZGVPDNZ5-C6hdkGQb.js +62 -0
  33. package/console-app/assets/chunk-ZIRB5QZD-H-kepumB.js +32 -0
  34. package/console-app/assets/classDiagram-OUVF2IWQ-CTYJkTT0.js +1 -0
  35. package/console-app/assets/classDiagram-v2-EOCWNBFH-CTYJkTT0.js +1 -0
  36. package/console-app/assets/cose-bilkent-JH36ORCC-B6ZPxN6v.js +1 -0
  37. package/console-app/assets/cynefin-VYW2F7L2-D_nmxNz_.js +1 -0
  38. package/console-app/assets/cynefinDiagram-TSTJHNR4-CHy5QN0S.js +62 -0
  39. package/console-app/assets/cytoscape.esm-h6BdjjI9.js +321 -0
  40. package/console-app/assets/dagre-CXRCoUWR.js +1 -0
  41. package/console-app/assets/dagre-VKFMJZFB-DYfukM34.js +4 -0
  42. package/console-app/assets/defaultLocale-C8Fc0cco.js +1 -0
  43. package/console-app/assets/diagram-FQU43EPY-Dgb9TPSB.js +3 -0
  44. package/console-app/assets/diagram-G47NLZAW-CnFNZs9Z.js +24 -0
  45. package/console-app/assets/diagram-NH7WQ7WH-DN7h2DU-.js +24 -0
  46. package/console-app/assets/diagram-OA4YK3LP-RLaQaNtK.js +30 -0
  47. package/console-app/assets/diagram-WEI45ONY-DxHWhVGd.js +41 -0
  48. package/console-app/assets/dist-BaJNIo4I.js +1 -0
  49. package/console-app/assets/ebnfDiagram-CCIWWBDH-UN3Z81-l.js +1 -0
  50. package/console-app/assets/erDiagram-Q63AITRT-C9lGAY3i.js +85 -0
  51. package/console-app/assets/eventmodeling-45OFAUF4-Dc5wNSSK.js +1 -0
  52. package/console-app/assets/flowDiagram-23GEKE2U-zPyGHMi4.js +1 -0
  53. package/console-app/assets/ganttDiagram-NO4QXBWP-CvBjBcdK.js +292 -0
  54. package/console-app/assets/gitGraph-TEB2WS4Q-Cs5Z9jMo.js +1 -0
  55. package/console-app/assets/gitGraphDiagram-IHSO6WYX-B0i_IJ5r.js +106 -0
  56. package/console-app/assets/graphlib-B8gBHxth.js +1 -0
  57. package/console-app/assets/{index-CmAplHjZ.js → index-71U8EEj7.js} +155 -153
  58. package/console-app/assets/{index-BYj7ZbUU.css → index-BXMjqLQ5.css} +1 -1
  59. package/console-app/assets/info-DKCQHKI2-DHL0afNl.js +1 -0
  60. package/console-app/assets/infoDiagram-FWYZ7A6U-CBWykodX.js +2 -0
  61. package/console-app/assets/init-D6jRqBbL.js +1 -0
  62. package/console-app/assets/ishikawaDiagram-FXEZZL3T-DM377eW_.js +70 -0
  63. package/console-app/assets/journeyDiagram-5HDEW3XC-BpX_-Cns.js +139 -0
  64. package/console-app/assets/kanban-definition-HUTT4EX6-D3xFsQkO.js +89 -0
  65. package/console-app/assets/katex-Vhh-h91d.js +257 -0
  66. package/console-app/assets/line-CTSKHTE0.js +1 -0
  67. package/console-app/assets/linear-R5GlBvXT.js +1 -0
  68. package/console-app/assets/map-DsCK-0Cs.js +1 -0
  69. package/console-app/assets/mermaid-parser.core-CkHk4BPi.js +7 -0
  70. package/console-app/assets/mermaid.core-CcjGXuV6.js +11 -0
  71. package/console-app/assets/mindmap-definition-LN4V7U3C-CtolazqQ.js +96 -0
  72. package/console-app/assets/ordinal-hYBb2elL.js +1 -0
  73. package/console-app/assets/packet-7NZHBO7P-BxSOj_Ny.js +1 -0
  74. package/console-app/assets/path-BWPyau1x.js +1 -0
  75. package/console-app/assets/pegDiagram-2B236MQR-BNsMtxsM.js +1 -0
  76. package/console-app/assets/pie-RZYD4A2V-BbkKQBA5.js +1 -0
  77. package/console-app/assets/pieDiagram-ENE6RG2P-BAZLIz2f.js +39 -0
  78. package/console-app/assets/quadrantDiagram-ABIIQ3AL-Dpvn-1Fs.js +7 -0
  79. package/console-app/assets/radar-I7S5WNFK-B-uKXIAH.js +1 -0
  80. package/console-app/assets/railroad-3IZDKUUU-BHXXK04t.js +1 -0
  81. package/console-app/assets/railroad-abnf-AHOZXSZD-tXSQaBvY.js +1 -0
  82. package/console-app/assets/railroad-ebnf-EBAXGLYW-DG3aohR0.js +1 -0
  83. package/console-app/assets/railroad-peg-LSFZ7HO6-DY_gBA-x.js +1 -0
  84. package/console-app/assets/railroadDiagram-RFXS5EU6-DfUApEQj.js +1 -0
  85. package/console-app/assets/requirementDiagram-TGXJPOKE-B2zX0jqo.js +84 -0
  86. package/console-app/assets/rough.esm-CSKSodPl.js +1 -0
  87. package/console-app/assets/sankeyDiagram-HTMAVEWB-CbQ2zc7z.js +40 -0
  88. package/console-app/assets/sequenceDiagram-DBY2YBRQ-BLT8PXI_.js +162 -0
  89. package/console-app/assets/sizeCapture-X5ZJPWSS-B0uUizjq.js +1 -0
  90. package/console-app/assets/src-BLuPUFWW.js +1 -0
  91. package/console-app/assets/stateDiagram-2N3HPSRC-BvEyVp85.js +1 -0
  92. package/console-app/assets/stateDiagram-v2-6OUMAXLB-RGKS9iU4.js +1 -0
  93. package/console-app/assets/swimlanes-5IMT3BWC-1AZ459s6.js +2 -0
  94. package/console-app/assets/swimlanesDiagram-G3AALYLV-Ck_0-rfN.js +8 -0
  95. package/console-app/assets/timeline-definition-FHXFAJF6-dLuvH4s2.js +120 -0
  96. package/console-app/assets/treeView-QDETBFTQ-xL2msjo2.js +1 -0
  97. package/console-app/assets/treemap-6X3UGDF4-C98ichVP.js +1 -0
  98. package/console-app/assets/vennDiagram-L72KCM5P-HbUmidhv.js +34 -0
  99. package/console-app/assets/wardley-OPB4EBWU-C4gJS-m2.js +1 -0
  100. package/console-app/assets/wardleyDiagram-EHGQE667-B7b-LB02.js +78 -0
  101. package/console-app/assets/xychartDiagram-FW5EYKEG-Cm03zUGy.js +7 -0
  102. package/console-app/index.html +2 -2
  103. package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +1 -1
  104. package/dist/.pikku/auth/auth.types.d.ts +1 -1
  105. package/dist/.pikku/auth/auth.types.js +1 -1
  106. package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +1 -1
  107. package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
  108. package/dist/.pikku/cli/pikku-cli-channel.d.ts +13 -15
  109. package/dist/.pikku/cli/pikku-cli-channel.js +62 -8
  110. package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +14 -4
  111. package/dist/.pikku/cli/pikku-cli-client.gen.js +55 -18
  112. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.d.ts +1 -1
  113. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.js +1 -1
  114. package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +1 -1
  115. package/dist/.pikku/cli/pikku-cli-types.gen.js +1 -1
  116. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +1 -1
  117. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.json +136 -10
  118. package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
  119. package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
  120. package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
  121. package/dist/.pikku/cli/pikku-cli.gen.js +18 -2
  122. package/dist/.pikku/console/pikku-node-types.gen.d.ts +1 -1
  123. package/dist/.pikku/function/pikku-function-types.gen.d.ts +64 -23
  124. package/dist/.pikku/function/pikku-function-types.gen.js +27 -1
  125. package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
  126. package/dist/.pikku/function/pikku-functions-meta.gen.json +171 -37
  127. package/dist/.pikku/function/pikku-functions.gen.js +13 -3
  128. package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
  129. package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
  130. package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
  131. package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
  132. package/dist/.pikku/pikku-bootstrap-scenarios.gen.d.ts +1 -1
  133. package/dist/.pikku/pikku-bootstrap-scenarios.gen.js +1 -1
  134. package/dist/.pikku/pikku-bootstrap.gen.d.ts +1 -1
  135. package/dist/.pikku/pikku-bootstrap.gen.js +1 -1
  136. package/dist/.pikku/pikku-meta-service.gen.d.ts +1 -1
  137. package/dist/.pikku/pikku-meta-service.gen.js +1 -1
  138. package/dist/.pikku/pikku-services.gen.d.ts +2 -1
  139. package/dist/.pikku/pikku-services.gen.js +1 -0
  140. package/dist/.pikku/pikku-types.gen.d.ts +1 -1
  141. package/dist/.pikku/pikku-types.gen.js +1 -1
  142. package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
  143. package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
  144. package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +1 -1
  145. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
  146. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
  147. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +1 -1
  148. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.json +8 -1
  149. package/dist/.pikku/scenarios/pikku-scenario-functions-meta.gen.js +1 -1
  150. package/dist/.pikku/scenarios/pikku-scenario-functions.gen.d.ts +1 -1
  151. package/dist/.pikku/scenarios/pikku-scenario-wirings-meta.gen.js +1 -1
  152. package/dist/.pikku/scenarios/pikku-scenario-wirings.gen.d.ts +1 -1
  153. package/dist/.pikku/scenarios/schemas/register.gen.d.ts +1 -1
  154. package/dist/.pikku/scenarios/schemas/register.gen.js +1 -1
  155. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
  156. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
  157. package/dist/.pikku/schemas/register.gen.js +15 -5
  158. package/dist/.pikku/schemas/schemas/DbResetInput.schema.json +1 -1
  159. package/dist/.pikku/schemas/schemas/PersonaRunInput.schema.json +1 -0
  160. package/dist/.pikku/schemas/schemas/PersonaSyncInput.schema.json +1 -0
  161. package/dist/.pikku/schemas/schemas/PikkuPersonasInput.schema.json +1 -0
  162. package/dist/.pikku/schemas/schemas/PikkuRolesInput.schema.json +1 -0
  163. package/dist/.pikku/schemas/schemas/PikkuVirtualUserFunctionsOutput.schema.json +1 -0
  164. package/dist/.pikku/schemas/schemas/RolesPruneInput.schema.json +1 -0
  165. package/dist/.pikku/scopes/pikku-personas-meta.gen.json +1 -0
  166. package/dist/.pikku/scopes/pikku-personas.gen.d.ts +36 -0
  167. package/dist/.pikku/scopes/pikku-personas.gen.js +17 -0
  168. package/dist/.pikku/scopes/pikku-roles-meta.gen.json +1 -0
  169. package/dist/.pikku/scopes/pikku-roles.gen.d.ts +30 -0
  170. package/dist/.pikku/scopes/pikku-roles.gen.js +18 -0
  171. package/dist/.pikku/scopes/pikku-scope-types.gen.d.ts +4 -2
  172. package/dist/.pikku/scopes/pikku-scope-types.gen.js +3 -2
  173. package/dist/.pikku/scopes/pikku-scopes.gen.d.ts +1 -1
  174. package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +2 -2
  175. package/dist/.pikku/secrets/pikku-secret-types.gen.js +2 -2
  176. package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +1 -1
  177. package/dist/.pikku/secrets/pikku-secrets.gen.js +1 -1
  178. package/dist/.pikku/trigger/pikku-trigger-types.gen.d.ts +1 -1
  179. package/dist/.pikku/trigger/pikku-trigger-types.gen.js +1 -1
  180. package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +2 -2
  181. package/dist/.pikku/variables/pikku-variable-types.gen.js +2 -2
  182. package/dist/.pikku/variables/pikku-variables.gen.d.ts +1 -1
  183. package/dist/.pikku/variables/pikku-variables.gen.js +1 -1
  184. package/dist/.pikku/workflow/meta/allWorkflow.gen.json +46 -16
  185. package/dist/.pikku/workflow/pikku-personas.gen.d.ts +15 -0
  186. package/dist/.pikku/workflow/pikku-personas.gen.js +17 -0
  187. package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +101 -24
  188. package/dist/.pikku/workflow/pikku-workflow-types.gen.js +22 -2
  189. package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +1 -1
  190. package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +1 -1
  191. package/dist/bin/pikku-bin.mjs +2 -2
  192. package/dist/bin/pikku.js +0 -0
  193. package/dist/src/cli.wiring.js +108 -8
  194. package/dist/src/deploy/analyzer/analyzer.js +14 -0
  195. package/dist/src/deploy/analyzer/manifest.d.ts +11 -0
  196. package/dist/src/fabric/functions/validate.function.js +77 -177
  197. package/dist/src/functions/commands/all.d.ts +1 -1
  198. package/dist/src/functions/commands/bootstrap.d.ts +1 -1
  199. package/dist/src/functions/commands/bootstrap.js +3 -0
  200. package/dist/src/functions/commands/db-audit.js +1 -1
  201. package/dist/src/functions/commands/db-baseline.js +1 -1
  202. package/dist/src/functions/commands/db-check.js +6 -5
  203. package/dist/src/functions/commands/db-codegen.js +1 -1
  204. package/dist/src/functions/commands/db-generate.js +1 -1
  205. package/dist/src/functions/commands/db-migrate.js +1 -1
  206. package/dist/src/functions/commands/db-reset.d.ts +15 -1
  207. package/dist/src/functions/commands/db-reset.js +18 -6
  208. package/dist/src/functions/commands/db-shared.d.ts +14 -0
  209. package/dist/src/functions/commands/deploy-info.d.ts +1 -1
  210. package/dist/src/functions/commands/dev-ai-runner.d.ts +16 -4
  211. package/dist/src/functions/commands/dev-ai-runner.js +63 -29
  212. package/dist/src/functions/commands/dev.js +10 -5
  213. package/dist/src/functions/commands/enable.d.ts +8 -8
  214. package/dist/src/functions/commands/enable.js +15 -19
  215. package/dist/src/functions/commands/{scenario-environment.d.ts → environment.d.ts} +9 -6
  216. package/dist/src/functions/commands/{scenario-environment.js → environment.js} +5 -4
  217. package/dist/src/functions/commands/new-addon.js +14 -14
  218. package/dist/src/functions/commands/persona-sync.d.ts +33 -0
  219. package/dist/src/functions/commands/persona-sync.js +151 -0
  220. package/dist/src/functions/commands/persona.d.ts +58 -0
  221. package/dist/src/functions/commands/persona.js +215 -0
  222. package/dist/src/functions/commands/roles-audit.d.ts +1 -0
  223. package/dist/src/functions/commands/roles-audit.js +37 -0
  224. package/dist/src/functions/commands/roles-prune.d.ts +16 -0
  225. package/dist/src/functions/commands/roles-prune.js +52 -0
  226. package/dist/src/functions/commands/roles-shared.d.ts +40 -0
  227. package/dist/src/functions/commands/roles-shared.js +77 -0
  228. package/dist/src/functions/commands/scenario-browser.d.ts +3 -3
  229. package/dist/src/functions/commands/scenario-browser.js +1 -1
  230. package/dist/src/functions/commands/scenario-ladder.d.ts +44 -2
  231. package/dist/src/functions/commands/scenario-ladder.js +52 -3
  232. package/dist/src/functions/commands/scenario.d.ts +7 -0
  233. package/dist/src/functions/commands/scenario.js +82 -18
  234. package/dist/src/functions/commands/scopes-shared.d.ts +12 -0
  235. package/dist/src/functions/commands/scopes-shared.js +2 -2
  236. package/dist/src/functions/commands/serve.js +8 -4
  237. package/dist/src/functions/commands/versions-check.js +3 -3
  238. package/dist/src/functions/commands/virtual-user-formatter.d.ts +30 -0
  239. package/dist/src/functions/commands/virtual-user-formatter.js +65 -0
  240. package/dist/src/functions/db/annotation-parser.d.ts +14 -0
  241. package/dist/src/functions/db/annotation-parser.js +50 -2
  242. package/dist/src/functions/db/better-auth-schema.js +2 -1
  243. package/dist/src/functions/db/db-codegen.d.ts +12 -0
  244. package/dist/src/functions/db/db-codegen.js +149 -16
  245. package/dist/src/functions/db/local-db.d.ts +87 -6
  246. package/dist/src/functions/db/local-db.js +239 -35
  247. package/dist/src/functions/db/sqlite/dev-seed.d.ts +12 -0
  248. package/dist/src/functions/db/sqlite/dev-seed.js +23 -0
  249. package/dist/src/functions/db/sqlite/sqlite-runtime-bun.js +1 -1
  250. package/dist/src/functions/validate/bootstrap-checks.d.ts +19 -0
  251. package/dist/src/functions/validate/bootstrap-checks.js +90 -0
  252. package/dist/src/functions/validate/persona-checks.d.ts +24 -0
  253. package/dist/src/functions/validate/persona-checks.js +136 -0
  254. package/dist/src/functions/validate/scenario-file-checks.d.ts +17 -0
  255. package/dist/src/functions/validate/scenario-file-checks.js +123 -0
  256. package/dist/src/functions/validate/shared-checks.d.ts +59 -0
  257. package/dist/src/functions/validate/shared-checks.js +311 -0
  258. package/dist/src/functions/validate/workspace-validate.d.ts +1 -2
  259. package/dist/src/functions/validate/workspace-validate.js +4 -196
  260. package/dist/src/functions/wirings/ai-agent/pikku-command-public-agent.js +2 -1
  261. package/dist/src/functions/wirings/ai-agent/serialize-public-agent.js +1 -0
  262. package/dist/src/functions/wirings/auth/serialize-auth-gen.d.ts +2 -2
  263. package/dist/src/functions/wirings/auth/serialize-auth-gen.js +24 -9
  264. package/dist/src/functions/wirings/auth/serialize-auth-types.d.ts +3 -1
  265. package/dist/src/functions/wirings/auth/serialize-auth-types.js +3 -1
  266. package/dist/src/functions/wirings/channels/pikku-channels.d.ts +1 -1
  267. package/dist/src/functions/wirings/channels/serialize-typed-channel-map.js +10 -2
  268. package/dist/src/functions/wirings/cli/pikku-command-cli-entry.js +9 -4
  269. package/dist/src/functions/wirings/cli/serialize-channel-cli-client.d.ts +7 -3
  270. package/dist/src/functions/wirings/cli/serialize-channel-cli-client.js +64 -28
  271. package/dist/src/functions/wirings/cli/serialize-channel-cli.js +63 -6
  272. package/dist/src/functions/wirings/cli/serialize-cli-entrypoint-guard.d.ts +12 -0
  273. package/dist/src/functions/wirings/cli/serialize-cli-entrypoint-guard.js +28 -0
  274. package/dist/src/functions/wirings/cli/serialize-local-cli-bootstrap.js +4 -1
  275. package/dist/src/functions/wirings/console/serialize-console-functions.js +5 -8
  276. package/dist/src/functions/wirings/functions/serialize-addon-types.js +1 -1
  277. package/dist/src/functions/wirings/functions/serialize-function-types.js +106 -32
  278. package/dist/src/functions/wirings/middleware/serialize-middleware-imports.js +25 -9
  279. package/dist/src/functions/wirings/package/pikku-command-package-types.d.ts +3 -3
  280. package/dist/src/functions/wirings/package/serialize-package-types.js +5 -3
  281. package/dist/src/functions/wirings/personas/personas-secrets-file.d.ts +8 -0
  282. package/dist/src/functions/wirings/personas/personas-secrets-file.js +9 -0
  283. package/dist/src/functions/wirings/personas/pikku-command-personas.d.ts +7 -0
  284. package/dist/src/functions/wirings/personas/pikku-command-personas.js +57 -0
  285. package/dist/src/functions/wirings/personas/serialize-personas-secrets.d.ts +16 -0
  286. package/dist/src/functions/wirings/personas/serialize-personas-secrets.js +34 -0
  287. package/dist/src/functions/wirings/personas/serialize-personas-types.d.ts +18 -0
  288. package/dist/src/functions/wirings/personas/serialize-personas-types.js +76 -0
  289. package/dist/src/functions/wirings/queue/serialize-queue-map.js +2 -1
  290. package/dist/src/functions/wirings/queue/serialize-queue-wrapper.js +2 -1
  291. package/dist/src/functions/wirings/realtime/pikku-command-events-scaffold.js +2 -1
  292. package/dist/src/functions/wirings/roles/pikku-command-roles.d.ts +7 -0
  293. package/dist/src/functions/wirings/roles/pikku-command-roles.js +33 -0
  294. package/dist/src/functions/wirings/roles/serialize-roles-types.d.ts +14 -0
  295. package/dist/src/functions/wirings/roles/serialize-roles-types.js +55 -0
  296. package/dist/src/functions/wirings/rpc/pikku-command-public-rpc.js +2 -1
  297. package/dist/src/functions/wirings/scenarios/register-scenario-instrumentation.d.ts +3 -3
  298. package/dist/src/functions/wirings/scenarios/register-scenario-instrumentation.js +3 -3
  299. package/dist/src/functions/wirings/scopes/serialize-scopes-types.d.ts +1 -1
  300. package/dist/src/functions/wirings/scopes/serialize-scopes-types.js +1 -1
  301. package/dist/src/functions/wirings/user-admin/pikku-command-user-admin-functions.js +2 -1
  302. package/dist/src/functions/wirings/user-admin/serialize-user-admin-functions.js +2 -2
  303. package/dist/src/functions/wirings/virtual-user/pikku-command-virtual-user-functions.d.ts +1 -0
  304. package/dist/src/functions/wirings/virtual-user/pikku-command-virtual-user-functions.js +42 -0
  305. package/dist/src/functions/wirings/virtual-user/serialize-virtual-user-functions.d.ts +28 -0
  306. package/dist/src/functions/wirings/virtual-user/serialize-virtual-user-functions.js +439 -0
  307. package/dist/src/functions/wirings/workflow/pikku-command-workflow-routes.js +2 -1
  308. package/dist/src/functions/wirings/workflow/pikku-command-workflow.js +13 -13
  309. package/dist/src/functions/wirings/workflow/serialize-personas.d.ts +10 -0
  310. package/dist/src/functions/wirings/workflow/serialize-personas.js +46 -0
  311. package/dist/src/functions/wirings/workflow/serialize-scenario-step-map.js +13 -4
  312. package/dist/src/functions/wirings/workflow/serialize-workflow-types.js +170 -40
  313. package/dist/src/functions/workflows/all.workflow.js +55 -16
  314. package/dist/src/server/bun-server-runner.d.ts +2 -2
  315. package/dist/src/server/bun-server-runner.js +5 -1
  316. package/dist/src/server/content-signing-jwt.d.ts +13 -0
  317. package/dist/src/server/content-signing-jwt.js +51 -0
  318. package/dist/src/server/dev-server-runner.interface.d.ts +10 -2
  319. package/dist/src/server/node-server-runner.d.ts +2 -2
  320. package/dist/src/server/node-server-runner.js +2 -1
  321. package/dist/src/services/cli-logger.service.d.ts +28 -16
  322. package/dist/src/services/cli-logger.service.js +25 -16
  323. package/dist/src/services.d.ts +3 -1
  324. package/dist/src/services.js +10 -1
  325. package/dist/src/utils/file-import-path.js +9 -0
  326. package/dist/src/utils/pikku-cli-config.js +52 -2
  327. package/dist/src/utils/resolve-personas.d.ts +27 -0
  328. package/dist/src/utils/resolve-personas.js +35 -0
  329. package/dist/src/utils/resolve-scaffold-feature.d.ts +19 -0
  330. package/dist/src/utils/resolve-scaffold-feature.js +49 -0
  331. package/dist/tsconfig.tsbuildinfo +1 -1
  332. package/package.json +20 -17
  333. package/dist/.pikku/schemas/schemas/BootstrapInput.schema.json +0 -1
  334. package/dist/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +0 -1
  335. package/dist/.pikku/schemas/schemas/ScenarioRunInput.schema.json +0 -1
  336. package/dist/.pikku/workflow/pikku-scenario-actors.gen.d.ts +0 -19
  337. package/dist/.pikku/workflow/pikku-scenario-actors.gen.js +0 -17
  338. package/dist/src/functions/commands/db-seed.d.ts +0 -1
  339. package/dist/src/functions/commands/db-seed.js +0 -24
  340. package/dist/src/functions/db/sqlite/seed.d.ts +0 -11
  341. package/dist/src/functions/db/sqlite/seed.js +0 -22
  342. package/dist/src/functions/wirings/workflow/serialize-scenario-actors.d.ts +0 -2
  343. package/dist/src/functions/wirings/workflow/serialize-scenario-actors.js +0 -40
  344. package/dist/src/utils/resolve-scenario-actors.d.ts +0 -23
  345. package/dist/src/utils/resolve-scenario-actors.js +0 -74
  346. /package/dist/.pikku/schemas/schemas/{DbSeedInput.schema.json → RolesAuditInput.schema.json} +0 -0
@@ -1,4 +1,4 @@
1
- export const serializeWorkflowTypes = (functionTypesImportPath, rpcMapImportPath, workflowMapImportPath, agentMapImportPath, scopesImportPath, scenarioStepMapImportPath = './pikku-scenario-step-map.gen.js', scenarioActorsImportPath = './pikku-scenario-actors.gen.js') => {
1
+ export const serializeWorkflowTypes = (functionTypesImportPath, rpcMapImportPath, workflowMapImportPath, agentMapImportPath, scopesImportPath, scenarioStepMapImportPath = './pikku-scenario-step-map.gen.js', scenarioActorsImportPath = './pikku-personas.gen.js') => {
2
2
  return `import { WorkflowCancelledException } from '@pikku/core/workflow'
3
3
  import { template } from '@pikku/core/workflow'
4
4
  import {
@@ -14,9 +14,9 @@ import type { FlattenedRPCMap } from '${rpcMapImportPath}'
14
14
  import type { FlattenedWorkflowMap } from '${workflowMapImportPath}'
15
15
  import type { AgentMap as FlattenedAgentMap } from '${agentMapImportPath}'
16
16
  import type { FlattenedScenarioStepMap } from '${scenarioStepMapImportPath}'
17
- import type { TypedScenarioActors } from '${scenarioActorsImportPath}'
17
+ import type { TypedPersonas } from '${scenarioActorsImportPath}'
18
18
 
19
- export type { TypedScenarioActors }
19
+ export type { TypedPersonas }
20
20
 
21
21
  export { template }
22
22
 
@@ -43,18 +43,12 @@ export interface TypedWorkflow extends PikkuWorkflowWire {
43
43
  }
44
44
 
45
45
  /**
46
- * The typed half of a scenario wire: \`step\` and its \`given\`/\`when\`/\`then\`
47
- * sugar, narrowed to the names declared by \`pikkuScenarioStep\` in this project.
48
- * The phase only changes the prose the reporter renders.
46
+ * The typed half of a scenario wire: \`given\`/\`when\`/\`then\`, narrowed to the
47
+ * names declared by \`pikkuScenarioStep\` in this project. \`given\` and \`when\`
48
+ * differ only in the prose the reporter renders; \`then\` additionally makes the
49
+ * step's bindings witnesses rather than alternatives.
49
50
  */
50
51
  export interface TypedScenarioSteps {
51
- step<K extends keyof FlattenedScenarioStepMap>(
52
- stepName: string,
53
- stepFunc: K,
54
- data?: FlattenedScenarioStepMap[K]['input'],
55
- options?: ScenarioStepOptions
56
- ): Promise<FlattenedScenarioStepMap[K]['output']>
57
-
58
52
  given<K extends keyof FlattenedScenarioStepMap>(
59
53
  stepName: string,
60
54
  stepFunc: K,
@@ -308,18 +302,28 @@ export function pikkuFeature<const Scenarios extends readonly unknown[]>(
308
302
  return config
309
303
  }
310
304
 
305
+ /**
306
+ * One surface's implementation of a step.
307
+ *
308
+ * Each binding is typed independently, so a browser binding gets a non-optional
309
+ * \`wire.browser\` and a cli binding a non-optional \`wire.cli\` without either
310
+ * leaking into the other.
311
+ */
311
312
  export type PikkuFunctionScenarioStep<
312
313
  In = unknown,
313
314
  Out = never,
314
- B extends boolean = false
315
- > = PikkuFunctionSessionless<In, Out, B extends true ? 'scenarioStep' | 'browser' : 'scenarioStep'>
315
+ Surface extends 'browser' | 'cli' | 'default' = 'default'
316
+ > = PikkuFunctionSessionless<
317
+ In,
318
+ Out,
319
+ Surface extends 'default' ? 'scenarioStep' : 'scenarioStep' | Surface
320
+ >
316
321
 
317
322
  export type PikkuScenarioStepConfigWithSchema<
318
323
  InputSchema extends StandardSchemaV1 | undefined = undefined,
319
- OutputSchema extends StandardSchemaV1 | undefined = undefined,
320
- B extends boolean = false
324
+ OutputSchema extends StandardSchemaV1 | undefined = undefined
321
325
  > = {
322
- /** Registered name — this is the string \`scenario.step()\` references. */
326
+ /** Registered name — this is the string \`scenario.given()\` references. */
323
327
  name: string
324
328
  /**
325
329
  * What this step does, for the console and for whoever reads the source. It
@@ -336,49 +340,175 @@ export type PikkuScenarioStepConfigWithSchema<
336
340
  * sentence per call site.
337
341
  */
338
342
  template?: string
339
- /**
340
- * This step drives a browser. The runner provisions one for the step's actor
341
- * before calling it — which also makes an actor mandatory — and \`wire.browser\`
342
- * is non-optional inside \`func\`.
343
- */
344
- browser?: B
345
343
  title?: string
346
344
  tags?: string[]
347
345
  input?: InputSchema
348
346
  output?: OutputSchema
349
347
  errors?: Array<typeof PikkuError>
350
- func: PikkuFunctionScenarioStep<
348
+ /**
349
+ * Drive this step through a real browser, as a human would. The runner
350
+ * provisions a window for the step's actor first — which makes an actor
351
+ * mandatory — and \`wire.browser\` is non-optional inside it.
352
+ *
353
+ * Compose shared utilities here rather than writing raw clicks: the step says
354
+ * what the actor is doing, the utilities say how.
355
+ */
356
+ browser?: PikkuFunctionScenarioStep<
357
+ InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown,
358
+ OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown,
359
+ 'browser'
360
+ >
361
+ /** Drive this step remotely, over the websocket. */
362
+ cli?: PikkuFunctionScenarioStep<
363
+ InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown,
364
+ OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown,
365
+ 'cli'
366
+ >
367
+ /**
368
+ * The server-side path — the fast suite, and the floor every other surface
369
+ * falls back to.
370
+ *
371
+ * On a \`then\`, this is not an alternative to the other bindings but a second
372
+ * **witness**: the run executes every binding it has and fails if they
373
+ * disagree, because "the row says paid" and "the page says paid" are different
374
+ * claims and the gap between them is the bug nobody catches.
375
+ */
376
+ default?: PikkuFunctionScenarioStep<
351
377
  InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown,
352
378
  OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown,
353
- B
379
+ 'default'
354
380
  >
355
381
  }
356
382
 
357
- export type PikkuScenarioStepConfig<In, Out, B extends boolean = false> =
358
- Omit<PikkuScenarioStepConfigWithSchema<undefined, undefined, B>, 'func' | 'input' | 'output'> & {
359
- func: PikkuFunctionScenarioStep<In, Out, B>
383
+ export type PikkuScenarioStepConfig<In, Out> =
384
+ Omit<PikkuScenarioStepConfigWithSchema<undefined, undefined>, 'browser' | 'cli' | 'default' | 'input' | 'output'> & {
385
+ browser?: PikkuFunctionScenarioStep<In, Out, 'browser'>
386
+ cli?: PikkuFunctionScenarioStep<In, Out, 'cli'>
387
+ default?: PikkuFunctionScenarioStep<In, Out, 'default'>
360
388
  }
361
389
 
362
390
  /**
363
- * A named, reusable scenario step. Unlike \`scenario.do\`, which can only name an
364
- * RPC, a step's body is an ordinary pikku function — so it may drive a browser,
365
- * invoke RPCs as its actor, or run a workflow.
391
+ * A named, reusable scenario step, declaring one implementation per surface an
392
+ * actor can drive it through.
393
+ *
394
+ * The step's identity is what the actor is trying to do; which surface carries
395
+ * it out is a binding. That is what lets one ladder run through a real browser,
396
+ * over the websocket, or entirely server-side — and what makes "how much of this
397
+ * flow can a human actually reach" a number rather than a guess.
366
398
  *
367
399
  * Steps are deliberately NOT registered as RPCs: a browser-driving step must
368
400
  * never be network-callable.
369
401
  */
370
402
  export function pikkuScenarioStep<
371
403
  InputSchema extends StandardSchemaV1 | undefined = undefined,
372
- OutputSchema extends StandardSchemaV1 | undefined = undefined,
373
- B extends boolean = false
404
+ OutputSchema extends StandardSchemaV1 | undefined = undefined
374
405
  >(
375
- config: PikkuScenarioStepConfigWithSchema<InputSchema, OutputSchema, B>
376
- ): PikkuFunctionConfig<InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown, OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown, B extends true ? 'scenarioStep' | 'browser' : 'scenarioStep', PikkuFunctionScenarioStep<InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown, OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown, B>, InputSchema, OutputSchema>
377
- export function pikkuScenarioStep<In, Out = unknown, B extends boolean = false>(
378
- config: PikkuScenarioStepConfig<In, Out, B>
379
- ): PikkuFunctionConfig<In, Out, B extends true ? 'scenarioStep' | 'browser' : 'scenarioStep'>
406
+ config: PikkuScenarioStepConfigWithSchema<InputSchema, OutputSchema>
407
+ ): PikkuFunctionConfig<InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown, OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown, 'scenarioStep' | 'browser' | 'cli', PikkuFunctionScenarioStep<InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown, OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown, 'browser' | 'cli' | 'default'>, InputSchema, OutputSchema>
408
+ export function pikkuScenarioStep<In, Out = unknown>(
409
+ config: PikkuScenarioStepConfig<In, Out>
410
+ ): PikkuFunctionConfig<In, Out, 'scenarioStep' | 'browser' | 'cli'>
380
411
  export function pikkuScenarioStep(config: any) {
381
- return config
412
+ const surfaces = (['browser', 'cli', 'default'] as const).filter(
413
+ (surface) => typeof config[surface] === 'function'
414
+ )
415
+ if (surfaces.length === 0) {
416
+ throw new Error(
417
+ \`[scenario] step '\${config.name}' declares no surface bindings. Add at least a \\\`default\\\` (server-side) implementation.\`
418
+ )
419
+ }
420
+ return {
421
+ ...config,
422
+ surfaces,
423
+ // The runner sets the surface on the wire and calls this once per binding it
424
+ // resolved — every witness of a \`then\`, exactly one for an action step.
425
+ func: (services: any, data: any, wire: any) => {
426
+ const surface = wire?.scenarioStep?.surface ?? 'default'
427
+ const binding = config[surface] ?? config.default
428
+ return binding(services, data, wire)
429
+ },
430
+ }
431
+ }
432
+
433
+ /**
434
+ * What a step declares when nobody drives it: one implementation, and no
435
+ * surfaces to choose between.
436
+ *
437
+ * \`func\` rather than \`default\` is the point. \`default\` means *the fallback when
438
+ * no other surface applies*, which implies others could exist; \`func\` says
439
+ * structurally that there is one way this happens. That also keeps the phase
440
+ * rule coherent — an assertion runs every witness it has and fails if they
441
+ * disagree, and this has exactly one by construction.
442
+ */
443
+ export type PikkuSubjectScenarioStepConfigWithSchema<
444
+ InputSchema extends StandardSchemaV1 | undefined = undefined,
445
+ OutputSchema extends StandardSchemaV1 | undefined = undefined
446
+ > = Omit<
447
+ PikkuScenarioStepConfigWithSchema<InputSchema, OutputSchema>,
448
+ 'browser' | 'cli' | 'default'
449
+ > & {
450
+ func: PikkuFunctionScenarioStep<
451
+ InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown,
452
+ OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown,
453
+ 'default'
454
+ >
455
+ }
456
+
457
+ export type PikkuSubjectScenarioStepConfig<In, Out> =
458
+ Omit<PikkuScenarioStepConfig<In, Out>, 'browser' | 'cli' | 'default'> & {
459
+ func: PikkuFunctionScenarioStep<In, Out, 'default'>
460
+ }
461
+
462
+ /**
463
+ * A step in which the app acts on itself — "Given the platform has expired the
464
+ * trial".
465
+ *
466
+ * The grammatical subject of that sentence is not a user of your app; it **is**
467
+ * your app, which is why it is its own declaration rather than a persona with an
468
+ * asterisk. A persona is a person.
469
+ *
470
+ * Local-test-only, and never in a virtual user's catalogue: a virtual user that
471
+ * could expire its own trial is manufacturing the outcome it exists to discover.
472
+ */
473
+ export function pikkuPlatformScenarioStep<
474
+ InputSchema extends StandardSchemaV1 | undefined = undefined,
475
+ OutputSchema extends StandardSchemaV1 | undefined = undefined
476
+ >(
477
+ config: PikkuSubjectScenarioStepConfigWithSchema<InputSchema, OutputSchema>
478
+ ): PikkuFunctionConfig<InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown, OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown, 'scenarioStep', PikkuFunctionScenarioStep<InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown, OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown, 'default'>, InputSchema, OutputSchema>
479
+ export function pikkuPlatformScenarioStep<In, Out = unknown>(
480
+ config: PikkuSubjectScenarioStepConfig<In, Out>
481
+ ): PikkuFunctionConfig<In, Out, 'scenarioStep'>
482
+ export function pikkuPlatformScenarioStep(config: any) {
483
+ return { ...config, surfaces: ['default'] }
484
+ }
485
+
486
+ /**
487
+ * A step in which a third-party system acts — "Given Stripe's webhook arrives",
488
+ * "When Mailgun bounces it".
489
+ *
490
+ * \`addon\` names the addon that wraps that service, the same name its
491
+ * \`wireAddon\` declares. These steps *are* the mock its consumers currently
492
+ * hand-write: shipped by the addon author, maintained with the addon, and the
493
+ * same artifact that appears in the prose.
494
+ *
495
+ * Note that arranging and asserting are different — "Stripe's webhook arrives"
496
+ * stubs, "Then Stripe was charged" asserts, and only the first is a stub.
497
+ *
498
+ * Local-test-only, and never in a virtual user's catalogue: one that could
499
+ * invoke this would forge its own payment success.
500
+ */
501
+ export function pikkuAddonScenarioStep<
502
+ InputSchema extends StandardSchemaV1 | undefined = undefined,
503
+ OutputSchema extends StandardSchemaV1 | undefined = undefined
504
+ >(
505
+ config: PikkuSubjectScenarioStepConfigWithSchema<InputSchema, OutputSchema> & { addon: string }
506
+ ): PikkuFunctionConfig<InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown, OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown, 'scenarioStep', PikkuFunctionScenarioStep<InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown, OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown, 'default'>, InputSchema, OutputSchema>
507
+ export function pikkuAddonScenarioStep<In, Out = unknown>(
508
+ config: PikkuSubjectScenarioStepConfig<In, Out> & { addon: string }
509
+ ): PikkuFunctionConfig<In, Out, 'scenarioStep'>
510
+ export function pikkuAddonScenarioStep(config: any) {
511
+ return { ...config, surfaces: ['default'] }
382
512
  }
383
513
 
384
514
  type TypedRef<T> = { $ref: string; path?: string } & { __phantomType?: T }
@@ -22,6 +22,11 @@ const scaffoldFiles = (config) => {
22
22
  file: config.userAdminFunctionsFile,
23
23
  generator: 'pikkuUserAdminFunctions',
24
24
  });
25
+ if (config.scaffold?.virtualUser && config.virtualUserFunctionsFile)
26
+ files.push({
27
+ file: config.virtualUserFunctionsFile,
28
+ generator: 'pikkuVirtualUserFunctions',
29
+ });
25
30
  if (config.scaffold?.agent && config.publicAgentFile)
26
31
  files.push({
27
32
  file: config.publicAgentFile,
@@ -46,13 +51,27 @@ export const allWorkflow = pikkuWorkflowComplexFunc({
46
51
  let typesDeclarationFileExists = true;
47
52
  if (!existsSync(config.outDir)) {
48
53
  logger.debug(`• .pikku directory not found, running bootstrap first...`);
49
- await workflow.do('Bootstrap inspect', async () => getInspectorState(false, true, true));
54
+ // Every `getInspectorState` step below discards its result on purpose. A
55
+ // step's return value is stored as the step result and stays reachable for
56
+ // the life of the run, and an InspectorState holds a whole ts.Program — so
57
+ // returning it pins one TypeScript program per inspection instead of
58
+ // letting the previous one be collected. On a large project that is the
59
+ // difference between ~1.7GB and ~2.6GB peak RSS, i.e. between fitting in a
60
+ // 2GB CI heap and dying in it. Callers that need the state call
61
+ // `getInspectorState()` directly (it caches), never through a step.
62
+ await workflow.do('Bootstrap inspect', async () => {
63
+ await getInspectorState(false, true, true);
64
+ });
50
65
  // Both before function types: pikku-types.gen.ts re-exports the scope
51
66
  // definition types and imports ScopeId from the scopes codegen, so any
52
67
  // later import of '#pikku' — the inspector reading a project's zod
53
68
  // schemas, for one — fails until these two files exist.
54
69
  await workflow.do('Bootstrap scope definition types', 'pikkuScopeDefinitionTypes', null);
55
70
  await workflow.do('Bootstrap scopes', 'pikkuScopes', { bootstrap: true });
71
+ await workflow.do('Bootstrap roles', 'pikkuRoles', { bootstrap: true });
72
+ await workflow.do('Bootstrap personas', 'pikkuPersonas', {
73
+ bootstrap: true,
74
+ });
56
75
  await workflow.do('Bootstrap function types split', 'pikkuFunctionTypesSplit', { bootstrap: true });
57
76
  // Pre-write a stub auth.types.ts (if the project uses better-auth) so the
58
77
  // pikkuBetterAuth re-export resolves before any user file is imported.
@@ -86,7 +105,9 @@ export const allWorkflow = pikkuWorkflowComplexFunc({
86
105
  bootstrap: true,
87
106
  });
88
107
  }
89
- await workflow.do('Bootstrap re-inspect', async () => getInspectorState(true, true));
108
+ await workflow.do('Bootstrap re-inspect', async () => {
109
+ await getInspectorState(true, true);
110
+ });
90
111
  }
91
112
  if (!existsSync(config.typesDeclarationFile)) {
92
113
  typesDeclarationFileExists = false;
@@ -100,7 +121,9 @@ export const allWorkflow = pikkuWorkflowComplexFunc({
100
121
  await workflow.do('Generate function types', 'pikkuFunctionTypes', {});
101
122
  if (!typesDeclarationFileExists || missingScaffolds.length > 0) {
102
123
  logger.debug(`• Type file or scaffolds first created, inspecting again...`);
103
- await workflow.do('Re-inspect after types', async () => getInspectorState(true));
124
+ await workflow.do('Re-inspect after types', async () => {
125
+ await getInspectorState(true);
126
+ });
104
127
  }
105
128
  // Type generators are independent of each other
106
129
  const typeGenerators = [
@@ -147,6 +170,7 @@ export const allWorkflow = pikkuWorkflowComplexFunc({
147
170
  workflow.do('Public RPC', 'pikkuPublicRPC', null),
148
171
  workflow.do('Console functions', 'pikkuConsoleFunctions', null),
149
172
  workflow.do('User admin functions', 'pikkuUserAdminFunctions', null),
173
+ workflow.do('Virtual user functions', 'pikkuVirtualUserFunctions', null),
150
174
  workflow.do('Events scaffold', 'pikkuEventsScaffold', null),
151
175
  workflow.do('Emails', 'pikkuEmails', null),
152
176
  workflow.do('Secret definition types', 'pikkuSecretDefinitionTypes', null),
@@ -155,6 +179,8 @@ export const allWorkflow = pikkuWorkflowComplexFunc({
155
179
  workflow.do('Credentials', 'pikkuCredentials', null),
156
180
  workflow.do('Scope definition types', 'pikkuScopeDefinitionTypes', null),
157
181
  workflow.do('Scopes', 'pikkuScopes', {}),
182
+ workflow.do('Roles', 'pikkuRoles', {}),
183
+ workflow.do('Personas', 'pikkuPersonas', {}),
158
184
  workflow.do('Variable definition types', 'pikkuVariableDefinitionTypes', null),
159
185
  workflow.do('Variables', 'pikkuVariables', null),
160
186
  workflow.do('Addon types', 'pikkuAddonTypes', null),
@@ -163,18 +189,25 @@ export const allWorkflow = pikkuWorkflowComplexFunc({
163
189
  allImports.push(config.rpcInternalWiringMetaFile);
164
190
  }
165
191
  if (agents || !config.addon) {
166
- await workflow.do('Re-inspect after agents', async () => getInspectorState(true));
192
+ await workflow.do('Re-inspect after agents', async () => {
193
+ await getInspectorState(true);
194
+ });
167
195
  }
168
- // pikkuAuth generates auth-secrets.gen.ts (with wireSecret calls) inside the
169
- // Promise.all above, but pikkuSecrets runs concurrently from the pre-auth
170
- // inspector state. Re-run secret/credential/variable codegen now so that the
171
- // freshly-generated auth-secrets.gen.ts (just picked up by Re-inspect above)
172
- // is reflected in pikku-secrets-meta.gen.json.
173
- if ((await getInspectorState()).auth.definition) {
196
+ // pikkuAuth generates auth-secrets.gen.ts and pikkuPersonas generates
197
+ // pikku-personas-secrets.gen.ts (both full of defineSecret calls) inside the
198
+ // Promise.all above, but pikkuSecrets runs concurrently from the inspector
199
+ // state as it was before either wrote anything. Re-run secret/credential/
200
+ // variable codegen now so those freshly-generated files — just picked up by
201
+ // Re-inspect above — are reflected in pikku-secrets-meta.gen.json. Without
202
+ // this the declaration only lands on a second `pikku` run, and a cold
203
+ // project deploys without ever being asked for the value.
204
+ const stateAfterScaffold = await getInspectorState();
205
+ if (stateAfterScaffold.auth.definition ||
206
+ stateAfterScaffold.personas.definitions.length > 0) {
174
207
  await Promise.all([
175
- workflow.do('Secrets (post-auth)', 'pikkuSecrets', null),
176
- workflow.do('Credentials (post-auth)', 'pikkuCredentials', null),
177
- workflow.do('Variables (post-auth)', 'pikkuVariables', null),
208
+ workflow.do('Secrets (post-scaffold)', 'pikkuSecrets', null),
209
+ workflow.do('Credentials (post-scaffold)', 'pikkuCredentials', null),
210
+ workflow.do('Variables (post-scaffold)', 'pikkuVariables', null),
178
211
  ]);
179
212
  }
180
213
  const schemas = await workflow.do('Schemas', 'pikkuSchemas', null);
@@ -198,7 +231,9 @@ export const allWorkflow = pikkuWorkflowComplexFunc({
198
231
  }
199
232
  }
200
233
  if (workflows || remoteRPC || webhook || workflowRoutes) {
201
- await workflow.do('Re-inspect after workflows', async () => getInspectorState(true));
234
+ await workflow.do('Re-inspect after workflows', async () => {
235
+ await getInspectorState(true);
236
+ });
202
237
  const regeneratedSchemas = await workflow.do('Re-generate schemas', 'pikkuSchemas', null);
203
238
  if (regeneratedSchemas && !schemas) {
204
239
  allImports.push(`${config.schemaDirectory}/register.gen.ts`);
@@ -276,7 +311,9 @@ export const allWorkflow = pikkuWorkflowComplexFunc({
276
311
  const cliChannelGenerated = await workflow.do('CLI entry', 'pikkuCLIEntry', null);
277
312
  allImports.push(config.cliWiringMetaFile, config.cliWiringsFile);
278
313
  if (cliChannelGenerated) {
279
- await workflow.do('Re-inspect after CLI channel', async () => getInspectorState(true));
314
+ await workflow.do('Re-inspect after CLI channel', async () => {
315
+ await getInspectorState(true);
316
+ });
280
317
  const cliChannels = await workflow.do('Channels after CLI', 'pikkuCommandChannels', null);
281
318
  await workflow.do('Functions after CLI', 'pikkuFunctions', null);
282
319
  await workflow.do('Schemas after CLI', 'pikkuSchemas', null);
@@ -296,7 +333,9 @@ export const allWorkflow = pikkuWorkflowComplexFunc({
296
333
  }
297
334
  if (config.openAPI) {
298
335
  logger.debug(`• OpenAPI requires a reinspection to pickup new generated types..`);
299
- await workflow.do('OpenAPI re-inspect', async () => getInspectorState(true));
336
+ await workflow.do('OpenAPI re-inspect', async () => {
337
+ await getInspectorState(true);
338
+ });
300
339
  await workflow.do('OpenAPI', 'pikkuOpenAPI', null);
301
340
  }
302
341
  await workflow.do('Versions update', 'pikkuVersionsUpdate', null);
@@ -8,10 +8,10 @@
8
8
  */
9
9
  import type { EventHubService } from '@pikku/core';
10
10
  import type { Logger } from '@pikku/core/services';
11
- import type { DevServerRunner, DevServerInstance, DevServerConfig } from './dev-server-runner.interface.js';
11
+ import type { DevServerRunner, DevServerInstance, DevServerConfig, DevServerOptions } from './dev-server-runner.interface.js';
12
12
  export declare class BunServerRunner implements DevServerRunner {
13
13
  private mod?;
14
14
  private eventHub?;
15
15
  createEventHub(): Promise<EventHubService<any>>;
16
- createServer(config: DevServerConfig, logger: Logger): DevServerInstance;
16
+ createServer(config: DevServerConfig, logger: Logger, options?: DevServerOptions): DevServerInstance;
17
17
  }
@@ -14,12 +14,16 @@ export class BunServerRunner {
14
14
  this.eventHub = new this.mod.BunEventHubService();
15
15
  return this.eventHub;
16
16
  }
17
- createServer(config, logger) {
17
+ createServer(config, logger, options = {}) {
18
18
  if (!this.mod || !this.eventHub) {
19
19
  throw new Error('createEventHub() must be called before createServer()');
20
20
  }
21
21
  return new this.mod.PikkuBunServer(config, logger, {
22
22
  eventHub: this.eventHub,
23
+ // Dropped here until now, which silently disabled signed asset reads for
24
+ // every Bun project: `config.content` arrived, but the service that
25
+ // verifies its signatures did not.
26
+ contentSigningJWT: options.contentSigningJWT,
23
27
  });
24
28
  }
25
29
  }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * `pikku dev` and `pikku serve` construct the local content service themselves,
3
+ * so they must supply the key its signed asset URLs are signed and verified
4
+ * with — a project is not required to wire a JWTService just to serve uploads
5
+ * in development.
6
+ *
7
+ * The key is random and per-process: URLs signed by one dev server mean
8
+ * nothing to the next. That is the right lifetime for a development secret,
9
+ * and it lets the runtime reject any signature it cannot verify instead of
10
+ * waving through requests when no key is configured.
11
+ */
12
+ import type { JWTService } from '@pikku/core/services';
13
+ export declare const createEphemeralContentSigningJWT: () => JWTService;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * `pikku dev` and `pikku serve` construct the local content service themselves,
3
+ * so they must supply the key its signed asset URLs are signed and verified
4
+ * with — a project is not required to wire a JWTService just to serve uploads
5
+ * in development.
6
+ *
7
+ * The key is random and per-process: URLs signed by one dev server mean
8
+ * nothing to the next. That is the right lifetime for a development secret,
9
+ * and it lets the runtime reject any signature it cannot verify instead of
10
+ * waving through requests when no key is configured.
11
+ */
12
+ import { createHmac, randomBytes, timingSafeEqual } from 'node:crypto';
13
+ import { getRelativeTimeOffsetFromNow } from '@pikku/core';
14
+ export const createEphemeralContentSigningJWT = () => {
15
+ const key = randomBytes(32);
16
+ const sign = (body) => createHmac('sha256', key).update(body).digest('base64url');
17
+ return {
18
+ encode: async (expiresIn, payload) => {
19
+ const envelope = {
20
+ exp: getRelativeTimeOffsetFromNow(expiresIn).getTime(),
21
+ payload,
22
+ };
23
+ const body = Buffer.from(JSON.stringify(envelope), 'utf8').toString('base64url');
24
+ return `${body}.${sign(body)}`;
25
+ },
26
+ decode: async (hash, invalidHashError) => {
27
+ const invalid = invalidHashError ?? new Error('Invalid content signature');
28
+ const [body, signature] = hash.split('.');
29
+ if (!body || !signature) {
30
+ throw invalid;
31
+ }
32
+ const expected = Buffer.from(sign(body), 'utf8');
33
+ const actual = Buffer.from(signature, 'utf8');
34
+ if (expected.length !== actual.length ||
35
+ !timingSafeEqual(expected, actual)) {
36
+ throw invalid;
37
+ }
38
+ let envelope;
39
+ try {
40
+ envelope = JSON.parse(Buffer.from(body, 'base64url').toString('utf8'));
41
+ }
42
+ catch {
43
+ throw invalid;
44
+ }
45
+ if (typeof envelope.exp !== 'number' || Date.now() > envelope.exp) {
46
+ throw invalid;
47
+ }
48
+ return envelope.payload;
49
+ },
50
+ };
51
+ };
@@ -9,7 +9,7 @@
9
9
  * `services.ts` and injected — no `typeof Bun` checks in the dev command.
10
10
  */
11
11
  import type { EventHubService } from '@pikku/core';
12
- import type { Logger } from '@pikku/core/services';
12
+ import type { JWTService, Logger } from '@pikku/core/services';
13
13
  import type { NodeHTTPServerConfig } from '@pikku/node-http-server';
14
14
  export interface DevServerInstance {
15
15
  init(): Promise<void>;
@@ -19,6 +19,14 @@ export interface DevServerInstance {
19
19
  }
20
20
  /** Config shape both runtimes accept (Core config + host/port/content). */
21
21
  export type DevServerConfig = NodeHTTPServerConfig;
22
+ export type DevServerOptions = {
23
+ /**
24
+ * The JWTService the dev server's content service signs asset URLs with.
25
+ * The transport verifies signed asset reads with it, so it must be the same
26
+ * instance — otherwise every signed URL is rejected.
27
+ */
28
+ contentSigningJWT?: JWTService;
29
+ };
22
30
  export interface DevServerRunner {
23
31
  /**
24
32
  * Create the EventHub for this runtime. Shared into singleton services so
@@ -27,5 +35,5 @@ export interface DevServerRunner {
27
35
  */
28
36
  createEventHub(): Promise<EventHubService<any>>;
29
37
  /** Create the dev HTTP/WS server. Must be called after `createEventHub`. */
30
- createServer(config: DevServerConfig, logger: Logger): DevServerInstance;
38
+ createServer(config: DevServerConfig, logger: Logger, options?: DevServerOptions): DevServerInstance;
31
39
  }
@@ -5,8 +5,8 @@
5
5
  */
6
6
  import type { EventHubService } from '@pikku/core';
7
7
  import type { Logger } from '@pikku/core/services';
8
- import type { DevServerRunner, DevServerInstance, DevServerConfig } from './dev-server-runner.interface.js';
8
+ import type { DevServerRunner, DevServerInstance, DevServerConfig, DevServerOptions } from './dev-server-runner.interface.js';
9
9
  export declare class NodeServerRunner implements DevServerRunner {
10
10
  createEventHub(): Promise<EventHubService<any>>;
11
- createServer(config: DevServerConfig, logger: Logger): DevServerInstance;
11
+ createServer(config: DevServerConfig, logger: Logger, options?: DevServerOptions): DevServerInstance;
12
12
  }
@@ -11,12 +11,13 @@ export class NodeServerRunner {
11
11
  async createEventHub() {
12
12
  return new LocalEventHubService();
13
13
  }
14
- createServer(config, logger) {
14
+ createServer(config, logger, options = {}) {
15
15
  const wss = new WebSocketServer({ noServer: true });
16
16
  const server = new PikkuNodeHTTPServer(config, logger, {
17
17
  configureServer: (httpServer) => {
18
18
  pikkuWebsocketHandler({ server: httpServer, wss, logger });
19
19
  },
20
+ contentSigningJWT: options.contentSigningJWT,
20
21
  });
21
22
  return {
22
23
  init: () => server.init(),
@@ -1,7 +1,17 @@
1
1
  import type { Logger } from '@pikku/core/services';
2
+ import type { Safe } from '@pikku/core';
2
3
  import { LogLevel } from '@pikku/core/services';
3
4
  import type { ErrorCode, DiagnosticSeverity, CodedDiagnostic } from '@pikku/inspector';
4
5
  export type CLIOutputMode = 'text' | 'json';
6
+ /**
7
+ * The structured form a CLI log line may take. The `Record<string, any>` arm
8
+ * mirrors the `Logger` interface, which admits any object as a message.
9
+ */
10
+ export type CLILogMessage = string | {
11
+ message: string;
12
+ type?: string;
13
+ data?: Record<string, unknown>;
14
+ } | Record<string, any>;
5
15
  export declare class CLILogger implements Logger {
6
16
  private silent;
7
17
  private level;
@@ -23,25 +33,27 @@ export declare class CLILogger implements Logger {
23
33
  private ensureJSONFlushHook;
24
34
  flushJSONBuffer(): void;
25
35
  private emit;
26
- info(message: string | {
27
- message: string;
28
- type?: string;
29
- data?: Record<string, unknown>;
36
+ /**
37
+ * Splits a log line into the parts `emit` needs.
38
+ *
39
+ * The public methods declare their message as `Safe<M>`, which distributes
40
+ * over the `CLILogMessage` union and cannot be narrowed by `typeof`. The
41
+ * guard's job is done once the call site has been checked, so the message is
42
+ * converted back to its domain type here — in one place rather than in each
43
+ * method.
44
+ */
45
+ private messageParts;
46
+ info<M extends CLILogMessage, A extends unknown[]>(message: Safe<M>, ...__meta: {
47
+ [K in keyof A]: Safe<A[K]>;
30
48
  }): void;
31
- error(message: string | Error | {
32
- message: string;
33
- type?: string;
34
- data?: Record<string, unknown>;
49
+ error<M extends CLILogMessage | Error, A extends unknown[]>(message: Safe<M>, ...__meta: {
50
+ [K in keyof A]: Safe<A[K]>;
35
51
  }): void;
36
- warn(message: string | {
37
- message: string;
38
- type?: string;
39
- data?: Record<string, unknown>;
52
+ warn<M extends CLILogMessage, A extends unknown[]>(message: Safe<M>, ...__meta: {
53
+ [K in keyof A]: Safe<A[K]>;
40
54
  }): void;
41
- debug(message: string | {
42
- message: string;
43
- type?: string;
44
- data?: Record<string, unknown>;
55
+ debug<M extends CLILogMessage, A extends unknown[]>(message: Safe<M>, ...__meta: {
56
+ [K in keyof A]: Safe<A[K]>;
45
57
  }): void;
46
58
  diagnostic({ severity, code, message }: CodedDiagnostic): void;
47
59
  /** Sugar for `diagnostic({ severity: 'critical', code, message })`. */