@pikku/cli 0.12.156 → 0.12.160
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/{HelpPanel-DaE02BQE.js → HelpPanel-C06T226y.js} +1 -1
- package/console-app/assets/{abnfDiagram-VCTEODGH-CExRuljg.js → abnfDiagram-VCTEODGH-BVwdT3Es.js} +1 -1
- package/console-app/assets/architecture-7GRP2DOG-3y7bWtag.js +1 -0
- package/console-app/assets/{architectureDiagram-5GKGNRK7-uKjmdPIQ.js → architectureDiagram-5GKGNRK7-XfzqZ3mW.js} +1 -1
- package/console-app/assets/{blockDiagram-I7D4REHJ-DNgIFbT4.js → blockDiagram-I7D4REHJ-B5omSqDK.js} +1 -1
- package/console-app/assets/{c4Diagram-7LVT6UL2-0vP9sLld.js → c4Diagram-7LVT6UL2-DkPe7xCg.js} +1 -1
- package/console-app/assets/channel-CTiluQVw.js +1 -0
- package/console-app/assets/{chunk-4HAMMTFA-BJ59eqJI.js → chunk-4HAMMTFA-QfSXT_X7.js} +1 -1
- package/console-app/assets/{chunk-75Z2AOVW-Bge6xoqX.js → chunk-75Z2AOVW-h7UnPWNo.js} +1 -1
- package/console-app/assets/{chunk-DU6HZSFF-CkmYNhC5.js → chunk-DU6HZSFF-VaMy-LOI.js} +1 -1
- package/console-app/assets/{chunk-F27PBJKO-C44ef28t.js → chunk-F27PBJKO-toywqOqS.js} +1 -1
- package/console-app/assets/{chunk-GMAD6QVW-Bmqdx1l0.js → chunk-GMAD6QVW-Cpa-YKLB.js} +1 -1
- package/console-app/assets/{chunk-GVQU2GXP-AQp_KNx4.js → chunk-GVQU2GXP-BWSHPLNL.js} +1 -1
- package/console-app/assets/{chunk-IMKFNOWR-Ca3GoHnO.js → chunk-IMKFNOWR-yhQzfQuj.js} +1 -1
- package/console-app/assets/{chunk-L3NEJ4N5-C_GhayZt.js → chunk-L3NEJ4N5-C8pAfDlo.js} +1 -1
- package/console-app/assets/{chunk-OSK3NFVY-DGzfF4JV.js → chunk-OSK3NFVY-749yk2fa.js} +1 -1
- package/console-app/assets/{chunk-P2QGCYS3-N8xMDiFw.js → chunk-P2QGCYS3-C1Y9GyYT.js} +1 -1
- package/console-app/assets/{chunk-POPQ4Y6H-CdhIikwj.js → chunk-POPQ4Y6H-DzI9aRsX.js} +1 -1
- package/console-app/assets/{chunk-PWAF6VOD-CdTJmOYg.js → chunk-PWAF6VOD-D3fAPSwz.js} +1 -1
- package/console-app/assets/{chunk-SHT3W25Y-Ctj8zSAF.js → chunk-SHT3W25Y-D9w7LzM9.js} +1 -1
- package/console-app/assets/{chunk-SVP7TREG-DTNKveWo.js → chunk-SVP7TREG-D55MjOJw.js} +1 -1
- package/console-app/assets/{chunk-TICWLB2K-Df6e0LIf.js → chunk-TICWLB2K-DV8q7H-z.js} +1 -1
- package/console-app/assets/chunk-XXDRQBXY-DBtYQykd.js +1 -0
- package/console-app/assets/classDiagram-ZZMXUADV-BnWa-i9n.js +1 -0
- package/console-app/assets/classDiagram-v2-VYDZK3BY-BnWa-i9n.js +1 -0
- package/console-app/assets/{cose-bilkent-JH36ORCC-DBd_emhQ.js → cose-bilkent-JH36ORCC-CLedPW9a.js} +1 -1
- package/console-app/assets/{cynefin-OW5HDTMX-3aBVpBMI.js → cynefin-OW5HDTMX-CS5NKw2p.js} +1 -1
- package/console-app/assets/{cynefinDiagram-5FMLGOSQ-5BZzBehJ.js → cynefinDiagram-5FMLGOSQ-DGTHW90E.js} +1 -1
- package/console-app/assets/{dagre-DATELzSq.js → dagre-BNQdos_2.js} +1 -1
- package/console-app/assets/{dagre-GXQ25YYZ-orKIUXIt.js → dagre-GXQ25YYZ-DHZ8wtwQ.js} +1 -1
- package/console-app/assets/{diagram-S7CK7UJ4-CwwxVQ_N.js → diagram-S7CK7UJ4-C41Begsy.js} +1 -1
- package/console-app/assets/{diagram-UQ7AKVKN-CcEJxIEU.js → diagram-UQ7AKVKN-CU8D-sRT.js} +1 -1
- package/console-app/assets/{diagram-VSXAHHWV-DGfXNB6v.js → diagram-VSXAHHWV-DTTiXYnQ.js} +1 -1
- package/console-app/assets/{diagram-VX7I27RA-Kqkord1q.js → diagram-VX7I27RA-BBy91pxm.js} +1 -1
- package/console-app/assets/{diagram-Z3DM3KII-Dy5rfOxu.js → diagram-Z3DM3KII-D50xTYe5.js} +1 -1
- package/console-app/assets/{ebnfDiagram-PWID7BFC-y1bmj1ry.js → ebnfDiagram-PWID7BFC-BHjnFZgE.js} +1 -1
- package/console-app/assets/{erDiagram-RLTQ6QDP-CNk_w5Ib.js → erDiagram-RLTQ6QDP-B4-yVo9b.js} +1 -1
- package/console-app/assets/eventmodeling-NTZA5JFV-C_IpFSCw.js +1 -0
- package/console-app/assets/flowDiagram-HODETNUW-Q90rgVpx.js +1 -0
- package/console-app/assets/{ganttDiagram-EL5Y4UJY-DdVaRGRy.js → ganttDiagram-EL5Y4UJY-D1T-2BlO.js} +1 -1
- package/console-app/assets/{gitGraph-4MIJSDKK-DpSAepQv.js → gitGraph-4MIJSDKK-ClqKTUfQ.js} +1 -1
- package/console-app/assets/{gitGraphDiagram-WWUBYQGX-CIhGnwZW.js → gitGraphDiagram-WWUBYQGX-ruq2MAhM.js} +1 -1
- package/console-app/assets/{graphlib-CRp93vEd.js → graphlib-D-vLYPdw.js} +1 -1
- package/console-app/assets/{index-B34OoL_f.js → index-BIEZPuyK.js} +5 -5
- package/console-app/assets/{info-A6RAGUB7-DckDPZ56.js → info-A6RAGUB7-BGI-8HNB.js} +1 -1
- package/console-app/assets/{infoDiagram-27XIBGKW-DMk6mpjP.js → infoDiagram-27XIBGKW-BGURgKHv.js} +1 -1
- package/console-app/assets/{ishikawaDiagram-5VMMS53U-Dqr5CEc9.js → ishikawaDiagram-5VMMS53U-DzgAaPTR.js} +1 -1
- package/console-app/assets/{journeyDiagram-3NMN7TZE-Kv0orI9j.js → journeyDiagram-3NMN7TZE-BsyWad8z.js} +1 -1
- package/console-app/assets/{kanban-definition-UXKFOSKX-BrYb0IpS.js → kanban-definition-UXKFOSKX-g1nO2rWF.js} +1 -1
- package/console-app/assets/{line-D2jQ449E.js → line-CeFoQ5y-.js} +1 -1
- package/console-app/assets/{linear-BKu0S9-y.js → linear-C4Pk-YMX.js} +1 -1
- package/console-app/assets/{mermaid-parser.core-DhWf8x6B.js → mermaid-parser.core-U7wquvx8.js} +3 -3
- package/console-app/assets/{mermaid.core-RkgzUTr1.js → mermaid.core-8TRpFRm9.js} +4 -4
- package/console-app/assets/{mindmap-definition-YA3MSWOX-BKATx3X1.js → mindmap-definition-YA3MSWOX-C7lzwqBX.js} +1 -1
- package/console-app/assets/{packet-AYTQ26CC-Dek-5xov.js → packet-AYTQ26CC-DiQV_rU3.js} +1 -1
- package/console-app/assets/{pegDiagram-XKGWAZYB-CkEJ5MeF.js → pegDiagram-XKGWAZYB-63ajP7-W.js} +1 -1
- package/console-app/assets/{pie-WAS4IAKB-BIoN9DHQ.js → pie-WAS4IAKB-B5q_o6dr.js} +1 -1
- package/console-app/assets/{pieDiagram-E7YTZNPT-CEPQgMPk.js → pieDiagram-E7YTZNPT-BTbvj-by.js} +1 -1
- package/console-app/assets/{quadrantDiagram-AXDQQJYC-eJxMa_50.js → quadrantDiagram-AXDQQJYC-CulqsAYd.js} +1 -1
- package/console-app/assets/{radar-RG4KPBEZ-BwJnovJ0.js → radar-RG4KPBEZ-CW_KoURS.js} +1 -1
- package/console-app/assets/{railroad-74A4TZTK-D1_fi4Md.js → railroad-74A4TZTK-CUmF6uBQ.js} +1 -1
- package/console-app/assets/railroad-abnf-HS5TGJTU-CcPw9q8a.js +1 -0
- package/console-app/assets/railroad-ebnf-LZEXJU2U-Ci_fZics.js +1 -0
- package/console-app/assets/railroad-peg-WCYAUIDC-DTsDykSf.js +1 -0
- package/console-app/assets/{railroadDiagram-O6MQD6OU-BpOx1Ffe.js → railroadDiagram-O6MQD6OU-WlkBu_N3.js} +1 -1
- package/console-app/assets/{requirementDiagram-BXWQKSXE-D-IEFxpk.js → requirementDiagram-BXWQKSXE-CJK_CbPR.js} +1 -1
- package/console-app/assets/{sankeyDiagram-P5KCCOFB-SdALSgLt.js → sankeyDiagram-P5KCCOFB-C466WOH8.js} +1 -1
- package/console-app/assets/{sequenceDiagram-WJ2MYXX4-Burhioru.js → sequenceDiagram-WJ2MYXX4-CV0dCcj0.js} +1 -1
- package/console-app/assets/{src-BI-J79xw.js → src-P4Nw8sY0.js} +1 -1
- package/console-app/assets/{stateDiagram-D77RDMKH-BhWb5zb7.js → stateDiagram-D77RDMKH-HaLGm8V9.js} +1 -1
- package/console-app/assets/stateDiagram-v2-MP3YSRHH--GM14Hz5.js +1 -0
- package/console-app/assets/{swimlanes-42K2YHIH-BoaeXC6b.js → swimlanes-42K2YHIH-Bi-O5vWa.js} +1 -1
- package/console-app/assets/swimlanesDiagram-VR7AAH4N-_6rRi6Wt.js +8 -0
- package/console-app/assets/{timeline-definition-24CTP7MA-uuBDVcEL.js → timeline-definition-24CTP7MA-B4h-gx-i.js} +1 -1
- package/console-app/assets/{treeView-Q6P3EWNA-BRZawPMp.js → treeView-Q6P3EWNA-CXJ_pHQw.js} +1 -1
- package/console-app/assets/{treemap-WGGIJYW6-WSINjp5g.js → treemap-WGGIJYW6-M84p2a_3.js} +1 -1
- package/console-app/assets/{vennDiagram-4TSXK5OY-K6UjE9uq.js → vennDiagram-4TSXK5OY-BesF4k_r.js} +1 -1
- package/console-app/assets/{wardley-WFR3VGLG-BMecQ-Z6.js → wardley-WFR3VGLG-n9ulickP.js} +1 -1
- package/console-app/assets/{wardleyDiagram-VM6X3IG4-9blTcGMt.js → wardleyDiagram-VM6X3IG4-BG0nnWDf.js} +1 -1
- package/console-app/assets/{xychartDiagram-S5SC5T6Z-DSnHhis6.js → xychartDiagram-S5SC5T6Z-BtOW7fpF.js} +1 -1
- package/console-app/index.html +1 -1
- package/dist/.pikku/addon/index.d.ts +1 -1
- package/dist/.pikku/addon/index.js +1 -1
- package/dist/.pikku/addon/pikku-addon-types.gen.d.ts +1 -1
- package/dist/.pikku/addon/pikku-addon-types.gen.js +1 -1
- package/dist/.pikku/agent/index.d.ts +1 -1
- package/dist/.pikku/agent/index.js +1 -1
- package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +1 -1
- package/dist/.pikku/agent/pikku-model-aliases.gen.js +1 -1
- package/dist/.pikku/analytics/index.d.ts +1 -1
- package/dist/.pikku/analytics/index.js +1 -1
- package/dist/.pikku/analytics/pikku-analytics-types.gen.d.ts +1 -1
- package/dist/.pikku/analytics/pikku-analytics-types.gen.js +1 -1
- package/dist/.pikku/auth/index.d.ts +1 -1
- package/dist/.pikku/auth/index.js +1 -1
- package/dist/.pikku/auth/pikku-auth-types.gen.d.ts +1 -1
- package/dist/.pikku/auth/pikku-auth-types.gen.js +1 -1
- package/dist/.pikku/channel/index.d.ts +1 -1
- package/dist/.pikku/channel/index.js +1 -1
- package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +1 -1
- package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
- package/dist/.pikku/cli/index.d.ts +1 -1
- package/dist/.pikku/cli/index.js +1 -1
- package/dist/.pikku/cli/pikku-cli-channel.js +6 -1
- package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-client.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.json +11 -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 +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.json +55 -3
- package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli.gen.js +1 -1
- package/dist/.pikku/error/index.d.ts +1 -1
- package/dist/.pikku/error/index.js +1 -1
- package/dist/.pikku/error/pikku-error-types.gen.d.ts +1 -1
- package/dist/.pikku/error/pikku-error-types.gen.js +1 -1
- package/dist/.pikku/function/index.d.ts +1 -1
- package/dist/.pikku/function/index.js +1 -1
- package/dist/.pikku/function/pikku-function-types.gen.d.ts +1 -1
- package/dist/.pikku/function/pikku-function-types.gen.js +1 -1
- package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
- package/dist/.pikku/function/pikku-functions-meta.gen.json +38 -21
- package/dist/.pikku/function/pikku-functions.gen.js +1 -1
- package/dist/.pikku/gateway/index.d.ts +1 -1
- package/dist/.pikku/gateway/index.js +1 -1
- package/dist/.pikku/gateway/pikku-gateway-types.gen.d.ts +1 -1
- package/dist/.pikku/gateway/pikku-gateway-types.gen.js +1 -1
- package/dist/.pikku/http/index.d.ts +1 -1
- package/dist/.pikku/http/index.js +1 -1
- package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
- package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
- package/dist/.pikku/mcp/index.d.ts +1 -1
- package/dist/.pikku/mcp/index.js +1 -1
- package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
- package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
- package/dist/.pikku/middleware/index.d.ts +1 -1
- package/dist/.pikku/middleware/index.js +1 -1
- package/dist/.pikku/middleware/pikku-middleware-types.gen.d.ts +1 -1
- package/dist/.pikku/middleware/pikku-middleware-types.gen.js +1 -1
- package/dist/.pikku/pikku-bootstrap-scenarios.gen.d.ts +1 -1
- package/dist/.pikku/pikku-bootstrap-scenarios.gen.js +1 -1
- package/dist/.pikku/pikku-bootstrap.gen.d.ts +1 -1
- package/dist/.pikku/pikku-bootstrap.gen.js +1 -1
- package/dist/.pikku/pikku-services.gen.d.ts +1 -1
- package/dist/.pikku/queue/index.d.ts +1 -1
- package/dist/.pikku/queue/index.js +1 -1
- package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
- package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
- package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +1 -1
- package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.json +1 -0
- package/dist/.pikku/scenarios/index.d.ts +1 -1
- package/dist/.pikku/scenarios/index.js +1 -1
- package/dist/.pikku/scenarios/pikku-personas.gen.js +1 -1
- package/dist/.pikku/scenarios/pikku-scenario-functions-meta.gen.js +1 -1
- package/dist/.pikku/scenarios/pikku-scenario-functions.gen.d.ts +1 -1
- package/dist/.pikku/scenarios/pikku-scenario-types.gen.d.ts +7 -1
- package/dist/.pikku/scenarios/pikku-scenario-wirings-meta.gen.js +1 -1
- package/dist/.pikku/scenarios/pikku-scenario-wirings.gen.d.ts +1 -1
- package/dist/.pikku/scenarios/schemas/register.gen.d.ts +1 -1
- package/dist/.pikku/scenarios/schemas/register.gen.js +1 -1
- package/dist/.pikku/scheduler/index.d.ts +1 -1
- package/dist/.pikku/scheduler/index.js +1 -1
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
- package/dist/.pikku/schemas/register.gen.js +3 -1
- package/dist/.pikku/schemas/schemas/FabricChangesAskInput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/FabricInitInput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/FabricLinkInput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/KnowledgeReconcileInput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/KnowledgeReconcileOutput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/PikkuSkillsInstallInput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/ScenarioGuideInput.schema.json +1 -0
- package/dist/.pikku/scopes/index.d.ts +1 -1
- package/dist/.pikku/scopes/index.js +1 -1
- package/dist/.pikku/scopes/pikku-flags.gen.d.ts +1 -1
- package/dist/.pikku/scopes/pikku-personas.gen.js +1 -1
- package/dist/.pikku/scopes/pikku-roles.gen.d.ts +1 -1
- package/dist/.pikku/scopes/pikku-scope-types.gen.d.ts +1 -1
- package/dist/.pikku/scopes/pikku-scope-types.gen.js +1 -1
- package/dist/.pikku/scopes/pikku-scopes.gen.d.ts +1 -1
- package/dist/.pikku/secrets/index.d.ts +1 -1
- package/dist/.pikku/secrets/index.js +1 -1
- package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +1 -1
- package/dist/.pikku/secrets/pikku-secret-types.gen.js +1 -1
- package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +1 -1
- package/dist/.pikku/secrets/pikku-secrets.gen.js +1 -1
- package/dist/.pikku/services/pikku-meta-service.gen.d.ts +1 -1
- package/dist/.pikku/services/pikku-meta-service.gen.js +1 -1
- package/dist/.pikku/setup/index.d.ts +1 -1
- package/dist/.pikku/setup/index.js +1 -1
- package/dist/.pikku/setup/pikku-setup-types.gen.d.ts +1 -1
- package/dist/.pikku/setup/pikku-setup-types.gen.js +1 -1
- package/dist/.pikku/trigger/index.d.ts +1 -1
- package/dist/.pikku/trigger/index.js +1 -1
- package/dist/.pikku/trigger/pikku-trigger-types.gen.d.ts +1 -1
- package/dist/.pikku/trigger/pikku-trigger-types.gen.js +1 -1
- package/dist/.pikku/variables/index.d.ts +1 -1
- package/dist/.pikku/variables/index.js +1 -1
- package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +1 -1
- package/dist/.pikku/variables/pikku-variable-types.gen.js +1 -1
- package/dist/.pikku/variables/pikku-variables.gen.d.ts +1 -1
- package/dist/.pikku/variables/pikku-variables.gen.js +1 -1
- package/dist/.pikku/workflow/index.d.ts +1 -1
- package/dist/.pikku/workflow/index.js +1 -1
- package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +1 -1
- package/dist/.pikku/workflow/pikku-workflow-types.gen.js +1 -1
- package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +1 -1
- package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +1 -1
- package/dist/bin/pikku-bin.mjs +3 -3
- package/dist/src/cli.wiring.js +44 -2
- package/dist/src/deploy/analyzer/analyzer.js +93 -4
- package/dist/src/deploy/build-pipeline.d.ts +2 -0
- package/dist/src/deploy/build-pipeline.js +4 -3
- package/dist/src/deploy/codegen/per-unit-codegen.js +24 -0
- package/dist/src/fabric/fabric-commands.d.ts +9 -0
- package/dist/src/fabric/fabric-commands.js +11 -1
- package/dist/src/fabric/functions/changes-ask.function.d.ts +4 -0
- package/dist/src/fabric/functions/changes-ask.function.js +7 -1
- package/dist/src/fabric/functions/init.function.d.ts +4 -0
- package/dist/src/fabric/functions/init.function.js +5 -1
- package/dist/src/fabric/functions/link.function.d.ts +4 -0
- package/dist/src/fabric/functions/link.function.js +9 -1
- package/dist/src/fabric/lib/organization.d.ts +8 -0
- package/dist/src/fabric/lib/organization.js +26 -0
- package/dist/src/functions/commands/deploy-apply.js +129 -13
- package/dist/src/functions/commands/deploy-plan.js +1 -0
- package/dist/src/functions/commands/dev-mcp-manifests.d.ts +27 -0
- package/dist/src/functions/commands/dev-mcp-manifests.js +52 -0
- package/dist/src/functions/commands/dev.js +10 -30
- package/dist/src/functions/commands/knowledge-reconcile.d.ts +15 -3
- package/dist/src/functions/commands/knowledge-reconcile.js +1 -1
- package/dist/src/functions/commands/scenario-guide.d.ts +184 -0
- package/dist/src/functions/commands/scenario-guide.js +313 -0
- package/dist/src/functions/commands/scenario-ladder.d.ts +3 -1
- package/dist/src/functions/commands/scenario-ladder.js +1 -0
- package/dist/src/functions/commands/scenario-plan.d.ts +17 -1
- package/dist/src/functions/commands/scenario-plan.js +15 -0
- package/dist/src/functions/commands/scenario.d.ts +30 -0
- package/dist/src/functions/commands/scenario.js +187 -23
- package/dist/src/functions/commands/skill-agents.d.ts +43 -0
- package/dist/src/functions/commands/skill-agents.js +135 -0
- package/dist/src/functions/commands/skills.d.ts +9 -0
- package/dist/src/functions/commands/skills.js +29 -2
- package/dist/src/functions/db/postgres/postgres-introspector.d.ts +6 -0
- package/dist/src/functions/db/postgres/postgres-introspector.js +7 -1
- package/dist/src/functions/knowledge/render.d.ts +1 -1
- package/dist/src/functions/knowledge/render.js +25 -2
- package/dist/src/functions/knowledge/schemas.d.ts +5 -1
- package/dist/src/functions/wirings/mcp/pikku-command-mcp-json.js +32 -5
- package/dist/src/functions/wirings/scenarios/serialize-feature-meta.js +1 -0
- package/dist/src/functions/wirings/workflow/serialize-scenario-types.js +6 -0
- package/dist/src/server/bun-server-runner.js +1 -0
- package/dist/src/server/dev-server-runner.interface.d.ts +13 -0
- package/dist/src/server/node-server-runner.js +1 -0
- package/dist/src/services.js +3 -1
- package/dist/src/utils/mcp-surface.d.ts +8 -0
- package/dist/src/utils/mcp-surface.js +9 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +12 -12
- package/surface.json +19 -13
- package/console-app/assets/architecture-7GRP2DOG-DMiKIh61.js +0 -1
- package/console-app/assets/channel-D3pFDQ-Y.js +0 -1
- package/console-app/assets/chunk-XXDRQBXY-CPBzG1Ie.js +0 -1
- package/console-app/assets/classDiagram-ZZMXUADV-Bh5HK4MN.js +0 -1
- package/console-app/assets/classDiagram-v2-VYDZK3BY-Bh5HK4MN.js +0 -1
- package/console-app/assets/eventmodeling-NTZA5JFV-DLjVcr4S.js +0 -1
- package/console-app/assets/flowDiagram-HODETNUW-CCiyVZIU.js +0 -1
- package/console-app/assets/railroad-abnf-HS5TGJTU-D-_q3UaA.js +0 -1
- package/console-app/assets/railroad-ebnf-LZEXJU2U-kh7JN-2k.js +0 -1
- package/console-app/assets/railroad-peg-WCYAUIDC-rrwoksLW.js +0 -1
- package/console-app/assets/stateDiagram-v2-MP3YSRHH-OjHOAFS5.js +0 -1
- package/console-app/assets/swimlanesDiagram-VR7AAH4N-CkKXVcij.js +0 -8
|
@@ -5,17 +5,18 @@ import { readFile } from 'node:fs/promises';
|
|
|
5
5
|
import { existsSync, readFileSync } from 'node:fs';
|
|
6
6
|
import { pikkuSessionlessFunc } from '#pikku/function';
|
|
7
7
|
import { runBuildPipeline, describeBuildFailure, PikkuDeployBuildFailedError, } from '../../deploy/build-pipeline.js';
|
|
8
|
+
// A bundler reads anything not starting with `./` or `../` as a bare package
|
|
9
|
+
// specifier, and a path into a dot-directory (`.pikku/...`) starts with a dot
|
|
10
|
+
// without being relative — so testing for `.` alone silently emits an import
|
|
11
|
+
// no bundler can resolve.
|
|
8
12
|
function toRelativeImport(fromDir, toFile) {
|
|
9
13
|
let rel = relative(fromDir, toFile).replace(/\\/g, '/');
|
|
10
|
-
if (!rel.startsWith('.'))
|
|
14
|
+
if (!rel.startsWith('./') && !rel.startsWith('../'))
|
|
11
15
|
rel = `./${rel}`;
|
|
12
16
|
return rel.replace(/\.ts$/, '.js');
|
|
13
17
|
}
|
|
14
18
|
export function getEntryContext(unitDir, pikkuDir, unit, inspectorState) {
|
|
15
|
-
const
|
|
16
|
-
const bootstrapPath = bootstrapRelative.startsWith('./') || bootstrapRelative.startsWith('../')
|
|
17
|
-
? bootstrapRelative
|
|
18
|
-
: `./${bootstrapRelative}`;
|
|
19
|
+
const bootstrapPath = toRelativeImport(unitDir, join(pikkuDir, 'pikku-bootstrap.gen.js'));
|
|
19
20
|
const { pikkuConfigFactory, singletonServicesFactory, singletonServicesType, } = inspectorState.filesAndMethods;
|
|
20
21
|
if (!pikkuConfigFactory || !singletonServicesFactory) {
|
|
21
22
|
throw new Error('Cannot generate deploy entries: createConfig and createSingletonServices must be defined in your project');
|
|
@@ -28,14 +29,22 @@ export function getEntryContext(unitDir, pikkuDir, unit, inspectorState) {
|
|
|
28
29
|
const servicesType = singletonServicesType
|
|
29
30
|
? `Partial<${singletonServicesType.type}>`
|
|
30
31
|
: 'Record<string, unknown>';
|
|
31
|
-
// MCP: when the unit's
|
|
32
|
-
//
|
|
33
|
-
//
|
|
32
|
+
// MCP: when the unit's surface manifest is non-empty, import it and pass it
|
|
33
|
+
// to the generated server so it mounts the surface. Without this the deployed
|
|
34
|
+
// bundle never serves MCP even though the dev server does.
|
|
35
|
+
//
|
|
36
|
+
// An `mcp` unit serves exactly the one surface it was emitted for — its name
|
|
37
|
+
// carries that surface's slug, which is also the manifest's filename. Any
|
|
38
|
+
// other unit (a monolith, say) serves the default surface, as before.
|
|
34
39
|
let mcpImport = '';
|
|
35
40
|
let mcpServerOption = '';
|
|
36
|
-
const
|
|
41
|
+
const mcpSlug = unit.role === 'mcp' && unit.name !== 'mcp-server'
|
|
42
|
+
? unit.name.replace(/^mcp-/, '')
|
|
43
|
+
: undefined;
|
|
44
|
+
const mcpJsonAbs = join(pikkuDir, 'mcp', mcpSlug ? `mcp.${mcpSlug}.gen.json` : 'mcp.gen.json');
|
|
37
45
|
if (existsSync(mcpJsonAbs)) {
|
|
38
46
|
let hasMcp = false;
|
|
47
|
+
let mcpPath = '/mcp';
|
|
39
48
|
try {
|
|
40
49
|
const parsed = JSON.parse(readFileSync(mcpJsonAbs, 'utf-8'));
|
|
41
50
|
hasMcp =
|
|
@@ -43,15 +52,18 @@ export function getEntryContext(unitDir, pikkuDir, unit, inspectorState) {
|
|
|
43
52
|
(parsed.resources?.length ?? 0) +
|
|
44
53
|
(parsed.prompts?.length ?? 0) >
|
|
45
54
|
0;
|
|
55
|
+
mcpPath = parsed.mcpPath ?? mcpPath;
|
|
46
56
|
}
|
|
47
57
|
catch (err) {
|
|
48
58
|
console.warn(`[pikku] could not parse ${mcpJsonAbs} — skipping MCP mount: ${err instanceof Error ? err.message : String(err)}`);
|
|
49
59
|
}
|
|
50
60
|
if (hasMcp) {
|
|
51
|
-
const
|
|
52
|
-
const relImport = rel.startsWith('.') ? rel : `./${rel}`;
|
|
61
|
+
const relImport = toRelativeImport(unitDir, mcpJsonAbs);
|
|
53
62
|
mcpImport = `import mcpJson from '${relImport}' with { type: 'json' }`;
|
|
54
|
-
mcpServerOption =
|
|
63
|
+
mcpServerOption =
|
|
64
|
+
mcpPath === '/mcp'
|
|
65
|
+
? 'mcpJson, '
|
|
66
|
+
: `mcpJson, mcpPath: ${JSON.stringify(mcpPath)}, `;
|
|
55
67
|
}
|
|
56
68
|
}
|
|
57
69
|
return {
|
|
@@ -103,7 +115,105 @@ async function resolveProjectId(projectDir) {
|
|
|
103
115
|
* configured provider may also be a URL, and a runtime whose `require.resolve`
|
|
104
116
|
* hands a bare specifier straight back for its own built-ins has resolved
|
|
105
117
|
* nothing. Both of those import as written.
|
|
118
|
+
*
|
|
119
|
+
* `require.resolve` applies the `require` condition, so an ESM-only provider —
|
|
120
|
+
* one whose exports map offers `types` and `import` and nothing else, which is
|
|
121
|
+
* a perfectly ordinary way to publish — does not resolve there even though it
|
|
122
|
+
* is installed and importable. Falling through to the bare import does not
|
|
123
|
+
* rescue it, because that resolves from the CLI rather than the project, so
|
|
124
|
+
* `resolveEsmOnlyEntry` reads the package's own entry instead. It has to walk
|
|
125
|
+
* the resolution paths by hand: the exports map that blocked the package also
|
|
126
|
+
* blocks `<name>/package.json`.
|
|
127
|
+
*
|
|
128
|
+
* Which is why it runs on any resolution failure rather than on one code. Node
|
|
129
|
+
* reports this as ERR_PACKAGE_PATH_NOT_EXPORTED and bun as a plain
|
|
130
|
+
* MODULE_NOT_FOUND, indistinguishable from a package that is genuinely absent.
|
|
131
|
+
* Telling them apart is what the filesystem is for: a package that is not there
|
|
132
|
+
* yields no entry and the bare import still runs, unchanged.
|
|
133
|
+
*/
|
|
134
|
+
/**
|
|
135
|
+
* The conditions that are true for the `import()` this resolution ends in.
|
|
136
|
+
* `default` matches unconditionally and is handled by the resolver rather than
|
|
137
|
+
* listed here, because node treats it as the fallthrough rather than as a name.
|
|
138
|
+
*/
|
|
139
|
+
const ACTIVE_EXPORT_CONDITIONS = new Set(['node', 'import']);
|
|
140
|
+
/**
|
|
141
|
+
* Picks an export target the way node does: a conditions object is walked in
|
|
142
|
+
* DECLARATION order and the first key that is active wins, nesting included.
|
|
143
|
+
*
|
|
144
|
+
* The order is the package author's, not ours. `{ "import": { "node": "./n.js",
|
|
145
|
+
* "default": "./browser.js" } }` resolves to `./n.js`, because `node` is listed
|
|
146
|
+
* first and is true here — preferring a fixed list of condition names instead
|
|
147
|
+
* would hand back the browser build and load a different provider than the one
|
|
148
|
+
* node would have.
|
|
149
|
+
*
|
|
150
|
+
* An array is a list of fallbacks, and `null` is a deliberate block, so both
|
|
151
|
+
* carry on to the next candidate rather than ending the walk.
|
|
106
152
|
*/
|
|
153
|
+
const resolveExportTarget = (target) => {
|
|
154
|
+
if (typeof target === 'string')
|
|
155
|
+
return target;
|
|
156
|
+
if (target === null || target === undefined)
|
|
157
|
+
return undefined;
|
|
158
|
+
if (Array.isArray(target)) {
|
|
159
|
+
for (const candidate of target) {
|
|
160
|
+
const resolved = resolveExportTarget(candidate);
|
|
161
|
+
if (resolved !== undefined)
|
|
162
|
+
return resolved;
|
|
163
|
+
}
|
|
164
|
+
return undefined;
|
|
165
|
+
}
|
|
166
|
+
if (typeof target !== 'object')
|
|
167
|
+
return undefined;
|
|
168
|
+
for (const [condition, value] of Object.entries(target)) {
|
|
169
|
+
if (condition !== 'default' && !ACTIVE_EXPORT_CONDITIONS.has(condition)) {
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
const resolved = resolveExportTarget(value);
|
|
173
|
+
if (resolved !== undefined)
|
|
174
|
+
return resolved;
|
|
175
|
+
}
|
|
176
|
+
return undefined;
|
|
177
|
+
};
|
|
178
|
+
/**
|
|
179
|
+
* The entry an exports map offers to `import`, or, for a package with no
|
|
180
|
+
* exports map at all, its legacy main. A map that deliberately omits a root
|
|
181
|
+
* entry offers nothing: falling back to `main` there would reach past the
|
|
182
|
+
* encapsulation the package asked for, so this reports no entry and the caller
|
|
183
|
+
* treats the provider as missing.
|
|
184
|
+
*/
|
|
185
|
+
const esmEntryFromManifest = (manifest) => {
|
|
186
|
+
const exportsField = manifest.exports;
|
|
187
|
+
if (exportsField === undefined || exportsField === null) {
|
|
188
|
+
const legacy = manifest.module ?? manifest.main;
|
|
189
|
+
return typeof legacy === 'string' ? legacy : undefined;
|
|
190
|
+
}
|
|
191
|
+
const isSubpathMap = typeof exportsField === 'object' &&
|
|
192
|
+
!Array.isArray(exportsField) &&
|
|
193
|
+
Object.keys(exportsField).some((key) => key.startsWith('.'));
|
|
194
|
+
const root = isSubpathMap ? exportsField['.'] : exportsField;
|
|
195
|
+
return resolveExportTarget(root);
|
|
196
|
+
};
|
|
197
|
+
const resolveEsmOnlyEntry = (require, packageName) => {
|
|
198
|
+
const searchPaths = require.resolve.paths(packageName) ?? [];
|
|
199
|
+
for (const searchPath of searchPaths) {
|
|
200
|
+
const packageJsonPath = join(searchPath, packageName, 'package.json');
|
|
201
|
+
if (!existsSync(packageJsonPath))
|
|
202
|
+
continue;
|
|
203
|
+
let manifest;
|
|
204
|
+
try {
|
|
205
|
+
manifest = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
return undefined;
|
|
209
|
+
}
|
|
210
|
+
const entry = esmEntryFromManifest(manifest);
|
|
211
|
+
if (!entry)
|
|
212
|
+
return undefined;
|
|
213
|
+
return join(searchPath, packageName, entry);
|
|
214
|
+
}
|
|
215
|
+
return undefined;
|
|
216
|
+
};
|
|
107
217
|
const importProviderPackage = async (packageName, projectDir) => {
|
|
108
218
|
const require = createRequire(join(projectDir ?? process.cwd(), 'package.json'));
|
|
109
219
|
try {
|
|
@@ -115,9 +225,14 @@ const importProviderPackage = async (packageName, projectDir) => {
|
|
|
115
225
|
catch (e) {
|
|
116
226
|
const err = e;
|
|
117
227
|
if (err?.code !== 'ERR_MODULE_NOT_FOUND' &&
|
|
118
|
-
err?.code !== 'MODULE_NOT_FOUND'
|
|
228
|
+
err?.code !== 'MODULE_NOT_FOUND' &&
|
|
229
|
+
err?.code !== 'ERR_PACKAGE_PATH_NOT_EXPORTED') {
|
|
119
230
|
throw e;
|
|
120
231
|
}
|
|
232
|
+
const entry = resolveEsmOnlyEntry(require, packageName);
|
|
233
|
+
if (entry && existsSync(entry)) {
|
|
234
|
+
return await import(pathToFileURL(entry).href);
|
|
235
|
+
}
|
|
121
236
|
}
|
|
122
237
|
return await import(packageName);
|
|
123
238
|
};
|
|
@@ -250,6 +365,7 @@ export const deployApply = pikkuSessionlessFunc({
|
|
|
250
365
|
serverlessIncompatible: config.deploy?.serverlessIncompatible,
|
|
251
366
|
defaultTarget: config.deploy?.defaultTarget,
|
|
252
367
|
grouping: config.deploy?.grouping,
|
|
368
|
+
mangleIdentifiers: config.deploy?.mangleIdentifiers,
|
|
253
369
|
globalHTTPPrefix: config.globalHTTPPrefix,
|
|
254
370
|
getEntryContext,
|
|
255
371
|
frontend: config.frontend,
|
|
@@ -59,6 +59,7 @@ export const deployPlan = pikkuSessionlessFunc({
|
|
|
59
59
|
serverlessIncompatible: config.deploy?.serverlessIncompatible,
|
|
60
60
|
defaultTarget: config.deploy?.defaultTarget,
|
|
61
61
|
grouping: config.deploy?.grouping,
|
|
62
|
+
mangleIdentifiers: config.deploy?.mangleIdentifiers,
|
|
62
63
|
globalHTTPPrefix: config.globalHTTPPrefix,
|
|
63
64
|
getEntryContext,
|
|
64
65
|
frontend: config.frontend,
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type McpManifest = {
|
|
2
|
+
mcpPath?: string;
|
|
3
|
+
tools?: unknown[];
|
|
4
|
+
resources?: unknown[];
|
|
5
|
+
prompts?: unknown[];
|
|
6
|
+
};
|
|
7
|
+
export type McpSurfaceMount = {
|
|
8
|
+
mcpJson: McpManifest;
|
|
9
|
+
mcpPath: string;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Every MCP endpoint the generated tree describes: the default one, plus one
|
|
13
|
+
* per surface for a project that serves several connectors.
|
|
14
|
+
*
|
|
15
|
+
* Dev mounts all of them so a connector can be pointed at `pikku dev` and tried
|
|
16
|
+
* before it is deployed. Without the surfaces, a project that moved its tools
|
|
17
|
+
* onto their own endpoints would serve nothing locally at all — the default
|
|
18
|
+
* manifest it does read is empty precisely because they moved.
|
|
19
|
+
*
|
|
20
|
+
* A surface manifest without an `mcpPath` is skipped rather than guessed at: the
|
|
21
|
+
* path is what the deployed unit is routed on, and a mount at a different path
|
|
22
|
+
* would make dev disagree with production.
|
|
23
|
+
*/
|
|
24
|
+
export declare const readMcpManifests: (pikkuDir: string, onWarning: (message: string) => void) => {
|
|
25
|
+
mcpJson?: McpManifest;
|
|
26
|
+
mcpSurfaces: McpSurfaceMount[];
|
|
27
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { existsSync, readFileSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* A manifest with nothing in it reads as "no MCP here": the transports mount
|
|
5
|
+
* only when there is something to serve, so an empty one would announce an
|
|
6
|
+
* endpoint that answers every call with a missing tool.
|
|
7
|
+
*
|
|
8
|
+
* Absent or unparseable is not an error either — an app with no MCP wirings
|
|
9
|
+
* has no manifest, and that is the common case.
|
|
10
|
+
*/
|
|
11
|
+
const readMcpManifest = (file, onWarning) => {
|
|
12
|
+
if (!existsSync(file))
|
|
13
|
+
return undefined;
|
|
14
|
+
try {
|
|
15
|
+
const parsed = JSON.parse(readFileSync(file, 'utf-8'));
|
|
16
|
+
const count = (parsed.tools?.length ?? 0) +
|
|
17
|
+
(parsed.resources?.length ?? 0) +
|
|
18
|
+
(parsed.prompts?.length ?? 0);
|
|
19
|
+
return count > 0 ? parsed : undefined;
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
onWarning(`[pikku] could not parse ${file} — MCP will not be served: ${err instanceof Error ? err.message : String(err)}`);
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Every MCP endpoint the generated tree describes: the default one, plus one
|
|
28
|
+
* per surface for a project that serves several connectors.
|
|
29
|
+
*
|
|
30
|
+
* Dev mounts all of them so a connector can be pointed at `pikku dev` and tried
|
|
31
|
+
* before it is deployed. Without the surfaces, a project that moved its tools
|
|
32
|
+
* onto their own endpoints would serve nothing locally at all — the default
|
|
33
|
+
* manifest it does read is empty precisely because they moved.
|
|
34
|
+
*
|
|
35
|
+
* A surface manifest without an `mcpPath` is skipped rather than guessed at: the
|
|
36
|
+
* path is what the deployed unit is routed on, and a mount at a different path
|
|
37
|
+
* would make dev disagree with production.
|
|
38
|
+
*/
|
|
39
|
+
export const readMcpManifests = (pikkuDir, onWarning) => {
|
|
40
|
+
const mcpDir = join(pikkuDir, 'mcp');
|
|
41
|
+
const mcpJson = readMcpManifest(join(mcpDir, 'mcp.gen.json'), onWarning);
|
|
42
|
+
const mcpSurfaces = (existsSync(mcpDir) ? readdirSync(mcpDir) : [])
|
|
43
|
+
.filter((name) => /^mcp\..+\.gen\.json$/.test(name))
|
|
44
|
+
.sort()
|
|
45
|
+
.flatMap((name) => {
|
|
46
|
+
const parsed = readMcpManifest(join(mcpDir, name), onWarning);
|
|
47
|
+
if (!parsed?.mcpPath)
|
|
48
|
+
return [];
|
|
49
|
+
return [{ mcpJson: parsed, mcpPath: parsed.mcpPath }];
|
|
50
|
+
});
|
|
51
|
+
return { mcpJson, mcpSurfaces };
|
|
52
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { join, resolve } from 'path';
|
|
2
|
-
import {
|
|
2
|
+
import { readMcpManifests } from './dev-mcp-manifests.js';
|
|
3
3
|
import { pikkuSessionlessFunc } from '#pikku/function';
|
|
4
4
|
import chokidar from 'chokidar';
|
|
5
5
|
import { pikkuDevReloader, reloadGeneratedMeta, reconcileAddonRegistry, } from '@pikku/core/dev';
|
|
@@ -308,45 +308,25 @@ export const dev = pikkuSessionlessFunc({
|
|
|
308
308
|
...(consoleMount ? [consoleMount] : []),
|
|
309
309
|
];
|
|
310
310
|
/**
|
|
311
|
-
* Hand the server the generated MCP
|
|
311
|
+
* Hand the server the generated MCP manifests so it actually serves MCP.
|
|
312
312
|
*
|
|
313
313
|
* Codegen reports "N MCP endpoints" and both transports mount them at
|
|
314
|
-
* `mcpPath` — but only when given
|
|
314
|
+
* `mcpPath` — but only when given the manifest, and dev never passed it.
|
|
315
315
|
*
|
|
316
|
-
*
|
|
317
|
-
* off its third argument, and the runners forward a hand-picked list
|
|
318
|
-
* fields. Putting
|
|
319
|
-
* So every pikku app announced an MCP surface at startup and
|
|
320
|
-
* and the only way to exercise a tool was to deploy.
|
|
321
|
-
* carries a comment saying the deployed bundle should match "the dev server"
|
|
322
|
-
* — which had never served it either.
|
|
323
|
-
*
|
|
324
|
-
* Absent or unparseable is not an error: an app with no MCP wirings has no
|
|
325
|
-
* manifest, and that is the common case.
|
|
316
|
+
* They go in the runner *options*, not in the config: the transport reads
|
|
317
|
+
* them off its third argument, and the runners forward a hand-picked list
|
|
318
|
+
* of fields. Putting them in `config` type-checks and is discarded in
|
|
319
|
+
* silence. So every pikku app announced an MCP surface at startup and
|
|
320
|
+
* served a 404, and the only way to exercise a tool was to deploy.
|
|
326
321
|
*/
|
|
327
|
-
const mcpJson =
|
|
328
|
-
const file = join(pikkuDir, 'mcp', 'mcp.gen.json');
|
|
329
|
-
if (!existsSync(file))
|
|
330
|
-
return undefined;
|
|
331
|
-
try {
|
|
332
|
-
const parsed = JSON.parse(readFileSync(file, 'utf-8'));
|
|
333
|
-
const count = (parsed.tools?.length ?? 0) +
|
|
334
|
-
(parsed.resources?.length ?? 0) +
|
|
335
|
-
(parsed.prompts?.length ?? 0);
|
|
336
|
-
return count > 0 ? parsed : undefined;
|
|
337
|
-
}
|
|
338
|
-
catch (err) {
|
|
339
|
-
logger.warn(`[pikku] could not parse ${file} — MCP will not be served: ${err instanceof Error ? err.message : String(err)}`);
|
|
340
|
-
return undefined;
|
|
341
|
-
}
|
|
342
|
-
})();
|
|
322
|
+
const { mcpJson, mcpSurfaces } = readMcpManifests(pikkuDir, (message) => logger.warn(message));
|
|
343
323
|
const pikkuServer = devServerRunner.createServer({
|
|
344
324
|
...userConfig,
|
|
345
325
|
hostname: bindHostname,
|
|
346
326
|
port: resolvedPort,
|
|
347
327
|
content: localContentConfig,
|
|
348
328
|
...(staticMounts.length > 0 ? { staticMounts } : {}),
|
|
349
|
-
}, logger, { contentSigningJWT, mcpJson });
|
|
329
|
+
}, logger, { contentSigningJWT, mcpJson, mcpSurfaces });
|
|
350
330
|
const lifecycle = await loadLifecycle();
|
|
351
331
|
await pikkuServer.init();
|
|
352
332
|
await lifecycle?.beforeStart?.(resolvedServices);
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { renderKnowledgeReconcile } from '../knowledge/render.js';
|
|
2
|
-
export declare const knowledgeReconcile: import("#pikku/function").PikkuFunctionConfig<
|
|
2
|
+
export declare const knowledgeReconcile: import("#pikku/function").PikkuFunctionConfig<{
|
|
3
|
+
require?: string | undefined;
|
|
4
|
+
}, {
|
|
3
5
|
kind: "ask-user" | "dispatch" | "hold" | "idle" | "repair-note" | "write-plan";
|
|
4
6
|
reason: string;
|
|
5
7
|
note?: string | undefined;
|
|
@@ -13,7 +15,11 @@ export declare const knowledgeReconcile: import("#pikku/function").PikkuFunction
|
|
|
13
15
|
description?: string | undefined;
|
|
14
16
|
}[];
|
|
15
17
|
} | undefined;
|
|
16
|
-
|
|
18
|
+
satisfied?: boolean | undefined;
|
|
19
|
+
required?: string[] | undefined;
|
|
20
|
+
}, "rpc" | "session", import("#pikku/function").PikkuFunction<{
|
|
21
|
+
require?: string | undefined;
|
|
22
|
+
}, {
|
|
17
23
|
kind: "ask-user" | "dispatch" | "hold" | "idle" | "repair-note" | "write-plan";
|
|
18
24
|
reason: string;
|
|
19
25
|
note?: string | undefined;
|
|
@@ -27,7 +33,11 @@ export declare const knowledgeReconcile: import("#pikku/function").PikkuFunction
|
|
|
27
33
|
description?: string | undefined;
|
|
28
34
|
}[];
|
|
29
35
|
} | undefined;
|
|
30
|
-
|
|
36
|
+
satisfied?: boolean | undefined;
|
|
37
|
+
required?: string[] | undefined;
|
|
38
|
+
}, "rpc" | "session", import("#pikku/function").WiredServices> | import("#pikku/function").PikkuFunctionSessionless<{
|
|
39
|
+
require?: string | undefined;
|
|
40
|
+
}, {
|
|
31
41
|
kind: "ask-user" | "dispatch" | "hold" | "idle" | "repair-note" | "write-plan";
|
|
32
42
|
reason: string;
|
|
33
43
|
note?: string | undefined;
|
|
@@ -41,5 +51,7 @@ export declare const knowledgeReconcile: import("#pikku/function").PikkuFunction
|
|
|
41
51
|
description?: string | undefined;
|
|
42
52
|
}[];
|
|
43
53
|
} | undefined;
|
|
54
|
+
satisfied?: boolean | undefined;
|
|
55
|
+
required?: string[] | undefined;
|
|
44
56
|
}, "rpc" | "session", import("#pikku/function").WiredServices, unknown>, undefined, undefined>;
|
|
45
57
|
export { renderKnowledgeReconcile };
|
|
@@ -6,6 +6,6 @@ export const knowledgeReconcile = pikkuSessionlessFunc({
|
|
|
6
6
|
description: 'Say the one thing to do next with the knowledge base — repair a note, write a plan, ask the user, dispatch a build, or nothing — derived from what is on disk rather than from what a previous step remembered to announce.',
|
|
7
7
|
input: KnowledgeReconcileInputSchema,
|
|
8
8
|
output: KnowledgeReconcileOutputSchema,
|
|
9
|
-
func: async ({ config }) => runKnowledgeReconcile(config.rootDir),
|
|
9
|
+
func: async ({ config }, input) => runKnowledgeReconcile(config.rootDir, input),
|
|
10
10
|
});
|
|
11
11
|
export { renderKnowledgeReconcile };
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/** One step of a scenario, as the run recorded it. */
|
|
2
|
+
export interface GuideStep {
|
|
3
|
+
/** The gherkin keyword the sentence was recorded under: Given, When, Then, And. */
|
|
4
|
+
phase?: string;
|
|
5
|
+
/** The sentence itself, without the keyword. */
|
|
6
|
+
sentence: string;
|
|
7
|
+
}
|
|
8
|
+
/** One screenshot a scenario filed, ready to reference. */
|
|
9
|
+
export interface GuideScreenshot {
|
|
10
|
+
/** The artifact's stable id, when the run recorded one. */
|
|
11
|
+
id?: string;
|
|
12
|
+
/** The caption the scenario author took the shot under; the alt text. */
|
|
13
|
+
name?: string;
|
|
14
|
+
/**
|
|
15
|
+
* The artifact's content key, relative to the run's artifact root and always
|
|
16
|
+
* forward-slashed — what the record stores, not a path on this machine. A
|
|
17
|
+
* page turns it into a link by prefixing the base it was rendered with.
|
|
18
|
+
*/
|
|
19
|
+
path: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The recording a scenario filed, when the run kept one.
|
|
23
|
+
*
|
|
24
|
+
* A browser run keeps a video per scenario and per actor, so a two-actor
|
|
25
|
+
* scenario files two. Same shape as a screenshot because a consumer treats it
|
|
26
|
+
* the same way — a key under the run's artifact root that a base is prefixed
|
|
27
|
+
* onto.
|
|
28
|
+
*/
|
|
29
|
+
export interface GuideVideo {
|
|
30
|
+
id?: string;
|
|
31
|
+
/** Whose window it was, when the run recorded more than one. */
|
|
32
|
+
actor?: string;
|
|
33
|
+
path: string;
|
|
34
|
+
}
|
|
35
|
+
export interface GuideScenario {
|
|
36
|
+
/** The scenario registration this ran. */
|
|
37
|
+
name: string;
|
|
38
|
+
/** What the run labelled it — the registration name, plus its feature and data. */
|
|
39
|
+
title: string;
|
|
40
|
+
description?: string;
|
|
41
|
+
/**
|
|
42
|
+
* The recorded ladder. Never rendered — a reader wants prose, not a
|
|
43
|
+
* Given/When/Then list — but it is the seed the prose is written from and the
|
|
44
|
+
* input {@link featureEvidence} watches.
|
|
45
|
+
*/
|
|
46
|
+
steps: GuideStep[];
|
|
47
|
+
screenshots: GuideScreenshot[];
|
|
48
|
+
/**
|
|
49
|
+
* Optional so that a record predating video, and every fixture written
|
|
50
|
+
* against one, still describes a scenario.
|
|
51
|
+
*/
|
|
52
|
+
videos?: GuideVideo[];
|
|
53
|
+
}
|
|
54
|
+
export interface GuideFeature {
|
|
55
|
+
id: string;
|
|
56
|
+
name: string;
|
|
57
|
+
description?: string;
|
|
58
|
+
/** `document !== false` on the registered feature. */
|
|
59
|
+
document: boolean;
|
|
60
|
+
scenarios: GuideScenario[];
|
|
61
|
+
}
|
|
62
|
+
/** One checked-in editorial source, parsed. */
|
|
63
|
+
export interface GuidePage {
|
|
64
|
+
/** Path relative to the docs source root, e.g. `deployments/promoting.md`. */
|
|
65
|
+
path: string;
|
|
66
|
+
title?: string;
|
|
67
|
+
description?: string;
|
|
68
|
+
/**
|
|
69
|
+
* The features this page cites, in the order their markers appear. Read off
|
|
70
|
+
* the body rather than declared in frontmatter: see {@link parseGuidePage}.
|
|
71
|
+
*/
|
|
72
|
+
features: string[];
|
|
73
|
+
/**
|
|
74
|
+
* The frontmatter as it was written, every key of it. Carried whole rather
|
|
75
|
+
* than picked apart because a docs site reads its own keys off it — `slug`,
|
|
76
|
+
* `draft`, `sidebar_position` — and a compiler that rebuilt the block from
|
|
77
|
+
* the fields it happens to know about would drop them on the first rebuild.
|
|
78
|
+
*/
|
|
79
|
+
frontmatter: Record<string, unknown>;
|
|
80
|
+
/** Everything after the frontmatter, generated regions included. */
|
|
81
|
+
body: string;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Read one editorial source.
|
|
85
|
+
*
|
|
86
|
+
* A page cites a feature by leaving the marker pair where the block belongs —
|
|
87
|
+
* an author writing `<!-- pikku:guide feature=x -->` followed by
|
|
88
|
+
* `<!-- /pikku:guide -->` and nothing between them. That one line is both
|
|
89
|
+
* halves of the job: it says *where* the block goes, which a frontmatter list
|
|
90
|
+
* cannot express, and it is what the coverage gate counts to decide *whether* a
|
|
91
|
+
* feature is documented at all. The mapping stays many-to-many and falls out of
|
|
92
|
+
* the union of every marker in the tree, so a feature written about in three
|
|
93
|
+
* places needs no index to say so.
|
|
94
|
+
*/
|
|
95
|
+
export declare const parseGuidePage: (path: string, content: string) => GuidePage;
|
|
96
|
+
/**
|
|
97
|
+
* The hash a page's prose is written against.
|
|
98
|
+
*
|
|
99
|
+
* The input is the feature's **step sentences and artifact ids**, and
|
|
100
|
+
* deliberately not the image bytes and not the prose: restyling a UI changes
|
|
101
|
+
* every screenshot and no sentence, while inserting, reordering or renaming a
|
|
102
|
+
* step changes the sentence list — and that is what actually invalidates a
|
|
103
|
+
* paragraph describing the flow. It watches something the reader never sees.
|
|
104
|
+
*
|
|
105
|
+
* Canonically, the hashed value is the JSON of
|
|
106
|
+
* `[[scenarioName, [sentence, …], [artifactId, …]], …]` where:
|
|
107
|
+
*
|
|
108
|
+
* - scenarios are sorted by name then title, because a run's order is a
|
|
109
|
+
* property of how the suite was selected that day, not of the feature;
|
|
110
|
+
* - sentences keep their ladder order, keyword included, because that order is
|
|
111
|
+
* the flow being described — the one thing a step change must move;
|
|
112
|
+
* - each sentence is whitespace-collapsed, so the reporter's column padding is
|
|
113
|
+
* not part of the promise;
|
|
114
|
+
* - artifact ids are sorted, because artifacts are filed as they are finalised
|
|
115
|
+
* rather than as they were taken.
|
|
116
|
+
*
|
|
117
|
+
* Seven hex characters, like a short commit hash: it is read by a human
|
|
118
|
+
* comparing two lines, not by a collision-resistant protocol.
|
|
119
|
+
*/
|
|
120
|
+
export declare const featureEvidence: (feature: GuideFeature) => string;
|
|
121
|
+
/**
|
|
122
|
+
* What each documented feature's evidence was the last time the guide was
|
|
123
|
+
* built, keyed by feature id.
|
|
124
|
+
*
|
|
125
|
+
* This is the one piece of machine state the pipeline keeps, and it is kept out
|
|
126
|
+
* of both the marker and the page frontmatter so that no hash is ever typed or
|
|
127
|
+
* merged by hand. It is generated, and it is checked in: a build that cannot
|
|
128
|
+
* read the previous hashes cannot tell stale prose from fresh, so a guide tree
|
|
129
|
+
* whose lock is untracked reports every page as current forever.
|
|
130
|
+
*/
|
|
131
|
+
export type GuideLock = Record<string, string>;
|
|
132
|
+
export declare const parseGuideLock: (content: string) => GuideLock;
|
|
133
|
+
export declare const renderGuideLock: (features: GuideFeature[], cited: Iterable<string>) => string;
|
|
134
|
+
/** Which features are documented, which pages cite something that is not. */
|
|
135
|
+
export interface GuideCoverage {
|
|
136
|
+
/** Registered, documented, and cited by at least one page. */
|
|
137
|
+
cited: string[];
|
|
138
|
+
/** Registered, documented, and cited by no page. */
|
|
139
|
+
missing: string[];
|
|
140
|
+
/** Cited by a page and not registered at all. */
|
|
141
|
+
unknown: Array<{
|
|
142
|
+
path: string;
|
|
143
|
+
featureId: string;
|
|
144
|
+
}>;
|
|
145
|
+
/** Cited by a page and registered with `document: false`. */
|
|
146
|
+
optedOut: Array<{
|
|
147
|
+
path: string;
|
|
148
|
+
featureId: string;
|
|
149
|
+
}>;
|
|
150
|
+
/** Cited, but the run filed no figure for it — a citation that shows nothing. */
|
|
151
|
+
figureless: Array<{
|
|
152
|
+
path: string;
|
|
153
|
+
featureId: string;
|
|
154
|
+
}>;
|
|
155
|
+
/** Pages whose locked evidence is not the feature's current evidence. */
|
|
156
|
+
stale: Array<{
|
|
157
|
+
path: string;
|
|
158
|
+
featureId: string;
|
|
159
|
+
locked: string;
|
|
160
|
+
current: string;
|
|
161
|
+
}>;
|
|
162
|
+
}
|
|
163
|
+
export declare const checkGuideCoverage: (features: GuideFeature[], pages: GuidePage[], lock?: GuideLock) => GuideCoverage;
|
|
164
|
+
/**
|
|
165
|
+
* Merge one editorial source with the blocks its features generate.
|
|
166
|
+
*
|
|
167
|
+
* Hand-written prose and generated blocks stay separable, so a rebuild never
|
|
168
|
+
* clobbers writing: the body is the author's file, and only the regions between
|
|
169
|
+
* the markers are replaced. A block whose feature the page has stopped citing is
|
|
170
|
+
* dropped, since nothing would ever rewrite it again.
|
|
171
|
+
*
|
|
172
|
+
* `artifactBase` is prefixed onto every artifact key: the relative path from
|
|
173
|
+
* this page to the run's artifact root, which is all this module knows about
|
|
174
|
+
* where anything lives.
|
|
175
|
+
*/
|
|
176
|
+
export declare const renderGuidePage: (page: GuidePage, features: Map<string, GuideFeature>, artifactBase: string) => string;
|
|
177
|
+
/**
|
|
178
|
+
* A recorded step sentence, split into its gherkin keyword and the rest.
|
|
179
|
+
*
|
|
180
|
+
* The run stores the composed sentence — `Given yasser signs in`, padded to
|
|
181
|
+
* the reporter's keyword column — so the phase is already in it and is read
|
|
182
|
+
* back off the record rather than re-derived from today's source.
|
|
183
|
+
*/
|
|
184
|
+
export declare const guideStep: (sentence: string) => GuideStep;
|