@pikku/cli 0.12.125 → 0.12.127
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 +231 -0
- package/console-app/assets/{abnfDiagram-N423BO3Z-B2suyn6i.js → abnfDiagram-N423BO3Z-BY2LM8wi.js} +1 -1
- package/console-app/assets/architecture-TIHT7OUA-CWwmvxZF.js +1 -0
- package/console-app/assets/{architectureDiagram-T3A2C74G-BQ5Dfvpo.js → architectureDiagram-T3A2C74G-CeqjY3Kw.js} +1 -1
- package/console-app/assets/{blockDiagram-VBNYF7ZC-D4pVRDiF.js → blockDiagram-VBNYF7ZC-BW5174xj.js} +1 -1
- package/console-app/assets/{c4Diagram-5PPSVZJV-Da04jGpq.js → c4Diagram-5PPSVZJV-B7zXAFL0.js} +1 -1
- package/console-app/assets/channel-pOkwZ_Ot.js +1 -0
- package/console-app/assets/{chunk-2GRJ4B5K-CwODIPP4.js → chunk-2GRJ4B5K-BfRYzQ4t.js} +1 -1
- package/console-app/assets/{chunk-4I5QYGJK-Bep4akjR.js → chunk-4I5QYGJK-DBA7-Nu4.js} +1 -1
- package/console-app/assets/{chunk-5RXB4S5H-CGyCRU9L.js → chunk-5RXB4S5H-D03lNzwi.js} +1 -1
- package/console-app/assets/{chunk-6Q2QTUOP-D0IK0SMT.js → chunk-6Q2QTUOP-DloGRHJZ.js} +1 -1
- package/console-app/assets/{chunk-7Z6QIM7H-D12vS1jX.js → chunk-7Z6QIM7H-DH3uHtl2.js} +1 -1
- package/console-app/assets/{chunk-GF5L2VYU-kOLwTzIA.js → chunk-GF5L2VYU-Cu252lza.js} +1 -1
- package/console-app/assets/{chunk-I66GZJ75-Cb2nDoa3.js → chunk-I66GZJ75-DH54FcuO.js} +1 -1
- package/console-app/assets/{chunk-JQJVKLGR-B3a_ctfQ.js → chunk-JQJVKLGR-CeFuTL-V.js} +1 -1
- package/console-app/assets/{chunk-KBJHAD2P-DeP2Lqwp.js → chunk-KBJHAD2P-B-prFo0-.js} +1 -1
- package/console-app/assets/{chunk-NSK5VX7P-BO8vlGrO.js → chunk-NSK5VX7P-C10iA4GS.js} +1 -1
- package/console-app/assets/{chunk-QR6OTTB3-sX5V0Lok.js → chunk-QR6OTTB3-Cd8apAsA.js} +1 -1
- package/console-app/assets/{chunk-RYQCIY6F-DoCObEhk.js → chunk-RYQCIY6F-rfPUp2Fj.js} +1 -1
- package/console-app/assets/{chunk-UBXNYLIW-BndMXU5r.js → chunk-UBXNYLIW-D25wqJBc.js} +1 -1
- package/console-app/assets/{chunk-W5SLKNZC--VrZN8EC.js → chunk-W5SLKNZC-CJvxkxuK.js} +1 -1
- package/console-app/assets/{chunk-WRU74C26-DdS0mzXO.js → chunk-WRU74C26-B9Wju92P.js} +1 -1
- package/console-app/assets/chunk-XXDRQBXY-BU_UP6f5.js +1 -0
- package/console-app/assets/classDiagram-JCYQIIEL-CLBKUuxj.js +1 -0
- package/console-app/assets/classDiagram-v2-OCEON4UE-CLBKUuxj.js +1 -0
- package/console-app/assets/{cose-bilkent-JH36ORCC-C5EnHkFn.js → cose-bilkent-JH36ORCC-CwA1VCP5.js} +1 -1
- package/console-app/assets/{cynefin-VYW2F7L2-9irdkTt4.js → cynefin-VYW2F7L2-C_qsD7eR.js} +1 -1
- package/console-app/assets/{cynefinDiagram-MW4NZA55-DY19660c.js → cynefinDiagram-MW4NZA55-CkSLreFW.js} +1 -1
- package/console-app/assets/{dagre-VZM6K2ZE-BYFZSaSb.js → dagre-VZM6K2ZE-0ssqLoHs.js} +1 -1
- package/console-app/assets/{dagre-nXgDYqvf.js → dagre-WqgBlKb7.js} +1 -1
- package/console-app/assets/{diagram-7IWD3JNH-oDftiTp1.js → diagram-7IWD3JNH-DmRL3lmL.js} +1 -1
- package/console-app/assets/{diagram-B4RE2ZJO-Cbj-pPbH.js → diagram-B4RE2ZJO-Bsr9wG4I.js} +1 -1
- package/console-app/assets/{diagram-LBJQPF4R-Ch53oSKw.js → diagram-LBJQPF4R-DdMw1FSY.js} +1 -1
- package/console-app/assets/{diagram-Q27KOJAE-DA7K814v.js → diagram-Q27KOJAE-TPx5TB2B.js} +1 -1
- package/console-app/assets/{diagram-UB23O5K3-B-_C-ctS.js → diagram-UB23O5K3-e_1zSlZR.js} +1 -1
- package/console-app/assets/{ebnfDiagram-BXEA7PRR-DsOdsKXy.js → ebnfDiagram-BXEA7PRR-BACajh2b.js} +1 -1
- package/console-app/assets/{erDiagram-JOGREHBK-XB1mP5_A.js → erDiagram-JOGREHBK-CojomKqL.js} +1 -1
- package/console-app/assets/eventmodeling-45OFAUF4-DkN2KCrT.js +1 -0
- package/console-app/assets/flowDiagram-UKHOOZJN-DL0M9lBc.js +1 -0
- package/console-app/assets/{ganttDiagram-PKOTCBZU-knk0XSHi.js → ganttDiagram-PKOTCBZU-yoOX4Xj2.js} +1 -1
- package/console-app/assets/{gitGraph-TEB2WS4Q-COJnK2tM.js → gitGraph-TEB2WS4Q-BcUY5hIc.js} +1 -1
- package/console-app/assets/{gitGraphDiagram-DS77QQ5N-sF0v605q.js → gitGraphDiagram-DS77QQ5N-BtuIPjuB.js} +1 -1
- package/console-app/assets/{index-DMnbsgzs.js → index-CzWW052c.js} +151 -151
- package/console-app/assets/{info-DKCQHKI2-Cbatr0w6.js → info-DKCQHKI2-B-iR9PUz.js} +1 -1
- package/console-app/assets/{infoDiagram-6WML65LV-93TFPCu2.js → infoDiagram-6WML65LV-CuXKIFH2.js} +1 -1
- package/console-app/assets/{ishikawaDiagram-WSZJBQD7-BBR8_Qms.js → ishikawaDiagram-WSZJBQD7-CSueMFD6.js} +1 -1
- package/console-app/assets/{journeyDiagram-NVQOT4AX-zG55yDoc.js → journeyDiagram-NVQOT4AX-kvnKStZp.js} +1 -1
- package/console-app/assets/{kanban-definition-27J2QSJJ-DonGcEAY.js → kanban-definition-27J2QSJJ-CGGDEz30.js} +1 -1
- package/console-app/assets/{line-D1WdVm1S.js → line-mtMM5-xO.js} +1 -1
- package/console-app/assets/{linear-D2GQL4Cm.js → linear-CLSje0O_.js} +1 -1
- package/console-app/assets/{mermaid-parser.core-b4yKyO56.js → mermaid-parser.core-Cx6yvn3j.js} +3 -3
- package/console-app/assets/{mermaid.core-Cwfec1gr.js → mermaid.core-BebGyklS.js} +4 -4
- package/console-app/assets/{mindmap-definition-FAOFIHXS-D0G4yKgw.js → mindmap-definition-FAOFIHXS-C2_WUUJ9.js} +1 -1
- package/console-app/assets/{packet-7NZHBO7P-DDa4HL2T.js → packet-7NZHBO7P-Dh5yNCA8.js} +1 -1
- package/console-app/assets/{pegDiagram-VL7TDLO6-fPdN5VZs.js → pegDiagram-VL7TDLO6-XgUxesi8.js} +1 -1
- package/console-app/assets/{pie-RZYD4A2V-DRHURUqo.js → pie-RZYD4A2V-D2x2RAXI.js} +1 -1
- package/console-app/assets/{pieDiagram-7S7Q4E2Y-DMYn8ga_.js → pieDiagram-7S7Q4E2Y-Bbor0KbG.js} +1 -1
- package/console-app/assets/{quadrantDiagram-CIZ2JOQS-C190OamC.js → quadrantDiagram-CIZ2JOQS-DZmnMHpM.js} +1 -1
- package/console-app/assets/{radar-I7S5WNFK-Djvqzz9A.js → radar-I7S5WNFK-CPeriDtN.js} +1 -1
- package/console-app/assets/{railroad-3IZDKUUU-C9YvFeFq.js → railroad-3IZDKUUU-2iKAyaie.js} +1 -1
- package/console-app/assets/railroad-abnf-AHOZXSZD-D26xz4MM.js +1 -0
- package/console-app/assets/railroad-ebnf-EBAXGLYW-CCAiMPWc.js +1 -0
- package/console-app/assets/railroad-peg-LSFZ7HO6-BA1zcisq.js +1 -0
- package/console-app/assets/{railroadDiagram-AXF67PYL-IRFg1VrU.js → railroadDiagram-AXF67PYL-DVEqCXoo.js} +1 -1
- package/console-app/assets/{requirementDiagram-LRYGKXZP-L-7ubbcT.js → requirementDiagram-LRYGKXZP-CSgSNL8p.js} +1 -1
- package/console-app/assets/{sankeyDiagram-W5VNT64P-DBttV6Gt.js → sankeyDiagram-W5VNT64P-CFk11odN.js} +1 -1
- package/console-app/assets/{sequenceDiagram-SI44F4Z6-Bg15oKAB.js → sequenceDiagram-SI44F4Z6-Cb5u6FsJ.js} +1 -1
- package/console-app/assets/{src-DUC7tLWb.js → src-LceHEY_Q.js} +1 -1
- package/console-app/assets/{stateDiagram-OKZ733FA-PWl0XGs5.js → stateDiagram-OKZ733FA-DM1jWlkU.js} +1 -1
- package/console-app/assets/stateDiagram-v2-UEYNNEHI-COVnPYic.js +1 -0
- package/console-app/assets/{swimlanes-SLNWSIFB-CyXEtGBV.js → swimlanes-SLNWSIFB-DD6MchlE.js} +1 -1
- package/console-app/assets/swimlanesDiagram-ULZ7WXOC-B5q8iRCQ.js +8 -0
- package/console-app/assets/{timeline-definition-Z64GVDOM-BLA-DhBt.js → timeline-definition-Z64GVDOM-zu5cNnVv.js} +1 -1
- package/console-app/assets/{treeView-QDETBFTQ-Bfnmn2UY.js → treeView-QDETBFTQ-D_4IbvCG.js} +1 -1
- package/console-app/assets/{treemap-6X3UGDF4-DTA0wveO.js → treemap-6X3UGDF4-DNc6bjUc.js} +1 -1
- package/console-app/assets/{vennDiagram-T6HMQDX7-CLXYZln0.js → vennDiagram-T6HMQDX7-DfqoG28f.js} +1 -1
- package/console-app/assets/{wardley-OPB4EBWU-zwxqisG0.js → wardley-OPB4EBWU-BqpI2Lx-.js} +1 -1
- package/console-app/assets/{wardleyDiagram-T6FBY63Y-hKtKvNlv.js → wardleyDiagram-T6FBY63Y-CLIZSvNi.js} +1 -1
- package/console-app/assets/{xychartDiagram-ELKLHX3M-BGf8p4bo.js → xychartDiagram-ELKLHX3M-Cni-XXa6.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/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 +26 -1
- 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 +103 -0
- 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 +116 -0
- 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 +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 +114 -21
- 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/rpc/pikku-rpc-wirings-meta.internal.gen.json +5 -0
- 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 +19 -1
- package/dist/.pikku/schemas/schemas/FabricFindingsClearInput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/FabricFindingsClearOutput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/FabricFindingsFlushInput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/FabricFindingsFlushOutput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/FabricFindingsListInput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/FabricFindingsListOutput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/FabricReportInput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/FabricReportOutput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/FabricSecretsListInput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/FabricSecretsRotateInput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/FabricSecretsSetInput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/FabricVariablesGetInput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/FabricVariablesSetInput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/PersonaSecretInput.schema.json +1 -0
- 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 +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/src/cli.wiring.js +6 -1
- package/dist/src/deploy/bundler/bun-bundler.js +12 -5
- package/dist/src/fabric/fabric-commands.d.ts +153 -15
- package/dist/src/fabric/fabric-commands.js +65 -0
- package/dist/src/fabric/functions/deploy.function.js +12 -2
- package/dist/src/fabric/functions/findings-clear.function.d.ts +12 -0
- package/dist/src/fabric/functions/findings-clear.function.js +17 -0
- package/dist/src/fabric/functions/findings-flush.function.d.ts +33 -0
- package/dist/src/fabric/functions/findings-flush.function.js +36 -0
- package/dist/src/fabric/functions/findings-list.function.d.ts +55 -0
- package/dist/src/fabric/functions/findings-list.function.js +52 -0
- package/dist/src/fabric/functions/report.function.d.ts +121 -0
- package/dist/src/fabric/functions/report.function.js +84 -0
- package/dist/src/fabric/functions/secrets-list.function.d.ts +4 -4
- package/dist/src/fabric/functions/secrets-list.function.js +4 -4
- package/dist/src/fabric/functions/secrets-rotate.function.d.ts +4 -4
- package/dist/src/fabric/functions/secrets-rotate.function.js +8 -5
- package/dist/src/fabric/functions/secrets-set.function.d.ts +4 -4
- package/dist/src/fabric/functions/secrets-set.function.js +4 -4
- package/dist/src/fabric/functions/validate.function.js +49 -24
- package/dist/src/fabric/functions/variables-get.function.d.ts +4 -4
- package/dist/src/fabric/functions/variables-get.function.js +4 -4
- package/dist/src/fabric/functions/variables-set.function.d.ts +4 -4
- package/dist/src/fabric/functions/variables-set.function.js +4 -4
- package/dist/src/fabric/lib/blank-comments.d.ts +21 -0
- package/dist/src/fabric/lib/blank-comments.js +71 -0
- package/dist/src/fabric/lib/blank-scenario-meta.d.ts +1 -0
- package/dist/src/fabric/lib/blank-scenario-meta.js +110 -0
- package/dist/src/fabric/lib/deployment.d.ts +26 -0
- package/dist/src/fabric/lib/deployment.js +35 -0
- package/dist/src/fabric/lib/finding-spool.d.ts +56 -0
- package/dist/src/fabric/lib/finding-spool.js +105 -0
- package/dist/src/fabric/lib/finding.d.ts +92 -0
- package/dist/src/fabric/lib/finding.js +156 -0
- package/dist/src/fabric/lib/report-environment.d.ts +53 -0
- package/dist/src/fabric/lib/report-environment.js +119 -0
- package/dist/src/fabric/lib/stage.d.ts +19 -3
- package/dist/src/fabric/lib/stage.js +29 -6
- package/dist/src/functions/commands/db-reset.js +6 -2
- package/dist/src/functions/commands/dev.js +5 -1
- package/dist/src/functions/commands/environment.d.ts +5 -0
- package/dist/src/functions/commands/persona.d.ts +18 -0
- package/dist/src/functions/commands/persona.js +42 -2
- package/dist/src/functions/commands/scenario-browser.d.ts +13 -5
- package/dist/src/functions/commands/scenario.js +1 -0
- package/dist/src/functions/db/check-enums.d.ts +38 -0
- package/dist/src/functions/db/check-enums.js +103 -0
- package/dist/src/functions/db/db-codegen.js +15 -0
- package/dist/src/functions/db/postgres/postgres-introspector.d.ts +14 -0
- package/dist/src/functions/db/postgres/postgres-introspector.js +48 -0
- package/dist/src/functions/db/sqlite/sqlite-introspector.d.ts +3 -4
- package/dist/src/functions/db/sqlite/sqlite-introspector.js +5 -17
- package/dist/src/functions/validate/auth-plugin-checks.d.ts +1 -1
- package/dist/src/functions/validate/auth-plugin-checks.js +8 -5
- package/dist/src/functions/validate/persona-checks.js +8 -6
- package/dist/src/functions/wirings/user-admin/pikku-command-user-admin-functions.js +10 -5
- package/dist/src/functions/wirings/user-admin/serialize-user-admin-functions.d.ts +1 -1
- package/dist/src/functions/wirings/user-admin/serialize-user-admin-functions.js +3 -3
- package/dist/src/functions/wirings/virtual-user/serialize-virtual-user-functions.d.ts +9 -6
- package/dist/src/functions/wirings/virtual-user/serialize-virtual-user-functions.js +51 -27
- package/dist/src/server/actor-sign-in.d.ts +24 -1
- package/dist/src/server/actor-sign-in.js +45 -2
- package/dist/src/services.js +9 -0
- package/dist/src/utils/persona-credentials.d.ts +23 -2
- package/dist/src/utils/persona-credentials.js +55 -2
- package/dist/src/utils/pikku-cli-config.d.ts +4 -4
- package/dist/src/utils/pikku-cli-config.js +30 -10
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -8
- package/snippets.json +1 -1
- package/surface.json +102 -52
- package/console-app/assets/architecture-TIHT7OUA-DmG0bXDT.js +0 -1
- package/console-app/assets/channel-BgCT5gon.js +0 -1
- package/console-app/assets/chunk-XXDRQBXY-EP2C9tTO.js +0 -1
- package/console-app/assets/classDiagram-JCYQIIEL-D9wGqB4J.js +0 -1
- package/console-app/assets/classDiagram-v2-OCEON4UE-D9wGqB4J.js +0 -1
- package/console-app/assets/eventmodeling-45OFAUF4-NKFCZ8Fj.js +0 -1
- package/console-app/assets/flowDiagram-UKHOOZJN-BpdPkmum.js +0 -1
- package/console-app/assets/railroad-abnf-AHOZXSZD-B3CYVW4p.js +0 -1
- package/console-app/assets/railroad-ebnf-EBAXGLYW-DrZ2yF62.js +0 -1
- package/console-app/assets/railroad-peg-LSFZ7HO6-CWAmMyxd.js +0 -1
- package/console-app/assets/stateDiagram-v2-UEYNNEHI-Celbgz4u.js +0 -1
- package/console-app/assets/swimlanesDiagram-ULZ7WXOC-zxpNaB4U.js +0 -8
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { mkdir, readdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { randomBytes } from 'node:crypto';
|
|
6
|
+
import { postFinding } from './finding.js';
|
|
7
|
+
/** Oldest entries past this are dropped, so a logged-out machine stays bounded. */
|
|
8
|
+
export const SPOOL_LIMIT = 100;
|
|
9
|
+
export function spoolDir() {
|
|
10
|
+
return (process.env.FABRIC_FINDINGS_DIR ?? join(homedir(), '.fabric', 'findings'));
|
|
11
|
+
}
|
|
12
|
+
export async function spoolFinding(entry) {
|
|
13
|
+
const dir = spoolDir();
|
|
14
|
+
await mkdir(dir, { recursive: true });
|
|
15
|
+
const stamp = entry.payload.reportedAt.replace(/[:.]/g, '-');
|
|
16
|
+
const file = join(dir, `${stamp}-${randomBytes(3).toString('hex')}.json`);
|
|
17
|
+
await writeFile(file, JSON.stringify({
|
|
18
|
+
spooledAt: new Date().toISOString(),
|
|
19
|
+
reason: entry.reason,
|
|
20
|
+
projectId: entry.projectId,
|
|
21
|
+
payload: entry.payload,
|
|
22
|
+
}, null, 2) + '\n', { encoding: 'utf8', mode: 0o600 });
|
|
23
|
+
await pruneSpool();
|
|
24
|
+
return file;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Chronological, by the timestamp inside each finding rather than the one its
|
|
28
|
+
* name carries — the name is for a human reading the directory, and ordering
|
|
29
|
+
* the queue by it would make the send order a property of how a filename
|
|
30
|
+
* happens to sort. A file that no longer parses is skipped rather than thrown
|
|
31
|
+
* for: one corrupt entry is not a reason to lose the rest, or to fail the
|
|
32
|
+
* command that happened to notice.
|
|
33
|
+
*/
|
|
34
|
+
export async function readSpool() {
|
|
35
|
+
const dir = spoolDir();
|
|
36
|
+
if (!existsSync(dir))
|
|
37
|
+
return [];
|
|
38
|
+
const names = (await readdir(dir)).filter((n) => n.endsWith('.json'));
|
|
39
|
+
const entries = [];
|
|
40
|
+
for (const name of names) {
|
|
41
|
+
const file = join(dir, name);
|
|
42
|
+
try {
|
|
43
|
+
const parsed = JSON.parse(await readFile(file, 'utf8'));
|
|
44
|
+
if (!parsed?.payload)
|
|
45
|
+
continue;
|
|
46
|
+
entries.push({
|
|
47
|
+
file,
|
|
48
|
+
spooledAt: parsed.spooledAt ?? '',
|
|
49
|
+
reason: parsed.reason ?? 'unknown',
|
|
50
|
+
projectId: parsed.projectId ?? null,
|
|
51
|
+
payload: parsed.payload,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return entries.sort((a, b) => a.payload.reportedAt.localeCompare(b.payload.reportedAt) ||
|
|
59
|
+
a.file.localeCompare(b.file));
|
|
60
|
+
}
|
|
61
|
+
export async function clearSpool() {
|
|
62
|
+
const entries = await readSpool();
|
|
63
|
+
for (const entry of entries)
|
|
64
|
+
await rm(entry.file, { force: true });
|
|
65
|
+
return entries.length;
|
|
66
|
+
}
|
|
67
|
+
async function pruneSpool() {
|
|
68
|
+
const entries = await readSpool();
|
|
69
|
+
const excess = Math.max(0, entries.length - SPOOL_LIMIT);
|
|
70
|
+
for (const entry of entries.slice(0, excess)) {
|
|
71
|
+
await rm(entry.file, { force: true });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Drain the spool oldest-first, stopping at the first entry fabric does not
|
|
76
|
+
* accept — a refusal usually means the next one will be refused too, and
|
|
77
|
+
* hammering an endpoint that just said no is the wrong thing for a command
|
|
78
|
+
* whose real job is something else.
|
|
79
|
+
*
|
|
80
|
+
* An entry keeps the project it was filed against; one spooled before the repo
|
|
81
|
+
* was linked adopts the project linked now, and sends without one if there is
|
|
82
|
+
* still none.
|
|
83
|
+
*/
|
|
84
|
+
export async function flushSpool(ctx) {
|
|
85
|
+
const entries = await readSpool();
|
|
86
|
+
let sent = 0;
|
|
87
|
+
for (const [index, entry] of entries.entries()) {
|
|
88
|
+
const result = await postFinding({
|
|
89
|
+
apiUrl: ctx.apiUrl,
|
|
90
|
+
token: ctx.token,
|
|
91
|
+
projectId: entry.projectId ?? ctx.projectId,
|
|
92
|
+
payload: entry.payload,
|
|
93
|
+
});
|
|
94
|
+
if (!result.sent) {
|
|
95
|
+
return {
|
|
96
|
+
sent,
|
|
97
|
+
remaining: entries.length - index,
|
|
98
|
+
reason: result.reason,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
await rm(entry.file, { force: true });
|
|
102
|
+
sent++;
|
|
103
|
+
}
|
|
104
|
+
return { sent, remaining: 0 };
|
|
105
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { ReportEnvironment } from './report-environment.js';
|
|
3
|
+
export declare const FindingInput: z.ZodObject<{
|
|
4
|
+
title: z.ZodString;
|
|
5
|
+
kind: z.ZodEnum<{
|
|
6
|
+
product: "product";
|
|
7
|
+
harness: "harness";
|
|
8
|
+
}>;
|
|
9
|
+
model: z.ZodString;
|
|
10
|
+
expected: z.ZodString;
|
|
11
|
+
actual: z.ZodString;
|
|
12
|
+
skill: z.ZodOptional<z.ZodString>;
|
|
13
|
+
passage: z.ZodOptional<z.ZodString>;
|
|
14
|
+
command: z.ZodOptional<z.ZodString>;
|
|
15
|
+
error: z.ZodOptional<z.ZodString>;
|
|
16
|
+
repro: z.ZodOptional<z.ZodString>;
|
|
17
|
+
workaround: z.ZodOptional<z.ZodString>;
|
|
18
|
+
proposal: z.ZodOptional<z.ZodString>;
|
|
19
|
+
tried: z.ZodOptional<z.ZodString>;
|
|
20
|
+
unresolved: z.ZodOptional<z.ZodBoolean>;
|
|
21
|
+
area: z.ZodOptional<z.ZodString>;
|
|
22
|
+
surface: z.ZodOptional<z.ZodEnum<{
|
|
23
|
+
local: "local";
|
|
24
|
+
deployed: "deployed";
|
|
25
|
+
both: "both";
|
|
26
|
+
}>>;
|
|
27
|
+
cost: z.ZodOptional<z.ZodString>;
|
|
28
|
+
run: z.ZodOptional<z.ZodString>;
|
|
29
|
+
deployTarget: z.ZodOptional<z.ZodString>;
|
|
30
|
+
}, z.core.$strip>;
|
|
31
|
+
export type FindingInput = z.infer<typeof FindingInput>;
|
|
32
|
+
export type ParsedFinding = {
|
|
33
|
+
finding: FindingInput;
|
|
34
|
+
} | {
|
|
35
|
+
problems: string[];
|
|
36
|
+
};
|
|
37
|
+
/** Shape-check a finding from either path, naming every field that is wrong. */
|
|
38
|
+
export declare function parseFinding(value: unknown): ParsedFinding;
|
|
39
|
+
/**
|
|
40
|
+
* A finding read as JSON rather than assembled out of flags.
|
|
41
|
+
*
|
|
42
|
+
* Half the fields are prose, and prose carries apostrophes, quotes, backticks
|
|
43
|
+
* and newlines — every one of them a shell metacharacter before it is a
|
|
44
|
+
* character in a sentence. An error message pasted into `--error` breaks the
|
|
45
|
+
* command at its first newline; one carrying a backtick runs whatever follows
|
|
46
|
+
* it. JSON has its own escaping, so this path has none of that.
|
|
47
|
+
*
|
|
48
|
+
* Returns the finding or the problems with it, never throws: a malformed
|
|
49
|
+
* payload is a usage mistake worth naming precisely.
|
|
50
|
+
*/
|
|
51
|
+
export declare function parseFindingJson(raw: string): ParsedFinding;
|
|
52
|
+
export interface FindingPayload extends Omit<FindingInput, 'run'> {
|
|
53
|
+
runId?: string;
|
|
54
|
+
environment: ReportEnvironment;
|
|
55
|
+
reportedAt: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The rules the field set exists to enforce, checked before anything is sent.
|
|
59
|
+
*
|
|
60
|
+
* A usage mistake is the agent's own and is worth failing loudly for — unlike a
|
|
61
|
+
* failed send, which must never surface as a build failure. Every problem is
|
|
62
|
+
* returned at once so a malformed call is fixed in one pass.
|
|
63
|
+
*/
|
|
64
|
+
export declare function validateFinding(input: FindingInput): string[];
|
|
65
|
+
export declare function buildFindingPayload(input: FindingInput, environment: ReportEnvironment, now?: Date): FindingPayload;
|
|
66
|
+
/**
|
|
67
|
+
* Best-effort by construction. A finding is worth having and never worth
|
|
68
|
+
* failing a build for, so a refused, slow or unreachable endpoint is reported
|
|
69
|
+
* to the terminal and swallowed.
|
|
70
|
+
*/
|
|
71
|
+
export declare function postFinding(opts: {
|
|
72
|
+
apiUrl: string;
|
|
73
|
+
token: string;
|
|
74
|
+
/**
|
|
75
|
+
* Provenance, not a routing key. A finding is about the framework rather
|
|
76
|
+
* than about anyone's project, and the reports worth having most — a
|
|
77
|
+
* scaffold that never produced a config, a first run that went wrong — come
|
|
78
|
+
* from checkouts that have no project to name.
|
|
79
|
+
*/
|
|
80
|
+
projectId: string | null;
|
|
81
|
+
payload: FindingPayload;
|
|
82
|
+
timeoutMs?: number;
|
|
83
|
+
}): Promise<{
|
|
84
|
+
sent: boolean;
|
|
85
|
+
reason?: string;
|
|
86
|
+
}>;
|
|
87
|
+
/**
|
|
88
|
+
* The receipt. Nothing is written to disk, so the terminal is the only place
|
|
89
|
+
* the user sees what left their machine. Printed before the request goes out,
|
|
90
|
+
* so it is there whether or not the send succeeds.
|
|
91
|
+
*/
|
|
92
|
+
export declare function renderReceipt(payload: FindingPayload): string;
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export const FindingInput = z.object({
|
|
3
|
+
title: z.string(),
|
|
4
|
+
kind: z.enum(['product', 'harness']),
|
|
5
|
+
model: z.string(),
|
|
6
|
+
expected: z.string(),
|
|
7
|
+
actual: z.string(),
|
|
8
|
+
skill: z.string().optional(),
|
|
9
|
+
passage: z.string().optional(),
|
|
10
|
+
command: z.string().optional(),
|
|
11
|
+
error: z.string().optional(),
|
|
12
|
+
repro: z.string().optional(),
|
|
13
|
+
workaround: z.string().optional(),
|
|
14
|
+
proposal: z.string().optional(),
|
|
15
|
+
tried: z.string().optional(),
|
|
16
|
+
unresolved: z.boolean().optional(),
|
|
17
|
+
area: z.string().optional(),
|
|
18
|
+
surface: z.enum(['local', 'deployed', 'both']).optional(),
|
|
19
|
+
cost: z.string().optional(),
|
|
20
|
+
run: z.string().optional(),
|
|
21
|
+
deployTarget: z.string().optional(),
|
|
22
|
+
});
|
|
23
|
+
/** Shape-check a finding from either path, naming every field that is wrong. */
|
|
24
|
+
export function parseFinding(value) {
|
|
25
|
+
const result = FindingInput.safeParse(value);
|
|
26
|
+
if (result.success)
|
|
27
|
+
return { finding: result.data };
|
|
28
|
+
return {
|
|
29
|
+
problems: result.error.issues.map((issue) => `${issue.path.join('.') || 'finding'}: ${issue.message}`),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A finding read as JSON rather than assembled out of flags.
|
|
34
|
+
*
|
|
35
|
+
* Half the fields are prose, and prose carries apostrophes, quotes, backticks
|
|
36
|
+
* and newlines — every one of them a shell metacharacter before it is a
|
|
37
|
+
* character in a sentence. An error message pasted into `--error` breaks the
|
|
38
|
+
* command at its first newline; one carrying a backtick runs whatever follows
|
|
39
|
+
* it. JSON has its own escaping, so this path has none of that.
|
|
40
|
+
*
|
|
41
|
+
* Returns the finding or the problems with it, never throws: a malformed
|
|
42
|
+
* payload is a usage mistake worth naming precisely.
|
|
43
|
+
*/
|
|
44
|
+
export function parseFindingJson(raw) {
|
|
45
|
+
let parsed;
|
|
46
|
+
try {
|
|
47
|
+
parsed = JSON.parse(raw);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
return {
|
|
51
|
+
problems: [`--stdin expected a JSON object (${error.message}).`],
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
55
|
+
return { problems: ['--stdin expected a JSON object.'] };
|
|
56
|
+
}
|
|
57
|
+
return parseFinding(parsed);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The rules the field set exists to enforce, checked before anything is sent.
|
|
61
|
+
*
|
|
62
|
+
* A usage mistake is the agent's own and is worth failing loudly for — unlike a
|
|
63
|
+
* failed send, which must never surface as a build failure. Every problem is
|
|
64
|
+
* returned at once so a malformed call is fixed in one pass.
|
|
65
|
+
*/
|
|
66
|
+
export function validateFinding(input) {
|
|
67
|
+
const problems = [];
|
|
68
|
+
if (input.kind === 'harness' && !input.skill) {
|
|
69
|
+
problems.push('A harness finding names the skill that misled you — pass --skill (and --passage for the line it contradicts).');
|
|
70
|
+
}
|
|
71
|
+
if (input.unresolved) {
|
|
72
|
+
if (!input.tried) {
|
|
73
|
+
problems.push('An unresolved finding carries what you tried and how each attempt failed — pass --tried.');
|
|
74
|
+
}
|
|
75
|
+
if (input.workaround) {
|
|
76
|
+
problems.push('Unresolved means no workaround was found. Drop --unresolved, or drop --workaround.');
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else if (!input.workaround && !input.proposal) {
|
|
80
|
+
problems.push('A resolved finding carries the workaround you used — pass --workaround, or --unresolved if there was none.');
|
|
81
|
+
}
|
|
82
|
+
return problems;
|
|
83
|
+
}
|
|
84
|
+
export function buildFindingPayload(input, environment, now = new Date()) {
|
|
85
|
+
const { run, ...rest } = input;
|
|
86
|
+
return { ...rest, runId: run, environment, reportedAt: now.toISOString() };
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Best-effort by construction. A finding is worth having and never worth
|
|
90
|
+
* failing a build for, so a refused, slow or unreachable endpoint is reported
|
|
91
|
+
* to the terminal and swallowed.
|
|
92
|
+
*/
|
|
93
|
+
export async function postFinding(opts) {
|
|
94
|
+
try {
|
|
95
|
+
const response = await fetch(`${opts.apiUrl}/findings`, {
|
|
96
|
+
method: 'POST',
|
|
97
|
+
headers: {
|
|
98
|
+
'content-type': 'application/json',
|
|
99
|
+
authorization: `Bearer ${opts.token}`,
|
|
100
|
+
},
|
|
101
|
+
body: JSON.stringify({
|
|
102
|
+
projectId: opts.projectId,
|
|
103
|
+
finding: opts.payload,
|
|
104
|
+
}),
|
|
105
|
+
signal: AbortSignal.timeout(opts.timeoutMs ?? 5000),
|
|
106
|
+
});
|
|
107
|
+
if (!response.ok) {
|
|
108
|
+
return { sent: false, reason: `fabric answered ${response.status}` };
|
|
109
|
+
}
|
|
110
|
+
return { sent: true };
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
return { sent: false, reason: error?.message ?? 'request failed' };
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* The receipt. Nothing is written to disk, so the terminal is the only place
|
|
118
|
+
* the user sees what left their machine. Printed before the request goes out,
|
|
119
|
+
* so it is there whether or not the send succeeds.
|
|
120
|
+
*/
|
|
121
|
+
export function renderReceipt(payload) {
|
|
122
|
+
const lines = [`[fabric] reporting: ${payload.title}`];
|
|
123
|
+
const field = (label, value) => {
|
|
124
|
+
if (value)
|
|
125
|
+
lines.push(` ${label}: ${value}`);
|
|
126
|
+
};
|
|
127
|
+
field('kind', payload.unresolved ? `${payload.kind} (unresolved)` : payload.kind);
|
|
128
|
+
field('area', payload.area);
|
|
129
|
+
field('skill', payload.passage ? `${payload.skill} — ${payload.passage}` : payload.skill);
|
|
130
|
+
field('command', payload.command);
|
|
131
|
+
field('expected', payload.expected);
|
|
132
|
+
field('actual', payload.actual);
|
|
133
|
+
field('error', payload.error);
|
|
134
|
+
field('surface', payload.surface);
|
|
135
|
+
field('cost', payload.cost);
|
|
136
|
+
field('repro', payload.repro);
|
|
137
|
+
field('workaround', payload.workaround);
|
|
138
|
+
field('tried', payload.tried);
|
|
139
|
+
field('proposal', payload.proposal);
|
|
140
|
+
field('model', payload.model);
|
|
141
|
+
field('run', payload.runId);
|
|
142
|
+
field('deploy target', payload.deployTarget);
|
|
143
|
+
field('reported at', payload.reportedAt);
|
|
144
|
+
const env = payload.environment;
|
|
145
|
+
field('versions', env.packages
|
|
146
|
+
.map((p) => `${p.name}@${p.version}${p.linked ? ' (linked)' : ''}`)
|
|
147
|
+
.join(' ') || 'no @pikku/* found');
|
|
148
|
+
if (env.versionSkew) {
|
|
149
|
+
lines.push(' note: the installed @pikku/* versions are not all the same');
|
|
150
|
+
}
|
|
151
|
+
if (env.linkedFramework) {
|
|
152
|
+
lines.push(' note: an @pikku/* resolves to a workspace or link — this app is running framework code that may be modified');
|
|
153
|
+
}
|
|
154
|
+
field('runtime', `node ${env.node} ${env.platform} ${env.packageManager ?? ''}`.trim());
|
|
155
|
+
return lines.join('\n');
|
|
156
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** One installed `@pikku/*` package as it actually resolves on disk. */
|
|
2
|
+
export interface PikkuPackageVersion {
|
|
3
|
+
name: string;
|
|
4
|
+
version: string;
|
|
5
|
+
/**
|
|
6
|
+
* Resolved through a symlink — a yarn workspace or a `yarn link`ed checkout
|
|
7
|
+
* rather than a published tarball. The framework is read-only during a build
|
|
8
|
+
* run, so a linked package is code that may already have been modified, and a
|
|
9
|
+
* finding describing it is describing something other than a release.
|
|
10
|
+
*/
|
|
11
|
+
linked: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface ReportEnvironment {
|
|
14
|
+
packages: PikkuPackageVersion[];
|
|
15
|
+
/**
|
|
16
|
+
* The resolved `@pikku/*` versions are not all the same. Pinning the CLI does
|
|
17
|
+
* not pin its `@pikku/*` dependencies, so a mixed tree is a common cause of
|
|
18
|
+
* behaviour that looks like a framework bug.
|
|
19
|
+
*/
|
|
20
|
+
versionSkew: boolean;
|
|
21
|
+
/** Any package is `linked` — see {@link PikkuPackageVersion.linked}. */
|
|
22
|
+
linkedFramework: boolean;
|
|
23
|
+
node: string;
|
|
24
|
+
packageManager: string | null;
|
|
25
|
+
platform: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Walk up from `startDir` for the first `node_modules/@pikku` that holds
|
|
29
|
+
* packages. A monorepo hoists to the root, an app installs locally, and either
|
|
30
|
+
* way the nearest populated scope is the one that was loaded.
|
|
31
|
+
*
|
|
32
|
+
* Populated means holding something `readPikkuPackages` would read, so the
|
|
33
|
+
* hidden entries it skips cannot qualify a scope either: a stray `.DS_Store` in
|
|
34
|
+
* an empty nested scope would otherwise end the walk there and report a tree
|
|
35
|
+
* with no packages in it.
|
|
36
|
+
*/
|
|
37
|
+
export declare function findPikkuScope(startDir: string): Promise<string | null>;
|
|
38
|
+
/**
|
|
39
|
+
* Versions read off the installed tree rather than out of `package.json`. A
|
|
40
|
+
* range like `^0.12.35` says nothing about what ran, and the version that ran
|
|
41
|
+
* is the only one worth reporting.
|
|
42
|
+
*/
|
|
43
|
+
export declare function readPikkuPackages(scopeDir: string): Promise<PikkuPackageVersion[]>;
|
|
44
|
+
/**
|
|
45
|
+
* `packageManager` in the nearest manifest is authoritative when it is set;
|
|
46
|
+
* otherwise the lockfile is the only evidence of what installed the tree.
|
|
47
|
+
*/
|
|
48
|
+
export declare function detectPackageManager(startDir: string): Promise<string | null>;
|
|
49
|
+
/**
|
|
50
|
+
* Everything about the run a finding needs and no agent should be asked for.
|
|
51
|
+
* All of it is a directory read — no network, no prompting.
|
|
52
|
+
*/
|
|
53
|
+
export declare function collectReportEnvironment(startDir?: string): Promise<ReportEnvironment>;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { readFile, lstat, readdir } from 'node:fs/promises';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
/**
|
|
5
|
+
* Walk up from `startDir` for the first `node_modules/@pikku` that holds
|
|
6
|
+
* packages. A monorepo hoists to the root, an app installs locally, and either
|
|
7
|
+
* way the nearest populated scope is the one that was loaded.
|
|
8
|
+
*
|
|
9
|
+
* Populated means holding something `readPikkuPackages` would read, so the
|
|
10
|
+
* hidden entries it skips cannot qualify a scope either: a stray `.DS_Store` in
|
|
11
|
+
* an empty nested scope would otherwise end the walk there and report a tree
|
|
12
|
+
* with no packages in it.
|
|
13
|
+
*/
|
|
14
|
+
export async function findPikkuScope(startDir) {
|
|
15
|
+
let dir = startDir;
|
|
16
|
+
while (true) {
|
|
17
|
+
const candidate = join(dir, 'node_modules', '@pikku');
|
|
18
|
+
if (existsSync(candidate)) {
|
|
19
|
+
const entries = await readdir(candidate).catch(() => []);
|
|
20
|
+
if (entries.some((entry) => !entry.startsWith('.')))
|
|
21
|
+
return candidate;
|
|
22
|
+
}
|
|
23
|
+
const parent = dirname(dir);
|
|
24
|
+
if (parent === dir)
|
|
25
|
+
return null;
|
|
26
|
+
dir = parent;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Versions read off the installed tree rather than out of `package.json`. A
|
|
31
|
+
* range like `^0.12.35` says nothing about what ran, and the version that ran
|
|
32
|
+
* is the only one worth reporting.
|
|
33
|
+
*/
|
|
34
|
+
export async function readPikkuPackages(scopeDir) {
|
|
35
|
+
const entries = await readdir(scopeDir).catch(() => []);
|
|
36
|
+
const packages = [];
|
|
37
|
+
for (const entry of entries.sort()) {
|
|
38
|
+
if (entry.startsWith('.'))
|
|
39
|
+
continue;
|
|
40
|
+
const packageDir = join(scopeDir, entry);
|
|
41
|
+
const manifest = join(packageDir, 'package.json');
|
|
42
|
+
const raw = await readFile(manifest, 'utf8').catch(() => null);
|
|
43
|
+
if (!raw)
|
|
44
|
+
continue;
|
|
45
|
+
let version;
|
|
46
|
+
try {
|
|
47
|
+
version = JSON.parse(raw).version;
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (typeof version !== 'string')
|
|
53
|
+
continue;
|
|
54
|
+
const stats = await lstat(packageDir).catch(() => null);
|
|
55
|
+
packages.push({
|
|
56
|
+
name: `@pikku/${entry}`,
|
|
57
|
+
version,
|
|
58
|
+
linked: stats?.isSymbolicLink() ?? false,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return packages;
|
|
62
|
+
}
|
|
63
|
+
const LOCKFILES = [
|
|
64
|
+
['yarn.lock', 'yarn'],
|
|
65
|
+
['pnpm-lock.yaml', 'pnpm'],
|
|
66
|
+
['bun.lockb', 'bun'],
|
|
67
|
+
['bun.lock', 'bun'],
|
|
68
|
+
['package-lock.json', 'npm'],
|
|
69
|
+
];
|
|
70
|
+
/**
|
|
71
|
+
* `packageManager` in the nearest manifest is authoritative when it is set;
|
|
72
|
+
* otherwise the lockfile is the only evidence of what installed the tree.
|
|
73
|
+
*/
|
|
74
|
+
export async function detectPackageManager(startDir) {
|
|
75
|
+
let dir = startDir;
|
|
76
|
+
while (true) {
|
|
77
|
+
const manifest = join(dir, 'package.json');
|
|
78
|
+
if (existsSync(manifest)) {
|
|
79
|
+
const raw = await readFile(manifest, 'utf8').catch(() => null);
|
|
80
|
+
if (raw) {
|
|
81
|
+
try {
|
|
82
|
+
const declared = JSON.parse(raw)
|
|
83
|
+
.packageManager;
|
|
84
|
+
if (typeof declared === 'string' && declared.length > 0) {
|
|
85
|
+
return declared;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
// An unparseable manifest tells us nothing; keep walking up.
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
for (const [lockfile, manager] of LOCKFILES) {
|
|
94
|
+
if (existsSync(join(dir, lockfile)))
|
|
95
|
+
return manager;
|
|
96
|
+
}
|
|
97
|
+
const parent = dirname(dir);
|
|
98
|
+
if (parent === dir)
|
|
99
|
+
return null;
|
|
100
|
+
dir = parent;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Everything about the run a finding needs and no agent should be asked for.
|
|
105
|
+
* All of it is a directory read — no network, no prompting.
|
|
106
|
+
*/
|
|
107
|
+
export async function collectReportEnvironment(startDir = process.cwd()) {
|
|
108
|
+
const scope = await findPikkuScope(startDir);
|
|
109
|
+
const packages = scope ? await readPikkuPackages(scope) : [];
|
|
110
|
+
const versions = new Set(packages.map((p) => p.version));
|
|
111
|
+
return {
|
|
112
|
+
packages,
|
|
113
|
+
versionSkew: versions.size > 1,
|
|
114
|
+
linkedFramework: packages.some((p) => p.linked),
|
|
115
|
+
node: process.version,
|
|
116
|
+
packageManager: await detectPackageManager(startDir),
|
|
117
|
+
platform: `${process.platform}-${process.arch}`,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
@@ -1,7 +1,23 @@
|
|
|
1
1
|
import type { PikkuRPC } from '../sdk/pikku-rpc.gen.js';
|
|
2
|
+
export interface ResolvedStage {
|
|
3
|
+
stageId: string;
|
|
4
|
+
branch: string;
|
|
5
|
+
}
|
|
2
6
|
/**
|
|
3
|
-
* Resolve a stage
|
|
4
|
-
*
|
|
7
|
+
* Resolve a stage from (projectId, branch) via the `listStages` RPC. The
|
|
8
|
+
* stageId-based read RPCs (listDeployments, listDeploymentWorkers,
|
|
5
9
|
* getStageDatabaseSchema) need a UUID, but the CLI only knows the branch.
|
|
10
|
+
*
|
|
11
|
+
* `branch` is optional because it is optional in practice: nothing upstream
|
|
12
|
+
* guarantees the flag was passed, and interpolating what arrived produced
|
|
13
|
+
* `No stage for branch "undefined"` — an error naming the missing argument's
|
|
14
|
+
* value rather than saying the argument is missing, directly above a line
|
|
15
|
+
* listing the one stage it could have used. With exactly one stage there is
|
|
16
|
+
* nothing to disambiguate, so that stage is the answer.
|
|
17
|
+
*
|
|
18
|
+
* The branch comes back with the id so callers can name the stage they acted
|
|
19
|
+
* on rather than echoing the argument, which is `undefined` in exactly the
|
|
20
|
+
* case this function exists to handle.
|
|
6
21
|
*/
|
|
7
|
-
export declare function
|
|
22
|
+
export declare function resolveStage(rpc: PikkuRPC, projectId: string, branch: string | undefined): Promise<ResolvedStage>;
|
|
23
|
+
export declare function resolveStageId(rpc: PikkuRPC, projectId: string, branch: string | undefined): Promise<string>;
|
|
@@ -1,14 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Resolve a stage
|
|
3
|
-
*
|
|
2
|
+
* Resolve a stage from (projectId, branch) via the `listStages` RPC. The
|
|
3
|
+
* stageId-based read RPCs (listDeployments, listDeploymentWorkers,
|
|
4
4
|
* getStageDatabaseSchema) need a UUID, but the CLI only knows the branch.
|
|
5
|
+
*
|
|
6
|
+
* `branch` is optional because it is optional in practice: nothing upstream
|
|
7
|
+
* guarantees the flag was passed, and interpolating what arrived produced
|
|
8
|
+
* `No stage for branch "undefined"` — an error naming the missing argument's
|
|
9
|
+
* value rather than saying the argument is missing, directly above a line
|
|
10
|
+
* listing the one stage it could have used. With exactly one stage there is
|
|
11
|
+
* nothing to disambiguate, so that stage is the answer.
|
|
12
|
+
*
|
|
13
|
+
* The branch comes back with the id so callers can name the stage they acted
|
|
14
|
+
* on rather than echoing the argument, which is `undefined` in exactly the
|
|
15
|
+
* case this function exists to handle.
|
|
5
16
|
*/
|
|
6
|
-
export async function
|
|
17
|
+
export async function resolveStage(rpc, projectId, branch) {
|
|
7
18
|
const { stages } = await rpc.invoke('listStages', { projectId });
|
|
19
|
+
const known = stages.map((s) => s.branch);
|
|
20
|
+
if (!branch) {
|
|
21
|
+
const only = stages[0];
|
|
22
|
+
if (stages.length === 1 && only) {
|
|
23
|
+
return { stageId: only.stageId, branch: only.branch };
|
|
24
|
+
}
|
|
25
|
+
throw new Error(stages.length === 0
|
|
26
|
+
? 'No stages deployed for this project yet — run `pikku fabric deploy apply --branch <branch>` first.'
|
|
27
|
+
: `--branch is required — this project has ${stages.length} stages: ${known.join(', ')}`);
|
|
28
|
+
}
|
|
8
29
|
const stage = stages.find((s) => s.branch === branch);
|
|
9
30
|
if (!stage) {
|
|
10
|
-
|
|
11
|
-
throw new Error(`No stage for branch "${branch}".${known ? ` Existing: ${known}` : ''}`);
|
|
31
|
+
throw new Error(`No stage for branch "${branch}".${known.length ? ` Existing: ${known.join(', ')}` : ''}`);
|
|
12
32
|
}
|
|
13
|
-
return stage.stageId;
|
|
33
|
+
return { stageId: stage.stageId, branch: stage.branch };
|
|
34
|
+
}
|
|
35
|
+
export async function resolveStageId(rpc, projectId, branch) {
|
|
36
|
+
return (await resolveStage(rpc, projectId, branch)).stageId;
|
|
14
37
|
}
|
|
@@ -43,13 +43,17 @@ export const dbReset = pikkuSessionlessFunc({
|
|
|
43
43
|
logger.info(zod.written
|
|
44
44
|
? `db reset: regenerated ${zod.outFile} (${zod.tables.length} tables)`
|
|
45
45
|
: `db reset: ${zod.outFile} unchanged`);
|
|
46
|
+
// Both lines report on the SEED STEP, never on the database. A migration
|
|
47
|
+
// is free to carry rows — data a deployed stage needs is migration data —
|
|
48
|
+
// so "database is empty" was a verdict this step has no standing to reach,
|
|
49
|
+
// and it read as a failed reset every time it was wrong.
|
|
46
50
|
if (noSeed) {
|
|
47
|
-
logger.info('db reset: --no-seed,
|
|
51
|
+
logger.info('db reset: --no-seed, skipping the dev seed');
|
|
48
52
|
return;
|
|
49
53
|
}
|
|
50
54
|
const devSeedResult = await devSeed(resolved);
|
|
51
55
|
logger.info(devSeedResult.applied
|
|
52
56
|
? `db reset: seeded ${resolved.devSeedFile} (${devSeedResult.bytes} bytes)`
|
|
53
|
-
: `db reset: no ${resolved.devSeedFile} found
|
|
57
|
+
: `db reset: no dev seed applied (${resolved.devSeedFile} not found)`);
|
|
54
58
|
},
|
|
55
59
|
});
|
|
@@ -24,13 +24,17 @@ import { resolveConsoleMount } from './serve-console.js';
|
|
|
24
24
|
import { serverReadyLine } from '../../server/server-ready.js';
|
|
25
25
|
import { createEphemeralContentSigningJWT } from '../../server/content-signing-jwt.js';
|
|
26
26
|
import { enableDevActorSignIn } from '../../server/actor-sign-in.js';
|
|
27
|
+
import { resolvePersonas } from '../../utils/resolve-personas.js';
|
|
27
28
|
import { applyModelAliasOverride } from '../../utils/model-alias-override.js';
|
|
28
29
|
export const dev = pikkuSessionlessFunc({
|
|
29
30
|
remote: true,
|
|
30
31
|
func: async ({ logger, config, getInspectorState, invalidateInspectorState, variables, devServerRunner, }, { port, watch, hmr, coverage, test, model }, { rpc }) => {
|
|
31
32
|
process.env.PIKKU_DEV_QUICK_LOGIN ??= 'true';
|
|
32
33
|
process.env.PIKKU_ENV ??= resolveDevEnvironmentName(config.environments ?? {});
|
|
33
|
-
enableDevActorSignIn(logger)
|
|
34
|
+
await enableDevActorSignIn(logger, async () => {
|
|
35
|
+
const state = await getInspectorState(true, false, false, true);
|
|
36
|
+
return Object.values(resolvePersonas(state.personas?.definitions ?? [], config.scenarios?.emailDomain));
|
|
37
|
+
});
|
|
34
38
|
applyModelAliasOverride(logger, model, config.models);
|
|
35
39
|
if (test) {
|
|
36
40
|
process.env.PIKKU_TEST_RUN = 'true';
|
|
@@ -11,6 +11,11 @@
|
|
|
11
11
|
export interface PikkuEnvironment {
|
|
12
12
|
apiUrl: string;
|
|
13
13
|
signInPath?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Where the session and its roles are read back, for a stage that reports
|
|
16
|
+
* them somewhere other than `get-session` under the sign-in path's own mount.
|
|
17
|
+
*/
|
|
18
|
+
sessionPath?: string;
|
|
14
19
|
rpcPath?: string;
|
|
15
20
|
appUrl?: string;
|
|
16
21
|
/**
|
|
@@ -55,4 +55,22 @@ export declare const personaRun: import("#pikku/function").PikkuFunctionConfig<{
|
|
|
55
55
|
out?: string;
|
|
56
56
|
}, void, "rpc" | "session", import("#pikku/function").WiredServices>, undefined, undefined>;
|
|
57
57
|
/** Who this app is for, and what each of them wants, without running anything. */
|
|
58
|
+
/**
|
|
59
|
+
* Mint the actor credential for one persona, or for every declared persona.
|
|
60
|
+
*
|
|
61
|
+
* The root secret is entitled to all of them, so nothing that only needs to be
|
|
62
|
+
* one person should ever hold it. What comes out is bound to that persona's
|
|
63
|
+
* address by the target — presenting it for anyone else is refused — so a CI
|
|
64
|
+
* job, a container or a virtual user can be handed exactly the people it is
|
|
65
|
+
* meant to be and no more.
|
|
66
|
+
*
|
|
67
|
+
* Printed as `id=secret` lines, which is the shape PIKKU_PERSONA_SECRETS reads.
|
|
68
|
+
*/
|
|
69
|
+
export declare const personaSecret: import("#pikku/function").PikkuFunctionConfig<{
|
|
70
|
+
personas?: string[];
|
|
71
|
+
}, void, "rpc" | "session", import("#pikku/function").PikkuFunctionSessionless<{
|
|
72
|
+
personas?: string[];
|
|
73
|
+
}, void, "rpc" | "session", import("#pikku/function").WiredServices, unknown> | import("#pikku/function").PikkuFunction<{
|
|
74
|
+
personas?: string[];
|
|
75
|
+
}, void, "rpc" | "session", import("#pikku/function").WiredServices>, undefined, undefined>;
|
|
58
76
|
export declare const personaList: import("#pikku/function").PikkuFunctionConfig<void, void, "rpc" | "session", import("#pikku/function").PikkuFunctionSessionless<void, void, "rpc" | "session", import("#pikku/function").WiredServices, unknown> | import("#pikku/function").PikkuFunction<void, void, "rpc" | "session", import("#pikku/function").WiredServices>, undefined, undefined>;
|