@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,6 +1,7 @@
1
1
  import { existsSync, mkdirSync, rmSync, writeFileSync, readFileSync, readdirSync, } from 'node:fs';
2
2
  import { resolve, isAbsolute, relative, dirname, join } from 'node:path';
3
3
  import { createRequire } from 'node:module';
4
+ import { pathToFileURL } from 'node:url';
4
5
  import { runInNewContext } from 'node:vm';
5
6
  import { transformSync } from 'esbuild';
6
7
  import { CamelCasePlugin, Kysely, PostgresDialect } from 'kysely';
@@ -15,7 +16,7 @@ import { SqliteMigrationExecutor } from './sqlite/sqlite-migrator.js';
15
16
  import { SqliteIntrospector } from './sqlite/sqlite-introspector.js';
16
17
  import { createSqliteKysely } from './sqlite/sqlite-kysely.js';
17
18
  import { loadSqliteRuntime } from './sqlite/sqlite-runtime.js';
18
- import { seed as runSeed } from './sqlite/seed.js';
19
+ import { devSeed as runDevSeed } from './sqlite/dev-seed.js';
19
20
  import { PostgresMigrationExecutor } from './postgres/postgres-migrator.js';
20
21
  import { createPGliteKysely } from './postgres/pglite-kysely.js';
21
22
  import { PostgresIntrospector } from './postgres/postgres-introspector.js';
@@ -37,7 +38,11 @@ export function parseDatabaseUrl(url) {
37
38
  * Resolve a UserConfigShape into an absolute-path descriptor.
38
39
  * Returns null when neither sqliteDb nor postgresUrl is configured.
39
40
  */
40
- export function resolveDb(userConfig, rootDir, outDir, runtimeDir) {
41
+ export function resolveDb(userConfig, rootDir, outDir, runtimeDir, dbConfig) {
42
+ // The parameter took a bare schema string before `defaultSchema` existed;
43
+ // both forms are accepted so callers outside this repo keep working.
44
+ const schema = typeof dbConfig === 'string' ? dbConfig : dbConfig?.schema;
45
+ const defaultSchema = typeof dbConfig === 'string' ? undefined : dbConfig?.defaultSchema;
41
46
  const resolvedRuntimeDir = runtimeDir
42
47
  ? resolveAgainst(rootDir, runtimeDir)
43
48
  : join(rootDir, '.pikku-runtime');
@@ -58,17 +63,21 @@ export function resolveDb(userConfig, rootDir, outDir, runtimeDir) {
58
63
  classificationsGenJsonFile: join(rootDir, 'db', 'annotations.gen.json'),
59
64
  zodFile: join(outDir, 'db', 'zod.gen.ts'),
60
65
  camelCase: true,
66
+ defaultSchema,
61
67
  });
62
68
  if (userConfig.postgresUrl && userConfig.sqliteDb) {
63
69
  throw new Error('Both postgresUrl and sqliteDb are set. Configure exactly one database dialect.');
64
70
  }
71
+ const pgliteExtensions = userConfig.pgliteExtensions ?? [];
65
72
  if (userConfig.postgresUrl) {
66
73
  return {
67
74
  dialect: 'postgres',
68
75
  mode: 'url',
69
76
  connectionString: userConfig.postgresUrl,
70
77
  runtimeDir: resolvedRuntimeDir,
71
- seedFile: resolveAgainst(rootDir, 'db/postgres-seed.sql'),
78
+ devSeedFile: resolveAgainst(rootDir, 'db/postgres-dev-seed.sql'),
79
+ pgliteExtensions,
80
+ schema,
72
81
  ...base('db/postgres'),
73
82
  };
74
83
  }
@@ -77,11 +86,17 @@ export function resolveDb(userConfig, rootDir, outDir, runtimeDir) {
77
86
  ? '.pikku-runtime/dev.db'
78
87
  : undefined);
79
88
  if (sqliteDb) {
89
+ if (schema) {
90
+ throw new Error(`db.schema is set to '${schema}', but the resolved database is sqlite. ` +
91
+ 'sqlite has one schema to be in, and its REFERENCES clause takes a bare ' +
92
+ 'table name, so qualified DDL does not compile there. Remove db.schema, ' +
93
+ 'or configure postgres.');
94
+ }
80
95
  return {
81
96
  dialect: 'sqlite',
82
97
  dbFile: resolveAgainst(rootDir, sqliteDb),
83
98
  runtimeDir: resolvedRuntimeDir,
84
- seedFile: resolveAgainst(rootDir, 'db/sqlite-seed.sql'),
99
+ devSeedFile: resolveAgainst(rootDir, 'db/sqlite-dev-seed.sql'),
85
100
  ...base('db/sqlite'),
86
101
  };
87
102
  }
@@ -91,7 +106,9 @@ export function resolveDb(userConfig, rootDir, outDir, runtimeDir) {
91
106
  mode: 'pglite',
92
107
  pgliteDir: join(resolvedRuntimeDir, 'dev-postgres'),
93
108
  runtimeDir: resolvedRuntimeDir,
94
- seedFile: resolveAgainst(rootDir, 'db/postgres-seed.sql'),
109
+ devSeedFile: resolveAgainst(rootDir, 'db/postgres-dev-seed.sql'),
110
+ pgliteExtensions,
111
+ schema,
95
112
  ...base('db/postgres'),
96
113
  };
97
114
  }
@@ -120,21 +137,144 @@ async function createPostgresClient(resolved) {
120
137
  throw new Error('PGlite Postgres resolution is missing pgliteDir.');
121
138
  }
122
139
  mkdirSync(dirname(resolved.pgliteDir), { recursive: true });
123
- const db = await createEmbeddedPostgres(resolved.pgliteDir);
140
+ const db = await createEmbeddedPostgres(resolved, resolved.pgliteDir);
124
141
  return pgliteAsClient(db);
125
142
  }
126
- async function createEmbeddedPostgres(dataDir) {
127
- const [{ PGlite }, { pgcrypto }] = await Promise.all([
143
+ let embeddedPostgresWasm;
144
+ /**
145
+ * Compile PGlite's two WASM modules once and hand them to every instance.
146
+ *
147
+ * PGlite already caches them across instances internally, so this saves one
148
+ * 10.5MB compile per process rather than one per instance — measured at ~5% off
149
+ * a four-instance run. It is worth the few lines because a `WebAssembly.Module`
150
+ * is stateless compiled code, safe to instantiate any number of times.
151
+ *
152
+ * Note what this does *not* fix: each instance still compiles ~4MB of its own
153
+ * WASM (~3.3MB of it the pgcrypto side module, which PGlite offers no way to
154
+ * share) across ~15 module constructions, and frees it on close. That per
155
+ * instance churn is the suspected trigger for the rare V8 abort seen in CI on
156
+ * Linux x64, where PKU-based ThreadIsolation loses track of a code allocation:
157
+ *
158
+ * Check failed: jit_page_->allocations_.erase(addr) == 1.
159
+ *
160
+ * Resolution mirrors PGlite's own `new URL('./pglite.wasm', import.meta.url)`.
161
+ * If the files are not where the package puts them (a bundled CLI, say), we
162
+ * hand back nothing and PGlite loads them itself as before.
163
+ */
164
+ async function loadEmbeddedPostgresWasm() {
165
+ try {
166
+ const dist = dirname(createRequire(import.meta.url).resolve('@electric-sql/pglite'));
167
+ const [pgliteWasmModule, initdbWasmModule] = await Promise.all([
168
+ WebAssembly.compile(readFileSync(join(dist, 'pglite.wasm'))),
169
+ WebAssembly.compile(readFileSync(join(dist, 'initdb.wasm'))),
170
+ ]);
171
+ return { pgliteWasmModule, initdbWasmModule };
172
+ }
173
+ catch {
174
+ return undefined;
175
+ }
176
+ }
177
+ const isPGliteExtension = (value) => typeof value === 'object' &&
178
+ value !== null &&
179
+ typeof value.setup === 'function';
180
+ /**
181
+ * Turn a declared extension specifier into the module that publishes it.
182
+ *
183
+ * A bare name is one of PGlite's own contrib extensions (`hstore`, `citext`,
184
+ * `uuid_ossp`), which ship with the CLI's copy of PGlite and need nothing
185
+ * installed. Anything else is a package the project depends on — pgvector, say,
186
+ * as `@electric-sql/pglite-pgvector` — so it is resolved from the project first
187
+ * and only then from the CLI, since the project is where a user installs it.
188
+ */
189
+ async function importPGliteExtensionModule(spec, rootDir) {
190
+ const id = spec.includes('/') || spec.startsWith('@')
191
+ ? spec
192
+ : `@electric-sql/pglite/contrib/${spec}`;
193
+ for (const from of [join(rootDir, 'package.json'), import.meta.url]) {
194
+ let resolvedPath;
195
+ try {
196
+ resolvedPath = createRequire(from).resolve(id);
197
+ }
198
+ catch {
199
+ continue;
200
+ }
201
+ return (await import(pathToFileURL(resolvedPath).href));
202
+ }
203
+ throw new Error(`The PGlite extension '${spec}' could not be resolved as '${id}', ` +
204
+ `from either the project (${rootDir}) or the pikku CLI. ` +
205
+ `Install it in your project, or name one of PGlite's bundled contrib ` +
206
+ `extensions (hstore, citext, uuid_ossp, …), which need no install.`);
207
+ }
208
+ /**
209
+ * Load every extension the project declares, keyed the way PGlite wants them.
210
+ *
211
+ * The key is the export name (`vector`, `hstore`), which is also the name the
212
+ * SQL uses, so `CREATE EXTENSION vector` finds what a declaration of
213
+ * `@electric-sql/pglite-pgvector` loaded. A module exporting several is fine —
214
+ * all of them are taken — and a `default` export is used only when it is the
215
+ * only extension there, so a package that default-exports the same object it
216
+ * also names is not registered twice.
217
+ */
218
+ export async function loadPGliteExtensions(rootDir, specs) {
219
+ const extensions = {};
220
+ for (const spec of specs) {
221
+ const module = await importPGliteExtensionModule(spec, rootDir);
222
+ const found = Object.entries(module).filter(([, value]) => isPGliteExtension(value));
223
+ const named = found.filter(([name]) => name !== 'default');
224
+ const chosen = named.length > 0 ? named : found;
225
+ if (chosen.length === 0) {
226
+ throw new Error(`'${spec}' exports no PGlite extension. A PGlite extension is an ` +
227
+ `object with a 'setup' function — check that the package is one, ` +
228
+ `and that its version matches the PGlite the CLI runs.`);
229
+ }
230
+ for (const [name, extension] of chosen) {
231
+ extensions[name === 'default' ? (extension.name ?? spec) : name] =
232
+ extension;
233
+ }
234
+ }
235
+ return extensions;
236
+ }
237
+ async function createEmbeddedPostgres(context, dataDir) {
238
+ embeddedPostgresWasm ??= loadEmbeddedPostgresWasm();
239
+ const [{ PGlite }, { pgcrypto }, wasm, declared] = await Promise.all([
128
240
  import('@electric-sql/pglite'),
129
241
  import('@electric-sql/pglite/contrib/pgcrypto'),
242
+ embeddedPostgresWasm,
243
+ loadPGliteExtensions(context.rootDir, context.pgliteExtensions),
130
244
  ]);
131
245
  return new PGlite({
132
246
  ...(dataDir ? { dataDir } : {}),
247
+ ...wasm,
133
248
  extensions: {
134
249
  pgcrypto,
250
+ ...declared,
135
251
  },
136
252
  });
137
253
  }
254
+ /**
255
+ * PGlite reports an extension it was never given as a plain
256
+ * `extension "x" is not available`, which reads as though the SQL is at fault.
257
+ * It is not: the database is real Postgres, the migration is fine, and the one
258
+ * thing missing is the declaration that would have loaded the extension into
259
+ * this particular instance. Say so, since nothing else in the message points
260
+ * anywhere near the fix.
261
+ */
262
+ function explainMissingExtension(error, declared) {
263
+ const message = error instanceof Error ? error.message : '';
264
+ const match = /extension "([^"]+)" is not available/.exec(message);
265
+ if (!match)
266
+ return error;
267
+ const name = match[1];
268
+ return new Error(`The embedded PGlite database has no '${name}' extension. ` +
269
+ `The CLI migrates a PGlite shadow database to type and diff your schema, ` +
270
+ `so every extension your migrations use has to be declared as ` +
271
+ `pgliteExtensions in createConfig — e.g. pgliteExtensions: ['${name}'] ` +
272
+ `for a PGlite contrib extension, or the package that publishes it ` +
273
+ `('@electric-sql/pglite-pgvector' for pgvector).` +
274
+ (declared.length > 0
275
+ ? ` Currently declared: ${declared.join(', ')}.`
276
+ : ''), { cause: error });
277
+ }
138
278
  function pgliteAsClient(db) {
139
279
  return {
140
280
  query: (sql, params) => db.query(sql, params),
@@ -152,6 +292,14 @@ async function withPostgresClient(resolved, run) {
152
292
  try {
153
293
  return await run(client);
154
294
  }
295
+ catch (error) {
296
+ // Only the embedded database's missing extensions are the declaration's
297
+ // doing. On a real server it is the server that lacks the extension, and
298
+ // pointing at the CLI's config would send the reader the wrong way.
299
+ throw resolved.mode === 'pglite'
300
+ ? explainMissingExtension(error, resolved.pgliteExtensions)
301
+ : error;
302
+ }
155
303
  finally {
156
304
  await client.end();
157
305
  }
@@ -189,6 +337,7 @@ export async function migrateAndCodegen(resolved, options = {}) {
189
337
  schemaJsonFile: resolved.schemaJsonFile,
190
338
  enumsFile: resolved.enumsFile,
191
339
  camelCase: resolved.camelCase,
340
+ defaultSchema: resolved.defaultSchema,
192
341
  rootDir: resolved.rootDir,
193
342
  dialect: 'sqlite',
194
343
  migrationsDir: resolved.migrationsDir,
@@ -200,7 +349,7 @@ export async function migrateAndCodegen(resolved, options = {}) {
200
349
  }
201
350
  else {
202
351
  const withClient = options.scratch
203
- ? (_r, run) => withScratchPostgresDatabase(run)
352
+ ? (r, run) => withScratchPostgresDatabase(r, run)
204
353
  : withPostgresClient;
205
354
  await withClient(resolved, async (client) => {
206
355
  const introspector = new PostgresIntrospector(client);
@@ -216,6 +365,7 @@ export async function migrateAndCodegen(resolved, options = {}) {
216
365
  schemaJsonFile: resolved.schemaJsonFile,
217
366
  enumsFile: resolved.enumsFile,
218
367
  camelCase: resolved.camelCase,
368
+ defaultSchema: resolved.defaultSchema,
219
369
  rootDir: resolved.rootDir,
220
370
  dialect: 'postgres',
221
371
  migrationsDir: resolved.migrationsDir,
@@ -245,21 +395,32 @@ export async function migrateAndCodegen(resolved, options = {}) {
245
395
  };
246
396
  }
247
397
  // ─── SQLite-only operations ───────────────────────────────────────────────────
248
- export async function seed(resolved) {
398
+ /**
399
+ * Apply the dev seed file. Only {@link reset} calls this, immediately after
400
+ * migrating a database it has just wiped, which is what lets a seed file be
401
+ * plain `INSERT`s rather than idempotent ones.
402
+ *
403
+ * `reset` refuses production before it gets here, so this guard is unreachable
404
+ * through the CLI. It stays because the export is reachable without it.
405
+ */
406
+ export async function devSeed(resolved) {
407
+ if (process.env.NODE_ENV === 'production') {
408
+ throw new Error(`pikku dev seed refused: NODE_ENV=production. Seed data is test data — it only runs in dev.`);
409
+ }
249
410
  if (resolved.dialect === 'sqlite') {
250
411
  const runtime = await loadSqliteRuntime();
251
412
  const db = runtime.open(resolved.dbFile);
252
413
  try {
253
- return runSeed(db, resolved.seedFile);
414
+ return runDevSeed(db, resolved.devSeedFile);
254
415
  }
255
416
  finally {
256
417
  db.close();
257
418
  }
258
419
  }
259
- if (!existsSync(resolved.seedFile)) {
420
+ if (!existsSync(resolved.devSeedFile)) {
260
421
  return { applied: false, bytes: 0 };
261
422
  }
262
- const sql = readFileSync(resolved.seedFile, 'utf8');
423
+ const sql = readFileSync(resolved.devSeedFile, 'utf8');
263
424
  if (sql.trim().length === 0) {
264
425
  return { applied: false, bytes: 0 };
265
426
  }
@@ -309,8 +470,7 @@ export async function reset(resolved, rootDir) {
309
470
  AND schema_name NOT LIKE 'pg_temp_%'
310
471
  `);
311
472
  for (const { schema_name: schemaName } of result.rows) {
312
- const quoted = `"${schemaName.replace(/"/g, '""')}"`;
313
- await client.query(`DROP SCHEMA IF EXISTS ${quoted} CASCADE`);
473
+ await client.query(`DROP SCHEMA IF EXISTS ${quoteIdentifier(schemaName)} CASCADE`);
314
474
  }
315
475
  await client.query('CREATE SCHEMA IF NOT EXISTS public');
316
476
  });
@@ -437,7 +597,7 @@ export async function createKysely(resolved) {
437
597
  }
438
598
  mkdirSync(dirname(resolved.pgliteDir), { recursive: true });
439
599
  return createPGliteKysely({
440
- db: await createEmbeddedPostgres(resolved.pgliteDir),
600
+ db: await createEmbeddedPostgres(resolved, resolved.pgliteDir),
441
601
  camelCase: resolved.camelCase,
442
602
  plugins,
443
603
  });
@@ -449,11 +609,22 @@ async function introspectorToMap(intro) {
449
609
  }
450
610
  return map;
451
611
  }
452
- function diffSchemas(desired, actual) {
612
+ /**
613
+ * The tables and columns `desired` has that `actual` does not.
614
+ *
615
+ * `schema` is the one the desired bare names belong in, when the caller knows.
616
+ * Given it, only that schema's copy of a table counts: a `workflow_step` in
617
+ * `public` is a different table from the `app.workflow_step` a source with
618
+ * `db.schema: "app"` wants, and letting it match would report the source
619
+ * satisfied by a table its SQL never creates.
620
+ */
621
+ function diffSchemas(desired, actual, schema) {
453
622
  const missingTables = [];
454
623
  const missingColumns = [];
455
624
  for (const [table, cols] of desired) {
456
- const actualCols = actual.get(table) ?? schemaQualifiedMatch(actual, table);
625
+ const actualCols = schema
626
+ ? actual.get(qualifiedTableKey(schema, table))
627
+ : (actual.get(table) ?? schemaQualifiedMatch(actual, table));
457
628
  if (!actualCols) {
458
629
  missingTables.push(table);
459
630
  continue;
@@ -464,6 +635,19 @@ function diffSchemas(desired, actual) {
464
635
  }
465
636
  return { missingTables, missingColumns };
466
637
  }
638
+ /**
639
+ * How an introspected schema map keys a table in a given schema.
640
+ *
641
+ * Introspection elides `public`, so the key for a table there is the bare name.
642
+ * Anything else carries its qualifier.
643
+ */
644
+ function qualifiedTableKey(schema, table) {
645
+ return schema === 'public' ? table : `${schema}.${table}`;
646
+ }
647
+ /** A PostgreSQL identifier, quoted so its casing survives the parser. */
648
+ function quoteIdentifier(name) {
649
+ return `"${name.replace(/"/g, '""')}"`;
650
+ }
467
651
  /**
468
652
  * The one table in `actual` whose name matches `table` once its schema is
469
653
  * dropped, if there is exactly one.
@@ -493,11 +677,14 @@ function isPostgresAuthDatabase(options) {
493
677
  // target server. Creating a real database via `CREATE DATABASE` would require
494
678
  // elevated privileges that application roles (correctly) don't have, which made
495
679
  // `pikku db migrate` fail against managed/locked-down Postgres (error 42501).
496
- async function withScratchPostgresDatabase(run) {
497
- const scratchDb = await createEmbeddedPostgres();
680
+ async function withScratchPostgresDatabase(context, run) {
681
+ const scratchDb = await createEmbeddedPostgres(context);
498
682
  try {
499
683
  return await run(pgliteAsClient(scratchDb));
500
684
  }
685
+ catch (error) {
686
+ throw explainMissingExtension(error, context.pgliteExtensions);
687
+ }
501
688
  finally {
502
689
  if (!scratchDb.closed) {
503
690
  await scratchDb.close();
@@ -514,8 +701,8 @@ async function postgresDatabaseToMap(client) {
514
701
  await intro.close();
515
702
  }
516
703
  }
517
- async function desiredPostgresAuthSchema(rootDir, srcDirectories, logger) {
518
- return withScratchPostgresDatabase(async (scratchDb) => {
704
+ async function desiredPostgresAuthSchema(context, rootDir, srcDirectories, logger) {
705
+ return withScratchPostgresDatabase(context, async (scratchDb) => {
519
706
  // The scratch DB is always an embedded PGlite instance (see
520
707
  // withScratchPostgresDatabase), so drive Better Auth's migration codegen
521
708
  // through the PGlite-backed Kysely regardless of how the app DB is
@@ -561,7 +748,7 @@ export async function desiredAuthSchema(resolved, rootDir, srcDirectories, logge
561
748
  if (resolved.dialect !== 'postgres') {
562
749
  throw new Error('Better Auth database.type is postgres, but the resolved app database is not postgres.');
563
750
  }
564
- return desiredPostgresAuthSchema(rootDir, srcDirectories, logger);
751
+ return desiredPostgresAuthSchema(resolved, rootDir, srcDirectories, logger);
565
752
  }
566
753
  const { runMigrations, compileMigrations } = await getAuthMigrations(options);
567
754
  await runMigrations();
@@ -648,7 +835,7 @@ export async function desiredRuntimeSchema(resolved, rootDir, srcDirectories, lo
648
835
  db.close();
649
836
  }
650
837
  }
651
- return withScratchPostgresDatabase(async (db) => {
838
+ return withScratchPostgresDatabase(resolved, async (db) => {
652
839
  const kysely = createPGliteKysely({
653
840
  db: db.__pglite,
654
841
  camelCase: true,
@@ -657,7 +844,7 @@ export async function desiredRuntimeSchema(resolved, rootDir, srcDirectories, lo
657
844
  const { tables, schemas, types } = await collect(kysely, () => postgresDatabaseToMap(db));
658
845
  return {
659
846
  tables,
660
- sql: compilePikkuSchemas(kysely, schemas, types),
847
+ sql: compilePikkuSchemas(kysely, schemas, types, resolved.schema),
661
848
  skipped,
662
849
  };
663
850
  }
@@ -699,8 +886,8 @@ async function coveredSqliteSchema(migrationsDir) {
699
886
  db.close();
700
887
  }
701
888
  }
702
- async function coveredPostgresSchema(migrationsDir) {
703
- return withScratchPostgresDatabase(async (client) => {
889
+ async function coveredPostgresSchema(migrationsDir, context) {
890
+ return withScratchPostgresDatabase(context, async (client) => {
704
891
  await migrate(new PostgresMigrationExecutor(client), migrationsDir);
705
892
  return postgresDatabaseToMap(client);
706
893
  });
@@ -727,7 +914,7 @@ async function coveredPostgresSchema(migrationsDir) {
727
914
  export async function computeSchemaDrift(resolved, rootDir, srcDirectories, logger) {
728
915
  const covered = resolved.dialect === 'sqlite'
729
916
  ? await coveredSqliteSchema(resolved.migrationsDir)
730
- : await coveredPostgresSchema(resolved.migrationsDir);
917
+ : await coveredPostgresSchema(resolved.migrationsDir, resolved);
731
918
  const actual = await introspectSchema(resolved);
732
919
  const { missingTables, missingColumns } = diffSchemas(covered, actual);
733
920
  // Compare on the full name. A migration that names no schema lands in
@@ -852,7 +1039,7 @@ const concatMigrations = (migrationsDir) => readdirSync(migrationsDir)
852
1039
  * happens to be configured against — an addon is published once and consumed by
853
1040
  * projects on either engine.
854
1041
  */
855
- export async function exportSchema(rootDir) {
1042
+ export async function exportSchema(rootDir, pgliteExtensions = []) {
856
1043
  const artifact = {};
857
1044
  const sqliteDir = join(rootDir, 'db', 'sqlite');
858
1045
  if (existsSync(sqliteDir)) {
@@ -865,7 +1052,7 @@ export async function exportSchema(rootDir) {
865
1052
  if (existsSync(postgresDir)) {
866
1053
  artifact.postgres = {
867
1054
  sql: concatMigrations(postgresDir),
868
- tables: serializeSchemaMap(await coveredPostgresSchema(postgresDir)),
1055
+ tables: serializeSchemaMap(await coveredPostgresSchema(postgresDir, { rootDir, pgliteExtensions })),
869
1056
  };
870
1057
  }
871
1058
  return artifact;
@@ -938,6 +1125,7 @@ export async function schemaSources(resolved, rootDir, srcDirectories, logger, a
938
1125
  name: 'pikku-runtime',
939
1126
  desired: runtime,
940
1127
  origin: "@pikku/kysely's runtime services",
1128
+ schema: resolved.dialect === 'postgres' ? resolved.schema : undefined,
941
1129
  });
942
1130
  }
943
1131
  sources.push(...(await addonSchemaSources(rootDir, resolved.dialect, addons, logger)));
@@ -1005,15 +1193,31 @@ export async function generateMigrations(resolved, rootDir, srcDirectories, logg
1005
1193
  // is part of what the next one is compared against.
1006
1194
  const covered = resolved.dialect === 'sqlite'
1007
1195
  ? await coveredSqliteSchema(resolved.migrationsDir)
1008
- : await coveredPostgresSchema(resolved.migrationsDir);
1009
- const { missingTables, missingColumns } = diffSchemas(source.desired.tables, covered);
1196
+ : await coveredPostgresSchema(resolved.migrationsDir, resolved);
1197
+ const { missingTables, missingColumns } = diffSchemas(source.desired.tables, covered, source.schema);
1010
1198
  if (missingTables.length === 0 && missingColumns.length === 0) {
1011
1199
  result.upToDate.push(source.name);
1012
1200
  continue;
1013
1201
  }
1014
- const partial = [...source.desired.tables.keys()].some((t) => covered.has(t));
1202
+ // Matched the same way `diffSchemas` matches, qualifier and all. A project
1203
+ // that keeps its tables in a schema has them covered as `app.workflow_step`
1204
+ // while the declaration names them bare, so a strict `covered.has(t)` reads
1205
+ // "nothing is covered" and re-emits the whole schema over tables that are
1206
+ // already there — and a copy in some other schema is not that table, so it
1207
+ // must not count either.
1208
+ const partial = [...source.desired.tables.keys()].some((t) => source.schema
1209
+ ? covered.has(qualifiedTableKey(source.schema, t))
1210
+ : covered.has(t) || schemaQualifiedMatch(covered, t) !== undefined);
1015
1211
  let body;
1016
1212
  let needsBackfill = [];
1213
+ // The source's own SQL is already qualified when it can be; the delta below
1214
+ // is written here from bare introspected names, so it has to be qualified
1215
+ // to match, or it alters a table in whichever schema `search_path` finds.
1216
+ // Quoted, because the compiled SQL this delta has to line up with goes
1217
+ // through the schema builder and is quoted there. `db.schema: "App"` left
1218
+ // raw folds to `app`, so the delta would alter a table in a schema the
1219
+ // runtime never uses.
1220
+ const qualify = (table) => source.schema ? `${quoteIdentifier(source.schema)}.${table}` : table;
1017
1221
  if (!partial) {
1018
1222
  body = source.desired.sql;
1019
1223
  }
@@ -1034,7 +1238,7 @@ export async function generateMigrations(resolved, rootDir, srcDirectories, logg
1034
1238
  statements.push(`-- REVIEW: ${table} is new, and its CREATE TABLE could not be found in the\n` +
1035
1239
  `-- source's own SQL. The column list below carries no indexes, constraints\n` +
1036
1240
  `-- or foreign keys — copy the real statement over it before applying.\n` +
1037
- `CREATE TABLE ${table} (\n` +
1241
+ `CREATE TABLE ${qualify(table)} (\n` +
1038
1242
  [...(columns?.values() ?? [])]
1039
1243
  .map((c) => ` ${c.name} ${c.type}${c.notNull ? ' NOT NULL' : ''}`)
1040
1244
  .join(',\n') +
@@ -1044,7 +1248,7 @@ export async function generateMigrations(resolved, rootDir, srcDirectories, logg
1044
1248
  const infos = columns
1045
1249
  .map((name) => source.desired.tables.get(table)?.get(name))
1046
1250
  .filter((c) => c !== undefined);
1047
- const added = addColumnStatements(table, infos);
1251
+ const added = addColumnStatements(qualify(table), infos);
1048
1252
  statements.push(...added.sql);
1049
1253
  needsBackfill.push(...added.needsBackfill);
1050
1254
  }
@@ -0,0 +1,12 @@
1
+ import type { SyncSqliteDatabase } from './sqlite-runtime.js';
2
+ export interface DevSeedResult {
3
+ applied: boolean;
4
+ bytes: number;
5
+ }
6
+ /**
7
+ * Apply db/<engine>-dev-seed.sql to the open db. Only `pikku db reset` reaches
8
+ * here, against a database it has just wiped and migrated, so the file may be
9
+ * plain `INSERT`s — it is never applied twice. Returns `applied: false` if the
10
+ * file doesn't exist; throws on SQL errors.
11
+ */
12
+ export declare function devSeed(db: SyncSqliteDatabase, devSeedFile: string): DevSeedResult;
@@ -0,0 +1,23 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ /**
3
+ * Apply db/<engine>-dev-seed.sql to the open db. Only `pikku db reset` reaches
4
+ * here, against a database it has just wiped and migrated, so the file may be
5
+ * plain `INSERT`s — it is never applied twice. Returns `applied: false` if the
6
+ * file doesn't exist; throws on SQL errors.
7
+ */
8
+ export function devSeed(db, devSeedFile) {
9
+ if (!existsSync(devSeedFile)) {
10
+ return { applied: false, bytes: 0 };
11
+ }
12
+ const raw = readFileSync(devSeedFile);
13
+ db.exec('BEGIN');
14
+ try {
15
+ db.exec(raw.toString('utf8'));
16
+ db.exec('COMMIT');
17
+ }
18
+ catch (err) {
19
+ db.exec('ROLLBACK');
20
+ throw err;
21
+ }
22
+ return { applied: true, bytes: raw.length };
23
+ }
@@ -30,7 +30,7 @@ class BunSqliteDatabase {
30
30
  }
31
31
  exec(sql) {
32
32
  // bun:sqlite throws "no valid SQL statement" on comment-only/empty input
33
- // (e.g. a placeholder seed.sql); node:sqlite silently no-ops. Match node's
33
+ // (e.g. a placeholder dev-seed.sql); node:sqlite silently no-ops. Match node's
34
34
  // tolerance by skipping when nothing executable remains after stripping
35
35
  // comments. The original `sql` is still exec'd verbatim when non-empty.
36
36
  const executable = sql
@@ -0,0 +1,19 @@
1
+ import type { ValidateFinding } from './persona-checks.js';
2
+ type PackageManifest = {
3
+ scripts?: Record<string, string>;
4
+ dependencies?: Record<string, string>;
5
+ devDependencies?: Record<string, string>;
6
+ };
7
+ /**
8
+ * Reports a root `start`/`dev` script that boots a server Pikku does not own.
9
+ *
10
+ * Services built in a hand-rolled entrypoint never reach the
11
+ * `pikkuServerLifecycle` hooks, so startup and shutdown work silently does not
12
+ * run. A project depending on a runtime adapter has opted into owning its own
13
+ * server, and a script that delegates to another runner cannot be followed, so
14
+ * neither is reported.
15
+ */
16
+ export declare function runBootstrapChecks(root: string, rootPkg: PackageManifest | null, pikkuConfig: {
17
+ lint?: unknown;
18
+ } | null): Promise<ValidateFinding[]>;
19
+ export {};