@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.
- package/CHANGELOG.md +273 -0
- package/console-app/assets/{abnfDiagram-N423BO3Z-Bltf5dmS.js → abnfDiagram-N423BO3Z-WNIAg_Oa.js} +1 -1
- package/console-app/assets/architecture-TIHT7OUA-CIT-Nug2.js +1 -0
- package/console-app/assets/{architectureDiagram-T3A2C74G-BTtx6R7-.js → architectureDiagram-T3A2C74G-DM698mgf.js} +1 -1
- package/console-app/assets/{blockDiagram-VBNYF7ZC-DgeTIOaM.js → blockDiagram-VBNYF7ZC-DPfy9K5S.js} +1 -1
- package/console-app/assets/{c4Diagram-5PPSVZJV-CaswnNob.js → c4Diagram-5PPSVZJV-DhLbbBbX.js} +1 -1
- package/console-app/assets/channel-DQC6cL1c.js +1 -0
- package/console-app/assets/{chunk-2GRJ4B5K-OnpnkpQT.js → chunk-2GRJ4B5K-C1RQ1gvs.js} +1 -1
- package/console-app/assets/{chunk-4I5QYGJK-CWmfNXFr.js → chunk-4I5QYGJK-BkzSdNc_.js} +1 -1
- package/console-app/assets/{chunk-5RXB4S5H-M8QmKeuk.js → chunk-5RXB4S5H-DZpBpdcU.js} +1 -1
- package/console-app/assets/{chunk-6Q2QTUOP-C_h5lS68.js → chunk-6Q2QTUOP-mZObxdld.js} +1 -1
- package/console-app/assets/{chunk-7Z6QIM7H-DSnVb09k.js → chunk-7Z6QIM7H-C0HbxZEa.js} +1 -1
- package/console-app/assets/{chunk-GF5L2VYU-BkX038sq.js → chunk-GF5L2VYU-DXPVwWqW.js} +1 -1
- package/console-app/assets/{chunk-I66GZJ75-b3yMIljX.js → chunk-I66GZJ75-pVpq9ckD.js} +1 -1
- package/console-app/assets/{chunk-JQJVKLGR-Bihcz4nv.js → chunk-JQJVKLGR-DJQ8K4wK.js} +1 -1
- package/console-app/assets/{chunk-KBJHAD2P-CS7eflbk.js → chunk-KBJHAD2P-B8XuxRCO.js} +1 -1
- package/console-app/assets/{chunk-NSK5VX7P-CfigFGDQ.js → chunk-NSK5VX7P-cYzQU4bD.js} +1 -1
- package/console-app/assets/{chunk-QR6OTTB3-BBy8NfTW.js → chunk-QR6OTTB3-CNoTFsqn.js} +1 -1
- package/console-app/assets/{chunk-RYQCIY6F-BCfZVQef.js → chunk-RYQCIY6F-DoKRUO_N.js} +1 -1
- package/console-app/assets/{chunk-UBXNYLIW-DkMKDHW4.js → chunk-UBXNYLIW-BqcIoUpU.js} +1 -1
- package/console-app/assets/{chunk-W5SLKNZC-BSLytTSJ.js → chunk-W5SLKNZC-p0Qalbjj.js} +1 -1
- package/console-app/assets/{chunk-WRU74C26-Dic7ZP8H.js → chunk-WRU74C26-DUMn96Dr.js} +1 -1
- package/console-app/assets/chunk-XXDRQBXY-Dgz5VbWO.js +1 -0
- package/console-app/assets/classDiagram-JCYQIIEL-1ASFocNV.js +1 -0
- package/console-app/assets/classDiagram-v2-OCEON4UE-1ASFocNV.js +1 -0
- package/console-app/assets/{cose-bilkent-JH36ORCC-CEpWcE3M.js → cose-bilkent-JH36ORCC-BCh3BlPI.js} +1 -1
- package/console-app/assets/{cynefin-VYW2F7L2-irPiPhgz.js → cynefin-VYW2F7L2-ZfghUZsD.js} +1 -1
- package/console-app/assets/{cynefinDiagram-MW4NZA55-CIkqQ912.js → cynefinDiagram-MW4NZA55-DcV3QXCe.js} +1 -1
- package/console-app/assets/{dagre-FZyyw3H3.js → dagre-BPFWXLBN.js} +1 -1
- package/console-app/assets/{dagre-VZM6K2ZE-Dxnnu7Rh.js → dagre-VZM6K2ZE-DETshBO-.js} +1 -1
- package/console-app/assets/{diagram-7IWD3JNH-DaT47sVs.js → diagram-7IWD3JNH-CsLX3P2o.js} +1 -1
- package/console-app/assets/{diagram-B4RE2ZJO-Dmht03tx.js → diagram-B4RE2ZJO-o2zcxm5S.js} +1 -1
- package/console-app/assets/{diagram-LBJQPF4R-B--jwILh.js → diagram-LBJQPF4R-BD2zKU21.js} +1 -1
- package/console-app/assets/{diagram-Q27KOJAE-D9H0euUr.js → diagram-Q27KOJAE-DHaacyna.js} +1 -1
- package/console-app/assets/{diagram-UB23O5K3-DloUQ8tO.js → diagram-UB23O5K3-pSLCMUyV.js} +1 -1
- package/console-app/assets/{ebnfDiagram-BXEA7PRR-gaOXzNBU.js → ebnfDiagram-BXEA7PRR-BDzawX3O.js} +1 -1
- package/console-app/assets/{erDiagram-JOGREHBK-3X9eTLsh.js → erDiagram-JOGREHBK-CyYnPmbN.js} +1 -1
- package/console-app/assets/eventmodeling-45OFAUF4-BYJ0A5k-.js +1 -0
- package/console-app/assets/flowDiagram-UKHOOZJN-CVn87uiP.js +1 -0
- package/console-app/assets/{ganttDiagram-PKOTCBZU-khAFwSBy.js → ganttDiagram-PKOTCBZU-3fhCBbPA.js} +1 -1
- package/console-app/assets/{gitGraph-TEB2WS4Q-Bb7uENmk.js → gitGraph-TEB2WS4Q-CdLRkVux.js} +1 -1
- package/console-app/assets/{gitGraphDiagram-DS77QQ5N-OkSBM0h0.js → gitGraphDiagram-DS77QQ5N-CC1epdKw.js} +1 -1
- package/console-app/assets/{index-Bn1BoT3w.js → index-BRmokG9t.js} +184 -184
- package/console-app/assets/{index-suVNAhyL.css → index-GruDnAhJ.css} +1 -1
- package/console-app/assets/{info-DKCQHKI2-BH5dbX2B.js → info-DKCQHKI2-BJs8WkzC.js} +1 -1
- package/console-app/assets/{infoDiagram-6WML65LV-IbUl8J2C.js → infoDiagram-6WML65LV-uoOwoIeI.js} +1 -1
- package/console-app/assets/{ishikawaDiagram-WSZJBQD7-CX0gA3de.js → ishikawaDiagram-WSZJBQD7-vCUJhwTi.js} +1 -1
- package/console-app/assets/{journeyDiagram-NVQOT4AX--k2etXu8.js → journeyDiagram-NVQOT4AX-D2QcIlLG.js} +1 -1
- package/console-app/assets/{kanban-definition-27J2QSJJ-D1FvtPpN.js → kanban-definition-27J2QSJJ-JwwKowmR.js} +1 -1
- package/console-app/assets/{line-JLMY_DDK.js → line-h2oRreYF.js} +1 -1
- package/console-app/assets/{linear-CSvLB3cd.js → linear-Dz002X_a.js} +1 -1
- package/console-app/assets/{mermaid-parser.core-CwwjcAjz.js → mermaid-parser.core-DTgmT0AA.js} +3 -3
- package/console-app/assets/{mermaid.core-hmS_M4K5.js → mermaid.core-1jSEDr-j.js} +4 -4
- package/console-app/assets/{mindmap-definition-FAOFIHXS-rTDa_CTp.js → mindmap-definition-FAOFIHXS-C3Txxhj4.js} +1 -1
- package/console-app/assets/{packet-7NZHBO7P-DBUJcYfI.js → packet-7NZHBO7P-BGG7zIK2.js} +1 -1
- package/console-app/assets/{pegDiagram-VL7TDLO6-D42PxXnS.js → pegDiagram-VL7TDLO6--g1r_rov.js} +1 -1
- package/console-app/assets/{pie-RZYD4A2V-dM0uFAE4.js → pie-RZYD4A2V-C5OepMH7.js} +1 -1
- package/console-app/assets/{pieDiagram-7S7Q4E2Y-wCln1ucl.js → pieDiagram-7S7Q4E2Y-DGD_LzGm.js} +1 -1
- package/console-app/assets/{quadrantDiagram-CIZ2JOQS-DrRwS1g5.js → quadrantDiagram-CIZ2JOQS-CyBQQlD2.js} +1 -1
- package/console-app/assets/{radar-I7S5WNFK-BW0V-EGR.js → radar-I7S5WNFK-CaBOAO95.js} +1 -1
- package/console-app/assets/{railroad-3IZDKUUU-FiTHaDbb.js → railroad-3IZDKUUU-2aTWN4Pw.js} +1 -1
- package/console-app/assets/railroad-abnf-AHOZXSZD-TU7k5gB_.js +1 -0
- package/console-app/assets/railroad-ebnf-EBAXGLYW-DbArPBkM.js +1 -0
- package/console-app/assets/railroad-peg-LSFZ7HO6-TzB93z4K.js +1 -0
- package/console-app/assets/{railroadDiagram-AXF67PYL-9ef7j5U7.js → railroadDiagram-AXF67PYL-3Nr0rlTp.js} +1 -1
- package/console-app/assets/{requirementDiagram-LRYGKXZP-Cu90DbEZ.js → requirementDiagram-LRYGKXZP-BN7sEwSa.js} +1 -1
- package/console-app/assets/{sankeyDiagram-W5VNT64P-Bhxmyxaw.js → sankeyDiagram-W5VNT64P-CXZR46wO.js} +1 -1
- package/console-app/assets/{sequenceDiagram-SI44F4Z6-CBsbRTz8.js → sequenceDiagram-SI44F4Z6-DNtmdJ4U.js} +1 -1
- package/console-app/assets/{src-BR8qR3lM.js → src-x1E3pJJ-.js} +1 -1
- package/console-app/assets/{stateDiagram-OKZ733FA-Dr0frETZ.js → stateDiagram-OKZ733FA-B_GyYdl_.js} +1 -1
- package/console-app/assets/stateDiagram-v2-UEYNNEHI-D7V_HITc.js +1 -0
- package/console-app/assets/{swimlanes-SLNWSIFB-CXMjvd_a.js → swimlanes-SLNWSIFB-D4N7VdF7.js} +1 -1
- package/console-app/assets/swimlanesDiagram-ULZ7WXOC-C4XcIHKT.js +8 -0
- package/console-app/assets/{timeline-definition-Z64GVDOM-DpmEZPV0.js → timeline-definition-Z64GVDOM-DU5rsOWQ.js} +1 -1
- package/console-app/assets/{treeView-QDETBFTQ-CjmuinMk.js → treeView-QDETBFTQ-DaKM_9sB.js} +1 -1
- package/console-app/assets/{treemap-6X3UGDF4-BP_fU6Cn.js → treemap-6X3UGDF4-BabsKtZY.js} +1 -1
- package/console-app/assets/{vennDiagram-T6HMQDX7-DgZS7iuW.js → vennDiagram-T6HMQDX7-Dniftpq0.js} +1 -1
- package/console-app/assets/{wardley-OPB4EBWU-CgMPoouN.js → wardley-OPB4EBWU-BWffQNys.js} +1 -1
- package/console-app/assets/{wardleyDiagram-T6FBY63Y-6y-xxP1R.js → wardleyDiagram-T6FBY63Y-CQ74fVdn.js} +1 -1
- package/console-app/assets/{xychartDiagram-ELKLHX3M-DOeIQjYI.js → xychartDiagram-ELKLHX3M-D-XxbGIL.js} +1 -1
- package/console-app/index.html +2 -2
- 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 +42 -1
- package/dist/.pikku/agent/pikku-agent-types.gen.js +41 -0
- package/dist/.pikku/agent/pikku-model-aliases.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 +2 -19
- package/dist/.pikku/auth/pikku-auth-types.gen.js +2 -19
- 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 +10 -18
- package/dist/.pikku/channel/pikku-channel-types.gen.js +9 -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 +6 -6
- package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-client.gen.js +1 -1
- 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 +24 -23
- package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +8 -7
- package/dist/.pikku/cli/pikku-cli-types.gen.js +8 -7
- package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.json +51 -23
- 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 +1 -1
- 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 +36 -37
- package/dist/.pikku/function/pikku-function-types.gen.js +21 -9
- package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
- package/dist/.pikku/function/pikku-functions-meta.gen.json +34 -34
- 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 +7 -1
- package/dist/.pikku/http/pikku-http-types.gen.js +5 -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 +11 -1
- package/dist/.pikku/mcp/pikku-mcp-types.gen.js +5 -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 +33 -24
- package/dist/.pikku/middleware/pikku-middleware-types.gen.js +29 -24
- 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 +3 -1
- package/dist/.pikku/queue/pikku-queue-types.gen.js +3 -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/rpc/pikku-rpc-wirings-meta.internal.gen.json +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.d.ts +4 -0
- 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 +13 -1
- package/dist/.pikku/scenarios/pikku-scenario-types.gen.js +4 -0
- 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 +3 -1
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +3 -1
- package/dist/.pikku/schemas/register.gen.js +5 -5
- package/dist/.pikku/schemas/schemas/DocInput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/DocOutput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/FabricDeployApplyInput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/FabricDeployApplyOutput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/FabricSecretsRotateOutput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/PikkuSkillsInstallInput.schema.json +1 -1
- package/dist/.pikku/scopes/index.d.ts +1 -1
- package/dist/.pikku/scopes/index.js +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 +9 -1
- package/dist/.pikku/secrets/pikku-secrets.gen.js +5 -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 +7 -19
- package/dist/.pikku/setup/pikku-setup-types.gen.js +11 -19
- 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 +5 -1
- package/dist/.pikku/trigger/pikku-trigger-types.gen.js +5 -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 +9 -1
- package/dist/.pikku/variables/pikku-variables.gen.js +5 -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 +29 -1
- package/dist/.pikku/workflow/pikku-workflow-types.gen.js +8 -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/src/cli.wiring.js +21 -0
- package/dist/src/deploy/analyzer/analyzer.d.ts +1 -0
- package/dist/src/deploy/analyzer/analyzer.js +8 -6
- package/dist/src/deploy/build-pipeline.d.ts +1 -0
- package/dist/src/deploy/build-pipeline.js +1 -0
- package/dist/src/fabric/fabric-commands.d.ts +170 -54
- package/dist/src/fabric/fabric-commands.js +25 -20
- package/dist/src/fabric/functions/deploy.function.d.ts +246 -67
- package/dist/src/fabric/functions/deploy.function.js +316 -69
- package/dist/src/fabric/functions/init.function.js +1 -0
- package/dist/src/fabric/functions/link.function.js +4 -1
- package/dist/src/fabric/functions/secrets-rotate.function.d.ts +4 -4
- package/dist/src/fabric/functions/secrets-rotate.function.js +2 -2
- package/dist/src/fabric/functions/validate.function.js +123 -0
- package/dist/src/fabric/lib/deployment.d.ts +107 -0
- package/dist/src/fabric/lib/deployment.js +264 -0
- package/dist/src/fabric/sdk/pikku-fetch.gen.d.ts +1 -1
- package/dist/src/fabric/sdk/pikku-fetch.gen.js +1 -1
- package/dist/src/fabric/sdk/pikku-rpc.gen.d.ts +4 -1
- package/dist/src/fabric/sdk/pikku-rpc.gen.js +4 -1
- 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/doc.d.ts +22 -0
- package/dist/src/functions/commands/doc.js +25 -0
- package/dist/src/functions/commands/skills.d.ts +3 -0
- package/dist/src/functions/commands/skills.js +4 -2
- package/dist/src/functions/runtimes/tanstack-start/serialize-tanstack-start-shim.d.ts +3 -2
- package/dist/src/functions/runtimes/tanstack-start/serialize-tanstack-start-shim.js +33 -10
- package/dist/src/functions/surface/build-surface-doc.d.ts +8 -1
- package/dist/src/functions/surface/build-surface-doc.js +21 -8
- package/dist/src/functions/surface/collect-snippets.d.ts +13 -0
- package/dist/src/functions/surface/collect-snippets.js +83 -0
- package/dist/src/functions/surface/collect-surface.d.ts +27 -1
- package/dist/src/functions/surface/collect-surface.js +323 -13
- package/dist/src/functions/surface/generate-surface-doc.js +40 -5
- package/dist/src/functions/surface/render-surface-doc.d.ts +12 -0
- package/dist/src/functions/surface/render-surface-doc.js +209 -0
- package/dist/src/functions/surface/surface-doc.types.d.ts +15 -2
- package/dist/src/functions/surface/surface-editorial.d.ts +6 -0
- package/dist/src/functions/surface/surface-editorial.js +22 -1
- package/dist/src/functions/wirings/agent/serialize-agent-types.js +41 -0
- package/dist/src/functions/wirings/agent/serialize-public-agent.js +1 -1
- package/dist/src/functions/wirings/auth/serialize-auth-guards.js +1 -18
- package/dist/src/functions/wirings/auth/serialize-auth-types.js +7 -0
- package/dist/src/functions/wirings/channels/serialize-channel-types.js +9 -17
- package/dist/src/functions/wirings/cli/serialize-cli-types.js +7 -6
- package/dist/src/functions/wirings/functions/pikku-command-function-types-split.js +1 -1
- package/dist/src/functions/wirings/functions/serialize-addon-refs.js +12 -0
- package/dist/src/functions/wirings/functions/serialize-function-types.js +23 -36
- package/dist/src/functions/wirings/http/serialize-http-types.js +6 -0
- package/dist/src/functions/wirings/mcp/serialize-mcp-types.js +10 -0
- package/dist/src/functions/wirings/middleware/serialize-middleware-types.js +32 -23
- package/dist/src/functions/wirings/queue/serialize-queue-types.js +2 -0
- package/dist/src/functions/wirings/scheduler/serialize-scheduler-types.js +2 -0
- package/dist/src/functions/wirings/secrets/serialize-secrets-types.js +8 -0
- package/dist/src/functions/wirings/setup/serialize-setup-types.d.ts +1 -1
- package/dist/src/functions/wirings/setup/serialize-setup-types.js +19 -19
- package/dist/src/functions/wirings/triggers/serialize-trigger-types.js +4 -0
- package/dist/src/functions/wirings/variables/serialize-variables-types.js +8 -0
- package/dist/src/functions/wirings/workflow/serialize-personas.js +4 -0
- package/dist/src/functions/wirings/workflow/serialize-scenario-types.js +12 -0
- package/dist/src/functions/wirings/workflow/serialize-workflow-types.js +28 -0
- package/dist/src/services.js +8 -1
- package/dist/src/utils/persona-credentials.js +5 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -7
- package/snippets-meta.json +131 -0
- package/snippets.json +131 -0
- package/surface.json +7393 -458
- package/console-app/assets/architecture-TIHT7OUA-DgRqRaqo.js +0 -1
- package/console-app/assets/channel-37lNznWk.js +0 -1
- package/console-app/assets/chunk-XXDRQBXY-B1prMCvW.js +0 -1
- package/console-app/assets/classDiagram-JCYQIIEL-BDCX9ZLm.js +0 -1
- package/console-app/assets/classDiagram-v2-OCEON4UE-BDCX9ZLm.js +0 -1
- package/console-app/assets/eventmodeling-45OFAUF4-BarrKD55.js +0 -1
- package/console-app/assets/flowDiagram-UKHOOZJN-B6RiRjcD.js +0 -1
- package/console-app/assets/railroad-abnf-AHOZXSZD-lmUjOixE.js +0 -1
- package/console-app/assets/railroad-ebnf-EBAXGLYW-ZjdA7OHp.js +0 -1
- package/console-app/assets/railroad-peg-LSFZ7HO6-VHSlvwI8.js +0 -1
- package/console-app/assets/stateDiagram-v2-UEYNNEHI-BSXWhCvf.js +0 -1
- package/console-app/assets/swimlanesDiagram-ULZ7WXOC-BUdsPDKC.js +0 -8
- package/dist/.pikku/schemas/schemas/FabricDeployPlanInput.schema.json +0 -1
- 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
|
-
|
|
13
|
-
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
-
|
|
39
|
-
|
|
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
|
-
|
|
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
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
|
101
|
-
|
|
186
|
+
const base = {
|
|
187
|
+
event: 'result',
|
|
102
188
|
projectId,
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
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
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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
|
-
|
|
127
|
-
|
|
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
|
};
|
|
@@ -57,7 +57,10 @@ export const FabricLink = pikkuSessionlessFunc({
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
|
-
const project = await rpc.invoke('importProject', {
|
|
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;
|