@pikku/cli 0.12.99 → 0.12.102
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/console-app/assets/{abnfDiagram-VRR7QNED-CytV-CG1.js → abnfDiagram-VRR7QNED-BneJZPuq.js} +1 -1
- package/console-app/assets/{arc-C5PvmnaA.js → arc-B6oXAx95.js} +1 -1
- package/console-app/assets/architecture-TIHT7OUA-BIpQbDwm.js +1 -0
- package/console-app/assets/{architectureDiagram-ZJ3FMSHR-CJ2xb7C-.js → architectureDiagram-ZJ3FMSHR-Dn6JKcGL.js} +1 -1
- package/console-app/assets/{blockDiagram-677ZJIJ3-CCecrBrk.js → blockDiagram-677ZJIJ3-CQtakjN5.js} +1 -1
- package/console-app/assets/{c4Diagram-LMCZKHZV-CBnpukvQ.js → c4Diagram-LMCZKHZV-DRBlz-sO.js} +1 -1
- package/console-app/assets/channel-D9eZ2wja.js +1 -0
- package/console-app/assets/{chunk-32BRIVSS-D8qWWZRQ.js → chunk-32BRIVSS-DIionvWe.js} +1 -1
- package/console-app/assets/{chunk-52WLFC77-BEpXHMsp.js → chunk-52WLFC77-DwrMMV53.js} +1 -1
- package/console-app/assets/{chunk-C7G6YPKG-DsHUMkOp.js → chunk-C7G6YPKG-C7_SHoee.js} +1 -1
- package/console-app/assets/{chunk-EX3LRPZG-mM7TjVx9.js → chunk-EX3LRPZG-Brqi3de0.js} +1 -1
- package/console-app/assets/{chunk-FWX5IMBZ-CndRAn18.js → chunk-FWX5IMBZ-CGXYdLJv.js} +2 -2
- package/console-app/assets/{chunk-HOUHSVGY-D1kT8umn.js → chunk-HOUHSVGY-C-mHnXIa.js} +1 -1
- package/console-app/assets/{chunk-ICXQ74PX-CeSaGyro.js → chunk-ICXQ74PX-x3psPzuY.js} +1 -1
- package/console-app/assets/{chunk-MOJQB5TN-CaZOCHYr.js → chunk-MOJQB5TN-2uXUItkq.js} +1 -1
- package/console-app/assets/{chunk-OGEWGWER-CnB1CsPt.js → chunk-OGEWGWER-eXRvfFkE.js} +1 -1
- package/console-app/assets/{chunk-PUDLZKDR-BbGulHJm.js → chunk-PUDLZKDR-CyN33Wwe.js} +1 -1
- package/console-app/assets/{chunk-Q4XR5HBZ-BywwzeeR.js → chunk-Q4XR5HBZ-uyzxeIyh.js} +1 -1
- package/console-app/assets/{chunk-RYQCIY6F-CV0R1Adv.js → chunk-RYQCIY6F-CB9wv1YB.js} +1 -1
- package/console-app/assets/{chunk-V7JOEXUC-DGFaAWzB.js → chunk-V7JOEXUC-DLMzjIkb.js} +1 -1
- package/console-app/assets/chunk-VAUOI2AC--YVrsYCZ.js +1 -0
- package/console-app/assets/{chunk-VR4S4FIN-D4-UaW_J.js → chunk-VR4S4FIN-DtBvdHYI.js} +1 -1
- package/console-app/assets/{chunk-WYO6CB5R-D_TFN0d9.js → chunk-WYO6CB5R-B_EVxwHf.js} +1 -1
- package/console-app/assets/chunk-XXDRQBXY-By-5aH9h.js +1 -0
- package/console-app/assets/{chunk-ZGVPDNZ5-C6hdkGQb.js → chunk-ZGVPDNZ5-CGfMGxHR.js} +1 -1
- package/console-app/assets/classDiagram-OUVF2IWQ-Bg6U871E.js +1 -0
- package/console-app/assets/classDiagram-v2-EOCWNBFH-Bg6U871E.js +1 -0
- package/console-app/assets/{cose-bilkent-JH36ORCC-B6ZPxN6v.js → cose-bilkent-JH36ORCC-B_3kCkWC.js} +1 -1
- package/console-app/assets/{cynefin-VYW2F7L2-D_nmxNz_.js → cynefin-VYW2F7L2-Buqf60VA.js} +1 -1
- package/console-app/assets/{cynefinDiagram-TSTJHNR4-CHy5QN0S.js → cynefinDiagram-TSTJHNR4-DOjw2x6X.js} +1 -1
- package/console-app/assets/{dagre-VKFMJZFB-DYfukM34.js → dagre-VKFMJZFB-CTZTYT0b.js} +1 -1
- package/console-app/assets/{diagram-FQU43EPY-Dgb9TPSB.js → diagram-FQU43EPY-BZh4LC_G.js} +1 -1
- package/console-app/assets/{diagram-G47NLZAW-CnFNZs9Z.js → diagram-G47NLZAW-DDHD69gC.js} +1 -1
- package/console-app/assets/{diagram-NH7WQ7WH-DN7h2DU-.js → diagram-NH7WQ7WH-YnfI_N0A.js} +1 -1
- package/console-app/assets/{diagram-OA4YK3LP-RLaQaNtK.js → diagram-OA4YK3LP-ByfLxp7x.js} +1 -1
- package/console-app/assets/{diagram-WEI45ONY-DxHWhVGd.js → diagram-WEI45ONY-CghNIRYp.js} +1 -1
- package/console-app/assets/{dist-BaJNIo4I.js → dist-DCLZxlZv.js} +1 -1
- package/console-app/assets/{ebnfDiagram-CCIWWBDH-UN3Z81-l.js → ebnfDiagram-CCIWWBDH-D5_G_ZqU.js} +1 -1
- package/console-app/assets/{erDiagram-Q63AITRT-C9lGAY3i.js → erDiagram-Q63AITRT-B5ZtoDJs.js} +1 -1
- package/console-app/assets/eventmodeling-45OFAUF4-eU2Q2DYK.js +1 -0
- package/console-app/assets/flowDiagram-23GEKE2U-CtRJ8nYJ.js +1 -0
- package/console-app/assets/{ganttDiagram-NO4QXBWP-CvBjBcdK.js → ganttDiagram-NO4QXBWP-R-TggPMB.js} +1 -1
- package/console-app/assets/{gitGraph-TEB2WS4Q-Cs5Z9jMo.js → gitGraph-TEB2WS4Q-Cjhl-pwb.js} +1 -1
- package/console-app/assets/{gitGraphDiagram-IHSO6WYX-B0i_IJ5r.js → gitGraphDiagram-IHSO6WYX-DnQe5wWr.js} +1 -1
- package/console-app/assets/{index-71U8EEj7.js → index-BZTTf18Y.js} +150 -164
- package/console-app/assets/{index-BXMjqLQ5.css → index-r763CZB4.css} +1 -1
- package/console-app/assets/{info-DKCQHKI2-DHL0afNl.js → info-DKCQHKI2-DlSWT4UP.js} +1 -1
- package/console-app/assets/{infoDiagram-FWYZ7A6U-CBWykodX.js → infoDiagram-FWYZ7A6U-xqpfzGnj.js} +1 -1
- package/console-app/assets/{ishikawaDiagram-FXEZZL3T-DM377eW_.js → ishikawaDiagram-FXEZZL3T-M_pUeGWs.js} +1 -1
- package/console-app/assets/{journeyDiagram-5HDEW3XC-BpX_-Cns.js → journeyDiagram-5HDEW3XC-Dm6FR2DD.js} +1 -1
- package/console-app/assets/{kanban-definition-HUTT4EX6-D3xFsQkO.js → kanban-definition-HUTT4EX6-CbhkDdQH.js} +1 -1
- package/console-app/assets/{line-CTSKHTE0.js → line-C98Z2IVv.js} +1 -1
- package/console-app/assets/{linear-R5GlBvXT.js → linear-fYIkDCbB.js} +1 -1
- package/console-app/assets/{mermaid-parser.core-CkHk4BPi.js → mermaid-parser.core-Dkioi2z2.js} +3 -3
- package/console-app/assets/{mermaid.core-CcjGXuV6.js → mermaid.core-CeJcbw8_.js} +3 -3
- package/console-app/assets/{mindmap-definition-LN4V7U3C-CtolazqQ.js → mindmap-definition-LN4V7U3C-DDitGESW.js} +1 -1
- package/console-app/assets/{packet-7NZHBO7P-BxSOj_Ny.js → packet-7NZHBO7P-DWZKJ9Us.js} +1 -1
- package/console-app/assets/{pegDiagram-2B236MQR-BNsMtxsM.js → pegDiagram-2B236MQR-CZGjPLXH.js} +1 -1
- package/console-app/assets/{pie-RZYD4A2V-BbkKQBA5.js → pie-RZYD4A2V-DT4-E-uE.js} +1 -1
- package/console-app/assets/{pieDiagram-ENE6RG2P-BAZLIz2f.js → pieDiagram-ENE6RG2P-bgr82Jyt.js} +1 -1
- package/console-app/assets/{quadrantDiagram-ABIIQ3AL-Dpvn-1Fs.js → quadrantDiagram-ABIIQ3AL-Dcw3uNG0.js} +1 -1
- package/console-app/assets/{radar-I7S5WNFK-B-uKXIAH.js → radar-I7S5WNFK-CFAbRVFk.js} +1 -1
- package/console-app/assets/{railroad-3IZDKUUU-BHXXK04t.js → railroad-3IZDKUUU-CjkCoEjH.js} +1 -1
- package/console-app/assets/railroad-abnf-AHOZXSZD-BM21cj3I.js +1 -0
- package/console-app/assets/railroad-ebnf-EBAXGLYW-CDjo5TUI.js +1 -0
- package/console-app/assets/railroad-peg-LSFZ7HO6-CiKQmfgW.js +1 -0
- package/console-app/assets/{railroadDiagram-RFXS5EU6-DfUApEQj.js → railroadDiagram-RFXS5EU6-BUoL0dsw.js} +1 -1
- package/console-app/assets/{requirementDiagram-TGXJPOKE-B2zX0jqo.js → requirementDiagram-TGXJPOKE-C27qMKlr.js} +1 -1
- package/console-app/assets/{sankeyDiagram-HTMAVEWB-CbQ2zc7z.js → sankeyDiagram-HTMAVEWB-BYEhrrY0.js} +1 -1
- package/console-app/assets/{sequenceDiagram-DBY2YBRQ-BLT8PXI_.js → sequenceDiagram-DBY2YBRQ-BCuL4Pl6.js} +1 -1
- package/console-app/assets/{src-BLuPUFWW.js → src-jNbD6Nj3.js} +1 -1
- package/console-app/assets/{stateDiagram-2N3HPSRC-BvEyVp85.js → stateDiagram-2N3HPSRC-C8Ywa3Ah.js} +1 -1
- package/console-app/assets/stateDiagram-v2-6OUMAXLB-BIGwMDyj.js +1 -0
- package/console-app/assets/{swimlanes-5IMT3BWC-1AZ459s6.js → swimlanes-5IMT3BWC-C12iYfdp.js} +1 -1
- package/console-app/assets/swimlanesDiagram-G3AALYLV-BsoUfqN-.js +8 -0
- package/console-app/assets/{timeline-definition-FHXFAJF6-dLuvH4s2.js → timeline-definition-FHXFAJF6-BFQotHp7.js} +1 -1
- package/console-app/assets/{treeView-QDETBFTQ-xL2msjo2.js → treeView-QDETBFTQ-CGbwDLTd.js} +1 -1
- package/console-app/assets/{treemap-6X3UGDF4-C98ichVP.js → treemap-6X3UGDF4-DxSGskiF.js} +1 -1
- package/console-app/assets/{vennDiagram-L72KCM5P-HbUmidhv.js → vennDiagram-L72KCM5P-D4hlUYc9.js} +1 -1
- package/console-app/assets/{wardley-OPB4EBWU-C4gJS-m2.js → wardley-OPB4EBWU-XlXl32Vn.js} +1 -1
- package/console-app/assets/{wardleyDiagram-EHGQE667-B7b-LB02.js → wardleyDiagram-EHGQE667-ttCeFzYx.js} +1 -1
- package/console-app/assets/{xychartDiagram-FW5EYKEG-Cm03zUGy.js → xychartDiagram-FW5EYKEG-BMG4kbfv.js} +1 -1
- package/console-app/index.html +2 -2
- package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +6 -2
- package/dist/.pikku/agent/pikku-agent-types.gen.js +3 -0
- package/dist/.pikku/agent/pikku-model-aliases.gen.d.ts +1 -0
- package/dist/.pikku/agent/pikku-model-aliases.gen.js +5 -0
- 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/pikku-cli-channel.d.ts +11 -2
- package/dist/.pikku/cli/pikku-cli-channel.js +34 -9
- 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-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 +2 -2
- package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.json +18 -12
- 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/console/pikku-node-types.gen.d.ts +1 -1
- package/dist/.pikku/function/pikku-function-types.gen.d.ts +10 -20
- package/dist/.pikku/function/pikku-function-types.gen.js +2 -2
- package/dist/.pikku/function/pikku-functions-meta.gen.js +2 -2
- package/dist/.pikku/function/pikku-functions-meta.gen.json +59 -35
- package/dist/.pikku/function/pikku-functions.gen.js +3 -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/pikku-mcp-types.gen.d.ts +1 -1
- package/dist/.pikku/mcp/pikku-mcp-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 +2 -1
- package/dist/.pikku/pikku-bootstrap.gen.js +2 -1
- package/dist/.pikku/pikku-meta-service.gen.d.ts +1 -1
- package/dist/.pikku/pikku-meta-service.gen.js +1 -1
- package/dist/.pikku/pikku-services.gen.d.ts +1 -1
- package/dist/.pikku/pikku-types.gen.d.ts +1 -1
- package/dist/.pikku/pikku-types.gen.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 +2 -2
- 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 +2 -2
- package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.json +2 -1
- package/dist/.pikku/scenarios/pikku-scenario-functions-meta.gen.js +2 -2
- package/dist/.pikku/scenarios/pikku-scenario-functions.gen.d.ts +1 -1
- package/dist/.pikku/scenarios/pikku-scenario-wirings-meta.gen.js +2 -2
- 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/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 +7 -5
- package/dist/.pikku/schemas/schemas/DevInput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/PikkuAIScorerOutput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/ServeInput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/ValidateOutput.schema.json +1 -0
- 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/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/trigger/pikku-trigger-types.gen.d.ts +1 -1
- package/dist/.pikku/trigger/pikku-trigger-types.gen.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/meta/allWorkflow.gen.json +8 -2
- package/dist/.pikku/workflow/pikku-personas.gen.js +1 -1
- package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +18 -10
- package/dist/.pikku/workflow/pikku-workflow-types.gen.js +1 -1
- package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +2 -2
- 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 +20 -11
- package/dist/src/deploy/analyzer/analyzer.js +21 -6
- package/dist/src/deploy/analyzer/manifest.d.ts +18 -0
- package/dist/src/deploy/codegen/per-unit-codegen.js +0 -3
- package/dist/src/deploy/server-entry.js +1 -1
- package/dist/src/fabric/fabric-commands.d.ts +26 -26
- package/dist/src/fabric/functions/add.function.d.ts +1 -1
- package/dist/src/fabric/functions/addon-verify.function.d.ts +1 -1
- package/dist/src/fabric/functions/db-schema.function.d.ts +1 -1
- package/dist/src/fabric/functions/deploy-list.function.d.ts +1 -1
- package/dist/src/fabric/functions/deploy-units.function.d.ts +1 -1
- package/dist/src/fabric/functions/deploy.function.d.ts +2 -2
- package/dist/src/fabric/functions/domains-add.function.d.ts +1 -1
- package/dist/src/fabric/functions/domains-list.function.d.ts +1 -1
- package/dist/src/fabric/functions/domains-remove.function.d.ts +1 -1
- package/dist/src/fabric/functions/errors.function.d.ts +1 -1
- package/dist/src/fabric/functions/init.function.d.ts +1 -1
- package/dist/src/fabric/functions/link.function.d.ts +1 -1
- package/dist/src/fabric/functions/llm-key.function.d.ts +1 -1
- package/dist/src/fabric/functions/login.function.d.ts +1 -1
- package/dist/src/fabric/functions/logs.function.d.ts +1 -1
- package/dist/src/fabric/functions/metrics.function.d.ts +1 -1
- package/dist/src/fabric/functions/publish.function.d.ts +1 -1
- package/dist/src/fabric/functions/rollback.function.d.ts +1 -1
- package/dist/src/fabric/functions/secrets-list.function.d.ts +1 -1
- package/dist/src/fabric/functions/secrets-rotate.function.d.ts +1 -1
- package/dist/src/fabric/functions/secrets-set.function.d.ts +1 -1
- package/dist/src/fabric/functions/smoke.function.d.ts +1 -1
- package/dist/src/fabric/functions/smoke.function.js +7 -4
- package/dist/src/fabric/functions/status.function.d.ts +1 -1
- package/dist/src/fabric/functions/trace.function.d.ts +1 -1
- package/dist/src/fabric/functions/validate.function.d.ts +1 -1
- package/dist/src/fabric/functions/validate.function.js +1 -1
- package/dist/src/functions/commands/all.d.ts +1 -1
- package/dist/src/functions/commands/audit.d.ts +1 -1
- package/dist/src/functions/commands/binary.d.ts +1 -1
- package/dist/src/functions/commands/bootstrap.d.ts +1 -1
- package/dist/src/functions/commands/db-audit.d.ts +1 -1
- package/dist/src/functions/commands/db-baseline.d.ts +1 -1
- package/dist/src/functions/commands/db-check.d.ts +1 -1
- package/dist/src/functions/commands/db-codegen.d.ts +1 -1
- package/dist/src/functions/commands/db-export.d.ts +1 -1
- package/dist/src/functions/commands/db-export.js +1 -1
- package/dist/src/functions/commands/db-generate.d.ts +1 -1
- package/dist/src/functions/commands/db-migrate.d.ts +1 -1
- package/dist/src/functions/commands/db-reset.d.ts +1 -1
- package/dist/src/functions/commands/db-shared.d.ts +0 -14
- package/dist/src/functions/commands/deploy-apply.d.ts +1 -1
- package/dist/src/functions/commands/deploy-info.d.ts +1 -1
- package/dist/src/functions/commands/deploy-plan.d.ts +1 -1
- package/dist/src/functions/commands/dev.d.ts +4 -1
- package/dist/src/functions/commands/dev.js +42 -3
- package/dist/src/functions/commands/emails-init.d.ts +1 -1
- package/dist/src/functions/commands/enable.d.ts +8 -8
- package/dist/src/functions/commands/import-n8n.d.ts +1 -1
- package/dist/src/functions/commands/info.d.ts +4 -4
- package/dist/src/functions/commands/knowledge-index.d.ts +4 -4
- package/dist/src/functions/commands/knowledge-validate.d.ts +1 -1
- package/dist/src/functions/commands/login.d.ts +3 -3
- package/dist/src/functions/commands/meta.d.ts +19 -19
- package/dist/src/functions/commands/new-addon.d.ts +1 -1
- package/dist/src/functions/commands/new-addon.js +6 -3
- package/dist/src/functions/commands/new-function.d.ts +1 -1
- package/dist/src/functions/commands/new-middleware.d.ts +1 -1
- package/dist/src/functions/commands/new-permission.d.ts +1 -1
- package/dist/src/functions/commands/new-wiring.d.ts +1 -1
- package/dist/src/functions/commands/persona-sync.d.ts +1 -1
- package/dist/src/functions/commands/persona.d.ts +2 -2
- package/dist/src/functions/commands/pikku-command-bootstrap.d.ts +1 -1
- package/dist/src/functions/commands/pikku-command-summary.d.ts +1 -1
- package/dist/src/functions/commands/roles-audit.d.ts +1 -1
- package/dist/src/functions/commands/roles-prune.d.ts +1 -1
- package/dist/src/functions/commands/scenario-browser.d.ts +24 -1
- package/dist/src/functions/commands/scenario-browser.js +5 -1
- package/dist/src/functions/commands/scenario.d.ts +8 -2
- package/dist/src/functions/commands/scenario.js +58 -10
- package/dist/src/functions/commands/scopes-audit.d.ts +1 -1
- package/dist/src/functions/commands/scopes-prune.d.ts +1 -1
- package/dist/src/functions/commands/serve.d.ts +4 -1
- package/dist/src/functions/commands/serve.js +16 -2
- package/dist/src/functions/commands/skills.d.ts +2 -2
- package/dist/src/functions/commands/{workspace-validate.d.ts → validate.d.ts} +19 -4
- package/dist/src/functions/commands/validate.js +9 -0
- package/dist/src/functions/commands/versions-check.d.ts +1 -1
- package/dist/src/functions/commands/versions-init.d.ts +1 -1
- package/dist/src/functions/commands/versions-update.d.ts +1 -1
- package/dist/src/functions/commands/watch.d.ts +1 -1
- package/dist/src/functions/db/local-db.d.ts +2 -1
- package/dist/src/functions/db/local-db.js +2 -2
- package/dist/src/functions/runtimes/fetch/index.d.ts +1 -1
- package/dist/src/functions/runtimes/nextjs/pikku-command-nextjs.d.ts +1 -1
- package/dist/src/functions/runtimes/tanstack-start/pikku-command-tanstack-start.d.ts +1 -1
- package/dist/src/functions/runtimes/websocket/pikku-command-websocket-typed.d.ts +1 -1
- package/dist/src/functions/validate/addon-package-checks.d.ts +26 -0
- package/dist/src/functions/validate/addon-package-checks.js +258 -0
- package/dist/src/functions/validate/persona-checks.d.ts +1 -1
- package/dist/src/functions/validate/persona-checks.js +1 -1
- package/dist/src/functions/validate/scenario-file-checks.js +33 -0
- package/dist/src/functions/validate/shared-checks.d.ts +1 -1
- package/dist/src/functions/validate/shared-checks.js +1 -1
- package/dist/src/functions/validate/validate-registry.d.ts +52 -0
- package/dist/src/functions/validate/validate-registry.js +100 -0
- package/dist/src/functions/validate/validate.d.ts +47 -0
- package/dist/src/functions/validate/{workspace-validate.js → validate.js} +46 -12
- package/dist/src/functions/wirings/ai-agent/pikku-command-ai-agent-types.d.ts +1 -1
- package/dist/src/functions/wirings/ai-agent/pikku-command-ai-agent-types.js +3 -2
- package/dist/src/functions/wirings/ai-agent/pikku-command-ai-agent.d.ts +1 -1
- package/dist/src/functions/wirings/ai-agent/pikku-command-ai-agent.js +6 -2
- package/dist/src/functions/wirings/ai-agent/pikku-command-public-agent.d.ts +1 -1
- package/dist/src/functions/wirings/ai-agent/serialize-ai-agent-types.d.ts +1 -1
- package/dist/src/functions/wirings/ai-agent/serialize-ai-agent-types.js +15 -2
- package/dist/src/functions/wirings/ai-agent/serialize-model-aliases.d.ts +5 -0
- package/dist/src/functions/wirings/ai-agent/serialize-model-aliases.js +12 -0
- package/dist/src/functions/wirings/ai-scorer/pikku-command-ai-scorer.d.ts +1 -0
- package/dist/src/functions/wirings/ai-scorer/pikku-command-ai-scorer.js +51 -0
- package/dist/src/functions/wirings/ai-scorer/serialize-scorer-names.d.ts +10 -0
- package/dist/src/functions/wirings/ai-scorer/serialize-scorer-names.js +17 -0
- package/dist/src/functions/wirings/auth/pikku-command-auth.d.ts +1 -1
- package/dist/src/functions/wirings/auth/serialize-auth-gen.js +27 -10
- package/dist/src/functions/wirings/channels/pikku-channels.d.ts +1 -1
- package/dist/src/functions/wirings/channels/pikku-channels.js +1 -1
- package/dist/src/functions/wirings/channels/pikku-command-channel-types.d.ts +1 -1
- package/dist/src/functions/wirings/channels/pikku-command-channels-map.d.ts +1 -1
- package/dist/src/functions/wirings/channels/pikku-command-channels.d.ts +1 -1
- package/dist/src/functions/wirings/channels/pikku-command-channels.js +1 -1
- package/dist/src/functions/wirings/cli/pikku-command-cli-entry.d.ts +1 -1
- package/dist/src/functions/wirings/cli/pikku-command-cli-types.d.ts +1 -1
- package/dist/src/functions/wirings/cli/pikku-command-cli.d.ts +1 -1
- package/dist/src/functions/wirings/cli/pikku-command-cli.js +1 -1
- package/dist/src/functions/wirings/cli/serialize-channel-cli.js +12 -7
- package/dist/src/functions/wirings/console/pikku-command-console-functions.d.ts +1 -1
- package/dist/src/functions/wirings/console/pikku-command-node-types.d.ts +1 -1
- package/dist/src/functions/wirings/console/pikku-command-nodes-meta.d.ts +1 -1
- package/dist/src/functions/wirings/console/serialize-console-functions.js +9 -56
- package/dist/src/functions/wirings/credentials/pikku-command-credentials.d.ts +1 -1
- package/dist/src/functions/wirings/emails/pikku-command-emails.d.ts +1 -1
- package/dist/src/functions/wirings/functions/pikku-command-addon-types.d.ts +1 -1
- package/dist/src/functions/wirings/functions/pikku-command-function-types-split.d.ts +1 -1
- package/dist/src/functions/wirings/functions/pikku-command-function-types.d.ts +1 -1
- package/dist/src/functions/wirings/functions/pikku-command-functions.d.ts +1 -1
- package/dist/src/functions/wirings/functions/pikku-command-functions.js +1 -1
- package/dist/src/functions/wirings/functions/pikku-command-services.d.ts +1 -1
- package/dist/src/functions/wirings/functions/schemas.d.ts +1 -1
- package/dist/src/functions/wirings/functions/serialize-function-types.js +12 -21
- package/dist/src/functions/wirings/gateway/pikku-command-gateway.d.ts +1 -1
- package/dist/src/functions/wirings/graph/pikku-command-graph-wirings.d.ts +1 -1
- package/dist/src/functions/wirings/http/pikku-command-http-map.d.ts +1 -1
- package/dist/src/functions/wirings/http/pikku-command-http-routes.d.ts +1 -1
- package/dist/src/functions/wirings/http/pikku-command-http-routes.js +1 -1
- package/dist/src/functions/wirings/http/pikku-command-http-types.d.ts +1 -1
- package/dist/src/functions/wirings/http/pikku-command-openapi.d.ts +1 -1
- package/dist/src/functions/wirings/http/pikku-http-routes.d.ts +1 -1
- package/dist/src/functions/wirings/http/pikku-http-routes.js +1 -1
- package/dist/src/functions/wirings/mcp/pikku-command-mcp-json.d.ts +1 -1
- package/dist/src/functions/wirings/mcp/pikku-command-mcp-types.d.ts +1 -1
- package/dist/src/functions/wirings/mcp/pikku-command-mcp.d.ts +1 -1
- package/dist/src/functions/wirings/mcp/pikku-command-mcp.js +1 -1
- package/dist/src/functions/wirings/middleware/pikku-command-middleware.d.ts +1 -1
- package/dist/src/functions/wirings/middleware/serialize-middleware-imports.js +5 -1
- package/dist/src/functions/wirings/package/pikku-command-package-types.d.ts +3 -3
- package/dist/src/functions/wirings/package/pikku-command-package.d.ts +1 -1
- package/dist/src/functions/wirings/package/pikku-command-package.js +12 -1
- package/dist/src/functions/wirings/package/serialize-package.d.ts +1 -1
- package/dist/src/functions/wirings/package/serialize-package.js +6 -3
- package/dist/src/functions/wirings/permissions/pikku-command-permissions.d.ts +1 -1
- package/dist/src/functions/wirings/personas/pikku-command-personas.d.ts +1 -1
- package/dist/src/functions/wirings/queue/pikku-command-queue-map.d.ts +1 -1
- package/dist/src/functions/wirings/queue/pikku-command-queue-service.d.ts +1 -1
- package/dist/src/functions/wirings/queue/pikku-command-queue-types.d.ts +1 -1
- package/dist/src/functions/wirings/queue/pikku-command-queue.d.ts +1 -1
- package/dist/src/functions/wirings/queue/pikku-queue-map.d.ts +1 -1
- package/dist/src/functions/wirings/queue/pikku-queue.d.ts +1 -1
- package/dist/src/functions/wirings/realtime/pikku-command-events-scaffold.d.ts +1 -1
- package/dist/src/functions/wirings/realtime/pikku-command-realtime.d.ts +1 -1
- package/dist/src/functions/wirings/roles/pikku-command-roles.d.ts +1 -1
- package/dist/src/functions/wirings/rpc/pikku-command-public-rpc.d.ts +1 -1
- package/dist/src/functions/wirings/rpc/pikku-command-react-query.d.ts +1 -1
- package/dist/src/functions/wirings/rpc/pikku-command-remote-rpc.d.ts +1 -1
- package/dist/src/functions/wirings/rpc/pikku-command-rpc-client.d.ts +1 -1
- package/dist/src/functions/wirings/rpc/pikku-command-rpc-map.d.ts +3 -3
- package/dist/src/functions/wirings/rpc/pikku-command-rpc.d.ts +1 -1
- package/dist/src/functions/wirings/rpc/pikku-command-rpc.js +1 -1
- package/dist/src/functions/wirings/rpc/serialize-typed-rpc-map.js +1 -6
- package/dist/src/functions/wirings/scenarios/register-scenario-instrumentation.js +31 -1
- package/dist/src/functions/wirings/scenarios/serialize-scenario-meta.js +2 -2
- package/dist/src/functions/wirings/scheduler/pikku-command-scheduler-types.d.ts +1 -1
- package/dist/src/functions/wirings/scheduler/pikku-command-scheduler.d.ts +1 -1
- package/dist/src/functions/wirings/scopes/pikku-command-scopes.d.ts +1 -1
- package/dist/src/functions/wirings/secrets/pikku-command-secrets.d.ts +1 -1
- package/dist/src/functions/wirings/triggers/pikku-command-trigger-types.d.ts +1 -1
- package/dist/src/functions/wirings/triggers/pikku-command-trigger.d.ts +1 -1
- package/dist/src/functions/wirings/triggers/serialize-trigger-meta.js +2 -2
- package/dist/src/functions/wirings/user-admin/pikku-command-user-admin-functions.d.ts +1 -1
- package/dist/src/functions/wirings/variables/pikku-command-variables.d.ts +1 -1
- package/dist/src/functions/wirings/virtual-user/pikku-command-virtual-user-functions.d.ts +1 -1
- package/dist/src/functions/wirings/webhook/pikku-command-webhook.d.ts +1 -1
- package/dist/src/functions/wirings/workflow/pikku-command-workflow-routes.d.ts +1 -1
- package/dist/src/functions/wirings/workflow/pikku-command-workflow.d.ts +1 -1
- package/dist/src/functions/wirings/workflow/serialize-workflow-meta.js +2 -2
- package/dist/src/functions/wirings/workflow/serialize-workflow-routes.js +23 -32
- package/dist/src/functions/wirings/workflow/serialize-workflow-types.js +25 -14
- package/dist/src/functions/workflows/all.workflow.js +6 -1
- package/dist/src/server/bun-server-runner.js +3 -0
- package/dist/src/server/dev-server-runner.interface.d.ts +10 -0
- package/dist/src/server/node-server-runner.js +3 -0
- package/dist/src/services.d.ts +1 -1
- package/dist/src/services.js +1 -0
- package/dist/src/utils/meta-diff.d.ts +1 -1
- package/dist/src/utils/meta-diff.js +2 -0
- package/dist/src/utils/model-alias-override.d.ts +7 -0
- package/dist/src/utils/model-alias-override.js +33 -0
- package/dist/src/utils/pikku-cli-config.js +16 -0
- package/dist/src/utils/serialize-meta-ts.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +19 -19
- package/console-app/assets/architecture-TIHT7OUA-C1_ScvPX.js +0 -1
- package/console-app/assets/channel-CwDOkXGI.js +0 -1
- package/console-app/assets/chunk-VAUOI2AC-DxPUd8Yb.js +0 -1
- package/console-app/assets/chunk-XXDRQBXY-BzVuweA_.js +0 -1
- package/console-app/assets/classDiagram-OUVF2IWQ-CTYJkTT0.js +0 -1
- package/console-app/assets/classDiagram-v2-EOCWNBFH-CTYJkTT0.js +0 -1
- package/console-app/assets/eventmodeling-45OFAUF4-Dc5wNSSK.js +0 -1
- package/console-app/assets/flowDiagram-23GEKE2U-zPyGHMi4.js +0 -1
- package/console-app/assets/railroad-abnf-AHOZXSZD-tXSQaBvY.js +0 -1
- package/console-app/assets/railroad-ebnf-EBAXGLYW-DG3aohR0.js +0 -1
- package/console-app/assets/railroad-peg-LSFZ7HO6-DY_gBA-x.js +0 -1
- package/console-app/assets/stateDiagram-v2-6OUMAXLB-RGKS9iU4.js +0 -1
- package/console-app/assets/swimlanesDiagram-G3AALYLV-Ck_0-rfN.js +0 -8
- package/dist/.pikku/schemas/schemas/WorkspaceValidateOutput.schema.json +0 -1
- package/dist/src/functions/commands/workspace-validate.js +0 -9
- package/dist/src/functions/validate/workspace-validate.d.ts +0 -33
- /package/dist/.pikku/schemas/schemas/{WorkspaceValidateInput.schema.json → ValidateInput.schema.json} +0 -0
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { readdir } from 'node:fs/promises';
|
|
3
|
+
import { dirname, join, relative, resolve, sep } from 'node:path';
|
|
4
|
+
import { readJsonSafe, readTextSafe } from './shared-checks.js';
|
|
5
|
+
/** Where the CLI writes generated output, both in source and once built. */
|
|
6
|
+
const GENERATED_DIRS = ['.pikku', join('dist', '.pikku')];
|
|
7
|
+
/** Roots that carry generated output into the tarball when listed in `files`. */
|
|
8
|
+
const SHIPPING_ROOTS = new Set(['dist', '.pikku']);
|
|
9
|
+
/**
|
|
10
|
+
* A package that publishes generated pikku output.
|
|
11
|
+
*
|
|
12
|
+
* The generated files carry relative imports to hand-written sources, so what
|
|
13
|
+
* the package ships and what it references have to agree — which is what the
|
|
14
|
+
* checks below are for.
|
|
15
|
+
*
|
|
16
|
+
* Having a `.pikku` directory is not enough on its own: an app's
|
|
17
|
+
* packages/functions has one too, and it is codegen output for that app rather
|
|
18
|
+
* than something anybody installs. The question is whether the package *ships*
|
|
19
|
+
* it, so the signal is a `files`/`exports` that carries it into the tarball.
|
|
20
|
+
* A private package is excluded for the same reason — nobody installs it, so
|
|
21
|
+
* its published file set is not a thing that can be wrong.
|
|
22
|
+
*/
|
|
23
|
+
export async function isAddonPackage(pkgDir) {
|
|
24
|
+
const pkg = await readJsonSafe(join(pkgDir, 'package.json'));
|
|
25
|
+
if (!pkg || pkg.private)
|
|
26
|
+
return false;
|
|
27
|
+
if (!GENERATED_DIRS.some((dir) => existsSync(join(pkgDir, dir))))
|
|
28
|
+
return false;
|
|
29
|
+
const shipsViaFiles = (pkg.files ?? []).some((entry) => SHIPPING_ROOTS.has(entry.replace(/^\.\//, '').split('/')[0]));
|
|
30
|
+
return shipsViaFiles || JSON.stringify(pkg.exports ?? null).includes('.pikku');
|
|
31
|
+
}
|
|
32
|
+
async function walk(dir) {
|
|
33
|
+
const out = [];
|
|
34
|
+
let entries;
|
|
35
|
+
try {
|
|
36
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
41
|
+
for (const entry of entries) {
|
|
42
|
+
const path = join(dir, entry.name);
|
|
43
|
+
if (entry.isDirectory())
|
|
44
|
+
out.push(...(await walk(path)));
|
|
45
|
+
else
|
|
46
|
+
out.push(path);
|
|
47
|
+
}
|
|
48
|
+
return out;
|
|
49
|
+
}
|
|
50
|
+
const IMPORT_RE = /(?:^|[\s(};])(?:from|import|require)\s*\(?\s*['"]([^'"]+)['"]/g;
|
|
51
|
+
function relativeSpecifiers(source) {
|
|
52
|
+
const found = new Set();
|
|
53
|
+
for (const match of source.matchAll(IMPORT_RE)) {
|
|
54
|
+
const specifier = match[1];
|
|
55
|
+
if (specifier.startsWith('.'))
|
|
56
|
+
found.add(specifier);
|
|
57
|
+
}
|
|
58
|
+
return [...found];
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The on-disk file a specifier names, under TypeScript's NodeNext rules.
|
|
62
|
+
*
|
|
63
|
+
* `./x.js` may be satisfied by `x.ts` or `x.d.ts`, and pikku's generated files
|
|
64
|
+
* import hand-written declarations as `./x.d.js` — the `.js` extension the
|
|
65
|
+
* compiler wants, on a file that only ever exists as `.d.ts`.
|
|
66
|
+
*/
|
|
67
|
+
function resolveCandidates(specifier, fromDir) {
|
|
68
|
+
const base = resolve(fromDir, specifier);
|
|
69
|
+
if (base.endsWith('.d.js'))
|
|
70
|
+
return [base.slice(0, -5) + '.d.ts'];
|
|
71
|
+
if (base.endsWith('.js')) {
|
|
72
|
+
const stem = base.slice(0, -3);
|
|
73
|
+
return [base, stem + '.ts', stem + '.d.ts', stem + '.tsx'];
|
|
74
|
+
}
|
|
75
|
+
// `.mjs` and `.cjs` are scanned as generated files, so they are also imported
|
|
76
|
+
// as one, and each has its own TypeScript twin rather than sharing `.ts`.
|
|
77
|
+
if (base.endsWith('.mjs') || base.endsWith('.cjs')) {
|
|
78
|
+
const stem = base.slice(0, -4);
|
|
79
|
+
const kind = base.slice(-3, -2);
|
|
80
|
+
return [base, `${stem}.${kind}ts`, `${stem}.d.${kind}ts`];
|
|
81
|
+
}
|
|
82
|
+
if (/\.(ts|tsx|json)$/.test(base))
|
|
83
|
+
return [base];
|
|
84
|
+
return [
|
|
85
|
+
base + '.ts',
|
|
86
|
+
base + '.d.ts',
|
|
87
|
+
base + '.js',
|
|
88
|
+
join(base, 'index.ts'),
|
|
89
|
+
join(base, 'index.d.ts'),
|
|
90
|
+
join(base, 'index.js'),
|
|
91
|
+
];
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* The directory a `files` entry is rooted at.
|
|
95
|
+
*
|
|
96
|
+
* `dist`, `dist/`, `dist/**` and `dist/*` all publish the same tree, so the
|
|
97
|
+
* root is what decides both whether a path ships and whether the entry has
|
|
98
|
+
* anything behind it. Anything more elaborate than a trailing wildcard is left
|
|
99
|
+
* to npm.
|
|
100
|
+
*/
|
|
101
|
+
function packedRoot(entry) {
|
|
102
|
+
return entry
|
|
103
|
+
.replace(/^\.\//, '')
|
|
104
|
+
.replace(/\/\*+$/, '')
|
|
105
|
+
.replace(/\/$/, '');
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Whether `files` carries this path into the published tarball.
|
|
109
|
+
*
|
|
110
|
+
* A package with no `files` publishes everything, so the question only has
|
|
111
|
+
* teeth when the field is present.
|
|
112
|
+
*/
|
|
113
|
+
function isPacked(absPath, pkgDir, files) {
|
|
114
|
+
if (!files)
|
|
115
|
+
return true;
|
|
116
|
+
const rel = relative(pkgDir, absPath);
|
|
117
|
+
if (rel.startsWith('..'))
|
|
118
|
+
return false;
|
|
119
|
+
return files.some((entry) => {
|
|
120
|
+
const normalized = packedRoot(entry);
|
|
121
|
+
return rel === normalized || rel.startsWith(normalized + sep);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Every `./…` target reachable through an `exports` or `imports` map, paired
|
|
126
|
+
* with the entry-point name that leads to it.
|
|
127
|
+
*
|
|
128
|
+
* Both fields nest arbitrarily deep — a subpath holds a condition object, which
|
|
129
|
+
* may hold another — so the walk collects strings rather than assuming a shape.
|
|
130
|
+
* A `*` is left in place: the wildcard's own directory is what has to ship.
|
|
131
|
+
*/
|
|
132
|
+
function entryPointTargets(map, name = '') {
|
|
133
|
+
if (typeof map === 'string') {
|
|
134
|
+
return map.startsWith('./') ? [{ name, target: map }] : [];
|
|
135
|
+
}
|
|
136
|
+
if (!map || typeof map !== 'object')
|
|
137
|
+
return [];
|
|
138
|
+
return Object.entries(map).flatMap(([key, value]) => entryPointTargets(value, name || key));
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Every relative import in a shipped generated file must resolve to a file
|
|
142
|
+
* that is itself shipped.
|
|
143
|
+
*
|
|
144
|
+
* Stated as a property rather than as "the build script must copy types/",
|
|
145
|
+
* because the build script is not the only way to get this wrong and will not
|
|
146
|
+
* always be a `cp`. The generated files declare what they need; the check just
|
|
147
|
+
* holds the package to it.
|
|
148
|
+
*/
|
|
149
|
+
export async function runAddonPackageChecks(pkgDir) {
|
|
150
|
+
const findings = [];
|
|
151
|
+
const pkg = await readJsonSafe(join(pkgDir, 'package.json'));
|
|
152
|
+
if (!pkg)
|
|
153
|
+
return findings;
|
|
154
|
+
// `files` is the package's own statement of what it publishes, so an entry
|
|
155
|
+
// with nothing behind it means the build has not run — and validating the
|
|
156
|
+
// published file set of a package that has not been built proves nothing.
|
|
157
|
+
const absent = (pkg.files ?? []).filter((entry) => !existsSync(join(pkgDir, packedRoot(entry))));
|
|
158
|
+
if (absent.length > 0) {
|
|
159
|
+
findings.push({
|
|
160
|
+
id: 'addon-not-built',
|
|
161
|
+
severity: 'info',
|
|
162
|
+
message: `${pkg.name ?? relative(dirname(pkgDir), pkgDir)} lists ${absent.join(', ')} in "files" with nothing on disk — packaging was not verified because the package is not built`,
|
|
163
|
+
path: join(pkgDir, absent[0]),
|
|
164
|
+
fixHint: 'Run the package build first, then validate. In CI, `build && pikku validate` is the order that checks what actually publishes.',
|
|
165
|
+
});
|
|
166
|
+
return findings;
|
|
167
|
+
}
|
|
168
|
+
// The entry points are the package's promise about what can be reached from
|
|
169
|
+
// outside it, and nothing inside dist/.pikku mentions them — so the import
|
|
170
|
+
// walk below cannot see a `#pikku` that still points at the source tree.
|
|
171
|
+
for (const { name, target } of [
|
|
172
|
+
...entryPointTargets(pkg.imports),
|
|
173
|
+
...entryPointTargets(pkg.exports),
|
|
174
|
+
]) {
|
|
175
|
+
const withoutWildcard = target.slice(2).split('*')[0];
|
|
176
|
+
if (!isPacked(join(pkgDir, withoutWildcard), pkgDir, pkg.files)) {
|
|
177
|
+
findings.push({
|
|
178
|
+
id: 'addon-entry-point-not-packed',
|
|
179
|
+
severity: 'error',
|
|
180
|
+
message: `"${name}" resolves to ${target}, which "files" does not publish — the entry point exists here and not for anyone who installs ${pkg.name ?? 'this addon'}`,
|
|
181
|
+
path: join(pkgDir, withoutWildcard),
|
|
182
|
+
fixHint: `Point it at the built copy under dist, or add ${withoutWildcard.split('/')[0]} to "files".`,
|
|
183
|
+
});
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
// Shipping the directory is not the same as producing the file. A wildcard
|
|
187
|
+
// names a directory whose contents are the point, so only a concrete
|
|
188
|
+
// target can be held to existing.
|
|
189
|
+
if (!target.includes('*') && !existsSync(join(pkgDir, withoutWildcard))) {
|
|
190
|
+
findings.push({
|
|
191
|
+
id: 'addon-entry-point-missing',
|
|
192
|
+
severity: 'error',
|
|
193
|
+
message: `"${name}" resolves to ${target}, which does not exist — importing it fails for anyone who installs ${pkg.name ?? 'this addon'}`,
|
|
194
|
+
path: join(pkgDir, withoutWildcard),
|
|
195
|
+
fixHint: 'Point the entry point at a file the build produces, or drop it from "exports".',
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// Both generated directories ship, and they are not the same check twice.
|
|
200
|
+
// `exports` maps `./.pikku/*` to the root one, making it a public entry
|
|
201
|
+
// point whose imports climb to `<pkg>/types`, while the copy under dist
|
|
202
|
+
// reaches `<pkg>/dist/types` — two roots, two ways to fall outside the
|
|
203
|
+
// tarball.
|
|
204
|
+
const generatedRoots = GENERATED_DIRS.map((dir) => join(pkgDir, dir)).filter((dir) => existsSync(dir) && isPacked(dir, pkgDir, pkg.files));
|
|
205
|
+
// One missing file is imported by every generated file that needs its types,
|
|
206
|
+
// so reporting per import turns a single packaging mistake into a page of
|
|
207
|
+
// findings. Group by what is actually wrong: the thing that is not shipped.
|
|
208
|
+
const unresolved = new Map();
|
|
209
|
+
const unpacked = new Map();
|
|
210
|
+
const shippedFiles = (await Promise.all(generatedRoots.map((root) => walk(root)))).flat();
|
|
211
|
+
for (const file of shippedFiles) {
|
|
212
|
+
if (!/\.(ts|tsx|js|mjs|cjs)$/.test(file))
|
|
213
|
+
continue;
|
|
214
|
+
const source = await readTextSafe(file);
|
|
215
|
+
if (!source)
|
|
216
|
+
continue;
|
|
217
|
+
for (const specifier of relativeSpecifiers(source)) {
|
|
218
|
+
const candidates = resolveCandidates(specifier, dirname(file));
|
|
219
|
+
const target = candidates.find((candidate) => existsSync(candidate));
|
|
220
|
+
if (!target) {
|
|
221
|
+
// Keyed by the file that is missing rather than by the specifier: the
|
|
222
|
+
// same absent file is spelled `../types/x` from one directory and
|
|
223
|
+
// `../../types/x` from another, and it is still one thing to fix.
|
|
224
|
+
const missing = candidates[0];
|
|
225
|
+
const seen = unresolved.get(missing) ?? { specifier, files: [] };
|
|
226
|
+
seen.files.push(file);
|
|
227
|
+
unresolved.set(missing, seen);
|
|
228
|
+
}
|
|
229
|
+
else if (!isPacked(target, pkgDir, pkg.files)) {
|
|
230
|
+
const seen = unpacked.get(target) ?? { target, files: [] };
|
|
231
|
+
seen.files.push(file);
|
|
232
|
+
unpacked.set(target, seen);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
const alsoIn = (files) => files.length > 1
|
|
237
|
+
? ` (and ${files.length - 1} other generated file${files.length > 2 ? 's' : ''})`
|
|
238
|
+
: '';
|
|
239
|
+
for (const [missing, { specifier, files }] of unresolved) {
|
|
240
|
+
findings.push({
|
|
241
|
+
id: 'addon-shipped-import-unresolved',
|
|
242
|
+
severity: 'error',
|
|
243
|
+
message: `${relative(pkgDir, missing)} is not in the package, but ${files.length} shipped generated file${files.length === 1 ? '' : 's'} import${files.length === 1 ? 's' : ''} it (as "${specifier}" from ${relative(pkgDir, files[0])}) — anything installing ${pkg.name ?? 'this addon'} typechecks against a module that is not there`,
|
|
244
|
+
path: missing,
|
|
245
|
+
fixHint: 'Ship the file it names. The generated output is copied into dist, so whatever it imports has to be copied too — e.g. `cp -r .pikku types dist/` rather than `cp -r .pikku dist/`.',
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
for (const { target, files } of unpacked.values()) {
|
|
249
|
+
findings.push({
|
|
250
|
+
id: 'addon-shipped-import-not-packed',
|
|
251
|
+
severity: 'error',
|
|
252
|
+
message: `${relative(pkgDir, files[0])} imports ${relative(pkgDir, target)}${alsoIn(files)}, which exists but is excluded by "files" — it resolves here and not for anyone who installs the package`,
|
|
253
|
+
path: target,
|
|
254
|
+
fixHint: `Add ${relative(pkgDir, target).split(sep)[0]} to "files" in package.json, or move the file under a path already listed there.`,
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
return findings;
|
|
258
|
+
}
|
|
@@ -15,7 +15,7 @@ export type PersonaCheckConfig = {
|
|
|
15
15
|
/**
|
|
16
16
|
* The people this project can run as, and whether it can run as them.
|
|
17
17
|
*
|
|
18
|
-
* Shared by `pikku
|
|
18
|
+
* Shared by `pikku validate` and `pikku fabric validate` — the two
|
|
19
19
|
* validators are separate implementations, and a check that only one of them
|
|
20
20
|
* makes is a check half the projects never see.
|
|
21
21
|
*
|
|
@@ -100,7 +100,7 @@ const hasActorSignIn = async (sourceFiles) => {
|
|
|
100
100
|
/**
|
|
101
101
|
* The people this project can run as, and whether it can run as them.
|
|
102
102
|
*
|
|
103
|
-
* Shared by `pikku
|
|
103
|
+
* Shared by `pikku validate` and `pikku fabric validate` — the two
|
|
104
104
|
* validators are separate implementations, and a check that only one of them
|
|
105
105
|
* makes is a check half the projects never see.
|
|
106
106
|
*
|
|
@@ -36,6 +36,16 @@ const SCENARIO_FILE = /\.(scenario|scenarios|steps)\.tsx?$/;
|
|
|
36
36
|
*/
|
|
37
37
|
const VIRTUAL_USER_DECLARATIONS = ['definePersonas', 'runVirtualUser'];
|
|
38
38
|
const VIRTUAL_USER_FILE = /\.(virtual-user|vu)\.tsx?$/;
|
|
39
|
+
/**
|
|
40
|
+
* The declarations that grade an agent, and where they live.
|
|
41
|
+
*
|
|
42
|
+
* A scorer is a test of the agent that is also shipped, which is exactly why it
|
|
43
|
+
* needs its own file rather than sitting beside the agent it grades: the two
|
|
44
|
+
* are edited for opposite reasons, and a rubric buried in an agent definition
|
|
45
|
+
* is one nobody reviews as a rubric.
|
|
46
|
+
*/
|
|
47
|
+
const SCORER_DECLARATIONS = ['pikkuAIScorer', 'pikkuAIJudge'];
|
|
48
|
+
const SCORER_FILE = /\.scorers?\.tsx?$/;
|
|
39
49
|
const isGenerated = (path) => path.includes('.gen.') || path.includes(`${'/'}.pikku${'/'}`);
|
|
40
50
|
const listSourceFiles = async (dir) => {
|
|
41
51
|
if (!existsSync(dir))
|
|
@@ -119,5 +129,28 @@ export const runScenarioFileChecks = async (root, srcDirectories) => {
|
|
|
119
129
|
].join('\n'),
|
|
120
130
|
});
|
|
121
131
|
}
|
|
132
|
+
for (const file of files) {
|
|
133
|
+
if (SCORER_FILE.test(file) || isGenerated(file))
|
|
134
|
+
continue;
|
|
135
|
+
const text = await readTextSafe(file);
|
|
136
|
+
if (!text)
|
|
137
|
+
continue;
|
|
138
|
+
const used = SCORER_DECLARATIONS.filter((name) => new RegExp(`\\b${name}\\s*\\(`).test(text));
|
|
139
|
+
if (used.length === 0)
|
|
140
|
+
continue;
|
|
141
|
+
const rel = relative(root, file);
|
|
142
|
+
findings.push({
|
|
143
|
+
id: 'scorer-declared-outside-scorer-file',
|
|
144
|
+
severity: 'error',
|
|
145
|
+
message: `${rel} declares ${used.join(', ')} — scorers and judges must live in a *.scorer.ts file, not mixed into application code`,
|
|
146
|
+
path: file,
|
|
147
|
+
fixHint: [
|
|
148
|
+
'Move the declaration into a dedicated file, e.g.:',
|
|
149
|
+
` ${rel.replace(/[^/\\]+$/, 'grading.scorer.ts')}`,
|
|
150
|
+
'A scorer grades the agent it sits next to, and is edited for the',
|
|
151
|
+
'opposite reason — keeping it separate is what keeps it reviewable.',
|
|
152
|
+
].join('\n'),
|
|
153
|
+
});
|
|
154
|
+
}
|
|
122
155
|
return findings;
|
|
123
156
|
};
|
|
@@ -48,7 +48,7 @@ export declare function readTextSafe(path: string): Promise<string | null>;
|
|
|
48
48
|
/**
|
|
49
49
|
* Every check that is true of any pikku project, regardless of where it deploys.
|
|
50
50
|
*
|
|
51
|
-
* `pikku
|
|
51
|
+
* `pikku validate`'s app-project check is exactly this; `pikku fabric validate` is this
|
|
52
52
|
* plus the deploy-shaped checks (themes, frontends, the Cloudflare adapter, the
|
|
53
53
|
* .gitignore contract). Before this module the two were separate walks over the
|
|
54
54
|
* same project that duplicated sixteen findings verbatim, and each carried
|
|
@@ -85,7 +85,7 @@ const REQUIRED_SCAFFOLD = [
|
|
|
85
85
|
/**
|
|
86
86
|
* Every check that is true of any pikku project, regardless of where it deploys.
|
|
87
87
|
*
|
|
88
|
-
* `pikku
|
|
88
|
+
* `pikku validate`'s app-project check is exactly this; `pikku fabric validate` is this
|
|
89
89
|
* plus the deploy-shaped checks (themes, frontends, the Cloudflare adapter, the
|
|
90
90
|
* .gitignore contract). Before this module the two were separate walks over the
|
|
91
91
|
* same project that duplicated sixteen findings verbatim, and each carried
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { ValidateFinding as Finding } from './persona-checks.js';
|
|
2
|
+
export type ValidateTarget = {
|
|
3
|
+
/** Absolute directory the check runs against. */
|
|
4
|
+
dir: string;
|
|
5
|
+
/** How the target is named in output — repo-relative, or "." for the root. */
|
|
6
|
+
label: string;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* A check plus the condition under which it means anything.
|
|
10
|
+
*
|
|
11
|
+
* `pikku validate` runs every check whose precondition holds, wherever it
|
|
12
|
+
* holds. It deliberately does not detect a project *kind* and then dispatch:
|
|
13
|
+
* the repos that motivated this are several kinds at once — the addons
|
|
14
|
+
* monorepo is a workspace containing 217 publishable addons — and any
|
|
15
|
+
* single-kind guess is wrong for them. Preconditions compose where a mode
|
|
16
|
+
* would have had to pick.
|
|
17
|
+
*/
|
|
18
|
+
export type ValidateCheck = {
|
|
19
|
+
id: string;
|
|
20
|
+
/** What this check is for, shown when reporting what ran. */
|
|
21
|
+
subject: string;
|
|
22
|
+
applies: (target: ValidateTarget) => Promise<boolean>;
|
|
23
|
+
run: (target: ValidateTarget) => Promise<Finding[]>;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Every directory under `root` that holds a package.json.
|
|
27
|
+
*
|
|
28
|
+
* Walking beats reading the `workspaces` globs: the field is an array in one
|
|
29
|
+
* repo and `{ packages: [...] }` in the next, spells the same layout as
|
|
30
|
+
* `packages/**` or as six explicit globs, and a package that is real but
|
|
31
|
+
* unlisted is exactly the kind of thing worth validating. Over-collecting is
|
|
32
|
+
* harmless here because the preconditions decide what actually runs.
|
|
33
|
+
*/
|
|
34
|
+
export declare function discoverTargets(root: string, maxDepth?: number): Promise<ValidateTarget[]>;
|
|
35
|
+
export declare const CHECKS: ValidateCheck[];
|
|
36
|
+
export type ValidationPlan = Array<{
|
|
37
|
+
check: ValidateCheck;
|
|
38
|
+
target: ValidateTarget;
|
|
39
|
+
}>;
|
|
40
|
+
export declare function planValidation(root: string): Promise<ValidationPlan>;
|
|
41
|
+
export type ValidateReport = {
|
|
42
|
+
ok: boolean;
|
|
43
|
+
root: string;
|
|
44
|
+
/** What ran, so a clean result can say what it actually looked at. */
|
|
45
|
+
ran: Array<{
|
|
46
|
+
checkId: string;
|
|
47
|
+
subject: string;
|
|
48
|
+
target: string;
|
|
49
|
+
}>;
|
|
50
|
+
findings: Finding[];
|
|
51
|
+
};
|
|
52
|
+
export declare function runValidate(root: string): Promise<ValidateReport>;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { readdir } from 'node:fs/promises';
|
|
3
|
+
import { join, relative } from 'node:path';
|
|
4
|
+
import { isAddonPackage, runAddonPackageChecks, } from './addon-package-checks.js';
|
|
5
|
+
import { runSharedProjectChecks } from './shared-checks.js';
|
|
6
|
+
/** A hand-written `types/application-types.d.ts` beside package.json. */
|
|
7
|
+
const ADDON_MARKER = join('types', 'application-types.d.ts');
|
|
8
|
+
const SKIP_DIRS = new Set([
|
|
9
|
+
'node_modules',
|
|
10
|
+
'.git',
|
|
11
|
+
'dist',
|
|
12
|
+
'build',
|
|
13
|
+
'.pikku',
|
|
14
|
+
'.pikku-runtime',
|
|
15
|
+
'coverage',
|
|
16
|
+
'.next',
|
|
17
|
+
'.yarn',
|
|
18
|
+
]);
|
|
19
|
+
/**
|
|
20
|
+
* Every directory under `root` that holds a package.json.
|
|
21
|
+
*
|
|
22
|
+
* Walking beats reading the `workspaces` globs: the field is an array in one
|
|
23
|
+
* repo and `{ packages: [...] }` in the next, spells the same layout as
|
|
24
|
+
* `packages/**` or as six explicit globs, and a package that is real but
|
|
25
|
+
* unlisted is exactly the kind of thing worth validating. Over-collecting is
|
|
26
|
+
* harmless here because the preconditions decide what actually runs.
|
|
27
|
+
*/
|
|
28
|
+
export async function discoverTargets(root, maxDepth = 5) {
|
|
29
|
+
const targets = [];
|
|
30
|
+
const visit = async (dir, depth) => {
|
|
31
|
+
if (existsSync(join(dir, 'package.json'))) {
|
|
32
|
+
targets.push({ dir, label: relative(root, dir) || '.' });
|
|
33
|
+
}
|
|
34
|
+
if (depth >= maxDepth)
|
|
35
|
+
return;
|
|
36
|
+
let entries;
|
|
37
|
+
try {
|
|
38
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
for (const entry of entries) {
|
|
44
|
+
if (!entry.isDirectory())
|
|
45
|
+
continue;
|
|
46
|
+
if (entry.name.startsWith('.') || SKIP_DIRS.has(entry.name))
|
|
47
|
+
continue;
|
|
48
|
+
await visit(join(dir, entry.name), depth + 1);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
await visit(root, 0);
|
|
52
|
+
return targets;
|
|
53
|
+
}
|
|
54
|
+
export const CHECKS = [
|
|
55
|
+
{
|
|
56
|
+
id: 'app-project',
|
|
57
|
+
subject: 'app project',
|
|
58
|
+
// An addon also carries a pikku.config.json, and running the app-shaped
|
|
59
|
+
// checks against one reports every app convention it has no reason to
|
|
60
|
+
// follow — starting with a packages/functions/ it will never have.
|
|
61
|
+
applies: async ({ dir }) => existsSync(join(dir, 'pikku.config.json')) &&
|
|
62
|
+
!existsSync(join(dir, ADDON_MARKER)),
|
|
63
|
+
run: async ({ dir }) => (await runSharedProjectChecks(dir)).findings,
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: 'addon-package',
|
|
67
|
+
subject: 'addon',
|
|
68
|
+
applies: async ({ dir }) => isAddonPackage(dir),
|
|
69
|
+
run: async ({ dir }) => runAddonPackageChecks(dir),
|
|
70
|
+
},
|
|
71
|
+
];
|
|
72
|
+
export async function planValidation(root) {
|
|
73
|
+
const plan = [];
|
|
74
|
+
for (const target of await discoverTargets(root)) {
|
|
75
|
+
for (const check of CHECKS) {
|
|
76
|
+
if (await check.applies(target))
|
|
77
|
+
plan.push({ check, target });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return plan;
|
|
81
|
+
}
|
|
82
|
+
export async function runValidate(root) {
|
|
83
|
+
const plan = await planValidation(root);
|
|
84
|
+
const findings = [];
|
|
85
|
+
const ran = [];
|
|
86
|
+
for (const { check, target } of plan) {
|
|
87
|
+
findings.push(...(await check.run(target)));
|
|
88
|
+
ran.push({
|
|
89
|
+
checkId: check.id,
|
|
90
|
+
subject: check.subject,
|
|
91
|
+
target: target.label,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
ok: !findings.some((f) => f.severity === 'error'),
|
|
96
|
+
root,
|
|
97
|
+
ran,
|
|
98
|
+
findings,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export { readJsonSafe, readTextSafe } from './shared-checks.js';
|
|
3
|
+
export declare const FindingSchema: z.ZodObject<{
|
|
4
|
+
id: z.ZodString;
|
|
5
|
+
severity: z.ZodEnum<{
|
|
6
|
+
warn: "warn";
|
|
7
|
+
error: "error";
|
|
8
|
+
info: "info";
|
|
9
|
+
}>;
|
|
10
|
+
message: z.ZodString;
|
|
11
|
+
path: z.ZodString;
|
|
12
|
+
fixHint: z.ZodString;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
export type Finding = z.infer<typeof FindingSchema>;
|
|
15
|
+
export declare const ValidateInput: z.ZodObject<{}, z.core.$strip>;
|
|
16
|
+
export declare const ValidateOutput: z.ZodObject<{
|
|
17
|
+
ok: z.ZodBoolean;
|
|
18
|
+
root: z.ZodString;
|
|
19
|
+
ran: z.ZodArray<z.ZodObject<{
|
|
20
|
+
checkId: z.ZodString;
|
|
21
|
+
subject: z.ZodString;
|
|
22
|
+
target: z.ZodString;
|
|
23
|
+
}, z.core.$strip>>;
|
|
24
|
+
findings: z.ZodArray<z.ZodObject<{
|
|
25
|
+
id: z.ZodString;
|
|
26
|
+
severity: z.ZodEnum<{
|
|
27
|
+
warn: "warn";
|
|
28
|
+
error: "error";
|
|
29
|
+
info: "info";
|
|
30
|
+
}>;
|
|
31
|
+
message: z.ZodString;
|
|
32
|
+
path: z.ZodString;
|
|
33
|
+
fixHint: z.ZodString;
|
|
34
|
+
}, z.core.$strip>>;
|
|
35
|
+
}, z.core.$strip>;
|
|
36
|
+
/**
|
|
37
|
+
* The workspace root, or failing that the package the caller is standing in.
|
|
38
|
+
*
|
|
39
|
+
* A standalone publishable addon has no `workspaces` anywhere above it, and
|
|
40
|
+
* running from its `src/` would otherwise validate `src/` — a directory with no
|
|
41
|
+
* package.json, where every check's precondition is false and the run reports
|
|
42
|
+
* that nothing applied. The addon author is exactly who the addon checks are
|
|
43
|
+
* for, so the nearest package.json is the answer when no workspace claims it.
|
|
44
|
+
*/
|
|
45
|
+
export declare function findProjectRoot(startDir: string): Promise<string>;
|
|
46
|
+
export declare function runProjectValidate(startDir?: string): Promise<z.infer<typeof ValidateOutput>>;
|
|
47
|
+
export declare const renderValidate: (_s: unknown, { ok, root, ran, findings }: z.infer<typeof ValidateOutput>) => void;
|
|
@@ -3,7 +3,7 @@ import { readFile } from 'node:fs/promises';
|
|
|
3
3
|
import { dirname, join } from 'node:path';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import { added, changed, dim, removed } from '../../fabric/lib/output.js';
|
|
6
|
-
import {
|
|
6
|
+
import { runValidate } from './validate-registry.js';
|
|
7
7
|
export { readJsonSafe, readTextSafe } from './shared-checks.js';
|
|
8
8
|
export const FindingSchema = z.object({
|
|
9
9
|
id: z.string(),
|
|
@@ -12,16 +12,32 @@ export const FindingSchema = z.object({
|
|
|
12
12
|
path: z.string(),
|
|
13
13
|
fixHint: z.string(),
|
|
14
14
|
});
|
|
15
|
-
export const
|
|
16
|
-
export const
|
|
15
|
+
export const ValidateInput = z.object({});
|
|
16
|
+
export const ValidateOutput = z.object({
|
|
17
17
|
ok: z.boolean(),
|
|
18
18
|
root: z.string(),
|
|
19
|
+
ran: z.array(z.object({
|
|
20
|
+
checkId: z.string(),
|
|
21
|
+
subject: z.string(),
|
|
22
|
+
target: z.string(),
|
|
23
|
+
})),
|
|
19
24
|
findings: z.array(FindingSchema),
|
|
20
25
|
});
|
|
26
|
+
/**
|
|
27
|
+
* The workspace root, or failing that the package the caller is standing in.
|
|
28
|
+
*
|
|
29
|
+
* A standalone publishable addon has no `workspaces` anywhere above it, and
|
|
30
|
+
* running from its `src/` would otherwise validate `src/` — a directory with no
|
|
31
|
+
* package.json, where every check's precondition is false and the run reports
|
|
32
|
+
* that nothing applied. The addon author is exactly who the addon checks are
|
|
33
|
+
* for, so the nearest package.json is the answer when no workspace claims it.
|
|
34
|
+
*/
|
|
21
35
|
export async function findProjectRoot(startDir) {
|
|
22
36
|
let dir = startDir;
|
|
37
|
+
let nearestPackage;
|
|
23
38
|
while (true) {
|
|
24
39
|
if (existsSync(join(dir, 'package.json'))) {
|
|
40
|
+
nearestPackage ??= dir;
|
|
25
41
|
try {
|
|
26
42
|
const pkg = JSON.parse(await readFile(join(dir, 'package.json'), 'utf8'));
|
|
27
43
|
if (pkg.workspaces)
|
|
@@ -33,19 +49,37 @@ export async function findProjectRoot(startDir) {
|
|
|
33
49
|
}
|
|
34
50
|
const parent = dirname(dir);
|
|
35
51
|
if (parent === dir)
|
|
36
|
-
return startDir;
|
|
52
|
+
return nearestPackage ?? startDir;
|
|
37
53
|
dir = parent;
|
|
38
54
|
}
|
|
39
55
|
}
|
|
40
|
-
export async function
|
|
56
|
+
export async function runProjectValidate(startDir = process.cwd()) {
|
|
41
57
|
const root = await findProjectRoot(startDir);
|
|
42
|
-
|
|
43
|
-
const ok = !findings.some((f) => f.severity === 'error');
|
|
44
|
-
return { ok, root, findings };
|
|
58
|
+
return runValidate(root);
|
|
45
59
|
}
|
|
46
|
-
|
|
60
|
+
/** "2 addons, 1 app project" — what the run actually looked at. */
|
|
61
|
+
function describeRan(ran) {
|
|
62
|
+
const bySubject = new Map();
|
|
63
|
+
for (const entry of ran) {
|
|
64
|
+
bySubject.set(entry.subject, (bySubject.get(entry.subject) ?? 0) + 1);
|
|
65
|
+
}
|
|
66
|
+
return [...bySubject]
|
|
67
|
+
.map(([subject, count]) => `${count} ${subject}${count === 1 ? '' : 's'}`)
|
|
68
|
+
.join(', ');
|
|
69
|
+
}
|
|
70
|
+
export const renderValidate = (_s, { ok, root, ran, findings }) => {
|
|
71
|
+
// A green tick for a run that checked nothing is the one outcome worth
|
|
72
|
+
// guarding against: auto-detection that finds nothing looks identical to
|
|
73
|
+
// auto-detection that found everything and liked it.
|
|
74
|
+
if (ran.length === 0) {
|
|
75
|
+
console.log(changed('⚠') +
|
|
76
|
+
' ' +
|
|
77
|
+
'Nothing to validate here — no app project and no publishable addon found');
|
|
78
|
+
console.log(` ${dim('fix:')} Run from a directory with a pikku.config.json, or from a package that publishes generated pikku output.`);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
47
81
|
if (findings.length === 0) {
|
|
48
|
-
console.log(added(
|
|
82
|
+
console.log(added(`✓ All checks passed — checked ${describeRan(ran)}`));
|
|
49
83
|
return;
|
|
50
84
|
}
|
|
51
85
|
const relPath = (p) => p.startsWith(root + '/') || p.startsWith(root + '\\')
|
|
@@ -76,9 +110,9 @@ export const renderWorkspaceValidate = (_s, { ok, root, findings }) => {
|
|
|
76
110
|
counts.push(dim(`${infos.length} info${infos.length !== 1 ? 's' : ''}`));
|
|
77
111
|
}
|
|
78
112
|
console.log('─'.repeat(40));
|
|
79
|
-
console.log(counts.join(' '));
|
|
113
|
+
console.log(`${counts.join(' ')} ${dim(`across ${describeRan(ran)}`)}`);
|
|
80
114
|
if (ok) {
|
|
81
115
|
console.log();
|
|
82
|
-
console.log(added('✓') + ' ' + dim('no errors
|
|
116
|
+
console.log(added('✓') + ' ' + dim('no errors'));
|
|
83
117
|
}
|
|
84
118
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const pikkuAIAgentTypes: import("#pikku").PikkuFunctionConfig<void, void, "rpc" | "session", import("#pikku").PikkuFunctionSessionless<void, void, "rpc" | "session", import("#pikku").WiredServices> | import("#pikku").PikkuFunction<void, void, "rpc" | "session", import("#pikku").WiredServices>, undefined, undefined>;
|
|
1
|
+
export declare const pikkuAIAgentTypes: import("#pikku").PikkuFunctionConfig<void, void, "rpc" | "session", import("#pikku").PikkuFunctionSessionless<void, void, "rpc" | "session", import("#pikku").WiredServices, unknown> | import("#pikku").PikkuFunction<void, void, "rpc" | "session", import("#pikku").WiredServices>, undefined, undefined>;
|
|
@@ -5,11 +5,12 @@ import { logCommandInfoAndTime } from '../../../middleware/log-command-info-and-
|
|
|
5
5
|
import { serializeAIAgentTypes } from './serialize-ai-agent-types.js';
|
|
6
6
|
export const pikkuAIAgentTypes = pikkuSessionlessFunc({
|
|
7
7
|
func: async ({ logger, config }) => {
|
|
8
|
-
const { agentTypesFile, functionTypesFile, agentMapDeclarationFile, scopesFile, packageMappings, } = config;
|
|
8
|
+
const { agentTypesFile, functionTypesFile, agentMapDeclarationFile, scorerNamesDeclarationFile, scopesFile, packageMappings, } = config;
|
|
9
9
|
const functionTypesImportPath = getFileImportRelativePath(agentTypesFile, functionTypesFile, packageMappings);
|
|
10
10
|
const agentMapImportPath = getFileImportRelativePath(agentTypesFile, agentMapDeclarationFile, packageMappings);
|
|
11
11
|
const scopesImportPath = getFileImportRelativePath(agentTypesFile, scopesFile, packageMappings);
|
|
12
|
-
const
|
|
12
|
+
const scorerNamesImportPath = getFileImportRelativePath(agentTypesFile, scorerNamesDeclarationFile, packageMappings);
|
|
13
|
+
const content = serializeAIAgentTypes(functionTypesImportPath, agentMapImportPath, scopesImportPath, scorerNamesImportPath);
|
|
13
14
|
await writeFileInDir(logger, agentTypesFile, content);
|
|
14
15
|
},
|
|
15
16
|
middleware: [
|