@pikku/cli 0.12.114 → 0.12.116

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 (297) hide show
  1. package/CHANGELOG.md +273 -0
  2. package/console-app/assets/{abnfDiagram-N423BO3Z-Bltf5dmS.js → abnfDiagram-N423BO3Z-WNIAg_Oa.js} +1 -1
  3. package/console-app/assets/architecture-TIHT7OUA-CIT-Nug2.js +1 -0
  4. package/console-app/assets/{architectureDiagram-T3A2C74G-BTtx6R7-.js → architectureDiagram-T3A2C74G-DM698mgf.js} +1 -1
  5. package/console-app/assets/{blockDiagram-VBNYF7ZC-DgeTIOaM.js → blockDiagram-VBNYF7ZC-DPfy9K5S.js} +1 -1
  6. package/console-app/assets/{c4Diagram-5PPSVZJV-CaswnNob.js → c4Diagram-5PPSVZJV-DhLbbBbX.js} +1 -1
  7. package/console-app/assets/channel-DQC6cL1c.js +1 -0
  8. package/console-app/assets/{chunk-2GRJ4B5K-OnpnkpQT.js → chunk-2GRJ4B5K-C1RQ1gvs.js} +1 -1
  9. package/console-app/assets/{chunk-4I5QYGJK-CWmfNXFr.js → chunk-4I5QYGJK-BkzSdNc_.js} +1 -1
  10. package/console-app/assets/{chunk-5RXB4S5H-M8QmKeuk.js → chunk-5RXB4S5H-DZpBpdcU.js} +1 -1
  11. package/console-app/assets/{chunk-6Q2QTUOP-C_h5lS68.js → chunk-6Q2QTUOP-mZObxdld.js} +1 -1
  12. package/console-app/assets/{chunk-7Z6QIM7H-DSnVb09k.js → chunk-7Z6QIM7H-C0HbxZEa.js} +1 -1
  13. package/console-app/assets/{chunk-GF5L2VYU-BkX038sq.js → chunk-GF5L2VYU-DXPVwWqW.js} +1 -1
  14. package/console-app/assets/{chunk-I66GZJ75-b3yMIljX.js → chunk-I66GZJ75-pVpq9ckD.js} +1 -1
  15. package/console-app/assets/{chunk-JQJVKLGR-Bihcz4nv.js → chunk-JQJVKLGR-DJQ8K4wK.js} +1 -1
  16. package/console-app/assets/{chunk-KBJHAD2P-CS7eflbk.js → chunk-KBJHAD2P-B8XuxRCO.js} +1 -1
  17. package/console-app/assets/{chunk-NSK5VX7P-CfigFGDQ.js → chunk-NSK5VX7P-cYzQU4bD.js} +1 -1
  18. package/console-app/assets/{chunk-QR6OTTB3-BBy8NfTW.js → chunk-QR6OTTB3-CNoTFsqn.js} +1 -1
  19. package/console-app/assets/{chunk-RYQCIY6F-BCfZVQef.js → chunk-RYQCIY6F-DoKRUO_N.js} +1 -1
  20. package/console-app/assets/{chunk-UBXNYLIW-DkMKDHW4.js → chunk-UBXNYLIW-BqcIoUpU.js} +1 -1
  21. package/console-app/assets/{chunk-W5SLKNZC-BSLytTSJ.js → chunk-W5SLKNZC-p0Qalbjj.js} +1 -1
  22. package/console-app/assets/{chunk-WRU74C26-Dic7ZP8H.js → chunk-WRU74C26-DUMn96Dr.js} +1 -1
  23. package/console-app/assets/chunk-XXDRQBXY-Dgz5VbWO.js +1 -0
  24. package/console-app/assets/classDiagram-JCYQIIEL-1ASFocNV.js +1 -0
  25. package/console-app/assets/classDiagram-v2-OCEON4UE-1ASFocNV.js +1 -0
  26. package/console-app/assets/{cose-bilkent-JH36ORCC-CEpWcE3M.js → cose-bilkent-JH36ORCC-BCh3BlPI.js} +1 -1
  27. package/console-app/assets/{cynefin-VYW2F7L2-irPiPhgz.js → cynefin-VYW2F7L2-ZfghUZsD.js} +1 -1
  28. package/console-app/assets/{cynefinDiagram-MW4NZA55-CIkqQ912.js → cynefinDiagram-MW4NZA55-DcV3QXCe.js} +1 -1
  29. package/console-app/assets/{dagre-FZyyw3H3.js → dagre-BPFWXLBN.js} +1 -1
  30. package/console-app/assets/{dagre-VZM6K2ZE-Dxnnu7Rh.js → dagre-VZM6K2ZE-DETshBO-.js} +1 -1
  31. package/console-app/assets/{diagram-7IWD3JNH-DaT47sVs.js → diagram-7IWD3JNH-CsLX3P2o.js} +1 -1
  32. package/console-app/assets/{diagram-B4RE2ZJO-Dmht03tx.js → diagram-B4RE2ZJO-o2zcxm5S.js} +1 -1
  33. package/console-app/assets/{diagram-LBJQPF4R-B--jwILh.js → diagram-LBJQPF4R-BD2zKU21.js} +1 -1
  34. package/console-app/assets/{diagram-Q27KOJAE-D9H0euUr.js → diagram-Q27KOJAE-DHaacyna.js} +1 -1
  35. package/console-app/assets/{diagram-UB23O5K3-DloUQ8tO.js → diagram-UB23O5K3-pSLCMUyV.js} +1 -1
  36. package/console-app/assets/{ebnfDiagram-BXEA7PRR-gaOXzNBU.js → ebnfDiagram-BXEA7PRR-BDzawX3O.js} +1 -1
  37. package/console-app/assets/{erDiagram-JOGREHBK-3X9eTLsh.js → erDiagram-JOGREHBK-CyYnPmbN.js} +1 -1
  38. package/console-app/assets/eventmodeling-45OFAUF4-BYJ0A5k-.js +1 -0
  39. package/console-app/assets/flowDiagram-UKHOOZJN-CVn87uiP.js +1 -0
  40. package/console-app/assets/{ganttDiagram-PKOTCBZU-khAFwSBy.js → ganttDiagram-PKOTCBZU-3fhCBbPA.js} +1 -1
  41. package/console-app/assets/{gitGraph-TEB2WS4Q-Bb7uENmk.js → gitGraph-TEB2WS4Q-CdLRkVux.js} +1 -1
  42. package/console-app/assets/{gitGraphDiagram-DS77QQ5N-OkSBM0h0.js → gitGraphDiagram-DS77QQ5N-CC1epdKw.js} +1 -1
  43. package/console-app/assets/{index-Bn1BoT3w.js → index-BRmokG9t.js} +184 -184
  44. package/console-app/assets/{index-suVNAhyL.css → index-GruDnAhJ.css} +1 -1
  45. package/console-app/assets/{info-DKCQHKI2-BH5dbX2B.js → info-DKCQHKI2-BJs8WkzC.js} +1 -1
  46. package/console-app/assets/{infoDiagram-6WML65LV-IbUl8J2C.js → infoDiagram-6WML65LV-uoOwoIeI.js} +1 -1
  47. package/console-app/assets/{ishikawaDiagram-WSZJBQD7-CX0gA3de.js → ishikawaDiagram-WSZJBQD7-vCUJhwTi.js} +1 -1
  48. package/console-app/assets/{journeyDiagram-NVQOT4AX--k2etXu8.js → journeyDiagram-NVQOT4AX-D2QcIlLG.js} +1 -1
  49. package/console-app/assets/{kanban-definition-27J2QSJJ-D1FvtPpN.js → kanban-definition-27J2QSJJ-JwwKowmR.js} +1 -1
  50. package/console-app/assets/{line-JLMY_DDK.js → line-h2oRreYF.js} +1 -1
  51. package/console-app/assets/{linear-CSvLB3cd.js → linear-Dz002X_a.js} +1 -1
  52. package/console-app/assets/{mermaid-parser.core-CwwjcAjz.js → mermaid-parser.core-DTgmT0AA.js} +3 -3
  53. package/console-app/assets/{mermaid.core-hmS_M4K5.js → mermaid.core-1jSEDr-j.js} +4 -4
  54. package/console-app/assets/{mindmap-definition-FAOFIHXS-rTDa_CTp.js → mindmap-definition-FAOFIHXS-C3Txxhj4.js} +1 -1
  55. package/console-app/assets/{packet-7NZHBO7P-DBUJcYfI.js → packet-7NZHBO7P-BGG7zIK2.js} +1 -1
  56. package/console-app/assets/{pegDiagram-VL7TDLO6-D42PxXnS.js → pegDiagram-VL7TDLO6--g1r_rov.js} +1 -1
  57. package/console-app/assets/{pie-RZYD4A2V-dM0uFAE4.js → pie-RZYD4A2V-C5OepMH7.js} +1 -1
  58. package/console-app/assets/{pieDiagram-7S7Q4E2Y-wCln1ucl.js → pieDiagram-7S7Q4E2Y-DGD_LzGm.js} +1 -1
  59. package/console-app/assets/{quadrantDiagram-CIZ2JOQS-DrRwS1g5.js → quadrantDiagram-CIZ2JOQS-CyBQQlD2.js} +1 -1
  60. package/console-app/assets/{radar-I7S5WNFK-BW0V-EGR.js → radar-I7S5WNFK-CaBOAO95.js} +1 -1
  61. package/console-app/assets/{railroad-3IZDKUUU-FiTHaDbb.js → railroad-3IZDKUUU-2aTWN4Pw.js} +1 -1
  62. package/console-app/assets/railroad-abnf-AHOZXSZD-TU7k5gB_.js +1 -0
  63. package/console-app/assets/railroad-ebnf-EBAXGLYW-DbArPBkM.js +1 -0
  64. package/console-app/assets/railroad-peg-LSFZ7HO6-TzB93z4K.js +1 -0
  65. package/console-app/assets/{railroadDiagram-AXF67PYL-9ef7j5U7.js → railroadDiagram-AXF67PYL-3Nr0rlTp.js} +1 -1
  66. package/console-app/assets/{requirementDiagram-LRYGKXZP-Cu90DbEZ.js → requirementDiagram-LRYGKXZP-BN7sEwSa.js} +1 -1
  67. package/console-app/assets/{sankeyDiagram-W5VNT64P-Bhxmyxaw.js → sankeyDiagram-W5VNT64P-CXZR46wO.js} +1 -1
  68. package/console-app/assets/{sequenceDiagram-SI44F4Z6-CBsbRTz8.js → sequenceDiagram-SI44F4Z6-DNtmdJ4U.js} +1 -1
  69. package/console-app/assets/{src-BR8qR3lM.js → src-x1E3pJJ-.js} +1 -1
  70. package/console-app/assets/{stateDiagram-OKZ733FA-Dr0frETZ.js → stateDiagram-OKZ733FA-B_GyYdl_.js} +1 -1
  71. package/console-app/assets/stateDiagram-v2-UEYNNEHI-D7V_HITc.js +1 -0
  72. package/console-app/assets/{swimlanes-SLNWSIFB-CXMjvd_a.js → swimlanes-SLNWSIFB-D4N7VdF7.js} +1 -1
  73. package/console-app/assets/swimlanesDiagram-ULZ7WXOC-C4XcIHKT.js +8 -0
  74. package/console-app/assets/{timeline-definition-Z64GVDOM-DpmEZPV0.js → timeline-definition-Z64GVDOM-DU5rsOWQ.js} +1 -1
  75. package/console-app/assets/{treeView-QDETBFTQ-CjmuinMk.js → treeView-QDETBFTQ-DaKM_9sB.js} +1 -1
  76. package/console-app/assets/{treemap-6X3UGDF4-BP_fU6Cn.js → treemap-6X3UGDF4-BabsKtZY.js} +1 -1
  77. package/console-app/assets/{vennDiagram-T6HMQDX7-DgZS7iuW.js → vennDiagram-T6HMQDX7-Dniftpq0.js} +1 -1
  78. package/console-app/assets/{wardley-OPB4EBWU-CgMPoouN.js → wardley-OPB4EBWU-BWffQNys.js} +1 -1
  79. package/console-app/assets/{wardleyDiagram-T6FBY63Y-6y-xxP1R.js → wardleyDiagram-T6FBY63Y-CQ74fVdn.js} +1 -1
  80. package/console-app/assets/{xychartDiagram-ELKLHX3M-DOeIQjYI.js → xychartDiagram-ELKLHX3M-D-XxbGIL.js} +1 -1
  81. package/console-app/index.html +2 -2
  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 +42 -1
  89. package/dist/.pikku/agent/pikku-agent-types.gen.js +41 -0
  90. package/dist/.pikku/agent/pikku-model-aliases.gen.js +1 -1
  91. package/dist/.pikku/auth/index.d.ts +1 -1
  92. package/dist/.pikku/auth/index.js +1 -1
  93. package/dist/.pikku/auth/pikku-auth-types.gen.d.ts +2 -19
  94. package/dist/.pikku/auth/pikku-auth-types.gen.js +2 -19
  95. package/dist/.pikku/channel/index.d.ts +1 -1
  96. package/dist/.pikku/channel/index.js +1 -1
  97. package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +10 -18
  98. package/dist/.pikku/channel/pikku-channel-types.gen.js +9 -1
  99. package/dist/.pikku/cli/index.d.ts +1 -1
  100. package/dist/.pikku/cli/index.js +1 -1
  101. package/dist/.pikku/cli/pikku-cli-channel.js +6 -6
  102. package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +1 -1
  103. package/dist/.pikku/cli/pikku-cli-client.gen.js +1 -1
  104. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.d.ts +1 -1
  105. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.js +1 -1
  106. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.json +24 -23
  107. package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +8 -7
  108. package/dist/.pikku/cli/pikku-cli-types.gen.js +8 -7
  109. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +1 -1
  110. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.json +51 -23
  111. package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
  112. package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
  113. package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
  114. package/dist/.pikku/cli/pikku-cli.gen.js +1 -1
  115. package/dist/.pikku/error/index.d.ts +1 -1
  116. package/dist/.pikku/error/index.js +1 -1
  117. package/dist/.pikku/error/pikku-error-types.gen.d.ts +1 -1
  118. package/dist/.pikku/error/pikku-error-types.gen.js +1 -1
  119. package/dist/.pikku/function/index.d.ts +1 -1
  120. package/dist/.pikku/function/index.js +1 -1
  121. package/dist/.pikku/function/pikku-function-types.gen.d.ts +36 -37
  122. package/dist/.pikku/function/pikku-function-types.gen.js +21 -9
  123. package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
  124. package/dist/.pikku/function/pikku-functions-meta.gen.json +34 -34
  125. package/dist/.pikku/function/pikku-functions.gen.js +1 -1
  126. package/dist/.pikku/gateway/index.d.ts +1 -1
  127. package/dist/.pikku/gateway/index.js +1 -1
  128. package/dist/.pikku/gateway/pikku-gateway-types.gen.d.ts +1 -1
  129. package/dist/.pikku/gateway/pikku-gateway-types.gen.js +1 -1
  130. package/dist/.pikku/http/index.d.ts +1 -1
  131. package/dist/.pikku/http/index.js +1 -1
  132. package/dist/.pikku/http/pikku-http-types.gen.d.ts +7 -1
  133. package/dist/.pikku/http/pikku-http-types.gen.js +5 -1
  134. package/dist/.pikku/mcp/index.d.ts +1 -1
  135. package/dist/.pikku/mcp/index.js +1 -1
  136. package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +11 -1
  137. package/dist/.pikku/mcp/pikku-mcp-types.gen.js +5 -1
  138. package/dist/.pikku/middleware/index.d.ts +1 -1
  139. package/dist/.pikku/middleware/index.js +1 -1
  140. package/dist/.pikku/middleware/pikku-middleware-types.gen.d.ts +33 -24
  141. package/dist/.pikku/middleware/pikku-middleware-types.gen.js +29 -24
  142. package/dist/.pikku/pikku-bootstrap-scenarios.gen.d.ts +1 -1
  143. package/dist/.pikku/pikku-bootstrap-scenarios.gen.js +1 -1
  144. package/dist/.pikku/pikku-bootstrap.gen.d.ts +1 -1
  145. package/dist/.pikku/pikku-bootstrap.gen.js +1 -1
  146. package/dist/.pikku/pikku-services.gen.d.ts +1 -1
  147. package/dist/.pikku/queue/index.d.ts +1 -1
  148. package/dist/.pikku/queue/index.js +1 -1
  149. package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +3 -1
  150. package/dist/.pikku/queue/pikku-queue-types.gen.js +3 -1
  151. package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +1 -1
  152. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
  153. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
  154. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +1 -1
  155. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.json +1 -1
  156. package/dist/.pikku/scenarios/index.d.ts +1 -1
  157. package/dist/.pikku/scenarios/index.js +1 -1
  158. package/dist/.pikku/scenarios/pikku-personas.gen.d.ts +4 -0
  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 +13 -1
  163. package/dist/.pikku/scenarios/pikku-scenario-types.gen.js +4 -0
  164. package/dist/.pikku/scenarios/pikku-scenario-wirings-meta.gen.js +1 -1
  165. package/dist/.pikku/scenarios/pikku-scenario-wirings.gen.d.ts +1 -1
  166. package/dist/.pikku/scenarios/schemas/register.gen.d.ts +1 -1
  167. package/dist/.pikku/scenarios/schemas/register.gen.js +1 -1
  168. package/dist/.pikku/scheduler/index.d.ts +1 -1
  169. package/dist/.pikku/scheduler/index.js +1 -1
  170. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +3 -1
  171. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +3 -1
  172. package/dist/.pikku/schemas/register.gen.js +5 -5
  173. package/dist/.pikku/schemas/schemas/DocInput.schema.json +1 -0
  174. package/dist/.pikku/schemas/schemas/DocOutput.schema.json +1 -0
  175. package/dist/.pikku/schemas/schemas/FabricDeployApplyInput.schema.json +1 -1
  176. package/dist/.pikku/schemas/schemas/FabricDeployApplyOutput.schema.json +1 -1
  177. package/dist/.pikku/schemas/schemas/FabricSecretsRotateOutput.schema.json +1 -1
  178. package/dist/.pikku/schemas/schemas/PikkuSkillsInstallInput.schema.json +1 -1
  179. package/dist/.pikku/scopes/index.d.ts +1 -1
  180. package/dist/.pikku/scopes/index.js +1 -1
  181. package/dist/.pikku/scopes/pikku-personas.gen.js +1 -1
  182. package/dist/.pikku/scopes/pikku-roles.gen.d.ts +1 -1
  183. package/dist/.pikku/scopes/pikku-scope-types.gen.d.ts +1 -1
  184. package/dist/.pikku/scopes/pikku-scope-types.gen.js +1 -1
  185. package/dist/.pikku/scopes/pikku-scopes.gen.d.ts +1 -1
  186. package/dist/.pikku/secrets/index.d.ts +1 -1
  187. package/dist/.pikku/secrets/index.js +1 -1
  188. package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +1 -1
  189. package/dist/.pikku/secrets/pikku-secret-types.gen.js +1 -1
  190. package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +9 -1
  191. package/dist/.pikku/secrets/pikku-secrets.gen.js +5 -1
  192. package/dist/.pikku/services/pikku-meta-service.gen.d.ts +1 -1
  193. package/dist/.pikku/services/pikku-meta-service.gen.js +1 -1
  194. package/dist/.pikku/setup/index.d.ts +1 -1
  195. package/dist/.pikku/setup/index.js +1 -1
  196. package/dist/.pikku/setup/pikku-setup-types.gen.d.ts +7 -19
  197. package/dist/.pikku/setup/pikku-setup-types.gen.js +11 -19
  198. package/dist/.pikku/trigger/index.d.ts +1 -1
  199. package/dist/.pikku/trigger/index.js +1 -1
  200. package/dist/.pikku/trigger/pikku-trigger-types.gen.d.ts +5 -1
  201. package/dist/.pikku/trigger/pikku-trigger-types.gen.js +5 -1
  202. package/dist/.pikku/variables/index.d.ts +1 -1
  203. package/dist/.pikku/variables/index.js +1 -1
  204. package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +1 -1
  205. package/dist/.pikku/variables/pikku-variable-types.gen.js +1 -1
  206. package/dist/.pikku/variables/pikku-variables.gen.d.ts +9 -1
  207. package/dist/.pikku/variables/pikku-variables.gen.js +5 -1
  208. package/dist/.pikku/workflow/index.d.ts +1 -1
  209. package/dist/.pikku/workflow/index.js +1 -1
  210. package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +29 -1
  211. package/dist/.pikku/workflow/pikku-workflow-types.gen.js +8 -1
  212. package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +1 -1
  213. package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +1 -1
  214. package/dist/bin/pikku-bin.mjs +2 -2
  215. package/dist/src/cli.wiring.js +21 -0
  216. package/dist/src/deploy/analyzer/analyzer.d.ts +1 -0
  217. package/dist/src/deploy/analyzer/analyzer.js +8 -6
  218. package/dist/src/deploy/build-pipeline.d.ts +1 -0
  219. package/dist/src/deploy/build-pipeline.js +1 -0
  220. package/dist/src/fabric/fabric-commands.d.ts +170 -54
  221. package/dist/src/fabric/fabric-commands.js +25 -20
  222. package/dist/src/fabric/functions/deploy.function.d.ts +246 -67
  223. package/dist/src/fabric/functions/deploy.function.js +316 -69
  224. package/dist/src/fabric/functions/init.function.js +1 -0
  225. package/dist/src/fabric/functions/link.function.js +4 -1
  226. package/dist/src/fabric/functions/secrets-rotate.function.d.ts +4 -4
  227. package/dist/src/fabric/functions/secrets-rotate.function.js +2 -2
  228. package/dist/src/fabric/functions/validate.function.js +123 -0
  229. package/dist/src/fabric/lib/deployment.d.ts +107 -0
  230. package/dist/src/fabric/lib/deployment.js +264 -0
  231. package/dist/src/fabric/sdk/pikku-fetch.gen.d.ts +1 -1
  232. package/dist/src/fabric/sdk/pikku-fetch.gen.js +1 -1
  233. package/dist/src/fabric/sdk/pikku-rpc.gen.d.ts +4 -1
  234. package/dist/src/fabric/sdk/pikku-rpc.gen.js +4 -1
  235. package/dist/src/functions/commands/deploy-apply.js +1 -0
  236. package/dist/src/functions/commands/deploy-plan.js +1 -0
  237. package/dist/src/functions/commands/doc.d.ts +22 -0
  238. package/dist/src/functions/commands/doc.js +25 -0
  239. package/dist/src/functions/commands/skills.d.ts +3 -0
  240. package/dist/src/functions/commands/skills.js +4 -2
  241. package/dist/src/functions/runtimes/tanstack-start/serialize-tanstack-start-shim.d.ts +3 -2
  242. package/dist/src/functions/runtimes/tanstack-start/serialize-tanstack-start-shim.js +33 -10
  243. package/dist/src/functions/surface/build-surface-doc.d.ts +8 -1
  244. package/dist/src/functions/surface/build-surface-doc.js +21 -8
  245. package/dist/src/functions/surface/collect-snippets.d.ts +13 -0
  246. package/dist/src/functions/surface/collect-snippets.js +83 -0
  247. package/dist/src/functions/surface/collect-surface.d.ts +27 -1
  248. package/dist/src/functions/surface/collect-surface.js +323 -13
  249. package/dist/src/functions/surface/generate-surface-doc.js +40 -5
  250. package/dist/src/functions/surface/render-surface-doc.d.ts +12 -0
  251. package/dist/src/functions/surface/render-surface-doc.js +209 -0
  252. package/dist/src/functions/surface/surface-doc.types.d.ts +15 -2
  253. package/dist/src/functions/surface/surface-editorial.d.ts +6 -0
  254. package/dist/src/functions/surface/surface-editorial.js +22 -1
  255. package/dist/src/functions/wirings/agent/serialize-agent-types.js +41 -0
  256. package/dist/src/functions/wirings/agent/serialize-public-agent.js +1 -1
  257. package/dist/src/functions/wirings/auth/serialize-auth-guards.js +1 -18
  258. package/dist/src/functions/wirings/auth/serialize-auth-types.js +7 -0
  259. package/dist/src/functions/wirings/channels/serialize-channel-types.js +9 -17
  260. package/dist/src/functions/wirings/cli/serialize-cli-types.js +7 -6
  261. package/dist/src/functions/wirings/functions/pikku-command-function-types-split.js +1 -1
  262. package/dist/src/functions/wirings/functions/serialize-addon-refs.js +12 -0
  263. package/dist/src/functions/wirings/functions/serialize-function-types.js +23 -36
  264. package/dist/src/functions/wirings/http/serialize-http-types.js +6 -0
  265. package/dist/src/functions/wirings/mcp/serialize-mcp-types.js +10 -0
  266. package/dist/src/functions/wirings/middleware/serialize-middleware-types.js +32 -23
  267. package/dist/src/functions/wirings/queue/serialize-queue-types.js +2 -0
  268. package/dist/src/functions/wirings/scheduler/serialize-scheduler-types.js +2 -0
  269. package/dist/src/functions/wirings/secrets/serialize-secrets-types.js +8 -0
  270. package/dist/src/functions/wirings/setup/serialize-setup-types.d.ts +1 -1
  271. package/dist/src/functions/wirings/setup/serialize-setup-types.js +19 -19
  272. package/dist/src/functions/wirings/triggers/serialize-trigger-types.js +4 -0
  273. package/dist/src/functions/wirings/variables/serialize-variables-types.js +8 -0
  274. package/dist/src/functions/wirings/workflow/serialize-personas.js +4 -0
  275. package/dist/src/functions/wirings/workflow/serialize-scenario-types.js +12 -0
  276. package/dist/src/functions/wirings/workflow/serialize-workflow-types.js +28 -0
  277. package/dist/src/services.js +8 -1
  278. package/dist/src/utils/persona-credentials.js +5 -1
  279. package/dist/tsconfig.tsbuildinfo +1 -1
  280. package/package.json +9 -7
  281. package/snippets-meta.json +131 -0
  282. package/snippets.json +131 -0
  283. package/surface.json +7393 -458
  284. package/console-app/assets/architecture-TIHT7OUA-DgRqRaqo.js +0 -1
  285. package/console-app/assets/channel-37lNznWk.js +0 -1
  286. package/console-app/assets/chunk-XXDRQBXY-B1prMCvW.js +0 -1
  287. package/console-app/assets/classDiagram-JCYQIIEL-BDCX9ZLm.js +0 -1
  288. package/console-app/assets/classDiagram-v2-OCEON4UE-BDCX9ZLm.js +0 -1
  289. package/console-app/assets/eventmodeling-45OFAUF4-BarrKD55.js +0 -1
  290. package/console-app/assets/flowDiagram-UKHOOZJN-B6RiRjcD.js +0 -1
  291. package/console-app/assets/railroad-abnf-AHOZXSZD-lmUjOixE.js +0 -1
  292. package/console-app/assets/railroad-ebnf-EBAXGLYW-ZjdA7OHp.js +0 -1
  293. package/console-app/assets/railroad-peg-LSFZ7HO6-VHSlvwI8.js +0 -1
  294. package/console-app/assets/stateDiagram-v2-UEYNNEHI-BSXWhCvf.js +0 -1
  295. package/console-app/assets/swimlanesDiagram-ULZ7WXOC-BUdsPDKC.js +0 -8
  296. package/dist/.pikku/schemas/schemas/FabricDeployPlanInput.schema.json +0 -1
  297. package/dist/.pikku/schemas/schemas/FabricDeployPlanOutput.schema.json +0 -1
@@ -4,15 +4,30 @@ import { resolveApiContext } from '../lib/config.js';
4
4
  import { getFabricRPC } from '../lib/http.js';
5
5
  import { assertNamedBranchDeploySafety, resolveRef } from '../lib/git.js';
6
6
  import { promptConfirm } from '../lib/prompt.js';
7
- import { added, changed, dim } from '../lib/output.js';
7
+ import { added, changed, removed, dim, table } from '../lib/output.js';
8
+ import { blockedReason, blockedSummary, changesAreEmpty, classifyStatus, describeDeployment, destructiveMigrations, isApprovable, readDeploymentStatus, readWorkers, stateLabel, waitForDeployment, } from '../lib/deployment.js';
9
+ const DEFAULT_TIMEOUT_SECONDS = 900;
8
10
  export const FabricDeployInput = z.object({
9
11
  branch: z.string().optional(),
10
12
  production: z.boolean().optional(),
11
13
  ref: z.string().optional(),
12
- message: z.string().optional(),
13
- autoApply: z.boolean().optional(),
14
+ deploymentId: z.string().optional(),
15
+ sync: z.boolean().optional(),
16
+ autoApprove: z.boolean().optional(),
17
+ allowDestructive: z.boolean().optional(),
18
+ timeout: z.number().optional(),
19
+ json: z.boolean().optional(),
14
20
  });
15
21
  export const FabricDeployValidatedInput = FabricDeployInput.superRefine((value, ctx) => {
22
+ if (value.deploymentId) {
23
+ if (value.branch || value.production) {
24
+ ctx.addIssue({
25
+ code: z.ZodIssueCode.custom,
26
+ message: '--deployment-id already names its target — drop --branch/--production.',
27
+ });
28
+ }
29
+ return;
30
+ }
16
31
  if (!!value.branch === !!value.production) {
17
32
  ctx.addIssue({
18
33
  code: z.ZodIssueCode.custom,
@@ -20,28 +35,58 @@ export const FabricDeployValidatedInput = FabricDeployInput.superRefine((value,
20
35
  });
21
36
  }
22
37
  });
23
- // `plan` resolves the target ref and reports what a deploy would do — nothing
24
- // is queued, so there is no deploymentId/stageId/runId yet. `apply` carries
25
- // those once the deploy is queued. The two intentionally have distinct shapes
26
- // rather than one shape padded with empty-string sentinels.
27
- export const FabricDeployPlanOutput = z.object({
28
- projectId: z.string(),
29
- branch: z.string(),
30
- ref: z.string(),
31
- requestedRef: z.string().optional(),
38
+ const MissingConfig = z.object({
39
+ name: z.string(),
40
+ displayName: z.string().nullable(),
41
+ description: z.string().nullable(),
42
+ docsUrl: z.string().nullable(),
43
+ });
44
+ const Changes = z.object({
45
+ unitsAdded: z.array(z.string()),
46
+ unitsRemoved: z.array(z.string()),
47
+ handlersAdded: z.array(z.string()),
48
+ handlersRemoved: z.array(z.string()),
49
+ workflowsAdded: z.array(z.string()),
50
+ workflowsRemoved: z.array(z.string()),
51
+ workflowsChanged: z.array(z.string()),
52
+ functionsAdded: z.array(z.string()),
53
+ functionsRemoved: z.array(z.string()),
54
+ secretsChanged: z.array(z.string()),
55
+ variablesChanged: z.array(z.string()),
56
+ pendingMigrations: z.array(z.string()),
57
+ migrationRisks: z.array(z.object({
58
+ name: z.string(),
59
+ level: z.enum(['destructive', 'safe']),
60
+ reasons: z.array(z.string()),
61
+ })),
32
62
  });
33
63
  export const FabricDeployApplyOutput = z.object({
64
+ event: z.literal('result'),
65
+ outcome: z.enum(['queued', 'succeeded', 'failed', 'blocked', 'timeout']),
34
66
  projectId: z.string(),
35
- branch: z.string(),
36
- ref: z.string(),
37
67
  deploymentId: z.string(),
38
- stageId: z.string(),
39
- runId: z.string(),
68
+ branch: z.string().optional(),
69
+ ref: z.string().optional(),
70
+ status: z.string().optional(),
71
+ statusReason: z.string().nullable().optional(),
72
+ stageId: z.string().optional(),
73
+ runId: z.string().optional(),
74
+ blockedReason: z
75
+ .enum(['awaiting_approval', 'needs_config', 'needs_attention', 'unknown'])
76
+ .optional(),
77
+ missingSecrets: z.array(MissingConfig).optional(),
78
+ missingVariables: z.array(MissingConfig).optional(),
79
+ approvalWithheld: z.literal('destructive_migrations').optional(),
80
+ changes: Changes.optional(),
81
+ workers: z
82
+ .array(z.object({ name: z.string(), role: z.string(), status: z.string() }))
83
+ .optional(),
84
+ url: z.string().nullable().optional(),
85
+ approved: z.boolean().optional(),
86
+ elapsedMs: z.number().optional(),
87
+ timeoutSeconds: z.number().optional(),
40
88
  });
41
89
  /**
42
- * Shared prep for `deploy plan` and `deploy apply`: authenticate, resolve the
43
- * target branch, and resolve the ref to a concrete sha. Returns everything both
44
- * subcommands need; neither prints — human output lives in the renders.
45
90
  */
46
91
  async function prepDeploy({ branch, production, ref }) {
47
92
  const ctx = await resolveApiContext();
@@ -60,69 +105,271 @@ async function prepDeploy({ branch, production, ref }) {
60
105
  const targetBranch = production ? 'main' : branch;
61
106
  const safety = await assertNamedBranchDeploySafety(targetBranch);
62
107
  const resolved = ref ? ((await resolveRef(ref)) ?? ref) : safety.headSha;
63
- const requestedRef = ref && resolved !== safety.headSha ? ref : undefined;
64
- return {
65
- ctx,
66
- projectId: ctx.projectId,
67
- targetBranch,
68
- resolved,
69
- requestedRef,
70
- safety,
71
- };
108
+ return { ctx, projectId: ctx.projectId, targetBranch, resolved, safety };
72
109
  }
73
- export const FabricDeployPlan = pikkuSessionlessFunc({
74
- description: 'Resolve the target ref and report what a deploy would do.',
75
- input: FabricDeployValidatedInput,
76
- output: FabricDeployPlanOutput,
77
- func: async (_services, input) => {
78
- const { projectId, targetBranch, resolved, requestedRef } = await prepDeploy(input);
79
- return { projectId, branch: targetBranch, ref: resolved, requestedRef };
80
- },
81
- });
110
+ async function prepAttach() {
111
+ const ctx = await resolveApiContext();
112
+ if (!ctx.token) {
113
+ throw new Error('Not logged in. Run `pikku fabric login` first.');
114
+ }
115
+ if (!ctx.projectId) {
116
+ throw new Error('No fabric project linked. Run `pikku fabric link` first.');
117
+ }
118
+ return { ctx, projectId: ctx.projectId };
119
+ }
120
+ const EXIT_BY_OUTCOME = {
121
+ queued: 0,
122
+ succeeded: 0,
123
+ failed: 2,
124
+ blocked: 3,
125
+ timeout: 4,
126
+ };
82
127
  export const FabricDeployApply = pikkuSessionlessFunc({
83
- description: 'Build + deploy a named branch or production (main).',
128
+ description: 'Build + deploy a named branch or production (main), or attach to an existing deployment.',
84
129
  input: FabricDeployValidatedInput,
85
130
  output: FabricDeployApplyOutput,
86
131
  func: async (_services, input) => {
87
- const { ctx, projectId, targetBranch, resolved, safety } = await prepDeploy(input);
88
- // Classic yes/no guard. `--auto-apply` skips it; a non-interactive session
89
- // has no human to answer, so we refuse rather than hang.
90
- if (!input.autoApply) {
91
- const target = `${targetBranch} @ ${resolved.slice(0, 8)}`;
92
- if (!process.stdin.isTTY) {
93
- throw new Error(`Refusing to deploy ${target} without confirmation — re-run with --auto-apply to deploy non-interactively.`);
94
- }
95
- const ok = await promptConfirm(`Deploy ${target}?`);
96
- if (!ok) {
97
- throw new Error('Deploy aborted.');
132
+ const emit = input.json
133
+ ? (event) => console.log(JSON.stringify(event))
134
+ : () => { };
135
+ const timeoutSeconds = input.timeout ?? DEFAULT_TIMEOUT_SECONDS;
136
+ if (timeoutSeconds <= 0) {
137
+ throw new Error('--timeout must be a positive number of seconds.');
138
+ }
139
+ if (input.deploymentId && (input.branch || input.production)) {
140
+ throw new Error('--deployment-id already names its target — drop --branch/--production.');
141
+ }
142
+ const attaching = Boolean(input.deploymentId);
143
+ let projectId;
144
+ let deploymentId;
145
+ let branch;
146
+ let ref;
147
+ let stageId;
148
+ let runId;
149
+ let rpc;
150
+ if (attaching) {
151
+ const { ctx, projectId: id } = await prepAttach();
152
+ projectId = id;
153
+ rpc = getFabricRPC({ apiUrl: ctx.apiUrl, token: ctx.token });
154
+ deploymentId = input.deploymentId;
155
+ const current = await readDeploymentStatus(rpc, deploymentId);
156
+ stageId = current.stageId;
157
+ branch = (await describeDeployment(rpc, projectId, deploymentId))?.branch;
158
+ emit({ event: 'attached', deploymentId, status: current.status });
159
+ }
160
+ else {
161
+ const { ctx, projectId: id, targetBranch, resolved, safety, } = await prepDeploy(input);
162
+ projectId = id;
163
+ branch = targetBranch;
164
+ ref = resolved;
165
+ rpc = getFabricRPC({ apiUrl: ctx.apiUrl, token: ctx.token });
166
+ if (!input.autoApprove) {
167
+ const target = `${branch} @ ${resolved.slice(0, 8)}`;
168
+ if (!process.stdin.isTTY) {
169
+ throw new Error(`Refusing to deploy ${target} without confirmation — re-run with --auto-approve to deploy non-interactively.`);
170
+ }
171
+ if (!(await promptConfirm(`Deploy ${target}?`))) {
172
+ throw new Error('Deploy aborted.');
173
+ }
98
174
  }
175
+ const created = await rpc.invoke('deployByStageKind', {
176
+ projectId,
177
+ branch,
178
+ ref: resolved,
179
+ expectedHeadSha: safety.headSha,
180
+ });
181
+ deploymentId = created.deploymentId;
182
+ stageId = created.stageId;
183
+ runId = created.runId;
184
+ emit({ event: 'created', deploymentId, branch, ref: resolved });
99
185
  }
100
- const rpc = getFabricRPC({ apiUrl: ctx.apiUrl, token: ctx.token });
101
- const result = await rpc.invoke('deployByStageKind', {
186
+ const base = {
187
+ event: 'result',
102
188
  projectId,
103
- branch: targetBranch,
104
- ref: resolved,
105
- expectedHeadSha: safety.headSha,
189
+ deploymentId,
190
+ branch,
191
+ ...(ref ? { ref } : {}),
192
+ ...(stageId ? { stageId } : {}),
193
+ ...(runId ? { runId } : {}),
194
+ };
195
+ if (!input.sync && !attaching) {
196
+ return { ...base, outcome: 'queued' };
197
+ }
198
+ let approvalWithheld;
199
+ const approveGate = async (status) => {
200
+ const described = await describeDeployment(rpc, projectId, deploymentId);
201
+ const destructive = destructiveMigrations(described?.changes);
202
+ if (destructive.length > 0 && !input.allowDestructive) {
203
+ if (input.autoApprove || input.json || !process.stdin.isTTY) {
204
+ approvalWithheld = 'destructive_migrations';
205
+ return false;
206
+ }
207
+ }
208
+ else if (input.autoApprove) {
209
+ return true;
210
+ }
211
+ if (input.json || !process.stdin.isTTY)
212
+ return false;
213
+ const warning = destructive.length > 0
214
+ ? `\n${destructiveLines(destructive).join('\n')}\n`
215
+ : '';
216
+ return promptConfirm(`Plan for ${branch ?? deploymentId} is ready to publish (${stateLabel(status.status, status.statusReason)}).${warning} Approve?`);
217
+ };
218
+ if (!input.sync) {
219
+ const status = await readDeploymentStatus(rpc, deploymentId);
220
+ const klass = classifyStatus(status.status);
221
+ const outcome = klass === 'in_flight' ? 'queued' : klass;
222
+ const finished = await finalise(rpc, projectId, deploymentId, status.stageId, outcome);
223
+ process.exitCode = EXIT_BY_OUTCOME[outcome];
224
+ return {
225
+ ...base,
226
+ outcome,
227
+ status: status.status,
228
+ statusReason: status.statusReason,
229
+ url: status.hostname ? `https://${status.hostname}` : null,
230
+ ...(outcome === 'blocked'
231
+ ? {
232
+ blockedReason: blockedReason(status.statusReason),
233
+ missingSecrets: status.missingSecrets,
234
+ missingVariables: status.missingVariables,
235
+ }
236
+ : {}),
237
+ ...finished,
238
+ };
239
+ }
240
+ const waited = await waitForDeployment({
241
+ rpc,
242
+ deploymentId,
243
+ timeoutMs: timeoutSeconds * 1000,
244
+ approve: approveGate,
245
+ onEvent: emit,
106
246
  });
247
+ const finished = await finalise(rpc, projectId, deploymentId, waited.stageId, waited.outcome);
248
+ process.exitCode = EXIT_BY_OUTCOME[waited.outcome];
107
249
  return {
108
- projectId,
109
- branch: targetBranch,
110
- ref: resolved,
111
- deploymentId: result.deploymentId,
112
- stageId: result.stageId,
113
- runId: result.runId,
250
+ ...base,
251
+ outcome: waited.outcome,
252
+ status: waited.status,
253
+ statusReason: waited.statusReason,
254
+ approved: waited.approved,
255
+ elapsedMs: waited.elapsedMs,
256
+ url: waited.hostname ? `https://${waited.hostname}` : null,
257
+ ...(waited.outcome === 'timeout' ? { timeoutSeconds } : {}),
258
+ ...(waited.outcome === 'blocked'
259
+ ? {
260
+ blockedReason: waited.reason ?? 'unknown',
261
+ missingSecrets: waited.missingSecrets,
262
+ missingVariables: waited.missingVariables,
263
+ ...(approvalWithheld ? { approvalWithheld } : {}),
264
+ }
265
+ : {}),
266
+ ...finished,
114
267
  };
115
268
  },
116
269
  });
117
- export const renderDeployPlan = (_s, { projectId, branch, ref, requestedRef, }) => {
118
- if (requestedRef) {
119
- console.log(dim(`retargeted ${requestedRef} → ${ref.slice(0, 8)}`));
270
+ async function finalise(rpc, projectId, deploymentId, stageId, outcome) {
271
+ const out = {};
272
+ if (outcome === 'queued')
273
+ return out;
274
+ const described = await describeDeployment(rpc, projectId, deploymentId);
275
+ if (described?.changes)
276
+ out.changes = described.changes;
277
+ if (outcome === 'succeeded') {
278
+ out.workers = await readWorkers(rpc, stageId);
120
279
  }
121
- console.log(`${changed('plan')} ${dim('would deploy')} ${branch} ${dim('@')} ${ref.slice(0, 8)} ${dim(`(${projectId})`)}`);
122
- // The coloured added/changed/removed manifest diff lands here once `plan`
123
- // returns it from the preview workflow.
124
- console.log(dim('Run `pikku fabric deploy apply` to execute.'));
280
+ return out;
281
+ }
282
+ const shortList = (names, limit = 8) => names.length <= limit
283
+ ? names.join(', ')
284
+ : `${names.slice(0, limit).join(', ')} +${names.length - limit} more`;
285
+ const destructiveLines = (risks) => risks.map((r) => ` ${removed('! destructive')} ${r.name}${r.reasons.length > 0 ? dim(` (${r.reasons.join(', ')})`) : ''}`);
286
+ const changeLines = (changes) => {
287
+ if (!changes || changesAreEmpty(changes))
288
+ return [];
289
+ const lines = [];
290
+ const add = (label, names, colour) => {
291
+ if (names.length > 0)
292
+ lines.push(` ${colour(label)} ${shortList(names)}`);
293
+ };
294
+ add('+ units', changes.unitsAdded, added);
295
+ add('- units', changes.unitsRemoved, removed);
296
+ add('+ handlers', changes.handlersAdded, added);
297
+ add('- handlers', changes.handlersRemoved, removed);
298
+ add('+ functions', changes.functionsAdded, added);
299
+ add('- functions', changes.functionsRemoved, removed);
300
+ add('+ workflows', changes.workflowsAdded, added);
301
+ add('- workflows', changes.workflowsRemoved, removed);
302
+ add('~ workflows', changes.workflowsChanged, changed);
303
+ add('~ secrets', changes.secretsChanged, changed);
304
+ add('~ variables', changes.variablesChanged, changed);
305
+ add('~ migrations', changes.pendingMigrations, changed);
306
+ lines.push(...destructiveLines(destructiveMigrations(changes)));
307
+ return lines;
308
+ };
309
+ const missingLines = (label, entries) => {
310
+ if (!entries || entries.length === 0)
311
+ return [];
312
+ return [
313
+ ` ${removed(label)}`,
314
+ ...entries.map((e) => ` ${e.name}${e.displayName ? dim(` (${e.displayName})`) : ''}${e.docsUrl ? dim(` — ${e.docsUrl}`) : ''}`),
315
+ ];
125
316
  };
126
- export const renderDeployApply = (_s, { branch, ref, deploymentId }) => {
127
- console.log(`${added('queued')} deploy ${branch} ${dim('@')} ${ref.slice(0, 8)} ${dim('·')} ${deploymentId}`);
317
+ const reattachHint = (deploymentId) => dim(`Re-attach with \`pikku fabric deploy apply --deployment-id ${deploymentId} --sync\`.`);
318
+ export const renderDeployApply = (_s, result) => {
319
+ const { outcome, branch, ref, deploymentId, status, statusReason, changes, workers, url, elapsedMs, timeoutSeconds, approved, } = result;
320
+ const where = branch ?? 'deployment';
321
+ const at = ref ? ` ${dim('@')} ${ref.slice(0, 8)}` : '';
322
+ const took = elapsedMs === undefined ? '' : dim(` in ${Math.round(elapsedMs / 1000)}s`);
323
+ if (outcome === 'queued') {
324
+ console.log(`${added('queued')} deploy ${where}${at} ${dim('·')} ${deploymentId}`);
325
+ if (status) {
326
+ console.log(dim(`status ${stateLabel(status, statusReason ?? null)}`));
327
+ }
328
+ console.log(reattachHint(deploymentId));
329
+ return;
330
+ }
331
+ if (outcome === 'succeeded') {
332
+ console.log(`${added('deployed')} ${where}${at} ${dim('·')} ${deploymentId}${took}`);
333
+ for (const line of changeLines(changes))
334
+ console.log(line);
335
+ if (workers && workers.length > 0) {
336
+ console.log(table(['WORKER', 'ROLE', 'STATUS'], workers.map((w) => [w.name, w.role, w.status])));
337
+ }
338
+ if (url)
339
+ console.log(dim(url));
340
+ return;
341
+ }
342
+ if (outcome === 'blocked') {
343
+ const reason = result.blockedReason ?? 'unknown';
344
+ console.log(`${changed(stateLabel(status ?? 'suspended', statusReason ?? null))} ${where}${at} ${dim('·')} ${deploymentId}`);
345
+ console.log(dim(blockedSummary(reason)));
346
+ for (const line of missingLines('missing secrets', result.missingSecrets)) {
347
+ console.log(line);
348
+ }
349
+ for (const line of missingLines('missing variables', result.missingVariables)) {
350
+ console.log(line);
351
+ }
352
+ for (const line of changeLines(changes))
353
+ console.log(line);
354
+ if (result.approvalWithheld === 'destructive_migrations') {
355
+ console.log(dim('The plan drops or rewrites data. Nothing was published — review the migrations above, then re-run with `--allow-destructive` to accept them.'));
356
+ console.log(dim(`\`pikku fabric deploy apply --deployment-id ${deploymentId} --sync --auto-approve --allow-destructive\``));
357
+ }
358
+ else if (isApprovable(reason) && !approved) {
359
+ console.log(dim(`Approve it with \`pikku fabric deploy apply --deployment-id ${deploymentId} --sync --auto-approve\`.`));
360
+ }
361
+ else if (reason === 'needs_config') {
362
+ console.log(dim('Set the values with `pikku fabric secrets set <name>`.'));
363
+ }
364
+ return;
365
+ }
366
+ if (outcome === 'timeout') {
367
+ console.log(`${changed('timed out')} after ${timeoutSeconds}s ${dim('·')} ${deploymentId} ${dim(`(still ${status ?? 'in flight'})`)}`);
368
+ console.log(reattachHint(deploymentId));
369
+ console.log(dim('Raise the ceiling with `--timeout <seconds>`.'));
370
+ return;
371
+ }
372
+ console.log(`${removed('failed')} ${where}${at} ${dim('·')} ${deploymentId}${took} ${dim(`(${stateLabel(status ?? 'failed', statusReason ?? null)})`)}`);
373
+ if (branch)
374
+ console.log(dim(`Logs: \`pikku fabric logs --branch ${branch}\``));
128
375
  };
@@ -38,6 +38,7 @@ export const FabricInit = pikkuSessionlessFunc({
38
38
  repoUrl: repo,
39
39
  name,
40
40
  defaultBranch: branch,
41
+ productionBranch: 'main',
41
42
  });
42
43
  const path = await writeProjectConfig(process.cwd(), {
43
44
  projectId: result.projectId,
@@ -57,7 +57,10 @@ export const FabricLink = pikkuSessionlessFunc({
57
57
  }
58
58
  }
59
59
  }
60
- const project = await rpc.invoke('importProject', { repoUrl: remoteUrl });
60
+ const project = await rpc.invoke('importProject', {
61
+ repoUrl: remoteUrl,
62
+ productionBranch: 'main',
63
+ });
61
64
  await writeProjectConfig(process.cwd(), {
62
65
  projectId: project.projectId,
63
66
  ...(apiUrlOverride ? { apiUrl: apiUrlOverride } : {}),
@@ -4,21 +4,21 @@ export declare const FabricSecretsRotateInput: z.ZodObject<{
4
4
  force: z.ZodOptional<z.ZodBoolean>;
5
5
  }, z.core.$strip>;
6
6
  export declare const FabricSecretsRotateOutput: z.ZodObject<{
7
- retiredKeyId: z.ZodString;
7
+ retiredKeyId: z.ZodNullable<z.ZodString>;
8
8
  }, z.core.$strip>;
9
9
  export declare const FabricSecretsRotate: import("../../../.pikku/function/pikku-function-types.gen.js").PikkuFunctionConfig<{
10
10
  branch: string;
11
11
  force?: boolean | undefined;
12
12
  }, {
13
- retiredKeyId: string;
13
+ retiredKeyId: string | null;
14
14
  }, "rpc" | "session", import("../../../.pikku/function/pikku-function-types.gen.js").PikkuFunctionSessionless<{
15
15
  branch: string;
16
16
  force?: boolean | undefined;
17
17
  }, {
18
- retiredKeyId: string;
18
+ retiredKeyId: string | null;
19
19
  }, "rpc" | "session", import("../../../.pikku/function/pikku-function-types.gen.js").WiredServices, unknown> | import("../../../.pikku/function/pikku-function-types.gen.js").PikkuFunction<{
20
20
  branch: string;
21
21
  force?: boolean | undefined;
22
22
  }, {
23
- retiredKeyId: string;
23
+ retiredKeyId: string | null;
24
24
  }, "rpc" | "session", import("../../../.pikku/function/pikku-function-types.gen.js").WiredServices>, undefined, undefined>;
@@ -8,7 +8,7 @@ export const FabricSecretsRotateInput = z.object({
8
8
  force: z.boolean().optional(),
9
9
  });
10
10
  export const FabricSecretsRotateOutput = z.object({
11
- retiredKeyId: z.string(),
11
+ retiredKeyId: z.string().nullable(),
12
12
  });
13
13
  export const FabricSecretsRotate = pikkuSessionlessFunc({
14
14
  description: "Retire a stage's sealing key so the next deploy issues a new one. Secrets sealed to the old key must be set again.",
@@ -31,6 +31,6 @@ export const FabricSecretsRotate = pikkuSessionlessFunc({
31
31
  const result = await rpc.invoke('rotateStageSealingKey', { stageId });
32
32
  console.log(`[fabric] retired sealing key ${result.retiredKeyId} on ${branch}`);
33
33
  console.log('[fabric] deploy the stage to issue a new key, then set its secrets again');
34
- return result;
34
+ return { retiredKeyId: result.retiredKeyId };
35
35
  },
36
36
  });
@@ -811,6 +811,71 @@ export async function runValidate(startDir = process.cwd(), opts = {}) {
811
811
  declaredFrontends.push({ slug, cwd: rel, dir, deploy: deploy !== false });
812
812
  }
813
813
  }
814
+ const LOCALHOST_URL_RE = /['"`](?:https?|wss?):\/\/(?:localhost|127\.0\.0\.1|0\.0\.0\.0)(?::\d+)?[^'"`]*['"`]/;
815
+ const ENV_FALLBACK_RE = /(?:import\.meta\.env|process\.env)\s*(?:\.\w+|\[\s*['"][^'"]+['"]\s*\])\s*(?:\?\?|\|\|)\s*['"`](?:https?|wss?):\/\/(?:localhost|127\.0\.0\.1|0\.0\.0\.0)/;
816
+ const API_ENV_READ_RE = /(?:import\.meta\.env|process\.env)\s*(?:\.(\w*(?:API|BACKEND|SERVER)\w*)|\[\s*['"](\w*(?:API|BACKEND|SERVER)\w*)['"]\s*\])/g;
817
+ for (const fe of declaredFrontends) {
818
+ if (!fe.deploy)
819
+ continue;
820
+ const files = [
821
+ ...(await listSourceFiles(join(fe.dir, 'src'))),
822
+ ...(await listSourceFiles(join(fe.dir, 'app'))),
823
+ ...(await listSourceFiles(join(fe.dir, 'pages'))),
824
+ ];
825
+ const envFallbackHits = [];
826
+ const bareHits = [];
827
+ const apiEnvHits = [];
828
+ const apiEnvNames = new Set();
829
+ let derivesOrigin = false;
830
+ for (const file of files) {
831
+ const rel = file.slice(fe.dir.length + 1).replace(/\\/g, '/');
832
+ if (/\.(test|spec)\.[jt]sx?$/.test(rel) ||
833
+ rel.endsWith('.d.ts') ||
834
+ /(?:^|\/)(?:__tests__|__mocks__)\//.test(rel)) {
835
+ continue;
836
+ }
837
+ const text = await readTextSafe(file);
838
+ if (!text)
839
+ continue;
840
+ if (/\blocation\s*\.\s*origin\b/.test(text))
841
+ derivesOrigin = true;
842
+ for (const raw of text.split('\n')) {
843
+ const line = raw.trim();
844
+ if (line.startsWith('//') ||
845
+ line.startsWith('*') ||
846
+ line.startsWith('/*')) {
847
+ continue;
848
+ }
849
+ API_ENV_READ_RE.lastIndex = 0;
850
+ let m;
851
+ while ((m = API_ENV_READ_RE.exec(line)) !== null) {
852
+ apiEnvNames.add((m[1] ?? m[2]));
853
+ if (!apiEnvHits.includes(rel))
854
+ apiEnvHits.push(rel);
855
+ }
856
+ if (ENV_FALLBACK_RE.test(line)) {
857
+ if (!envFallbackHits.includes(rel))
858
+ envFallbackHits.push(rel);
859
+ }
860
+ else if (LOCALHOST_URL_RE.test(line)) {
861
+ if (!bareHits.includes(rel))
862
+ bareHits.push(rel);
863
+ }
864
+ }
865
+ }
866
+ const sample = (hits) => hits.slice(0, 5).join(', ') +
867
+ (hits.length > 5 ? `, +${hits.length - 5} more` : '');
868
+ const originFix = lines('Derive the base from the page instead of from a variable nobody sets:', '', ' const configured = import.meta.env.VITE_API_URL', ' const remote = !/^(localhost|127\\.0\\.0\\.1)$/.test(window.location.hostname)', ' // a localhost base served from a real origin is a stray dev value', ' if (configured && !(remote && /\\/\\/(localhost|127\\.0\\.0\\.1)(:|\\/)/.test(configured))) {', ' return configured', ' }', " return window.location.origin + '/api'", '', 'Fabric serves the app and the API on one hostname and routes /api/* to', 'the API units, so the derived value is correct on every stage, preview', 'and custom domain. Guard the `window` read for SSR.');
869
+ if (envFallbackHits.length > 0) {
870
+ e(`frontend-env-fallback-localhost-${fe.slug}`, `frontend "${fe.slug}" defaults a build-time env read to a localhost URL (${sample(envFallbackHits)}) — the deploy sets no VITE_*/NEXT_PUBLIC_* variable at build time, so that fallback is what the production bundle ships and every call from a browser will time out`, fe.dir, originFix);
871
+ }
872
+ else if (apiEnvHits.length > 0 && !derivesOrigin) {
873
+ e(`frontend-api-base-not-derived-${fe.slug}`, `frontend "${fe.slug}" takes its API base from ${[...apiEnvNames].sort().join(', ')} (${sample(apiEnvHits)}) and never derives it from the page origin — fabric binds VITE_API_URL on the deployed Worker at runtime, so the build inlines nothing and whatever follows the read is what ships`, fe.dir, originFix);
874
+ }
875
+ if (bareHits.length > 0 && !derivesOrigin) {
876
+ e(`frontend-localhost-url-${fe.slug}`, `frontend "${fe.slug}" hardcodes a localhost URL (${sample(bareHits)}) — unreachable from any deployed page`, fe.dir, originFix);
877
+ }
878
+ }
814
879
  // ── apps/ vs fabric.config.json frontends ─────────────────────────────
815
880
  const appsDir = join(root, 'apps');
816
881
  if (existsSync(appsDir)) {
@@ -1061,6 +1126,64 @@ export async function runValidate(startDir = process.cwd(), opts = {}) {
1061
1126
  }
1062
1127
  }
1063
1128
  }
1129
+ // ── scenario steps must locate by i18n key, not rendered copy ──────────
1130
+ // A browser step that says getByLabel('Full Name') passes only while the app
1131
+ // happens to render the base locale, and a copy edit breaks it as a timeout
1132
+ // on a selector — the failure points at the wizard rather than at the rename
1133
+ // that caused it. Any literal in a step file that is verbatim a value in the
1134
+ // base catalogue is that mistake: the catalogue already holds the string
1135
+ // under a key the test can read. Comments are stripped first, because the
1136
+ // prose around a step quotes the copy it is explaining.
1137
+ {
1138
+ const relFile = (p) => p.slice(root.length + 1).replace(/\\/g, '/');
1139
+ const keysByValue = new Map();
1140
+ const appsRoot = join(root, 'apps');
1141
+ if (existsSync(appsRoot)) {
1142
+ for (const ent of await readdir(appsRoot, { withFileTypes: true })) {
1143
+ if (!ent.isDirectory())
1144
+ continue;
1145
+ const appPath = join(appsRoot, ent.name);
1146
+ const settings = await readJsonSafe(join(appPath, 'project.inlang', 'settings.json'));
1147
+ if (!settings)
1148
+ continue;
1149
+ const catalogue = await readJsonSafe(join(appPath, 'messages', `${settings.baseLocale ?? 'en'}.json`));
1150
+ if (!catalogue)
1151
+ continue;
1152
+ for (const [key, value] of Object.entries(catalogue)) {
1153
+ if (typeof value !== 'string' || value.trim().length < 2)
1154
+ continue;
1155
+ const owners = keysByValue.get(value) ?? [];
1156
+ owners.push(key);
1157
+ keysByValue.set(value, owners);
1158
+ }
1159
+ }
1160
+ }
1161
+ if (keysByValue.size > 0) {
1162
+ const STRING_LITERAL = /(?<![A-Za-z0-9_$])(['"])((?:[^\\\n]|\\.){2,200}?)\1/g;
1163
+ for (const file of await walkSourceFiles(root)) {
1164
+ if (!/\.(steps|scenario)\.tsx?$/.test(file))
1165
+ continue;
1166
+ const text = await readTextSafe(file);
1167
+ if (!text)
1168
+ continue;
1169
+ const code = text
1170
+ .replace(/\/\*[\s\S]*?\*\//g, '')
1171
+ .replace(/(^|[^:'"`\\])\/\/[^\n]*/g, '$1');
1172
+ const hits = [];
1173
+ for (const match of code.matchAll(STRING_LITERAL)) {
1174
+ const literal = match[2];
1175
+ if (!literal)
1176
+ continue;
1177
+ const keys = keysByValue.get(literal);
1178
+ if (keys)
1179
+ hits.push(`"${literal}" → ${keys.join(' | ')}`);
1180
+ }
1181
+ if (hits.length === 0)
1182
+ continue;
1183
+ e(`scenario-hardcoded-copy-${relFile(file).replace(/[^a-z0-9]/gi, '-')}`, `${relFile(file)} hardcodes ${hits.length} string(s) the message catalogue already owns — the step passes only while the app renders the base locale, and a copy edit breaks it as an unexplained selector timeout`, file, lines('Read each string from the catalogue instead of repeating it:', ...hits.slice(0, 10).map((h) => ` - ${h}`), ...(hits.length > 10 ? [` …and ${hits.length - 10} more`] : []), 'Type the lookup off the catalogue so a renamed key is a compile error:', " import type messages from '<app>/messages/<baseLocale>.json'", ' export type MessageKey = keyof typeof messages'));
1184
+ }
1185
+ }
1186
+ }
1064
1187
  // ── packages/theme + packages/components ──────────────────────────────
1065
1188
  const designDocUrl = 'https://pikkufabric.dev/docs/design';
1066
1189
  const designSeverity = hasMantineFrontend ? w : info;