@pikku/cli 0.12.160 → 0.12.163

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 (262) hide show
  1. package/console-app/assets/{HelpPanel-C06T226y.js → HelpPanel-C__s-OXa.js} +1 -1
  2. package/console-app/assets/{abnfDiagram-VCTEODGH-BVwdT3Es.js → abnfDiagram-VCTEODGH-DLIFOOvF.js} +1 -1
  3. package/console-app/assets/architecture-7GRP2DOG-C3aOtis2.js +1 -0
  4. package/console-app/assets/{architectureDiagram-5GKGNRK7-XfzqZ3mW.js → architectureDiagram-5GKGNRK7-DTilS9zr.js} +1 -1
  5. package/console-app/assets/{blockDiagram-I7D4REHJ-B5omSqDK.js → blockDiagram-I7D4REHJ-CCTMqaSo.js} +1 -1
  6. package/console-app/assets/{c4Diagram-7LVT6UL2-DkPe7xCg.js → c4Diagram-7LVT6UL2-HTxceuVS.js} +1 -1
  7. package/console-app/assets/channel-C9rJmzgz.js +1 -0
  8. package/console-app/assets/{chunk-4HAMMTFA-QfSXT_X7.js → chunk-4HAMMTFA-CB4W3eSt.js} +1 -1
  9. package/console-app/assets/{chunk-75Z2AOVW-h7UnPWNo.js → chunk-75Z2AOVW-C9TP1VXB.js} +1 -1
  10. package/console-app/assets/{chunk-DU6HZSFF-VaMy-LOI.js → chunk-DU6HZSFF-84ww5mPe.js} +1 -1
  11. package/console-app/assets/{chunk-F27PBJKO-toywqOqS.js → chunk-F27PBJKO-B6nEGqlt.js} +1 -1
  12. package/console-app/assets/{chunk-GMAD6QVW-Cpa-YKLB.js → chunk-GMAD6QVW-SJ1Qwv1p.js} +1 -1
  13. package/console-app/assets/{chunk-GVQU2GXP-BWSHPLNL.js → chunk-GVQU2GXP-CpvfZAir.js} +1 -1
  14. package/console-app/assets/{chunk-IMKFNOWR-yhQzfQuj.js → chunk-IMKFNOWR-CdZpInOk.js} +1 -1
  15. package/console-app/assets/{chunk-L3NEJ4N5-C8pAfDlo.js → chunk-L3NEJ4N5-DDwTgcch.js} +1 -1
  16. package/console-app/assets/{chunk-OSK3NFVY-749yk2fa.js → chunk-OSK3NFVY-Ce8laAeV.js} +1 -1
  17. package/console-app/assets/{chunk-P2QGCYS3-C1Y9GyYT.js → chunk-P2QGCYS3-CfBNms3b.js} +1 -1
  18. package/console-app/assets/{chunk-POPQ4Y6H-DzI9aRsX.js → chunk-POPQ4Y6H-BZI0KZav.js} +1 -1
  19. package/console-app/assets/{chunk-PWAF6VOD-D3fAPSwz.js → chunk-PWAF6VOD-Car_F-5i.js} +1 -1
  20. package/console-app/assets/{chunk-SHT3W25Y-D9w7LzM9.js → chunk-SHT3W25Y-B7o3qSVw.js} +1 -1
  21. package/console-app/assets/{chunk-SVP7TREG-D55MjOJw.js → chunk-SVP7TREG-8bi0TugS.js} +1 -1
  22. package/console-app/assets/{chunk-TICWLB2K-DV8q7H-z.js → chunk-TICWLB2K-BT94BHEH.js} +1 -1
  23. package/console-app/assets/chunk-XXDRQBXY-CN-XariJ.js +1 -0
  24. package/console-app/assets/classDiagram-ZZMXUADV-C-G692c4.js +1 -0
  25. package/console-app/assets/classDiagram-v2-VYDZK3BY-C-G692c4.js +1 -0
  26. package/console-app/assets/{cose-bilkent-JH36ORCC-CLedPW9a.js → cose-bilkent-JH36ORCC-Bpn1bn9K.js} +1 -1
  27. package/console-app/assets/{cynefin-OW5HDTMX-CS5NKw2p.js → cynefin-OW5HDTMX-CfFkO8xq.js} +1 -1
  28. package/console-app/assets/{cynefinDiagram-5FMLGOSQ-DGTHW90E.js → cynefinDiagram-5FMLGOSQ-E66AVAFL.js} +1 -1
  29. package/console-app/assets/{dagre-BNQdos_2.js → dagre-54kLhRyV.js} +1 -1
  30. package/console-app/assets/{dagre-GXQ25YYZ-DHZ8wtwQ.js → dagre-GXQ25YYZ-D4En0mXW.js} +1 -1
  31. package/console-app/assets/{diagram-S7CK7UJ4-C41Begsy.js → diagram-S7CK7UJ4-DhFYC_I5.js} +1 -1
  32. package/console-app/assets/{diagram-UQ7AKVKN-CU8D-sRT.js → diagram-UQ7AKVKN-QV1teZ2Z.js} +1 -1
  33. package/console-app/assets/{diagram-VSXAHHWV-DTTiXYnQ.js → diagram-VSXAHHWV-CTZbzeS4.js} +1 -1
  34. package/console-app/assets/{diagram-VX7I27RA-BBy91pxm.js → diagram-VX7I27RA-BFoMlx0h.js} +1 -1
  35. package/console-app/assets/{diagram-Z3DM3KII-D50xTYe5.js → diagram-Z3DM3KII-DXYj_9Q8.js} +1 -1
  36. package/console-app/assets/{ebnfDiagram-PWID7BFC-BHjnFZgE.js → ebnfDiagram-PWID7BFC-C7TLD6M3.js} +1 -1
  37. package/console-app/assets/{erDiagram-RLTQ6QDP-B4-yVo9b.js → erDiagram-RLTQ6QDP-hPkM-ewN.js} +1 -1
  38. package/console-app/assets/eventmodeling-NTZA5JFV-U-EsOY6h.js +1 -0
  39. package/console-app/assets/flowDiagram-HODETNUW-LmjHrpKd.js +1 -0
  40. package/console-app/assets/{ganttDiagram-EL5Y4UJY-D1T-2BlO.js → ganttDiagram-EL5Y4UJY-B6TmOQZX.js} +1 -1
  41. package/console-app/assets/{gitGraph-4MIJSDKK-ClqKTUfQ.js → gitGraph-4MIJSDKK-BwbHr20B.js} +1 -1
  42. package/console-app/assets/{gitGraphDiagram-WWUBYQGX-ruq2MAhM.js → gitGraphDiagram-WWUBYQGX-Dl1TcmWc.js} +1 -1
  43. package/console-app/assets/{graphlib-D-vLYPdw.js → graphlib-DHZpPJUN.js} +1 -1
  44. package/console-app/assets/{index-BIEZPuyK.js → index-BzStIuLU.js} +137 -137
  45. package/console-app/assets/{info-A6RAGUB7-BGI-8HNB.js → info-A6RAGUB7-D708VGlV.js} +1 -1
  46. package/console-app/assets/{infoDiagram-27XIBGKW-BGURgKHv.js → infoDiagram-27XIBGKW-UHD7ySe3.js} +1 -1
  47. package/console-app/assets/{ishikawaDiagram-5VMMS53U-DzgAaPTR.js → ishikawaDiagram-5VMMS53U-GyFZr765.js} +1 -1
  48. package/console-app/assets/{journeyDiagram-3NMN7TZE-BsyWad8z.js → journeyDiagram-3NMN7TZE-CoewHpEg.js} +1 -1
  49. package/console-app/assets/{kanban-definition-UXKFOSKX-g1nO2rWF.js → kanban-definition-UXKFOSKX-F0W6Aec5.js} +1 -1
  50. package/console-app/assets/{line-CeFoQ5y-.js → line-C4wYKh6f.js} +1 -1
  51. package/console-app/assets/{linear-C4Pk-YMX.js → linear-nPQacEjt.js} +1 -1
  52. package/console-app/assets/{mermaid-parser.core-U7wquvx8.js → mermaid-parser.core-BVBt0Hmw.js} +3 -3
  53. package/console-app/assets/{mermaid.core-8TRpFRm9.js → mermaid.core-BMrHbMBm.js} +4 -4
  54. package/console-app/assets/{mindmap-definition-YA3MSWOX-C7lzwqBX.js → mindmap-definition-YA3MSWOX-Dhdn4hmh.js} +1 -1
  55. package/console-app/assets/{packet-AYTQ26CC-DiQV_rU3.js → packet-AYTQ26CC-CleVGuC-.js} +1 -1
  56. package/console-app/assets/{pegDiagram-XKGWAZYB-63ajP7-W.js → pegDiagram-XKGWAZYB-NDJ5URs9.js} +1 -1
  57. package/console-app/assets/{pie-WAS4IAKB-B5q_o6dr.js → pie-WAS4IAKB-DCgq6z8V.js} +1 -1
  58. package/console-app/assets/{pieDiagram-E7YTZNPT-BTbvj-by.js → pieDiagram-E7YTZNPT-BPo__c-e.js} +1 -1
  59. package/console-app/assets/{quadrantDiagram-AXDQQJYC-CulqsAYd.js → quadrantDiagram-AXDQQJYC-C6AlGJWn.js} +1 -1
  60. package/console-app/assets/{radar-RG4KPBEZ-CW_KoURS.js → radar-RG4KPBEZ-iKELPo6S.js} +1 -1
  61. package/console-app/assets/{railroad-74A4TZTK-CUmF6uBQ.js → railroad-74A4TZTK-D7o-4Y2z.js} +1 -1
  62. package/console-app/assets/railroad-abnf-HS5TGJTU-SJ0ZNV52.js +1 -0
  63. package/console-app/assets/railroad-ebnf-LZEXJU2U-CoxgM6s2.js +1 -0
  64. package/console-app/assets/railroad-peg-WCYAUIDC-Dt1jr0ie.js +1 -0
  65. package/console-app/assets/{railroadDiagram-O6MQD6OU-WlkBu_N3.js → railroadDiagram-O6MQD6OU-Bxb416Ip.js} +1 -1
  66. package/console-app/assets/{requirementDiagram-BXWQKSXE-CJK_CbPR.js → requirementDiagram-BXWQKSXE-wpPz84xe.js} +1 -1
  67. package/console-app/assets/{sankeyDiagram-P5KCCOFB-C466WOH8.js → sankeyDiagram-P5KCCOFB-DCtqI-U8.js} +1 -1
  68. package/console-app/assets/{sequenceDiagram-WJ2MYXX4-CV0dCcj0.js → sequenceDiagram-WJ2MYXX4-B9qErfQU.js} +1 -1
  69. package/console-app/assets/{src-P4Nw8sY0.js → src-CrUEtLgb.js} +1 -1
  70. package/console-app/assets/{stateDiagram-D77RDMKH-HaLGm8V9.js → stateDiagram-D77RDMKH-DVQO4UZZ.js} +1 -1
  71. package/console-app/assets/stateDiagram-v2-MP3YSRHH-qOQfgOOB.js +1 -0
  72. package/console-app/assets/{swimlanes-42K2YHIH-Bi-O5vWa.js → swimlanes-42K2YHIH-CfBqlUg-.js} +1 -1
  73. package/console-app/assets/swimlanesDiagram-VR7AAH4N-D6fTU5Cq.js +8 -0
  74. package/console-app/assets/{timeline-definition-24CTP7MA-B4h-gx-i.js → timeline-definition-24CTP7MA-CPFn_B-h.js} +1 -1
  75. package/console-app/assets/{treeView-Q6P3EWNA-CXJ_pHQw.js → treeView-Q6P3EWNA-CVWAH-EI.js} +1 -1
  76. package/console-app/assets/{treemap-WGGIJYW6-M84p2a_3.js → treemap-WGGIJYW6-DEBgfaYx.js} +1 -1
  77. package/console-app/assets/{vennDiagram-4TSXK5OY-BesF4k_r.js → vennDiagram-4TSXK5OY-BA4GGrwY.js} +1 -1
  78. package/console-app/assets/{wardley-WFR3VGLG-n9ulickP.js → wardley-WFR3VGLG-TajUo-aF.js} +1 -1
  79. package/console-app/assets/{wardleyDiagram-VM6X3IG4-BG0nnWDf.js → wardleyDiagram-VM6X3IG4-Bd1y8DdK.js} +1 -1
  80. package/console-app/assets/{xychartDiagram-S5SC5T6Z-BtOW7fpF.js → xychartDiagram-S5SC5T6Z-CWQmkOFg.js} +1 -1
  81. package/console-app/index.html +1 -1
  82. package/dist/.pikku/addon/index.d.ts +1 -1
  83. package/dist/.pikku/addon/index.js +1 -1
  84. package/dist/.pikku/addon/pikku-addon-types.gen.d.ts +1 -1
  85. package/dist/.pikku/addon/pikku-addon-types.gen.js +1 -1
  86. package/dist/.pikku/agent/index.d.ts +1 -1
  87. package/dist/.pikku/agent/index.js +1 -1
  88. package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +1 -1
  89. package/dist/.pikku/agent/pikku-model-aliases.gen.js +1 -1
  90. package/dist/.pikku/analytics/index.d.ts +1 -1
  91. package/dist/.pikku/analytics/index.js +1 -1
  92. package/dist/.pikku/analytics/pikku-analytics-types.gen.d.ts +1 -1
  93. package/dist/.pikku/analytics/pikku-analytics-types.gen.js +1 -1
  94. package/dist/.pikku/auth/index.d.ts +1 -1
  95. package/dist/.pikku/auth/index.js +1 -1
  96. package/dist/.pikku/auth/pikku-auth-types.gen.d.ts +1 -1
  97. package/dist/.pikku/auth/pikku-auth-types.gen.js +1 -1
  98. package/dist/.pikku/channel/index.d.ts +1 -1
  99. package/dist/.pikku/channel/index.js +1 -1
  100. package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +1 -1
  101. package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
  102. package/dist/.pikku/cli/index.d.ts +1 -1
  103. package/dist/.pikku/cli/index.js +1 -1
  104. package/dist/.pikku/cli/pikku-cli-channel.js +1 -1
  105. package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +1 -1
  106. package/dist/.pikku/cli/pikku-cli-client.gen.js +1 -1
  107. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.d.ts +1 -1
  108. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.js +1 -1
  109. package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +1 -1
  110. package/dist/.pikku/cli/pikku-cli-types.gen.js +1 -1
  111. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +1 -1
  112. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.json +20 -2
  113. package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
  114. package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
  115. package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
  116. package/dist/.pikku/cli/pikku-cli.gen.js +1 -1
  117. package/dist/.pikku/error/index.d.ts +1 -1
  118. package/dist/.pikku/error/index.js +1 -1
  119. package/dist/.pikku/error/pikku-error-types.gen.d.ts +1 -1
  120. package/dist/.pikku/error/pikku-error-types.gen.js +1 -1
  121. package/dist/.pikku/function/index.d.ts +1 -1
  122. package/dist/.pikku/function/index.js +1 -1
  123. package/dist/.pikku/function/pikku-function-types.gen.d.ts +1 -1
  124. package/dist/.pikku/function/pikku-function-types.gen.js +1 -1
  125. package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
  126. package/dist/.pikku/function/pikku-functions-meta.gen.json +16 -16
  127. package/dist/.pikku/function/pikku-functions.gen.js +1 -1
  128. package/dist/.pikku/gateway/index.d.ts +1 -1
  129. package/dist/.pikku/gateway/index.js +1 -1
  130. package/dist/.pikku/gateway/pikku-gateway-types.gen.d.ts +1 -1
  131. package/dist/.pikku/gateway/pikku-gateway-types.gen.js +1 -1
  132. package/dist/.pikku/http/index.d.ts +1 -1
  133. package/dist/.pikku/http/index.js +1 -1
  134. package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
  135. package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
  136. package/dist/.pikku/mcp/index.d.ts +1 -1
  137. package/dist/.pikku/mcp/index.js +1 -1
  138. package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
  139. package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
  140. package/dist/.pikku/middleware/index.d.ts +1 -1
  141. package/dist/.pikku/middleware/index.js +1 -1
  142. package/dist/.pikku/middleware/pikku-middleware-types.gen.d.ts +1 -1
  143. package/dist/.pikku/middleware/pikku-middleware-types.gen.js +1 -1
  144. package/dist/.pikku/pikku-bootstrap-scenarios.gen.d.ts +1 -1
  145. package/dist/.pikku/pikku-bootstrap-scenarios.gen.js +1 -1
  146. package/dist/.pikku/pikku-bootstrap.gen.d.ts +1 -1
  147. package/dist/.pikku/pikku-bootstrap.gen.js +1 -1
  148. package/dist/.pikku/pikku-services.gen.d.ts +1 -1
  149. package/dist/.pikku/queue/index.d.ts +1 -1
  150. package/dist/.pikku/queue/index.js +1 -1
  151. package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
  152. package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
  153. package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +1 -1
  154. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
  155. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
  156. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +1 -1
  157. package/dist/.pikku/scenarios/index.d.ts +1 -1
  158. package/dist/.pikku/scenarios/index.js +1 -1
  159. package/dist/.pikku/scenarios/pikku-personas.gen.js +1 -1
  160. package/dist/.pikku/scenarios/pikku-scenario-functions-meta.gen.js +1 -1
  161. package/dist/.pikku/scenarios/pikku-scenario-functions.gen.d.ts +1 -1
  162. package/dist/.pikku/scenarios/pikku-scenario-types.gen.d.ts +1 -1
  163. package/dist/.pikku/scenarios/pikku-scenario-wirings-meta.gen.js +1 -1
  164. package/dist/.pikku/scenarios/pikku-scenario-wirings.gen.d.ts +1 -1
  165. package/dist/.pikku/scenarios/schemas/register.gen.d.ts +1 -1
  166. package/dist/.pikku/scenarios/schemas/register.gen.js +1 -1
  167. package/dist/.pikku/scheduler/index.d.ts +1 -1
  168. package/dist/.pikku/scheduler/index.js +1 -1
  169. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
  170. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
  171. package/dist/.pikku/schemas/register.gen.js +1 -1
  172. package/dist/.pikku/schemas/schemas/KnowledgePlanProgressOutput.schema.json +1 -1
  173. package/dist/.pikku/schemas/schemas/KnowledgePlanSetOutput.schema.json +1 -1
  174. package/dist/.pikku/schemas/schemas/KnowledgePlanShowOutput.schema.json +1 -1
  175. package/dist/.pikku/schemas/schemas/PikkuNewAddonInput.schema.json +1 -1
  176. package/dist/.pikku/scopes/index.d.ts +1 -1
  177. package/dist/.pikku/scopes/index.js +1 -1
  178. package/dist/.pikku/scopes/pikku-flags.gen.d.ts +1 -1
  179. package/dist/.pikku/scopes/pikku-personas.gen.js +1 -1
  180. package/dist/.pikku/scopes/pikku-roles.gen.d.ts +1 -1
  181. package/dist/.pikku/scopes/pikku-scope-types.gen.d.ts +1 -1
  182. package/dist/.pikku/scopes/pikku-scope-types.gen.js +1 -1
  183. package/dist/.pikku/scopes/pikku-scopes.gen.d.ts +1 -1
  184. package/dist/.pikku/secrets/index.d.ts +1 -1
  185. package/dist/.pikku/secrets/index.js +1 -1
  186. package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +1 -1
  187. package/dist/.pikku/secrets/pikku-secret-types.gen.js +1 -1
  188. package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +1 -1
  189. package/dist/.pikku/secrets/pikku-secrets.gen.js +1 -1
  190. package/dist/.pikku/services/pikku-meta-service.gen.d.ts +1 -1
  191. package/dist/.pikku/services/pikku-meta-service.gen.js +1 -1
  192. package/dist/.pikku/setup/index.d.ts +1 -1
  193. package/dist/.pikku/setup/index.js +1 -1
  194. package/dist/.pikku/setup/pikku-setup-types.gen.d.ts +1 -1
  195. package/dist/.pikku/setup/pikku-setup-types.gen.js +1 -1
  196. package/dist/.pikku/trigger/index.d.ts +1 -1
  197. package/dist/.pikku/trigger/index.js +1 -1
  198. package/dist/.pikku/trigger/pikku-trigger-types.gen.d.ts +1 -1
  199. package/dist/.pikku/trigger/pikku-trigger-types.gen.js +1 -1
  200. package/dist/.pikku/variables/index.d.ts +1 -1
  201. package/dist/.pikku/variables/index.js +1 -1
  202. package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +1 -1
  203. package/dist/.pikku/variables/pikku-variable-types.gen.js +1 -1
  204. package/dist/.pikku/variables/pikku-variables.gen.d.ts +1 -1
  205. package/dist/.pikku/variables/pikku-variables.gen.js +1 -1
  206. package/dist/.pikku/workflow/index.d.ts +1 -1
  207. package/dist/.pikku/workflow/index.js +1 -1
  208. package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +1 -1
  209. package/dist/.pikku/workflow/pikku-workflow-types.gen.js +1 -1
  210. package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +1 -1
  211. package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +1 -1
  212. package/dist/bin/pikku-bin.mjs +2 -2
  213. package/dist/src/cli.wiring.js +20 -2
  214. package/dist/src/deploy/analyzer/analyzer.js +7 -1
  215. package/dist/src/functions/commands/dev-credentials.d.ts +18 -0
  216. package/dist/src/functions/commands/dev-credentials.js +59 -0
  217. package/dist/src/functions/commands/dev.js +11 -2
  218. package/dist/src/functions/commands/install-addon.d.ts +45 -0
  219. package/dist/src/functions/commands/install-addon.js +225 -0
  220. package/dist/src/functions/commands/knowledge-plan.d.ts +9 -0
  221. package/dist/src/functions/commands/knowledge-plan.js +13 -3
  222. package/dist/src/functions/commands/new-addon.d.ts +47 -1
  223. package/dist/src/functions/commands/new-addon.js +284 -106
  224. package/dist/src/functions/commands/serve.js +7 -2
  225. package/dist/src/functions/db/better-auth-schema.d.ts +1 -0
  226. package/dist/src/functions/db/better-auth-schema.js +75 -2
  227. package/dist/src/functions/db/ensure-db-types.d.ts +12 -0
  228. package/dist/src/functions/db/ensure-db-types.js +29 -0
  229. package/dist/src/functions/knowledge/console-url.d.ts +13 -0
  230. package/dist/src/functions/knowledge/console-url.js +18 -0
  231. package/dist/src/functions/knowledge/render.d.ts +7 -3
  232. package/dist/src/functions/knowledge/render.js +10 -3
  233. package/dist/src/functions/knowledge/schemas.d.ts +3 -0
  234. package/dist/src/functions/knowledge/schemas.js +4 -3
  235. package/dist/src/functions/surface/collect-snippets.d.ts +1 -13
  236. package/dist/src/functions/surface/collect-snippets.js +1 -83
  237. package/dist/src/functions/validate/type-identity-checks.d.ts +3 -2
  238. package/dist/src/functions/validate/type-identity-checks.js +74 -5
  239. package/dist/src/functions/validate/validate-registry.js +3 -3
  240. package/dist/src/functions/wirings/auth/serialize-auth-gen.js +33 -1
  241. package/dist/src/functions/wirings/functions/serialize-addon-types.js +4 -2
  242. package/dist/src/functions/wirings/rpc/pikku-command-react-query.js +3 -2
  243. package/dist/src/functions/wirings/rpc/serialize-react-query-hooks.d.ts +1 -1
  244. package/dist/src/functions/wirings/rpc/serialize-react-query-hooks.js +60 -3
  245. package/dist/src/functions/workflows/all.workflow.js +7 -1
  246. package/dist/tsconfig.tsbuildinfo +1 -1
  247. package/package.json +10 -10
  248. package/snippets-meta.json +1 -0
  249. package/snippets.json +1 -0
  250. package/surface.json +37 -3
  251. package/console-app/assets/architecture-7GRP2DOG-3y7bWtag.js +0 -1
  252. package/console-app/assets/channel-CTiluQVw.js +0 -1
  253. package/console-app/assets/chunk-XXDRQBXY-DBtYQykd.js +0 -1
  254. package/console-app/assets/classDiagram-ZZMXUADV-BnWa-i9n.js +0 -1
  255. package/console-app/assets/classDiagram-v2-VYDZK3BY-BnWa-i9n.js +0 -1
  256. package/console-app/assets/eventmodeling-NTZA5JFV-C_IpFSCw.js +0 -1
  257. package/console-app/assets/flowDiagram-HODETNUW-Q90rgVpx.js +0 -1
  258. package/console-app/assets/railroad-abnf-HS5TGJTU-CcPw9q8a.js +0 -1
  259. package/console-app/assets/railroad-ebnf-LZEXJU2U-Ci_fZics.js +0 -1
  260. package/console-app/assets/railroad-peg-WCYAUIDC-DTsDykSf.js +0 -1
  261. package/console-app/assets/stateDiagram-v2-MP3YSRHH--GM14Hz5.js +0 -1
  262. package/console-app/assets/swimlanesDiagram-VR7AAH4N-_6rRi6Wt.js +0 -8
@@ -5,7 +5,8 @@ import { spawnSync } from 'node:child_process';
5
5
  import { findInstallRoot } from './update.js';
6
6
  import { createEmptyManifest, saveManifest, } from '../../utils/contract-versions.js';
7
7
  import { pikkuSessionlessFunc } from '#pikku/function';
8
- import { parseOpenAPISpec, computeContractHash, generateAddonFromOpenAPI, loadAuthConfig, } from '@pikku/openapi-parser';
8
+ import { parseOpenAPISpec, computeContractHash, detectLoginOperation, filterOperations, generateAddonFromOpenAPI, loadAuthConfig, specCoverageWarning, } from '@pikku/openapi-parser';
9
+ import { installAddonIntoApp } from './install-addon.js';
9
10
  /**
10
11
  * Pick the protocol the generated test app uses to depend on its parent addon.
11
12
  *
@@ -128,6 +129,27 @@ const literal = (value) => JSON.stringify(value);
128
129
  const inTemplate = (value) => value.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\$\{/g, '\\${');
129
130
  /** The same prose on a `//` comment line, where a newline ends the comment. */
130
131
  const inComment = (value) => value.replace(/\s+/g, ' ').trim();
132
+ const CREDENTIAL_SHAPES = {
133
+ apikey: '{ apiKey: string }',
134
+ bearer: '{ token: string }',
135
+ basic: '{ username: string; password: string }',
136
+ };
137
+ const CREDENTIAL_FIELDS = { apikey: 'apiKey', bearer: 'token' };
138
+ const ICON_COLOURS = [
139
+ '#2563eb',
140
+ '#7c3aed',
141
+ '#db2777',
142
+ '#ea580c',
143
+ '#16a34a',
144
+ '#0891b2',
145
+ ];
146
+ function placeholderIcon(displayName) {
147
+ const letter = (displayName.match(/[A-Za-z0-9]/)?.[0] ?? '?').toUpperCase();
148
+ const colour = ICON_COLOURS[[...displayName].reduce((sum, c) => sum + c.charCodeAt(0), 0) %
149
+ ICON_COLOURS.length];
150
+ return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect width="64" height="64" rx="14" fill="${colour}"/><text x="32" y="43" font-family="system-ui, sans-serif" font-size="30" font-weight="600" fill="#fff" text-anchor="middle">${letter}</text></svg>
151
+ `;
152
+ }
131
153
  export function getAddonFiles(vars, flags) {
132
154
  const { name, camelName, pascalName, screamingName, displayName, description, category, } = vars;
133
155
  const files = {};
@@ -183,14 +205,15 @@ export function getAddonFiles(vars, flags) {
183
205
  tsconfig: './tsconfig.json',
184
206
  srcDirectories: ['src', 'types'],
185
207
  outDir: './.pikku',
186
- addon: true,
187
- node: {
208
+ addon: {
188
209
  displayName,
189
210
  description,
190
211
  categories: [category],
191
212
  icon: `./${name}.svg`,
192
213
  },
214
+ forceRequiredServices: [camelName],
193
215
  }, null, 2);
216
+ files[`${name}.svg`] = placeholderIcon(displayName);
194
217
  // tsconfig.json
195
218
  files['tsconfig.json'] = JSON.stringify({
196
219
  compilerOptions: {
@@ -222,7 +245,7 @@ ${description}
222
245
 
223
246
  ## Setup
224
247
 
225
- 1. Add icon SVG at \`${name}.svg\`
248
+ 1. Replace the placeholder icon at \`${name}.svg\`
226
249
  2. Update secret schema with required fields
227
250
  3. Implement API service methods
228
251
  4. Create function files for each operation
@@ -234,11 +257,7 @@ ${description}
234
257
  // export { ${camelName}Operation } from './functions/operation.function.js'
235
258
  `;
236
259
  // src/services.ts
237
- if (flags.delegated) {
238
- // Delegated login: the credential is the upstream token captured at
239
- // sign-in; an expired token is the re-auth signal (UnauthorizedError).
240
- files['src/services.ts'] =
241
- `import { UnauthorizedError } from '@pikku/core/errors'
260
+ const wireCredential = (shape, check, missing, extra = '') => `import { ${missing.startsWith('new MissingCredentialError') ? 'MissingCredentialError' : 'CredentialRejectedError'} } from '@pikku/core/errors'
242
261
  import { ${pascalName}Service } from './${name}-api.service.js'
243
262
  import { pikkuAddonWireServices } from '#pikku/addon/setup'
244
263
 
@@ -247,67 +266,36 @@ export const createWireServices = pikkuAddonWireServices(
247
266
  if (!wire.getCredential) {
248
267
  throw new Error('Credential resolution is not available in this runtime')
249
268
  }
250
- const cred = await wire.getCredential<{ token: string; expiresAt?: number }>('${camelName}')
251
- if (!cred?.token) {
252
- throw new UnauthorizedError(${literal(`No ${displayName} session — sign in again`)})
253
- }
254
- if (cred.expiresAt && cred.expiresAt * 1000 < Date.now()) {
255
- throw new UnauthorizedError(${literal(`${displayName} session expired — sign in again`)})
256
- }
269
+ const cred = await wire.getCredential<${shape}>('${camelName}')
270
+ if (!${check}) {
271
+ throw ${missing}
272
+ }${extra}
257
273
  const ${camelName} = new ${pascalName}Service(cred, variables)
258
274
 
259
275
  return { ${camelName} }
260
276
  }
261
277
  )
262
278
  `;
279
+ if (flags.delegated) {
280
+ // Delegated login: the credential is the upstream token captured at
281
+ // sign-in, so a missing or expired one means signing in again.
282
+ files['src/services.ts'] = wireCredential('{ token: string; expiresAt?: number }', 'cred?.token', `new CredentialRejectedError('${camelName}', 'sign-in', ${literal(`No ${displayName} session — sign in again`)})`, `
283
+ if (cred.expiresAt && cred.expiresAt * 1000 < Date.now()) {
284
+ throw new CredentialRejectedError('${camelName}', 'sign-in', ${literal(`${displayName} session expired — sign in again`)})
285
+ }`);
263
286
  }
264
287
  else if (flags.credential && flags.credential !== 'oauth2') {
265
- // Per-user credential: use createWireServices with wire.getCredential()
266
- const credField = flags.credential === 'bearer' ? 'token' : 'apiKey';
267
- files['src/services.ts'] =
268
- `import { ${pascalName}Service } from './${name}-api.service.js'
269
- import { pikkuAddonWireServices } from '#pikku/addon/setup'
270
-
271
- export const createWireServices = pikkuAddonWireServices(
272
- async ({ variables }, wire) => {
273
- if (!wire.getCredential) {
274
- throw new Error('Credential resolution is not available in this runtime')
275
- }
276
- const cred = await wire.getCredential<{ ${credField}: string }>('${camelName}')
277
- if (!cred?.${credField}) {
278
- throw new Error('Missing ${camelName} credential')
279
- }
280
- const ${camelName} = new ${pascalName}Service(cred, variables)
281
-
282
- return { ${camelName} }
283
- }
284
- )
285
- `;
288
+ const shape = CREDENTIAL_SHAPES[flags.credential];
289
+ const field = flags.credential === 'basic'
290
+ ? 'username'
291
+ : CREDENTIAL_FIELDS[flags.credential];
292
+ files['src/services.ts'] = wireCredential(shape, `cred?.${field}`, `new MissingCredentialError('${camelName}', 'apikey')`);
286
293
  }
287
294
  else if (flags.oauth || flags.credential === 'oauth2') {
288
295
  // The OAuth2 access token is owned and refreshed by the platform credential
289
296
  // service (better-auth). Resolve a ready token per-request via the wire and
290
297
  // hand it to the service — the addon does not do its own token exchange.
291
- files['src/services.ts'] =
292
- `import { UnauthorizedError } from '@pikku/core/errors'
293
- import { ${pascalName}Service } from './${name}-api.service.js'
294
- import { pikkuAddonWireServices } from '#pikku/addon/setup'
295
-
296
- export const createWireServices = pikkuAddonWireServices(
297
- async ({ variables }, wire) => {
298
- if (!wire.getCredential) {
299
- throw new Error('Credential resolution is not available in this runtime')
300
- }
301
- const cred = await wire.getCredential<{ accessToken: string }>('${camelName}')
302
- if (!cred?.accessToken) {
303
- throw new UnauthorizedError(${literal(`No ${displayName} connection — connect ${displayName} first`)})
304
- }
305
- const ${camelName} = new ${pascalName}Service(cred, variables)
306
-
307
- return { ${camelName} }
308
- }
309
- )
310
- `;
298
+ files['src/services.ts'] = wireCredential('{ accessToken: string }', 'cred?.accessToken', `new MissingCredentialError('${camelName}', 'oauth2')`);
311
299
  }
312
300
  else if (flags.secret) {
313
301
  files['src/services.ts'] =
@@ -317,24 +305,25 @@ import { pikkuAddonServices } from '#pikku/addon/setup'
317
305
 
318
306
  export const createSingletonServices = pikkuAddonServices(async (
319
307
  config,
320
- { secrets }
308
+ { secrets, variables }
321
309
  ) => {
322
310
  const creds = await secrets.getSecret<${pascalName}Secrets>('${screamingName}_CREDENTIALS')
323
- const ${camelName} = new ${pascalName}Service(creds.reveal())
311
+ const ${camelName} = new ${pascalName}Service(creds.reveal(), variables)
324
312
 
325
313
  return { ${camelName} }
326
314
  })
327
315
  `;
328
316
  }
329
317
  else {
330
- // The plain service takes no constructor argument — the secret, credential
331
- // and oauth variants are the ones handed something to authenticate with.
332
318
  files['src/services.ts'] =
333
319
  `import { ${pascalName}Service } from './${name}-api.service.js'
334
320
  import { pikkuAddonServices } from '#pikku/addon/setup'
335
321
 
336
- export const createSingletonServices = pikkuAddonServices(async () => {
337
- const ${camelName} = new ${pascalName}Service()
322
+ export const createSingletonServices = pikkuAddonServices(async (
323
+ config,
324
+ { variables }
325
+ ) => {
326
+ const ${camelName} = new ${pascalName}Service(variables)
338
327
 
339
328
  return { ${camelName} }
340
329
  })
@@ -342,16 +331,16 @@ export const createSingletonServices = pikkuAddonServices(async () => {
342
331
  }
343
332
  // src/{name}-api.service.ts
344
333
  if (flags.credential && flags.credential !== 'oauth2') {
345
- const credField = flags.credential === 'bearer' ? 'token' : 'apiKey';
346
- const credType = `{ ${credField}: string }`;
347
- const authHeader = flags.credential === 'bearer'
348
- ? `\`Bearer \${this.creds.token}\``
349
- : `this.creds.apiKey`;
350
- const authLine = flags.credential === 'bearer'
351
- ? `'Authorization': ${authHeader},`
352
- : `'Authorization': \`Bearer \${this.creds.apiKey}\`,`;
334
+ const credType = CREDENTIAL_SHAPES[flags.credential];
335
+ const authLine = {
336
+ bearer: `'Authorization': \`Bearer \${this.creds.token}\`,`,
337
+ apikey: `'Authorization': \`Bearer \${this.creds.apiKey}\`,`,
338
+ basic: `'Authorization': \`Basic \${btoa(\`\${this.creds.username}:\${this.creds.password}\`)}\`,`,
339
+ }[flags.credential];
353
340
  files[`src/${name}-api.service.ts`] =
354
- `const BASE_URL = 'https://api.example.com/v1'
341
+ `import type { TypedVariablesService } from '#pikku/addon/variables/pikku-variables.gen.js'
342
+
343
+ const BASE_URL = 'https://api.example.com/v1'
355
344
 
356
345
  export interface RequestOptions {
357
346
  body?: unknown
@@ -359,7 +348,10 @@ export interface RequestOptions {
359
348
  }
360
349
 
361
350
  export class ${pascalName}Service {
362
- constructor(private creds: ${credType}) {}
351
+ constructor(
352
+ private creds: ${credType},
353
+ _variables?: TypedVariablesService
354
+ ) {}
363
355
 
364
356
  async request<T>(
365
357
  method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH',
@@ -451,6 +443,7 @@ export class ${pascalName}Service {
451
443
  else if (flags.secret) {
452
444
  files[`src/${name}-api.service.ts`] =
453
445
  `import type { ${pascalName}Secrets } from './${name}.secret.js'
446
+ import type { TypedVariablesService } from '#pikku/addon/variables/pikku-variables.gen.js'
454
447
 
455
448
  const BASE_URL = 'https://api.example.com/v1'
456
449
 
@@ -460,7 +453,10 @@ export interface RequestOptions {
460
453
  }
461
454
 
462
455
  export class ${pascalName}Service {
463
- constructor(private creds: ${pascalName}Secrets) {}
456
+ constructor(
457
+ private creds: ${pascalName}Secrets,
458
+ _variables?: TypedVariablesService
459
+ ) {}
464
460
 
465
461
  async request<T>(
466
462
  method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH',
@@ -498,7 +494,9 @@ export class ${pascalName}Service {
498
494
  }
499
495
  else {
500
496
  files[`src/${name}-api.service.ts`] =
501
- `const BASE_URL = 'https://api.example.com/v1'
497
+ `import type { TypedVariablesService } from '#pikku/addon/variables/pikku-variables.gen.js'
498
+
499
+ const BASE_URL = 'https://api.example.com/v1'
502
500
 
503
501
  export interface RequestOptions {
504
502
  body?: unknown
@@ -506,6 +504,8 @@ export interface RequestOptions {
506
504
  }
507
505
 
508
506
  export class ${pascalName}Service {
507
+ constructor(_variables?: TypedVariablesService) {}
508
+
509
509
  async request<T>(
510
510
  method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH',
511
511
  endpoint: string,
@@ -580,6 +580,24 @@ export const ${camelName}CredentialSchema = z.object({
580
580
  apiKey: z.string().describe(${literal(`${displayName} API key`)}),
581
581
  })
582
582
 
583
+ defineCredential({
584
+ name: '${camelName}',
585
+ displayName: ${literal(displayName)},
586
+ description: ${literal(description)},
587
+ type: 'wire',
588
+ schema: ${camelName}CredentialSchema,
589
+ })
590
+ `;
591
+ }
592
+ else if (flags.credential === 'basic') {
593
+ files[`src/${name}.credential.ts`] = `import { z } from 'zod'
594
+ import { defineCredential } from '#pikku/addon/auth'
595
+
596
+ export const ${camelName}CredentialSchema = z.object({
597
+ username: z.string().describe(${literal(`${displayName} username`)}),
598
+ password: z.string().describe(${literal(`${displayName} password`)}),
599
+ })
600
+
583
601
  defineCredential({
584
602
  name: '${camelName}',
585
603
  displayName: ${literal(displayName)},
@@ -926,8 +944,95 @@ export const buildGeneratedAddon = (addonDir, logger, run = spawnAddonBuildStep)
926
944
  }
927
945
  return true;
928
946
  };
947
+ /**
948
+ * `string[]` options split on commas, which would cut a header value like
949
+ * `Accept: a, b` in two; a piece that does not start a new `Name:` rejoins the
950
+ * previous one.
951
+ */
952
+ export function parseHeaderOptions(raw = []) {
953
+ const joined = [];
954
+ for (const piece of raw) {
955
+ if (/^[A-Za-z0-9!#$%&'*+.^_`|~-]+\s*:/.test(piece) || joined.length === 0) {
956
+ joined.push(piece);
957
+ }
958
+ else {
959
+ joined[joined.length - 1] += `, ${piece}`;
960
+ }
961
+ }
962
+ const headers = {};
963
+ for (const header of joined) {
964
+ const at = header.indexOf(':');
965
+ if (at <= 0) {
966
+ throw new Error(`--openapi-header "${header}" is not "Name: value"`);
967
+ }
968
+ headers[header.slice(0, at).trim()] = header.slice(at + 1).trim();
969
+ }
970
+ return headers;
971
+ }
972
+ /**
973
+ * How the addon authenticates, from the flags first and the spec second.
974
+ * Per-user is the default for anything the spec can authenticate: each user
975
+ * acts upstream as themselves. `--auth shared` puts one secret behind every
976
+ * user; `--auth none` is for public APIs.
977
+ */
978
+ export function resolveAddonAuth(spec, flags) {
979
+ if (flags.auth && !['user', 'shared', 'none'].includes(flags.auth)) {
980
+ throw new Error(`--auth must be user, shared or none (got "${flags.auth}")`);
981
+ }
982
+ if (flags.authConfig?.delegated) {
983
+ return {
984
+ mode: 'delegated',
985
+ credential: 'bearer',
986
+ secret: false,
987
+ oauth: false,
988
+ };
989
+ }
990
+ if (flags.auth === 'none') {
991
+ return { mode: 'none', secret: false, oauth: false };
992
+ }
993
+ if (flags.auth === 'shared' ||
994
+ (flags.secret && !flags.credential && !flags.oauth)) {
995
+ return { mode: 'shared', secret: true, oauth: false };
996
+ }
997
+ const explicit = flags.credential ?? (flags.oauth ? 'oauth2' : undefined);
998
+ const fromSpec = flags.authConfig?.headerName
999
+ ? 'apikey'
1000
+ : {
1001
+ oauth2: 'oauth2',
1002
+ apiKey: 'apikey',
1003
+ bearer: 'bearer',
1004
+ basic: 'basic',
1005
+ none: undefined,
1006
+ }[spec.authType];
1007
+ const credential = (explicit ?? fromSpec);
1008
+ if (!credential) {
1009
+ throw new Error(`${spec.info.title} declares no security scheme, so the addon cannot tell how to authenticate. ` +
1010
+ 'Pass --auth none for a public API, --credential apikey|bearer|basic|oauth2 for a per-user key, ' +
1011
+ '--auth shared for one key behind every user, or --auth-config <file> for a custom header or a delegated login (see pikku-build references/openapi.md).');
1012
+ }
1013
+ if (!['apikey', 'bearer', 'basic', 'oauth2'].includes(credential)) {
1014
+ throw new Error(`Invalid credential type "${credential}": must be one of apikey, bearer, basic, oauth2`);
1015
+ }
1016
+ return {
1017
+ mode: credential === 'oauth2' ? 'oauth2' : 'connect',
1018
+ credential,
1019
+ secret: false,
1020
+ oauth: credential === 'oauth2',
1021
+ };
1022
+ }
1023
+ /** The project `pikku new addon` runs in, when it is an app rather than an addon. */
1024
+ function findAppProject(config) {
1025
+ const root = config?.rootDir;
1026
+ if (!root || config.addon || !existsSync(join(root, 'pikku.config.json'))) {
1027
+ return undefined;
1028
+ }
1029
+ const src = config.srcDirectories?.[0];
1030
+ if (!src)
1031
+ return undefined;
1032
+ return { root, srcDir: join(root, src) };
1033
+ }
929
1034
  export const pikkuNewAddon = pikkuSessionlessFunc({
930
- func: async ({ logger, config }, { name, displayName, description, category = 'General', dir, secret = false, variable = false, oauth = false, credential, test = true, openapi, authConfig, mcp = false, camelCase = false, build = true, }) => {
1035
+ func: async ({ logger, config }, { name, displayName, description, category = 'General', dir, secret = false, variable = false, oauth = false, credential, test = true, openapi, openapiHeader, tags, include, exclude, auth, install, authConfig, mcp = false, camelCase = false, build = true, }) => {
931
1036
  name = sanitizeAddonName(name);
932
1037
  if (!/^[a-z][a-z0-9_-]*$/.test(name)) {
933
1038
  logger.error(`Invalid addon name "${name}": must start with a lowercase letter and contain only lowercase alphanumerics, hyphens, and underscores`);
@@ -936,8 +1041,19 @@ export const pikkuNewAddon = pikkuSessionlessFunc({
936
1041
  const pascalName = toPascalCase(name);
937
1042
  const resolvedDisplayName = displayName || pascalName;
938
1043
  const resolvedDescription = description || `${resolvedDisplayName} integration for Pikku`;
1044
+ const app = findAppProject(config);
1045
+ const installing = Boolean(openapi) && (install ?? Boolean(app));
1046
+ if (installing && !app) {
1047
+ logger.error('--install needs to run inside a pikku app (a pikku.config.json that is not an addon)');
1048
+ process.exit(1);
1049
+ }
939
1050
  // Resolve target directory
940
- const baseDir = dir || config.scaffold?.addonDir || process.cwd();
1051
+ const workspacePackages = app ? join(app.root, 'packages') : undefined;
1052
+ const baseDir = dir ||
1053
+ config.scaffold?.addonDir ||
1054
+ (installing && workspacePackages && existsSync(workspacePackages)
1055
+ ? workspacePackages
1056
+ : process.cwd());
941
1057
  // Folder mirrors the package name (@pikku/addon-<name>) so a packages/
942
1058
  // listing reads as packages/addon-<name>, distinct from app workspaces.
943
1059
  const addonDir = join(baseDir, `addon-${name}`);
@@ -955,53 +1071,88 @@ export const pikkuNewAddon = pikkuSessionlessFunc({
955
1071
  category,
956
1072
  addonDepProtocol: resolveAddonDepProtocol(baseDir),
957
1073
  };
958
- // Load the auth config (custom auth header / delegated login overrides)
959
1074
  let loadedAuthConfig;
960
1075
  if (authConfig) {
961
1076
  loadedAuthConfig = await loadAuthConfig(authConfig);
962
- if (loadedAuthConfig.delegated) {
963
- // Delegated login stores the upstream token per-user — bearer is the
964
- // only coherent credential mode.
965
- if (credential && credential !== 'bearer') {
966
- logger.error(`--auth-config with delegated login requires --credential bearer (got "${credential}")`);
967
- process.exit(1);
1077
+ if (loadedAuthConfig.delegated && credential && credential !== 'bearer') {
1078
+ logger.error(`--auth-config with delegated login stores the upstream token per user, so it cannot be combined with --credential ${credential}`);
1079
+ process.exit(1);
1080
+ }
1081
+ }
1082
+ let spec;
1083
+ let resolved;
1084
+ try {
1085
+ if (openapi) {
1086
+ spec = await parseOpenAPISpec(openapi, {
1087
+ headers: parseHeaderOptions(openapiHeader),
1088
+ });
1089
+ const total = spec.operations.length;
1090
+ spec = filterOperations(spec, { tags, include, exclude });
1091
+ if (spec.operations.length === 0) {
1092
+ throw new Error(`No operations left out of ${total} after --tags/--include/--exclude`);
1093
+ }
1094
+ const warning = specCoverageWarning(spec);
1095
+ if (warning) {
1096
+ logger.warn(`\n⚠️ ${warning}\n`);
968
1097
  }
969
- credential = 'bearer';
1098
+ resolved = resolveAddonAuth(spec, {
1099
+ auth,
1100
+ credential,
1101
+ oauth,
1102
+ secret,
1103
+ authConfig: loadedAuthConfig,
1104
+ });
1105
+ const login = detectLoginOperation(spec);
1106
+ if (login && resolved.mode !== 'delegated') {
1107
+ logger.info(`${spec.info.title} has a login route (${login.method.toUpperCase()} ${login.path}). To let users sign in to the app with their ${resolvedDisplayName} account, pass --auth-config with a "delegated" block (see pikku-build references/openapi.md).`);
1108
+ }
1109
+ logger.info(`${spec.operations.length} operations, auth: ${resolved.mode}${resolved.credential ? ` (${resolved.credential})` : ''}`);
1110
+ }
1111
+ else {
1112
+ const credentialType = credential;
1113
+ if (credentialType &&
1114
+ !['apikey', 'bearer', 'basic', 'oauth2'].includes(credentialType)) {
1115
+ throw new Error(`Invalid credential type "${credential}": must be one of apikey, bearer, basic, oauth2`);
1116
+ }
1117
+ const effectiveOAuth = oauth || credentialType === 'oauth2';
1118
+ resolved = {
1119
+ mode: effectiveOAuth
1120
+ ? 'oauth2'
1121
+ : credentialType
1122
+ ? 'connect'
1123
+ : secret
1124
+ ? 'shared'
1125
+ : 'none',
1126
+ credential: loadedAuthConfig?.delegated ? 'bearer' : credentialType,
1127
+ secret: (secret || effectiveOAuth) && !credentialType,
1128
+ oauth: effectiveOAuth,
1129
+ };
1130
+ if (loadedAuthConfig?.delegated)
1131
+ resolved.mode = 'delegated';
970
1132
  }
971
1133
  }
972
- // Validate credential type if provided
973
- const credentialType = credential;
974
- if (credentialType &&
975
- !['apikey', 'bearer', 'oauth2'].includes(credentialType)) {
976
- logger.error(`Invalid credential type "${credential}": must be one of apikey, bearer, oauth2`);
1134
+ catch (error) {
1135
+ logger.error(error instanceof Error ? error.message : String(error));
977
1136
  process.exit(1);
978
1137
  }
979
- // oauth implies secret (unless credential flag is used); credential oauth2 implies oauth
980
- const effectiveOAuth = oauth || credentialType === 'oauth2';
981
1138
  const addonFiles = getAddonFiles(vars, {
982
- secret: (secret || effectiveOAuth) && !credentialType,
1139
+ secret: resolved.secret,
983
1140
  variable,
984
- oauth: effectiveOAuth,
985
- credential: credentialType,
986
- delegated: Boolean(loadedAuthConfig?.delegated),
1141
+ oauth: resolved.oauth,
1142
+ credential: resolved.credential,
1143
+ delegated: resolved.mode === 'delegated',
987
1144
  });
988
- // If openapi spec provided, generate typed files and merge over scaffold
989
- if (openapi) {
990
- const spec = await parseOpenAPISpec(openapi);
1145
+ if (spec) {
991
1146
  const openapiFiles = generateAddonFromOpenAPI(spec, vars, {
992
- oauth: effectiveOAuth,
993
- secret: (secret || effectiveOAuth) && !credentialType,
994
- credential: credentialType,
1147
+ oauth: resolved.oauth,
1148
+ secret: resolved.secret,
1149
+ credential: resolved.credential,
995
1150
  mcp,
996
1151
  camelCase,
997
1152
  authConfig: loadedAuthConfig,
998
1153
  });
999
1154
  Object.assign(addonFiles, openapiFiles);
1000
- // Inject openapi metadata into pikku.config.json
1001
1155
  const config = JSON.parse(addonFiles['pikku.config.json']);
1002
- if (typeof config.addon === 'boolean' || !config.addon) {
1003
- config.addon = {};
1004
- }
1005
1156
  config.addon.openapi = {
1006
1157
  version: spec.info.version,
1007
1158
  hash: computeContractHash(spec),
@@ -1024,6 +1175,33 @@ export const pikkuNewAddon = pikkuSessionlessFunc({
1024
1175
  for (const f of written) {
1025
1176
  logger.debug({ message: ` ${f}`, type: 'success' });
1026
1177
  }
1178
+ if (installing && app && spec) {
1179
+ const functions = Object.fromEntries(Object.entries(addonFiles)
1180
+ .filter(([path]) => /^src\/functions\/[^/]+\.function\.ts$/.test(path))
1181
+ .map(([path, source]) => [
1182
+ path.slice('src/functions/'.length, -'.function.ts'.length),
1183
+ source,
1184
+ ]));
1185
+ const baseUrl = spec.serverUrls.find((url) => /^https?:\/\//.test(url));
1186
+ const { written: installed, notes } = installAddonIntoApp({
1187
+ projectRoot: app.root,
1188
+ srcDir: app.srcDir,
1189
+ name,
1190
+ camelName: vars.camelName,
1191
+ pascalName,
1192
+ screamingName: vars.screamingName,
1193
+ packageName: `@pikku/addon-${name}`,
1194
+ addonDir,
1195
+ inWorkspace: workspaceCovers(app.root, addonDir),
1196
+ mode: resolved.mode,
1197
+ functions,
1198
+ baseUrl: baseUrl?.replace(/\/+$/, ''),
1199
+ });
1200
+ for (const f of installed)
1201
+ logger.info(` updated ${f}`);
1202
+ for (const note of notes)
1203
+ logger.warn(note);
1204
+ }
1027
1205
  if (build && !buildGeneratedAddon(addonDir, logger)) {
1028
1206
  process.exit(1);
1029
1207
  }
@@ -180,8 +180,13 @@ export const serve = pikkuSessionlessFunc({
180
180
  ? await resolveFrontendMount(config.frontend)
181
181
  : undefined;
182
182
  // The console goes first so a frontend mounted at `/` cannot claim
183
- // `/console` before the console's own mount is offered the request.
184
- const staticMounts = [consoleMount, frontendMount].filter((mount) => Boolean(mount));
183
+ // `/console` before the console's own mount is offered the request, and
184
+ // the app's own mounts are kept ahead of the catch-all frontend.
185
+ const staticMounts = [
186
+ ...(consoleMount ? [consoleMount] : []),
187
+ ...(userConfig.staticMounts ?? []),
188
+ ...(frontendMount ? [frontendMount] : []),
189
+ ];
185
190
  const pikkuServer = devServerRunner.createServer({
186
191
  ...userConfig,
187
192
  hostname: bindHostname,
@@ -12,6 +12,7 @@ export interface GetMigrationsResult {
12
12
  runMigrations: () => Promise<void>;
13
13
  compileMigrations: () => Promise<string>;
14
14
  }
15
+ export declare function withoutAuthSchemaCheck<DB>(kysely: Kysely<DB>): Kysely<DB>;
15
16
  export declare function loadAuthOptions(opts: {
16
17
  rootDir: string;
17
18
  srcDirectories: string[];