@canonical/pragma-cli 0.34.0 → 0.35.0
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/README.md +153 -30
- package/dist/.build-ok +0 -0
- package/dist/package.json +83 -0
- package/dist/pragma.conf.js +814 -0
- package/dist/pragma.conf.js.map +1 -0
- package/dist/src/bin.js +356 -0
- package/dist/src/bin.js.map +1 -0
- package/dist/src/capabilities/capabilities/capabilities.render.js +70 -0
- package/dist/src/capabilities/capabilities/capabilities.render.js.map +1 -0
- package/dist/src/capabilities/capabilities/capabilities.verb.js +59 -0
- package/dist/src/capabilities/capabilities/capabilities.verb.js.map +1 -0
- package/dist/src/capabilities/capabilities/catalog.js +130 -0
- package/dist/src/capabilities/capabilities/catalog.js.map +1 -0
- package/dist/src/capabilities/capabilities/hints.js +195 -0
- package/dist/src/capabilities/capabilities/hints.js.map +1 -0
- package/dist/src/capabilities/capabilities/index.js +11 -0
- package/dist/src/capabilities/capabilities/index.js.map +1 -0
- package/dist/src/capabilities/capabilities/types.js +11 -0
- package/dist/src/capabilities/capabilities/types.js.map +1 -0
- package/dist/src/capabilities/colophon/collectColophon.js +83 -0
- package/dist/src/capabilities/colophon/collectColophon.js.map +1 -0
- package/dist/src/capabilities/colophon/colophon.render.js +59 -0
- package/dist/src/capabilities/colophon/colophon.render.js.map +1 -0
- package/dist/src/capabilities/colophon/colophon.verb.js +43 -0
- package/dist/src/capabilities/colophon/colophon.verb.js.map +1 -0
- package/dist/src/capabilities/colophon/index.js +5 -0
- package/dist/src/capabilities/colophon/index.js.map +1 -0
- package/dist/src/capabilities/colophon/markdownTerminal.js +90 -0
- package/dist/src/capabilities/colophon/markdownTerminal.js.map +1 -0
- package/dist/src/capabilities/colophon/types.js +10 -0
- package/dist/src/capabilities/colophon/types.js.map +1 -0
- package/dist/src/capabilities/config/collectConfigShow.js +59 -0
- package/dist/src/capabilities/config/collectConfigShow.js.map +1 -0
- package/dist/src/capabilities/config/field.render.js +22 -0
- package/dist/src/capabilities/config/field.render.js.map +1 -0
- package/dist/src/capabilities/config/fields.js +46 -0
- package/dist/src/capabilities/config/fields.js.map +1 -0
- package/dist/src/capabilities/config/get.verb.js +61 -0
- package/dist/src/capabilities/config/get.verb.js.map +1 -0
- package/dist/src/capabilities/config/index.js +5 -0
- package/dist/src/capabilities/config/index.js.map +1 -0
- package/dist/src/capabilities/config/runField.js +59 -0
- package/dist/src/capabilities/config/runField.js.map +1 -0
- package/dist/src/capabilities/config/runGet.js +28 -0
- package/dist/src/capabilities/config/runGet.js.map +1 -0
- package/dist/src/capabilities/config/runSet.js +53 -0
- package/dist/src/capabilities/config/runSet.js.map +1 -0
- package/dist/src/capabilities/config/set.verb.js +66 -0
- package/dist/src/capabilities/config/set.verb.js.map +1 -0
- package/dist/src/capabilities/config/show.render.js +84 -0
- package/dist/src/capabilities/config/show.render.js.map +1 -0
- package/dist/src/capabilities/config/show.verb.js +44 -0
- package/dist/src/capabilities/config/show.verb.js.map +1 -0
- package/dist/src/capabilities/config/types.js +5 -0
- package/dist/src/capabilities/config/types.js.map +1 -0
- package/dist/src/capabilities/config/unset.verb.js +49 -0
- package/dist/src/capabilities/config/unset.verb.js.map +1 -0
- package/dist/src/capabilities/create/cliProjection.js +195 -0
- package/dist/src/capabilities/create/cliProjection.js.map +1 -0
- package/dist/src/capabilities/create/constants.js +47 -0
- package/dist/src/capabilities/create/constants.js.map +1 -0
- package/dist/src/capabilities/create/create.render.js +100 -0
- package/dist/src/capabilities/create/create.render.js.map +1 -0
- package/dist/src/capabilities/create/create.verb.js +438 -0
- package/dist/src/capabilities/create/create.verb.js.map +1 -0
- package/dist/src/capabilities/create/createHelp.js +47 -0
- package/dist/src/capabilities/create/createHelp.js.map +1 -0
- package/dist/src/capabilities/create/createSurface.generated.js +394 -0
- package/dist/src/capabilities/create/createSurface.generated.js.map +1 -0
- package/dist/src/capabilities/create/generatorToVerbSpec.js +106 -0
- package/dist/src/capabilities/create/generatorToVerbSpec.js.map +1 -0
- package/dist/src/capabilities/create/index.js +18 -0
- package/dist/src/capabilities/create/index.js.map +1 -0
- package/dist/src/capabilities/create/messages.js +16 -0
- package/dist/src/capabilities/create/messages.js.map +1 -0
- package/dist/src/capabilities/create/mount.js +293 -0
- package/dist/src/capabilities/create/mount.js.map +1 -0
- package/dist/src/capabilities/create/pathJail.js +65 -0
- package/dist/src/capabilities/create/pathJail.js.map +1 -0
- package/dist/src/capabilities/create/pickGenerator.js +53 -0
- package/dist/src/capabilities/create/pickGenerator.js.map +1 -0
- package/dist/src/capabilities/create/types.js +2 -0
- package/dist/src/capabilities/create/types.js.map +1 -0
- package/dist/src/capabilities/distribution.js +40 -0
- package/dist/src/capabilities/distribution.js.map +1 -0
- package/dist/src/capabilities/doctor/checks/checkKeStore.js +40 -0
- package/dist/src/capabilities/doctor/checks/checkKeStore.js.map +1 -0
- package/dist/src/capabilities/doctor/checks/checkNodeVersion.js +21 -0
- package/dist/src/capabilities/doctor/checks/checkNodeVersion.js.map +1 -0
- package/dist/src/capabilities/doctor/checks/checkPackageRefs.js +92 -0
- package/dist/src/capabilities/doctor/checks/checkPackageRefs.js.map +1 -0
- package/dist/src/capabilities/doctor/checks/checkPragmaVersion.js +19 -0
- package/dist/src/capabilities/doctor/checks/checkPragmaVersion.js.map +1 -0
- package/dist/src/capabilities/doctor/checks/checkShellCompletions.js +199 -0
- package/dist/src/capabilities/doctor/checks/checkShellCompletions.js.map +1 -0
- package/dist/src/capabilities/doctor/checks/index.js +27 -0
- package/dist/src/capabilities/doctor/checks/index.js.map +1 -0
- package/dist/src/capabilities/doctor/checks/mcpCommand.js +57 -0
- package/dist/src/capabilities/doctor/checks/mcpCommand.js.map +1 -0
- package/dist/src/capabilities/doctor/checks/targetHealth.js +205 -0
- package/dist/src/capabilities/doctor/checks/targetHealth.js.map +1 -0
- package/dist/src/capabilities/doctor/doctor.render.js +185 -0
- package/dist/src/capabilities/doctor/doctor.render.js.map +1 -0
- package/dist/src/capabilities/doctor/doctor.verb.js +45 -0
- package/dist/src/capabilities/doctor/doctor.verb.js.map +1 -0
- package/dist/src/capabilities/doctor/index.js +5 -0
- package/dist/src/capabilities/doctor/index.js.map +1 -0
- package/dist/src/capabilities/doctor/runChecks.js +83 -0
- package/dist/src/capabilities/doctor/runChecks.js.map +1 -0
- package/dist/src/capabilities/doctor/types.js +5 -0
- package/dist/src/capabilities/doctor/types.js.map +1 -0
- package/dist/src/capabilities/graph/index.js +19 -0
- package/dist/src/capabilities/graph/index.js.map +1 -0
- package/dist/src/capabilities/graph/inspect.render.js +76 -0
- package/dist/src/capabilities/graph/inspect.render.js.map +1 -0
- package/dist/src/capabilities/graph/inspect.verb.js +53 -0
- package/dist/src/capabilities/graph/inspect.verb.js.map +1 -0
- package/dist/src/capabilities/graph/query.render.js +73 -0
- package/dist/src/capabilities/graph/query.render.js.map +1 -0
- package/dist/src/capabilities/graph/query.verb.js +49 -0
- package/dist/src/capabilities/graph/query.verb.js.map +1 -0
- package/dist/src/capabilities/graph/runQuery.js +41 -0
- package/dist/src/capabilities/graph/runQuery.js.map +1 -0
- package/dist/src/capabilities/index.js +56 -0
- package/dist/src/capabilities/index.js.map +1 -0
- package/dist/src/capabilities/info/collectInfo.js +66 -0
- package/dist/src/capabilities/info/collectInfo.js.map +1 -0
- package/dist/src/capabilities/info/index.js +5 -0
- package/dist/src/capabilities/info/index.js.map +1 -0
- package/dist/src/capabilities/info/info.render.js +53 -0
- package/dist/src/capabilities/info/info.render.js.map +1 -0
- package/dist/src/capabilities/info/info.verb.js +42 -0
- package/dist/src/capabilities/info/info.verb.js.map +1 -0
- package/dist/src/capabilities/info/types.js +5 -0
- package/dist/src/capabilities/info/types.js.map +1 -0
- package/dist/src/capabilities/meta/complete.verb.js +43 -0
- package/dist/src/capabilities/meta/complete.verb.js.map +1 -0
- package/dist/src/capabilities/meta/index.js +13 -0
- package/dist/src/capabilities/meta/index.js.map +1 -0
- package/dist/src/capabilities/meta/mcp.verb.js +34 -0
- package/dist/src/capabilities/meta/mcp.verb.js.map +1 -0
- package/dist/src/capabilities/ontology/index.js +21 -0
- package/dist/src/capabilities/ontology/index.js.map +1 -0
- package/dist/src/capabilities/ontology/queries.js +123 -0
- package/dist/src/capabilities/ontology/queries.js.map +1 -0
- package/dist/src/capabilities/ontology/render.js +66 -0
- package/dist/src/capabilities/ontology/render.js.map +1 -0
- package/dist/src/capabilities/ontology/verbs.js +181 -0
- package/dist/src/capabilities/ontology/verbs.js.map +1 -0
- package/dist/src/capabilities/prompt/index.js +16 -0
- package/dist/src/capabilities/prompt/index.js.map +1 -0
- package/dist/src/capabilities/prompt/prompt.render.js +78 -0
- package/dist/src/capabilities/prompt/prompt.render.js.map +1 -0
- package/dist/src/capabilities/prompt/types.js +10 -0
- package/dist/src/capabilities/prompt/types.js.map +1 -0
- package/dist/src/capabilities/prompt/verbs.js +93 -0
- package/dist/src/capabilities/prompt/verbs.js.map +1 -0
- package/dist/src/capabilities/resources/index.js +10 -0
- package/dist/src/capabilities/resources/index.js.map +1 -0
- package/dist/src/capabilities/resources/provider.js +423 -0
- package/dist/src/capabilities/resources/provider.js.map +1 -0
- package/dist/src/capabilities/setup/buildPlan.js +168 -0
- package/dist/src/capabilities/setup/buildPlan.js.map +1 -0
- package/dist/src/capabilities/setup/index.js +5 -0
- package/dist/src/capabilities/setup/index.js.map +1 -0
- package/dist/src/capabilities/setup/mode.js +53 -0
- package/dist/src/capabilities/setup/mode.js.map +1 -0
- package/dist/src/capabilities/setup/operations/index.js +39 -0
- package/dist/src/capabilities/setup/operations/index.js.map +1 -0
- package/dist/src/capabilities/setup/operations/setupCompletions.js +160 -0
- package/dist/src/capabilities/setup/operations/setupCompletions.js.map +1 -0
- package/dist/src/capabilities/setup/operations/setupConfig.js +101 -0
- package/dist/src/capabilities/setup/operations/setupConfig.js.map +1 -0
- package/dist/src/capabilities/setup/operations/setupGenerator.js +343 -0
- package/dist/src/capabilities/setup/operations/setupGenerator.js.map +1 -0
- package/dist/src/capabilities/setup/operations/setupLsp.js +277 -0
- package/dist/src/capabilities/setup/operations/setupLsp.js.map +1 -0
- package/dist/src/capabilities/setup/operations/setupMcp.js +207 -0
- package/dist/src/capabilities/setup/operations/setupMcp.js.map +1 -0
- package/dist/src/capabilities/setup/operations/setupSkills.js +316 -0
- package/dist/src/capabilities/setup/operations/setupSkills.js.map +1 -0
- package/dist/src/capabilities/setup/plan.js +128 -0
- package/dist/src/capabilities/setup/plan.js.map +1 -0
- package/dist/src/capabilities/setup/plan.render.js +193 -0
- package/dist/src/capabilities/setup/plan.render.js.map +1 -0
- package/dist/src/capabilities/setup/setup.render.js +54 -0
- package/dist/src/capabilities/setup/setup.render.js.map +1 -0
- package/dist/src/capabilities/setup/setup.verb.js +334 -0
- package/dist/src/capabilities/setup/setup.verb.js.map +1 -0
- package/dist/src/capabilities/setup/shell.js +196 -0
- package/dist/src/capabilities/setup/shell.js.map +1 -0
- package/dist/src/capabilities/setup/targets.js +263 -0
- package/dist/src/capabilities/setup/targets.js.map +1 -0
- package/dist/src/capabilities/setup/types.js +5 -0
- package/dist/src/capabilities/setup/types.js.map +1 -0
- package/dist/src/capabilities/shared/assertExecOk.js +137 -0
- package/dist/src/capabilities/shared/assertExecOk.js.map +1 -0
- package/dist/src/capabilities/shared/bands.js +16 -0
- package/dist/src/capabilities/shared/bands.js.map +1 -0
- package/dist/src/capabilities/shared/index.js +26 -0
- package/dist/src/capabilities/shared/index.js.map +1 -0
- package/dist/src/capabilities/shared/packageManager.js +103 -0
- package/dist/src/capabilities/shared/packageManager.js.map +1 -0
- package/dist/src/capabilities/shared/registry.js +55 -0
- package/dist/src/capabilities/shared/registry.js.map +1 -0
- package/dist/src/capabilities/skill/discover.js +195 -0
- package/dist/src/capabilities/skill/discover.js.map +1 -0
- package/dist/src/capabilities/skill/index.js +10 -0
- package/dist/src/capabilities/skill/index.js.map +1 -0
- package/dist/src/capabilities/skill/render.js +49 -0
- package/dist/src/capabilities/skill/render.js.map +1 -0
- package/dist/src/capabilities/skill/verbs.js +83 -0
- package/dist/src/capabilities/skill/verbs.js.map +1 -0
- package/dist/src/capabilities/sources/collectStatus.js +103 -0
- package/dist/src/capabilities/sources/collectStatus.js.map +1 -0
- package/dist/src/capabilities/sources/index.js +13 -0
- package/dist/src/capabilities/sources/index.js.map +1 -0
- package/dist/src/capabilities/sources/installSkills.js +167 -0
- package/dist/src/capabilities/sources/installSkills.js.map +1 -0
- package/dist/src/capabilities/sources/runUpdate.js +394 -0
- package/dist/src/capabilities/sources/runUpdate.js.map +1 -0
- package/dist/src/capabilities/sources/status.render.js +64 -0
- package/dist/src/capabilities/sources/status.render.js.map +1 -0
- package/dist/src/capabilities/sources/status.verb.js +40 -0
- package/dist/src/capabilities/sources/status.verb.js.map +1 -0
- package/dist/src/capabilities/sources/types.js +6 -0
- package/dist/src/capabilities/sources/types.js.map +1 -0
- package/dist/src/capabilities/sources/update.render.js +34 -0
- package/dist/src/capabilities/sources/update.render.js.map +1 -0
- package/dist/src/capabilities/sources/update.verb.js +55 -0
- package/dist/src/capabilities/sources/update.verb.js.map +1 -0
- package/dist/src/capabilities/upgrade/index.js +5 -0
- package/dist/src/capabilities/upgrade/index.js.map +1 -0
- package/dist/src/capabilities/upgrade/runUpgrade.js +99 -0
- package/dist/src/capabilities/upgrade/runUpgrade.js.map +1 -0
- package/dist/src/capabilities/upgrade/types.js +5 -0
- package/dist/src/capabilities/upgrade/types.js.map +1 -0
- package/dist/src/capabilities/upgrade/upgrade.render.js +44 -0
- package/dist/src/capabilities/upgrade/upgrade.render.js.map +1 -0
- package/dist/src/capabilities/upgrade/upgrade.verb.js +52 -0
- package/dist/src/capabilities/upgrade/upgrade.verb.js.map +1 -0
- package/dist/src/capabilities/version/index.js +10 -0
- package/dist/src/capabilities/version/index.js.map +1 -0
- package/dist/src/capabilities/version/version.verb.js +36 -0
- package/dist/src/capabilities/version/version.verb.js.map +1 -0
- package/dist/src/constants.js +82 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/index.js +12 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/kernel/completion/complete.js +66 -0
- package/dist/src/kernel/completion/complete.js.map +1 -0
- package/dist/src/kernel/completion/emitScripts.js +92 -0
- package/dist/src/kernel/completion/emitScripts.js.map +1 -0
- package/dist/src/kernel/completion/entitySource.js +285 -0
- package/dist/src/kernel/completion/entitySource.js.map +1 -0
- package/dist/src/kernel/completion/index.js +14 -0
- package/dist/src/kernel/completion/index.js.map +1 -0
- package/dist/src/kernel/completion/model.js +301 -0
- package/dist/src/kernel/completion/model.js.map +1 -0
- package/dist/src/kernel/completion/parse.js +253 -0
- package/dist/src/kernel/completion/parse.js.map +1 -0
- package/dist/src/kernel/completion/rank.js +101 -0
- package/dist/src/kernel/completion/rank.js.map +1 -0
- package/dist/src/kernel/completion/resolve.js +100 -0
- package/dist/src/kernel/completion/resolve.js.map +1 -0
- package/dist/src/kernel/completion/templates/bash.js +209 -0
- package/dist/src/kernel/completion/templates/bash.js.map +1 -0
- package/dist/src/kernel/completion/templates/fish.js +214 -0
- package/dist/src/kernel/completion/templates/fish.js.map +1 -0
- package/dist/src/kernel/completion/templates/index.js +23 -0
- package/dist/src/kernel/completion/templates/index.js.map +1 -0
- package/dist/src/kernel/completion/templates/shared.js +98 -0
- package/dist/src/kernel/completion/templates/shared.js.map +1 -0
- package/dist/src/kernel/completion/templates/zsh.js +201 -0
- package/dist/src/kernel/completion/templates/zsh.js.map +1 -0
- package/dist/src/kernel/completion/types.js +13 -0
- package/dist/src/kernel/completion/types.js.map +1 -0
- package/dist/src/kernel/config/defaults.js +17 -0
- package/dist/src/kernel/config/defaults.js.map +1 -0
- package/dist/src/kernel/config/evaluateProjectConfig.js +126 -0
- package/dist/src/kernel/config/evaluateProjectConfig.js.map +1 -0
- package/dist/src/kernel/config/findProjectConfig.js +43 -0
- package/dist/src/kernel/config/findProjectConfig.js.map +1 -0
- package/dist/src/kernel/config/firstRun.js +34 -0
- package/dist/src/kernel/config/firstRun.js.map +1 -0
- package/dist/src/kernel/config/globalConfig.js +79 -0
- package/dist/src/kernel/config/globalConfig.js.map +1 -0
- package/dist/src/kernel/config/index.js +16 -0
- package/dist/src/kernel/config/index.js.map +1 -0
- package/dist/src/kernel/config/paths.js +35 -0
- package/dist/src/kernel/config/paths.js.map +1 -0
- package/dist/src/kernel/config/readConfig.js +78 -0
- package/dist/src/kernel/config/readConfig.js.map +1 -0
- package/dist/src/kernel/config/schema.js +130 -0
- package/dist/src/kernel/config/schema.js.map +1 -0
- package/dist/src/kernel/config/types.js +19 -0
- package/dist/src/kernel/config/types.js.map +1 -0
- package/dist/src/kernel/config/writeConfigField.js +59 -0
- package/dist/src/kernel/config/writeConfigField.js.map +1 -0
- package/dist/src/kernel/copy.js +43 -0
- package/dist/src/kernel/copy.js.map +1 -0
- package/dist/src/kernel/error/PragmaError.js +149 -0
- package/dist/src/kernel/error/PragmaError.js.map +1 -0
- package/dist/src/kernel/error/constants.js +40 -0
- package/dist/src/kernel/error/constants.js.map +1 -0
- package/dist/src/kernel/error/fromTaskError.js +96 -0
- package/dist/src/kernel/error/fromTaskError.js.map +1 -0
- package/dist/src/kernel/error/index.js +13 -0
- package/dist/src/kernel/error/index.js.map +1 -0
- package/dist/src/kernel/error/recovery.js +52 -0
- package/dist/src/kernel/error/recovery.js.map +1 -0
- package/dist/src/kernel/error/renderError.js +115 -0
- package/dist/src/kernel/error/renderError.js.map +1 -0
- package/dist/src/kernel/error/serialize.js +25 -0
- package/dist/src/kernel/error/serialize.js.map +1 -0
- package/dist/src/kernel/error/types.js +9 -0
- package/dist/src/kernel/error/types.js.map +1 -0
- package/dist/src/kernel/index.js +25 -0
- package/dist/src/kernel/index.js.map +1 -0
- package/dist/src/kernel/packs/collect.js +187 -0
- package/dist/src/kernel/packs/collect.js.map +1 -0
- package/dist/src/kernel/packs/compile.js +304 -0
- package/dist/src/kernel/packs/compile.js.map +1 -0
- package/dist/src/kernel/packs/disclosure.js +76 -0
- package/dist/src/kernel/packs/disclosure.js.map +1 -0
- package/dist/src/kernel/packs/glob.js +38 -0
- package/dist/src/kernel/packs/glob.js.map +1 -0
- package/dist/src/kernel/packs/graphql/buildLookupDocument.js +258 -0
- package/dist/src/kernel/packs/graphql/buildLookupDocument.js.map +1 -0
- package/dist/src/kernel/packs/graphql/fetchGraphqlLookup.js +157 -0
- package/dist/src/kernel/packs/graphql/fetchGraphqlLookup.js.map +1 -0
- package/dist/src/kernel/packs/graphql/index.js +20 -0
- package/dist/src/kernel/packs/graphql/index.js.map +1 -0
- package/dist/src/kernel/packs/graphql/nameMap.js +63 -0
- package/dist/src/kernel/packs/graphql/nameMap.js.map +1 -0
- package/dist/src/kernel/packs/index.js +34 -0
- package/dist/src/kernel/packs/index.js.map +1 -0
- package/dist/src/kernel/packs/iri.js +110 -0
- package/dist/src/kernel/packs/iri.js.map +1 -0
- package/dist/src/kernel/packs/renderPack.js +129 -0
- package/dist/src/kernel/packs/renderPack.js.map +1 -0
- package/dist/src/kernel/packs/resolveEntity.js +223 -0
- package/dist/src/kernel/packs/resolveEntity.js.map +1 -0
- package/dist/src/kernel/packs/runBodies.js +87 -0
- package/dist/src/kernel/packs/runBodies.js.map +1 -0
- package/dist/src/kernel/packs/sample.js +56 -0
- package/dist/src/kernel/packs/sample.js.map +1 -0
- package/dist/src/kernel/packs/schema.js +369 -0
- package/dist/src/kernel/packs/schema.js.map +1 -0
- package/dist/src/kernel/packs/sparql/applyFilters.js +68 -0
- package/dist/src/kernel/packs/sparql/applyFilters.js.map +1 -0
- package/dist/src/kernel/packs/sparql/applySearch.js +25 -0
- package/dist/src/kernel/packs/sparql/applySearch.js.map +1 -0
- package/dist/src/kernel/packs/sparql/buildLookupQuery.js +217 -0
- package/dist/src/kernel/packs/sparql/buildLookupQuery.js.map +1 -0
- package/dist/src/kernel/packs/sparql/escape.js +21 -0
- package/dist/src/kernel/packs/sparql/escape.js.map +1 -0
- package/dist/src/kernel/packs/sparql/index.js +31 -0
- package/dist/src/kernel/packs/sparql/index.js.map +1 -0
- package/dist/src/kernel/packs/sparql/runSelect.js +101 -0
- package/dist/src/kernel/packs/sparql/runSelect.js.map +1 -0
- package/dist/src/kernel/packs/types.js +30 -0
- package/dist/src/kernel/packs/types.js.map +1 -0
- package/dist/src/kernel/packs/uniqueness.js +30 -0
- package/dist/src/kernel/packs/uniqueness.js.map +1 -0
- package/dist/src/kernel/project/cli/buildProgram.js +263 -0
- package/dist/src/kernel/project/cli/buildProgram.js.map +1 -0
- package/dist/src/kernel/project/cli/constants.js +27 -0
- package/dist/src/kernel/project/cli/constants.js.map +1 -0
- package/dist/src/kernel/project/cli/dispatch.js +420 -0
- package/dist/src/kernel/project/cli/dispatch.js.map +1 -0
- package/dist/src/kernel/project/cli/exitCodes.js +66 -0
- package/dist/src/kernel/project/cli/exitCodes.js.map +1 -0
- package/dist/src/kernel/project/cli/globalFlags.js +216 -0
- package/dist/src/kernel/project/cli/globalFlags.js.map +1 -0
- package/dist/src/kernel/project/cli/helpFormat.js +59 -0
- package/dist/src/kernel/project/cli/helpFormat.js.map +1 -0
- package/dist/src/kernel/project/cli/index.js +14 -0
- package/dist/src/kernel/project/cli/index.js.map +1 -0
- package/dist/src/kernel/project/cli/rootHelp.js +197 -0
- package/dist/src/kernel/project/cli/rootHelp.js.map +1 -0
- package/dist/src/kernel/project/cli/suggest.js +75 -0
- package/dist/src/kernel/project/cli/suggest.js.map +1 -0
- package/dist/src/kernel/project/cli/suggestNames.js +96 -0
- package/dist/src/kernel/project/cli/suggestNames.js.map +1 -0
- package/dist/src/kernel/project/cli/verbHelp.js +131 -0
- package/dist/src/kernel/project/cli/verbHelp.js.map +1 -0
- package/dist/src/kernel/project/mcp/buildServer.js +67 -0
- package/dist/src/kernel/project/mcp/buildServer.js.map +1 -0
- package/dist/src/kernel/project/mcp/envelope.js +37 -0
- package/dist/src/kernel/project/mcp/envelope.js.map +1 -0
- package/dist/src/kernel/project/mcp/index.js +8 -0
- package/dist/src/kernel/project/mcp/index.js.map +1 -0
- package/dist/src/kernel/project/mcp/instructions.js +44 -0
- package/dist/src/kernel/project/mcp/instructions.js.map +1 -0
- package/dist/src/kernel/project/mcp/mcpError.js +42 -0
- package/dist/src/kernel/project/mcp/mcpError.js.map +1 -0
- package/dist/src/kernel/project/mcp/prompts/index.js +36 -0
- package/dist/src/kernel/project/mcp/prompts/index.js.map +1 -0
- package/dist/src/kernel/project/mcp/prompts/provider.js +98 -0
- package/dist/src/kernel/project/mcp/prompts/provider.js.map +1 -0
- package/dist/src/kernel/project/mcp/prompts/source.js +154 -0
- package/dist/src/kernel/project/mcp/prompts/source.js.map +1 -0
- package/dist/src/kernel/project/mcp/registerVerb.js +300 -0
- package/dist/src/kernel/project/mcp/registerVerb.js.map +1 -0
- package/dist/src/kernel/project/mcp/serve.js +35 -0
- package/dist/src/kernel/project/mcp/serve.js.map +1 -0
- package/dist/src/kernel/render/compactUri.js +24 -0
- package/dist/src/kernel/render/compactUri.js.map +1 -0
- package/dist/src/kernel/render/contracts.js +10 -0
- package/dist/src/kernel/render/contracts.js.map +1 -0
- package/dist/src/kernel/render/disclosure.js +34 -0
- package/dist/src/kernel/render/disclosure.js.map +1 -0
- package/dist/src/kernel/render/envelope.js +30 -0
- package/dist/src/kernel/render/envelope.js.map +1 -0
- package/dist/src/kernel/render/formatters.js +27 -0
- package/dist/src/kernel/render/formatters.js.map +1 -0
- package/dist/src/kernel/render/index.js +15 -0
- package/dist/src/kernel/render/index.js.map +1 -0
- package/dist/src/kernel/render/prefixes.js +46 -0
- package/dist/src/kernel/render/prefixes.js.map +1 -0
- package/dist/src/kernel/render/renderers.js +468 -0
- package/dist/src/kernel/render/renderers.js.map +1 -0
- package/dist/src/kernel/render/style.js +85 -0
- package/dist/src/kernel/render/style.js.map +1 -0
- package/dist/src/kernel/render/turtle.js +194 -0
- package/dist/src/kernel/render/turtle.js.map +1 -0
- package/dist/src/kernel/render/writeStdout.js +43 -0
- package/dist/src/kernel/render/writeStdout.js.map +1 -0
- package/dist/src/kernel/runtime/boot.js +49 -0
- package/dist/src/kernel/runtime/boot.js.map +1 -0
- package/dist/src/kernel/runtime/facade.js +39 -0
- package/dist/src/kernel/runtime/facade.js.map +1 -0
- package/dist/src/kernel/runtime/graphpack/build.js +122 -0
- package/dist/src/kernel/runtime/graphpack/build.js.map +1 -0
- package/dist/src/kernel/runtime/graphpack/buildIndex.js +303 -0
- package/dist/src/kernel/runtime/graphpack/buildIndex.js.map +1 -0
- package/dist/src/kernel/runtime/graphpack/embedded/pack.generated.js +6 -0
- package/dist/src/kernel/runtime/graphpack/embedded/pack.generated.js.map +1 -0
- package/dist/src/kernel/runtime/graphpack/embedded/pack.index.generated.js +4 -0
- package/dist/src/kernel/runtime/graphpack/embedded/pack.index.generated.js.map +1 -0
- package/dist/src/kernel/runtime/graphpack/embedded/pack.stories.generated.js +4 -0
- package/dist/src/kernel/runtime/graphpack/embedded/pack.stories.generated.js.map +1 -0
- package/dist/src/kernel/runtime/graphpack/embedded.js +82 -0
- package/dist/src/kernel/runtime/graphpack/embedded.js.map +1 -0
- package/dist/src/kernel/runtime/graphpack/hash.js +38 -0
- package/dist/src/kernel/runtime/graphpack/hash.js.map +1 -0
- package/dist/src/kernel/runtime/graphpack/index.js +11 -0
- package/dist/src/kernel/runtime/graphpack/index.js.map +1 -0
- package/dist/src/kernel/runtime/graphpack/manifest.js +145 -0
- package/dist/src/kernel/runtime/graphpack/manifest.js.map +1 -0
- package/dist/src/kernel/runtime/graphpack/read.js +92 -0
- package/dist/src/kernel/runtime/graphpack/read.js.map +1 -0
- package/dist/src/kernel/runtime/graphpack/schemas.js +70 -0
- package/dist/src/kernel/runtime/graphpack/schemas.js.map +1 -0
- package/dist/src/kernel/runtime/graphpack/stories.js +68 -0
- package/dist/src/kernel/runtime/graphpack/stories.js.map +1 -0
- package/dist/src/kernel/runtime/graphpack/types.js +55 -0
- package/dist/src/kernel/runtime/graphpack/types.js.map +1 -0
- package/dist/src/kernel/runtime/index.js +8 -0
- package/dist/src/kernel/runtime/index.js.map +1 -0
- package/dist/src/kernel/runtime/loadSession.js +34 -0
- package/dist/src/kernel/runtime/loadSession.js.map +1 -0
- package/dist/src/kernel/runtime/paths.js +78 -0
- package/dist/src/kernel/runtime/paths.js.map +1 -0
- package/dist/src/kernel/runtime/probe.js +37 -0
- package/dist/src/kernel/runtime/probe.js.map +1 -0
- package/dist/src/kernel/runtime/readEntity.js +363 -0
- package/dist/src/kernel/runtime/readEntity.js.map +1 -0
- package/dist/src/kernel/runtime/refs/gitOps.js +65 -0
- package/dist/src/kernel/runtime/refs/gitOps.js.map +1 -0
- package/dist/src/kernel/runtime/refs/index.js +29 -0
- package/dist/src/kernel/runtime/refs/index.js.map +1 -0
- package/dist/src/kernel/runtime/refs/parseRef.js +70 -0
- package/dist/src/kernel/runtime/refs/parseRef.js.map +1 -0
- package/dist/src/kernel/runtime/refs/resolve.js +332 -0
- package/dist/src/kernel/runtime/refs/resolve.js.map +1 -0
- package/dist/src/kernel/runtime/resolveSources.js +62 -0
- package/dist/src/kernel/runtime/resolveSources.js.map +1 -0
- package/dist/src/kernel/runtime/store.js +75 -0
- package/dist/src/kernel/runtime/store.js.map +1 -0
- package/dist/src/kernel/runtime/storeReadiness.js +51 -0
- package/dist/src/kernel/runtime/storeReadiness.js.map +1 -0
- package/dist/src/kernel/runtime/types.js +11 -0
- package/dist/src/kernel/runtime/types.js.map +1 -0
- package/dist/src/kernel/spec/asVerb.js +21 -0
- package/dist/src/kernel/spec/asVerb.js.map +1 -0
- package/dist/src/kernel/spec/emitReference.js +578 -0
- package/dist/src/kernel/spec/emitReference.js.map +1 -0
- package/dist/src/kernel/spec/emitSurface.js +202 -0
- package/dist/src/kernel/spec/emitSurface.js.map +1 -0
- package/dist/src/kernel/spec/index.js +11 -0
- package/dist/src/kernel/spec/index.js.map +1 -0
- package/dist/src/kernel/spec/surfaceConformance.js +103 -0
- package/dist/src/kernel/spec/surfaceConformance.js.map +1 -0
- package/dist/src/kernel/spec/types.js +14 -0
- package/dist/src/kernel/spec/types.js.map +1 -0
- package/dist/src/kernel/spec/validate.js +110 -0
- package/dist/src/kernel/spec/validate.js.map +1 -0
- package/dist/src/kernel/vocabulary.js +97 -0
- package/dist/src/kernel/vocabulary.js.map +1 -0
- package/dist/src/types.js +11 -0
- package/dist/src/types.js.map +1 -0
- package/package.json +20 -22
- package/pragma.conf.ts +249 -60
- package/src/bin.ts +267 -82
- package/src/capabilities/block.parity.test.ts +6 -3
- package/src/capabilities/capabilities/capabilities.render.ts +1 -1
- package/src/capabilities/capabilities/capabilities.verb.ts +1 -1
- package/src/capabilities/capabilities/catalog.ts +3 -3
- package/src/capabilities/capabilities/hints.ts +32 -7
- package/src/capabilities/capabilities/index.ts +1 -1
- package/src/capabilities/colophon/collectColophon.ts +35 -24
- package/src/capabilities/colophon/colophon.render.ts +25 -1
- package/src/capabilities/colophon/colophon.test.ts +42 -21
- package/src/capabilities/colophon/colophon.verb.ts +4 -4
- package/src/capabilities/config/collectConfigShow.test.ts +1 -0
- package/src/capabilities/config/collectConfigShow.ts +3 -3
- package/src/capabilities/config/field.render.ts +4 -5
- package/src/capabilities/config/fields.ts +17 -10
- package/src/capabilities/config/get.verb.ts +70 -0
- package/src/capabilities/config/getUnset.test.ts +264 -0
- package/src/capabilities/config/index.ts +5 -1
- package/src/capabilities/config/runField.ts +40 -22
- package/src/capabilities/config/runGet.ts +34 -0
- package/src/capabilities/config/runSet.ts +35 -9
- package/src/capabilities/config/set.test.ts +48 -14
- package/src/capabilities/config/set.verb.ts +8 -7
- package/src/capabilities/config/show.render.ts +1 -1
- package/src/capabilities/config/show.verb.ts +9 -6
- package/src/capabilities/config/types.ts +18 -4
- package/src/capabilities/config/unset.verb.ts +58 -0
- package/src/capabilities/create/byteEquality.subprocess.test.ts +2 -3
- package/src/capabilities/create/byteEquality.test.ts +25 -11
- package/src/capabilities/create/cliProjection.ts +227 -0
- package/src/capabilities/create/constants.ts +36 -61
- package/src/capabilities/create/create.mcp.test.ts +89 -5
- package/src/capabilities/create/create.render.ts +71 -7
- package/src/capabilities/create/create.test.ts +433 -219
- package/src/capabilities/create/create.verb.ts +297 -328
- package/src/capabilities/create/createGrammar.test.ts +865 -0
- package/src/capabilities/create/createHelp.ts +71 -0
- package/src/capabilities/create/createSurface.generated.ts +400 -0
- package/src/capabilities/create/crossCli.subprocess.test.ts +745 -0
- package/src/capabilities/create/cwdJail.test.ts +24 -5
- package/src/capabilities/create/generatorToVerbSpec.test.ts +186 -0
- package/src/capabilities/create/generatorToVerbSpec.ts +13 -11
- package/src/capabilities/create/index.ts +7 -4
- package/src/capabilities/create/messages.ts +18 -0
- package/src/capabilities/create/mount.ts +391 -0
- package/src/capabilities/create/pathJail.test.ts +90 -0
- package/src/capabilities/create/pathJail.ts +8 -5
- package/src/capabilities/create/pickGenerator.ts +23 -35
- package/src/capabilities/create/shippedCreate.subprocess.test.ts +164 -0
- package/src/capabilities/create/types.ts +20 -0
- package/src/capabilities/distribution.test.ts +3 -1
- package/src/capabilities/distribution.ts +10 -15
- package/src/capabilities/doctor/checks/checkKeStore.ts +7 -5
- package/src/capabilities/doctor/checks/checkPackageRefs.ts +6 -4
- package/src/capabilities/doctor/checks/checkPragmaVersion.ts +2 -2
- package/src/capabilities/doctor/checks/checkShellCompletions.test.ts +72 -27
- package/src/capabilities/doctor/checks/checkShellCompletions.ts +59 -13
- package/src/capabilities/doctor/checks/index.ts +27 -0
- package/src/capabilities/doctor/checks/mcpCommand.test.ts +100 -0
- package/src/capabilities/doctor/checks/mcpCommand.ts +69 -0
- package/src/capabilities/doctor/checks/targetHealth.ts +274 -0
- package/src/capabilities/doctor/doctor.render.test.ts +18 -7
- package/src/capabilities/doctor/doctor.render.ts +43 -19
- package/src/capabilities/doctor/doctor.test.ts +123 -34
- package/src/capabilities/doctor/doctor.verb.ts +3 -3
- package/src/capabilities/doctor/runChecks.ts +62 -63
- package/src/capabilities/doctor/types.ts +20 -4
- package/src/capabilities/emptyRecovery.test.ts +13 -8
- package/src/capabilities/graph/examples.exec.test.ts +107 -0
- package/src/capabilities/graph/index.ts +1 -1
- package/src/capabilities/graph/inspect.render.ts +70 -22
- package/src/capabilities/graph/inspect.test.ts +260 -5
- package/src/capabilities/graph/inspect.verb.ts +18 -6
- package/src/capabilities/graph/query.render.ts +15 -3
- package/src/capabilities/graph/query.verb.ts +3 -3
- package/src/capabilities/graph/runQuery.ts +2 -3
- package/src/capabilities/index.ts +3 -1
- package/src/capabilities/info/collectInfo.ts +5 -4
- package/src/capabilities/info/info.render.ts +1 -1
- package/src/capabilities/info/info.verb.ts +1 -1
- package/src/capabilities/lazy.test.ts +32 -0
- package/src/capabilities/meta/complete.verb.ts +1 -1
- package/src/capabilities/meta/index.ts +1 -1
- package/src/capabilities/meta/mcp.verb.ts +10 -8
- package/src/capabilities/ontology/index.ts +15 -11
- package/src/capabilities/ontology/ontology.test.ts +6 -55
- package/src/capabilities/ontology/queries.ts +2 -2
- package/src/capabilities/ontology/render.ts +3 -4
- package/src/capabilities/ontology/verbs.ts +27 -68
- package/src/capabilities/prompt/index.ts +2 -2
- package/src/capabilities/prompt/prompt.render.ts +6 -2
- package/src/capabilities/prompt/types.ts +1 -1
- package/src/capabilities/prompt/verbs.ts +4 -5
- package/src/capabilities/reference.test.ts +63 -0
- package/src/capabilities/resources/provider.ts +342 -85
- package/src/capabilities/resources/resources.test.ts +355 -59
- package/src/capabilities/setup/buildPlan.ts +236 -0
- package/src/capabilities/setup/index.ts +7 -7
- package/src/capabilities/setup/mode.ts +74 -0
- package/src/capabilities/setup/operations/index.ts +74 -0
- package/src/capabilities/setup/operations/setupCompletions.ts +97 -24
- package/src/capabilities/setup/operations/setupConfig.ts +124 -0
- package/src/capabilities/setup/operations/setupGenerator.ts +396 -326
- package/src/capabilities/setup/operations/setupLsp.ts +329 -68
- package/src/capabilities/setup/operations/setupMcp.ts +137 -97
- package/src/capabilities/setup/operations/setupSkills.ts +336 -108
- package/src/capabilities/setup/plan.render.ts +241 -0
- package/src/capabilities/setup/plan.ts +236 -0
- package/src/capabilities/setup/setup.mcp.correctness.test.ts +432 -0
- package/src/capabilities/setup/setup.render.test.ts +281 -73
- package/src/capabilities/setup/setup.render.ts +45 -77
- package/src/capabilities/setup/setup.test.ts +972 -209
- package/src/capabilities/setup/setup.verb.ts +223 -71
- package/src/capabilities/setup/shell.test.ts +86 -0
- package/src/capabilities/setup/shell.ts +137 -11
- package/src/capabilities/setup/targets.ts +367 -0
- package/src/capabilities/setup/types.ts +18 -57
- package/src/capabilities/shared/assertExecOk.ts +68 -10
- package/src/capabilities/shared/index.ts +32 -0
- package/src/capabilities/shared/packageManager.test.ts +55 -0
- package/src/capabilities/shared/packageManager.ts +62 -6
- package/src/capabilities/skill/discover.ts +37 -5
- package/src/capabilities/skill/index.ts +1 -1
- package/src/capabilities/skill/render.ts +10 -9
- package/src/capabilities/skill/skill.test.ts +7 -5
- package/src/capabilities/skill/verbs.ts +3 -4
- package/src/capabilities/sources/collectStatus.ts +7 -2
- package/src/capabilities/sources/index.ts +1 -1
- package/src/capabilities/sources/installSkills.ts +84 -7
- package/src/capabilities/sources/runUpdate.ts +53 -21
- package/src/capabilities/sources/sources.test.ts +154 -2
- package/src/capabilities/sources/status.render.ts +1 -1
- package/src/capabilities/sources/status.verb.ts +1 -1
- package/src/capabilities/sources/update.render.ts +1 -1
- package/src/capabilities/sources/update.verb.ts +1 -1
- package/src/capabilities/surface.test.ts +134 -17
- package/src/capabilities/upgrade/runUpgrade.ts +8 -8
- package/src/capabilities/upgrade/upgrade.render.ts +4 -5
- package/src/capabilities/upgrade/upgrade.test.ts +3 -3
- package/src/capabilities/upgrade/upgrade.verb.ts +1 -1
- package/src/capabilities/version/index.ts +12 -0
- package/src/capabilities/version/version.test.ts +66 -0
- package/src/capabilities/version/version.verb.ts +39 -0
- package/src/constants.ts +31 -1
- package/src/identity.test.ts +40 -25
- package/src/kernel/completion/__snapshots__/emitScripts.test.ts.snap +15 -13
- package/src/kernel/completion/complete.test.ts +12 -2
- package/src/kernel/completion/complete.ts +1 -1
- package/src/kernel/completion/emitScripts.ts +1 -1
- package/src/kernel/completion/entitySource.test.ts +1 -1
- package/src/kernel/completion/entitySource.ts +21 -8
- package/src/kernel/completion/model.test.ts +164 -12
- package/src/kernel/completion/model.ts +94 -14
- package/src/kernel/completion/parse.test.ts +4 -7
- package/src/kernel/completion/parse.ts +15 -0
- package/src/kernel/completion/resolve.test.ts +0 -1
- package/src/kernel/completion/safety.test.ts +34 -26
- package/src/kernel/completion/shellDrive.test.ts +28 -9
- package/src/kernel/completion/templates/bash.ts +7 -2
- package/src/kernel/completion/templates/index.ts +23 -0
- package/src/kernel/completion/types.ts +7 -0
- package/src/kernel/config/defaults.test.ts +25 -2
- package/src/kernel/config/defaults.ts +4 -3
- package/src/kernel/config/evaluateProjectConfig.ts +31 -8
- package/src/kernel/config/firstRun.test.ts +44 -38
- package/src/kernel/config/firstRun.ts +24 -88
- package/src/kernel/config/index.ts +1 -1
- package/src/kernel/config/readConfig.test.ts +6 -3
- package/src/kernel/config/readConfig.ts +1 -1
- package/src/kernel/config/schema.ts +3 -1
- package/src/kernel/config/types.ts +3 -1
- package/src/kernel/copy.test.ts +34 -4
- package/src/kernel/copy.ts +54 -0
- package/src/kernel/error/PragmaError.test.ts +5 -2
- package/src/kernel/error/PragmaError.ts +4 -2
- package/src/kernel/error/constants.ts +7 -5
- package/src/kernel/error/fromTaskError.ts +28 -6
- package/src/kernel/error/recovery.ts +14 -0
- package/src/kernel/error/renderError.ts +42 -1
- package/src/kernel/error/types.ts +21 -1
- package/src/kernel/index.ts +26 -0
- package/src/kernel/packs/collect.ts +12 -16
- package/src/kernel/packs/compile.test.ts +130 -1
- package/src/kernel/packs/compile.ts +93 -3
- package/src/kernel/packs/disclosure.ts +2 -2
- package/src/kernel/packs/graphql/buildLookupDocument.ts +1 -1
- package/src/kernel/packs/graphql/fetchGraphqlLookup.ts +3 -4
- package/src/kernel/packs/graphql/index.ts +20 -0
- package/src/kernel/packs/index.ts +40 -0
- package/src/kernel/packs/iri.test.ts +73 -0
- package/src/kernel/packs/iri.ts +66 -14
- package/src/kernel/packs/renderPack.ts +24 -5
- package/src/kernel/packs/resolveEntity.test.ts +213 -0
- package/src/kernel/packs/resolveEntity.ts +112 -18
- package/src/kernel/packs/runBodies.ts +2 -3
- package/src/kernel/packs/sample.ts +1 -1
- package/src/kernel/packs/schema.ts +18 -1
- package/src/kernel/packs/sparql/applyFilters.ts +16 -17
- package/src/kernel/packs/sparql/buildLookupQuery.ts +75 -3
- package/src/kernel/packs/sparql/index.ts +37 -0
- package/src/kernel/packs/sparql/runSelect.test.ts +1 -1
- package/src/kernel/packs/sparql/runSelect.ts +3 -4
- package/src/kernel/packs/toolDescription.test.ts +42 -3
- package/src/kernel/packs/types.ts +13 -0
- package/src/kernel/packs/uniqueness.ts +1 -1
- package/src/kernel/project/cli/buildProgram.test.ts +147 -12
- package/src/kernel/project/cli/buildProgram.ts +77 -18
- package/src/kernel/project/cli/constants.ts +34 -0
- package/src/kernel/project/cli/dispatch.test.ts +160 -3
- package/src/kernel/project/cli/dispatch.ts +222 -42
- package/src/kernel/project/cli/exitCodes.ts +1 -1
- package/src/kernel/project/cli/globalFlags.test.ts +117 -1
- package/src/kernel/project/cli/globalFlags.ts +130 -30
- package/src/kernel/project/cli/helpFormat.ts +13 -0
- package/src/kernel/project/cli/rootHelp.ts +41 -12
- package/src/kernel/project/cli/suggest.test.ts +33 -1
- package/src/kernel/project/cli/suggest.ts +25 -1
- package/src/kernel/project/cli/verbHelp.test.ts +30 -0
- package/src/kernel/project/cli/verbHelp.ts +23 -7
- package/src/kernel/project/mcp/buildServer.ts +7 -4
- package/src/kernel/project/mcp/envelope.ts +2 -2
- package/src/kernel/project/mcp/instructions.ts +2 -2
- package/src/kernel/project/mcp/mcpError.ts +1 -1
- package/src/kernel/project/mcp/parity.test.ts +5 -2
- package/src/kernel/project/mcp/prompts/index.ts +37 -0
- package/src/kernel/project/mcp/prompts/source.ts +2 -2
- package/src/kernel/project/mcp/registerVerb.ts +35 -9
- package/src/kernel/project/mcp/serve.ts +2 -2
- package/src/kernel/render/__snapshots__/renderers.test.ts.snap +7 -4
- package/src/kernel/render/contracts.ts +21 -0
- package/src/kernel/render/envelope.ts +2 -3
- package/src/kernel/render/formatters.ts +1 -1
- package/src/kernel/render/renderers.test.ts +243 -6
- package/src/kernel/render/renderers.ts +222 -20
- package/src/kernel/render/style.test.ts +75 -24
- package/src/kernel/render/style.ts +31 -1
- package/src/kernel/render/turtle.ts +222 -0
- package/src/kernel/runtime/graphpack/buildIndex.ts +1 -1
- package/src/kernel/runtime/graphpack/embedded/pack.generated.ts +3 -3
- package/src/kernel/runtime/graphpack/embedded/pack.index.generated.ts +1 -1
- package/src/kernel/runtime/graphpack/embedded.ts +3 -3
- package/src/kernel/runtime/graphpack/manifest.ts +1 -1
- package/src/kernel/runtime/graphpack/read.ts +1 -2
- package/src/kernel/runtime/loadSession.ts +1 -1
- package/src/kernel/runtime/probe.ts +6 -6
- package/src/kernel/runtime/readEntity.ts +472 -28
- package/src/kernel/runtime/refs/index.ts +39 -0
- package/src/kernel/runtime/refs/parseRef.ts +2 -2
- package/src/kernel/runtime/refs/resolve.ts +4 -4
- package/src/kernel/runtime/storeReadiness.ts +1 -2
- package/src/kernel/runtime/types.ts +15 -1
- package/src/kernel/runtime/wasmEmbed.test.ts +37 -39
- package/src/kernel/spec/emitReference.ts +105 -30
- package/src/kernel/spec/emitSurface.ts +48 -6
- package/src/kernel/spec/surfaceConformance.test.ts +4 -2
- package/src/kernel/spec/types.ts +248 -4
- package/src/testing/behavioral/docExamples.test.ts +14 -0
- package/src/testing/behavioral/errorMatrix.mcp.test.ts +2 -2
- package/src/testing/behavioral/firstRun.e2e.test.ts +24 -24
- package/src/testing/behavioral/journeys.cli.test.ts +1 -1
- package/src/testing/behavioral/journeys.defaultPack.test.ts +7 -7
- package/src/testing/behavioral/journeys.implementation.test.ts +206 -0
- package/src/testing/behavioral/journeys.interactiveTty.e2e.test.ts +2 -2
- package/src/testing/behavioral/journeys.packageStories.test.ts +4 -4
- package/src/testing/behavioral/mcpServe.e2e.test.ts +57 -2
- package/src/testing/behavioral/mcpSurface.test.ts +1 -1
- package/src/testing/behavioral/rootCli.e2e.test.ts +26 -2
- package/src/testing/eval/cases/effectful.ts +3 -2
- package/src/testing/fixtures/blockGraph.ts +79 -0
- package/src/testing/fixtures/graph/canonical.ts +88 -2
- package/src/testing/fixtures/graph/defaultPack.ts +1 -1
- package/src/testing/helpers/blankCanonicalRanges.ts +36 -0
- package/src/testing/helpers/projectMcp.ts +32 -6
- package/src/testing/helpers/runCli.ts +35 -18
- package/src/testing/perf/budgets.test.ts +20 -9
- package/src/testing/perf/budgets.ts +58 -9
- package/src/testing/perf/codegen.test.ts +126 -0
- package/src/testing/perf/globalSetup.test.ts +286 -0
- package/src/testing/perf/globalSetup.ts +505 -23
- package/src/testing/perf/measure.test.ts +38 -0
- package/src/testing/perf/measure.ts +23 -4
- package/src/testing/setupXdgIsolation.ts +81 -21
- package/src/testing/tempRoot.globalSetup.ts +122 -0
- package/dist/pragma +0 -0
- package/src/capabilities/create/compiledCreate.subprocess.test.ts +0 -189
- package/src/capabilities/create/templates.embedded.generated.ts +0 -28
- package/src/capabilities/doctor/checks/checkConfigFile.ts +0 -42
- package/src/capabilities/doctor/checks/checkMcpCommands.ts +0 -114
- package/src/capabilities/doctor/checks/checkMcpConfigured.ts +0 -68
- package/src/capabilities/doctor/checks/checkSkillsSymlinked.ts +0 -61
- package/src/capabilities/doctor/checks/deriveBand.test.ts +0 -42
- package/src/capabilities/doctor/checks/deriveBand.ts +0 -28
- package/src/kernel/config/__snapshots__/firstRun.test.ts.snap +0 -11
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `setup mcp` — register the pragma MCP server in detected AI harnesses.
|
|
3
|
+
*
|
|
4
|
+
* Split into `detectMcp` (harness detection runs FOR REAL up front, via
|
|
5
|
+
* `runTask` over safe reads, and the resolved config targets are deduplicated
|
|
6
|
+
* into per-file {@link TargetGroup}s for the chosen `--scope`) and `composeMcp`
|
|
7
|
+
* (a pure, re-runnable write body driven by the SELECTED groups). Each write is
|
|
8
|
+
* a distinct `(path, mcpKey)` so two harnesses sharing a file (VS Code + Cline)
|
|
9
|
+
* each preserve the other. What a run SAYS about each file is the plan row's
|
|
10
|
+
* per-file children, not a log line composed here.
|
|
11
|
+
*
|
|
12
|
+
* Detection ALSO reads each group's existing config (via `readMcpConfigFrom`,
|
|
13
|
+
* FOR REAL up front) and classifies every group as `absent` (no pragma entry
|
|
14
|
+
* yet), `configured` (the pragma entry already matches what we'd write), or
|
|
15
|
+
* `drifted` (a pragma entry exists but differs). The wizard shows that prior
|
|
16
|
+
* state in each row and DEFAULT-DESELECTS the already-`configured` files; the
|
|
17
|
+
* write itself stays idempotent (a re-merge of the identical entry is
|
|
18
|
+
* byte-for-byte), so a re-run is a no-op the recap reports as "unchanged" — the
|
|
19
|
+
* same state-awareness `setup skills` has always had.
|
|
20
|
+
*/
|
|
21
|
+
import { dirname } from "node:path";
|
|
22
|
+
import { mkdir, sequence_ } from "@canonical/task";
|
|
23
|
+
import { MCP_SERVER_NAME } from "../../../constants.js";
|
|
24
|
+
/**
|
|
25
|
+
* The argv a registered harness spawns to reach the server.
|
|
26
|
+
*
|
|
27
|
+
* The server verb is `mcp serve`: `mcp` is the noun, and the noun on its own is
|
|
28
|
+
* not the server entry. An entry still carrying the old single-token `mcp`
|
|
29
|
+
* spawns something that no longer serves, so it must not survive.
|
|
30
|
+
*
|
|
31
|
+
* It does not have to: `mcpEntryMatches` treats `args` as a controlled field,
|
|
32
|
+
* so an entry written before this rename classifies as `drifted` on the very
|
|
33
|
+
* next detection and the ordinary forward write repairs it. That is the whole
|
|
34
|
+
* migration — no flag, no prompt, no compatibility branch — and the run after
|
|
35
|
+
* it converges, because the repaired entry then matches byte for byte.
|
|
36
|
+
*/
|
|
37
|
+
const MCP_SERVE_ARGV = ["mcp", "serve"];
|
|
38
|
+
/**
|
|
39
|
+
* The pragma MCP server entry we register — the SINGLE source of truth both the
|
|
40
|
+
* classifier (does the existing entry match this?) and the writer (`composeMcp`)
|
|
41
|
+
* consume, so "already configured" means byte-for-byte what a write would emit.
|
|
42
|
+
*
|
|
43
|
+
* The entry is BAND-shaped: a project-band entry records the project root as
|
|
44
|
+
* `cwd` (that binding is the point of a per-repo registration), while a
|
|
45
|
+
* global-band entry OMITS `cwd` entirely — a per-user server must not be
|
|
46
|
+
* pinned to whatever directory `setup mcp --global` happened to run from
|
|
47
|
+
* (observed: a global registration from `~/Downloads` permanently served
|
|
48
|
+
* `~/Downloads`, and re-running from repo B "repaired" it to repo B,
|
|
49
|
+
* ping-ponging the machine band between projects). The per-harness
|
|
50
|
+
* serializers already omit an undefined `cwd`, and the matcher treats an
|
|
51
|
+
* omitted controlled field as must-be-absent, so a stale global entry still
|
|
52
|
+
* carrying a `cwd` classifies as `drifted` and converges on the next write.
|
|
53
|
+
*
|
|
54
|
+
* @param cwd - The project root (recorded only on project-band entries).
|
|
55
|
+
* @param band - The config band the entry is written to.
|
|
56
|
+
* @returns The pragma {@link McpServerConfig}.
|
|
57
|
+
*/
|
|
58
|
+
export function pragmaMcpEntry(cwd, band) {
|
|
59
|
+
return band === "project"
|
|
60
|
+
? { command: MCP_SERVER_NAME, args: [...MCP_SERVE_ARGV], cwd }
|
|
61
|
+
: { command: MCP_SERVER_NAME, args: [...MCP_SERVE_ARGV] };
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Classify one target group against its on-disk config: `absent` when no pragma
|
|
65
|
+
* entry exists in ANY of the group's writes, `configured` when EVERY write
|
|
66
|
+
* already carries a matching pragma entry, `drifted` otherwise (present in at
|
|
67
|
+
* least one write but not matching everywhere). Reads each write's file for real
|
|
68
|
+
* via `readMcpConfigFrom`, and matches each raw entry against what THAT write's
|
|
69
|
+
* per-harness serializer would emit for the group's BAND (`mcpEntryMatches`
|
|
70
|
+
* compares the serializer's controlled fields — so a global entry still
|
|
71
|
+
* pinning a `cwd` reads as drifted — and ignores extra keys a harness or user
|
|
72
|
+
* added, so we never churn a file we did not author).
|
|
73
|
+
*
|
|
74
|
+
* @param group - The target group whose writes to inspect.
|
|
75
|
+
* @param want - The canonical pragma entry for the group's band.
|
|
76
|
+
* @param harnessesApi - The dynamically imported harnesses module.
|
|
77
|
+
* @param runTask - The node Task interpreter.
|
|
78
|
+
* @returns The group's {@link McpTargetState}.
|
|
79
|
+
* @note Impure — reads each write's config file.
|
|
80
|
+
*/
|
|
81
|
+
async function classifyGroup(group, want, harnessesApi, runTask) {
|
|
82
|
+
let present = 0;
|
|
83
|
+
let matching = 0;
|
|
84
|
+
for (const write of group.writes) {
|
|
85
|
+
const servers = await runTask(harnessesApi.readMcpConfigFrom(write));
|
|
86
|
+
const existing = servers[MCP_SERVER_NAME];
|
|
87
|
+
if (existing === undefined)
|
|
88
|
+
continue;
|
|
89
|
+
present += 1;
|
|
90
|
+
if (harnessesApi.mcpEntryMatches(existing, want, write.serializeEntry)) {
|
|
91
|
+
matching += 1;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (present === 0)
|
|
95
|
+
return "absent";
|
|
96
|
+
if (matching === group.writes.length)
|
|
97
|
+
return "configured";
|
|
98
|
+
return "drifted";
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Detect the AI harnesses present in the project (real reads, up front),
|
|
102
|
+
* resolve+dedup their config targets for the chosen scope, AND read each
|
|
103
|
+
* group's existing config to classify it `absent`/`configured`/`drifted` — so
|
|
104
|
+
* the wizard can show prior state and default-deselect already-`configured`
|
|
105
|
+
* files.
|
|
106
|
+
*
|
|
107
|
+
* @param rt - The per-invocation runtime.
|
|
108
|
+
* @param band - The band being planned (global or project).
|
|
109
|
+
* @returns The band's target groups, their prior states, + the config writer.
|
|
110
|
+
* @note Impure — reads the filesystem via `detectHarnesses` + `readMcpConfigFrom`.
|
|
111
|
+
*/
|
|
112
|
+
export async function detectMcp(rt, band) {
|
|
113
|
+
const cwd = rt.cwd;
|
|
114
|
+
const [{ detectHarnesses, groupTargetsForScope, mcpEntryMatches, readMcpConfigFrom, readPlatformEnv, removeMcpConfigFrom, writeMcpConfigTargets, }, { runTask },] = await Promise.all([
|
|
115
|
+
import("@canonical/harnesses"),
|
|
116
|
+
import("@canonical/task/node"),
|
|
117
|
+
]);
|
|
118
|
+
const platform = readPlatformEnv();
|
|
119
|
+
const detected = await runTask(detectHarnesses(cwd, platform));
|
|
120
|
+
const groups = groupTargetsForScope(detected, cwd, band, platform);
|
|
121
|
+
// Read each group's existing config (for real, up front) so the recap/preview
|
|
122
|
+
// and the default selection reflect true prior state — the same discipline
|
|
123
|
+
// `detectSkills` uses for its per-link create/skip/replace decision. The
|
|
124
|
+
// wanted entry is BAND-shaped (a global entry omits `cwd`), so it is built
|
|
125
|
+
// per group, not once.
|
|
126
|
+
const stateByPath = new Map();
|
|
127
|
+
await Promise.all(groups.map(async (group) => {
|
|
128
|
+
const state = await classifyGroup(group, pragmaMcpEntry(cwd, group.scope), { readMcpConfigFrom, mcpEntryMatches }, runTask);
|
|
129
|
+
stateByPath.set(group.path, state);
|
|
130
|
+
}));
|
|
131
|
+
return {
|
|
132
|
+
groups,
|
|
133
|
+
stateByPath,
|
|
134
|
+
cwd,
|
|
135
|
+
platform,
|
|
136
|
+
writeMcpConfigTargets,
|
|
137
|
+
removeMcpConfigFrom,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* The prior state of a group, defaulting to `absent` for an unknown path (so a
|
|
142
|
+
* caller never has to guard the map lookup).
|
|
143
|
+
*/
|
|
144
|
+
export function mcpGroupState(d, path) {
|
|
145
|
+
return d.stateByPath.get(path) ?? "absent";
|
|
146
|
+
}
|
|
147
|
+
/** The target groups the user selected (by path), or all when none recorded. */
|
|
148
|
+
export function selectedGroups(d, selectedPaths) {
|
|
149
|
+
return d.groups.filter((g) => selectedPaths.includes(g.path));
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Compose the per-target config writes for the SELECTED groups (pure —
|
|
153
|
+
* re-runnable; builds ABSOLUTE config paths itself). An already-`configured`
|
|
154
|
+
* group composes NOTHING: the entry on disk is byte-for-byte what a write would
|
|
155
|
+
* emit, so re-writing it would only move an mtime. Removal no longer depends on
|
|
156
|
+
* the forward plan having written something ({@link composeMcpRemoval}), which
|
|
157
|
+
* is what used to force the redundant write.
|
|
158
|
+
*
|
|
159
|
+
* The task carries no log effects — the plan row owns what the run says.
|
|
160
|
+
*
|
|
161
|
+
* @param d - The detection gathered up front.
|
|
162
|
+
* @param groups - The target groups the user chose (a subset of `d.groups`).
|
|
163
|
+
* @returns A Task that writes the pragma MCP config into each chosen file.
|
|
164
|
+
*/
|
|
165
|
+
export function composeMcp(d, groups) {
|
|
166
|
+
// Re-runnable combinators (NOT a single-use `gen`): `execute` interprets the
|
|
167
|
+
// task twice (preview + perform). One combined write per file keeps a shared
|
|
168
|
+
// file (VS Code + Cline) a single read-modify-write — dry-run safe. The
|
|
169
|
+
// written entry is BAND-shaped per group (a global entry omits `cwd`).
|
|
170
|
+
const pending = groups.filter((group) => mcpGroupState(d, group.path) !== "configured");
|
|
171
|
+
return sequence_(pending.map((group) => d.writeMcpConfigTargets(group.writes, MCP_SERVER_NAME, pragmaMcpEntry(d.cwd, group.scope))));
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* The groups this band OWNS right now — every file where detection classifies a
|
|
175
|
+
* pragma entry as present (`configured` or `drifted`). Removal acts on exactly
|
|
176
|
+
* this set, so a file that never carried the entry is never rewritten and a
|
|
177
|
+
* foreign server in a file that does is never touched.
|
|
178
|
+
*/
|
|
179
|
+
export const ownedMcpGroups = (d) => d.groups.filter((group) => mcpGroupState(d, group.path) !== "absent");
|
|
180
|
+
/**
|
|
181
|
+
* Compose the removal of the pragma entry from every owned file.
|
|
182
|
+
*
|
|
183
|
+
* The FORWARD side of this task must be walkable without reading anything.
|
|
184
|
+
* `runUndo` collects undos by walking the forward task with effects MOCKED —
|
|
185
|
+
* real `Exists`, but `ReadFile` deliberately returns a placeholder, so that the
|
|
186
|
+
* walk cannot observe the forward run's own edits. Re-asserting the entry here
|
|
187
|
+
* (the obvious composition, and the one this had) put a read-parse-merge on
|
|
188
|
+
* that walk: the placeholder is not JSON, the parse failed closed, and the
|
|
189
|
+
* collection aborted before gathering a single undo. `setup mcp --undo` could
|
|
190
|
+
* not remove anything, and said so by refusing a config that was perfectly
|
|
191
|
+
* valid.
|
|
192
|
+
*
|
|
193
|
+
* So the forward effect is a `mkdir` of the config's own directory — which
|
|
194
|
+
* already exists, reads nothing, and is a genuine no-op — carrying the
|
|
195
|
+
* key-scoped removal as its `undo`. Phase two then runs that removal against
|
|
196
|
+
* the real file. Only the pragma key is ever deleted; a foreign server in the
|
|
197
|
+
* same file is never touched.
|
|
198
|
+
*
|
|
199
|
+
* @param d - The detection gathered up front.
|
|
200
|
+
* @returns A Task whose undo removes the pragma entry from each owned file.
|
|
201
|
+
*/
|
|
202
|
+
export function composeMcpRemoval(d) {
|
|
203
|
+
return sequence_(ownedMcpGroups(d).map((group) => mkdir(dirname(group.path), true, {
|
|
204
|
+
undo: sequence_(group.writes.map((write) => d.removeMcpConfigFrom(write, MCP_SERVER_NAME))),
|
|
205
|
+
})));
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=setupMcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setupMcp.js","sourceRoot":"","sources":["../../../../../src/capabilities/setup/operations/setupMcp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `setup skills` — symlink discovered skills into harness skill directories.
|
|
3
|
+
*
|
|
4
|
+
* BAND-MATCHED: the band picks the source root AND the link destination, and
|
|
5
|
+
* the two always match.
|
|
6
|
+
*
|
|
7
|
+
* - global (the default): INSTALLED skills (`$XDG_DATA_HOME/<bin>/skills`, where
|
|
8
|
+
* `sources update` puts package skills) link into user-level harness skill
|
|
9
|
+
* directories — the cross-client `~/.agents/skills`, plus the user-level
|
|
10
|
+
* directory of each detected harness whose user-level location is verified.
|
|
11
|
+
* - project (`--local`): PROJECT skills (`<cwd>/.<bin>/skills`) link into the
|
|
12
|
+
* project's harness directories — the checked-in, team-shared arrangement.
|
|
13
|
+
*
|
|
14
|
+
* Cross-band linking is what this replaces: linking installed skills into a
|
|
15
|
+
* repository's directories leaks machine state into a checkout, and linking a
|
|
16
|
+
* repository's skills into the home directory applies one project's skills
|
|
17
|
+
* machine-wide. Neither is ever what the user asked for.
|
|
18
|
+
*
|
|
19
|
+
* Split into `detectSkills` (discovery, harness detection, and the per-link
|
|
20
|
+
* create/skip/replace DECISION, all against the real filesystem up front, so
|
|
21
|
+
* the plan and the recap reflect true state) and pure compose bodies performing
|
|
22
|
+
* only the symlink/delete effects the dry-run interpreter mocks.
|
|
23
|
+
*/
|
|
24
|
+
import { lstatSync, readdirSync, readlinkSync } from "node:fs";
|
|
25
|
+
import { dirname, isAbsolute, relative, resolve, sep } from "node:path";
|
|
26
|
+
import { deleteFile, mkdir, sequence_, symlink, } from "@canonical/task";
|
|
27
|
+
/** Cross-client skill directory, shared across all harnesses. */
|
|
28
|
+
const CROSS_CLIENT_DIR = ".agents/skills";
|
|
29
|
+
/**
|
|
30
|
+
* The harnesses whose USER-LEVEL skills directory is verified against the
|
|
31
|
+
* harness's own documentation, and therefore safe to link into on the global
|
|
32
|
+
* band. A harness absent from this set simply contributes no global link
|
|
33
|
+
* directory: an invented `~/.<something>/skills` would be a directory nothing
|
|
34
|
+
* reads, and creating it would be litter dressed up as configuration.
|
|
35
|
+
*
|
|
36
|
+
* The path itself is still the registry's — `skillsPath` is a function of a
|
|
37
|
+
* root, so a user-level location is `skillsPath(home)`. What lives here is only
|
|
38
|
+
* the JUDGEMENT that the location has been confirmed.
|
|
39
|
+
*/
|
|
40
|
+
const VERIFIED_GLOBAL_SKILL_HARNESSES = new Set([
|
|
41
|
+
"claude-code",
|
|
42
|
+
]);
|
|
43
|
+
/**
|
|
44
|
+
* Whether a link's destination lives INSIDE the band's skill root — the
|
|
45
|
+
* ownership test, and the one that decides what `--undo` deletes.
|
|
46
|
+
*
|
|
47
|
+
* A raw `readlink` target may be relative, so it is resolved against the link's
|
|
48
|
+
* own directory first; then containment is tested by PATH SEGMENT. A string
|
|
49
|
+
* prefix answered yes for `<root>-backup/foo`, so a user's own link into a
|
|
50
|
+
* sibling directory was classified as ours and removed by `--undo` — a file we
|
|
51
|
+
* never created and had no business deleting.
|
|
52
|
+
*
|
|
53
|
+
* The root itself is not "inside" it: a link pointing AT the root is not one of
|
|
54
|
+
* the per-skill links this command writes.
|
|
55
|
+
*
|
|
56
|
+
* @param root - The band's skill source root, absolute.
|
|
57
|
+
* @param linkPath - The absolute path of the link being classified.
|
|
58
|
+
* @param rawTarget - The link's destination exactly as `readlink` reported it.
|
|
59
|
+
* @returns Whether the destination is a path under the root.
|
|
60
|
+
* @note Pure — it resolves and compares strings, and reads nothing.
|
|
61
|
+
*/
|
|
62
|
+
function withinRoot(root, linkPath, rawTarget) {
|
|
63
|
+
const destination = resolve(dirname(linkPath), rawTarget);
|
|
64
|
+
const rel = relative(root, destination);
|
|
65
|
+
return (rel.length > 0 &&
|
|
66
|
+
rel !== ".." &&
|
|
67
|
+
!rel.startsWith(`..${sep}`) &&
|
|
68
|
+
!isAbsolute(rel));
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Classify a link path WITHOUT following it: absent, a symlink (with its raw
|
|
72
|
+
* target, resolving or not), or a real (non-symlink) entry. `lstat`-based, the
|
|
73
|
+
* same classification `sources/installSkills.ts`'s `linkState` uses — probing
|
|
74
|
+
* with `existsSync` FOLLOWS the link, so a DANGLING symlink read as "absent",
|
|
75
|
+
* the plan said `created`, and the real `symlink()` crashed EEXIST while the
|
|
76
|
+
* dry-run previewed a clean create.
|
|
77
|
+
*/
|
|
78
|
+
function linkState(linkPath) {
|
|
79
|
+
let stat;
|
|
80
|
+
try {
|
|
81
|
+
stat = lstatSync(linkPath);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return { kind: "absent" };
|
|
85
|
+
}
|
|
86
|
+
if (stat.isSymbolicLink()) {
|
|
87
|
+
try {
|
|
88
|
+
return { kind: "symlink", target: readlinkSync(linkPath) };
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return { kind: "other" };
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return { kind: "other" };
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* The link directories for a band. Project: every detected harness's
|
|
98
|
+
* project-rooted skills directory plus the cross-client one, exactly as
|
|
99
|
+
* before. Global: the same construction rooted at the user's home directory,
|
|
100
|
+
* but only for the harnesses in {@link VERIFIED_GLOBAL_SKILL_HARNESSES} —
|
|
101
|
+
* plus the cross-client directory, which every client reads by convention.
|
|
102
|
+
*
|
|
103
|
+
* @param detected - The detected harnesses.
|
|
104
|
+
* @param band - The band being set up.
|
|
105
|
+
* @param root - The band's link root (`cwd` for project, home for global).
|
|
106
|
+
* @returns The deduplicated target directories, first-seen wins.
|
|
107
|
+
*/
|
|
108
|
+
function linkTargets(detected, band, root) {
|
|
109
|
+
const seen = new Set();
|
|
110
|
+
const targets = [];
|
|
111
|
+
for (const d of detected) {
|
|
112
|
+
if (band === "global" &&
|
|
113
|
+
!VERIFIED_GLOBAL_SKILL_HARNESSES.has(d.harness.id)) {
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
const dir = d.harness.skillsPath(root);
|
|
117
|
+
if (seen.has(dir))
|
|
118
|
+
continue;
|
|
119
|
+
seen.add(dir);
|
|
120
|
+
targets.push({ dir, name: d.harness.name });
|
|
121
|
+
}
|
|
122
|
+
const crossDir = resolve(root, CROSS_CLIENT_DIR);
|
|
123
|
+
if (!seen.has(crossDir))
|
|
124
|
+
targets.push({ dir: crossDir, name: CROSS_CLIENT_DIR });
|
|
125
|
+
return targets;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Every owned link sitting in the target directories that the per-skill pass
|
|
129
|
+
* did not already visit.
|
|
130
|
+
*
|
|
131
|
+
* The forward pass enumerates CURRENT skills, so it can only ever see links a
|
|
132
|
+
* skill still exists for. Once the source root is emptied — or one skill is
|
|
133
|
+
* removed upstream — the link it left behind is invisible to that pass, and
|
|
134
|
+
* removal derived from it found nothing to do. Ownership is the same
|
|
135
|
+
* containment test the forward pass applies, so a user's own link is no more
|
|
136
|
+
* removable here than it is there.
|
|
137
|
+
*
|
|
138
|
+
* @param targets - The band's link directories.
|
|
139
|
+
* @param sourceRoot - The band's skill source root.
|
|
140
|
+
* @param covered - Link paths the per-skill pass already decided.
|
|
141
|
+
* @returns The owned links no current skill accounts for.
|
|
142
|
+
* @note Impure — reads each target directory and lstats its entries.
|
|
143
|
+
*/
|
|
144
|
+
function orphanedLinks(targets, sourceRoot, covered) {
|
|
145
|
+
const orphans = [];
|
|
146
|
+
for (const { dir, name } of targets) {
|
|
147
|
+
let entries;
|
|
148
|
+
try {
|
|
149
|
+
entries = readdirSync(dir);
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
continue; // The directory does not exist — it holds no links.
|
|
153
|
+
}
|
|
154
|
+
for (const entry of entries) {
|
|
155
|
+
const linkPath = resolve(dir, entry);
|
|
156
|
+
if (covered.has(linkPath))
|
|
157
|
+
continue;
|
|
158
|
+
const state = linkState(linkPath);
|
|
159
|
+
if (state.kind !== "symlink")
|
|
160
|
+
continue;
|
|
161
|
+
if (!withinRoot(sourceRoot, linkPath, state.target))
|
|
162
|
+
continue;
|
|
163
|
+
orphans.push({
|
|
164
|
+
skillName: entry,
|
|
165
|
+
target: resolve(dirname(linkPath), state.target),
|
|
166
|
+
linkPath,
|
|
167
|
+
action: "skipped",
|
|
168
|
+
harnessName: name,
|
|
169
|
+
blocked: false,
|
|
170
|
+
owned: true,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return orphans;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Discover the band's skills, detect harnesses, and decide each link action
|
|
178
|
+
* (real filesystem, up front).
|
|
179
|
+
*
|
|
180
|
+
* Target discovery runs even when the band holds NO skills: the directories are
|
|
181
|
+
* where this command's own links live, and a removal has to be able to find
|
|
182
|
+
* them after the source root has been emptied.
|
|
183
|
+
*
|
|
184
|
+
* @param rt - The per-invocation runtime.
|
|
185
|
+
* @param band - Which band to plan: global (installed skills) or project.
|
|
186
|
+
* @returns The band's link plan.
|
|
187
|
+
* @note Impure — reads the filesystem (skills + harnesses + existing links).
|
|
188
|
+
*/
|
|
189
|
+
export async function detectSkills(rt, band) {
|
|
190
|
+
const cwd = rt.cwd;
|
|
191
|
+
const [{ discoverSkillsFrom, installedSkillsDir, projectSkillsDir }, { detectHarnesses, readPlatformEnv, userHome }, { runTask },] = await Promise.all([
|
|
192
|
+
import("../../skill/discover.js"),
|
|
193
|
+
import("@canonical/harnesses"),
|
|
194
|
+
import("@canonical/task/node"),
|
|
195
|
+
]);
|
|
196
|
+
const sourceRoot = band === "project" ? projectSkillsDir(cwd) : installedSkillsDir();
|
|
197
|
+
const linkRoot = band === "project" ? cwd : userHome(readPlatformEnv());
|
|
198
|
+
const skills = discoverSkillsFrom([sourceRoot]);
|
|
199
|
+
const detected = await runTask(detectHarnesses(cwd));
|
|
200
|
+
const targets = linkTargets(detected, band, linkRoot);
|
|
201
|
+
// Decide each action against REAL fs (so the preview is accurate). Dangling
|
|
202
|
+
// or wrong-target symlinks are `replaced` (delete + relink); a real
|
|
203
|
+
// (non-symlink) file or directory at the path is `skipped` — a hand-placed
|
|
204
|
+
// skill is never this command's to delete.
|
|
205
|
+
const actions = [];
|
|
206
|
+
for (const { dir, name } of targets) {
|
|
207
|
+
for (const skill of skills) {
|
|
208
|
+
const linkPath = resolve(dir, skill.folderName);
|
|
209
|
+
const state = linkState(linkPath);
|
|
210
|
+
const action = state.kind === "absent"
|
|
211
|
+
? "created"
|
|
212
|
+
: state.kind === "symlink" && state.target === skill.sourcePath
|
|
213
|
+
? "skipped"
|
|
214
|
+
: state.kind === "symlink"
|
|
215
|
+
? "replaced"
|
|
216
|
+
: "skipped";
|
|
217
|
+
actions.push({
|
|
218
|
+
skillName: skill.name,
|
|
219
|
+
target: skill.sourcePath,
|
|
220
|
+
linkPath,
|
|
221
|
+
action,
|
|
222
|
+
harnessName: name,
|
|
223
|
+
blocked: state.kind === "other",
|
|
224
|
+
owned: state.kind === "symlink" &&
|
|
225
|
+
withinRoot(sourceRoot, linkPath, state.target),
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
const warnings = actions
|
|
230
|
+
.filter((a) => a.action === "replaced")
|
|
231
|
+
.map((a) => `Replaced a stale symlink for ${a.skillName} in ${a.harnessName}`);
|
|
232
|
+
return {
|
|
233
|
+
band,
|
|
234
|
+
sourceRoot,
|
|
235
|
+
available: skills.length > 0,
|
|
236
|
+
targets,
|
|
237
|
+
actions,
|
|
238
|
+
orphans: orphanedLinks(targets, sourceRoot, new Set(actions.map((a) => a.linkPath))),
|
|
239
|
+
skillCount: skills.length,
|
|
240
|
+
harnessCount: targets.length,
|
|
241
|
+
warnings,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Compose the (re)link effects from a detection (builds ABSOLUTE link paths
|
|
246
|
+
* itself).
|
|
247
|
+
*
|
|
248
|
+
* Built from re-runnable combinators (NOT a single-use `gen`) because `execute`
|
|
249
|
+
* interprets the task twice (preview + perform). `created` links carry an undo;
|
|
250
|
+
* a `replaced` link is delete-then-relink (idempotent); `skipped` is a no-op —
|
|
251
|
+
* and a detection where every action is `skipped` composes NOTHING, so a
|
|
252
|
+
* converged re-run performs zero filesystem mutations.
|
|
253
|
+
*
|
|
254
|
+
* @param d - The detection gathered up front.
|
|
255
|
+
* @returns A Task that mkdirs each needed target and creates/replaces links.
|
|
256
|
+
*/
|
|
257
|
+
export function composeSkills(d) {
|
|
258
|
+
const pending = d.actions.filter((a) => a.action !== "skipped");
|
|
259
|
+
if (!d.available || pending.length === 0)
|
|
260
|
+
return sequence_([]);
|
|
261
|
+
const dirs = new Set(pending.map((a) => dirname(a.linkPath)));
|
|
262
|
+
const tasks = [...dirs]
|
|
263
|
+
.sort()
|
|
264
|
+
.map((dir) => mkdir(dir, true));
|
|
265
|
+
for (const a of pending) {
|
|
266
|
+
if (a.action === "created") {
|
|
267
|
+
tasks.push(symlink(a.target, a.linkPath, { undo: deleteFile(a.linkPath) }));
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
tasks.push(deleteFile(a.linkPath));
|
|
271
|
+
tasks.push(symlink(a.target, a.linkPath, { undo: deleteFile(a.linkPath) }));
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return sequence_(tasks);
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* The links this band OWNS right now — every existing symlink pointing into the
|
|
278
|
+
* band's skill root, including dangling ones, ones already correct, and the
|
|
279
|
+
* ones no current skill accounts for. This is what removal acts on, and it is
|
|
280
|
+
* deliberately NOT the forward plan: undoing a freshly composed forward plan on
|
|
281
|
+
* an already-linked tree reversed the mkdirs and removed nothing, while
|
|
282
|
+
* reporting a step count.
|
|
283
|
+
*/
|
|
284
|
+
/**
|
|
285
|
+
* The named reason a skills row skips, shared by the setup plan and the doctor
|
|
286
|
+
* row so the two surfaces cannot word the same finding differently. Two strings
|
|
287
|
+
* for one condition is how a user ends up unsure whether they are looking at one
|
|
288
|
+
* problem or two.
|
|
289
|
+
*
|
|
290
|
+
* @param sourceRoot - The band's skill source root, already root-relative.
|
|
291
|
+
* @param band - The band being reported.
|
|
292
|
+
* @returns The reason line.
|
|
293
|
+
*/
|
|
294
|
+
export const skillsSkipReason = (sourceRoot, band) => band === "project"
|
|
295
|
+
? `no project skills (${sourceRoot} is absent)`
|
|
296
|
+
: "no skills installed";
|
|
297
|
+
export const ownedSkillLinks = (d) => [
|
|
298
|
+
...d.actions.filter((a) => a.owned),
|
|
299
|
+
...d.orphans,
|
|
300
|
+
];
|
|
301
|
+
/**
|
|
302
|
+
* Compose the removal of every owned link. Each forward effect re-asserts the
|
|
303
|
+
* link (idempotent) and carries its deletion as `undo`, which is what the undo
|
|
304
|
+
* interpreter executes — so the reversal is composed from what detection says
|
|
305
|
+
* this command owns, never from what a fresh forward plan would create.
|
|
306
|
+
*
|
|
307
|
+
* @param d - The detection gathered up front.
|
|
308
|
+
* @returns A Task whose undo removes every owned link.
|
|
309
|
+
*/
|
|
310
|
+
export function composeSkillsRemoval(d) {
|
|
311
|
+
const owned = ownedSkillLinks(d);
|
|
312
|
+
if (owned.length === 0)
|
|
313
|
+
return sequence_([]);
|
|
314
|
+
return sequence_(owned.map((a) => symlink(a.target, a.linkPath, { undo: deleteFile(a.linkPath) })));
|
|
315
|
+
}
|
|
316
|
+
//# sourceMappingURL=setupSkills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setupSkills.js","sourceRoot":"","sources":["../../../../../src/capabilities/setup/operations/setupSkills.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The setup plan — ONE structure with four readers.
|
|
3
|
+
*
|
|
4
|
+
* `--dry-run` prints it, the wizard edits its `selected` flags, progress reports
|
|
5
|
+
* one line per row as its outcome lands, and the recap is the same rows with
|
|
6
|
+
* `outcome` filled. `--format json` emits `{ scope, roots, rows }` verbatim.
|
|
7
|
+
* Doctor reads the same target table (see {@link ./targets.js}) so the two
|
|
8
|
+
* surfaces cannot disagree about what they looked at.
|
|
9
|
+
*
|
|
10
|
+
* The shape is deliberately flat and JSON-ready: no class, no live handle, no
|
|
11
|
+
* task. A row is a fact about what a run WOULD do (or, once `outcome` is set,
|
|
12
|
+
* what it did), which is why the plan can be rendered before, during, and after
|
|
13
|
+
* the run without any reader having to know which phase produced it.
|
|
14
|
+
*
|
|
15
|
+
* This module is pure data + pure derivations. It carries no import of the
|
|
16
|
+
* operations, the harnesses runtime, or React — so the renderers, the doctor
|
|
17
|
+
* checks, and the verb can all reach it without dragging anything heavy along.
|
|
18
|
+
*/
|
|
19
|
+
import { isAbsolute, relative, sep } from "node:path";
|
|
20
|
+
/** The five setup targets, in table (and therefore display) order. */
|
|
21
|
+
export const TARGET_IDS = [
|
|
22
|
+
"config",
|
|
23
|
+
"completions",
|
|
24
|
+
"lsp",
|
|
25
|
+
"mcp",
|
|
26
|
+
"skills",
|
|
27
|
+
];
|
|
28
|
+
/**
|
|
29
|
+
* Whether a plan action would touch the filesystem. `none` and `skip` are the
|
|
30
|
+
* two quiet outcomes: a converged re-run composes no effects at all, so mtimes
|
|
31
|
+
* stay untouched and a second `--yes` writes nothing.
|
|
32
|
+
*/
|
|
33
|
+
export const isActionable = (action) => action === "install" ||
|
|
34
|
+
action === "update" ||
|
|
35
|
+
action === "link" ||
|
|
36
|
+
action === "remove";
|
|
37
|
+
/**
|
|
38
|
+
* Default selection for a freshly built row: actionable rows are pre-selected,
|
|
39
|
+
* already-current rows are shown de-selected, and a skip is never selectable.
|
|
40
|
+
*/
|
|
41
|
+
export const defaultSelected = (action) => isActionable(action);
|
|
42
|
+
/** The rows a run acts on: selected, and not a skip. */
|
|
43
|
+
export const selectedRows = (plan) => plan.rows.filter((row) => row.selected && row.action !== "skip");
|
|
44
|
+
/**
|
|
45
|
+
* THE exit rule (and the reason it is stated once, here): a run fails only when
|
|
46
|
+
* a selected row was attempted and did not happen. Every selected row ending
|
|
47
|
+
* `done`, `noop` or `skipped` exits 0 — including a headless box where nothing
|
|
48
|
+
* is installable, because a skip is "nothing to do here, honestly named", the
|
|
49
|
+
* same semantics doctor gives its skip glyph. Punishing a converged or benignly
|
|
50
|
+
* empty state with a non-zero exit makes a dotfiles script fail on a machine
|
|
51
|
+
* with an exotic shell, which teaches people to ignore the exit code.
|
|
52
|
+
*
|
|
53
|
+
* @param plan - The plan, with outcomes filled in.
|
|
54
|
+
* @returns Whether any selected row ended `failed`.
|
|
55
|
+
*/
|
|
56
|
+
export const planExitFailed = (plan) => plan.rows.some((row) => row.outcome?.status === "failed");
|
|
57
|
+
/**
|
|
58
|
+
* `N of M targets` — the recap headline's counts.
|
|
59
|
+
*
|
|
60
|
+
* M is the rows this run took RESPONSIBILITY for: every row that reached an
|
|
61
|
+
* outcome other than `skipped`. That is deliberately not "rows with the checkbox
|
|
62
|
+
* ticked". An already-current row is offered de-selected because there is
|
|
63
|
+
* nothing to do to it, so counting ticks reported a fully converged machine as
|
|
64
|
+
* `0 of 0 configured` — a sentence that describes a machine where nothing
|
|
65
|
+
* worked exactly as it describes one where everything already did.
|
|
66
|
+
*
|
|
67
|
+
* Skips stay out of both counts: a target that cannot act on this machine is
|
|
68
|
+
* neither a success nor a shortfall, and it is already named on its own row.
|
|
69
|
+
* A row the user deselected has no outcome at all and is likewise absent.
|
|
70
|
+
*
|
|
71
|
+
* @param plan - The plan, with outcomes filled in.
|
|
72
|
+
* @returns The headline's numerator and denominator.
|
|
73
|
+
*/
|
|
74
|
+
export function planTally(plan) {
|
|
75
|
+
const accountable = plan.rows.filter((row) => row.outcome !== undefined && row.outcome.status !== "skipped");
|
|
76
|
+
const configured = accountable.filter((row) => row.outcome?.status === "done" ||
|
|
77
|
+
row.outcome?.status === "noop" ||
|
|
78
|
+
row.outcome?.status === "removed" ||
|
|
79
|
+
row.outcome?.status === "kept");
|
|
80
|
+
return { configured: configured.length, accountable: accountable.length };
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Render one absolute path relative to whichever root contains it — the header
|
|
84
|
+
* names both roots once, so a row never repeats a 120-character prefix. The
|
|
85
|
+
* global root prints as `~`; the project root prints as `.`. A path under
|
|
86
|
+
* neither root stays absolute, because shortening it would be a guess — and a
|
|
87
|
+
* sibling directory whose name merely EXTENDS a root's is under neither.
|
|
88
|
+
*
|
|
89
|
+
* The project root is tried FIRST: a project checked out inside the home
|
|
90
|
+
* directory sits under both, and the more specific root is the informative one.
|
|
91
|
+
*
|
|
92
|
+
* @param path - An absolute path.
|
|
93
|
+
* @param roots - The plan's two named roots.
|
|
94
|
+
* @returns The root-relative rendering.
|
|
95
|
+
*/
|
|
96
|
+
export function shortenPath(path, roots) {
|
|
97
|
+
for (const [root, marker] of [
|
|
98
|
+
[roots.project, "."],
|
|
99
|
+
[roots.global, "~"],
|
|
100
|
+
]) {
|
|
101
|
+
if (!root)
|
|
102
|
+
continue;
|
|
103
|
+
if (path === root)
|
|
104
|
+
return marker;
|
|
105
|
+
// Containment is a question about path SEGMENTS, and the separator is the
|
|
106
|
+
// host's. Testing `startsWith(root + "/")` answered no for every Windows
|
|
107
|
+
// path `node:path` produces, so the plan printed absolute paths where it
|
|
108
|
+
// had just named the root they sit under — and it answered YES for a
|
|
109
|
+
// sibling whose name merely extends the root's.
|
|
110
|
+
const rel = relative(root, path);
|
|
111
|
+
if (rel.length === 0 ||
|
|
112
|
+
rel === ".." ||
|
|
113
|
+
rel.startsWith(`..${sep}`) ||
|
|
114
|
+
isAbsolute(rel)) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
return `${marker}${sep}${rel}`;
|
|
118
|
+
}
|
|
119
|
+
return path;
|
|
120
|
+
}
|
|
121
|
+
/** Replace a row's outcome, leaving every other field untouched. */
|
|
122
|
+
export const withOutcome = (row, outcome) => ({
|
|
123
|
+
...row,
|
|
124
|
+
outcome,
|
|
125
|
+
});
|
|
126
|
+
/** Replace a plan's rows (the wizard's edit, and the apply phase's fill-in). */
|
|
127
|
+
export const withRows = (plan, rows) => ({ ...plan, rows });
|
|
128
|
+
//# sourceMappingURL=plan.js.map
|