@pikku/cli 0.12.153 → 0.12.155
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.
- package/console-app/assets/{HelpPanel-0XQ4CyKC.js → HelpPanel-Ndvkqpn8.js} +1 -1
- package/console-app/assets/{abnfDiagram-VCTEODGH-DZTF_2aX.js → abnfDiagram-VCTEODGH-DvUR4gej.js} +1 -1
- package/console-app/assets/architecture-7GRP2DOG-DJkDVzM_.js +1 -0
- package/console-app/assets/{architectureDiagram-5GKGNRK7-Re4-6X-k.js → architectureDiagram-5GKGNRK7-HLwJ3llk.js} +1 -1
- package/console-app/assets/{blockDiagram-I7D4REHJ-Dbj7SnRK.js → blockDiagram-I7D4REHJ-LMSdIVfc.js} +1 -1
- package/console-app/assets/{c4Diagram-7LVT6UL2-DUr02Wxh.js → c4Diagram-7LVT6UL2-CcWW9nYv.js} +1 -1
- package/console-app/assets/channel-C6yZyX_m.js +1 -0
- package/console-app/assets/{chunk-4HAMMTFA-DjatzNf_.js → chunk-4HAMMTFA-Dxcu8ptc.js} +1 -1
- package/console-app/assets/{chunk-75Z2AOVW-BGsmWEdU.js → chunk-75Z2AOVW-BBINCcJe.js} +1 -1
- package/console-app/assets/{chunk-DU6HZSFF-CC7WiVgI.js → chunk-DU6HZSFF-BgJhrYpo.js} +1 -1
- package/console-app/assets/{chunk-F27PBJKO-BATuW9Ej.js → chunk-F27PBJKO-CctviqIo.js} +1 -1
- package/console-app/assets/{chunk-GMAD6QVW-CgHNo00B.js → chunk-GMAD6QVW-BJ-InAqp.js} +1 -1
- package/console-app/assets/{chunk-GVQU2GXP-VT_xckd9.js → chunk-GVQU2GXP-DaeerGJS.js} +1 -1
- package/console-app/assets/{chunk-IMKFNOWR-BhSVbWtF.js → chunk-IMKFNOWR-eOSAFAc9.js} +1 -1
- package/console-app/assets/{chunk-L3NEJ4N5-HUF6a3Xl.js → chunk-L3NEJ4N5-DRfMBpkp.js} +1 -1
- package/console-app/assets/{chunk-OSK3NFVY-C_LPDGIB.js → chunk-OSK3NFVY-DMZ2WBA1.js} +1 -1
- package/console-app/assets/{chunk-P2QGCYS3-lWDBgw4Q.js → chunk-P2QGCYS3-d0BFQiY1.js} +1 -1
- package/console-app/assets/{chunk-POPQ4Y6H--6JTzmZJ.js → chunk-POPQ4Y6H-D4zICDtR.js} +1 -1
- package/console-app/assets/{chunk-PWAF6VOD-C1GqaJJs.js → chunk-PWAF6VOD-_v9wUl6m.js} +1 -1
- package/console-app/assets/{chunk-SHT3W25Y-Dd_4Zpdj.js → chunk-SHT3W25Y-DZ3Wa0Mc.js} +1 -1
- package/console-app/assets/{chunk-SVP7TREG-B8OY7dfD.js → chunk-SVP7TREG-2yCR3ywB.js} +1 -1
- package/console-app/assets/{chunk-TICWLB2K-B8S7Hmnu.js → chunk-TICWLB2K-CtulM0X6.js} +1 -1
- package/console-app/assets/chunk-XXDRQBXY-CLsn_tEh.js +1 -0
- package/console-app/assets/classDiagram-ZZMXUADV-D7FKceOo.js +1 -0
- package/console-app/assets/classDiagram-v2-VYDZK3BY-D7FKceOo.js +1 -0
- package/console-app/assets/{cose-bilkent-JH36ORCC-C6RM8oPO.js → cose-bilkent-JH36ORCC-DNc5wiJ_.js} +1 -1
- package/console-app/assets/{cynefin-OW5HDTMX-COh9rFYY.js → cynefin-OW5HDTMX-CQPn9kED.js} +1 -1
- package/console-app/assets/{cynefinDiagram-5FMLGOSQ-Dd9AR17w.js → cynefinDiagram-5FMLGOSQ-CkW1ZG13.js} +1 -1
- package/console-app/assets/{dagre-BDMvDAer.js → dagre-BcTdbH8b.js} +1 -1
- package/console-app/assets/{dagre-GXQ25YYZ-C_nBUPgr.js → dagre-GXQ25YYZ-Cgvwy7_U.js} +1 -1
- package/console-app/assets/{diagram-S7CK7UJ4-BGOobQeC.js → diagram-S7CK7UJ4-JB3GlMwZ.js} +1 -1
- package/console-app/assets/{diagram-UQ7AKVKN-CAF_vcj0.js → diagram-UQ7AKVKN-CaIeYJXa.js} +1 -1
- package/console-app/assets/{diagram-VSXAHHWV-q-aY0Nsc.js → diagram-VSXAHHWV-Cku8J3KG.js} +1 -1
- package/console-app/assets/{diagram-VX7I27RA-CnUibSOe.js → diagram-VX7I27RA-Dp3jeYrS.js} +1 -1
- package/console-app/assets/{diagram-Z3DM3KII-DY0V5kOJ.js → diagram-Z3DM3KII-B56Ys0Pf.js} +1 -1
- package/console-app/assets/{ebnfDiagram-PWID7BFC-CXp4CmEF.js → ebnfDiagram-PWID7BFC-CfxeEpk1.js} +1 -1
- package/console-app/assets/{erDiagram-RLTQ6QDP-CKnfXmPl.js → erDiagram-RLTQ6QDP-Dp9sOoSf.js} +1 -1
- package/console-app/assets/eventmodeling-NTZA5JFV-CccBkMWb.js +1 -0
- package/console-app/assets/flowDiagram-HODETNUW-Cp_XHTFC.js +1 -0
- package/console-app/assets/{ganttDiagram-EL5Y4UJY-D6v_RJ7o.js → ganttDiagram-EL5Y4UJY-BsD1LYkb.js} +1 -1
- package/console-app/assets/{gitGraph-4MIJSDKK-y3kWDddY.js → gitGraph-4MIJSDKK-CSHhAZoD.js} +1 -1
- package/console-app/assets/{gitGraphDiagram-WWUBYQGX-CBaE24KN.js → gitGraphDiagram-WWUBYQGX-CZ_0OI7F.js} +1 -1
- package/console-app/assets/{graphlib-DAA_TPmU.js → graphlib-Bpf494dL.js} +1 -1
- package/console-app/assets/{index-HuTd6kcC.js → index-DXtR4J7Y.js} +68 -68
- package/console-app/assets/{info-A6RAGUB7-BvxfRJ9-.js → info-A6RAGUB7-Cym2YsaS.js} +1 -1
- package/console-app/assets/{infoDiagram-27XIBGKW-BlFmgW96.js → infoDiagram-27XIBGKW-n9atnl-K.js} +1 -1
- package/console-app/assets/{ishikawaDiagram-5VMMS53U-Dpwhnwwq.js → ishikawaDiagram-5VMMS53U-BeLDkr8-.js} +1 -1
- package/console-app/assets/{journeyDiagram-3NMN7TZE-iOSeOQma.js → journeyDiagram-3NMN7TZE-B__R_eOL.js} +1 -1
- package/console-app/assets/{kanban-definition-UXKFOSKX-DFGTB8S5.js → kanban-definition-UXKFOSKX-Cwsl1hYB.js} +1 -1
- package/console-app/assets/{line-B_5qZKoM.js → line-UWFHtT2i.js} +1 -1
- package/console-app/assets/{linear-BmXUYu4J.js → linear-BHDHoGpb.js} +1 -1
- package/console-app/assets/{mermaid-parser.core-DyPi3Lbr.js → mermaid-parser.core-CyGW9xht.js} +3 -3
- package/console-app/assets/{mermaid.core-S4y9jX8K.js → mermaid.core-zeBKxakC.js} +4 -4
- package/console-app/assets/{mindmap-definition-YA3MSWOX-Bl09mCaS.js → mindmap-definition-YA3MSWOX-bZ2kbbMM.js} +1 -1
- package/console-app/assets/{packet-AYTQ26CC-B5zoasmU.js → packet-AYTQ26CC-DtH3ZjsO.js} +1 -1
- package/console-app/assets/{pegDiagram-XKGWAZYB-CAa0SOHf.js → pegDiagram-XKGWAZYB-Cy-M_2Zc.js} +1 -1
- package/console-app/assets/{pie-WAS4IAKB-C91xXCXY.js → pie-WAS4IAKB-DEZDAaJW.js} +1 -1
- package/console-app/assets/{pieDiagram-E7YTZNPT-CmUHVYwz.js → pieDiagram-E7YTZNPT-Ce3Yl--P.js} +1 -1
- package/console-app/assets/{quadrantDiagram-AXDQQJYC-XWsej4ss.js → quadrantDiagram-AXDQQJYC-BTK8v4H5.js} +1 -1
- package/console-app/assets/{radar-RG4KPBEZ-B7ieCnSw.js → radar-RG4KPBEZ-CTPhaLOE.js} +1 -1
- package/console-app/assets/{railroad-74A4TZTK-KTKjMg4U.js → railroad-74A4TZTK-DMa9G1LV.js} +1 -1
- package/console-app/assets/railroad-abnf-HS5TGJTU-K0DgRobv.js +1 -0
- package/console-app/assets/railroad-ebnf-LZEXJU2U-CHEGHd9y.js +1 -0
- package/console-app/assets/railroad-peg-WCYAUIDC-EYHvZbXp.js +1 -0
- package/console-app/assets/{railroadDiagram-O6MQD6OU-oh1FjI2K.js → railroadDiagram-O6MQD6OU-CYbkYMqD.js} +1 -1
- package/console-app/assets/{requirementDiagram-BXWQKSXE-D6z7hLfj.js → requirementDiagram-BXWQKSXE-DjWjfWOk.js} +1 -1
- package/console-app/assets/{sankeyDiagram-P5KCCOFB-DFb92jfp.js → sankeyDiagram-P5KCCOFB-6sAcPgDK.js} +1 -1
- package/console-app/assets/{sequenceDiagram-WJ2MYXX4-BRKj-PG1.js → sequenceDiagram-WJ2MYXX4-DzyU1CIr.js} +1 -1
- package/console-app/assets/{src-DYBVouJk.js → src-0ppm3vZe.js} +1 -1
- package/console-app/assets/{stateDiagram-D77RDMKH-BfTLNw5t.js → stateDiagram-D77RDMKH-S5osVh5p.js} +1 -1
- package/console-app/assets/stateDiagram-v2-MP3YSRHH-BZUe_KiH.js +1 -0
- package/console-app/assets/{swimlanes-42K2YHIH-DXkNYzX9.js → swimlanes-42K2YHIH-Dd7HjelH.js} +1 -1
- package/console-app/assets/swimlanesDiagram-VR7AAH4N-D6xRypPY.js +8 -0
- package/console-app/assets/{timeline-definition-24CTP7MA-B8m2V75P.js → timeline-definition-24CTP7MA-eZ3AIIpc.js} +1 -1
- package/console-app/assets/{treeView-Q6P3EWNA-BisqOzat.js → treeView-Q6P3EWNA-DF5sOT6y.js} +1 -1
- package/console-app/assets/{treemap-WGGIJYW6-DOxEXpb1.js → treemap-WGGIJYW6-Bob0iUUb.js} +1 -1
- package/console-app/assets/{vennDiagram-4TSXK5OY-ZeuU7o23.js → vennDiagram-4TSXK5OY-CeowTqyG.js} +1 -1
- package/console-app/assets/{wardley-WFR3VGLG-sspeOMuz.js → wardley-WFR3VGLG-DrnQFkZZ.js} +1 -1
- package/console-app/assets/{wardleyDiagram-VM6X3IG4-CF2vzNJV.js → wardleyDiagram-VM6X3IG4-Dsfkp6D5.js} +1 -1
- package/console-app/assets/{xychartDiagram-S5SC5T6Z-BR9XBq3s.js → xychartDiagram-S5SC5T6Z-YC_qsmJw.js} +1 -1
- package/console-app/index.html +1 -1
- package/dist/.pikku/addon/index.d.ts +1 -1
- package/dist/.pikku/addon/index.js +1 -1
- package/dist/.pikku/addon/pikku-addon-types.gen.d.ts +1 -1
- package/dist/.pikku/addon/pikku-addon-types.gen.js +1 -1
- package/dist/.pikku/agent/index.d.ts +1 -1
- package/dist/.pikku/agent/index.js +1 -1
- package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +1 -1
- package/dist/.pikku/agent/pikku-model-aliases.gen.js +1 -1
- package/dist/.pikku/analytics/index.d.ts +1 -1
- package/dist/.pikku/analytics/index.js +1 -1
- package/dist/.pikku/analytics/pikku-analytics-types.gen.d.ts +1 -1
- package/dist/.pikku/analytics/pikku-analytics-types.gen.js +1 -1
- package/dist/.pikku/auth/index.d.ts +1 -1
- package/dist/.pikku/auth/index.js +1 -1
- package/dist/.pikku/auth/pikku-auth-types.gen.d.ts +1 -1
- package/dist/.pikku/auth/pikku-auth-types.gen.js +1 -1
- package/dist/.pikku/channel/index.d.ts +1 -1
- package/dist/.pikku/channel/index.js +1 -1
- package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +1 -1
- package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
- package/dist/.pikku/cli/index.d.ts +1 -1
- package/dist/.pikku/cli/index.js +1 -1
- package/dist/.pikku/cli/pikku-cli-channel.js +1 -1
- package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-client.gen.js +15 -5
- package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.json +1 -1
- package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-types.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.json +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli.gen.js +15 -6
- package/dist/.pikku/error/index.d.ts +1 -1
- package/dist/.pikku/error/index.js +1 -1
- package/dist/.pikku/error/pikku-error-types.gen.d.ts +1 -1
- package/dist/.pikku/error/pikku-error-types.gen.js +1 -1
- package/dist/.pikku/function/index.d.ts +1 -1
- package/dist/.pikku/function/index.js +1 -1
- package/dist/.pikku/function/pikku-function-types.gen.d.ts +1 -1
- package/dist/.pikku/function/pikku-function-types.gen.js +1 -1
- package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
- package/dist/.pikku/function/pikku-functions-meta.gen.json +33 -33
- package/dist/.pikku/function/pikku-functions.gen.js +1 -1
- package/dist/.pikku/gateway/index.d.ts +1 -1
- package/dist/.pikku/gateway/index.js +1 -1
- package/dist/.pikku/gateway/pikku-gateway-types.gen.d.ts +1 -1
- package/dist/.pikku/gateway/pikku-gateway-types.gen.js +1 -1
- package/dist/.pikku/http/index.d.ts +1 -1
- package/dist/.pikku/http/index.js +1 -1
- package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
- package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
- package/dist/.pikku/mcp/index.d.ts +1 -1
- package/dist/.pikku/mcp/index.js +1 -1
- package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
- package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
- package/dist/.pikku/middleware/index.d.ts +1 -1
- package/dist/.pikku/middleware/index.js +1 -1
- package/dist/.pikku/middleware/pikku-middleware-types.gen.d.ts +1 -1
- package/dist/.pikku/middleware/pikku-middleware-types.gen.js +1 -1
- package/dist/.pikku/pikku-bootstrap-scenarios.gen.d.ts +1 -1
- package/dist/.pikku/pikku-bootstrap-scenarios.gen.js +1 -1
- package/dist/.pikku/pikku-bootstrap.gen.d.ts +1 -1
- package/dist/.pikku/pikku-bootstrap.gen.js +1 -1
- package/dist/.pikku/pikku-services.gen.d.ts +1 -1
- package/dist/.pikku/queue/index.d.ts +1 -1
- package/dist/.pikku/queue/index.js +1 -1
- package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
- package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
- package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +1 -1
- package/dist/.pikku/scenarios/index.d.ts +1 -1
- package/dist/.pikku/scenarios/index.js +1 -1
- package/dist/.pikku/scenarios/pikku-personas.gen.js +1 -1
- package/dist/.pikku/scenarios/pikku-scenario-functions-meta.gen.js +1 -1
- package/dist/.pikku/scenarios/pikku-scenario-functions.gen.d.ts +1 -1
- package/dist/.pikku/scenarios/pikku-scenario-types.gen.d.ts +1 -1
- package/dist/.pikku/scenarios/pikku-scenario-wirings-meta.gen.js +1 -1
- package/dist/.pikku/scenarios/pikku-scenario-wirings.gen.d.ts +1 -1
- package/dist/.pikku/scenarios/schemas/register.gen.d.ts +1 -1
- package/dist/.pikku/scenarios/schemas/register.gen.js +1 -1
- package/dist/.pikku/scheduler/index.d.ts +1 -1
- package/dist/.pikku/scheduler/index.js +1 -1
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
- package/dist/.pikku/schemas/register.gen.js +1 -1
- package/dist/.pikku/scopes/index.d.ts +1 -1
- package/dist/.pikku/scopes/index.js +1 -1
- package/dist/.pikku/scopes/pikku-flags.gen.d.ts +1 -1
- package/dist/.pikku/scopes/pikku-personas.gen.js +1 -1
- package/dist/.pikku/scopes/pikku-roles.gen.d.ts +1 -1
- package/dist/.pikku/scopes/pikku-scope-types.gen.d.ts +1 -1
- package/dist/.pikku/scopes/pikku-scope-types.gen.js +1 -1
- package/dist/.pikku/scopes/pikku-scopes.gen.d.ts +1 -1
- package/dist/.pikku/secrets/index.d.ts +1 -1
- package/dist/.pikku/secrets/index.js +1 -1
- package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +1 -1
- package/dist/.pikku/secrets/pikku-secret-types.gen.js +1 -1
- package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +1 -1
- package/dist/.pikku/secrets/pikku-secrets.gen.js +1 -1
- package/dist/.pikku/services/pikku-meta-service.gen.d.ts +1 -1
- package/dist/.pikku/services/pikku-meta-service.gen.js +1 -1
- package/dist/.pikku/setup/index.d.ts +1 -1
- package/dist/.pikku/setup/index.js +1 -1
- package/dist/.pikku/setup/pikku-setup-types.gen.d.ts +1 -1
- package/dist/.pikku/setup/pikku-setup-types.gen.js +1 -1
- package/dist/.pikku/trigger/index.d.ts +1 -1
- package/dist/.pikku/trigger/index.js +1 -1
- package/dist/.pikku/trigger/pikku-trigger-types.gen.d.ts +1 -1
- package/dist/.pikku/trigger/pikku-trigger-types.gen.js +1 -1
- package/dist/.pikku/variables/index.d.ts +1 -1
- package/dist/.pikku/variables/index.js +1 -1
- package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +1 -1
- package/dist/.pikku/variables/pikku-variable-types.gen.js +1 -1
- package/dist/.pikku/variables/pikku-variables.gen.d.ts +1 -1
- package/dist/.pikku/variables/pikku-variables.gen.js +1 -1
- package/dist/.pikku/workflow/index.d.ts +1 -1
- package/dist/.pikku/workflow/index.js +1 -1
- package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +1 -1
- package/dist/.pikku/workflow/pikku-workflow-types.gen.js +1 -1
- package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +1 -1
- package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +1 -1
- package/dist/bin/pikku-bin.mjs +2 -2
- package/dist/bin/pikku.js +32 -2
- package/dist/src/deploy/build-pipeline.d.ts +43 -0
- package/dist/src/deploy/build-pipeline.js +79 -30
- package/dist/src/fabric/fabric-commands.js +3 -1
- package/dist/src/fabric/functions/add.function.js +4 -3
- package/dist/src/fabric/functions/changes-file.function.js +2 -1
- package/dist/src/fabric/functions/changes-shot.function.js +3 -2
- package/dist/src/fabric/functions/db-schema.function.js +3 -2
- package/dist/src/fabric/functions/deploy-list.function.js +3 -2
- package/dist/src/fabric/functions/deploy-units.function.js +3 -2
- package/dist/src/fabric/functions/deploy.function.js +4 -4
- package/dist/src/fabric/functions/domains-add.function.js +4 -3
- package/dist/src/fabric/functions/domains-list.function.js +3 -2
- package/dist/src/fabric/functions/domains-remove.function.js +5 -4
- package/dist/src/fabric/functions/errors.function.js +3 -2
- package/dist/src/fabric/functions/findings-flush.function.js +2 -1
- package/dist/src/fabric/functions/init.function.js +3 -2
- package/dist/src/fabric/functions/link.function.js +10 -10
- package/dist/src/fabric/functions/login.function.js +4 -3
- package/dist/src/fabric/functions/logs.function.js +2 -2
- package/dist/src/fabric/functions/metrics.function.js +3 -2
- package/dist/src/fabric/functions/projects-list.function.js +2 -1
- package/dist/src/fabric/functions/publish.function.js +7 -6
- package/dist/src/fabric/functions/report.function.js +4 -3
- package/dist/src/fabric/functions/rollback.function.js +3 -2
- package/dist/src/fabric/functions/secrets-delete.function.js +5 -4
- package/dist/src/fabric/functions/secrets-list.function.js +3 -2
- package/dist/src/fabric/functions/secrets-rotate.function.js +4 -3
- package/dist/src/fabric/functions/secrets-set.function.js +11 -4
- package/dist/src/fabric/functions/smoke.function.js +4 -3
- package/dist/src/fabric/functions/status.function.js +3 -2
- package/dist/src/fabric/functions/trace.function.js +3 -2
- package/dist/src/fabric/functions/variables-get.function.js +3 -2
- package/dist/src/fabric/functions/variables-set.function.js +3 -2
- package/dist/src/fabric/lib/changes.js +3 -2
- package/dist/src/fabric/lib/config.js +2 -1
- package/dist/src/fabric/lib/deployment.js +2 -1
- package/dist/src/fabric/lib/git.d.ts +10 -1
- package/dist/src/fabric/lib/git.js +10 -1
- package/dist/src/fabric/lib/prompt.d.ts +14 -5
- package/dist/src/fabric/lib/prompt.js +78 -15
- package/dist/src/fabric/lib/report-environment.d.ts +5 -4
- package/dist/src/fabric/lib/report-environment.js +18 -4
- package/dist/src/fabric/lib/sealed-box.js +3 -2
- package/dist/src/fabric/lib/stage.js +3 -2
- package/dist/src/functions/commands/deploy-apply.js +1 -0
- package/dist/src/functions/commands/deploy-plan.js +1 -0
- package/dist/src/functions/commands/watch.js +5 -2
- package/dist/src/functions/db/sqlite/scenario-baseline.js +5 -0
- package/dist/src/functions/wirings/agent/serialize-public-agent.js +2 -0
- package/dist/src/functions/wirings/cli/serialize-channel-cli-client.js +18 -4
- package/dist/src/functions/wirings/cli/serialize-local-cli-bootstrap.js +16 -5
- package/dist/src/functions/wirings/functions/pikku-command-addon-types.js +26 -5
- package/dist/src/functions/wirings/functions/serialize-addon-types.d.ts +1 -1
- package/dist/src/functions/wirings/functions/serialize-addon-types.js +46 -1
- package/dist/src/functions/wirings/mcp/pikku-command-mcp.js +3 -1
- package/dist/src/functions/wirings/middleware/pikku-command-middleware.js +13 -1
- package/dist/src/functions/wirings/middleware/serialize-middleware-imports.d.ts +13 -0
- package/dist/src/functions/wirings/middleware/serialize-middleware-imports.js +48 -8
- package/dist/src/utils/pikku-cli-config-error.d.ts +8 -3
- package/dist/src/utils/pikku-cli-config-error.js +8 -3
- package/dist/src/utils/pikku-cli-config.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -9
- package/surface.json +4 -16
- package/console-app/assets/architecture-7GRP2DOG-NotVOJ5Y.js +0 -1
- package/console-app/assets/channel-DU63_zXh.js +0 -1
- package/console-app/assets/chunk-XXDRQBXY-BLuHuEZN.js +0 -1
- package/console-app/assets/classDiagram-ZZMXUADV-BTYfUi7u.js +0 -1
- package/console-app/assets/classDiagram-v2-VYDZK3BY-BTYfUi7u.js +0 -1
- package/console-app/assets/eventmodeling-NTZA5JFV-CBfQhnG8.js +0 -1
- package/console-app/assets/flowDiagram-HODETNUW-BnY3G7p6.js +0 -1
- package/console-app/assets/railroad-abnf-HS5TGJTU-e9AlsYmr.js +0 -1
- package/console-app/assets/railroad-ebnf-LZEXJU2U-BVX8UG1z.js +0 -1
- package/console-app/assets/railroad-peg-WCYAUIDC-BzWQFvD9.js +0 -1
- package/console-app/assets/stateDiagram-v2-MP3YSRHH-B8sMNnnF.js +0 -1
- package/console-app/assets/swimlanesDiagram-VR7AAH4N-CiZdLDyk.js +0 -8
|
@@ -6,6 +6,7 @@ import { tmpdir } from 'node:os';
|
|
|
6
6
|
import { execFileSync } from 'node:child_process';
|
|
7
7
|
import { pikkuSessionlessFunc } from '../../../.pikku/function/index.js';
|
|
8
8
|
import { resolveApiContext } from '../lib/config.js';
|
|
9
|
+
import { FabricPreconditionError } from '../lib/errors.js';
|
|
9
10
|
export const FabricPublishInput = z.object({
|
|
10
11
|
dir: z.string().optional(),
|
|
11
12
|
apiUrl: z.string().optional(),
|
|
@@ -33,18 +34,18 @@ export const FabricPublish = pikkuSessionlessFunc({
|
|
|
33
34
|
const verification = await rpc.invoke('FabricAddonVerify', { dir });
|
|
34
35
|
await cli?.channel.send(verification);
|
|
35
36
|
if (!verification.ok) {
|
|
36
|
-
throw new
|
|
37
|
+
throw new FabricPreconditionError('Addon verification failed — fix the errors above before publishing.');
|
|
37
38
|
}
|
|
38
39
|
const ctx = await resolveApiContext({ apiUrlOverride });
|
|
39
40
|
if (!ctx.token)
|
|
40
|
-
throw new
|
|
41
|
+
throw new FabricPreconditionError('Not logged in. Run `pikku fabric login` first.');
|
|
41
42
|
const packageDir = dir ?? process.cwd();
|
|
42
43
|
const pkgPath = join(packageDir, 'package.json');
|
|
43
44
|
if (!existsSync(pkgPath))
|
|
44
|
-
throw new
|
|
45
|
+
throw new FabricPreconditionError(`No package.json found in ${packageDir}`);
|
|
45
46
|
const pkg = JSON.parse(await readFile(pkgPath, 'utf8'));
|
|
46
47
|
if (!pkg.name || !pkg.version)
|
|
47
|
-
throw new
|
|
48
|
+
throw new FabricPreconditionError('package.json must have a name and version');
|
|
48
49
|
// Pack via `npm pack` so the artifact honours the package's `files` field
|
|
49
50
|
// (ship src/.pikku/types, not build/VCS noise) and matches the layout a
|
|
50
51
|
// normal install produces. npm nests contents under `package/`; the
|
|
@@ -65,7 +66,7 @@ export const FabricPublish = pikkuSessionlessFunc({
|
|
|
65
66
|
body: JSON.stringify(body),
|
|
66
67
|
});
|
|
67
68
|
if (!r.ok)
|
|
68
|
-
throw new
|
|
69
|
+
throw new FabricPreconditionError(`POST ${path} → ${r.status}: ${await r.text()}`);
|
|
69
70
|
return r.json();
|
|
70
71
|
};
|
|
71
72
|
// 1. presigned upload URL (short-lived)
|
|
@@ -74,7 +75,7 @@ export const FabricPublish = pikkuSessionlessFunc({
|
|
|
74
75
|
// is signed over host only; mismatched headers break the signature).
|
|
75
76
|
const put = await fetch(uploadUrl, { method: 'PUT', body: artifact });
|
|
76
77
|
if (!put.ok)
|
|
77
|
-
throw new
|
|
78
|
+
throw new FabricPreconditionError(`upload failed → ${put.status}: ${await put.text()}`);
|
|
78
79
|
// 3. finalize — server reads the artifact back, extracts meta, indexes it
|
|
79
80
|
const entry = await post('/registry/addons/publish', { artifactKey });
|
|
80
81
|
const publisher = entry.publisher?.name ?? null;
|
|
@@ -4,6 +4,7 @@ import { resolveApiContext } from '../lib/config.js';
|
|
|
4
4
|
import { collectReportEnvironment } from '../lib/report-environment.js';
|
|
5
5
|
import { FindingInput, buildFindingPayload, parseFinding, parseFindingJson, postFinding, renderReceipt, validateFinding, } from '../lib/finding.js';
|
|
6
6
|
import { flushSpool, readSpool, spoolFinding } from '../lib/finding-spool.js';
|
|
7
|
+
import { FabricPreconditionError } from '../lib/errors.js';
|
|
7
8
|
/**
|
|
8
9
|
* Every field is optional here and the strictness lives in `FindingInput`,
|
|
9
10
|
* because `--stdin` supplies the whole finding at once and the flags then
|
|
@@ -21,7 +22,7 @@ export const FabricReportOutput = z.object({
|
|
|
21
22
|
});
|
|
22
23
|
const readStdin = async () => {
|
|
23
24
|
if (process.stdin.isTTY) {
|
|
24
|
-
throw new
|
|
25
|
+
throw new FabricPreconditionError('--stdin expects the finding as JSON on standard input, and nothing was piped in.');
|
|
25
26
|
}
|
|
26
27
|
const chunks = [];
|
|
27
28
|
for await (const chunk of process.stdin)
|
|
@@ -49,11 +50,11 @@ export const FabricReport = pikkuSessionlessFunc({
|
|
|
49
50
|
? parseFindingJson(await readStdin())
|
|
50
51
|
: parseFinding(flags);
|
|
51
52
|
if ('problems' in parsed) {
|
|
52
|
-
throw new
|
|
53
|
+
throw new FabricPreconditionError(parsed.problems.join('\n'));
|
|
53
54
|
}
|
|
54
55
|
const problems = validateFinding(parsed.finding);
|
|
55
56
|
if (problems.length > 0) {
|
|
56
|
-
throw new
|
|
57
|
+
throw new FabricPreconditionError(problems.join('\n'));
|
|
57
58
|
}
|
|
58
59
|
const payload = buildFindingPayload(parsed.finding, await collectReportEnvironment());
|
|
59
60
|
console.log(renderReceipt(payload));
|
|
@@ -2,6 +2,7 @@ import { z } from 'zod';
|
|
|
2
2
|
import { pikkuSessionlessFunc } from '../../../.pikku/function/index.js';
|
|
3
3
|
import { resolveApiContext } from '../lib/config.js';
|
|
4
4
|
import { getFabricRPC } from '../lib/http.js';
|
|
5
|
+
import { FabricPreconditionError } from '../lib/errors.js';
|
|
5
6
|
export const FabricRollbackInput = z.object({
|
|
6
7
|
branch: z.string(),
|
|
7
8
|
target: z.string().optional(),
|
|
@@ -29,9 +30,9 @@ export const FabricRollback = pikkuSessionlessFunc({
|
|
|
29
30
|
func: async (_services, { target, list, dryRun }) => {
|
|
30
31
|
const ctx = await resolveApiContext();
|
|
31
32
|
if (!ctx.token)
|
|
32
|
-
throw new
|
|
33
|
+
throw new FabricPreconditionError('Not logged in. Run `pikku fabric login` first.');
|
|
33
34
|
if (!ctx.projectId)
|
|
34
|
-
throw new
|
|
35
|
+
throw new FabricPreconditionError('No fabric project linked. Run `pikku fabric link` first.');
|
|
35
36
|
const rpc = getFabricRPC({ apiUrl: ctx.apiUrl, token: ctx.token });
|
|
36
37
|
// --list (or no target) → just show candidates.
|
|
37
38
|
if (list || !target) {
|
|
@@ -4,6 +4,7 @@ import { resolveApiContext } from '../lib/config.js';
|
|
|
4
4
|
import { getFabricRPC } from '../lib/http.js';
|
|
5
5
|
import { promptConfirm } from '../lib/prompt.js';
|
|
6
6
|
import { resolveStage } from '../lib/stage.js';
|
|
7
|
+
import { FabricPreconditionError } from '../lib/errors.js';
|
|
7
8
|
export const FabricSecretsDeleteInput = z.object({
|
|
8
9
|
name: z.string(),
|
|
9
10
|
branch: z.string().optional(),
|
|
@@ -21,21 +22,21 @@ export const FabricSecretsDelete = pikkuSessionlessFunc({
|
|
|
21
22
|
func: async (_services, { name, branch: requested, force }) => {
|
|
22
23
|
const ctx = await resolveApiContext();
|
|
23
24
|
if (!ctx.token)
|
|
24
|
-
throw new
|
|
25
|
+
throw new FabricPreconditionError('Not logged in. Run `pikku fabric login` first.');
|
|
25
26
|
if (!ctx.projectId)
|
|
26
|
-
throw new
|
|
27
|
+
throw new FabricPreconditionError('No fabric project linked. Run `pikku fabric link` first.');
|
|
27
28
|
// Resolved before the prompt so the confirmation names the stage that
|
|
28
29
|
// would actually lose the secret, not an argument that may be absent.
|
|
29
30
|
const rpc = getFabricRPC({ apiUrl: ctx.apiUrl, token: ctx.token });
|
|
30
31
|
const { stageId, branch } = await resolveStage(rpc, ctx.projectId, requested);
|
|
31
32
|
if (!force) {
|
|
32
33
|
if (!process.stdin.isTTY) {
|
|
33
|
-
throw new
|
|
34
|
+
throw new FabricPreconditionError(`Refusing to delete ${name} from ${branch} without confirmation — re-run with --force to delete non-interactively.`);
|
|
34
35
|
}
|
|
35
36
|
// Fabric cannot read the sealed value back, so this is not recoverable
|
|
36
37
|
// by re-reading it — the plaintext has to be supplied again.
|
|
37
38
|
if (!(await promptConfirm(`Delete ${name} from ${branch}? It cannot be recovered — the value must be set again.`))) {
|
|
38
|
-
throw new
|
|
39
|
+
throw new FabricPreconditionError('Delete aborted.');
|
|
39
40
|
}
|
|
40
41
|
}
|
|
41
42
|
const result = await rpc.invoke('deleteStageSecret', { stageId, name });
|
|
@@ -3,6 +3,7 @@ import { pikkuSessionlessFunc } from '../../../.pikku/function/index.js';
|
|
|
3
3
|
import { resolveApiContext } from '../lib/config.js';
|
|
4
4
|
import { getFabricRPC } from '../lib/http.js';
|
|
5
5
|
import { resolveStage } from '../lib/stage.js';
|
|
6
|
+
import { FabricPreconditionError } from '../lib/errors.js';
|
|
6
7
|
export const FabricSecretsListInput = z.object({
|
|
7
8
|
branch: z.string().optional(),
|
|
8
9
|
json: z.boolean().optional(),
|
|
@@ -17,9 +18,9 @@ export const FabricSecretsList = pikkuSessionlessFunc({
|
|
|
17
18
|
func: async (_services, { branch: requested, json }) => {
|
|
18
19
|
const ctx = await resolveApiContext();
|
|
19
20
|
if (!ctx.token)
|
|
20
|
-
throw new
|
|
21
|
+
throw new FabricPreconditionError('Not logged in. Run `pikku fabric login` first.');
|
|
21
22
|
if (!ctx.projectId)
|
|
22
|
-
throw new
|
|
23
|
+
throw new FabricPreconditionError('No fabric project linked. Run `pikku fabric link` first.');
|
|
23
24
|
const rpc = getFabricRPC({ apiUrl: ctx.apiUrl, token: ctx.token });
|
|
24
25
|
const { stageId, branch } = await resolveStage(rpc, ctx.projectId, requested);
|
|
25
26
|
const result = await rpc.invoke('listStageSecretNames', { stageId });
|
|
@@ -3,6 +3,7 @@ import { pikkuSessionlessFunc } from '../../../.pikku/function/index.js';
|
|
|
3
3
|
import { resolveApiContext } from '../lib/config.js';
|
|
4
4
|
import { getFabricRPC } from '../lib/http.js';
|
|
5
5
|
import { resolveStage } from '../lib/stage.js';
|
|
6
|
+
import { FabricPreconditionError } from '../lib/errors.js';
|
|
6
7
|
export const FabricSecretsRotateInput = z.object({
|
|
7
8
|
branch: z.string().optional(),
|
|
8
9
|
force: z.boolean().optional(),
|
|
@@ -17,9 +18,9 @@ export const FabricSecretsRotate = pikkuSessionlessFunc({
|
|
|
17
18
|
func: async (_services, { branch: requested, force }) => {
|
|
18
19
|
const ctx = await resolveApiContext();
|
|
19
20
|
if (!ctx.token)
|
|
20
|
-
throw new
|
|
21
|
+
throw new FabricPreconditionError('Not logged in. Run `pikku fabric login` first.');
|
|
21
22
|
if (!ctx.projectId)
|
|
22
|
-
throw new
|
|
23
|
+
throw new FabricPreconditionError('No fabric project linked. Run `pikku fabric link` first.');
|
|
23
24
|
// Resolved before the refusal, so the one message standing between a
|
|
24
25
|
// typo and unreadable secrets names the stage that would actually be
|
|
25
26
|
// rotated rather than echoing an argument that may not have been passed.
|
|
@@ -29,7 +30,7 @@ export const FabricSecretsRotate = pikkuSessionlessFunc({
|
|
|
29
30
|
// Not a confirmation for politeness — this is the one operation here
|
|
30
31
|
// that destroys access to data. Fabric cannot read the sealed values, so
|
|
31
32
|
// it cannot carry them over, and nobody can undo it afterwards.
|
|
32
|
-
throw new
|
|
33
|
+
throw new FabricPreconditionError(`Rotating the sealing key on ${branch} makes every secret already set on it unreadable — fabric cannot re-seal values it cannot open, so each one must be set again after the next deploy. Re-run with --force if that is what you want.`);
|
|
33
34
|
}
|
|
34
35
|
const result = await rpc.invoke('rotateStageSealingKey', { stageId });
|
|
35
36
|
console.log(`[fabric] retired sealing key ${result.retiredKeyId} on ${branch}`);
|
|
@@ -2,6 +2,7 @@ import { z } from 'zod';
|
|
|
2
2
|
import { pikkuSessionlessFunc } from '../../../.pikku/function/index.js';
|
|
3
3
|
import { resolveApiContext } from '../lib/config.js';
|
|
4
4
|
import { getFabricRPC } from '../lib/http.js';
|
|
5
|
+
import { FabricPreconditionError } from '../lib/errors.js';
|
|
5
6
|
import { promptSecret } from '../lib/prompt.js';
|
|
6
7
|
import { resolveStage } from '../lib/stage.js';
|
|
7
8
|
import { seal, serializeSealedValue } from '../lib/sealed-box.js';
|
|
@@ -22,12 +23,18 @@ export const FabricSecretsSet = pikkuSessionlessFunc({
|
|
|
22
23
|
func: async (_services, { name, branch: requested, value }) => {
|
|
23
24
|
const ctx = await resolveApiContext();
|
|
24
25
|
if (!ctx.token)
|
|
25
|
-
throw new
|
|
26
|
+
throw new FabricPreconditionError('Not logged in. Run `pikku fabric login` first.');
|
|
26
27
|
if (!ctx.projectId)
|
|
27
|
-
throw new
|
|
28
|
-
|
|
28
|
+
throw new FabricPreconditionError('No fabric project linked. Run `pikku fabric link` first.');
|
|
29
|
+
// A value on the command line wins; otherwise the prompt, which reads
|
|
30
|
+
// piped stdin when there is no tty rather than waiting for a human who is
|
|
31
|
+
// not there. Both paths are scriptable, so neither can hang a CI job.
|
|
32
|
+
const plaintext = value ??
|
|
33
|
+
(await promptSecret(`${name} value`, {
|
|
34
|
+
nonInteractiveHint: `Pass the value with \`--value\`, or pipe it: \`echo '<value>' | pikku fabric secrets set ${name}\`.`,
|
|
35
|
+
}));
|
|
29
36
|
if (!plaintext)
|
|
30
|
-
throw new
|
|
37
|
+
throw new FabricPreconditionError('Empty secret value — aborting.');
|
|
31
38
|
const rpc = getFabricRPC({ apiUrl: ctx.apiUrl, token: ctx.token });
|
|
32
39
|
const { stageId, branch } = await resolveStage(rpc, ctx.projectId, requested);
|
|
33
40
|
// Fabric holds only the public half of this keypair. The private half went
|
|
@@ -11,6 +11,7 @@ import { pikkuSessionlessFunc } from '../../../.pikku/function/index.js';
|
|
|
11
11
|
import { findProjectRoot, readJsonSafe, } from '../../functions/validate/validate.js';
|
|
12
12
|
import { headSha, isWorkingTreeClean } from '../lib/git.js';
|
|
13
13
|
import { added, changed, dim, removed } from '../lib/output.js';
|
|
14
|
+
import { FabricPreconditionError } from '../lib/errors.js';
|
|
14
15
|
const DEFAULT_BUN_VERSION = 'bun@1.4.0';
|
|
15
16
|
const DEFAULT_STEP_TIMEOUT_SECONDS = 300;
|
|
16
17
|
const DEFAULT_STARTUP_TIMEOUT_SECONDS = 60;
|
|
@@ -146,7 +147,7 @@ async function waitForHealth(args) {
|
|
|
146
147
|
}
|
|
147
148
|
function rewriteFrontendCommand(command) {
|
|
148
149
|
if (command.length === 0) {
|
|
149
|
-
throw new
|
|
150
|
+
throw new FabricPreconditionError('frontend dev.command must not be empty');
|
|
150
151
|
}
|
|
151
152
|
if (command[0] === 'yarn') {
|
|
152
153
|
return {
|
|
@@ -461,7 +462,7 @@ async function createTempWorktree(root) {
|
|
|
461
462
|
timeoutMs: 60_000,
|
|
462
463
|
});
|
|
463
464
|
if (!cloneStep.ok) {
|
|
464
|
-
throw new
|
|
465
|
+
throw new FabricPreconditionError(`Failed to create temp checkout.\nworktree: ${step.tail || 'git worktree add failed.'}\nclone: ${cloneStep.tail || 'git clone failed.'}`);
|
|
465
466
|
}
|
|
466
467
|
const detachStep = await runCommandStep({
|
|
467
468
|
name: 'git checkout --detach',
|
|
@@ -471,7 +472,7 @@ async function createTempWorktree(root) {
|
|
|
471
472
|
timeoutMs: 60_000,
|
|
472
473
|
});
|
|
473
474
|
if (!detachStep.ok) {
|
|
474
|
-
throw new
|
|
475
|
+
throw new FabricPreconditionError(`Failed to detach temp checkout.\n${detachStep.tail || 'git checkout --detach failed.'}`);
|
|
475
476
|
}
|
|
476
477
|
return tempDir;
|
|
477
478
|
}
|
|
@@ -3,6 +3,7 @@ import { pikkuSessionlessFunc } from '../../../.pikku/function/index.js';
|
|
|
3
3
|
import { resolveApiContext } from '../lib/config.js';
|
|
4
4
|
import { getFabricRPC } from '../lib/http.js';
|
|
5
5
|
import { keyValue, statusColor, dim } from '../lib/output.js';
|
|
6
|
+
import { FabricPreconditionError } from '../lib/errors.js';
|
|
6
7
|
export const FabricStatusInput = z.object({});
|
|
7
8
|
export const FabricStatusOutput = z.object({
|
|
8
9
|
projectId: z.string(),
|
|
@@ -15,9 +16,9 @@ export const FabricStatus = pikkuSessionlessFunc({
|
|
|
15
16
|
func: async (_services) => {
|
|
16
17
|
const ctx = await resolveApiContext();
|
|
17
18
|
if (!ctx.token)
|
|
18
|
-
throw new
|
|
19
|
+
throw new FabricPreconditionError('Not logged in. Run `pikku fabric login` first.');
|
|
19
20
|
if (!ctx.projectId)
|
|
20
|
-
throw new
|
|
21
|
+
throw new FabricPreconditionError('No fabric project linked. Run `pikku fabric link` first.');
|
|
21
22
|
const rpc = getFabricRPC({ apiUrl: ctx.apiUrl, token: ctx.token });
|
|
22
23
|
const status = await rpc.invoke('getProjectStatus', {
|
|
23
24
|
projectId: ctx.projectId,
|
|
@@ -2,6 +2,7 @@ import { z } from 'zod';
|
|
|
2
2
|
import { pikkuSessionlessFunc } from '../../../.pikku/function/index.js';
|
|
3
3
|
import { resolveApiContext } from '../lib/config.js';
|
|
4
4
|
import { getFabricRPC } from '../lib/http.js';
|
|
5
|
+
import { FabricPreconditionError } from '../lib/errors.js';
|
|
5
6
|
export const FabricTraceInput = z.object({
|
|
6
7
|
branch: z.string(),
|
|
7
8
|
traceId: z.string(),
|
|
@@ -21,9 +22,9 @@ export const FabricTrace = pikkuSessionlessFunc({
|
|
|
21
22
|
func: async (_services, { branch, traceId, json }) => {
|
|
22
23
|
const ctx = await resolveApiContext();
|
|
23
24
|
if (!ctx.token)
|
|
24
|
-
throw new
|
|
25
|
+
throw new FabricPreconditionError('Not logged in. Run `pikku fabric login` first.');
|
|
25
26
|
if (!ctx.projectId)
|
|
26
|
-
throw new
|
|
27
|
+
throw new FabricPreconditionError('No fabric project linked. Run `pikku fabric link` first.');
|
|
27
28
|
const rpc = getFabricRPC({ apiUrl: ctx.apiUrl, token: ctx.token });
|
|
28
29
|
const res = await rpc.invoke('getTraceByStageKind', {
|
|
29
30
|
projectId: ctx.projectId,
|
|
@@ -3,6 +3,7 @@ import { pikkuSessionlessFunc } from '../../../.pikku/function/index.js';
|
|
|
3
3
|
import { resolveApiContext } from '../lib/config.js';
|
|
4
4
|
import { getFabricRPC } from '../lib/http.js';
|
|
5
5
|
import { resolveStage } from '../lib/stage.js';
|
|
6
|
+
import { FabricPreconditionError } from '../lib/errors.js';
|
|
6
7
|
export const FabricVariablesGetInput = z.object({
|
|
7
8
|
name: z.string(),
|
|
8
9
|
branch: z.string().optional(),
|
|
@@ -20,9 +21,9 @@ export const FabricVariablesGet = pikkuSessionlessFunc({
|
|
|
20
21
|
func: async (_services, { name, branch: requested, json }) => {
|
|
21
22
|
const ctx = await resolveApiContext();
|
|
22
23
|
if (!ctx.token)
|
|
23
|
-
throw new
|
|
24
|
+
throw new FabricPreconditionError('Not logged in. Run `pikku fabric login` first.');
|
|
24
25
|
if (!ctx.projectId)
|
|
25
|
-
throw new
|
|
26
|
+
throw new FabricPreconditionError('No fabric project linked. Run `pikku fabric link` first.');
|
|
26
27
|
const rpc = getFabricRPC({ apiUrl: ctx.apiUrl, token: ctx.token });
|
|
27
28
|
const { stageId, branch } = await resolveStage(rpc, ctx.projectId, requested);
|
|
28
29
|
const { exists, value } = await rpc.invoke('getStageConsoleVariable', {
|
|
@@ -4,6 +4,7 @@ import { resolveApiContext } from '../lib/config.js';
|
|
|
4
4
|
import { getFabricRPC } from '../lib/http.js';
|
|
5
5
|
import { resolveStage } from '../lib/stage.js';
|
|
6
6
|
import { parseVariableValue } from '../lib/variable-value.js';
|
|
7
|
+
import { FabricPreconditionError } from '../lib/errors.js';
|
|
7
8
|
export const FabricVariablesSetInput = z.object({
|
|
8
9
|
name: z.string(),
|
|
9
10
|
branch: z.string().optional(),
|
|
@@ -20,9 +21,9 @@ export const FabricVariablesSet = pikkuSessionlessFunc({
|
|
|
20
21
|
func: async (_services, { name, branch: requested, value }) => {
|
|
21
22
|
const ctx = await resolveApiContext();
|
|
22
23
|
if (!ctx.token)
|
|
23
|
-
throw new
|
|
24
|
+
throw new FabricPreconditionError('Not logged in. Run `pikku fabric login` first.');
|
|
24
25
|
if (!ctx.projectId)
|
|
25
|
-
throw new
|
|
26
|
+
throw new FabricPreconditionError('No fabric project linked. Run `pikku fabric link` first.');
|
|
26
27
|
const rpc = getFabricRPC({ apiUrl: ctx.apiUrl, token: ctx.token });
|
|
27
28
|
const { stageId, branch } = await resolveStage(rpc, ctx.projectId, requested);
|
|
28
29
|
// Deliberately not sealed, and deliberately not prompted for. A variable is
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { extname } from 'node:path';
|
|
2
2
|
import { resolveApiContext } from './config.js';
|
|
3
3
|
import { getFabricRPC } from './http.js';
|
|
4
|
+
import { FabricPreconditionError } from './errors.js';
|
|
4
5
|
/**
|
|
5
6
|
* Resolve the three things every `changes` command needs: the api url, a
|
|
6
7
|
* bearer, and the project the queue belongs to.
|
|
@@ -12,7 +13,7 @@ import { getFabricRPC } from './http.js';
|
|
|
12
13
|
export async function changesContext(apiUrlOverride, projectIdOverride) {
|
|
13
14
|
const ctx = await resolveApiContext({ apiUrlOverride });
|
|
14
15
|
if (!ctx.token)
|
|
15
|
-
throw new
|
|
16
|
+
throw new FabricPreconditionError('Not logged in. Run `pikku fabric login` first.');
|
|
16
17
|
return {
|
|
17
18
|
rpc: getFabricRPC({ apiUrl: ctx.apiUrl, token: ctx.token }),
|
|
18
19
|
projectId: projectIdOverride ?? ctx.projectId,
|
|
@@ -20,7 +21,7 @@ export async function changesContext(apiUrlOverride, projectIdOverride) {
|
|
|
20
21
|
}
|
|
21
22
|
export function requireProjectId(projectId) {
|
|
22
23
|
if (!projectId)
|
|
23
|
-
throw new
|
|
24
|
+
throw new FabricPreconditionError('No fabric project. Pass --project-id, or run `pikku fabric link` in the checkout.');
|
|
24
25
|
return projectId;
|
|
25
26
|
}
|
|
26
27
|
/**
|
|
@@ -2,6 +2,7 @@ import { readFile, writeFile, mkdir } from 'node:fs/promises';
|
|
|
2
2
|
import { existsSync } from 'node:fs';
|
|
3
3
|
import { dirname, join } from 'node:path';
|
|
4
4
|
import { homedir } from 'node:os';
|
|
5
|
+
import { FabricPreconditionError } from './errors.js';
|
|
5
6
|
const DEFAULT_API_URL = 'https://api.pikkufabric.com';
|
|
6
7
|
const projectConfigName = 'pikkufabric.config.json';
|
|
7
8
|
const authFilePath = join(homedir(), '.fabric', 'auth.json');
|
|
@@ -52,7 +53,7 @@ export async function writeProjectConfig(cwd, config) {
|
|
|
52
53
|
raw = await readFile(path, 'utf8');
|
|
53
54
|
}
|
|
54
55
|
catch (error) {
|
|
55
|
-
throw new
|
|
56
|
+
throw new FabricPreconditionError(`Cannot read ${projectConfigName} at ${path} (${error.message}) — refusing to overwrite it`);
|
|
56
57
|
}
|
|
57
58
|
try {
|
|
58
59
|
const parsed = JSON.parse(raw);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { FabricPreconditionError } from './errors.js';
|
|
1
2
|
const IN_FLIGHT = new Set(['queued', 'planning', 'building', 'deploying']);
|
|
2
3
|
const SUCCEEDED = new Set(['active']);
|
|
3
4
|
const FAILED = new Set([
|
|
@@ -313,7 +314,7 @@ export function reconcileDeployedRef({ requested, actual, deploymentId, }) {
|
|
|
313
314
|
if (actual === requested)
|
|
314
315
|
return actual;
|
|
315
316
|
const short = (sha) => sha.slice(0, 8);
|
|
316
|
-
throw new
|
|
317
|
+
throw new FabricPreconditionError([
|
|
317
318
|
`Refusing to continue: deployment ${deploymentId} is pinned to ${short(actual)}, not the ${short(requested)} you asked for.`,
|
|
318
319
|
'A deployment already parked for this branch was attached to rather than a new one being cut,',
|
|
319
320
|
'so continuing would deploy a different commit than the one named.',
|
|
@@ -1,9 +1,18 @@
|
|
|
1
|
+
import { PikkuError } from '@pikku/core/errors';
|
|
1
2
|
/**
|
|
2
3
|
* Local git probes for the deploy safety checks (clean tree, HEAD == remote,
|
|
3
4
|
* ref resolution). Shell out to `git` rather than depend on simple-git —
|
|
4
5
|
* matches what wrangler/vercel/fly do, no runtime dep.
|
|
5
6
|
*/
|
|
6
|
-
|
|
7
|
+
/**
|
|
8
|
+
* A `git` invocation that came back non-zero.
|
|
9
|
+
*
|
|
10
|
+
* A `PikkuError`, because the message already carries the whole diagnosis —
|
|
11
|
+
* which command, which exit code, and git's own stderr — and ten frames of the
|
|
12
|
+
* spawn helper in front of "fatal: not a git repository" answer a question
|
|
13
|
+
* nobody asked. `--verbose` / `PIKKU_DEBUG` still prints the stack.
|
|
14
|
+
*/
|
|
15
|
+
export declare class GitError extends PikkuError {
|
|
7
16
|
command: string;
|
|
8
17
|
exitCode: number;
|
|
9
18
|
stderr: string;
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
2
|
import { FabricPreconditionError } from './errors.js';
|
|
3
|
+
import { PikkuError } from '@pikku/core/errors';
|
|
3
4
|
/**
|
|
4
5
|
* Local git probes for the deploy safety checks (clean tree, HEAD == remote,
|
|
5
6
|
* ref resolution). Shell out to `git` rather than depend on simple-git —
|
|
6
7
|
* matches what wrangler/vercel/fly do, no runtime dep.
|
|
7
8
|
*/
|
|
8
|
-
|
|
9
|
+
/**
|
|
10
|
+
* A `git` invocation that came back non-zero.
|
|
11
|
+
*
|
|
12
|
+
* A `PikkuError`, because the message already carries the whole diagnosis —
|
|
13
|
+
* which command, which exit code, and git's own stderr — and ten frames of the
|
|
14
|
+
* spawn helper in front of "fatal: not a git repository" answer a question
|
|
15
|
+
* nobody asked. `--verbose` / `PIKKU_DEBUG` still prints the stack.
|
|
16
|
+
*/
|
|
17
|
+
export class GitError extends PikkuError {
|
|
9
18
|
command;
|
|
10
19
|
exitCode;
|
|
11
20
|
stderr;
|
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Ask for a value that should not end up in shell history.
|
|
3
|
+
*
|
|
4
|
+
* With a tty this is a prompt. Without one — piped input, CI, an agent — the
|
|
5
|
+
* value is read from stdin instead, because scripting `pikku fabric secrets
|
|
6
|
+
* set` is a reasonable thing to want, and because a prompt with nobody to
|
|
7
|
+
* answer it is a hang. If stdin is closed or empty, `nonInteractiveHint` tells
|
|
8
|
+
* the caller which flag to reach for; it is raised as a `PikkuError` so
|
|
9
|
+
* `formatCLIError` prints that sentence and nothing else.
|
|
5
10
|
*/
|
|
6
|
-
export declare function promptSecret(label: string
|
|
11
|
+
export declare function promptSecret(label: string, { nonInteractiveHint }: {
|
|
12
|
+
nonInteractiveHint: string;
|
|
13
|
+
}): Promise<string>;
|
|
7
14
|
/**
|
|
8
15
|
* Classic yes/no confirmation. Returns `defaultYes` on an empty answer.
|
|
9
16
|
* Callers must gate on `process.stdin.isTTY` first — there is no human to
|
|
10
|
-
* answer in a non-interactive session, so prompting there would hang.
|
|
17
|
+
* answer in a non-interactive session, so prompting there would hang. The
|
|
18
|
+
* guard below is the backstop for a caller that forgets: a refusal naming the
|
|
19
|
+
* question beats a process that never returns.
|
|
11
20
|
*/
|
|
12
21
|
export declare function promptConfirm(label: string, defaultYes?: boolean): Promise<boolean>;
|
|
@@ -1,32 +1,95 @@
|
|
|
1
1
|
import { createInterface } from 'node:readline/promises';
|
|
2
|
+
import { createInterface as createLineInterface } from 'node:readline';
|
|
2
3
|
import { stdin, stdout } from 'node:process';
|
|
4
|
+
import { FabricPreconditionError } from './errors.js';
|
|
3
5
|
/**
|
|
4
|
-
* Read
|
|
5
|
-
*
|
|
6
|
-
* the
|
|
6
|
+
* Read the first line stdin has to offer, or `null` if it has none.
|
|
7
|
+
*
|
|
8
|
+
* Resolves on the first newline rather than on EOF, so a pipe that stays open
|
|
9
|
+
* after the value has been written (a harness holding the write end, `cat |`)
|
|
10
|
+
* does not hang the command. `terminal: false` matters: readline's terminal
|
|
11
|
+
* mode tries to drive a tty it does not have, and on a closed stdin the
|
|
12
|
+
* `question()` promise it returns never settles at all — which is how
|
|
13
|
+
* `pikku fabric secrets set NAME < /dev/null` used to end in node's
|
|
14
|
+
* "Detected unsettled top-level await" warning instead of an error.
|
|
7
15
|
*/
|
|
8
|
-
|
|
16
|
+
const readFirstLine = async () => {
|
|
17
|
+
const rl = createLineInterface({ input: stdin, terminal: false });
|
|
18
|
+
try {
|
|
19
|
+
return await new Promise((resolve) => {
|
|
20
|
+
rl.once('line', (line) => resolve(line));
|
|
21
|
+
rl.once('close', () => resolve(null));
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
finally {
|
|
25
|
+
rl.close();
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Ask for a value that should not end up in shell history.
|
|
30
|
+
*
|
|
31
|
+
* With a tty this is a prompt. Without one — piped input, CI, an agent — the
|
|
32
|
+
* value is read from stdin instead, because scripting `pikku fabric secrets
|
|
33
|
+
* set` is a reasonable thing to want, and because a prompt with nobody to
|
|
34
|
+
* answer it is a hang. If stdin is closed or empty, `nonInteractiveHint` tells
|
|
35
|
+
* the caller which flag to reach for; it is raised as a `PikkuError` so
|
|
36
|
+
* `formatCLIError` prints that sentence and nothing else.
|
|
37
|
+
*/
|
|
38
|
+
export async function promptSecret(label, { nonInteractiveHint }) {
|
|
39
|
+
if (!stdin.isTTY) {
|
|
40
|
+
const piped = await readFirstLine();
|
|
41
|
+
const value = piped?.trim() ?? '';
|
|
42
|
+
if (!value) {
|
|
43
|
+
throw new FabricPreconditionError(`${label}: stdin is not a tty and nothing was piped in.\n${nonInteractiveHint}`);
|
|
44
|
+
}
|
|
45
|
+
return value;
|
|
46
|
+
}
|
|
9
47
|
const rl = createInterface({ input: stdin, output: stdout, terminal: true });
|
|
10
48
|
// Best-effort masking — the readline API doesn't suppress echo natively;
|
|
11
49
|
// for hardened input you'd want `read -s` or a tty trick, but for our
|
|
12
50
|
// CLI the standard prompt is fine and matches what wrangler does.
|
|
13
51
|
process.stdout.write(`${label}: `);
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
52
|
+
try {
|
|
53
|
+
// `question()` never rejects when the stream ends under it, so the close is
|
|
54
|
+
// raced explicitly: ^D at a prompt is an abort, not an infinite wait.
|
|
55
|
+
const value = await Promise.race([
|
|
56
|
+
rl.question(''),
|
|
57
|
+
new Promise((resolve) => rl.once('close', () => resolve(null))),
|
|
58
|
+
]);
|
|
59
|
+
if (value === null) {
|
|
60
|
+
throw new FabricPreconditionError(`${label}: input closed before a value was given.\n${nonInteractiveHint}`);
|
|
61
|
+
}
|
|
62
|
+
return value.trim();
|
|
63
|
+
}
|
|
64
|
+
finally {
|
|
65
|
+
rl.close();
|
|
66
|
+
}
|
|
17
67
|
}
|
|
18
68
|
/**
|
|
19
69
|
* Classic yes/no confirmation. Returns `defaultYes` on an empty answer.
|
|
20
70
|
* Callers must gate on `process.stdin.isTTY` first — there is no human to
|
|
21
|
-
* answer in a non-interactive session, so prompting there would hang.
|
|
71
|
+
* answer in a non-interactive session, so prompting there would hang. The
|
|
72
|
+
* guard below is the backstop for a caller that forgets: a refusal naming the
|
|
73
|
+
* question beats a process that never returns.
|
|
22
74
|
*/
|
|
23
75
|
export async function promptConfirm(label, defaultYes = false) {
|
|
76
|
+
if (!stdin.isTTY) {
|
|
77
|
+
throw new FabricPreconditionError(`Cannot ask "${label}" — stdin is not a tty. Re-run interactively, or pass the flag that answers it (--force / --auto-approve / --yes).`);
|
|
78
|
+
}
|
|
24
79
|
const rl = createInterface({ input: stdin, output: stdout });
|
|
25
|
-
|
|
26
|
-
.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
80
|
+
try {
|
|
81
|
+
const answer = await Promise.race([
|
|
82
|
+
rl.question(`${label} [${defaultYes ? 'Y/n' : 'y/N'}] `),
|
|
83
|
+
new Promise((resolve) => rl.once('close', () => resolve(null))),
|
|
84
|
+
]);
|
|
85
|
+
if (answer === null)
|
|
86
|
+
return false;
|
|
87
|
+
const normalized = answer.trim().toLowerCase();
|
|
88
|
+
if (!normalized)
|
|
89
|
+
return defaultYes;
|
|
90
|
+
return normalized === 'y' || normalized === 'yes';
|
|
91
|
+
}
|
|
92
|
+
finally {
|
|
93
|
+
rl.close();
|
|
94
|
+
}
|
|
32
95
|
}
|
|
@@ -3,10 +3,11 @@ export interface PikkuPackageVersion {
|
|
|
3
3
|
name: string;
|
|
4
4
|
version: string;
|
|
5
5
|
/**
|
|
6
|
-
* Resolved
|
|
7
|
-
* rather than a published tarball. The framework is read-only
|
|
8
|
-
* run, so a linked package is code that may already have been
|
|
9
|
-
* finding describing it is describing something other than a
|
|
6
|
+
* Resolved to a checkout outside `node_modules` — a workspace or a linked
|
|
7
|
+
* working tree rather than a published tarball. The framework is read-only
|
|
8
|
+
* during a build run, so a linked package is code that may already have been
|
|
9
|
+
* modified, and a finding describing it is describing something other than a
|
|
10
|
+
* release.
|
|
10
11
|
*/
|
|
11
12
|
linked: boolean;
|
|
12
13
|
}
|