@pikku/cli 0.12.156 → 0.12.159
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 +1 -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 +30 -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 +19 -19
- 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/scenarios/index.d.ts +1 -1
- package/dist/.pikku/scenarios/index.js +1 -1
- package/dist/.pikku/scenarios/pikku-personas.gen.js +1 -1
- package/dist/.pikku/scenarios/pikku-scenario-functions-meta.gen.js +1 -1
- package/dist/.pikku/scenarios/pikku-scenario-functions.gen.d.ts +1 -1
- package/dist/.pikku/scenarios/pikku-scenario-types.gen.d.ts +1 -1
- package/dist/.pikku/scenarios/pikku-scenario-wirings-meta.gen.js +1 -1
- package/dist/.pikku/scenarios/pikku-scenario-wirings.gen.d.ts +1 -1
- package/dist/.pikku/scenarios/schemas/register.gen.d.ts +1 -1
- package/dist/.pikku/scenarios/schemas/register.gen.js +1 -1
- package/dist/.pikku/scheduler/index.d.ts +1 -1
- package/dist/.pikku/scheduler/index.js +1 -1
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
- package/dist/.pikku/schemas/register.gen.js +1 -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/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 +19 -1
- package/dist/src/deploy/analyzer/analyzer.js +93 -4
- 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 +128 -13
- 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.js +1 -1
- 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/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/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
|
@@ -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 };
|
|
@@ -236,7 +236,7 @@ export const scenarioRun = pikkuSessionlessFunc({
|
|
|
236
236
|
apiUrl: env.apiUrl,
|
|
237
237
|
appUrl: env.appUrl,
|
|
238
238
|
});
|
|
239
|
-
scenarioService.setRunSurface(runSurface);
|
|
239
|
+
scenarioService.setRunSurface(runSurface, strict);
|
|
240
240
|
// Scenario steps run here, not on the target — everything they touch of the
|
|
241
241
|
// app goes over HTTP through an actor, which is what `guardRpc` below
|
|
242
242
|
// enforces. `actor.converse` is the exception, and the reason this is not
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The frontmatter a skill adds to become a subagent as well as a skill.
|
|
3
|
+
*
|
|
4
|
+
* A skill is instructions a session reads; an agent is a child process a host
|
|
5
|
+
* dispatches and then judges. The difference is entirely the gate, so the gate is
|
|
6
|
+
* the only thing a skill has to declare — everything else about the agent is
|
|
7
|
+
* derived from the skill it already is.
|
|
8
|
+
*/
|
|
9
|
+
export interface SkillAgentSpec {
|
|
10
|
+
tools?: string;
|
|
11
|
+
timeoutMs?: number;
|
|
12
|
+
acceptance?: Record<string, unknown>;
|
|
13
|
+
}
|
|
14
|
+
interface SkillFrontmatter {
|
|
15
|
+
name?: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
agent?: SkillAgentSpec;
|
|
18
|
+
}
|
|
19
|
+
export declare function parseSkill(content: string): {
|
|
20
|
+
frontmatter: SkillFrontmatter;
|
|
21
|
+
body: string;
|
|
22
|
+
} | null;
|
|
23
|
+
/**
|
|
24
|
+
* Write out an agent for every installed skill that declares one.
|
|
25
|
+
*
|
|
26
|
+
* Skills without an `agent:` block are not projected: a reference skill has no
|
|
27
|
+
* post-condition a host could check, and an agent whose acceptance is `none` is a
|
|
28
|
+
* subagent dispatched to read something the caller could have read itself.
|
|
29
|
+
*/
|
|
30
|
+
export declare function installSkillAgents(skills: string[], agentRoot: string, skillDir: string, update: boolean, existing: (path: string) => boolean, read: (path: string) => Promise<string | null>,
|
|
31
|
+
/**
|
|
32
|
+
* Host extensions every projected agent loads, as pi resolves them.
|
|
33
|
+
*
|
|
34
|
+
* They are passed in rather than declared by the skill because they belong to
|
|
35
|
+
* whoever is running the agent, not to the instructions it follows: a sandbox
|
|
36
|
+
* fences its writers and routes their model, and the same skill run on a
|
|
37
|
+
* developer's own checkout needs neither.
|
|
38
|
+
*/
|
|
39
|
+
extensions?: string[]): Promise<{
|
|
40
|
+
written: string[];
|
|
41
|
+
skipped: string[];
|
|
42
|
+
}>;
|
|
43
|
+
export {};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { mkdir, writeFile } from 'fs/promises';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { parse, stringify } from 'yaml';
|
|
4
|
+
/**
|
|
5
|
+
* The tools that can change the workspace, and so decide the agent's role.
|
|
6
|
+
*
|
|
7
|
+
* `bash` counts because a shell is a superset of the rest: `sed -i`, `echo >` and
|
|
8
|
+
* `git checkout` all mutate without touching a file tool.
|
|
9
|
+
*/
|
|
10
|
+
const MUTATING_TOOLS = [
|
|
11
|
+
'bash',
|
|
12
|
+
'shell',
|
|
13
|
+
'write',
|
|
14
|
+
'edit',
|
|
15
|
+
'write_files',
|
|
16
|
+
'edit_files',
|
|
17
|
+
'patch',
|
|
18
|
+
];
|
|
19
|
+
const DEFAULT_TOOLS = 'read, write, edit, bash, grep';
|
|
20
|
+
/**
|
|
21
|
+
* The role is derived from the tools rather than declared beside them.
|
|
22
|
+
*
|
|
23
|
+
* It is what acceptance is inferred from, so a skill that declares the two
|
|
24
|
+
* independently can declare them inconsistently — a read-only role holding `write`
|
|
25
|
+
* is an agent the host judges by rules its tools do not match.
|
|
26
|
+
*/
|
|
27
|
+
function acceptanceRole(tools) {
|
|
28
|
+
const declared = tools.split(',').map((tool) => tool.trim());
|
|
29
|
+
return declared.some((tool) => MUTATING_TOOLS.includes(tool))
|
|
30
|
+
? 'writer'
|
|
31
|
+
: 'read-only';
|
|
32
|
+
}
|
|
33
|
+
const FRONTMATTER = /^---\n([\s\S]*?)\n---\n?([\s\S]*)$/;
|
|
34
|
+
export function parseSkill(content) {
|
|
35
|
+
const match = content.match(FRONTMATTER);
|
|
36
|
+
if (!match)
|
|
37
|
+
return null;
|
|
38
|
+
try {
|
|
39
|
+
return { frontmatter: parse(match[1]) ?? {}, body: match[2] ?? '' };
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The first paragraph of the skill's own description, as the one line a host shows
|
|
47
|
+
* when it is choosing between agents.
|
|
48
|
+
*
|
|
49
|
+
* A skill description is written for a trigger matcher and carries TRIGGER/DO NOT
|
|
50
|
+
* TRIGGER clauses that mean nothing to a dispatcher, so they are cut rather than
|
|
51
|
+
* shipped as noise into every agent listing.
|
|
52
|
+
*/
|
|
53
|
+
function agentDescription(description) {
|
|
54
|
+
return description
|
|
55
|
+
.split(/\bTRIGGER when\b|\bDO NOT TRIGGER\b/)[0]
|
|
56
|
+
.replace(/\s+/g, ' ')
|
|
57
|
+
.trim()
|
|
58
|
+
.replace(/[,;]\s*$/, '');
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* pi reads `acceptance` as a JSON string on one line, and ignores any frontmatter key
|
|
62
|
+
* it does not know — a post-condition under a key pi has no reader for runs nowhere and
|
|
63
|
+
* says nothing about it. Emitting through the one key pi acts on is what makes the gate
|
|
64
|
+
* real rather than decorative.
|
|
65
|
+
*/
|
|
66
|
+
function renderAgent(name, frontmatter, skillDir, extensions) {
|
|
67
|
+
const agent = frontmatter.agent;
|
|
68
|
+
const tools = agent.tools ?? DEFAULT_TOOLS;
|
|
69
|
+
const lines = [
|
|
70
|
+
'---',
|
|
71
|
+
`name: ${name}`,
|
|
72
|
+
`description: ${JSON.stringify(agentDescription(frontmatter.description ?? name))}`,
|
|
73
|
+
`tools: ${tools}`,
|
|
74
|
+
];
|
|
75
|
+
if (extensions.length > 0) {
|
|
76
|
+
lines.push(`extensions: ${extensions.join(', ')}`);
|
|
77
|
+
}
|
|
78
|
+
if (agent.acceptance) {
|
|
79
|
+
lines.push('acceptance:');
|
|
80
|
+
lines.push(stringify(agent.acceptance, { indent: 2 })
|
|
81
|
+
.trimEnd()
|
|
82
|
+
.split('\n')
|
|
83
|
+
.map((line) => ` ${line}`)
|
|
84
|
+
.join('\n'));
|
|
85
|
+
}
|
|
86
|
+
lines.push(`acceptanceRole: ${acceptanceRole(tools)}`);
|
|
87
|
+
if (agent.timeoutMs) {
|
|
88
|
+
lines.push(`timeoutMs: ${agent.timeoutMs}`);
|
|
89
|
+
}
|
|
90
|
+
lines.push('---', '');
|
|
91
|
+
const verify = (agent.acceptance?.verify ?? []);
|
|
92
|
+
lines.push(`Your instructions are \`${skillDir}/${name}/SKILL.md\`. Read it in full before you act, and follow it as written rather than improvising around it.`, '', 'Your caller dispatched you because this stage of the pipeline has a gate it can check, not because it wanted prose back. So the gate is the job.', '');
|
|
93
|
+
if (verify.length > 0) {
|
|
94
|
+
lines.push('You are not done until every one of these exits 0, and you have run them yourself:', '', ...verify.map((v) => `- \`${v.command}\``), '', 'A refusal is the gate working. Read what it says is wrong, fix that, and run it again — do not stop at the first one, and do not report success on a command you have not seen pass.', '');
|
|
95
|
+
}
|
|
96
|
+
lines.push('Report what you ran and what it said, what you changed, and anything in the skill that was wrong, missing or ambiguous. If you could not pass the gate, say so outright and say where you got stuck — a truthful failure is worth more to your caller than a pass it cannot trust.', '');
|
|
97
|
+
return lines.join('\n');
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Write out an agent for every installed skill that declares one.
|
|
101
|
+
*
|
|
102
|
+
* Skills without an `agent:` block are not projected: a reference skill has no
|
|
103
|
+
* post-condition a host could check, and an agent whose acceptance is `none` is a
|
|
104
|
+
* subagent dispatched to read something the caller could have read itself.
|
|
105
|
+
*/
|
|
106
|
+
export async function installSkillAgents(skills, agentRoot, skillDir, update, existing, read,
|
|
107
|
+
/**
|
|
108
|
+
* Host extensions every projected agent loads, as pi resolves them.
|
|
109
|
+
*
|
|
110
|
+
* They are passed in rather than declared by the skill because they belong to
|
|
111
|
+
* whoever is running the agent, not to the instructions it follows: a sandbox
|
|
112
|
+
* fences its writers and routes their model, and the same skill run on a
|
|
113
|
+
* developer's own checkout needs neither.
|
|
114
|
+
*/
|
|
115
|
+
extensions = []) {
|
|
116
|
+
const written = [];
|
|
117
|
+
const skipped = [];
|
|
118
|
+
for (const name of skills) {
|
|
119
|
+
const content = await read(`${name}/SKILL.md`);
|
|
120
|
+
if (content === null)
|
|
121
|
+
continue;
|
|
122
|
+
const parsed = parseSkill(content);
|
|
123
|
+
if (!parsed?.frontmatter.agent)
|
|
124
|
+
continue;
|
|
125
|
+
const target = join(agentRoot, `${name}.md`);
|
|
126
|
+
if (existing(target) && !update) {
|
|
127
|
+
skipped.push(name);
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
await mkdir(agentRoot, { recursive: true });
|
|
131
|
+
await writeFile(target, renderAgent(name, parsed.frontmatter, skillDir, extensions), 'utf-8');
|
|
132
|
+
written.push(name);
|
|
133
|
+
}
|
|
134
|
+
return { written, skipped };
|
|
135
|
+
}
|
|
@@ -12,6 +12,9 @@ export declare const pikkuSkillsInstall: import("#pikku/function").PikkuFunction
|
|
|
12
12
|
fabric?: boolean;
|
|
13
13
|
client?: boolean;
|
|
14
14
|
update?: boolean;
|
|
15
|
+
agentExtensions?: string;
|
|
16
|
+
agentDir?: string;
|
|
17
|
+
agentSkillDir?: string;
|
|
15
18
|
}, void, "rpc" | "session", import("#pikku/function").PikkuFunction<{
|
|
16
19
|
agent?: string;
|
|
17
20
|
only?: string;
|
|
@@ -19,6 +22,9 @@ export declare const pikkuSkillsInstall: import("#pikku/function").PikkuFunction
|
|
|
19
22
|
fabric?: boolean;
|
|
20
23
|
client?: boolean;
|
|
21
24
|
update?: boolean;
|
|
25
|
+
agentExtensions?: string;
|
|
26
|
+
agentDir?: string;
|
|
27
|
+
agentSkillDir?: string;
|
|
22
28
|
}, void, "rpc" | "session", import("#pikku/function").WiredServices> | import("#pikku/function").PikkuFunctionSessionless<{
|
|
23
29
|
agent?: string;
|
|
24
30
|
only?: string;
|
|
@@ -26,4 +32,7 @@ export declare const pikkuSkillsInstall: import("#pikku/function").PikkuFunction
|
|
|
26
32
|
fabric?: boolean;
|
|
27
33
|
client?: boolean;
|
|
28
34
|
update?: boolean;
|
|
35
|
+
agentExtensions?: string;
|
|
36
|
+
agentDir?: string;
|
|
37
|
+
agentSkillDir?: string;
|
|
29
38
|
}, void, "rpc" | "session", import("#pikku/function").WiredServices, unknown>, undefined, undefined>;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { readdir, mkdir, writeFile } from 'fs/promises';
|
|
2
2
|
import { existsSync } from 'fs';
|
|
3
|
-
import { dirname, join, sep } from 'path';
|
|
3
|
+
import { dirname, isAbsolute, join, sep } from 'path';
|
|
4
4
|
import { listSkillFiles, listSkillNames, readSkillFile } from '@pikku/skills';
|
|
5
|
+
import { installSkillAgents } from './skill-agents.js';
|
|
5
6
|
import { pikkuSessionlessFunc } from '#pikku/function';
|
|
6
7
|
/**
|
|
7
8
|
* Write one skill's files out to `dest`, reading through @pikku/skills rather
|
|
@@ -33,6 +34,17 @@ const AGENT_SKILL_DIRS = {
|
|
|
33
34
|
opencode: join('.opencode', 'skills'),
|
|
34
35
|
pi: join('.pi', 'skills'),
|
|
35
36
|
};
|
|
37
|
+
/**
|
|
38
|
+
* Where a harness that dispatches subagents reads them from.
|
|
39
|
+
*
|
|
40
|
+
* Only harnesses that can enforce a post-condition are listed. Installing an agent
|
|
41
|
+
* for a harness that cannot run its `acceptance` gate ships the instruction to verify
|
|
42
|
+
* with nothing that verifies, which reads as stricter than the skill it came from
|
|
43
|
+
* while being exactly as strict.
|
|
44
|
+
*/
|
|
45
|
+
const AGENT_DIRS = {
|
|
46
|
+
pi: join('.pi', 'agents'),
|
|
47
|
+
};
|
|
36
48
|
function parseInstallGroups(frontmatter) {
|
|
37
49
|
const inline = frontmatter.match(/^\s*installGroups\s*:\s*\[([^\]]*)\]/m);
|
|
38
50
|
if (inline) {
|
|
@@ -118,7 +130,7 @@ export const pikkuSkillsList = pikkuSessionlessFunc({
|
|
|
118
130
|
},
|
|
119
131
|
});
|
|
120
132
|
export const pikkuSkillsInstall = pikkuSessionlessFunc({
|
|
121
|
-
func: async ({ logger }, { agent = 'claude', only, core = false, fabric = false, client = false, update = false, }) => {
|
|
133
|
+
func: async ({ logger }, { agent = 'claude', only, core = false, fabric = false, client = false, update = false, agentExtensions, agentDir, agentSkillDir, }) => {
|
|
122
134
|
const supportedAgents = Object.keys(AGENT_SKILL_DIRS);
|
|
123
135
|
if (!supportedAgents.includes(agent)) {
|
|
124
136
|
logger.error(`Agent "${agent}" is not yet supported. Supported: ${supportedAgents.join(', ')}. ` +
|
|
@@ -156,5 +168,20 @@ export const pikkuSkillsInstall = pikkuSessionlessFunc({
|
|
|
156
168
|
logger.info(`Installed ${installed} skill(s) into ${destLabel}${skipped > 0
|
|
157
169
|
? ` (skipped ${skipped} already present — pass --update to overwrite)`
|
|
158
170
|
: ''}`);
|
|
171
|
+
const agentRelative = agentDir ?? AGENT_DIRS[agent];
|
|
172
|
+
if (!agentRelative)
|
|
173
|
+
return;
|
|
174
|
+
const projected = await installSkillAgents(wanted, isAbsolute(agentRelative)
|
|
175
|
+
? agentRelative
|
|
176
|
+
: join(process.cwd(), agentRelative), agentSkillDir ?? AGENT_SKILL_DIRS[agent].split(sep).join('/'), update, existsSync, readSkillFile, agentExtensions
|
|
177
|
+
?.split(',')
|
|
178
|
+
.map((path) => path.trim())
|
|
179
|
+
.filter(Boolean));
|
|
180
|
+
if (projected.written.length === 0 && projected.skipped.length === 0)
|
|
181
|
+
return;
|
|
182
|
+
const agentLabel = `${agentRelative.split(sep).join('/')}/`;
|
|
183
|
+
logger.info(`Projected ${projected.written.length} agent(s) into ${agentLabel}${projected.skipped.length > 0
|
|
184
|
+
? ` (skipped ${projected.skipped.length} already present — pass --update to overwrite)`
|
|
185
|
+
: ''}`);
|
|
159
186
|
},
|
|
160
187
|
});
|
|
@@ -27,6 +27,12 @@ export declare class PostgresIntrospector implements DbIntrospector {
|
|
|
27
27
|
*/
|
|
28
28
|
private getCheckEnums;
|
|
29
29
|
getForeignKeys(table: string): Promise<ForeignKeyInfo[]>;
|
|
30
|
+
/**
|
|
31
|
+
* `pk_cols` is fenced with `AS MATERIALIZED` deliberately. Referenced once,
|
|
32
|
+
* Postgres 12+ inlines it, and the constraint views it joins are then
|
|
33
|
+
* re-derived per candidate row — quadratic in the number of tables, minutes
|
|
34
|
+
* instead of milliseconds on a large schema.
|
|
35
|
+
*/
|
|
30
36
|
getAllColumns(): Promise<Map<string, ColumnInfo[]>>;
|
|
31
37
|
getAllForeignKeys(): Promise<Map<string, ForeignKeyInfo[]>>;
|
|
32
38
|
listEnums(): Promise<EnumInfo[]>;
|
|
@@ -167,8 +167,14 @@ export class PostgresIntrospector {
|
|
|
167
167
|
foreignColumn: r.foreign_column_name,
|
|
168
168
|
}));
|
|
169
169
|
}
|
|
170
|
+
/**
|
|
171
|
+
* `pk_cols` is fenced with `AS MATERIALIZED` deliberately. Referenced once,
|
|
172
|
+
* Postgres 12+ inlines it, and the constraint views it joins are then
|
|
173
|
+
* re-derived per candidate row — quadratic in the number of tables, minutes
|
|
174
|
+
* instead of milliseconds on a large schema.
|
|
175
|
+
*/
|
|
170
176
|
async getAllColumns() {
|
|
171
|
-
const result = await this.client.query(`WITH pk_cols AS (
|
|
177
|
+
const result = await this.client.query(`WITH pk_cols AS MATERIALIZED (
|
|
172
178
|
SELECT tc.table_schema, tc.table_name, kcu.column_name
|
|
173
179
|
FROM information_schema.table_constraints tc
|
|
174
180
|
JOIN information_schema.key_column_usage kcu
|
|
@@ -16,4 +16,4 @@ export declare const renderKnowledgePlanDefer: (_services: unknown, { ok, messag
|
|
|
16
16
|
* rendered as a picker: this is the fallback every harness has, and one that can do
|
|
17
17
|
* better reads the same answer as JSON.
|
|
18
18
|
*/
|
|
19
|
-
export declare const renderKnowledgeReconcile: (_services: unknown, { kind, reason, note, hold, notes, question }: KnowledgeReconcileResult) => void;
|
|
19
|
+
export declare const renderKnowledgeReconcile: (_services: unknown, { kind, reason, note, hold, notes, question, required, satisfied, }: KnowledgeReconcileResult) => void;
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import { added, changed, dim, removed } from '../../fabric/lib/output.js';
|
|
2
|
+
const ORPHANS_SHOWN = 10;
|
|
2
3
|
export const renderKnowledgeValidate = (_services, { ok, notes, findings }) => {
|
|
3
4
|
const errors = findings.filter((f) => f.severity === 'error');
|
|
4
5
|
const warns = findings.filter((f) => f.severity === 'warn');
|
|
5
6
|
const infos = findings.filter((f) => f.severity === 'info');
|
|
6
|
-
|
|
7
|
+
// Orphans are one finding each so a consumer can act on one at a time, but a
|
|
8
|
+
// project with no knowledge base yet reports every function it has — printing
|
|
9
|
+
// those in full buries the findings somebody can actually fix.
|
|
10
|
+
const orphans = infos.filter((f) => f.id.startsWith('knowledge-orphan-'));
|
|
11
|
+
const rest = infos.filter((f) => !f.id.startsWith('knowledge-orphan-'));
|
|
12
|
+
for (const finding of [...errors, ...warns, ...rest]) {
|
|
7
13
|
const icon = finding.severity === 'error'
|
|
8
14
|
? removed('✗')
|
|
9
15
|
: finding.severity === 'warn'
|
|
@@ -13,6 +19,18 @@ export const renderKnowledgeValidate = (_services, { ok, notes, findings }) => {
|
|
|
13
19
|
console.log(` ${dim('fix:')} ${finding.fixHint}`);
|
|
14
20
|
console.log();
|
|
15
21
|
}
|
|
22
|
+
if (orphans.length) {
|
|
23
|
+
const shown = orphans.slice(0, ORPHANS_SHOWN);
|
|
24
|
+
console.log(`${dim('ℹ')} ${orphans.length} thing${orphans.length !== 1 ? 's' : ''} in the code that no note describes`);
|
|
25
|
+
for (const orphan of shown) {
|
|
26
|
+
console.log(` ${dim(orphan.id.slice('knowledge-orphan-'.length))}`);
|
|
27
|
+
}
|
|
28
|
+
if (orphans.length > shown.length) {
|
|
29
|
+
console.log(` ${dim(`… and ${orphans.length - shown.length} more`)}`);
|
|
30
|
+
}
|
|
31
|
+
console.log(` ${dim('fix:')} ${shown[0].fixHint}`);
|
|
32
|
+
console.log();
|
|
33
|
+
}
|
|
16
34
|
const counts = [dim(`${notes} note${notes !== 1 ? 's' : ''}`)];
|
|
17
35
|
if (errors.length) {
|
|
18
36
|
counts.push(removed(`${errors.length} error${errors.length !== 1 ? 's' : ''}`));
|
|
@@ -148,7 +166,12 @@ export const renderKnowledgePlanDefer = (_services, { ok, message }) => {
|
|
|
148
166
|
* rendered as a picker: this is the fallback every harness has, and one that can do
|
|
149
167
|
* better reads the same answer as JSON.
|
|
150
168
|
*/
|
|
151
|
-
export const renderKnowledgeReconcile = (_services, { kind, reason, note, hold, notes, question }) => {
|
|
169
|
+
export const renderKnowledgeReconcile = (_services, { kind, reason, note, hold, notes, question, required, satisfied, }) => {
|
|
170
|
+
if (required && !satisfied) {
|
|
171
|
+
process.exitCode = 1;
|
|
172
|
+
console.log(`${removed('✗')} next is ${kind}, and this check requires ${required.join(' or ')}`);
|
|
173
|
+
console.log();
|
|
174
|
+
}
|
|
152
175
|
if (kind === 'idle') {
|
|
153
176
|
console.log(`${dim('=')} ${dim(reason)}`);
|
|
154
177
|
return;
|
|
@@ -94,7 +94,9 @@ export declare const KnowledgePlanDeferOutputSchema: import("zod").ZodObject<{
|
|
|
94
94
|
path: import("zod").ZodString;
|
|
95
95
|
message: import("zod").ZodString;
|
|
96
96
|
}, import("zod/v4/core").$strip>;
|
|
97
|
-
export declare const KnowledgeReconcileInputSchema: import("zod").ZodObject<{
|
|
97
|
+
export declare const KnowledgeReconcileInputSchema: import("zod").ZodObject<{
|
|
98
|
+
require: import("zod").ZodOptional<import("zod").ZodString>;
|
|
99
|
+
}, import("zod/v4/core").$strip>;
|
|
98
100
|
export declare const KnowledgeReconcileOutputSchema: import("zod").ZodObject<{
|
|
99
101
|
kind: import("zod").ZodEnum<{
|
|
100
102
|
"ask-user": "ask-user";
|
|
@@ -116,4 +118,6 @@ export declare const KnowledgeReconcileOutputSchema: import("zod").ZodObject<{
|
|
|
116
118
|
description: import("zod").ZodOptional<import("zod").ZodString>;
|
|
117
119
|
}, import("zod/v4/core").$strip>>>;
|
|
118
120
|
}, import("zod/v4/core").$strip>>;
|
|
121
|
+
satisfied: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
|
122
|
+
required: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>;
|
|
119
123
|
}, import("zod/v4/core").$strip>;
|
|
@@ -1,16 +1,43 @@
|
|
|
1
1
|
import { pikkuSessionlessFunc } from '#pikku/function';
|
|
2
|
+
import { existsSync, readdirSync, rmSync } from 'node:fs';
|
|
3
|
+
import { dirname, join } from 'path';
|
|
2
4
|
import { writeFileInDir } from '../../../utils/file-writer.js';
|
|
3
5
|
import { logCommandInfoAndTime } from '../../../middleware/log-command-info-and-time.js';
|
|
6
|
+
import { mcpSurfaceSlug } from '../../../utils/mcp-surface.js';
|
|
4
7
|
import { serializeMCPJson } from '@pikku/inspector';
|
|
5
8
|
export const pikkuMCPJSON = pikkuSessionlessFunc({
|
|
6
9
|
func: async ({ logger, config, getInspectorState }) => {
|
|
7
10
|
const state = await getInspectorState();
|
|
8
11
|
const mcpJsonFile = config.mcpJsonFile ?? config.clientFiles?.mcpJsonFile;
|
|
9
|
-
if (mcpJsonFile) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
if (!mcpJsonFile) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
await writeFileInDir(logger, mcpJsonFile, serializeMCPJson(logger, state), {
|
|
16
|
+
ignoreModifyComment: true,
|
|
17
|
+
});
|
|
18
|
+
// A project serving several MCP endpoints gets one manifest per endpoint,
|
|
19
|
+
// named after its surface, beside the default one. `deploy-apply` finds
|
|
20
|
+
// each by the slug in its unit's name, so the slug has to be built the
|
|
21
|
+
// same way here as it is in the analyzer.
|
|
22
|
+
const mcpDir = dirname(mcpJsonFile);
|
|
23
|
+
const surfaces = state.mcpEndpoints.surfaces ?? {};
|
|
24
|
+
const written = new Set();
|
|
25
|
+
for (const surface of Object.keys(surfaces)) {
|
|
26
|
+
const name = `mcp.${mcpSurfaceSlug(surface)}.gen.json`;
|
|
27
|
+
written.add(name);
|
|
28
|
+
await writeFileInDir(logger, join(mcpDir, name), serializeMCPJson(logger, state, surface), { ignoreModifyComment: true });
|
|
29
|
+
}
|
|
30
|
+
// A surface that has gone away leaves its manifest behind, and `pikku dev`
|
|
31
|
+
// mounts every manifest it finds — so without this, dropping `mcpEndpoint`
|
|
32
|
+
// keeps serving the endpoint it was supposed to remove, with whatever tool
|
|
33
|
+
// list it had on the last run that still wrote it.
|
|
34
|
+
if (existsSync(mcpDir)) {
|
|
35
|
+
for (const name of readdirSync(mcpDir)) {
|
|
36
|
+
if (!/^mcp\..+\.gen\.json$/.test(name) || written.has(name))
|
|
37
|
+
continue;
|
|
38
|
+
logger.debug(`Removing manifest for a surface that no longer exists: ${name}`);
|
|
39
|
+
rmSync(join(mcpDir, name));
|
|
40
|
+
}
|
|
14
41
|
}
|
|
15
42
|
},
|
|
16
43
|
middleware: [
|
|
@@ -27,6 +27,7 @@ export class BunServerRunner {
|
|
|
27
27
|
// Read off this options object by the transport, not off `config` — so it
|
|
28
28
|
// has to be forwarded here explicitly, exactly like the JWT above.
|
|
29
29
|
mcpJson: options.mcpJson,
|
|
30
|
+
mcpSurfaces: options.mcpSurfaces,
|
|
30
31
|
});
|
|
31
32
|
}
|
|
32
33
|
}
|
|
@@ -45,6 +45,19 @@ export type DevServerOptions = {
|
|
|
45
45
|
resources?: unknown[];
|
|
46
46
|
prompts?: unknown[];
|
|
47
47
|
};
|
|
48
|
+
/**
|
|
49
|
+
* The further MCP endpoints this project serves, one per surface, each with
|
|
50
|
+
* the path it answers on. Forwarded the same way and with the same
|
|
51
|
+
* consequence for forgetting: the surface 404s with no error anywhere.
|
|
52
|
+
*/
|
|
53
|
+
mcpSurfaces?: Array<{
|
|
54
|
+
mcpJson: {
|
|
55
|
+
tools?: unknown[];
|
|
56
|
+
resources?: unknown[];
|
|
57
|
+
prompts?: unknown[];
|
|
58
|
+
};
|
|
59
|
+
mcpPath: string;
|
|
60
|
+
}>;
|
|
48
61
|
};
|
|
49
62
|
export interface DevServerRunner {
|
|
50
63
|
/**
|
|
@@ -47,6 +47,7 @@ export class NodeServerRunner {
|
|
|
47
47
|
// Read off this options object by the transport, not off `config` — so it
|
|
48
48
|
// has to be forwarded here explicitly, exactly like the JWT above.
|
|
49
49
|
mcpJson: options.mcpJson,
|
|
50
|
+
mcpSurfaces: options.mcpSurfaces,
|
|
50
51
|
});
|
|
51
52
|
return {
|
|
52
53
|
init: () => server.init(),
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The slug a surface's manifest filename and its deploy unit name are both
|
|
3
|
+
* built from. `deploy-apply` recovers the filename by stripping `mcp-` off the
|
|
4
|
+
* unit name, so codegen and the analyzer have to agree on it exactly or a
|
|
5
|
+
* deployed unit reads a manifest nobody wrote — hence one function, not the
|
|
6
|
+
* same expression written twice.
|
|
7
|
+
*/
|
|
8
|
+
export declare const mcpSurfaceSlug: (surface: string) => string;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { toSafeKebab } from '../deploy/analyzer/naming.js';
|
|
2
|
+
/**
|
|
3
|
+
* The slug a surface's manifest filename and its deploy unit name are both
|
|
4
|
+
* built from. `deploy-apply` recovers the filename by stripping `mcp-` off the
|
|
5
|
+
* unit name, so codegen and the analyzer have to agree on it exactly or a
|
|
6
|
+
* deployed unit reads a manifest nobody wrote — hence one function, not the
|
|
7
|
+
* same expression written twice.
|
|
8
|
+
*/
|
|
9
|
+
export const mcpSurfaceSlug = (surface) => toSafeKebab(surface);
|