@pikku/cli 0.12.126 → 0.12.128
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 +157 -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 +31 -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 +124 -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 +140 -1
- package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli.gen.js +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 +120 -8
- 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 +6 -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 +23 -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/FabricSecretsDeleteInput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/FabricSecretsDeleteOutput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/PikkuDistInput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/PikkuNewAddonInput.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 +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 +16 -1
- package/dist/src/fabric/fabric-commands.d.ts +163 -0
- package/dist/src/fabric/fabric-commands.js +78 -0
- 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-delete.function.d.ts +36 -0
- package/dist/src/fabric/functions/secrets-delete.function.js +51 -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/functions/commands/dev.js +2 -1
- package/dist/src/functions/commands/dist.d.ts +28 -0
- package/dist/src/functions/commands/dist.js +58 -0
- package/dist/src/functions/commands/environment.d.ts +5 -0
- package/dist/src/functions/commands/new-addon.d.ts +30 -0
- package/dist/src/functions/commands/new-addon.js +81 -3
- package/dist/src/functions/commands/persona-sync.d.ts +5 -4
- package/dist/src/functions/commands/persona-sync.js +6 -5
- package/dist/src/functions/commands/persona.js +7 -2
- package/dist/src/functions/commands/scenario.js +1 -0
- package/dist/src/functions/validate/auth-plugin-checks.d.ts +1 -1
- package/dist/src/functions/validate/auth-plugin-checks.js +9 -5
- package/dist/src/functions/validate/persona-checks.js +9 -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/services.js +9 -0
- package/dist/src/utils/persona-credentials.d.ts +0 -2
- package/dist/src/utils/persona-credentials.js +1 -8
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -8
- package/snippets.json +1 -1
- package/surface.json +1292 -4907
- 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,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
|
+
}
|
|
@@ -4,7 +4,7 @@ import { pikkuSessionlessFunc } from '#pikku/function';
|
|
|
4
4
|
import chokidar from 'chokidar';
|
|
5
5
|
import { pikkuDevReloader, reloadGeneratedMeta, reconcileAddonRegistry, } from '@pikku/core/dev';
|
|
6
6
|
import { InMemoryQueueService, QueueWebhookService } from '@pikku/core/services';
|
|
7
|
-
import { ConsoleLogger, LocalEmailService, spy, InMemoryAgentRunStateService, } from '@pikku/core/services';
|
|
7
|
+
import { ConsoleLogger, LocalEmailService, LocalCredentialService, spy, InMemoryAgentRunStateService, } from '@pikku/core/services';
|
|
8
8
|
import { InMemoryTriggerService } from '@pikku/core/services';
|
|
9
9
|
import { InMemoryWorkflowService } from '@pikku/core/services';
|
|
10
10
|
import { KyselyAgentStorageService, KyselyAgentRunStateService, KyselyAgentRunService, } from '@pikku/kysely';
|
|
@@ -230,6 +230,7 @@ export const dev = pikkuSessionlessFunc({
|
|
|
230
230
|
workflowService,
|
|
231
231
|
workflowRunService: workflowService,
|
|
232
232
|
triggerService: new InMemoryTriggerService(),
|
|
233
|
+
credentialService: new LocalCredentialService(),
|
|
233
234
|
agentStorage,
|
|
234
235
|
agentRunState,
|
|
235
236
|
agentRunService,
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Carry into the build output the files `tsc` compiles around but never emits.
|
|
3
|
+
*
|
|
4
|
+
* `tsc` turns the generated `.ts` under the pikku out dir into JavaScript, so
|
|
5
|
+
* that half arrives on its own. Two kinds of file do not:
|
|
6
|
+
*
|
|
7
|
+
* - the `*.gen.json` meta pikku writes beside them. `resolveJsonModule` lets
|
|
8
|
+
* TypeScript *read* a json, it never copies one to `outDir`, and the meta is
|
|
9
|
+
* read off disk at runtime — `MetaService` opens it by path — so a package
|
|
10
|
+
* that ships only tsc's output answers every meta lookup with nothing.
|
|
11
|
+
* - a hand-authored `.d.ts` such as `types/application-types.d.ts`. A
|
|
12
|
+
* declaration file is an input, and `declaration: true` does not re-emit it.
|
|
13
|
+
*
|
|
14
|
+
* Packages used to do this with `cp -r .pikku types dist/`, which also dumped
|
|
15
|
+
* every `.ts` source into the published output and needed a POSIX shell.
|
|
16
|
+
*/
|
|
17
|
+
export type DistCopy = {
|
|
18
|
+
from: string;
|
|
19
|
+
to: string;
|
|
20
|
+
};
|
|
21
|
+
export declare const planDistCopies: (rootDir: string, distDir: string, files: string[]) => DistCopy[];
|
|
22
|
+
export declare const pikkuDist: import("#pikku/function").PikkuFunctionConfig<{
|
|
23
|
+
distDir?: string;
|
|
24
|
+
}, void, "rpc" | "session", import("#pikku/function").PikkuFunctionSessionless<{
|
|
25
|
+
distDir?: string;
|
|
26
|
+
}, void, "rpc" | "session", import("#pikku/function").WiredServices, unknown> | import("#pikku/function").PikkuFunction<{
|
|
27
|
+
distDir?: string;
|
|
28
|
+
}, void, "rpc" | "session", import("#pikku/function").WiredServices>, undefined, undefined>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { cp, mkdir, readdir } from 'node:fs/promises';
|
|
3
|
+
import { dirname, join, relative, resolve } from 'node:path';
|
|
4
|
+
import ts from 'typescript';
|
|
5
|
+
import { pikkuSessionlessFunc } from '#pikku/function';
|
|
6
|
+
/**
|
|
7
|
+
* `tsc` compiles a `.ts` and emits it. Everything else it either reads without
|
|
8
|
+
* emitting — a `.d.ts` is an input, `declaration: true` does not re-emit one —
|
|
9
|
+
* or ignores entirely, like the generated json.
|
|
10
|
+
*/
|
|
11
|
+
const tscEmitsIt = (file) => file.endsWith('.ts') && !file.endsWith('.d.ts');
|
|
12
|
+
const walk = async (dir) => {
|
|
13
|
+
if (!existsSync(dir)) {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
17
|
+
const files = await Promise.all(entries.map(async (entry) => {
|
|
18
|
+
const path = join(dir, entry.name);
|
|
19
|
+
return entry.isDirectory() ? walk(path) : [path];
|
|
20
|
+
}));
|
|
21
|
+
return files.flat();
|
|
22
|
+
};
|
|
23
|
+
export const planDistCopies = (rootDir, distDir, files) => {
|
|
24
|
+
return files
|
|
25
|
+
.filter((file) => !tscEmitsIt(file))
|
|
26
|
+
.map((from) => ({
|
|
27
|
+
from,
|
|
28
|
+
to: join(distDir, relative(rootDir, from)),
|
|
29
|
+
}));
|
|
30
|
+
};
|
|
31
|
+
const readTsOutDir = (tsconfig) => {
|
|
32
|
+
const parsed = ts.getParsedCommandLineOfConfigFile(tsconfig, {}, {
|
|
33
|
+
...ts.sys,
|
|
34
|
+
onUnRecoverableConfigFileDiagnostic: () => { },
|
|
35
|
+
});
|
|
36
|
+
return parsed?.options.outDir;
|
|
37
|
+
};
|
|
38
|
+
export const pikkuDist = pikkuSessionlessFunc({
|
|
39
|
+
func: async ({ logger, config }, data) => {
|
|
40
|
+
const { rootDir, outDir, srcDirectories, tsconfig } = config;
|
|
41
|
+
const distDir = data.distDir
|
|
42
|
+
? resolve(rootDir, data.distDir)
|
|
43
|
+
: readTsOutDir(resolve(rootDir, tsconfig));
|
|
44
|
+
if (!distDir) {
|
|
45
|
+
logger.error(`${tsconfig} sets no compilerOptions.outDir, so there is nowhere to copy to. Set one, or pass --dist-dir.`);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
const copies = planDistCopies(rootDir, distDir, [
|
|
49
|
+
...(await walk(outDir)),
|
|
50
|
+
...(await Promise.all(srcDirectories.map((dir) => walk(resolve(rootDir, dir))))).flat(),
|
|
51
|
+
]);
|
|
52
|
+
for (const { from, to } of copies) {
|
|
53
|
+
await mkdir(dirname(to), { recursive: true });
|
|
54
|
+
await cp(from, to);
|
|
55
|
+
}
|
|
56
|
+
logger.info(`Copied ${copies.length} generated file(s) into ${relative(rootDir, distDir) || distDir}`);
|
|
57
|
+
},
|
|
58
|
+
});
|
|
@@ -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
|
/**
|
|
@@ -28,6 +28,33 @@ export declare function getAddonFiles(vars: AddonVars, flags: {
|
|
|
28
28
|
delegated?: boolean;
|
|
29
29
|
}): Record<string, string>;
|
|
30
30
|
export declare function getTestFiles(vars: AddonVars): Record<string, string>;
|
|
31
|
+
/**
|
|
32
|
+
* Does `root`'s `workspaces` field cover `dir`?
|
|
33
|
+
*
|
|
34
|
+
* Declaring workspaces is not enough — a root with `packages/*` does not own an
|
|
35
|
+
* addon written to `addons/crm`, and yarn, npm and pnpm all skip a nested
|
|
36
|
+
* package they were never told about.
|
|
37
|
+
*/
|
|
38
|
+
export declare function workspaceCovers(root: string, dir: string): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* An addon that has not been built is dead at runtime.
|
|
41
|
+
*
|
|
42
|
+
* The generated package exports `./dist/...` — that is what an installed
|
|
43
|
+
* consumer resolves, and what the app's own `pikku-bootstrap.gen.ts` imports.
|
|
44
|
+
* Until `build` has run, every `ref('<addon>:...')` resolves to nothing and the
|
|
45
|
+
* app fails at boot with PKU340 plus an ERR_MODULE_NOT_FOUND on a dist path
|
|
46
|
+
* nobody wrote. Nothing about the generated files shows the problem, so the
|
|
47
|
+
* generator finishes the job: install at the root that owns the lockfile, then
|
|
48
|
+
* run the addon's own `build` script (whose `prebuild` is `pikku all`).
|
|
49
|
+
*/
|
|
50
|
+
export type AddonBuildRunner = (command: string, args: string[], cwd: string) => {
|
|
51
|
+
status: number | null;
|
|
52
|
+
error?: Error;
|
|
53
|
+
};
|
|
54
|
+
export declare const buildGeneratedAddon: (addonDir: string, logger: {
|
|
55
|
+
info: (message: string) => void;
|
|
56
|
+
error: (message: string) => void;
|
|
57
|
+
}, run?: AddonBuildRunner) => boolean;
|
|
31
58
|
export declare const pikkuNewAddon: import("#pikku/function").PikkuFunctionConfig<{
|
|
32
59
|
name: string;
|
|
33
60
|
displayName?: string;
|
|
@@ -43,6 +70,7 @@ export declare const pikkuNewAddon: import("#pikku/function").PikkuFunctionConfi
|
|
|
43
70
|
authConfig?: string;
|
|
44
71
|
mcp?: boolean;
|
|
45
72
|
camelCase?: boolean;
|
|
73
|
+
build?: boolean;
|
|
46
74
|
}, void, "rpc" | "session", import("#pikku/function").PikkuFunctionSessionless<{
|
|
47
75
|
name: string;
|
|
48
76
|
displayName?: string;
|
|
@@ -58,6 +86,7 @@ export declare const pikkuNewAddon: import("#pikku/function").PikkuFunctionConfi
|
|
|
58
86
|
authConfig?: string;
|
|
59
87
|
mcp?: boolean;
|
|
60
88
|
camelCase?: boolean;
|
|
89
|
+
build?: boolean;
|
|
61
90
|
}, void, "rpc" | "session", import("#pikku/function").WiredServices, unknown> | import("#pikku/function").PikkuFunction<{
|
|
62
91
|
name: string;
|
|
63
92
|
displayName?: string;
|
|
@@ -73,4 +102,5 @@ export declare const pikkuNewAddon: import("#pikku/function").PikkuFunctionConfi
|
|
|
73
102
|
authConfig?: string;
|
|
74
103
|
mcp?: boolean;
|
|
75
104
|
camelCase?: boolean;
|
|
105
|
+
build?: boolean;
|
|
76
106
|
}, void, "rpc" | "session", import("#pikku/function").WiredServices>, undefined, undefined>;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'fs';
|
|
2
|
-
import { dirname, join } from 'path';
|
|
2
|
+
import { dirname, join, relative as relativePath, sep } from 'path';
|
|
3
3
|
import { mkdir, writeFile } from 'fs/promises';
|
|
4
|
+
import { spawnSync } from 'node:child_process';
|
|
5
|
+
import { findInstallRoot } from './update.js';
|
|
4
6
|
import { createEmptyManifest, saveManifest, } from '../../utils/contract-versions.js';
|
|
5
7
|
import { pikkuSessionlessFunc } from '#pikku/function';
|
|
6
8
|
import { parseOpenAPISpec, computeContractHash, generateAddonFromOpenAPI, loadAuthConfig, } from '@pikku/openapi-parser';
|
|
@@ -159,7 +161,7 @@ export function getAddonFiles(vars, flags) {
|
|
|
159
161
|
scripts: {
|
|
160
162
|
prepublishOnly: 'yarn build',
|
|
161
163
|
prebuild: 'pikku all',
|
|
162
|
-
build: 'tsc &&
|
|
164
|
+
build: 'tsc && pikku dist',
|
|
163
165
|
pikku: 'pikku all',
|
|
164
166
|
},
|
|
165
167
|
peerDependencies: {
|
|
@@ -851,8 +853,81 @@ async function writeFiles(baseDir, files) {
|
|
|
851
853
|
}
|
|
852
854
|
return written;
|
|
853
855
|
}
|
|
856
|
+
/**
|
|
857
|
+
* Does `root`'s `workspaces` field cover `dir`?
|
|
858
|
+
*
|
|
859
|
+
* Declaring workspaces is not enough — a root with `packages/*` does not own an
|
|
860
|
+
* addon written to `addons/crm`, and yarn, npm and pnpm all skip a nested
|
|
861
|
+
* package they were never told about.
|
|
862
|
+
*/
|
|
863
|
+
export function workspaceCovers(root, dir) {
|
|
864
|
+
const relative = relativePath(root, dir).split(sep).join('/');
|
|
865
|
+
if (relative === '' || relative.startsWith('..')) {
|
|
866
|
+
return false;
|
|
867
|
+
}
|
|
868
|
+
let patterns;
|
|
869
|
+
try {
|
|
870
|
+
const manifest = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'));
|
|
871
|
+
patterns = Array.isArray(manifest.workspaces)
|
|
872
|
+
? manifest.workspaces
|
|
873
|
+
: manifest.workspaces?.packages;
|
|
874
|
+
}
|
|
875
|
+
catch {
|
|
876
|
+
return false;
|
|
877
|
+
}
|
|
878
|
+
if (!Array.isArray(patterns)) {
|
|
879
|
+
return false;
|
|
880
|
+
}
|
|
881
|
+
return patterns.some((pattern) => {
|
|
882
|
+
if (typeof pattern !== 'string') {
|
|
883
|
+
return false;
|
|
884
|
+
}
|
|
885
|
+
const source = pattern
|
|
886
|
+
.split('/')
|
|
887
|
+
.map((segment) => segment === '**'
|
|
888
|
+
? '.*'
|
|
889
|
+
: segment.replace(/[.+^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '[^/]*'))
|
|
890
|
+
.join('/');
|
|
891
|
+
return new RegExp(`^${source}$`).test(relative);
|
|
892
|
+
});
|
|
893
|
+
}
|
|
894
|
+
const spawnAddonBuildStep = (command, args, cwd) => {
|
|
895
|
+
const { status, error } = spawnSync(command, args, {
|
|
896
|
+
cwd,
|
|
897
|
+
stdio: 'inherit',
|
|
898
|
+
shell: process.platform === 'win32',
|
|
899
|
+
});
|
|
900
|
+
return { status, error };
|
|
901
|
+
};
|
|
902
|
+
export const buildGeneratedAddon = (addonDir, logger, run = spawnAddonBuildStep) => {
|
|
903
|
+
const { dir: installDir, packageManager } = findInstallRoot(addonDir);
|
|
904
|
+
if (packageManager === 'unknown') {
|
|
905
|
+
logger.error(`Could not tell which package manager owns ${addonDir} — the addon is generated but NOT built. Run install, then the addon's build script, in ${addonDir} before using it.`);
|
|
906
|
+
return false;
|
|
907
|
+
}
|
|
908
|
+
// A root install only reaches the addon when the root's workspace patterns
|
|
909
|
+
// cover it. A root that owns the lockfile but not this package installs
|
|
910
|
+
// nothing for it, so its devDependencies — `@pikku/cli` and `typescript`,
|
|
911
|
+
// which the build script needs — would never arrive.
|
|
912
|
+
const installIn = workspaceCovers(installDir, addonDir)
|
|
913
|
+
? installDir
|
|
914
|
+
: addonDir;
|
|
915
|
+
const steps = [
|
|
916
|
+
[installIn, ['install']],
|
|
917
|
+
[addonDir, ['run', 'build']],
|
|
918
|
+
];
|
|
919
|
+
for (const [cwd, args] of steps) {
|
|
920
|
+
logger.info(`${packageManager} ${args.join(' ')} (${cwd})`);
|
|
921
|
+
const result = run(packageManager, args, cwd);
|
|
922
|
+
if (result.status !== 0) {
|
|
923
|
+
logger.error(`${packageManager} ${args.join(' ')} failed in ${cwd}: ${result.error?.message ?? `exit ${result.status}`}`);
|
|
924
|
+
return false;
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
return true;
|
|
928
|
+
};
|
|
854
929
|
export const pikkuNewAddon = pikkuSessionlessFunc({
|
|
855
|
-
func: async ({ logger, config }, { name, displayName, description, category = 'General', dir, secret = false, variable = false, oauth = false, credential, test = true, openapi, authConfig, mcp = false, camelCase = false, }) => {
|
|
930
|
+
func: async ({ logger, config }, { name, displayName, description, category = 'General', dir, secret = false, variable = false, oauth = false, credential, test = true, openapi, authConfig, mcp = false, camelCase = false, build = true, }) => {
|
|
856
931
|
name = sanitizeAddonName(name);
|
|
857
932
|
if (!/^[a-z][a-z0-9_-]*$/.test(name)) {
|
|
858
933
|
logger.error(`Invalid addon name "${name}": must start with a lowercase letter and contain only lowercase alphanumerics, hyphens, and underscores`);
|
|
@@ -949,6 +1024,9 @@ export const pikkuNewAddon = pikkuSessionlessFunc({
|
|
|
949
1024
|
for (const f of written) {
|
|
950
1025
|
logger.debug({ message: ` ${f}`, type: 'success' });
|
|
951
1026
|
}
|
|
1027
|
+
if (build && !buildGeneratedAddon(addonDir, logger)) {
|
|
1028
|
+
process.exit(1);
|
|
1029
|
+
}
|
|
952
1030
|
console.log(addonDir);
|
|
953
1031
|
},
|
|
954
1032
|
});
|
|
@@ -9,10 +9,11 @@
|
|
|
9
9
|
* config and write through it, which provisioned a local stage correctly and
|
|
10
10
|
* silently provisioned the wrong database for every other environment.
|
|
11
11
|
*
|
|
12
|
-
* So the deployment provisions itself: an app
|
|
13
|
-
* `@pikku/better-auth
|
|
14
|
-
*
|
|
15
|
-
*
|
|
12
|
+
* So the deployment provisions itself: an app hands its personas to
|
|
13
|
+
* `pikkuFabric` from `@pikku/better-auth`, and the plugin creates a missing one
|
|
14
|
+
* on the operator handshake that asks for it, where the database connection and
|
|
15
|
+
* better-auth's own adapter are both already open. What is left here is the
|
|
16
|
+
* half that needs no database — the
|
|
16
17
|
* declaration, and the environment rule applied to it — which is what tells you
|
|
17
18
|
* before a deploy whether the accounts you expect will appear.
|
|
18
19
|
*/
|
|
@@ -12,10 +12,11 @@ import { resolvePersonas } from '../../utils/resolve-personas.js';
|
|
|
12
12
|
* config and write through it, which provisioned a local stage correctly and
|
|
13
13
|
* silently provisioned the wrong database for every other environment.
|
|
14
14
|
*
|
|
15
|
-
* So the deployment provisions itself: an app
|
|
16
|
-
* `@pikku/better-auth
|
|
17
|
-
*
|
|
18
|
-
*
|
|
15
|
+
* So the deployment provisions itself: an app hands its personas to
|
|
16
|
+
* `pikkuFabric` from `@pikku/better-auth`, and the plugin creates a missing one
|
|
17
|
+
* on the operator handshake that asks for it, where the database connection and
|
|
18
|
+
* better-auth's own adapter are both already open. What is left here is the
|
|
19
|
+
* half that needs no database — the
|
|
19
20
|
* declaration, and the environment rule applied to it — which is what tells you
|
|
20
21
|
* before a deploy whether the accounts you expect will appear.
|
|
21
22
|
*/
|
|
@@ -65,6 +66,6 @@ export const personaSync = pikkuSessionlessFunc({
|
|
|
65
66
|
for (const refusal of skipped) {
|
|
66
67
|
logger.info(` skipped: ${refusal}`);
|
|
67
68
|
}
|
|
68
|
-
logger.info(" Provisioning runs in the deployment:
|
|
69
|
+
logger.info(" Provisioning runs in the deployment: pass `personas: { personas: personaConfigs, environments: personaEnvironments }` from the generated personas file to `pikkuFabric` from '@pikku/better-auth'.");
|
|
69
70
|
},
|
|
70
71
|
});
|