@canonical/pragma-cli 0.34.0 → 0.36.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/bundled-skills/add-standard/SKILL.md +338 -0
- package/bundled-skills/adoption-a1-styles/SKILL.md +269 -0
- package/bundled-skills/adoption-a2-components/SKILL.md +291 -0
- package/bundled-skills/adoption-a3-forms/SKILL.md +260 -0
- package/bundled-skills/anatomy-author/ANATOMY_DSL_SPEC.md +406 -0
- package/bundled-skills/anatomy-author/SKILL.md +1226 -0
- package/bundled-skills/design-auditor/SKILL.md +455 -0
- package/bundled-skills/implement-component/SKILL.md +333 -0
- package/bundled-skills/specify-component/SKILL.md +331 -0
- package/bundled-skills/specify-pattern/SKILL.md +292 -0
- package/dist/.build-ok +0 -0
- package/dist/package.json +84 -0
- package/dist/pragma.conf.js +1016 -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 +294 -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 +148 -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/harnessInventory.js +195 -0
- package/dist/src/capabilities/doctor/checks/harnessInventory.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 +349 -0
- package/dist/src/capabilities/doctor/checks/targetHealth.js.map +1 -0
- package/dist/src/capabilities/doctor/doctor.render.js +164 -0
- package/dist/src/capabilities/doctor/doctor.render.js.map +1 -0
- package/dist/src/capabilities/doctor/doctor.verb.js +49 -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 +86 -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 +72 -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 +57 -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 +172 -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 +390 -0
- package/dist/src/capabilities/setup/operations/setupGenerator.js.map +1 -0
- package/dist/src/capabilities/setup/operations/setupLsp.js +329 -0
- package/dist/src/capabilities/setup/operations/setupLsp.js.map +1 -0
- package/dist/src/capabilities/setup/operations/setupMcp.js +253 -0
- package/dist/src/capabilities/setup/operations/setupMcp.js.map +1 -0
- package/dist/src/capabilities/setup/operations/setupSkills.js +594 -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 +271 -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 +387 -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 +328 -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/index.js +27 -0
- package/dist/src/capabilities/shared/index.js.map +1 -0
- package/dist/src/capabilities/shared/packageManager.js +349 -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 +281 -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 +309 -0
- package/dist/src/capabilities/sources/installSkills.js.map +1 -0
- package/dist/src/capabilities/sources/runUpdate.js +460 -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 +135 -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 +52 -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 +87 -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 +34 -0
- package/dist/src/kernel/index.js.map +1 -0
- package/dist/src/kernel/interactivity.js +68 -0
- package/dist/src/kernel/interactivity.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 +274 -0
- package/dist/src/kernel/packs/resolveEntity.js.map +1 -0
- package/dist/src/kernel/packs/runBodies.js +140 -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 +421 -0
- package/dist/src/kernel/packs/schema.js.map +1 -0
- package/dist/src/kernel/packs/sparql/applyFilters.js +167 -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 +480 -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 +219 -0
- package/dist/src/kernel/project/cli/globalFlags.js.map +1 -0
- package/dist/src/kernel/project/cli/helpFormat.js +58 -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 +227 -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 +315 -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 +105 -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/vocabulary.js +174 -0
- package/dist/src/kernel/render/vocabulary.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 +22 -23
- package/pragma.conf.ts +486 -90
- package/src/bin.ts +274 -82
- package/src/capabilities/block.parity.test.ts +29 -12
- package/src/capabilities/block.shipped.exec.test.ts +282 -0
- package/src/capabilities/block.tierRank.exec.test.ts +300 -0
- 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 +24 -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.parity.test.ts +4 -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 +75 -8
- package/src/capabilities/doctor/checks/checkPragmaVersion.ts +2 -2
- package/src/capabilities/doctor/checks/checkShellCompletions.test.ts +76 -29
- package/src/capabilities/doctor/checks/checkShellCompletions.ts +63 -17
- package/src/capabilities/doctor/checks/harnessInventory.test.ts +219 -0
- package/src/capabilities/doctor/checks/harnessInventory.ts +298 -0
- 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 +444 -0
- package/src/capabilities/doctor/doctor.render.test.ts +125 -38
- package/src/capabilities/doctor/doctor.render.ts +74 -74
- package/src/capabilities/doctor/doctor.test.ts +338 -37
- package/src/capabilities/doctor/doctor.verb.ts +8 -3
- package/src/capabilities/doctor/runChecks.ts +65 -63
- package/src/capabilities/doctor/types.ts +22 -15
- package/src/capabilities/emptyRecovery.test.ts +21 -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 +13 -5
- package/src/capabilities/info/info.render.ts +7 -3
- package/src/capabilities/info/info.test.ts +37 -1
- package/src/capabilities/info/info.verb.ts +1 -1
- package/src/capabilities/info/types.ts +10 -2
- 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/renderVocabularySync.test.ts +82 -0
- package/src/capabilities/resources/provider.ts +342 -85
- package/src/capabilities/resources/resources.test.ts +355 -59
- package/src/capabilities/scopeTypeSync.test.ts +29 -15
- package/src/capabilities/setup/buildPlan.ts +240 -0
- package/src/capabilities/setup/index.ts +7 -7
- package/src/capabilities/setup/mode.ts +74 -0
- package/src/capabilities/setup/operations/index.ts +79 -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 +478 -334
- package/src/capabilities/setup/operations/setupLsp.ts +420 -67
- package/src/capabilities/setup/operations/setupMcp.ts +238 -127
- package/src/capabilities/setup/operations/setupSkills.ts +667 -105
- package/src/capabilities/setup/plan.render.ts +336 -0
- package/src/capabilities/setup/plan.ts +241 -0
- package/src/capabilities/setup/setup.mcp.correctness.test.ts +432 -0
- package/src/capabilities/setup/setup.render.test.ts +297 -75
- package/src/capabilities/setup/setup.render.ts +45 -77
- package/src/capabilities/setup/setup.test.ts +1819 -225
- package/src/capabilities/setup/setup.verb.ts +288 -78
- package/src/capabilities/setup/shell.test.ts +86 -0
- package/src/capabilities/setup/shell.ts +137 -11
- package/src/capabilities/setup/targets.ts +435 -0
- package/src/capabilities/setup/types.ts +23 -70
- package/src/capabilities/shared/assertExecOk.ts +68 -10
- package/src/capabilities/shared/index.ts +43 -0
- package/src/capabilities/shared/packageManager.test.ts +470 -0
- package/src/capabilities/shared/packageManager.ts +425 -34
- package/src/capabilities/skill/bundledSkills.test.ts +347 -0
- package/src/capabilities/skill/discover.ts +131 -10
- package/src/capabilities/skill/index.ts +1 -1
- package/src/capabilities/skill/render.ts +10 -9
- package/src/capabilities/skill/skill.test.ts +22 -7
- 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 +265 -10
- package/src/capabilities/sources/runUpdate.ts +131 -23
- package/src/capabilities/sources/sources.test.ts +382 -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 +4 -4
- package/src/capabilities/surface.test.ts +136 -19
- package/src/capabilities/upgrade/runUpgrade.ts +53 -14
- package/src/capabilities/upgrade/types.ts +10 -2
- package/src/capabilities/upgrade/upgrade.render.ts +13 -7
- package/src/capabilities/upgrade/upgrade.test.ts +75 -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 +36 -1
- package/src/identity.test.ts +57 -29
- 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 +16 -3
- 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 +50 -35
- 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 +27 -3
- 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 +35 -0
- package/src/kernel/interactivity.test.ts +76 -0
- package/src/kernel/interactivity.ts +69 -0
- package/src/kernel/packs/collect.ts +12 -16
- package/src/kernel/packs/compile.test.ts +222 -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 +25 -6
- package/src/kernel/packs/resolveEntity.test.ts +274 -0
- package/src/kernel/packs/resolveEntity.ts +200 -42
- package/src/kernel/packs/runBodies.ts +86 -22
- package/src/kernel/packs/sample.ts +1 -1
- package/src/kernel/packs/schema.ts +78 -5
- package/src/kernel/packs/sparql/applyFilters.ts +136 -16
- package/src/kernel/packs/sparql/buildLookupQuery.test.ts +290 -0
- package/src/kernel/packs/sparql/buildLookupQuery.ts +367 -17
- 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 +77 -4
- package/src/kernel/packs/types.ts +136 -0
- package/src/kernel/packs/uniqueness.ts +1 -1
- package/src/kernel/project/cli/buildProgram.test.ts +218 -12
- package/src/kernel/project/cli/buildProgram.ts +84 -18
- package/src/kernel/project/cli/constants.ts +34 -0
- package/src/kernel/project/cli/dispatch.test.ts +160 -2
- package/src/kernel/project/cli/dispatch.ts +226 -45
- 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 +134 -31
- package/src/kernel/project/cli/helpFormat.ts +14 -2
- package/src/kernel/project/cli/rootHelp.ts +74 -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 +55 -10
- 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 +59 -6
- package/src/kernel/render/turtle.ts +222 -0
- package/src/kernel/render/vocabulary.ts +276 -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 +277 -4
- package/src/testing/PARITY_GAPS.ts +9 -3
- package/src/testing/behavioral/docExamples.test.ts +16 -0
- package/src/testing/behavioral/errorMatrix.mcp.test.ts +112 -9
- 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.firstInstall.test.ts +7 -2
- 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 +10 -7
- 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/__snapshots__/eval.test.ts.snap +26 -1
- package/src/testing/eval/cases/effectful.ts +3 -2
- package/src/testing/eval/cases/readNouns.ts +245 -9
- package/src/testing/fixtures/blockGraph.ts +104 -10
- package/src/testing/fixtures/graph/canonical.ts +182 -13
- 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/capabilities/shared/bands.ts +0 -16
- package/src/kernel/config/__snapshots__/firstRun.test.ts.snap +0 -11
|
@@ -0,0 +1,865 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The mounted create grammar, end to end on the REAL bin (subprocess — the
|
|
3
|
+
* mount, the designed help, the R1 migration error, the excess guard and the
|
|
4
|
+
* refusal all live across bin.ts + buildProgram + the mount, so in-process
|
|
5
|
+
* slices would miss their composition), plus in-process pins for the
|
|
6
|
+
* dispatchPrepared refusal cell and the wizard's explicit-answer seed.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { spawnSync } from "node:child_process";
|
|
10
|
+
import { mkdirSync, mkdtempSync, readdirSync, writeFileSync } from "node:fs";
|
|
11
|
+
import { tmpdir } from "node:os";
|
|
12
|
+
import { dirname, join, resolve } from "node:path";
|
|
13
|
+
import { fileURLToPath } from "node:url";
|
|
14
|
+
import {
|
|
15
|
+
buildOptionInfo,
|
|
16
|
+
missingExplicitFlags,
|
|
17
|
+
} from "@canonical/summon-core/projection";
|
|
18
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
19
|
+
import { RECOVERY_CLI_PREFIX, VERSION } from "../../constants.js";
|
|
20
|
+
import type { GlobalFlags } from "../../kernel/runtime/types.js";
|
|
21
|
+
import { CREATE_SURFACE } from "./createSurface.generated.js";
|
|
22
|
+
import {
|
|
23
|
+
explicitLeafAnswers,
|
|
24
|
+
leafVerb,
|
|
25
|
+
resolveCreateMode,
|
|
26
|
+
topicTree,
|
|
27
|
+
} from "./mount.js";
|
|
28
|
+
|
|
29
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
30
|
+
const packageRoot = resolve(here, "../../..");
|
|
31
|
+
const pragmaBin = join(packageRoot, "src/bin.ts");
|
|
32
|
+
const freshCwd = (): string => mkdtempSync(join(tmpdir(), "pragma-grammar-"));
|
|
33
|
+
|
|
34
|
+
const FLAGS: GlobalFlags = {
|
|
35
|
+
llm: false,
|
|
36
|
+
autoLlm: false,
|
|
37
|
+
format: "plain",
|
|
38
|
+
verbose: false,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/** Spawn the real bin non-interactively in a fresh, XDG-isolated cwd. */
|
|
42
|
+
function run(args: readonly string[]): {
|
|
43
|
+
status: number | null;
|
|
44
|
+
stdout: string;
|
|
45
|
+
stderr: string;
|
|
46
|
+
cwd: string;
|
|
47
|
+
} {
|
|
48
|
+
const cwd = freshCwd();
|
|
49
|
+
const result = spawnSync("bun", [pragmaBin, ...args], {
|
|
50
|
+
cwd,
|
|
51
|
+
encoding: "utf-8",
|
|
52
|
+
input: "",
|
|
53
|
+
env: {
|
|
54
|
+
...process.env,
|
|
55
|
+
XDG_CONFIG_HOME: mkdtempSync(join(tmpdir(), "pragma-grammar-cfg-")),
|
|
56
|
+
XDG_STATE_HOME: mkdtempSync(join(tmpdir(), "pragma-grammar-state-")),
|
|
57
|
+
XDG_CACHE_HOME: mkdtempSync(join(tmpdir(), "pragma-grammar-cache-")),
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
return {
|
|
61
|
+
status: result.status,
|
|
62
|
+
stdout: result.stdout ?? "",
|
|
63
|
+
stderr: result.stderr ?? "",
|
|
64
|
+
cwd,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
describe("the mounted create grammar (subprocess)", () => {
|
|
69
|
+
it("bare `create` prints the topic tree and exits 0", () => {
|
|
70
|
+
const { status, stdout } = run(["create"]);
|
|
71
|
+
expect(status).toBe(0);
|
|
72
|
+
expect(stdout).toContain("component");
|
|
73
|
+
expect(stdout).toContain("react");
|
|
74
|
+
expect(stdout).toContain("svelte");
|
|
75
|
+
expect(stdout).toContain("lit");
|
|
76
|
+
expect(stdout).toContain("package");
|
|
77
|
+
expect(stdout).toContain("application");
|
|
78
|
+
// Derived from the manifest: paths + descriptions.
|
|
79
|
+
expect(stdout).toContain(
|
|
80
|
+
CREATE_SURFACE["component/react"]?.description ?? "",
|
|
81
|
+
);
|
|
82
|
+
}, 60_000);
|
|
83
|
+
|
|
84
|
+
it("`create --help` prints the same topic tree, exit 0", () => {
|
|
85
|
+
const bare = run(["create"]);
|
|
86
|
+
const help = run(["create", "--help"]);
|
|
87
|
+
expect(help.status).toBe(0);
|
|
88
|
+
// Same tree; Commander's help path appends one extra blank line.
|
|
89
|
+
expect(help.stdout.trimEnd()).toBe(bare.stdout.trimEnd());
|
|
90
|
+
}, 60_000);
|
|
91
|
+
|
|
92
|
+
it("a bare namespace mirrors summon: Commander help on stderr, exit 1", () => {
|
|
93
|
+
const { status, stdout, stderr } = run(["create", "component"]);
|
|
94
|
+
expect(status).toBe(1);
|
|
95
|
+
expect(stdout).toBe("");
|
|
96
|
+
expect(stderr).toContain("Usage:");
|
|
97
|
+
expect(stderr).toContain("react");
|
|
98
|
+
expect(stderr).toContain("svelte");
|
|
99
|
+
expect(stderr).toContain("lit");
|
|
100
|
+
}, 60_000);
|
|
101
|
+
|
|
102
|
+
it("R1: the old --framework grammar dies loudly, naming the new form", () => {
|
|
103
|
+
// The FACTS repro, verbatim.
|
|
104
|
+
const { status, stderr, cwd } = run([
|
|
105
|
+
"create",
|
|
106
|
+
"component",
|
|
107
|
+
"src/components/X",
|
|
108
|
+
"--framework",
|
|
109
|
+
"react",
|
|
110
|
+
]);
|
|
111
|
+
expect(status).toBe(2);
|
|
112
|
+
expect(stderr).toContain(
|
|
113
|
+
"error: unknown option '--framework' — the framework is now a path segment: " +
|
|
114
|
+
"`pragma create component <react|svelte|lit> [component-path]` (create mirrors summon).",
|
|
115
|
+
);
|
|
116
|
+
expect(readdirSync(cwd)).toEqual([]);
|
|
117
|
+
}, 60_000);
|
|
118
|
+
|
|
119
|
+
it("R1 stays scoped: `create package --framework` gets the real unknown-option error", () => {
|
|
120
|
+
// Only `create component` ever had the flag; the other bindings must
|
|
121
|
+
// keep Commander's honest unknown-option error instead of a migration
|
|
122
|
+
// message about a grammar they never spoke.
|
|
123
|
+
const { status, stderr } = run([
|
|
124
|
+
"create",
|
|
125
|
+
"package",
|
|
126
|
+
"--framework",
|
|
127
|
+
"react",
|
|
128
|
+
]);
|
|
129
|
+
expect(status).toBe(2);
|
|
130
|
+
expect(stderr).toContain("unknown option '--framework'");
|
|
131
|
+
expect(stderr).not.toContain("the framework is now a path segment");
|
|
132
|
+
}, 60_000);
|
|
133
|
+
|
|
134
|
+
it("R1 stops at the terminator: `--framework` after `--` is an operand, not the retired flag", () => {
|
|
135
|
+
// The retired-grammar scan must read only the pre-`--` span: here the
|
|
136
|
+
// parse failure is the unknown option BEFORE the terminator, and the
|
|
137
|
+
// `--framework` after it is user data — the honest error must stand
|
|
138
|
+
// instead of a migration message about a flag that was never passed.
|
|
139
|
+
const { status, stderr } = run([
|
|
140
|
+
"create",
|
|
141
|
+
"component",
|
|
142
|
+
"react",
|
|
143
|
+
"--bogus",
|
|
144
|
+
"--",
|
|
145
|
+
"--framework",
|
|
146
|
+
]);
|
|
147
|
+
expect(status).toBe(2);
|
|
148
|
+
expect(stderr).toContain("unknown option '--bogus'");
|
|
149
|
+
expect(stderr).not.toContain("the framework is now a path segment");
|
|
150
|
+
}, 60_000);
|
|
151
|
+
|
|
152
|
+
it("an excess positional errors with the designed message, exit 2", () => {
|
|
153
|
+
const { status, stderr, cwd } = run([
|
|
154
|
+
"create",
|
|
155
|
+
"component",
|
|
156
|
+
"react",
|
|
157
|
+
"MyComponent",
|
|
158
|
+
"Extra",
|
|
159
|
+
"--yes",
|
|
160
|
+
]);
|
|
161
|
+
expect(status).toBe(2);
|
|
162
|
+
expect(stderr).toContain('error: unexpected argument "Extra"');
|
|
163
|
+
expect(readdirSync(cwd)).toEqual([]);
|
|
164
|
+
}, 60_000);
|
|
165
|
+
|
|
166
|
+
it("a sibling segment among the operands earns a did-you-mean", () => {
|
|
167
|
+
const { status, stderr } = run([
|
|
168
|
+
"create",
|
|
169
|
+
"component",
|
|
170
|
+
"react",
|
|
171
|
+
"svelte",
|
|
172
|
+
"X",
|
|
173
|
+
]);
|
|
174
|
+
expect(status).toBe(2);
|
|
175
|
+
expect(stderr).toContain('error: unexpected argument "X"');
|
|
176
|
+
expect(stderr).toContain("Did you mean 'pragma create component svelte'?");
|
|
177
|
+
}, 60_000);
|
|
178
|
+
|
|
179
|
+
it("an unknown segment beneath a namespace names itself, exit 2", () => {
|
|
180
|
+
const { status, stderr } = run(["create", "component", "vue"]);
|
|
181
|
+
expect(status).toBe(2);
|
|
182
|
+
expect(stderr).toContain("error: unknown command 'vue'");
|
|
183
|
+
}, 60_000);
|
|
184
|
+
|
|
185
|
+
// The projection's two usage errors were the LAST create failure class
|
|
186
|
+
// still writing raw prose under an explicit machine format (round-1 M5
|
|
187
|
+
// closed the refusal; unknown option/verb already enveloped). The host
|
|
188
|
+
// writer reframes them under writeRefusal's exact condition — explicit
|
|
189
|
+
// `--format json`/`--format llm` only — with bin.ts's code taxonomy:
|
|
190
|
+
// unknown command → UNKNOWN_VERB, excess/usage → INVALID_INPUT — and a
|
|
191
|
+
// single prefix-stripped `message` line. The match serializes PER KIND:
|
|
192
|
+
// an unknown segment is a FUZZY match, so its bare candidate rides in
|
|
193
|
+
// `suggestions` (substitutable for the token the message names —
|
|
194
|
+
// ErrorPayload.suggestions' convention, matching bin.ts's UNKNOWN_VERB
|
|
195
|
+
// tier); an excess positional's match is NOT substitutable (it may BE
|
|
196
|
+
// the stray its own message calls unexpected), so that kind omits
|
|
197
|
+
// `suggestions` and carries the runnable correction as `recovery.cli` —
|
|
198
|
+
// the same command the DEFAULT prose did-you-mean line names.
|
|
199
|
+
it("the unknown-segment error envelopes under --format json — UNKNOWN_VERB with the bare segment in `suggestions`", () => {
|
|
200
|
+
const { status, stderr, cwd } = run([
|
|
201
|
+
"create",
|
|
202
|
+
"component",
|
|
203
|
+
"reakt",
|
|
204
|
+
"--format",
|
|
205
|
+
"json",
|
|
206
|
+
]);
|
|
207
|
+
expect(status).toBe(2);
|
|
208
|
+
const line = stderr
|
|
209
|
+
.split("\n")
|
|
210
|
+
.find((candidate) => candidate.startsWith("{"));
|
|
211
|
+
expect(line, `no JSON envelope on stderr:\n${stderr}`).toBeDefined();
|
|
212
|
+
const envelope = JSON.parse(line as string) as {
|
|
213
|
+
ok: boolean;
|
|
214
|
+
error: { code: string; message: string; suggestions?: string[] };
|
|
215
|
+
};
|
|
216
|
+
expect(envelope.ok).toBe(false);
|
|
217
|
+
expect(envelope.error.code).toBe("UNKNOWN_VERB");
|
|
218
|
+
// SINGLE line — an agent rendering `message` never meets an embedded
|
|
219
|
+
// newline, and the structured match sits where every other pragma
|
|
220
|
+
// fuzzy-match error puts it, in the field's convention: the bare
|
|
221
|
+
// candidate token, exactly as `pragma blok --format json` serializes.
|
|
222
|
+
expect(envelope.error.message).toBe("unknown command 'reakt'");
|
|
223
|
+
expect(envelope.error.suggestions).toEqual(["react"]);
|
|
224
|
+
expect(readdirSync(cwd)).toEqual([]);
|
|
225
|
+
}, 60_000);
|
|
226
|
+
|
|
227
|
+
it("the excess-positional error envelopes under --format json — INVALID_INPUT, recovery.cli carrying the correction", () => {
|
|
228
|
+
/** Parse the one JSON line an envelope-writing spawn leaves on stderr. */
|
|
229
|
+
const envelopeOf = (stderr: string) => {
|
|
230
|
+
const line = stderr
|
|
231
|
+
.split("\n")
|
|
232
|
+
.find((candidate) => candidate.startsWith("{"));
|
|
233
|
+
expect(line, `no JSON envelope on stderr:\n${stderr}`).toBeDefined();
|
|
234
|
+
return JSON.parse(line as string) as {
|
|
235
|
+
ok: boolean;
|
|
236
|
+
error: {
|
|
237
|
+
code: string;
|
|
238
|
+
message: string;
|
|
239
|
+
suggestions?: string[];
|
|
240
|
+
recovery?: { message: string; cli?: string };
|
|
241
|
+
};
|
|
242
|
+
};
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
const { status, stderr, cwd } = run([
|
|
246
|
+
"create",
|
|
247
|
+
"component",
|
|
248
|
+
"react",
|
|
249
|
+
"MyComponent",
|
|
250
|
+
"Extra",
|
|
251
|
+
"--format",
|
|
252
|
+
"json",
|
|
253
|
+
]);
|
|
254
|
+
expect(status).toBe(2);
|
|
255
|
+
const envelope = envelopeOf(stderr);
|
|
256
|
+
expect(envelope.ok).toBe(false);
|
|
257
|
+
expect(envelope.error.code).toBe("INVALID_INPUT");
|
|
258
|
+
expect(envelope.error.message).toBe('unexpected argument "Extra"');
|
|
259
|
+
// No operand matched a segment: nothing runnable exists, so BOTH
|
|
260
|
+
// optional fields are OMITTED — exactly as serializeError drops every
|
|
261
|
+
// empty optional.
|
|
262
|
+
expect(envelope.error.suggestions).toBeUndefined();
|
|
263
|
+
expect(envelope.error.recovery).toBeUndefined();
|
|
264
|
+
expect(readdirSync(cwd)).toEqual([]);
|
|
265
|
+
|
|
266
|
+
// WITH a match the correction is STRUCTURAL, never a substitution: in
|
|
267
|
+
// `react MyThing svelte` the matched operand (`svelte`) IS the token
|
|
268
|
+
// the message calls unexpected — a `suggestions` entry here told an
|
|
269
|
+
// agent to substitute `svelte` for `svelte` and retry the same argv
|
|
270
|
+
// (round-11 F2, found by four reviewers). The kind omits `suggestions`
|
|
271
|
+
// and carries the runnable command in the covenant's `recovery.cli` —
|
|
272
|
+
// byte-for-byte the command the default prose did-you-mean names.
|
|
273
|
+
const matched = run([
|
|
274
|
+
"create",
|
|
275
|
+
"component",
|
|
276
|
+
"react",
|
|
277
|
+
"MyThing",
|
|
278
|
+
"svelte",
|
|
279
|
+
"--format",
|
|
280
|
+
"json",
|
|
281
|
+
]);
|
|
282
|
+
expect(matched.status).toBe(2);
|
|
283
|
+
const matchedEnvelope = envelopeOf(matched.stderr);
|
|
284
|
+
expect(matchedEnvelope.error.code).toBe("INVALID_INPUT");
|
|
285
|
+
expect(matchedEnvelope.error.message).toBe('unexpected argument "svelte"');
|
|
286
|
+
expect(matchedEnvelope.error.suggestions).toBeUndefined();
|
|
287
|
+
// D5's third route, pinned as the INVARIANT and not only the output:
|
|
288
|
+
// this cli is COMPUTED at the mount (chain[0] = the root program's
|
|
289
|
+
// name), bypassing cliRecovery and invisible to copy.test.ts's
|
|
290
|
+
// quoted-literal position rule — so the expectation is COMPOSED from
|
|
291
|
+
// the same constant the derivation must land on. A `startsWith` check
|
|
292
|
+
// behind an exact literal could never fail (the literal throws first
|
|
293
|
+
// on every divergence); composing the ONE expectation makes a
|
|
294
|
+
// root-program rename redden this cell naming RECOVERY_CLI_PREFIX,
|
|
295
|
+
// not a stale-looking literal a maintainer would just update.
|
|
296
|
+
expect(matchedEnvelope.error.recovery).toEqual({
|
|
297
|
+
message: "Run the corrected invocation.",
|
|
298
|
+
cli: `${RECOVERY_CLI_PREFIX}create component svelte`,
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
// The stray≠suggestion shape — `react svelte X` binds `svelte` as the
|
|
302
|
+
// positional and overflows `X` — carries the SAME correction while its
|
|
303
|
+
// message names an operand the correction never mentions: the shape
|
|
304
|
+
// that made a bare `suggestions` token unactionable.
|
|
305
|
+
const crossed = run([
|
|
306
|
+
"create",
|
|
307
|
+
"component",
|
|
308
|
+
"react",
|
|
309
|
+
"svelte",
|
|
310
|
+
"X",
|
|
311
|
+
"--format",
|
|
312
|
+
"json",
|
|
313
|
+
]);
|
|
314
|
+
expect(crossed.status).toBe(2);
|
|
315
|
+
const crossedEnvelope = envelopeOf(crossed.stderr);
|
|
316
|
+
expect(crossedEnvelope.error.code).toBe("INVALID_INPUT");
|
|
317
|
+
expect(crossedEnvelope.error.message).toBe('unexpected argument "X"');
|
|
318
|
+
expect(crossedEnvelope.error.suggestions).toBeUndefined();
|
|
319
|
+
expect(crossedEnvelope.error.recovery).toEqual({
|
|
320
|
+
message: "Run the corrected invocation.",
|
|
321
|
+
cli: `${RECOVERY_CLI_PREFIX}create component svelte`,
|
|
322
|
+
});
|
|
323
|
+
}, 60_000);
|
|
324
|
+
|
|
325
|
+
it("the excess-positional recovery renders under --format llm through the renderer's own Recovery row", () => {
|
|
326
|
+
const { status, stderr } = run([
|
|
327
|
+
"create",
|
|
328
|
+
"component",
|
|
329
|
+
"react",
|
|
330
|
+
"MyThing",
|
|
331
|
+
"svelte",
|
|
332
|
+
"--format",
|
|
333
|
+
"llm",
|
|
334
|
+
]);
|
|
335
|
+
expect(status).toBe(2);
|
|
336
|
+
expect(stderr).toContain("## Error: INVALID_INPUT");
|
|
337
|
+
expect(stderr).toContain('unexpected argument "svelte"');
|
|
338
|
+
// renderErrorLlm's existing recovery framing — no Suggestions row for
|
|
339
|
+
// this kind, and no bespoke framing invented for it.
|
|
340
|
+
expect(stderr).toContain(
|
|
341
|
+
"Recovery: Run the corrected invocation. `pragma create component svelte`",
|
|
342
|
+
);
|
|
343
|
+
expect(stderr).not.toContain("Suggestions:");
|
|
344
|
+
expect(stderr).not.toContain("Did you mean");
|
|
345
|
+
}, 60_000);
|
|
346
|
+
|
|
347
|
+
it("a NAMESPACE match ships no recovery — `package`'s only siblings cannot scaffold, so the covenant's run-to-recover field never names one", () => {
|
|
348
|
+
// The one declared leaf whose siblings are namespaces: from `package`,
|
|
349
|
+
// a matched operand can only be `component`/`application` — and a bare
|
|
350
|
+
// namespace exits 1 with a help page in every format (§2), so a
|
|
351
|
+
// recovery.cli naming it told an agent to "run" a command that cannot
|
|
352
|
+
// scaffold (pre-gate this envelope carried
|
|
353
|
+
// cli: "pragma create component"; measured red before the fix). The
|
|
354
|
+
// mount's runnability gate (CREATE_SURFACE lookup) drops the recovery;
|
|
355
|
+
// like the no-match arm, the envelope then carries NEITHER optional
|
|
356
|
+
// field.
|
|
357
|
+
const { status, stderr, cwd } = run([
|
|
358
|
+
"create",
|
|
359
|
+
"package",
|
|
360
|
+
"component",
|
|
361
|
+
"--format",
|
|
362
|
+
"json",
|
|
363
|
+
]);
|
|
364
|
+
expect(status).toBe(2);
|
|
365
|
+
const line = stderr
|
|
366
|
+
.split("\n")
|
|
367
|
+
.find((candidate) => candidate.startsWith("{"));
|
|
368
|
+
expect(line, `no JSON envelope on stderr:\n${stderr}`).toBeDefined();
|
|
369
|
+
const envelope = JSON.parse(line as string) as {
|
|
370
|
+
ok: boolean;
|
|
371
|
+
error: {
|
|
372
|
+
code: string;
|
|
373
|
+
message: string;
|
|
374
|
+
suggestions?: string[];
|
|
375
|
+
recovery?: unknown;
|
|
376
|
+
};
|
|
377
|
+
};
|
|
378
|
+
expect(envelope.ok).toBe(false);
|
|
379
|
+
expect(envelope.error.code).toBe("INVALID_INPUT");
|
|
380
|
+
expect(envelope.error.message).toBe('unexpected argument "component"');
|
|
381
|
+
expect(envelope.error.suggestions).toBeUndefined();
|
|
382
|
+
expect(envelope.error.recovery).toBeUndefined();
|
|
383
|
+
expect(readdirSync(cwd)).toEqual([]);
|
|
384
|
+
|
|
385
|
+
// The DEFAULT prose keeps the navigation hint unchanged: an
|
|
386
|
+
// interrogative did-you-mean pointing at the namespace is fine — the
|
|
387
|
+
// delta was only ever the machine-format imperative.
|
|
388
|
+
const prose = run(["create", "package", "component"]);
|
|
389
|
+
expect(prose.status).toBe(2);
|
|
390
|
+
expect(prose.stderr).toContain('error: unexpected argument "component"');
|
|
391
|
+
expect(prose.stderr).toContain("Did you mean 'pragma create component'?");
|
|
392
|
+
expect(readdirSync(prose.cwd)).toEqual([]);
|
|
393
|
+
}, 60_000);
|
|
394
|
+
|
|
395
|
+
it("bin-tier usage errors envelope under --format llm too — the unknown option and the --framework migration error", () => {
|
|
396
|
+
// Before the hoist the machine-format decision existed as four copies
|
|
397
|
+
// under TWO gates: bin.ts's two sites enveloped on json ONLY, so under
|
|
398
|
+
// --format llm an excess positional enveloped while an unknown option
|
|
399
|
+
// and the --framework migration error stayed raw prose — one taxonomy
|
|
400
|
+
// class, split. All five usage-error sites (these two, the
|
|
401
|
+
// unknown-command arm, and the projection writer's two classes) now
|
|
402
|
+
// share renderErrorForFormat; the unknown-command member is pinned by
|
|
403
|
+
// its own cells below.
|
|
404
|
+
const bogus = run(["create", "package", "--bogus", "--format", "llm"]);
|
|
405
|
+
expect(bogus.status).toBe(2);
|
|
406
|
+
expect(bogus.stderr).toContain("## Error: INVALID_INPUT");
|
|
407
|
+
expect(bogus.stderr).toContain("unknown option '--bogus'");
|
|
408
|
+
|
|
409
|
+
const framework = run([
|
|
410
|
+
"create",
|
|
411
|
+
"component",
|
|
412
|
+
"src/components/X",
|
|
413
|
+
"--framework",
|
|
414
|
+
"react",
|
|
415
|
+
"--format",
|
|
416
|
+
"llm",
|
|
417
|
+
]);
|
|
418
|
+
expect(framework.status).toBe(2);
|
|
419
|
+
expect(framework.stderr).toContain("## Error: INVALID_INPUT");
|
|
420
|
+
expect(framework.stderr).toContain("the framework is now a path segment");
|
|
421
|
+
}, 60_000);
|
|
422
|
+
|
|
423
|
+
it("the unknown-segment error under --format llm carries the condensed framing with a Suggestions line", () => {
|
|
424
|
+
const { status, stderr } = run([
|
|
425
|
+
"create",
|
|
426
|
+
"component",
|
|
427
|
+
"reakt",
|
|
428
|
+
"--format",
|
|
429
|
+
"llm",
|
|
430
|
+
]);
|
|
431
|
+
expect(status).toBe(2);
|
|
432
|
+
expect(stderr).toContain("## Error: UNKNOWN_VERB");
|
|
433
|
+
expect(stderr).toContain("unknown command 'reakt'");
|
|
434
|
+
// The renderer's own Suggestions row — not a third prose line — with
|
|
435
|
+
// the bare candidate segment, the field's one convention.
|
|
436
|
+
expect(stderr).toContain("Suggestions: react");
|
|
437
|
+
expect(stderr).not.toContain("Did you mean");
|
|
438
|
+
}, 60_000);
|
|
439
|
+
|
|
440
|
+
it("the bin-tier unknown command envelopes under --format llm — UNKNOWN_VERB with bare-token suggestions", () => {
|
|
441
|
+
// The unknown-command arm was the last handleProgramError site off
|
|
442
|
+
// renderErrorForFormat: under an explicit --format llm a typo'd verb
|
|
443
|
+
// (`pragma blok`) rendered the plain prose while its create-tier
|
|
444
|
+
// sibling (`create component reakt`) enveloped — one code, two gates.
|
|
445
|
+
const { status, stderr } = run(["blok", "--format", "llm"]);
|
|
446
|
+
expect(status).toBe(2);
|
|
447
|
+
expect(stderr).toContain("## Error: UNKNOWN_VERB");
|
|
448
|
+
expect(stderr).toContain('Unknown command "blok".');
|
|
449
|
+
expect(stderr).toContain("Suggestions: block");
|
|
450
|
+
expect(stderr).not.toContain("Did you mean");
|
|
451
|
+
}, 60_000);
|
|
452
|
+
|
|
453
|
+
it("the bin-tier unknown command envelopes under --format json — bare-token suggestions, byte-stable", () => {
|
|
454
|
+
const { status, stderr } = run(["blok", "--format", "json"]);
|
|
455
|
+
expect(status).toBe(2);
|
|
456
|
+
const line = stderr
|
|
457
|
+
.split("\n")
|
|
458
|
+
.find((candidate) => candidate.startsWith("{"));
|
|
459
|
+
expect(line, `no JSON envelope on stderr:\n${stderr}`).toBeDefined();
|
|
460
|
+
const envelope = JSON.parse(line as string) as {
|
|
461
|
+
ok: boolean;
|
|
462
|
+
error: { code: string; message: string; suggestions?: string[] };
|
|
463
|
+
};
|
|
464
|
+
expect(envelope.ok).toBe(false);
|
|
465
|
+
expect(envelope.error.code).toBe("UNKNOWN_VERB");
|
|
466
|
+
expect(envelope.error.message).toBe('Unknown command "blok".');
|
|
467
|
+
// The bare candidate token — the same convention the create tier's
|
|
468
|
+
// envelope carries, so one code has one `suggestions` shape.
|
|
469
|
+
expect(envelope.error.suggestions).toEqual(["block"]);
|
|
470
|
+
}, 60_000);
|
|
471
|
+
|
|
472
|
+
it("DEFAULT piped output for both projection usage errors stays the raw prose — full stderr, no envelope", () => {
|
|
473
|
+
// Full-stderr byte-equality needs a quiet stream: seed the global config
|
|
474
|
+
// so the one-time first-run note (stderr by design) does not fire.
|
|
475
|
+
const configHome = mkdtempSync(join(tmpdir(), "pragma-grammar-cfg-"));
|
|
476
|
+
mkdirSync(join(configHome, "pragma"));
|
|
477
|
+
writeFileSync(join(configHome, "pragma", "config.json"), "{}\n");
|
|
478
|
+
const spawn = (args: readonly string[]) =>
|
|
479
|
+
spawnSync("bun", [pragmaBin, ...args], {
|
|
480
|
+
cwd: freshCwd(),
|
|
481
|
+
encoding: "utf-8",
|
|
482
|
+
input: "",
|
|
483
|
+
env: {
|
|
484
|
+
...process.env,
|
|
485
|
+
XDG_CONFIG_HOME: configHome,
|
|
486
|
+
XDG_STATE_HOME: mkdtempSync(join(tmpdir(), "pragma-grammar-state-")),
|
|
487
|
+
XDG_CACHE_HOME: mkdtempSync(join(tmpdir(), "pragma-grammar-cache-")),
|
|
488
|
+
},
|
|
489
|
+
});
|
|
490
|
+
const segment = spawn(["create", "component", "reakt"]);
|
|
491
|
+
expect(segment.status).toBe(2);
|
|
492
|
+
expect(segment.stderr).toBe(
|
|
493
|
+
"error: unknown command 'reakt'\n" +
|
|
494
|
+
"Did you mean 'pragma create component react'?\n",
|
|
495
|
+
);
|
|
496
|
+
const excess = spawn(["create", "component", "react", "MyComponent", "X"]);
|
|
497
|
+
expect(excess.status).toBe(2);
|
|
498
|
+
expect(excess.stderr).toBe('error: unexpected argument "X"\n');
|
|
499
|
+
}, 60_000);
|
|
500
|
+
|
|
501
|
+
it("`-v` is an unknown option in the subtree — exit 2, nothing written (§2)", () => {
|
|
502
|
+
// summon's `-v` is `--verbose` (its run proceeds); pragma has no short
|
|
503
|
+
// flags at all — one spelling per flag — so the token reaches the
|
|
504
|
+
// subtree and fails as an ordinary unknown option instead of silently
|
|
505
|
+
// meaning something else. This cell keeps the divergence deliberate,
|
|
506
|
+
// not accidental (the host flag surface is bin.ts's — out of CIS scope;
|
|
507
|
+
// the covenant freezes neither token).
|
|
508
|
+
const { status, stdout, stderr, cwd } = run([
|
|
509
|
+
"create",
|
|
510
|
+
"component",
|
|
511
|
+
"react",
|
|
512
|
+
"src/components/X",
|
|
513
|
+
"-v",
|
|
514
|
+
"--yes",
|
|
515
|
+
]);
|
|
516
|
+
expect(status).toBe(2);
|
|
517
|
+
expect(stdout).toBe("");
|
|
518
|
+
expect(stderr).toContain("error: unknown option '-v'");
|
|
519
|
+
expect(readdirSync(cwd)).toEqual([]);
|
|
520
|
+
}, 60_000);
|
|
521
|
+
|
|
522
|
+
it("the confirm convention is summon's: --no-with-styles is accepted, --with-styles is not", () => {
|
|
523
|
+
const accepted = run([
|
|
524
|
+
"create",
|
|
525
|
+
"component",
|
|
526
|
+
"react",
|
|
527
|
+
"src/components/W",
|
|
528
|
+
"--no-with-styles",
|
|
529
|
+
"--dry-run",
|
|
530
|
+
]);
|
|
531
|
+
expect(accepted.status).toBe(0);
|
|
532
|
+
expect(accepted.stdout).toContain("Dry-run complete.");
|
|
533
|
+
expect(readdirSync(accepted.cwd)).toEqual([]);
|
|
534
|
+
|
|
535
|
+
const rejected = run([
|
|
536
|
+
"create",
|
|
537
|
+
"component",
|
|
538
|
+
"react",
|
|
539
|
+
"src/components/W",
|
|
540
|
+
"--with-styles",
|
|
541
|
+
"--dry-run",
|
|
542
|
+
]);
|
|
543
|
+
expect(rejected.status).toBe(2);
|
|
544
|
+
expect(rejected.stderr).toContain("--with-styles");
|
|
545
|
+
}, 60_000);
|
|
546
|
+
|
|
547
|
+
it("row 6 on the wire: a bare non-TTY leaf refuses with the shared message, exit 2", () => {
|
|
548
|
+
const { status, stderr, cwd } = run(["create", "component", "react"]);
|
|
549
|
+
expect(status).toBe(2);
|
|
550
|
+
expect(stderr).toContain(
|
|
551
|
+
"Refusing to scaffold in a non-interactive run without complete input. " +
|
|
552
|
+
"Pass --yes to accept defaults, --dry-run to preview, or provide every answer as a flag. " +
|
|
553
|
+
"Missing: --component-path, --no-with-styles, --no-with-stories, --no-with-ssr-tests.",
|
|
554
|
+
);
|
|
555
|
+
expect(readdirSync(cwd)).toEqual([]);
|
|
556
|
+
}, 60_000);
|
|
557
|
+
|
|
558
|
+
it("the refusal envelopes under --format json (D3) — never raw prose on a machine stream", () => {
|
|
559
|
+
const { status, stderr, cwd } = run([
|
|
560
|
+
"create",
|
|
561
|
+
"component",
|
|
562
|
+
"react",
|
|
563
|
+
"--format",
|
|
564
|
+
"json",
|
|
565
|
+
]);
|
|
566
|
+
expect(status).toBe(2);
|
|
567
|
+
// The one JSON line is the same {ok:false, error} envelope every other
|
|
568
|
+
// pragma error emits; the shared refusal text rides inside it.
|
|
569
|
+
const line = stderr
|
|
570
|
+
.split("\n")
|
|
571
|
+
.find((candidate) => candidate.startsWith("{"));
|
|
572
|
+
expect(line, `no JSON envelope on stderr:\n${stderr}`).toBeDefined();
|
|
573
|
+
const envelope = JSON.parse(line as string) as {
|
|
574
|
+
ok: boolean;
|
|
575
|
+
error: { code: string; message: string };
|
|
576
|
+
};
|
|
577
|
+
expect(envelope.ok).toBe(false);
|
|
578
|
+
expect(envelope.error.code).toBe("INVALID_INPUT");
|
|
579
|
+
expect(envelope.error.message).toContain(
|
|
580
|
+
"Refusing to scaffold in a non-interactive run without complete input.",
|
|
581
|
+
);
|
|
582
|
+
expect(envelope.error.message).toContain("Missing: --component-path");
|
|
583
|
+
expect(readdirSync(cwd)).toEqual([]);
|
|
584
|
+
}, 60_000);
|
|
585
|
+
|
|
586
|
+
it("the refusal envelopes under an explicit --format llm — the condensed D3 error form", () => {
|
|
587
|
+
const { status, stderr, cwd } = run([
|
|
588
|
+
"create",
|
|
589
|
+
"component",
|
|
590
|
+
"react",
|
|
591
|
+
"--format",
|
|
592
|
+
"llm",
|
|
593
|
+
]);
|
|
594
|
+
expect(status).toBe(2);
|
|
595
|
+
// The same `## Error: <code>` framing every other pragma error carries in
|
|
596
|
+
// llm form, with the shared refusal line riding beneath it.
|
|
597
|
+
expect(stderr).toContain("## Error: INVALID_INPUT");
|
|
598
|
+
expect(stderr).toContain(
|
|
599
|
+
"Refusing to scaffold in a non-interactive run without complete input.",
|
|
600
|
+
);
|
|
601
|
+
expect(readdirSync(cwd)).toEqual([]);
|
|
602
|
+
}, 60_000);
|
|
603
|
+
|
|
604
|
+
it("a DEFAULT piped refusal is the bare shared line — no envelope; auto-LLM never reframes it", () => {
|
|
605
|
+
// Full-stderr byte-equality needs a quiet stream: seed the global config
|
|
606
|
+
// so the one-time first-run note (stderr by design) does not fire.
|
|
607
|
+
const configHome = mkdtempSync(join(tmpdir(), "pragma-grammar-cfg-"));
|
|
608
|
+
mkdirSync(join(configHome, "pragma"));
|
|
609
|
+
writeFileSync(join(configHome, "pragma", "config.json"), "{}\n");
|
|
610
|
+
const cwd = freshCwd();
|
|
611
|
+
const result = spawnSync(
|
|
612
|
+
"bun",
|
|
613
|
+
[pragmaBin, "create", "component", "react"],
|
|
614
|
+
{
|
|
615
|
+
cwd,
|
|
616
|
+
encoding: "utf-8",
|
|
617
|
+
input: "",
|
|
618
|
+
env: {
|
|
619
|
+
...process.env,
|
|
620
|
+
XDG_CONFIG_HOME: configHome,
|
|
621
|
+
XDG_STATE_HOME: mkdtempSync(join(tmpdir(), "pragma-grammar-state-")),
|
|
622
|
+
XDG_CACHE_HOME: mkdtempSync(join(tmpdir(), "pragma-grammar-cache-")),
|
|
623
|
+
},
|
|
624
|
+
},
|
|
625
|
+
);
|
|
626
|
+
expect(result.status).toBe(2);
|
|
627
|
+
// Byte-equality of the WHOLE stream with the shared message (contract §3):
|
|
628
|
+
// the parity surface summon writes verbatim, with no framing line above it.
|
|
629
|
+
expect(result.stderr).toBe(
|
|
630
|
+
"Refusing to scaffold in a non-interactive run without complete input. " +
|
|
631
|
+
"Pass --yes to accept defaults, --dry-run to preview, or provide every answer as a flag. " +
|
|
632
|
+
"Missing: --component-path, --no-with-styles, --no-with-stories, --no-with-ssr-tests.\n",
|
|
633
|
+
);
|
|
634
|
+
expect(readdirSync(cwd)).toEqual([]);
|
|
635
|
+
}, 60_000);
|
|
636
|
+
|
|
637
|
+
// The refusal's own instruction WORKS — on EVERY declared leaf. Take the
|
|
638
|
+
// message's advice VERBATIM: extract the tokens the bare refusal prints,
|
|
639
|
+
// supply each back (a valid value where the registered form takes one, the
|
|
640
|
+
// `--no-` confirms bare), add --dry-run, and the same leaf must preview
|
|
641
|
+
// cleanly and write nothing. Round 14 proved the tokens PARSE; this closes
|
|
642
|
+
// the round trip: a leaf may not advertise a completion its own generator
|
|
643
|
+
// then rejects — `application/react` did exactly that (its Missing list
|
|
644
|
+
// named `--no-ssr, --no-router` and its guard refused precisely those two,
|
|
645
|
+
// a two-state loop with no all-flags exit) until the dead prompt pair was
|
|
646
|
+
// removed. Pre-round-14 the list kebab-cased prompt NAMES (`--with-styles`
|
|
647
|
+
// and friends, which no host registers), so the round-trip was `error:
|
|
648
|
+
// unknown option` — this cell reddens on either regression.
|
|
649
|
+
const REPLY_VALUES: Record<string, Record<string, string>> = {
|
|
650
|
+
"component/react": { "--component-path": "src/components/Replied" },
|
|
651
|
+
"component/svelte": { "--component-path": "src/lib/Replied" },
|
|
652
|
+
"component/lit": { "--component-path": "src/lib/Replied" },
|
|
653
|
+
package: {
|
|
654
|
+
"--name": "@canonical/replied-lib",
|
|
655
|
+
"--type": "library",
|
|
656
|
+
"--description": "A replied library.",
|
|
657
|
+
},
|
|
658
|
+
"application/react": { "--app-path": "replied-app" },
|
|
659
|
+
};
|
|
660
|
+
for (const [commandPath, surface] of Object.entries(CREATE_SURFACE)) {
|
|
661
|
+
it(`${commandPath}: the refusal's own instruction WORKS — its Missing tokens supplied back (+ --dry-run) preview, exit 0`, () => {
|
|
662
|
+
const path = commandPath.split("/");
|
|
663
|
+
const refusal = run(["create", ...path]);
|
|
664
|
+
expect(refusal.status).toBe(2);
|
|
665
|
+
const missing = /Missing: ([^\n]*)\./.exec(refusal.stderr);
|
|
666
|
+
expect(missing, `no Missing list in:\n${refusal.stderr}`).not.toBeNull();
|
|
667
|
+
const tokens = (missing as RegExpExecArray)[1]?.split(", ") ?? [];
|
|
668
|
+
// The live list IS the derivation — parsed off the wire, tied to the
|
|
669
|
+
// same authority the mount registers from (non-empty by declaration).
|
|
670
|
+
expect(tokens).toEqual(missingExplicitFlags(surface.prompts, {}));
|
|
671
|
+
expect(tokens.length).toBeGreaterThan(0);
|
|
672
|
+
// A token whose registered form takes a value gets a valid one from
|
|
673
|
+
// the table above — fail loudly on a leaf the table does not know.
|
|
674
|
+
const takesValue = new Map(
|
|
675
|
+
surface.prompts.map((prompt) => {
|
|
676
|
+
const info = buildOptionInfo(prompt);
|
|
677
|
+
return [info.flags.split(" ")[0], info.flags.includes(" ")] as const;
|
|
678
|
+
}),
|
|
679
|
+
);
|
|
680
|
+
const supplied = tokens.flatMap((token) => {
|
|
681
|
+
if (!takesValue.get(token)) return [token];
|
|
682
|
+
const value = REPLY_VALUES[commandPath]?.[token];
|
|
683
|
+
if (value === undefined) {
|
|
684
|
+
throw new Error(`no reply value for ${token} on ${commandPath}`);
|
|
685
|
+
}
|
|
686
|
+
return [token, value];
|
|
687
|
+
});
|
|
688
|
+
const replied = run(["create", ...path, ...supplied, "--dry-run"]);
|
|
689
|
+
expect(replied.stderr).not.toContain("unknown option");
|
|
690
|
+
expect(replied.status, replied.stderr).toBe(0);
|
|
691
|
+
expect(replied.stdout).toContain("Dry-run complete.");
|
|
692
|
+
expect(readdirSync(replied.cwd)).toEqual([]);
|
|
693
|
+
}, 60_000);
|
|
694
|
+
}
|
|
695
|
+
// The react list stays pinned at its exact bytes (the round-14 literal):
|
|
696
|
+
// the loop above ties every leaf to the derivation; this cell keeps one
|
|
697
|
+
// wire literal a derivation bug cannot move silently.
|
|
698
|
+
it("component/react's Missing list is the exact four registered tokens", () => {
|
|
699
|
+
const refusal = run(["create", "component", "react"]);
|
|
700
|
+
const missing = /Missing: ([^\n]*)\./.exec(refusal.stderr);
|
|
701
|
+
expect((missing as RegExpExecArray)[1]?.split(", ")).toEqual([
|
|
702
|
+
"--component-path",
|
|
703
|
+
"--no-with-styles",
|
|
704
|
+
"--no-with-stories",
|
|
705
|
+
"--no-with-ssr-tests",
|
|
706
|
+
]);
|
|
707
|
+
}, 60_000);
|
|
708
|
+
|
|
709
|
+
it("row 5 on the wire: a fully-explicit non-TTY leaf runs without --yes", () => {
|
|
710
|
+
const { status, cwd } = run([
|
|
711
|
+
"create",
|
|
712
|
+
"component",
|
|
713
|
+
"react",
|
|
714
|
+
"src/components/Widget",
|
|
715
|
+
"--no-with-styles",
|
|
716
|
+
"--no-with-stories",
|
|
717
|
+
"--no-with-ssr-tests",
|
|
718
|
+
]);
|
|
719
|
+
expect(status).toBe(0);
|
|
720
|
+
expect(readdirSync(join(cwd, "src/components/Widget"))).toContain(
|
|
721
|
+
"Widget.tsx",
|
|
722
|
+
);
|
|
723
|
+
}, 60_000);
|
|
724
|
+
|
|
725
|
+
it("the invalid-value cell echoes the offending value, exit 2", () => {
|
|
726
|
+
const { status, stderr, cwd } = run([
|
|
727
|
+
"create",
|
|
728
|
+
"component",
|
|
729
|
+
"react",
|
|
730
|
+
"not-pascal",
|
|
731
|
+
"--yes",
|
|
732
|
+
]);
|
|
733
|
+
expect(status).toBe(2);
|
|
734
|
+
expect(stderr).toContain(
|
|
735
|
+
'Invalid --component-path "not-pascal": ' +
|
|
736
|
+
"Component name must be in PascalCase",
|
|
737
|
+
);
|
|
738
|
+
expect(readdirSync(cwd)).toEqual([]);
|
|
739
|
+
}, 60_000);
|
|
740
|
+
});
|
|
741
|
+
|
|
742
|
+
describe("the refusal cell through dispatchPrepared (in-process)", () => {
|
|
743
|
+
afterEach(() => {
|
|
744
|
+
process.exitCode = 0;
|
|
745
|
+
vi.restoreAllMocks();
|
|
746
|
+
});
|
|
747
|
+
|
|
748
|
+
it("runCreate re-derives refuse and the kernel renders it, exit 2", async () => {
|
|
749
|
+
const { dispatchPrepared } = await import(
|
|
750
|
+
"../../kernel/project/cli/dispatch.js"
|
|
751
|
+
);
|
|
752
|
+
const stderr = vi
|
|
753
|
+
.spyOn(process.stderr, "write")
|
|
754
|
+
.mockImplementation(() => true);
|
|
755
|
+
await dispatchPrepared(
|
|
756
|
+
leafVerb("component/react"),
|
|
757
|
+
{},
|
|
758
|
+
{ dryRun: false, undo: false, yes: false },
|
|
759
|
+
FLAGS,
|
|
760
|
+
);
|
|
761
|
+
const written = stderr.mock.calls.map((call) => String(call[0])).join("");
|
|
762
|
+
expect(written).toContain("Refusing to scaffold in a non-interactive run");
|
|
763
|
+
expect(written).toContain("Missing: --component-path");
|
|
764
|
+
expect(process.exitCode).toBe(2);
|
|
765
|
+
}, 60_000);
|
|
766
|
+
});
|
|
767
|
+
|
|
768
|
+
describe("the mount's mode resolution — TTY driven through the seam", () => {
|
|
769
|
+
// No suite can hand a subprocess a real TTY, so the §L rows that depend on
|
|
770
|
+
// isTTY: true are pinned HERE, through the exported resolver the action
|
|
771
|
+
// itself calls (with canPrompt()). The OLD decision block routed TTY
|
|
772
|
+
// dry-run/undo into Ink; these rows keep that from silently returning.
|
|
773
|
+
const prompts = CREATE_SURFACE["component/react"]?.prompts ?? [];
|
|
774
|
+
const flags = (dryRun: boolean, undo: boolean, yes: boolean) => ({
|
|
775
|
+
dryRun,
|
|
776
|
+
undo,
|
|
777
|
+
yes,
|
|
778
|
+
});
|
|
779
|
+
|
|
780
|
+
it("TTY --dry-run resolves batch-dry-run — never an interactive preview", () => {
|
|
781
|
+
expect(
|
|
782
|
+
resolveCreateMode(prompts, {}, flags(true, false, false), true),
|
|
783
|
+
).toBe("batch-dry-run");
|
|
784
|
+
});
|
|
785
|
+
|
|
786
|
+
it("TTY --undo resolves batch-undo — never a prompting wizard", () => {
|
|
787
|
+
expect(
|
|
788
|
+
resolveCreateMode(prompts, {}, flags(false, true, false), true),
|
|
789
|
+
).toBe("batch-undo");
|
|
790
|
+
});
|
|
791
|
+
|
|
792
|
+
it("TTY --dry-run outranks --undo (the shared precedence)", () => {
|
|
793
|
+
expect(resolveCreateMode(prompts, {}, flags(true, true, false), true)).toBe(
|
|
794
|
+
"batch-dry-run",
|
|
795
|
+
);
|
|
796
|
+
});
|
|
797
|
+
|
|
798
|
+
it("a bare TTY leaf resolves wizard; the same input without a TTY refuses", () => {
|
|
799
|
+
expect(
|
|
800
|
+
resolveCreateMode(prompts, {}, flags(false, false, false), true),
|
|
801
|
+
).toBe("wizard");
|
|
802
|
+
expect(
|
|
803
|
+
resolveCreateMode(prompts, {}, flags(false, false, false), false),
|
|
804
|
+
).toBe("refuse");
|
|
805
|
+
});
|
|
806
|
+
});
|
|
807
|
+
|
|
808
|
+
describe("the wizard's seed — explicit answers only", () => {
|
|
809
|
+
const prompts = CREATE_SURFACE["component/react"]?.prompts ?? [];
|
|
810
|
+
|
|
811
|
+
it("extracts ONLY explicit answers (defaults never leak into the seed)", () => {
|
|
812
|
+
// The wizard cell asks pendingPrompts(prompts, explicit); the seed handed
|
|
813
|
+
// to runCreate must therefore be the EXPLICIT set, not defaults.
|
|
814
|
+
expect(
|
|
815
|
+
explicitLeafAnswers(prompts, undefined, {
|
|
816
|
+
withStyles: false,
|
|
817
|
+
dryRun: false,
|
|
818
|
+
}),
|
|
819
|
+
).toEqual({ withStyles: false });
|
|
820
|
+
// A confirm equal to its default is NOT explicit (Commander reports
|
|
821
|
+
// untouched --no- flags as true).
|
|
822
|
+
expect(
|
|
823
|
+
explicitLeafAnswers(prompts, undefined, { withStyles: true }),
|
|
824
|
+
).toEqual({});
|
|
825
|
+
});
|
|
826
|
+
|
|
827
|
+
it("the positional lands under its prompt name", () => {
|
|
828
|
+
expect(explicitLeafAnswers(prompts, "src/components/X", {})).toEqual({
|
|
829
|
+
componentPath: "src/components/X",
|
|
830
|
+
});
|
|
831
|
+
});
|
|
832
|
+
|
|
833
|
+
it("the topic tree lists every declared path with its description", () => {
|
|
834
|
+
const tree = topicTree("pragma");
|
|
835
|
+
for (const [commandPath, surface] of Object.entries(CREATE_SURFACE)) {
|
|
836
|
+
for (const segment of commandPath.split("/")) {
|
|
837
|
+
expect(tree).toContain(segment);
|
|
838
|
+
}
|
|
839
|
+
expect(tree).toContain(surface.description);
|
|
840
|
+
}
|
|
841
|
+
});
|
|
842
|
+
});
|
|
843
|
+
|
|
844
|
+
describe("the refusal's Missing tokens are REGISTERED flags — every declared leaf", () => {
|
|
845
|
+
// The round-14 defect: kebab-casing prompt NAMES advertised 13 of the 25
|
|
846
|
+
// tokens across the five leaves under spellings NO host registers (a
|
|
847
|
+
// default-true confirm registers ONLY `--no-<kebab>`), so following the
|
|
848
|
+
// refusal's own instruction exited 2. The pin: for every declared leaf,
|
|
849
|
+
// the bare-invocation Missing list ⊆ the long-flag set the single
|
|
850
|
+
// flag-shape authority yields for that leaf's prompts.
|
|
851
|
+
for (const [commandPath, surface] of Object.entries(CREATE_SURFACE)) {
|
|
852
|
+
it(`${commandPath}: missingExplicitFlags({}) names only buildOptionInfo's registered long forms`, () => {
|
|
853
|
+
const registered = surface.prompts.map(
|
|
854
|
+
(prompt) => buildOptionInfo(prompt).flags.split(" ")[0],
|
|
855
|
+
);
|
|
856
|
+
const missing = missingExplicitFlags(surface.prompts, {});
|
|
857
|
+
// Every declared leaf has at least one unconditional prompt, so an
|
|
858
|
+
// empty list can never green this pin vacuously.
|
|
859
|
+
expect(missing.length).toBeGreaterThan(0);
|
|
860
|
+
for (const token of missing) {
|
|
861
|
+
expect(registered).toContain(token);
|
|
862
|
+
}
|
|
863
|
+
});
|
|
864
|
+
}
|
|
865
|
+
});
|