@canonical/pragma-cli 0.33.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 +25 -24
- package/pragma.conf.ts +853 -0
- package/src/bin.ts +276 -82
- package/src/capabilities/block.parity.test.ts +253 -0
- package/src/capabilities/capabilities/capabilities.render.ts +4 -3
- package/src/capabilities/capabilities/capabilities.verb.ts +32 -14
- package/src/capabilities/capabilities/catalog.ts +20 -12
- package/src/capabilities/capabilities/hints.ts +43 -24
- package/src/capabilities/capabilities/index.ts +1 -1
- package/src/capabilities/colophon/collectColophon.ts +50 -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 +9 -5
- package/src/capabilities/colophon/types.ts +16 -7
- package/src/capabilities/config/collectConfigShow.test.ts +58 -0
- package/src/capabilities/config/collectConfigShow.ts +43 -6
- package/src/capabilities/config/field.render.ts +4 -5
- package/src/capabilities/config/fields.ts +17 -37
- 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 +14 -9
- package/src/capabilities/config/show.render.test.ts +77 -5
- package/src/capabilities/config/show.render.ts +8 -13
- package/src/capabilities/config/show.verb.ts +13 -9
- package/src/capabilities/config/types.ts +26 -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 +95 -103
- package/src/capabilities/create/cliProjection.ts +227 -0
- package/src/capabilities/create/constants.ts +50 -0
- package/src/capabilities/create/create.mcp.test.ts +91 -7
- package/src/capabilities/create/create.render.ts +71 -7
- package/src/capabilities/create/create.test.ts +523 -162
- package/src/capabilities/create/create.verb.ts +361 -321
- 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 +9 -14
- 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 +40 -46
- package/src/capabilities/create/shippedCreate.subprocess.test.ts +164 -0
- package/src/capabilities/create/types.ts +29 -5
- package/src/capabilities/{standard/parity.test.ts → distribution.parity.test.ts} +24 -14
- package/src/capabilities/distribution.test.ts +122 -0
- package/src/capabilities/distribution.ts +54 -0
- package/src/capabilities/doctor/checks/checkKeStore.ts +9 -7
- package/src/capabilities/doctor/checks/checkPackageRefs.ts +82 -46
- package/src/capabilities/doctor/checks/checkPragmaVersion.ts +5 -4
- package/src/capabilities/doctor/checks/checkShellCompletions.test.ts +125 -30
- package/src/capabilities/doctor/checks/checkShellCompletions.ts +113 -27
- 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 +24 -13
- package/src/capabilities/doctor/doctor.render.ts +45 -20
- package/src/capabilities/doctor/doctor.test.ts +158 -40
- package/src/capabilities/doctor/doctor.verb.ts +9 -5
- package/src/capabilities/doctor/runChecks.ts +65 -66
- package/src/capabilities/doctor/types.ts +21 -5
- package/src/capabilities/emptyRecovery.test.ts +44 -22
- 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 -5
- package/src/capabilities/graph/query.render.ts +15 -3
- package/src/capabilities/graph/query.verb.ts +5 -4
- package/src/capabilities/graph/runQuery.ts +9 -7
- package/src/capabilities/index.ts +25 -19
- package/src/capabilities/info/collectInfo.ts +15 -10
- package/src/capabilities/info/info.render.ts +4 -3
- package/src/capabilities/info/info.verb.ts +4 -3
- package/src/capabilities/lazy.test.ts +125 -2
- 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 +42 -83
- package/src/capabilities/prompt/index.ts +2 -2
- package/src/capabilities/prompt/prompt.render.ts +6 -2
- package/src/capabilities/prompt/prompt.test.ts +12 -6
- package/src/capabilities/prompt/types.ts +1 -1
- package/src/capabilities/prompt/verbs.ts +26 -14
- package/src/capabilities/reference.test.ts +63 -0
- package/src/capabilities/resources/provider.ts +367 -91
- package/src/capabilities/resources/resources.test.ts +411 -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 +397 -320
- 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 +233 -74
- package/src/capabilities/setup/shell.test.ts +86 -0
- package/src/capabilities/setup/shell.ts +166 -14
- 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 +47 -9
- package/src/capabilities/skill/index.ts +1 -1
- package/src/capabilities/skill/render.ts +14 -14
- package/src/capabilities/skill/skill.test.ts +7 -5
- package/src/capabilities/skill/verbs.ts +9 -10
- package/src/capabilities/sources/collectStatus.ts +61 -51
- package/src/capabilities/sources/index.ts +2 -2
- package/src/capabilities/sources/installSkills.ts +86 -9
- package/src/capabilities/sources/runUpdate.ts +164 -141
- package/src/capabilities/sources/sources.test.ts +265 -119
- package/src/capabilities/sources/status.render.test.ts +53 -24
- package/src/capabilities/sources/status.render.ts +25 -30
- package/src/capabilities/sources/status.verb.ts +16 -9
- package/src/capabilities/sources/types.ts +18 -25
- package/src/capabilities/sources/update.render.ts +10 -3
- package/src/capabilities/sources/update.verb.ts +13 -24
- package/src/capabilities/surface.test.ts +165 -25
- package/src/capabilities/tier.parity.test.ts +144 -0
- 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 +8 -4
- 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.test.ts +8 -6
- package/src/constants.ts +78 -22
- package/src/identity.test.ts +348 -0
- package/src/index.ts +2 -2
- package/src/kernel/completion/__snapshots__/emitScripts.test.ts.snap +20 -15
- package/src/kernel/completion/complete.test.ts +12 -2
- package/src/kernel/completion/complete.ts +1 -1
- package/src/kernel/completion/emitScripts.test.ts +1 -1
- package/src/kernel/completion/emitScripts.ts +5 -3
- package/src/kernel/completion/entitySource.test.ts +185 -41
- package/src/kernel/completion/entitySource.ts +133 -110
- package/src/kernel/completion/model.test.ts +165 -13
- package/src/kernel/completion/model.ts +105 -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 +104 -50
- package/src/kernel/completion/shellDrive.test.ts +611 -0
- package/src/kernel/completion/templates/bash.ts +7 -2
- package/src/kernel/completion/templates/fish.ts +28 -6
- package/src/kernel/completion/templates/index.ts +23 -0
- package/src/kernel/completion/types.ts +10 -3
- package/src/kernel/config/defaults.test.ts +108 -0
- package/src/kernel/config/defaults.ts +13 -23
- package/src/kernel/config/evaluateProjectConfig.ts +33 -11
- package/src/kernel/config/findProjectConfig.ts +4 -3
- package/src/kernel/config/firstRun.test.ts +44 -38
- package/src/kernel/config/firstRun.ts +24 -81
- package/src/kernel/config/globalConfig.ts +2 -2
- package/src/kernel/config/index.ts +5 -6
- package/src/kernel/config/paths.ts +17 -17
- package/src/kernel/config/readConfig.test.ts +246 -7
- package/src/kernel/config/readConfig.ts +8 -8
- package/src/kernel/config/schema.test.ts +50 -0
- package/src/kernel/config/schema.ts +100 -11
- package/src/kernel/config/types.ts +75 -19
- package/src/kernel/copy.test.ts +483 -0
- package/src/kernel/copy.ts +54 -0
- package/src/kernel/error/PragmaError.test.ts +6 -3
- package/src/kernel/error/PragmaError.ts +4 -2
- package/src/kernel/error/constants.ts +7 -4
- package/src/kernel/error/fromTaskError.ts +28 -6
- package/src/kernel/error/index.ts +1 -1
- package/src/kernel/error/recovery.test.ts +22 -45
- package/src/kernel/error/recovery.ts +36 -27
- package/src/kernel/error/renderError.ts +42 -1
- package/src/kernel/error/types.ts +25 -4
- package/src/kernel/index.ts +26 -0
- package/src/kernel/packs/collect.test.ts +195 -11
- package/src/kernel/packs/collect.ts +212 -61
- package/src/kernel/packs/compile.test.ts +293 -8
- package/src/kernel/packs/compile.ts +108 -15
- package/src/kernel/packs/disclosure.test.ts +5 -2
- package/src/kernel/packs/disclosure.ts +2 -2
- package/src/kernel/packs/graphql/buildLookupDocument.ts +1 -1
- package/src/kernel/packs/graphql/fetchGraphqlLookup.ts +13 -13
- package/src/kernel/packs/graphql/index.ts +20 -0
- package/src/kernel/packs/graphqlSource.test.ts +6 -3
- package/src/kernel/packs/index.ts +40 -0
- package/src/kernel/packs/iri.test.ts +73 -0
- package/src/kernel/packs/iri.ts +70 -20
- package/src/kernel/packs/renderPack.ts +28 -7
- package/src/kernel/packs/resolveEntity.test.ts +213 -0
- package/src/kernel/packs/resolveEntity.ts +132 -34
- package/src/kernel/packs/runBodies.ts +16 -16
- package/src/kernel/packs/sample.ts +1 -1
- package/src/kernel/packs/schema.ts +114 -11
- 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 +104 -10
- package/src/kernel/packs/sparql/runSelect.ts +75 -37
- package/src/kernel/packs/toolDescription.test.ts +52 -5
- package/src/kernel/packs/types.ts +52 -4
- package/src/kernel/packs/uniqueness.ts +5 -5
- package/src/kernel/project/cli/buildProgram.test.ts +157 -17
- 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 +227 -3
- package/src/kernel/project/cli/dispatch.ts +250 -48
- 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 +14 -1
- package/src/kernel/project/cli/rootHelp.ts +140 -111
- 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 +18 -10
- package/src/kernel/project/mcp/envelope.ts +2 -2
- package/src/kernel/project/mcp/instructions.ts +12 -7
- package/src/kernel/project/mcp/mcpError.ts +1 -1
- package/src/kernel/project/mcp/parity.test.ts +42 -1
- package/src/kernel/project/mcp/prompts/index.ts +37 -0
- package/src/kernel/project/mcp/prompts/prompts.test.ts +120 -5
- package/src/kernel/project/mcp/prompts/provider.ts +22 -8
- package/src/kernel/project/mcp/prompts/source.ts +69 -68
- package/src/kernel/project/mcp/registerVerb.ts +56 -11
- package/src/kernel/project/mcp/serve.ts +13 -5
- package/src/kernel/project/mcp/toolDescriptions.test.ts +6 -2
- package/src/kernel/render/__snapshots__/renderers.test.ts.snap +7 -4
- package/src/kernel/render/contracts.ts +21 -0
- package/src/kernel/render/disclosure.ts +4 -2
- package/src/kernel/render/envelope.ts +2 -3
- package/src/kernel/render/formatters.ts +1 -1
- package/src/kernel/render/prefixes.test.ts +36 -0
- package/src/kernel/render/prefixes.ts +40 -13
- package/src/kernel/render/renderers.test.ts +244 -7
- 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/build.ts +29 -3
- package/src/kernel/runtime/graphpack/buildIndex.test.ts +46 -0
- package/src/kernel/runtime/graphpack/buildIndex.ts +53 -18
- package/src/kernel/runtime/graphpack/embedded/pack.generated.ts +5 -5
- package/src/kernel/runtime/graphpack/embedded/pack.index.generated.ts +3 -3
- package/src/kernel/runtime/graphpack/embedded/pack.stories.generated.ts +3 -0
- package/src/kernel/runtime/graphpack/embedded.ts +39 -13
- package/src/kernel/runtime/graphpack/graphpack.test.ts +205 -5
- package/src/kernel/runtime/graphpack/hash.ts +3 -2
- package/src/kernel/runtime/graphpack/index.ts +1 -1
- package/src/kernel/runtime/graphpack/manifest.ts +114 -12
- package/src/kernel/runtime/graphpack/read.ts +5 -11
- package/src/kernel/runtime/graphpack/schemas.ts +74 -0
- package/src/kernel/runtime/graphpack/stories.ts +84 -0
- package/src/kernel/runtime/graphpack/types.ts +61 -48
- package/src/kernel/runtime/loadSession.ts +1 -1
- package/src/kernel/runtime/paths.ts +64 -15
- package/src/kernel/runtime/probe.test.ts +8 -4
- package/src/kernel/runtime/probe.ts +6 -6
- package/src/kernel/runtime/readEntity.ts +477 -32
- package/src/kernel/runtime/refs/gitOps.ts +1 -19
- package/src/kernel/runtime/refs/index.ts +39 -0
- package/src/kernel/runtime/refs/parseRef.ts +8 -8
- package/src/kernel/runtime/refs/resolve.ts +82 -66
- package/src/kernel/runtime/resolveSources.test.ts +63 -24
- package/src/kernel/runtime/resolveSources.ts +36 -25
- package/src/kernel/runtime/storeReadiness.ts +10 -10
- package/src/kernel/runtime/storeless.test.ts +1 -1
- package/src/kernel/runtime/types.ts +15 -1
- package/src/kernel/runtime/wasmEmbed.test.ts +56 -55
- package/src/kernel/spec/emitReference.test.ts +3 -3
- package/src/kernel/spec/emitReference.ts +242 -34
- package/src/kernel/spec/emitSurface.ts +57 -11
- package/src/kernel/spec/surfaceConformance.test.ts +4 -2
- package/src/kernel/spec/surfaceConformance.ts +8 -0
- package/src/kernel/spec/types.ts +277 -13
- package/src/kernel/spec/validate.ts +2 -1
- package/src/kernel/vocabulary.test.ts +164 -0
- package/src/kernel/vocabulary.ts +146 -0
- package/src/testing/PARITY_GAPS.ts +8 -2
- package/src/testing/behavioral/README.md +3 -3
- package/src/testing/behavioral/completion.test.ts +19 -6
- package/src/testing/behavioral/docExamples.test.ts +14 -0
- package/src/testing/behavioral/errorMatrix.mcp.test.ts +6 -5
- package/src/testing/behavioral/errorMatrix.storeless.test.ts +1 -1
- package/src/testing/behavioral/exitCodes.e2e.test.ts +6 -5
- package/src/testing/behavioral/firstRun.e2e.test.ts +24 -24
- package/src/testing/behavioral/harness.foundation.test.ts +14 -5
- package/src/testing/behavioral/journeys.cli.test.ts +117 -76
- package/src/testing/behavioral/journeys.defaultPack.test.ts +88 -182
- package/src/testing/behavioral/journeys.firstInstall.test.ts +167 -0
- 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.mcpLifecycle.mcp.test.ts +9 -6
- package/src/testing/behavioral/journeys.packageStories.test.ts +188 -0
- package/src/testing/behavioral/liveReadSurface.ts +4 -3
- package/src/testing/behavioral/mcpServe.e2e.test.ts +57 -2
- package/src/testing/behavioral/mcpSurface.test.ts +10 -5
- package/src/testing/behavioral/rootCli.e2e.test.ts +26 -2
- package/src/testing/behavioral/staleCommands.test.ts +10 -0
- package/src/testing/eval/__snapshots__/eval.test.ts.snap +7 -7
- package/src/testing/eval/cases/assembly.ts +13 -6
- package/src/testing/eval/cases/effectful.ts +28 -15
- package/src/testing/eval/cases/readNouns.ts +22 -20
- package/src/testing/eval/cases/stable.ts +5 -1
- package/src/testing/eval/eval.test.ts +7 -1
- package/src/testing/fixtures/blockGraph.ts +79 -0
- package/src/testing/fixtures/fixtureCapability.ts +45 -1
- package/src/testing/fixtures/graph/canonical.ts +94 -5
- package/src/testing/fixtures/graph/defaultPack.ts +7 -6
- package/src/testing/fixtures/graph/owlExport.ts +7 -5
- package/src/testing/helpers/blankCanonicalRanges.ts +36 -0
- package/src/testing/helpers/fixtureGraph.ts +33 -16
- package/src/testing/helpers/packRuntime.ts +2 -3
- package/src/testing/helpers/projectCli.ts +2 -1
- package/src/testing/helpers/projectMcp.ts +38 -6
- package/src/testing/helpers/runCli.ts +35 -18
- package/src/testing/perf/budgets.test.ts +24 -9
- package/src/testing/perf/budgets.ts +76 -12
- package/src/testing/perf/codegen.test.ts +126 -0
- package/src/testing/perf/globalSetup.test.ts +286 -0
- package/src/testing/perf/globalSetup.ts +611 -14
- 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/src/types.ts +2 -2
- package/dist/pragma +0 -0
- package/src/capabilities/block/blockList.test.ts +0 -79
- package/src/capabilities/block/blockList.verb.ts +0 -163
- package/src/capabilities/block/index.ts +0 -25
- package/src/capabilities/block/pack.ts +0 -166
- package/src/capabilities/block/parity.test.ts +0 -187
- package/src/capabilities/block/tierChain.ts +0 -78
- package/src/capabilities/colophon/pragmaColophon.ts +0 -66
- package/src/capabilities/create/compiledCreate.subprocess.test.ts +0 -152
- package/src/capabilities/create/templates.embedded.generated.ts +0 -53
- package/src/capabilities/doctor/checks/checkConfigFile.ts +0 -41
- package/src/capabilities/doctor/checks/checkMcpCommands.ts +0 -114
- package/src/capabilities/doctor/checks/checkMcpConfigured.ts +0 -67
- package/src/capabilities/doctor/checks/checkSkillsSymlinked.ts +0 -60
- package/src/capabilities/doctor/checks/deriveBand.test.ts +0 -42
- package/src/capabilities/doctor/checks/deriveBand.ts +0 -28
- package/src/capabilities/modifier/index.ts +0 -15
- package/src/capabilities/modifier/pack.ts +0 -64
- package/src/capabilities/standard/index.ts +0 -18
- package/src/capabilities/standard/pack.ts +0 -128
- package/src/capabilities/tier/index.ts +0 -19
- package/src/capabilities/tier/lookup.render.test.ts +0 -72
- package/src/capabilities/tier/lookup.render.ts +0 -59
- package/src/capabilities/tier/lookup.test.ts +0 -83
- package/src/capabilities/tier/lookup.verb.ts +0 -44
- package/src/capabilities/tier/pack.ts +0 -28
- package/src/capabilities/tier/runLookup.ts +0 -87
- package/src/capabilities/token/addConfig.render.ts +0 -27
- package/src/capabilities/token/addConfig.test.ts +0 -62
- package/src/capabilities/token/addConfig.verb.ts +0 -40
- package/src/capabilities/token/index.ts +0 -19
- package/src/capabilities/token/pack.ts +0 -58
- package/src/capabilities/token/runAddConfig.ts +0 -95
- package/src/kernel/completion/bashDrive.test.ts +0 -73
- package/src/kernel/config/__snapshots__/firstRun.test.ts.snap +0 -11
- package/src/kernel/runtime/graphpack/embedded/sample.ttl +0 -39
- package/src/kernel/runtime/lock.ts +0 -90
|
@@ -13,14 +13,47 @@ export const CHANNELS = ["normal", "experimental", "prerelease"] as const;
|
|
|
13
13
|
/** A release channel name. */
|
|
14
14
|
export type Channel = (typeof CHANNELS)[number];
|
|
15
15
|
|
|
16
|
-
/**
|
|
17
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Progressive-disclosure levels, least to most detail. Declared HERE, beside
|
|
18
|
+
* {@link CHANNELS}, because the config validator closes `detail` over this set
|
|
19
|
+
* and this module is the one config module the storeless fast path may reach
|
|
20
|
+
* (`completion/safety.test.ts` positive-lists it; `capabilities/lazy.test.ts`
|
|
21
|
+
* pins it inert). `src/constants.ts` re-exports it for every other reader.
|
|
22
|
+
*/
|
|
23
|
+
export const DETAIL_LEVELS = ["summary", "standard", "detailed"] as const;
|
|
24
|
+
|
|
25
|
+
/** A progressive-disclosure level. */
|
|
26
|
+
export type DetailLevel = (typeof DETAIL_LEVELS)[number];
|
|
27
|
+
|
|
28
|
+
/** The object form of a pack source declaration. */
|
|
29
|
+
export interface PackSource {
|
|
18
30
|
readonly name: string;
|
|
19
31
|
readonly source?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Declarative read stories this pack supplies, in the pack grammar
|
|
34
|
+
* (`kernel/packs/types.PackDefinition`). OPAQUE here on purpose — the config
|
|
35
|
+
* layer does not know that grammar; `parsePackDefinition` validates it at
|
|
36
|
+
* dispatch. Declared beside the pack so a story can move out to the package's
|
|
37
|
+
* own `stories/*.json` by deleting this field and nothing else.
|
|
38
|
+
*/
|
|
39
|
+
readonly stories?: readonly unknown[];
|
|
20
40
|
}
|
|
21
41
|
|
|
22
|
-
/** A `
|
|
23
|
-
export type
|
|
42
|
+
/** A `packs` entry: a bare npm name or a `{ name, source }` declaration. */
|
|
43
|
+
export type PackDeclaration = string | PackSource;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* The toolchain colophon the distribution declares — CONTENT, not machinery.
|
|
47
|
+
* The `colophon` verb renders whatever is declared here as its first section,
|
|
48
|
+
* titled with the distribution's name; a fork tells its own story by editing
|
|
49
|
+
* its config. Both strings are Markdown BODIES with no leading H1 (the
|
|
50
|
+
* renderer supplies the heading). `summary` is the condensed `--format llm`
|
|
51
|
+
* form; omitted, the full `markdown` serves both.
|
|
52
|
+
*/
|
|
53
|
+
export interface ColophonDeclaration {
|
|
54
|
+
readonly markdown: string;
|
|
55
|
+
readonly summary?: string;
|
|
56
|
+
}
|
|
24
57
|
|
|
25
58
|
/**
|
|
26
59
|
* Completion policy, read at `setup completions` emit time (never on the
|
|
@@ -31,28 +64,41 @@ export type PackageEntry = string | PackageDeclaration;
|
|
|
31
64
|
export interface CompletionConfig {
|
|
32
65
|
/** Minimum typed chars before the shell execs `__complete` (default 2). */
|
|
33
66
|
readonly minChars?: number;
|
|
34
|
-
/** Match case-sensitively (default false — loose match, canonical emit). */
|
|
35
|
-
readonly caseSensitive?: boolean;
|
|
36
67
|
/** Per-family opt-out: a noun mapped to `false` drops its name completion. */
|
|
37
68
|
readonly families?: Readonly<Record<string, boolean>>;
|
|
38
69
|
}
|
|
39
70
|
|
|
40
|
-
/**
|
|
71
|
+
/**
|
|
72
|
+
* The effective, resolved configuration. `channel` always has a value.
|
|
73
|
+
*
|
|
74
|
+
* IDENTITY IS NOT HERE. `name`, `help` and `issuesUrl` are read from
|
|
75
|
+
* `pragma.conf.ts` by `src/constants.ts` at module load, because the surfaces
|
|
76
|
+
* that need them — `--help`, `__complete`, the MCP handshake, first-run
|
|
77
|
+
* onboarding — all run before or without the config layer; `colophon` is read
|
|
78
|
+
* from the same file at render time by the `colophon` verb. They stay in
|
|
79
|
+
* {@link RawConfig} (the distribution config is `satisfies RawConfig`), but
|
|
80
|
+
* merging them into the effective config only bought `config show` a
|
|
81
|
+
* `[project]` marker the kernel does not honour.
|
|
82
|
+
*/
|
|
41
83
|
export interface PragmaConfig {
|
|
42
84
|
/** Active tier path, or absent when no tier is configured. */
|
|
43
85
|
readonly tier?: string;
|
|
44
86
|
/** Release channel controlling component visibility. */
|
|
45
87
|
readonly channel: Channel;
|
|
46
88
|
/** Default progressive-disclosure level. */
|
|
47
|
-
readonly detail?:
|
|
48
|
-
/** Semantic
|
|
49
|
-
readonly
|
|
50
|
-
/** Declarative read stories compiled at
|
|
89
|
+
readonly detail?: DetailLevel;
|
|
90
|
+
/** Semantic pack sources; replaces (does not merge) across layers. */
|
|
91
|
+
readonly packs?: readonly PackDeclaration[];
|
|
92
|
+
/** Declarative read stories, compiled at DISPATCH (opaque here). */
|
|
51
93
|
readonly stories?: readonly unknown[];
|
|
52
|
-
/**
|
|
94
|
+
/**
|
|
95
|
+
* Namespace prefixes the pack is built with — they win every harvest, so a
|
|
96
|
+
* layer here decides what the store binds and what the index is keyed under.
|
|
97
|
+
* The DISTRIBUTION layer's entries additionally seed the compiled-in
|
|
98
|
+
* `DEFAULT_PREFIX_MAP`; a project layer's do not, because that map is read on
|
|
99
|
+
* the storeless fast path where no config layer exists.
|
|
100
|
+
*/
|
|
53
101
|
readonly prefixes?: Readonly<Record<string, string>>;
|
|
54
|
-
/** Named prompt overrides (global machine state). */
|
|
55
|
-
readonly prompts?: Readonly<Record<string, unknown>>;
|
|
56
102
|
/** Completion policy (read at `setup completions` emit time). */
|
|
57
103
|
readonly completion?: CompletionConfig;
|
|
58
104
|
}
|
|
@@ -61,15 +107,26 @@ export interface PragmaConfig {
|
|
|
61
107
|
* The fields a single config layer (global JSON or project TS) may declare. A
|
|
62
108
|
* key is present only when that layer sets it — presence drives which layer
|
|
63
109
|
* wins during the merge.
|
|
110
|
+
*
|
|
111
|
+
* WIDER than {@link PragmaConfig}: the DISTRIBUTION layer (`pragma.conf.ts`)
|
|
112
|
+
* is `satisfies RawConfig` and declares the five identity fields, which are
|
|
113
|
+
* read statically and never merged. A global or project layer declaring one is
|
|
114
|
+
* accepted by the validator and has no effect — `docs/reference/config.md`
|
|
115
|
+
* says so, and `readConfig.test.ts` pins it.
|
|
64
116
|
*/
|
|
65
117
|
export interface RawConfig {
|
|
118
|
+
readonly name?: string;
|
|
119
|
+
readonly help?: string;
|
|
120
|
+
/** ASCII-art wordmark lines shown atop root `--help` (identity, like `name`). */
|
|
121
|
+
readonly logo?: readonly string[];
|
|
122
|
+
readonly colophon?: ColophonDeclaration;
|
|
123
|
+
readonly issuesUrl?: string;
|
|
66
124
|
readonly tier?: string;
|
|
67
125
|
readonly channel?: Channel;
|
|
68
|
-
readonly detail?:
|
|
69
|
-
readonly
|
|
126
|
+
readonly detail?: DetailLevel;
|
|
127
|
+
readonly packs?: readonly PackDeclaration[];
|
|
70
128
|
readonly stories?: readonly unknown[];
|
|
71
129
|
readonly prefixes?: Readonly<Record<string, string>>;
|
|
72
|
-
readonly prompts?: Readonly<Record<string, unknown>>;
|
|
73
130
|
readonly completion?: CompletionConfig;
|
|
74
131
|
}
|
|
75
132
|
|
|
@@ -81,10 +138,9 @@ export interface ConfigOrigins {
|
|
|
81
138
|
readonly tier: ConfigOrigin;
|
|
82
139
|
readonly channel: ConfigOrigin;
|
|
83
140
|
readonly detail: ConfigOrigin;
|
|
84
|
-
readonly
|
|
141
|
+
readonly packs: ConfigOrigin;
|
|
85
142
|
readonly stories: ConfigOrigin;
|
|
86
143
|
readonly prefixes: ConfigOrigin;
|
|
87
|
-
readonly prompts: ConfigOrigin;
|
|
88
144
|
}
|
|
89
145
|
|
|
90
146
|
/** A resolved config layer's file location and existence. */
|
|
@@ -0,0 +1,483 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The kernel is generic machinery: it may describe itself, but it may not name
|
|
3
|
+
* the distribution in an authored string. A fork changes `pragma.conf.ts`;
|
|
4
|
+
* anything the kernel hardcodes becomes a lie it cannot fix.
|
|
5
|
+
*
|
|
6
|
+
* What this guard enforces, exactly: no string literal under `src/kernel/**`
|
|
7
|
+
* (plus `constants.ts` and `bin.ts`) contains the distribution's `name` as a
|
|
8
|
+
* word, the domain phrase "design system", or any namespace IRI the
|
|
9
|
+
* distribution declares in `prefixes`. Module specifiers are not copy and are
|
|
10
|
+
* skipped; every remaining site that legitimately carries one is listed in
|
|
11
|
+
* {@link EXEMPT} with its reason.
|
|
12
|
+
*
|
|
13
|
+
* `src/capabilities/**` and `pragma.conf.ts` are OUT of the rule above.
|
|
14
|
+
* `pragma.conf.ts` is the file a fork edits, so it is content by definition;
|
|
15
|
+
* `src/capabilities/**` carries the kernel's own nouns — their prompts,
|
|
16
|
+
* setup copy, doctor findings and other runtime copy no doc publishes — and a
|
|
17
|
+
* guard needing a 65-entry exemption list is a guard that mostly exempts. (The
|
|
18
|
+
* `ds:` residue the exclusion was originally written for is gone: L-OPEN-9
|
|
19
|
+
* left no hand-written data verb behind, and `distribution.test.ts` now proves
|
|
20
|
+
* every data noun is exactly its declared story.) Two narrower rules reach it
|
|
21
|
+
* instead, at the bottom of this
|
|
22
|
+
* file — *a command a user is told to run is never a literal*, stated once as
|
|
23
|
+
* a POSITION ({@link COMMAND_POSITIONS}, read over raw source so it holds
|
|
24
|
+
* whatever the scanner can see) and once as a SHAPE (a backticked command
|
|
25
|
+
* inside any authored literal, read through {@link readCopy} so an
|
|
26
|
+
* interpolated one leaves no matching chunk). Neither rule carries an
|
|
27
|
+
* exemption: the last one — the colophon narrative, this distribution's voice
|
|
28
|
+
* in a capability source — became content the config declares
|
|
29
|
+
* (`pragma.conf.ts#colophon`), which is what made removing it checkable.
|
|
30
|
+
*
|
|
31
|
+
* Beside the naming rules, the same scanner enforces the HOUSE VOICE rules for
|
|
32
|
+
* user-facing copy ({@link COPY_RULES}, authored as data in `copy.ts`) over
|
|
33
|
+
* both file sets — the kernel set above and `src/capabilities/**` — in the
|
|
34
|
+
* last describe of this file. See `copy.ts` for what each rule bans and why.
|
|
35
|
+
*
|
|
36
|
+
* NOTE for a reader of an older revision: this docblock used to say the
|
|
37
|
+
* `examples[].cmd` sweep and the `docs/reference/*.md` regen "have to move
|
|
38
|
+
* together". They must be CONSISTENT, not simultaneous — the whole sweep was
|
|
39
|
+
* measured to move zero doc bytes, because every literal it replaced was
|
|
40
|
+
* already spelling this distribution's own name.
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
import { readdirSync, readFileSync } from "node:fs";
|
|
44
|
+
import { dirname, join, relative, resolve } from "node:path";
|
|
45
|
+
import { fileURLToPath } from "node:url";
|
|
46
|
+
import { describe, expect, it } from "vitest";
|
|
47
|
+
import conf from "../../pragma.conf.js";
|
|
48
|
+
import { BIN_NAME } from "../constants.js";
|
|
49
|
+
import { COPY_RULES } from "./copy.js";
|
|
50
|
+
|
|
51
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
52
|
+
const root = resolve(here, "..");
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Files whose strings are pinned, frozen, or owned by another lane, so changing
|
|
56
|
+
* them is not a copy edit:
|
|
57
|
+
* - `*.generated.ts` — build artifacts (the embedded pack's graph data).
|
|
58
|
+
* - `config/defaults.ts` — THE distribution seam: it imports the distribution
|
|
59
|
+
* config and names the file it imports. That is its job, not a leak.
|
|
60
|
+
* - `kernel/vocabulary.ts` — the same seam for the vocabulary declaration. Its
|
|
61
|
+
* diagnostics quote the file it imports, and five modules hardcode that
|
|
62
|
+
* specifier, so a fork cannot rename it: deriving the name from `BIN_NAME`
|
|
63
|
+
* here would name a path that does not exist.
|
|
64
|
+
* - `runtime/graphpack/hash.ts` — `<<<pragma-pack:…>>>` are hash domain
|
|
65
|
+
* separators; changing them re-mints every pack content hash. CROSS-LANE.
|
|
66
|
+
*/
|
|
67
|
+
const EXEMPT = [
|
|
68
|
+
".generated.ts",
|
|
69
|
+
"config/defaults.ts",
|
|
70
|
+
"kernel/vocabulary.ts",
|
|
71
|
+
"runtime/graphpack/hash.ts",
|
|
72
|
+
];
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Every authored `.ts` in the kernel, plus the identity module and the bin.
|
|
76
|
+
*
|
|
77
|
+
* @param dir - Directory to walk.
|
|
78
|
+
* @returns Absolute paths of the non-test TypeScript sources beneath it.
|
|
79
|
+
* @note Impure — reads the source tree.
|
|
80
|
+
*/
|
|
81
|
+
function listSources(dir: string): string[] {
|
|
82
|
+
const found: string[] = [];
|
|
83
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
84
|
+
const path = join(dir, entry.name);
|
|
85
|
+
if (entry.isDirectory()) found.push(...listSources(path));
|
|
86
|
+
else if (entry.name.endsWith(".ts") && !entry.name.endsWith(".test.ts")) {
|
|
87
|
+
found.push(path);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return found;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const files = [
|
|
94
|
+
...listSources(join(root, "kernel")),
|
|
95
|
+
join(root, "constants.ts"),
|
|
96
|
+
join(root, "bin.ts"),
|
|
97
|
+
].filter((file) => !EXEMPT.some((suffix) => file.endsWith(suffix)));
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* The authored copy in a file: every string literal that is neither a module
|
|
101
|
+
* specifier nor inside a comment.
|
|
102
|
+
*
|
|
103
|
+
* A single left-to-right pass, not a pair of regexes, because the two orderings
|
|
104
|
+
* a regex pair allows are both wrong: strip comments first and any literal
|
|
105
|
+
* containing `//` is truncated, re-pairing the quotes across the deleted tail
|
|
106
|
+
* and hiding whatever followed; match literals first and an apostrophe in prose
|
|
107
|
+
* ("the kernel's") opens a quote that never closes, which is also the shape
|
|
108
|
+
* that makes the literal pattern backtrack catastrophically. Reading the file
|
|
109
|
+
* in source order makes both cases fall out: a `//` inside a string belongs to
|
|
110
|
+
* the string, an apostrophe inside a comment belongs to the comment.
|
|
111
|
+
*
|
|
112
|
+
* A REGEX LITERAL is code, not copy, and it is the third ordering hazard: a `"`
|
|
113
|
+
* inside a regex (`/[<>"{}|\\^`\s]/`) would otherwise open a phantom string that
|
|
114
|
+
* swallows every literal until the next `"` — so the scanner reads regexes as
|
|
115
|
+
* regexes and skips them whole.
|
|
116
|
+
*
|
|
117
|
+
* A TEMPLATE SUBSTITUTION is the fourth, and the one this tree actually writes:
|
|
118
|
+
* `${…}` is code, and the code inside it may open another template. Reading a
|
|
119
|
+
* template as one flat span makes the NESTED backtick close the OUTER literal,
|
|
120
|
+
* and every quote after it in the file pairs off by one — which left the whole
|
|
121
|
+
* tail of `packs/renderPack.ts` invisible to this guard. So a substitution is
|
|
122
|
+
* handed back to the code scanner, and the literal chunks around it are the copy.
|
|
123
|
+
*
|
|
124
|
+
* Specifiers (`./x.js`, `@scope/pkg`) name modules, not users, and must stay
|
|
125
|
+
* literal, so they are not copy.
|
|
126
|
+
*
|
|
127
|
+
* @param source - The file's text.
|
|
128
|
+
* @returns The authored string literals.
|
|
129
|
+
*/
|
|
130
|
+
function readCopy(source: string): string[] {
|
|
131
|
+
const copy: string[] = [];
|
|
132
|
+
scanCode(source, 0, copy);
|
|
133
|
+
return copy;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** A `/` opens a regex only where a VALUE may start; after a value it divides. */
|
|
137
|
+
const REGEX_OPENS_AFTER = "=(,:[!&|?{};+-*%~^<>";
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Read code from `from`, pushing every authored literal it quotes onto `copy`.
|
|
141
|
+
*
|
|
142
|
+
* @param source - The file's text.
|
|
143
|
+
* @param from - Index to start reading at.
|
|
144
|
+
* @param copy - Accumulator the authored literals are pushed onto.
|
|
145
|
+
* @param untilBrace - Stop at the `}` closing a template substitution.
|
|
146
|
+
* @returns The index the scan stopped at.
|
|
147
|
+
*/
|
|
148
|
+
function scanCode(
|
|
149
|
+
source: string,
|
|
150
|
+
from: number,
|
|
151
|
+
copy: string[],
|
|
152
|
+
untilBrace = false,
|
|
153
|
+
): number {
|
|
154
|
+
// One character of context decides regex-vs-division — the last significant
|
|
155
|
+
// one — which is all TypeScript sources in this tree need (no `)`/`]`-preceded
|
|
156
|
+
// regex, i.e. no `if (x) /re/.test(y)`, which would read as division).
|
|
157
|
+
let previous = "";
|
|
158
|
+
let braces = 0;
|
|
159
|
+
for (let i = from; i < source.length; i++) {
|
|
160
|
+
const char = source[i];
|
|
161
|
+
if (char === "/" && source[i + 1] === "*") {
|
|
162
|
+
const end = source.indexOf("*/", i + 2);
|
|
163
|
+
if (end === -1) return source.length;
|
|
164
|
+
i = end + 1;
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
if (char === "/" && source[i + 1] === "/") {
|
|
168
|
+
const end = source.indexOf("\n", i + 2);
|
|
169
|
+
if (end === -1) return source.length;
|
|
170
|
+
i = end;
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
if (
|
|
174
|
+
char === "/" &&
|
|
175
|
+
previous !== "" &&
|
|
176
|
+
REGEX_OPENS_AFTER.includes(previous)
|
|
177
|
+
) {
|
|
178
|
+
// Skip the body, honouring escapes and `[…]` classes (where an unescaped
|
|
179
|
+
// `/` is an ordinary character). An unterminated regex cannot span a line,
|
|
180
|
+
// so a newline ends the scan rather than eating the rest of the file.
|
|
181
|
+
let inClass = false;
|
|
182
|
+
i += 1;
|
|
183
|
+
while (i < source.length && source[i] !== "\n") {
|
|
184
|
+
const body = source[i];
|
|
185
|
+
if (body === "\\") i += 1;
|
|
186
|
+
else if (body === "[") inClass = true;
|
|
187
|
+
else if (body === "]") inClass = false;
|
|
188
|
+
else if (body === "/" && !inClass) break;
|
|
189
|
+
i += 1;
|
|
190
|
+
}
|
|
191
|
+
previous = "/";
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
if (char === "`") {
|
|
195
|
+
i = scanTemplate(source, i + 1, copy);
|
|
196
|
+
previous = char;
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
if (char !== '"' && char !== "'") {
|
|
200
|
+
if (untilBrace && char === "{") braces += 1;
|
|
201
|
+
if (untilBrace && char === "}") {
|
|
202
|
+
if (braces === 0) return i;
|
|
203
|
+
braces -= 1;
|
|
204
|
+
}
|
|
205
|
+
if (!/\s/.test(char)) previous = char;
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
const start = ++i;
|
|
209
|
+
while (i < source.length && source[i] !== char) {
|
|
210
|
+
i += source[i] === "\\" ? 2 : 1;
|
|
211
|
+
}
|
|
212
|
+
pushCopy(copy, source.slice(start, i));
|
|
213
|
+
previous = char;
|
|
214
|
+
}
|
|
215
|
+
return source.length;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Read a template literal's body from `from` — just past the opening backtick —
|
|
220
|
+
* pushing its literal chunks onto `copy` and handing each `${…}` back to
|
|
221
|
+
* {@link scanCode}, which is where a nested template is read as a template.
|
|
222
|
+
*
|
|
223
|
+
* @param source - The file's text.
|
|
224
|
+
* @param from - Index of the first character after the opening backtick.
|
|
225
|
+
* @param copy - Accumulator the authored chunks are pushed onto.
|
|
226
|
+
* @returns The index of the closing backtick.
|
|
227
|
+
*/
|
|
228
|
+
function scanTemplate(source: string, from: number, copy: string[]): number {
|
|
229
|
+
let chunk = "";
|
|
230
|
+
let i = from;
|
|
231
|
+
while (i < source.length && source[i] !== "`") {
|
|
232
|
+
if (source[i] === "\\") {
|
|
233
|
+
chunk += source.slice(i, i + 2);
|
|
234
|
+
i += 2;
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
if (source[i] === "$" && source[i + 1] === "{") {
|
|
238
|
+
i = scanCode(source, i + 2, copy, true) + 1;
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
chunk += source[i];
|
|
242
|
+
i += 1;
|
|
243
|
+
}
|
|
244
|
+
pushCopy(copy, chunk);
|
|
245
|
+
return i;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/** Keep a literal unless it is empty or names a module rather than a user. */
|
|
249
|
+
function pushCopy(copy: string[], literal: string): void {
|
|
250
|
+
if (literal && !literal.startsWith(".") && !literal.startsWith("@")) {
|
|
251
|
+
copy.push(literal);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* `file: literal` for every authored literal matching `pattern`, so a failure
|
|
257
|
+
* names its offenders instead of only counting them.
|
|
258
|
+
*
|
|
259
|
+
* @param pattern - What the copy may not contain.
|
|
260
|
+
* @param sources - The files to read; the kernel set by default.
|
|
261
|
+
* @returns One entry per offending literal.
|
|
262
|
+
* @note Impure — reads every listed source.
|
|
263
|
+
*/
|
|
264
|
+
function findOffenders(
|
|
265
|
+
pattern: RegExp,
|
|
266
|
+
sources: readonly string[] = files,
|
|
267
|
+
): string[] {
|
|
268
|
+
const found: string[] = [];
|
|
269
|
+
for (const file of sources) {
|
|
270
|
+
for (const literal of readCopy(readFileSync(file, "utf-8"))) {
|
|
271
|
+
if (pattern.test(literal)) {
|
|
272
|
+
found.push(`${relative(root, file)}: ${literal}`);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return found;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
describe("the copy scanner (PROTECTED)", () => {
|
|
280
|
+
// The guard below is only as good as what the scanner can see, so the scanner
|
|
281
|
+
// is pinned directly on the shape that used to blind it: `src/kernel/packs/
|
|
282
|
+
// iri.ts` declares two regexes that each contain a `"`, and a leak between
|
|
283
|
+
// them was invisible. DERIVED, so the probe leaks whatever this distribution
|
|
284
|
+
// is called.
|
|
285
|
+
const leak = `${BIN_NAME} sources update`;
|
|
286
|
+
|
|
287
|
+
it("reads a literal sitting between two regexes that contain a quote", () => {
|
|
288
|
+
const source = [
|
|
289
|
+
'const UNSAFE = /[<>"{}|\\\\^`\\s]/;',
|
|
290
|
+
`const LEAK = "${leak}";`,
|
|
291
|
+
'const EMBEDDABLE = /^[A-Za-z][\\w+.-]*:\\/\\/[^<>"\\s]+$/;',
|
|
292
|
+
].join("\n");
|
|
293
|
+
expect(readCopy(source)).toEqual([leak]);
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
it("reads the same literal with no regex around it", () => {
|
|
297
|
+
expect(readCopy(`const LEAK = "${leak}";`)).toEqual([leak]);
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
it("reads a dividing slash as division, not as an opening regex", () => {
|
|
301
|
+
// The division and the leak share a LINE: a scanner that read every `/` as
|
|
302
|
+
// a regex opener would skip to the next `/` or the newline, whichever comes
|
|
303
|
+
// first, and swallow the leak. On separate lines the regex skip stops at the
|
|
304
|
+
// newline before it reaches the literal, so both scanners agree and the case
|
|
305
|
+
// asserts nothing.
|
|
306
|
+
const source = `const rate = done / all; const LEAK = "${leak}";`;
|
|
307
|
+
expect(readCopy(source)).toEqual([leak]);
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
it("reads a template substitution as code, not as the end of the literal", () => {
|
|
311
|
+
// `packs/renderPack.ts` writes exactly this: a template whose substitution
|
|
312
|
+
// contains another template, itself containing an ESCAPED backtick. Read
|
|
313
|
+
// flat, the nested backtick closes the outer literal and every quote after
|
|
314
|
+
// it in the file pairs off by one — so the leak below, and the whole tail of
|
|
315
|
+
// any file shaped like this, became invisible.
|
|
316
|
+
const source = [
|
|
317
|
+
"const hint = shape.emptyRecovery",
|
|
318
|
+
" ? `${shape.emptyRecovery.message}${",
|
|
319
|
+
" shape.emptyRecovery.cli",
|
|
320
|
+
" ? ` Run \\`${PREFIX}${shape.emptyRecovery.cli}\\`.`",
|
|
321
|
+
' : ""',
|
|
322
|
+
" }`",
|
|
323
|
+
" : DEFAULT_HINT;",
|
|
324
|
+
`const LEAK = "${leak}";`,
|
|
325
|
+
].join("\n");
|
|
326
|
+
expect(readCopy(source)).toContain(leak);
|
|
327
|
+
});
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
describe("kernel copy (PROTECTED)", () => {
|
|
331
|
+
it("no kernel string names the distribution", () => {
|
|
332
|
+
// DERIVED from the shipped `name`, and ESCAPED: this guard hardcodes no
|
|
333
|
+
// name, and a fork called `my.cli` or `c++tool` neither over-matches nor
|
|
334
|
+
// dies compiling its own name as a pattern. The word boundaries keep
|
|
335
|
+
// identifiers like `PragmaError` out while still catching the forms the
|
|
336
|
+
// name actually leaks in — `pragma.config.ts`, `pragma-pack`, `pragma `.
|
|
337
|
+
const name = BIN_NAME.replace(/[-.*+?^${}()|[\]\\]/g, "\\$&");
|
|
338
|
+
expect(findOffenders(new RegExp(`\\b${name}\\b`, "i"))).toEqual([]);
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
it("no kernel string names a domain", () => {
|
|
342
|
+
expect(findOffenders(/design[- ]system/i)).toEqual([]);
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
it("no kernel string hardcodes a namespace the distribution declares", () => {
|
|
346
|
+
// The behavioural half of the same rule. A kernel module that spells out a
|
|
347
|
+
// declared namespace IRI has decided what the domain is, so a fork editing
|
|
348
|
+
// `pragma.conf.ts` changes the store and not the code reading it.
|
|
349
|
+
//
|
|
350
|
+
// DERIVED from the declaration, one pattern per namespace rather than one
|
|
351
|
+
// alternation: a distribution that declares none then yields no offenders,
|
|
352
|
+
// instead of an empty alternation that matches every literal.
|
|
353
|
+
const offenders = Object.values(conf.prefixes ?? {}).flatMap((namespace) =>
|
|
354
|
+
findOffenders(
|
|
355
|
+
new RegExp(namespace.replace(/[-.*+?^${}()|[\]\\]/g, "\\$&")),
|
|
356
|
+
),
|
|
357
|
+
);
|
|
358
|
+
expect(offenders).toEqual([]);
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
it("no kernel string writes a term in a namespace the distribution declares", () => {
|
|
362
|
+
// The form the kernel actually leaked the domain in. Every coupling this
|
|
363
|
+
// guard exists to keep out — `ds:Prompt`, `ds:Tier`, `ds:name` — was a
|
|
364
|
+
// PREFIXED NAME, which contains no namespace IRI and so passes the rule
|
|
365
|
+
// above. DERIVED from the same declaration, by KEY this time.
|
|
366
|
+
//
|
|
367
|
+
// A leading non-word character keeps `https://…` and `foo.ds:x` out while
|
|
368
|
+
// still catching a bare term, one inside a query template, and one in
|
|
369
|
+
// user-facing copy.
|
|
370
|
+
const offenders = Object.keys(conf.prefixes ?? {}).flatMap((prefix) =>
|
|
371
|
+
findOffenders(
|
|
372
|
+
new RegExp(
|
|
373
|
+
`(^|[^A-Za-z0-9_])${prefix.replace(/[-.*+?^${}()|[\]\\]/g, "\\$&")}:[A-Za-z_]`,
|
|
374
|
+
),
|
|
375
|
+
),
|
|
376
|
+
);
|
|
377
|
+
expect(offenders).toEqual([]);
|
|
378
|
+
});
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* The grammar positions that quote a command a user is told to RUN: an example
|
|
383
|
+
* (`cmd:`), a recovery hint (`cli:`) and a doctor fix (`remedy:`).
|
|
384
|
+
*/
|
|
385
|
+
const COMMAND_POSITIONS = ["cmd", "cli", "remedy"];
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Every authored `.ts` under `src/capabilities/**` — no exemptions. The one
|
|
389
|
+
* file these rules used to exempt, `colophon/pragmaColophon.ts`, carried the
|
|
390
|
+
* distribution's own narrative in a capability source while the owner had not
|
|
391
|
+
* decided whether a fork inherits, rewrites, or declares it. The ruling
|
|
392
|
+
* (PRA-107): the narrative is DECLARED — it lives in `pragma.conf.ts` as
|
|
393
|
+
* `colophon: { markdown, summary }`, the file a fork edits — and the module is
|
|
394
|
+
* deleted. This filter-free list is the machine-checkable proof that the seam
|
|
395
|
+
* exists: a narrative reintroduced as a capability source falls under the two
|
|
396
|
+
* rules below like any other copy.
|
|
397
|
+
*/
|
|
398
|
+
const capabilitySources = listSources(join(root, "capabilities"));
|
|
399
|
+
|
|
400
|
+
describe("capability commands (PROTECTED)", () => {
|
|
401
|
+
it("no `cmd:`, `cli:` or `remedy:` value is a bare literal", () => {
|
|
402
|
+
// The rule that reaches `src/capabilities/**` without exempting most of it.
|
|
403
|
+
// The wider "name nothing" rule cannot: that tree legitimately carries the
|
|
404
|
+
// domain in runtime copy and in wire identifiers. But a command string is
|
|
405
|
+
// never content — it is the installed binary's own name plus a grammar
|
|
406
|
+
// path, and both are derived. So this is stated as a POSITION rule, not a
|
|
407
|
+
// file rule, and carries no exemptions.
|
|
408
|
+
//
|
|
409
|
+
// Raw source, not `readCopy`: the position is what makes it an offence, and
|
|
410
|
+
// reading the text directly means this guard holds whatever the scanner can
|
|
411
|
+
// see. DERIVED and ESCAPED from the shipped `name`, as above.
|
|
412
|
+
//
|
|
413
|
+
// A BACKTICK is a quote here. Every swept site is a template literal, so a
|
|
414
|
+
// regression that keeps the backtick and drops the interpolation is the ONE
|
|
415
|
+
// shape this rule has to catch — and it was the one shape the class `["']`
|
|
416
|
+
// could not see. The opening quote is captured and the span runs to it, so
|
|
417
|
+
// a name inside backticks in a double-quoted sentence still counts while
|
|
418
|
+
// the match cannot run past the literal that opened it.
|
|
419
|
+
//
|
|
420
|
+
// The scan is over the whole file, not line by line, because the formatter
|
|
421
|
+
// wraps a long value onto the line after its key: that is how `doctor`'s
|
|
422
|
+
// ke-store remedy sat in a `remedy:` position, naming this distribution,
|
|
423
|
+
// under a guard that reported zero exemptions.
|
|
424
|
+
const name = BIN_NAME.replace(/[-.*+?^${}()|[\]\\]/g, "\\$&");
|
|
425
|
+
const pattern = new RegExp(
|
|
426
|
+
`(?:${COMMAND_POSITIONS.join("|")}):\\s*(["'\`])(?:(?!\\1)[^])*?\\b${name}\\b`,
|
|
427
|
+
"gi",
|
|
428
|
+
);
|
|
429
|
+
const offenders: string[] = [];
|
|
430
|
+
for (const file of capabilitySources) {
|
|
431
|
+
for (const match of readFileSync(file, "utf-8").matchAll(pattern)) {
|
|
432
|
+
offenders.push(`${relative(root, file)}: ${match[0].trim()}`);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
expect(offenders).toEqual([]);
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
it("no command quoted in capability prose is a bare literal", () => {
|
|
439
|
+
// The other half of the same promise, and the half the position rule cannot
|
|
440
|
+
// reach: an empty-state hint, a recovery MESSAGE (the second argument to
|
|
441
|
+
// `cliRecovery`, beside a first argument the position rule already covers),
|
|
442
|
+
// a `sources status` headline, a wizard step's title. They reach the same
|
|
443
|
+
// user with the same instruction, and seven of them named this distribution
|
|
444
|
+
// while the rule above reported zero exemptions.
|
|
445
|
+
//
|
|
446
|
+
// A command in prose is a backticked one: `` run `pragma sources update` ``.
|
|
447
|
+
// `readCopy` reads a template's substitutions as code and its literal chunks
|
|
448
|
+
// as copy, so an interpolated `\`${BIN_NAME} …\`` leaves no chunk that
|
|
449
|
+
// begins with the name — which is exactly the difference this asserts.
|
|
450
|
+
// DERIVED and ESCAPED from the shipped `name`, as above.
|
|
451
|
+
const name = BIN_NAME.replace(/[-.*+?^${}()|[\]\\]/g, "\\$&");
|
|
452
|
+
const pattern = new RegExp(`\`${name}\\b`, "i");
|
|
453
|
+
const offenders: string[] = [];
|
|
454
|
+
for (const file of capabilitySources) {
|
|
455
|
+
for (const literal of readCopy(readFileSync(file, "utf-8"))) {
|
|
456
|
+
if (pattern.test(literal)) {
|
|
457
|
+
offenders.push(`${relative(root, file)}: ${literal}`);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
expect(offenders).toEqual([]);
|
|
462
|
+
});
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
describe("user-facing copy house style (PROTECTED)", () => {
|
|
466
|
+
// The voice rules ({@link COPY_RULES}) run over BOTH file sets the naming
|
|
467
|
+
// rules above read — the kernel set and the capability set — because voice,
|
|
468
|
+
// unlike the distribution's name, is not content anywhere: a capability's
|
|
469
|
+
// error is the same product speaking as a kernel diagnostic. `readCopy`
|
|
470
|
+
// keeps comments, regexes, specifiers and test files out of scope, so a
|
|
471
|
+
// rule fires only on a string a user can actually be shown.
|
|
472
|
+
//
|
|
473
|
+
// One `it` per rule, NAMED by the rule, so a red run states the rule that
|
|
474
|
+
// fired; the assertion message carries the fix. What a failure prints is the
|
|
475
|
+
// offender list plus those two strings — everything needed to correct the
|
|
476
|
+
// copy lives in this repo.
|
|
477
|
+
const allSources = [...files, ...capabilitySources];
|
|
478
|
+
for (const { pattern, rule, fix } of COPY_RULES) {
|
|
479
|
+
it(rule, () => {
|
|
480
|
+
expect(findOffenders(pattern, allSources), fix).toEqual([]);
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The house rules for user-facing copy, as data.
|
|
3
|
+
*
|
|
4
|
+
* Every string this CLI prints is one product speaking, and a product with one
|
|
5
|
+
* voice phrases one meaning one way. These descriptors name the phrasings that
|
|
6
|
+
* are out of that voice, why, and what to write instead; `copy.test.ts` runs
|
|
7
|
+
* them over every authored string literal in the tree — the same scanner and
|
|
8
|
+
* file sets as the naming rules there, so comments, regexes, module specifiers
|
|
9
|
+
* and test fixtures are never in scope. A failure quotes the offending literal,
|
|
10
|
+
* the rule, and the fix, and nothing else: everything a maintainer needs to
|
|
11
|
+
* correct the string lives in this file.
|
|
12
|
+
*
|
|
13
|
+
* Rules are DATA rather than assertions so the set can grow (or move into a
|
|
14
|
+
* shared standards package) without rewriting the guard, and so each rule's
|
|
15
|
+
* pattern, statement and fix are reviewed together as one unit. Precision is
|
|
16
|
+
* the set's credibility: a pattern that fires on domain vocabulary gets
|
|
17
|
+
* disabled in practice, so a carve-out is encoded in the pattern itself — with
|
|
18
|
+
* its reason — never in an exemption list beside it.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/** One banned phrasing: what copy may not contain, why, and the rewrite. */
|
|
22
|
+
export interface CopyRule {
|
|
23
|
+
/** What the copy must not contain. */
|
|
24
|
+
readonly pattern: RegExp;
|
|
25
|
+
/** The house rule, stated for a reader of THIS codebase. */
|
|
26
|
+
readonly rule: string;
|
|
27
|
+
/** How to fix an offending string. */
|
|
28
|
+
readonly fix: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** The banned phrasings for user-facing copy. Enforced by `copy.test.ts`. */
|
|
32
|
+
export const COPY_RULES: readonly CopyRule[] = [
|
|
33
|
+
{
|
|
34
|
+
pattern: /\b(?:could not|failed to|unable to)\b/i,
|
|
35
|
+
rule: "User-facing copy says `cannot` — one phrasing for one meaning, so the CLI reads as one voice.",
|
|
36
|
+
fix: "Rewrite with `cannot` (present tense, no hedging), naming what is wrong rather than what was attempted.",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
// `\w+n't` covers every negated contraction in one arm; the lookbehind
|
|
40
|
+
// carves out `do/don't`, which is domain vocabulary — the name of the
|
|
41
|
+
// paired good/bad example a coding standard ships — not conversational
|
|
42
|
+
// tone. The second arm lists the pronoun contractions, which have no
|
|
43
|
+
// shared suffix shape.
|
|
44
|
+
pattern:
|
|
45
|
+
/\b(?<!do\/)\w+n't\b|\b(?:you|we|they|it|that|there|here|what|let)'(?:re|ve|ll|s|d)\b|\bi'm\b/i,
|
|
46
|
+
rule: "No contractions in user-facing copy — instructions read as statements, not conversation.",
|
|
47
|
+
fix: "Spell the words out, or restructure the sentence to drop the second person.",
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
pattern: /\b(?:please|sorry|oops)\b/i,
|
|
51
|
+
rule: "The CLI does not apologise or plead; it states the fact and the action.",
|
|
52
|
+
fix: "Drop the pleading word and instruct directly: `Report this issue at <url>.`",
|
|
53
|
+
},
|
|
54
|
+
];
|