@pikku/cli 0.12.103 → 0.12.105
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-BLi9JHGg.js → abnfDiagram-VRR7QNED-QRjCVsso.js} +1 -1
- package/console-app/assets/{arc-B3b5uYlL.js → arc-CloGjkHW.js} +1 -1
- package/console-app/assets/architecture-TIHT7OUA-Cz78Qi5H.js +1 -0
- package/console-app/assets/{architectureDiagram-ZJ3FMSHR-Dkd8kxIa.js → architectureDiagram-ZJ3FMSHR-Dl10fVqw.js} +1 -1
- package/console-app/assets/{blockDiagram-677ZJIJ3-DnH0nNlb.js → blockDiagram-677ZJIJ3-CMNoQhwm.js} +1 -1
- package/console-app/assets/{c4Diagram-LMCZKHZV-BlelCS5i.js → c4Diagram-LMCZKHZV-C2pWYCa6.js} +1 -1
- package/console-app/assets/channel-Bm4o-pNB.js +1 -0
- package/console-app/assets/{chunk-32BRIVSS-D7tMgtT1.js → chunk-32BRIVSS-DC3ZGIPN.js} +1 -1
- package/console-app/assets/{chunk-52WLFC77-CRepS35y.js → chunk-52WLFC77-DuAheIlc.js} +1 -1
- package/console-app/assets/{chunk-C7G6YPKG-CUldlJz4.js → chunk-C7G6YPKG-BVtRZIEZ.js} +1 -1
- package/console-app/assets/{chunk-EX3LRPZG-DODbrqEj.js → chunk-EX3LRPZG-CWXF7N33.js} +1 -1
- package/console-app/assets/{chunk-FWX5IMBZ-nZa59wGD.js → chunk-FWX5IMBZ-UN3i5qMG.js} +2 -2
- package/console-app/assets/{chunk-HOUHSVGY-BaawVZCa.js → chunk-HOUHSVGY-DMorD8Ib.js} +1 -1
- package/console-app/assets/{chunk-ICXQ74PX-C86LrIRs.js → chunk-ICXQ74PX-BiuzWyj2.js} +1 -1
- package/console-app/assets/{chunk-MOJQB5TN-ovUDQlyW.js → chunk-MOJQB5TN-6BhXmDyj.js} +1 -1
- package/console-app/assets/{chunk-OGEWGWER-ByZKAcGu.js → chunk-OGEWGWER-BNi3Gsmc.js} +1 -1
- package/console-app/assets/{chunk-PUDLZKDR-DdeJN3wJ.js → chunk-PUDLZKDR-DNWGCeoL.js} +1 -1
- package/console-app/assets/{chunk-Q4XR5HBZ-Blp5W9-b.js → chunk-Q4XR5HBZ-i4zkt4cc.js} +1 -1
- package/console-app/assets/{chunk-RYQCIY6F-DehwjyPp.js → chunk-RYQCIY6F-DvRUzuDz.js} +1 -1
- package/console-app/assets/{chunk-V7JOEXUC-Ca1xeVdo.js → chunk-V7JOEXUC-JMjbqEgu.js} +1 -1
- package/console-app/assets/chunk-VAUOI2AC-D4_whP-t.js +1 -0
- package/console-app/assets/{chunk-VR4S4FIN-Cj7ZlsLr.js → chunk-VR4S4FIN-BcHHugM0.js} +1 -1
- package/console-app/assets/{chunk-WYO6CB5R-CsdBQ1HS.js → chunk-WYO6CB5R-COKjEQwP.js} +1 -1
- package/console-app/assets/chunk-XXDRQBXY-mkAF2YHU.js +1 -0
- package/console-app/assets/{chunk-ZGVPDNZ5-DMnFdLEO.js → chunk-ZGVPDNZ5-CENGdlFJ.js} +1 -1
- package/console-app/assets/classDiagram-OUVF2IWQ-B2cEvfK0.js +1 -0
- package/console-app/assets/classDiagram-v2-EOCWNBFH-B2cEvfK0.js +1 -0
- package/console-app/assets/{cose-bilkent-JH36ORCC-CiYBhiBv.js → cose-bilkent-JH36ORCC-D6F1MghO.js} +1 -1
- package/console-app/assets/{cynefin-VYW2F7L2-BXuNC8qm.js → cynefin-VYW2F7L2-BIhff1Ln.js} +1 -1
- package/console-app/assets/{cynefinDiagram-TSTJHNR4-Ck53b-Nr.js → cynefinDiagram-TSTJHNR4-DrlBq_QP.js} +1 -1
- package/console-app/assets/{dagre-VKFMJZFB-C9hZCnOv.js → dagre-VKFMJZFB-Cm2eP0ez.js} +1 -1
- package/console-app/assets/{diagram-FQU43EPY-DuEKSLPE.js → diagram-FQU43EPY-C667dC19.js} +1 -1
- package/console-app/assets/{diagram-G47NLZAW-B_yO-zKt.js → diagram-G47NLZAW-3K3OPEuG.js} +1 -1
- package/console-app/assets/{diagram-NH7WQ7WH-CtKFjoB4.js → diagram-NH7WQ7WH-CUK-d5iT.js} +1 -1
- package/console-app/assets/{diagram-OA4YK3LP-T9eIYXYs.js → diagram-OA4YK3LP-BmjCoGBZ.js} +1 -1
- package/console-app/assets/{diagram-WEI45ONY-BTgu-I69.js → diagram-WEI45ONY-D33qA2d9.js} +1 -1
- package/console-app/assets/{dist-DSVj7qxi.js → dist-jqlCD26w.js} +1 -1
- package/console-app/assets/{ebnfDiagram-CCIWWBDH-BdyNRX2k.js → ebnfDiagram-CCIWWBDH-DUHkt7z6.js} +1 -1
- package/console-app/assets/{erDiagram-Q63AITRT-B0cr0nxe.js → erDiagram-Q63AITRT-BAtdfbq3.js} +1 -1
- package/console-app/assets/eventmodeling-45OFAUF4-iK6rmyk3.js +1 -0
- package/console-app/assets/flowDiagram-23GEKE2U-CSYhKO9Y.js +1 -0
- package/console-app/assets/{ganttDiagram-NO4QXBWP-Cr1R_nGh.js → ganttDiagram-NO4QXBWP-64_vh9rj.js} +1 -1
- package/console-app/assets/{gitGraph-TEB2WS4Q-zcmQoWd4.js → gitGraph-TEB2WS4Q-DlFJY0cQ.js} +1 -1
- package/console-app/assets/{gitGraphDiagram-IHSO6WYX-CHB9Fnch.js → gitGraphDiagram-IHSO6WYX-D9fpmYRm.js} +1 -1
- package/console-app/assets/{index-BbIUXgNl.js → index-Byf4wkdP.js} +159 -153
- package/console-app/assets/{index-C9U-Zyvx.css → index-CTO5cTAD.css} +1 -1
- package/console-app/assets/{info-DKCQHKI2-BGPZGp_E.js → info-DKCQHKI2-DhyT_-b1.js} +1 -1
- package/console-app/assets/{infoDiagram-FWYZ7A6U-Br_p6SR_.js → infoDiagram-FWYZ7A6U-ufTemVSR.js} +1 -1
- package/console-app/assets/{ishikawaDiagram-FXEZZL3T-Ma2d4IuN.js → ishikawaDiagram-FXEZZL3T-CWHvEncb.js} +1 -1
- package/console-app/assets/{journeyDiagram-5HDEW3XC-LdCblEX2.js → journeyDiagram-5HDEW3XC-DKH8UvEq.js} +1 -1
- package/console-app/assets/{kanban-definition-HUTT4EX6-CRWetzV4.js → kanban-definition-HUTT4EX6-BODtp_fB.js} +1 -1
- package/console-app/assets/{line-DrceqMYY.js → line-Do9j3HRL.js} +1 -1
- package/console-app/assets/{linear-acWbtwAj.js → linear-5Z8stnH-.js} +1 -1
- package/console-app/assets/{mermaid-parser.core-n773Jf0G.js → mermaid-parser.core-CYJsdwMO.js} +3 -3
- package/console-app/assets/{mermaid.core-DyTRkSqH.js → mermaid.core-DwI4IdKs.js} +3 -3
- package/console-app/assets/{mindmap-definition-LN4V7U3C-CBU-ehFU.js → mindmap-definition-LN4V7U3C-D7IWNYnf.js} +1 -1
- package/console-app/assets/{packet-7NZHBO7P-DL_fgdX1.js → packet-7NZHBO7P-comMLvz_.js} +1 -1
- package/console-app/assets/{pegDiagram-2B236MQR-CrFaAHHj.js → pegDiagram-2B236MQR-CbqiI_m5.js} +1 -1
- package/console-app/assets/{pie-RZYD4A2V-STtzW8Tz.js → pie-RZYD4A2V-VZXoX73g.js} +1 -1
- package/console-app/assets/{pieDiagram-ENE6RG2P-DsUOr1Ud.js → pieDiagram-ENE6RG2P-SA-sCnrt.js} +1 -1
- package/console-app/assets/{quadrantDiagram-ABIIQ3AL-DmuSe_qW.js → quadrantDiagram-ABIIQ3AL-CI840rae.js} +1 -1
- package/console-app/assets/{radar-I7S5WNFK-L8w2lEOb.js → radar-I7S5WNFK-W0UH9BdP.js} +1 -1
- package/console-app/assets/{railroad-3IZDKUUU-CxqlE5vc.js → railroad-3IZDKUUU-_HEtbruA.js} +1 -1
- package/console-app/assets/railroad-abnf-AHOZXSZD-ghLnUEfg.js +1 -0
- package/console-app/assets/railroad-ebnf-EBAXGLYW-D8JHCZD5.js +1 -0
- package/console-app/assets/railroad-peg-LSFZ7HO6-C9eC4l2D.js +1 -0
- package/console-app/assets/{railroadDiagram-RFXS5EU6-CJ8Lpbeo.js → railroadDiagram-RFXS5EU6-Cm2SfP9Z.js} +1 -1
- package/console-app/assets/{requirementDiagram-TGXJPOKE-8OXQXUud.js → requirementDiagram-TGXJPOKE-CyHrMdrC.js} +1 -1
- package/console-app/assets/{sankeyDiagram-HTMAVEWB-Bezd2CqZ.js → sankeyDiagram-HTMAVEWB-DL0eJ1aK.js} +1 -1
- package/console-app/assets/{sequenceDiagram-DBY2YBRQ-DHb5js3D.js → sequenceDiagram-DBY2YBRQ-B2AvEvXu.js} +1 -1
- package/console-app/assets/{src-DfFamOl-.js → src-72nNqhBu.js} +1 -1
- package/console-app/assets/{stateDiagram-2N3HPSRC-UpyJm2mi.js → stateDiagram-2N3HPSRC-vgyc-CMC.js} +1 -1
- package/console-app/assets/stateDiagram-v2-6OUMAXLB-B2WCkCZh.js +1 -0
- package/console-app/assets/{swimlanes-5IMT3BWC-yUrV5f4O.js → swimlanes-5IMT3BWC-GiOMMhZh.js} +1 -1
- package/console-app/assets/swimlanesDiagram-G3AALYLV-CkCbtoLb.js +8 -0
- package/console-app/assets/{timeline-definition-FHXFAJF6-B6w-rZeZ.js → timeline-definition-FHXFAJF6-DTJQsTn8.js} +1 -1
- package/console-app/assets/{treeView-QDETBFTQ-0k2QpnXc.js → treeView-QDETBFTQ-aizmbgl7.js} +1 -1
- package/console-app/assets/{treemap-6X3UGDF4-ByCuDcGA.js → treemap-6X3UGDF4-DIBl6bfV.js} +1 -1
- package/console-app/assets/{vennDiagram-L72KCM5P-BH4374lw.js → vennDiagram-L72KCM5P-C4Ngu7VX.js} +1 -1
- package/console-app/assets/{wardley-OPB4EBWU-DNVwuJz6.js → wardley-OPB4EBWU-BqdXyJTm.js} +1 -1
- package/console-app/assets/{wardleyDiagram-EHGQE667-EXnQ6lkx.js → wardleyDiagram-EHGQE667-Cw2M8s0p.js} +1 -1
- package/console-app/assets/{xychartDiagram-FW5EYKEG-rFh-UdgH.js → xychartDiagram-FW5EYKEG-BxMLZdbF.js} +1 -1
- package/console-app/index.html +9 -2
- package/console-app/site.webmanifest +19 -8
- package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +12 -12
- package/dist/.pikku/agent/pikku-agent-types.gen.js +6 -6
- package/dist/.pikku/agent/pikku-model-aliases.gen.js +1 -1
- package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +4 -4
- package/dist/.pikku/channel/pikku-channel-types.gen.js +3 -2
- package/dist/.pikku/cli/pikku-cli-channel.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-channel.js +13 -3
- package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +2 -2
- package/dist/.pikku/cli/pikku-cli-client.gen.js +2 -2
- 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 +2 -2
- 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 +48 -4
- 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 +2 -2
- package/dist/.pikku/console/pikku-node-types.gen.d.ts +1 -1
- package/dist/.pikku/function/pikku-function-types.gen.d.ts +9 -7
- package/dist/.pikku/function/pikku-function-types.gen.js +5 -4
- package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
- package/dist/.pikku/function/pikku-functions-meta.gen.json +97 -54
- package/dist/.pikku/function/pikku-functions.gen.js +8 -8
- package/dist/.pikku/http/pikku-http-types.gen.d.ts +3 -3
- package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
- package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +4 -3
- 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 +1 -1
- package/dist/.pikku/pikku-bootstrap.gen.js +1 -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 +4 -4
- package/dist/.pikku/pikku-services.gen.js +3 -3
- 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 +2 -2
- package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
- package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +1 -1
- package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.json +5 -3
- 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-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/pikku-scheduler-types.gen.d.ts +2 -2
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
- package/dist/.pikku/schemas/register.gen.js +8 -6
- package/dist/.pikku/schemas/schemas/PikkuSemverOutput.schema.json +1 -0
- package/dist/.pikku/scopes/pikku-personas.gen.d.ts +2 -1
- package/dist/.pikku/scopes/pikku-personas.gen.js +1 -1
- package/dist/.pikku/scopes/pikku-roles.gen.d.ts +2 -2
- package/dist/.pikku/scopes/pikku-roles.gen.js +1 -1
- package/dist/.pikku/scopes/pikku-scope-types.gen.d.ts +5 -5
- package/dist/.pikku/scopes/pikku-scope-types.gen.js +3 -3
- package/dist/.pikku/scopes/pikku-scopes.gen.d.ts +2 -2
- package/dist/.pikku/scopes/pikku-scopes.gen.js +1 -1
- package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +3 -2
- 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 +3 -3
- package/dist/.pikku/trigger/pikku-trigger-types.gen.js +1 -1
- package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +2 -2
- package/dist/.pikku/variables/pikku-variable-types.gen.js +1 -1
- package/dist/.pikku/variables/pikku-variables.gen.d.ts +3 -3
- package/dist/.pikku/variables/pikku-variables.gen.js +2 -2
- package/dist/.pikku/workflow/meta/allWorkflow.gen.json +9 -9
- package/dist/.pikku/workflow/pikku-personas.gen.d.ts +3 -2
- package/dist/.pikku/workflow/pikku-personas.gen.js +2 -2
- package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +6 -6
- package/dist/.pikku/workflow/pikku-workflow-types.gen.js +3 -3
- 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 +50 -4
- package/dist/src/deploy/analyzer/analyzer.js +5 -5
- package/dist/src/deploy/bundler/bundler.js +2 -2
- package/dist/src/functions/commands/audit.js +33 -9
- package/dist/src/functions/commands/bootstrap.js +1 -1
- package/dist/src/functions/commands/{dev-ai-runner.d.ts → dev-agent-runner.d.ts} +3 -3
- package/dist/src/functions/commands/{dev-ai-runner.js → dev-agent-runner.js} +4 -4
- package/dist/src/functions/commands/dev.js +29 -23
- package/dist/src/functions/commands/persona-sync.js +2 -2
- package/dist/src/functions/commands/persona.js +7 -6
- package/dist/src/functions/commands/roles-prune.js +1 -1
- package/dist/src/functions/commands/roles-shared.d.ts +1 -1
- package/dist/src/functions/commands/roles-shared.js +1 -1
- package/dist/src/functions/commands/scenario-browser.d.ts +2 -2
- package/dist/src/functions/commands/scenario-formatter.d.ts +1 -1
- package/dist/src/functions/commands/scenario-ladder.d.ts +4 -3
- package/dist/src/functions/commands/scenario-ladder.js +1 -1
- package/dist/src/functions/commands/scenario-plan.d.ts +2 -2
- package/dist/src/functions/commands/scenario-plan.js +1 -1
- package/dist/src/functions/commands/scenario.d.ts +0 -3
- package/dist/src/functions/commands/scenario.js +40 -38
- package/dist/src/functions/commands/scopes-prune.js +1 -1
- package/dist/src/functions/commands/scopes-shared.d.ts +1 -1
- package/dist/src/functions/commands/scopes-shared.js +1 -1
- package/dist/src/functions/commands/semver-render.d.ts +2 -0
- package/dist/src/functions/commands/semver-render.js +60 -0
- package/dist/src/functions/commands/semver.d.ts +25 -0
- package/dist/src/functions/commands/semver.js +50 -0
- package/dist/src/functions/commands/serve.js +20 -19
- package/dist/src/functions/commands/start-coverage.d.ts +1 -1
- package/dist/src/functions/commands/start-coverage.js +2 -2
- package/dist/src/functions/commands/update-render.d.ts +2 -0
- package/dist/src/functions/commands/update-render.js +102 -0
- package/dist/src/functions/commands/update.d.ts +99 -0
- package/dist/src/functions/commands/update.js +392 -0
- package/dist/src/functions/commands/virtual-user-formatter.d.ts +1 -1
- package/dist/src/functions/validate/scenario-file-checks.js +1 -1
- package/dist/src/functions/validate/validate-registry.js +10 -0
- package/dist/src/functions/validate/workspace-exports-checks.d.ts +14 -0
- package/dist/src/functions/validate/workspace-exports-checks.js +211 -0
- package/dist/src/functions/wirings/agent/pikku-command-agent-types.d.ts +1 -0
- package/dist/src/functions/wirings/{ai-agent/pikku-command-ai-agent-types.js → agent/pikku-command-agent-types.js} +3 -3
- package/dist/src/functions/wirings/agent/pikku-command-agent.d.ts +1 -0
- package/dist/src/functions/wirings/{ai-agent/pikku-command-ai-agent.js → agent/pikku-command-agent.js} +5 -5
- package/dist/src/functions/wirings/{ai-agent → agent}/serialize-agent-map.d.ts +2 -2
- package/dist/src/functions/wirings/agent/serialize-agent-types.d.ts +1 -0
- package/dist/src/functions/wirings/{ai-agent/serialize-ai-agent-types.js → agent/serialize-agent-types.js} +21 -32
- package/dist/src/functions/wirings/{ai-agent → agent}/serialize-public-agent.js +1 -1
- package/dist/src/functions/wirings/agent-scorer/pikku-command-agent-scorer.d.ts +1 -0
- package/dist/src/functions/wirings/{ai-scorer/pikku-command-ai-scorer.js → agent-scorer/pikku-command-agent-scorer.js} +5 -5
- package/dist/src/functions/wirings/{ai-scorer → agent-scorer}/serialize-scorer-names.d.ts +1 -1
- package/dist/src/functions/wirings/auth/serialize-auth-gen.js +6 -6
- package/dist/src/functions/wirings/channels/pikku-channels.js +1 -1
- package/dist/src/functions/wirings/channels/pikku-command-channels.js +1 -1
- package/dist/src/functions/wirings/channels/serialize-channel-types.js +4 -3
- package/dist/src/functions/wirings/channels/serialize-typed-channel-map.d.ts +2 -2
- package/dist/src/functions/wirings/cli/pikku-command-cli.js +1 -1
- package/dist/src/functions/wirings/cli/serialize-channel-cli-client.d.ts +1 -1
- package/dist/src/functions/wirings/cli/serialize-channel-cli-client.js +3 -3
- package/dist/src/functions/wirings/cli/serialize-channel-cli.d.ts +1 -1
- package/dist/src/functions/wirings/cli/serialize-channel-cli.js +2 -2
- package/dist/src/functions/wirings/cli/serialize-cli-types.js +2 -1
- package/dist/src/functions/wirings/cli/serialize-local-cli-bootstrap.js +1 -1
- package/dist/src/functions/wirings/console/pikku-command-nodes-meta.js +1 -1
- package/dist/src/functions/wirings/credentials/pikku-command-credentials.js +1 -1
- package/dist/src/functions/wirings/credentials/serialize-credentials-types.d.ts +1 -1
- package/dist/src/functions/wirings/credentials/serialize-credentials-types.js +4 -3
- package/dist/src/functions/wirings/functions/pikku-command-functions.js +1 -1
- package/dist/src/functions/wirings/functions/serialize-addon-types.js +2 -1
- package/dist/src/functions/wirings/functions/serialize-function-imports.d.ts +1 -1
- package/dist/src/functions/wirings/functions/serialize-function-types.js +11 -12
- package/dist/src/functions/wirings/gateway/serialize-gateway-meta.d.ts +1 -1
- package/dist/src/functions/wirings/http/pikku-command-http-routes.js +1 -1
- package/dist/src/functions/wirings/http/pikku-http-routes.js +1 -1
- package/dist/src/functions/wirings/http/serialize-http-types.js +3 -2
- package/dist/src/functions/wirings/http/serialize-typed-http-map.d.ts +1 -1
- package/dist/src/functions/wirings/mcp/pikku-command-mcp.js +1 -1
- package/dist/src/functions/wirings/mcp/serialize-mcp-types.js +3 -11
- package/dist/src/functions/wirings/package/serialize-package-types.js +7 -6
- package/dist/src/functions/wirings/personas/pikku-command-personas.js +1 -1
- package/dist/src/functions/wirings/personas/serialize-personas-types.d.ts +1 -1
- package/dist/src/functions/wirings/personas/serialize-personas-types.js +6 -2
- package/dist/src/functions/wirings/queue/serialize-queue-map.d.ts +1 -1
- package/dist/src/functions/wirings/queue/serialize-queue-meta.d.ts +1 -1
- package/dist/src/functions/wirings/queue/serialize-queue-types.js +2 -1
- package/dist/src/functions/wirings/roles/pikku-command-roles.js +1 -1
- package/dist/src/functions/wirings/roles/serialize-roles-types.d.ts +1 -1
- package/dist/src/functions/wirings/roles/serialize-roles-types.js +2 -2
- package/dist/src/functions/wirings/rpc/serialize-remote-rpc.js +1 -1
- package/dist/src/functions/wirings/rpc/serialize-rpc-wrapper.js +1 -1
- package/dist/src/functions/wirings/rpc/serialize-typed-rpc-map.js +5 -5
- package/dist/src/functions/wirings/scenarios/register-scenario-instrumentation.js +3 -2
- package/dist/src/functions/wirings/scenarios/scenario-partition.d.ts +1 -1
- package/dist/src/functions/wirings/scenarios/scenario-schema-partition.d.ts +1 -1
- package/dist/src/functions/wirings/scenarios/serialize-feature-meta.d.ts +1 -1
- package/dist/src/functions/wirings/scenarios/serialize-scenario-meta.js +2 -2
- package/dist/src/functions/wirings/scenarios/serialize-scenario-registration.js +1 -1
- package/dist/src/functions/wirings/scheduler/serialize-scheduler-meta.d.ts +1 -1
- package/dist/src/functions/wirings/scheduler/serialize-scheduler-types.js +2 -1
- package/dist/src/functions/wirings/scopes/pikku-command-scopes.js +1 -1
- package/dist/src/functions/wirings/scopes/serialize-scopes-types.d.ts +1 -1
- package/dist/src/functions/wirings/scopes/serialize-scopes-types.js +3 -3
- package/dist/src/functions/wirings/secrets/pikku-command-secrets.js +1 -1
- package/dist/src/functions/wirings/secrets/serialize-secrets-types.d.ts +1 -1
- package/dist/src/functions/wirings/secrets/serialize-secrets-types.js +4 -3
- package/dist/src/functions/wirings/triggers/serialize-trigger-meta.d.ts +1 -1
- package/dist/src/functions/wirings/triggers/serialize-trigger-meta.js +2 -2
- package/dist/src/functions/wirings/triggers/serialize-trigger-types.js +3 -2
- package/dist/src/functions/wirings/variables/pikku-command-variables.js +1 -1
- package/dist/src/functions/wirings/variables/serialize-variables-types.d.ts +1 -1
- package/dist/src/functions/wirings/variables/serialize-variables-types.js +3 -3
- package/dist/src/functions/wirings/virtual-user/serialize-virtual-user-functions.js +7 -13
- package/dist/src/functions/wirings/webhook/serialize-webhook.js +1 -1
- package/dist/src/functions/wirings/workflow/serialize-personas.d.ts +1 -1
- package/dist/src/functions/wirings/workflow/serialize-personas.js +4 -3
- package/dist/src/functions/wirings/workflow/serialize-scenario-step-map.d.ts +1 -1
- package/dist/src/functions/wirings/workflow/serialize-workflow-bootstrap-map.d.ts +1 -1
- package/dist/src/functions/wirings/workflow/serialize-workflow-map.d.ts +2 -2
- package/dist/src/functions/wirings/workflow/serialize-workflow-map.js +1 -1
- package/dist/src/functions/wirings/workflow/serialize-workflow-meta.js +2 -2
- package/dist/src/functions/wirings/workflow/serialize-workflow-routes.js +1 -1
- package/dist/src/functions/wirings/workflow/serialize-workflow-types.js +6 -9
- package/dist/src/functions/workflows/all.workflow.js +6 -5
- package/dist/src/middleware/log-command-info-and-time.d.ts +1 -1
- package/dist/src/server/node-server-runner.js +5 -2
- package/dist/src/services/cli-logger.service.js +1 -1
- package/dist/src/utils/precise-coverage-map.d.ts +1 -1
- package/dist/src/utils/remove-legacy-scaffold-file.d.ts +14 -0
- package/dist/src/utils/remove-legacy-scaffold-file.js +28 -1
- package/dist/src/utils/resolve-personas.d.ts +3 -3
- package/dist/src/utils/resolve-personas.js +2 -2
- package/dist/src/utils/schema-diff.d.ts +22 -0
- package/dist/src/utils/schema-diff.js +190 -0
- package/dist/src/utils/serialize-schemas.d.ts +1 -1
- package/dist/src/utils/serialize-schemas.js +1 -1
- package/dist/src/utils/surface-diff.d.ts +35 -0
- package/dist/src/utils/surface-diff.js +183 -0
- package/dist/src/utils/surface.d.ts +51 -0
- package/dist/src/utils/surface.js +156 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +25 -17
- package/console-app/assets/architecture-TIHT7OUA-BYeDayHv.js +0 -1
- package/console-app/assets/channel-CTa6nggO.js +0 -1
- package/console-app/assets/chunk-VAUOI2AC-BCngaLxk.js +0 -1
- package/console-app/assets/chunk-XXDRQBXY-CGIlOoBU.js +0 -1
- package/console-app/assets/classDiagram-OUVF2IWQ-Bwt1ZVOR.js +0 -1
- package/console-app/assets/classDiagram-v2-EOCWNBFH-Bwt1ZVOR.js +0 -1
- package/console-app/assets/eventmodeling-45OFAUF4-BeHdsPzc.js +0 -1
- package/console-app/assets/flowDiagram-23GEKE2U-6N6mIkfB.js +0 -1
- package/console-app/assets/railroad-abnf-AHOZXSZD-CkJOR_Em.js +0 -1
- package/console-app/assets/railroad-ebnf-EBAXGLYW-BH_pRGgm.js +0 -1
- package/console-app/assets/railroad-peg-LSFZ7HO6-B50bKcii.js +0 -1
- package/console-app/assets/stateDiagram-v2-6OUMAXLB-C6gAfg82.js +0 -1
- package/console-app/assets/swimlanesDiagram-G3AALYLV-Ch2_j5W5.js +0 -8
- package/dist/src/functions/wirings/ai-agent/pikku-command-ai-agent-types.d.ts +0 -1
- package/dist/src/functions/wirings/ai-agent/pikku-command-ai-agent.d.ts +0 -1
- package/dist/src/functions/wirings/ai-agent/serialize-ai-agent-types.d.ts +0 -1
- package/dist/src/functions/wirings/ai-scorer/pikku-command-ai-scorer.d.ts +0 -1
- /package/dist/.pikku/schemas/schemas/{PikkuAIAgentOutput.schema.json → PikkuAgentOutput.schema.json} +0 -0
- /package/dist/.pikku/schemas/schemas/{PikkuAIScorerOutput.schema.json → PikkuAgentScorerOutput.schema.json} +0 -0
- /package/dist/src/functions/wirings/{ai-agent → agent}/pikku-command-public-agent.d.ts +0 -0
- /package/dist/src/functions/wirings/{ai-agent → agent}/pikku-command-public-agent.js +0 -0
- /package/dist/src/functions/wirings/{ai-agent → agent}/serialize-agent-map.js +0 -0
- /package/dist/src/functions/wirings/{ai-agent → agent}/serialize-model-aliases.d.ts +0 -0
- /package/dist/src/functions/wirings/{ai-agent → agent}/serialize-model-aliases.js +0 -0
- /package/dist/src/functions/wirings/{ai-agent → agent}/serialize-public-agent.d.ts +0 -0
- /package/dist/src/functions/wirings/{ai-scorer → agent-scorer}/serialize-scorer-names.js +0 -0
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join, relative, resolve, sep } from 'node:path';
|
|
3
|
+
import { spawnSync } from 'node:child_process';
|
|
4
|
+
import { glob } from 'tinyglobby';
|
|
5
|
+
import semver from 'semver';
|
|
6
|
+
import { pikkuSessionlessFunc } from '#pikku';
|
|
7
|
+
const DEPENDENCY_FIELDS = [
|
|
8
|
+
'dependencies',
|
|
9
|
+
'devDependencies',
|
|
10
|
+
'peerDependencies',
|
|
11
|
+
'optionalDependencies',
|
|
12
|
+
];
|
|
13
|
+
const LOCKFILES = [
|
|
14
|
+
['bun.lock', 'bun'],
|
|
15
|
+
['bun.lockb', 'bun'],
|
|
16
|
+
['pnpm-lock.yaml', 'pnpm'],
|
|
17
|
+
['yarn.lock', 'yarn'],
|
|
18
|
+
['package-lock.json', 'npm'],
|
|
19
|
+
];
|
|
20
|
+
/**
|
|
21
|
+
* Ranges we can rewrite without changing what the range *means*: a caret, a
|
|
22
|
+
* tilde, a `>=` floor, or an exact pin. Anything else — a union, an x-range, a
|
|
23
|
+
* `workspace:`/`file:` protocol — is reported and left alone, because moving
|
|
24
|
+
* its floor is a judgement call rather than a substitution.
|
|
25
|
+
*/
|
|
26
|
+
const SIMPLE_RANGE = /^(\^|~|>=|)(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?)$/;
|
|
27
|
+
/**
|
|
28
|
+
* A range that resolves to a checkout on disk rather than to the registry. The
|
|
29
|
+
* project is deliberately on a local copy, so there is nothing to update and
|
|
30
|
+
* nothing for the user to decide — it is reported apart from the ranges we
|
|
31
|
+
* genuinely cannot rewrite.
|
|
32
|
+
*/
|
|
33
|
+
const LINK_PROTOCOL = /^(workspace|file|link|portal):/;
|
|
34
|
+
/** The range `--update` writes for `latest`, or null when the range is not ours to move. */
|
|
35
|
+
export const rewriteRange = (range, latest) => {
|
|
36
|
+
const match = SIMPLE_RANGE.exec(range.trim());
|
|
37
|
+
if (!match) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
return `${match[1]}${latest}`;
|
|
41
|
+
};
|
|
42
|
+
/** The lowest version a range admits — what the project is pinned *at least* to. */
|
|
43
|
+
const floorOf = (range) => {
|
|
44
|
+
try {
|
|
45
|
+
return semver.minVersion(range)?.version ?? null;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
export const findProjectRoot = (startDir, exists = existsSync) => {
|
|
52
|
+
let dir = resolve(startDir);
|
|
53
|
+
for (let i = 0; i < 12; i++) {
|
|
54
|
+
if (exists(join(dir, 'package.json'))) {
|
|
55
|
+
return dir;
|
|
56
|
+
}
|
|
57
|
+
const parent = dirname(dir);
|
|
58
|
+
if (parent === dir) {
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
dir = parent;
|
|
62
|
+
}
|
|
63
|
+
return resolve(startDir);
|
|
64
|
+
};
|
|
65
|
+
const readJson = (path) => {
|
|
66
|
+
try {
|
|
67
|
+
return JSON.parse(readFileSync(path, 'utf-8'));
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
const KNOWN_MANAGERS = ['bun', 'yarn', 'pnpm', 'npm'];
|
|
74
|
+
/**
|
|
75
|
+
* Where `install` has to run: the nearest directory at or above the project
|
|
76
|
+
* root that says which package manager owns the tree. In a monorepo that is the
|
|
77
|
+
* workspace root, not the package the command was invoked in.
|
|
78
|
+
*
|
|
79
|
+
* The corepack `packageManager` field wins over lockfiles — it states intent
|
|
80
|
+
* before a lockfile exists, and a project can carry a stale one from another
|
|
81
|
+
* tool. Guessing wrong is not a soft failure: the install spawns a binary that
|
|
82
|
+
* isn't on PATH.
|
|
83
|
+
*/
|
|
84
|
+
export const findInstallRoot = (root, exists = existsSync, read = readJson) => {
|
|
85
|
+
let dir = resolve(root);
|
|
86
|
+
for (let i = 0; i < 12; i++) {
|
|
87
|
+
const declared = read(join(dir, 'package.json'))?.packageManager;
|
|
88
|
+
const name = typeof declared === 'string' ? declared.split('@')[0] : null;
|
|
89
|
+
if (name && KNOWN_MANAGERS.includes(name)) {
|
|
90
|
+
return { dir, packageManager: name };
|
|
91
|
+
}
|
|
92
|
+
for (const [file, pm] of LOCKFILES) {
|
|
93
|
+
if (exists(join(dir, file))) {
|
|
94
|
+
return { dir, packageManager: pm };
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const parent = dirname(dir);
|
|
98
|
+
if (parent === dir) {
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
dir = parent;
|
|
102
|
+
}
|
|
103
|
+
return { dir: resolve(root), packageManager: 'unknown' };
|
|
104
|
+
};
|
|
105
|
+
const workspacePatterns = (manifest) => {
|
|
106
|
+
const workspaces = manifest?.workspaces;
|
|
107
|
+
if (Array.isArray(workspaces)) {
|
|
108
|
+
return workspaces;
|
|
109
|
+
}
|
|
110
|
+
if (Array.isArray(workspaces?.packages)) {
|
|
111
|
+
return workspaces.packages;
|
|
112
|
+
}
|
|
113
|
+
return [];
|
|
114
|
+
};
|
|
115
|
+
/** Every package.json the run covers: the project root, plus its workspaces. */
|
|
116
|
+
export const collectManifestPaths = async (root) => {
|
|
117
|
+
const rootManifest = join(root, 'package.json');
|
|
118
|
+
const paths = existsSync(rootManifest) ? [rootManifest] : [];
|
|
119
|
+
const patterns = workspacePatterns(readJson(rootManifest));
|
|
120
|
+
if (patterns.length === 0) {
|
|
121
|
+
return paths;
|
|
122
|
+
}
|
|
123
|
+
const matches = await glob(patterns.map((pattern) => `${pattern.replace(/\/$/, '')}/package.json`), { cwd: root, absolute: true, ignore: ['**/node_modules/**'] });
|
|
124
|
+
for (const match of matches.sort()) {
|
|
125
|
+
if (!paths.includes(match)) {
|
|
126
|
+
paths.push(match);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return paths;
|
|
130
|
+
};
|
|
131
|
+
/** Version resolved in node_modules, walking up from the manifest's own directory. */
|
|
132
|
+
export const resolveInstalled = (manifestDir, name, read = readJson) => {
|
|
133
|
+
let dir = resolve(manifestDir);
|
|
134
|
+
for (let i = 0; i < 12; i++) {
|
|
135
|
+
const candidate = read(join(dir, 'node_modules', ...name.split('/'), 'package.json'));
|
|
136
|
+
if (candidate?.version) {
|
|
137
|
+
return String(candidate.version);
|
|
138
|
+
}
|
|
139
|
+
const parent = dirname(dir);
|
|
140
|
+
if (parent === dir) {
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
dir = parent;
|
|
144
|
+
}
|
|
145
|
+
return null;
|
|
146
|
+
};
|
|
147
|
+
const isPikkuPackage = (name) => name.startsWith('@pikku/');
|
|
148
|
+
const defaultFetchPackument = (registry) => async (name) => {
|
|
149
|
+
try {
|
|
150
|
+
const response = await fetch(`${registry.replace(/\/$/, '')}/${name}`, {
|
|
151
|
+
headers: { accept: 'application/vnd.npm.install-v1+json' },
|
|
152
|
+
});
|
|
153
|
+
if (!response.ok) {
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
return (await response.json());
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
/**
|
|
163
|
+
* Rewrite a manifest's ranges in place, keeping the file's own indentation and
|
|
164
|
+
* key order — a package.json is hand-edited far more often than it is
|
|
165
|
+
* generated, so a version bump must not reformat it.
|
|
166
|
+
*/
|
|
167
|
+
const writeManifest = (path, edits) => {
|
|
168
|
+
const raw = readFileSync(path, 'utf-8');
|
|
169
|
+
const json = JSON.parse(raw);
|
|
170
|
+
for (const edit of edits) {
|
|
171
|
+
if (json[edit.field]?.[edit.package] !== undefined) {
|
|
172
|
+
json[edit.field][edit.package] = edit.range;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
const indentMatch = raw.match(/\n(\s+)"/);
|
|
176
|
+
const indent = indentMatch ? indentMatch[1] : ' ';
|
|
177
|
+
const trailing = raw.endsWith('\n') ? '\n' : '';
|
|
178
|
+
writeFileSync(path, `${JSON.stringify(json, null, indent)}${trailing}`, 'utf-8');
|
|
179
|
+
};
|
|
180
|
+
export const runUpdate = async ({ rootDir, apply, updatePeers, install, tag, registry, fetchPackument, }) => {
|
|
181
|
+
const root = findProjectRoot(rootDir);
|
|
182
|
+
const { dir: installDir, packageManager } = findInstallRoot(root);
|
|
183
|
+
const fetchOne = fetchPackument ?? defaultFetchPackument(registry);
|
|
184
|
+
const manifests = [];
|
|
185
|
+
for (const path of await collectManifestPaths(root)) {
|
|
186
|
+
const json = readJson(path);
|
|
187
|
+
if (json) {
|
|
188
|
+
manifests.push({
|
|
189
|
+
path,
|
|
190
|
+
relative: relative(root, path).split(sep).join('/') || 'package.json',
|
|
191
|
+
dir: dirname(path),
|
|
192
|
+
json,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
const names = new Set();
|
|
197
|
+
for (const manifest of manifests) {
|
|
198
|
+
for (const field of DEPENDENCY_FIELDS) {
|
|
199
|
+
for (const name of Object.keys(manifest.json[field] ?? {})) {
|
|
200
|
+
if (isPikkuPackage(name)) {
|
|
201
|
+
names.add(name);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
const packuments = new Map();
|
|
207
|
+
await Promise.all([...names].map(async (name) => {
|
|
208
|
+
packuments.set(name, await fetchOne(name));
|
|
209
|
+
}));
|
|
210
|
+
const entries = [];
|
|
211
|
+
for (const manifest of manifests) {
|
|
212
|
+
for (const field of DEPENDENCY_FIELDS) {
|
|
213
|
+
const deps = manifest.json[field] ?? {};
|
|
214
|
+
for (const [name, range] of Object.entries(deps)) {
|
|
215
|
+
if (!isPikkuPackage(name)) {
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
const installedVersion = resolveInstalled(manifest.dir, name);
|
|
219
|
+
const latest = packuments.get(name)?.['dist-tags']?.[tag] ?? null;
|
|
220
|
+
const entry = {
|
|
221
|
+
package: name,
|
|
222
|
+
manifest: manifest.relative,
|
|
223
|
+
field,
|
|
224
|
+
range,
|
|
225
|
+
installed: installedVersion,
|
|
226
|
+
latest,
|
|
227
|
+
target: null,
|
|
228
|
+
status: 'current',
|
|
229
|
+
};
|
|
230
|
+
if (LINK_PROTOCOL.test(range.trim())) {
|
|
231
|
+
entry.status = 'linked';
|
|
232
|
+
}
|
|
233
|
+
else if (!latest) {
|
|
234
|
+
entry.status = 'unresolved';
|
|
235
|
+
entry.reason = `no '${tag}' release found on ${registry}`;
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
const rewritten = rewriteRange(range, latest);
|
|
239
|
+
if (rewritten === null) {
|
|
240
|
+
entry.status = 'manual';
|
|
241
|
+
entry.reason = `'${range}' is not a plain caret, tilde, >= or exact range`;
|
|
242
|
+
}
|
|
243
|
+
else if (rewritten !== range) {
|
|
244
|
+
entry.status = 'outdated';
|
|
245
|
+
entry.target = rewritten;
|
|
246
|
+
}
|
|
247
|
+
else if (installedVersion && semver.lt(installedVersion, latest)) {
|
|
248
|
+
entry.status = 'stale-install';
|
|
249
|
+
entry.reason = 'the range already allows it — run an install';
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
entries.push(entry);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Peers are read off the version the run lands on, not the one installed —
|
|
258
|
+
* the point is what the *target* needs. So resolve every @pikku package to
|
|
259
|
+
* its post-update version first, then read that version's peers.
|
|
260
|
+
*/
|
|
261
|
+
const targetVersion = (entry) => entry.status === 'outdated' || entry.status === 'stale-install'
|
|
262
|
+
? entry.latest
|
|
263
|
+
: (entry.installed ?? floorOf(entry.range));
|
|
264
|
+
const pikkuTargets = new Map();
|
|
265
|
+
for (const entry of entries) {
|
|
266
|
+
const version = targetVersion(entry);
|
|
267
|
+
if (version && semver.valid(version)) {
|
|
268
|
+
const existing = pikkuTargets.get(entry.package);
|
|
269
|
+
if (!existing || semver.gt(version, existing)) {
|
|
270
|
+
pikkuTargets.set(entry.package, version);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
const peers = [];
|
|
275
|
+
for (const manifest of manifests) {
|
|
276
|
+
const declared = new Map();
|
|
277
|
+
for (const field of DEPENDENCY_FIELDS) {
|
|
278
|
+
for (const [name, range] of Object.entries(manifest.json[field] ?? {})) {
|
|
279
|
+
if (!declared.has(name)) {
|
|
280
|
+
declared.set(name, { field, range });
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
for (const [name] of declared) {
|
|
285
|
+
if (!isPikkuPackage(name)) {
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
const version = pikkuTargets.get(name);
|
|
289
|
+
const versionMeta = version
|
|
290
|
+
? packuments.get(name)?.versions?.[version]
|
|
291
|
+
: undefined;
|
|
292
|
+
for (const [peer, required] of Object.entries(versionMeta?.peerDependencies ?? {})) {
|
|
293
|
+
const optional = versionMeta?.peerDependenciesMeta?.[peer]?.optional === true;
|
|
294
|
+
const found = declared.get(peer)?.range ?? null;
|
|
295
|
+
const resolved = pikkuTargets.get(peer) ??
|
|
296
|
+
resolveInstalled(manifest.dir, peer) ??
|
|
297
|
+
(found ? floorOf(found) : null);
|
|
298
|
+
if (resolved &&
|
|
299
|
+
semver.satisfies(resolved, required, { includePrerelease: true })) {
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
if (!found && optional) {
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
peers.push({
|
|
306
|
+
package: name,
|
|
307
|
+
peer,
|
|
308
|
+
required,
|
|
309
|
+
found,
|
|
310
|
+
resolved,
|
|
311
|
+
manifest: manifest.relative,
|
|
312
|
+
optional,
|
|
313
|
+
target: required,
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
const written = [];
|
|
319
|
+
if (apply) {
|
|
320
|
+
for (const manifest of manifests) {
|
|
321
|
+
const edits = entries
|
|
322
|
+
.filter((entry) => entry.manifest === manifest.relative && entry.target)
|
|
323
|
+
.map((entry) => ({
|
|
324
|
+
field: entry.field,
|
|
325
|
+
package: entry.package,
|
|
326
|
+
range: entry.target,
|
|
327
|
+
}));
|
|
328
|
+
if (updatePeers) {
|
|
329
|
+
for (const peer of peers) {
|
|
330
|
+
if (peer.manifest !== manifest.relative || !peer.found) {
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
const field = DEPENDENCY_FIELDS.find((candidate) => manifest.json[candidate]?.[peer.peer] !== undefined);
|
|
334
|
+
if (field) {
|
|
335
|
+
edits.push({ field, package: peer.peer, range: peer.target });
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
if (edits.length > 0) {
|
|
340
|
+
writeManifest(manifest.path, edits);
|
|
341
|
+
written.push(manifest.relative);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
let ranInstall = false;
|
|
346
|
+
if (apply && install && written.length > 0 && packageManager !== 'unknown') {
|
|
347
|
+
const result = spawnSync(packageManager, ['install'], {
|
|
348
|
+
cwd: installDir,
|
|
349
|
+
stdio: 'inherit',
|
|
350
|
+
});
|
|
351
|
+
if (result.error || result.status !== 0) {
|
|
352
|
+
throw new Error(`${packageManager} install failed: ${result.error?.message ?? `exit ${result.status}`}`);
|
|
353
|
+
}
|
|
354
|
+
ranInstall = true;
|
|
355
|
+
}
|
|
356
|
+
const count = (status) => entries.filter((entry) => entry.status === status).length;
|
|
357
|
+
return {
|
|
358
|
+
root,
|
|
359
|
+
registry,
|
|
360
|
+
tag,
|
|
361
|
+
packageManager,
|
|
362
|
+
entries,
|
|
363
|
+
peers,
|
|
364
|
+
applied: apply,
|
|
365
|
+
written,
|
|
366
|
+
installed: ranInstall,
|
|
367
|
+
summary: {
|
|
368
|
+
checked: entries.length,
|
|
369
|
+
outdated: count('outdated'),
|
|
370
|
+
staleInstall: count('stale-install'),
|
|
371
|
+
linked: count('linked'),
|
|
372
|
+
manual: count('manual'),
|
|
373
|
+
unresolved: count('unresolved'),
|
|
374
|
+
peerIssues: peers.length,
|
|
375
|
+
},
|
|
376
|
+
};
|
|
377
|
+
};
|
|
378
|
+
export const pikkuUpdate = pikkuSessionlessFunc({
|
|
379
|
+
func: async ({ config }, input) => {
|
|
380
|
+
const updatePeers = input?.updatePeers === true;
|
|
381
|
+
return runUpdate({
|
|
382
|
+
rootDir: config.rootDir,
|
|
383
|
+
apply: input?.update === true || updatePeers,
|
|
384
|
+
updatePeers,
|
|
385
|
+
install: input?.install !== false,
|
|
386
|
+
tag: input?.tag || 'latest',
|
|
387
|
+
registry: input?.registry ||
|
|
388
|
+
process.env.npm_config_registry ||
|
|
389
|
+
'https://registry.npmjs.org',
|
|
390
|
+
});
|
|
391
|
+
},
|
|
392
|
+
});
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* reporter is: a second formatter (JSON for fabric, JUnit for CI) is then one
|
|
11
11
|
* function rather than an unpicking of the runner.
|
|
12
12
|
*/
|
|
13
|
-
import type { VirtualUserRunResult } from '@pikku/core/virtual-user';
|
|
13
|
+
import type { VirtualUserRunResult } from '@pikku/core/ecosystem/virtual-user';
|
|
14
14
|
export interface VirtualUserReportContext {
|
|
15
15
|
persona: string;
|
|
16
16
|
disposition: string;
|
|
@@ -44,7 +44,7 @@ const VIRTUAL_USER_FILE = /\.(virtual-user|vu)\.tsx?$/;
|
|
|
44
44
|
* are edited for opposite reasons, and a rubric buried in an agent definition
|
|
45
45
|
* is one nobody reviews as a rubric.
|
|
46
46
|
*/
|
|
47
|
-
const SCORER_DECLARATIONS = ['
|
|
47
|
+
const SCORER_DECLARATIONS = ['pikkuAgentScorer', 'pikkuAgentJudge'];
|
|
48
48
|
const SCORER_FILE = /\.scorers?\.tsx?$/;
|
|
49
49
|
const isGenerated = (path) => path.includes('.gen.') || path.includes(`${'/'}.pikku${'/'}`);
|
|
50
50
|
const listSourceFiles = async (dir) => {
|
|
@@ -4,6 +4,7 @@ import { join, relative } from 'node:path';
|
|
|
4
4
|
import { isAddonPackage, runAddonPackageChecks, } from './addon-package-checks.js';
|
|
5
5
|
import { runSharedProjectChecks } from './shared-checks.js';
|
|
6
6
|
import { runTypeIdentityChecks } from './type-identity-checks.js';
|
|
7
|
+
import { runWorkspaceExportsChecks } from './workspace-exports-checks.js';
|
|
7
8
|
/** A hand-written `types/application-types.d.ts` beside package.json. */
|
|
8
9
|
const ADDON_MARKER = join('types', 'application-types.d.ts');
|
|
9
10
|
const SKIP_DIRS = new Set([
|
|
@@ -79,6 +80,15 @@ export const CHECKS = [
|
|
|
79
80
|
applies: async ({ dir, label }) => label === '.' && existsSync(join(dir, 'node_modules')),
|
|
80
81
|
run: async ({ dir }) => runTypeIdentityChecks(dir),
|
|
81
82
|
},
|
|
83
|
+
{
|
|
84
|
+
id: 'workspace-exports',
|
|
85
|
+
subject: 'workspace subpath imports',
|
|
86
|
+
// Root only: the check pairs an import in one package with the exports map
|
|
87
|
+
// of another, so it needs the whole tree in view. Per-package it would see
|
|
88
|
+
// the consumer without the producer and report nothing.
|
|
89
|
+
applies: async ({ label }) => label === '.',
|
|
90
|
+
run: async ({ dir }) => runWorkspaceExportsChecks(dir),
|
|
91
|
+
},
|
|
82
92
|
];
|
|
83
93
|
export async function planValidation(root) {
|
|
84
94
|
const plan = [];
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ValidateFinding } from './persona-checks.js';
|
|
2
|
+
/**
|
|
3
|
+
* Every workspace-internal subpath import must resolve through the owning
|
|
4
|
+
* package's own `exports`.
|
|
5
|
+
*
|
|
6
|
+
* `exports` does not probe extensions the way a bundler alias does, so a map
|
|
7
|
+
* like `"./pikku/*": "./src/pikku/*"` resolves `pkg/pikku/client.gen` to a file
|
|
8
|
+
* called `client.gen` that was never written — the real file is `client.gen.ts`.
|
|
9
|
+
* Nothing catches it while a `resolve.alias` in the consumer's own vite config
|
|
10
|
+
* covers the same specifier: the alias wins locally, and the broken map only
|
|
11
|
+
* surfaces where that config is not in play (a sandbox scaffold config, a
|
|
12
|
+
* different bundler, plain node, another app in the same repo).
|
|
13
|
+
*/
|
|
14
|
+
export declare function runWorkspaceExportsChecks(root: string): Promise<ValidateFinding[]>;
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { readdir, readFile } from 'node:fs/promises';
|
|
3
|
+
import { join, relative } from 'node:path';
|
|
4
|
+
import { readJsonSafe } from './shared-checks.js';
|
|
5
|
+
const SKIP_DIRS = new Set([
|
|
6
|
+
'node_modules',
|
|
7
|
+
'.git',
|
|
8
|
+
'dist',
|
|
9
|
+
'build',
|
|
10
|
+
'.pikku',
|
|
11
|
+
'.pikku-runtime',
|
|
12
|
+
'coverage',
|
|
13
|
+
'.next',
|
|
14
|
+
'.yarn',
|
|
15
|
+
]);
|
|
16
|
+
const SOURCE_EXTENSIONS = new Set([
|
|
17
|
+
'.ts',
|
|
18
|
+
'.tsx',
|
|
19
|
+
'.mts',
|
|
20
|
+
'.cts',
|
|
21
|
+
'.js',
|
|
22
|
+
'.jsx',
|
|
23
|
+
'.mjs',
|
|
24
|
+
'.cjs',
|
|
25
|
+
]);
|
|
26
|
+
const IMPORT_PATTERN = /(?:import|export)\s[^'"]*?from\s*['"]([^'"]+)['"]|import\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
27
|
+
/**
|
|
28
|
+
* Every target a single `exports` value can resolve to, in the order Node tries
|
|
29
|
+
* them. Conditions collapse to their targets because a subpath that only
|
|
30
|
+
* resolves under one condition still has to resolve under that condition.
|
|
31
|
+
*/
|
|
32
|
+
function targetsOf(value) {
|
|
33
|
+
if (typeof value === 'string')
|
|
34
|
+
return [value];
|
|
35
|
+
if (Array.isArray(value))
|
|
36
|
+
return value.flatMap(targetsOf);
|
|
37
|
+
if (value && typeof value === 'object') {
|
|
38
|
+
return Object.values(value).flatMap(targetsOf);
|
|
39
|
+
}
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Node picks the pattern with the longest literal prefix, then the longest
|
|
44
|
+
* suffix — so `./pikku/*.js` wins over `./pikku/*` for a `.js` specifier.
|
|
45
|
+
*/
|
|
46
|
+
function patternRank(key) {
|
|
47
|
+
const star = key.indexOf('*');
|
|
48
|
+
if (star === -1)
|
|
49
|
+
return [key.length, 0];
|
|
50
|
+
return [star, key.length - star - 1];
|
|
51
|
+
}
|
|
52
|
+
function matchSubpath(exportsField, subpath) {
|
|
53
|
+
if (!exportsField || typeof exportsField !== 'object')
|
|
54
|
+
return null;
|
|
55
|
+
const entries = Object.entries(exportsField);
|
|
56
|
+
if (!entries.some(([key]) => key.startsWith('.')))
|
|
57
|
+
return null;
|
|
58
|
+
const exact = entries.find(([key]) => key === subpath);
|
|
59
|
+
if (exact)
|
|
60
|
+
return { targets: targetsOf(exact[1]), key: exact[0] };
|
|
61
|
+
const candidates = entries
|
|
62
|
+
.filter(([key]) => key.includes('*'))
|
|
63
|
+
.map(([key, value]) => {
|
|
64
|
+
const star = key.indexOf('*');
|
|
65
|
+
const prefix = key.slice(0, star);
|
|
66
|
+
const suffix = key.slice(star + 1);
|
|
67
|
+
if (!subpath.startsWith(prefix) || !subpath.endsWith(suffix))
|
|
68
|
+
return null;
|
|
69
|
+
if (subpath.length < prefix.length + suffix.length)
|
|
70
|
+
return null;
|
|
71
|
+
const wildcard = subpath.slice(prefix.length, subpath.length - suffix.length);
|
|
72
|
+
return { key, value, wildcard };
|
|
73
|
+
})
|
|
74
|
+
.filter((c) => c !== null)
|
|
75
|
+
.sort((a, b) => {
|
|
76
|
+
const [ap, as] = patternRank(a.key);
|
|
77
|
+
const [bp, bs] = patternRank(b.key);
|
|
78
|
+
return bp - ap || bs - as;
|
|
79
|
+
});
|
|
80
|
+
const best = candidates[0];
|
|
81
|
+
if (!best)
|
|
82
|
+
return null;
|
|
83
|
+
return {
|
|
84
|
+
targets: targetsOf(best.value).map((t) => t.replaceAll('*', best.wildcard)),
|
|
85
|
+
key: best.key,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
async function collectWorkspacePackages(root, maxDepth = 5) {
|
|
89
|
+
const packages = new Map();
|
|
90
|
+
const visit = async (dir, depth) => {
|
|
91
|
+
const pkg = await readJsonSafe(join(dir, 'package.json'));
|
|
92
|
+
if (pkg?.name) {
|
|
93
|
+
packages.set(pkg.name, { name: pkg.name, dir, exports: pkg.exports });
|
|
94
|
+
}
|
|
95
|
+
if (depth >= maxDepth)
|
|
96
|
+
return;
|
|
97
|
+
const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
98
|
+
for (const entry of entries) {
|
|
99
|
+
if (!entry.isDirectory())
|
|
100
|
+
continue;
|
|
101
|
+
if (entry.name.startsWith('.') || SKIP_DIRS.has(entry.name))
|
|
102
|
+
continue;
|
|
103
|
+
await visit(join(dir, entry.name), depth + 1);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
await visit(root, 0);
|
|
107
|
+
return packages;
|
|
108
|
+
}
|
|
109
|
+
async function* sourceFiles(dir, depth = 0) {
|
|
110
|
+
if (depth > 8)
|
|
111
|
+
return;
|
|
112
|
+
const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
113
|
+
for (const entry of entries) {
|
|
114
|
+
const full = join(dir, entry.name);
|
|
115
|
+
if (entry.isDirectory()) {
|
|
116
|
+
if (entry.name.startsWith('.') || SKIP_DIRS.has(entry.name))
|
|
117
|
+
continue;
|
|
118
|
+
yield* sourceFiles(full, depth + 1);
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
if (!entry.isFile())
|
|
122
|
+
continue;
|
|
123
|
+
const dot = entry.name.lastIndexOf('.');
|
|
124
|
+
if (dot === -1)
|
|
125
|
+
continue;
|
|
126
|
+
if (entry.name.includes('.gen.'))
|
|
127
|
+
continue;
|
|
128
|
+
if (!SOURCE_EXTENSIONS.has(entry.name.slice(dot)))
|
|
129
|
+
continue;
|
|
130
|
+
yield full;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function splitSpecifier(specifier, packages) {
|
|
134
|
+
if (specifier.startsWith('.') || specifier.startsWith('/'))
|
|
135
|
+
return null;
|
|
136
|
+
const parts = specifier.split('/');
|
|
137
|
+
const name = specifier.startsWith('@')
|
|
138
|
+
? parts.slice(0, 2).join('/')
|
|
139
|
+
: parts[0];
|
|
140
|
+
const pkg = packages.get(name);
|
|
141
|
+
if (!pkg)
|
|
142
|
+
return null;
|
|
143
|
+
const rest = specifier.slice(name.length);
|
|
144
|
+
if (rest === '')
|
|
145
|
+
return null;
|
|
146
|
+
return { pkg, subpath: `.${rest}` };
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Every workspace-internal subpath import must resolve through the owning
|
|
150
|
+
* package's own `exports`.
|
|
151
|
+
*
|
|
152
|
+
* `exports` does not probe extensions the way a bundler alias does, so a map
|
|
153
|
+
* like `"./pikku/*": "./src/pikku/*"` resolves `pkg/pikku/client.gen` to a file
|
|
154
|
+
* called `client.gen` that was never written — the real file is `client.gen.ts`.
|
|
155
|
+
* Nothing catches it while a `resolve.alias` in the consumer's own vite config
|
|
156
|
+
* covers the same specifier: the alias wins locally, and the broken map only
|
|
157
|
+
* surfaces where that config is not in play (a sandbox scaffold config, a
|
|
158
|
+
* different bundler, plain node, another app in the same repo).
|
|
159
|
+
*/
|
|
160
|
+
export async function runWorkspaceExportsChecks(root) {
|
|
161
|
+
const packages = await collectWorkspacePackages(root);
|
|
162
|
+
if (packages.size === 0)
|
|
163
|
+
return [];
|
|
164
|
+
const findings = [];
|
|
165
|
+
const seen = new Set();
|
|
166
|
+
for await (const file of sourceFiles(root)) {
|
|
167
|
+
let source;
|
|
168
|
+
try {
|
|
169
|
+
source = await readFile(file, 'utf8');
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
if (!source.includes('from') && !source.includes('import('))
|
|
175
|
+
continue;
|
|
176
|
+
for (const match of source.matchAll(IMPORT_PATTERN)) {
|
|
177
|
+
const specifier = match[1] ?? match[2];
|
|
178
|
+
if (!specifier)
|
|
179
|
+
continue;
|
|
180
|
+
const split = splitSpecifier(specifier, packages);
|
|
181
|
+
if (!split)
|
|
182
|
+
continue;
|
|
183
|
+
const { pkg, subpath } = split;
|
|
184
|
+
if (!pkg.exports)
|
|
185
|
+
continue;
|
|
186
|
+
const resolved = matchSubpath(pkg.exports, subpath);
|
|
187
|
+
const targets = resolved?.targets ?? [];
|
|
188
|
+
if (targets.some((t) => existsSync(join(pkg.dir, t))))
|
|
189
|
+
continue;
|
|
190
|
+
const key = `${pkg.name}${subpath.slice(1)}`;
|
|
191
|
+
if (seen.has(key))
|
|
192
|
+
continue;
|
|
193
|
+
seen.add(key);
|
|
194
|
+
findings.push({
|
|
195
|
+
id: 'workspace-subpath-not-exported',
|
|
196
|
+
severity: 'error',
|
|
197
|
+
message: resolved
|
|
198
|
+
? `"${specifier}" matches "${resolved.key}" in ${pkg.name}'s exports, but every target it maps to is missing: ${targets.join(', ')}.`
|
|
199
|
+
: `"${specifier}" is not covered by any subpath in ${pkg.name}'s exports.`,
|
|
200
|
+
path: relative(root, file) || file,
|
|
201
|
+
fixHint: [
|
|
202
|
+
`Make ${pkg.name} resolvable on its own — exports does not add file extensions,`,
|
|
203
|
+
`so a target must name a file that exists (e.g. "./src/pikku/*.ts", or a`,
|
|
204
|
+
`fallback array ["./src/pikku/*.ts", "./src/pikku/*.d.ts"]).`,
|
|
205
|
+
`A resolve.alias in one consumer hides this everywhere else.`,
|
|
206
|
+
].join('\n'),
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return findings;
|
|
211
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const pikkuAgentTypes: 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>;
|
|
@@ -2,15 +2,15 @@ import { pikkuSessionlessFunc } from '#pikku';
|
|
|
2
2
|
import { writeFileInDir } from '../../../utils/file-writer.js';
|
|
3
3
|
import { getFileImportRelativePath } from '../../../utils/file-import-path.js';
|
|
4
4
|
import { logCommandInfoAndTime } from '../../../middleware/log-command-info-and-time.js';
|
|
5
|
-
import {
|
|
6
|
-
export const
|
|
5
|
+
import { serializeAgentTypes } from './serialize-agent-types.js';
|
|
6
|
+
export const pikkuAgentTypes = pikkuSessionlessFunc({
|
|
7
7
|
func: async ({ logger, config }) => {
|
|
8
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
12
|
const scorerNamesImportPath = getFileImportRelativePath(agentTypesFile, scorerNamesDeclarationFile, packageMappings);
|
|
13
|
-
const content =
|
|
13
|
+
const content = serializeAgentTypes(functionTypesImportPath, agentMapImportPath, scopesImportPath, scorerNamesImportPath);
|
|
14
14
|
await writeFileInDir(logger, agentTypesFile, content);
|
|
15
15
|
},
|
|
16
16
|
middleware: [
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const pikkuAgent: import("#pikku").PikkuFunctionConfig<void, boolean | undefined, "rpc" | "session", import("#pikku").PikkuFunctionSessionless<void, boolean | undefined, "rpc" | "session", import("#pikku").WiredServices, unknown> | import("#pikku").PikkuFunction<void, boolean | undefined, "rpc" | "session", import("#pikku").WiredServices>, undefined, undefined>;
|