@canonical/pragma-cli 0.18.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 +377 -0
- package/package.json +78 -0
- package/src/bin.test.ts +52 -0
- package/src/bin.ts +19 -0
- package/src/compile-validation.runner.ts +137 -0
- package/src/compile-validation.ts +192 -0
- package/src/completions/computeSocketPath.test.ts +26 -0
- package/src/completions/computeSocketPath.ts +16 -0
- package/src/completions/constants.ts +18 -0
- package/src/completions/handleQuery.test.ts +93 -0
- package/src/completions/handleQuery.ts +30 -0
- package/src/completions/index.ts +14 -0
- package/src/completions/queryCompletions.test.ts +100 -0
- package/src/completions/queryCompletions.ts +61 -0
- package/src/completions/querySocket.test.ts +70 -0
- package/src/completions/querySocket.ts +44 -0
- package/src/completions/startCompletionsServer.test.ts +74 -0
- package/src/completions/startCompletionsServer.ts +75 -0
- package/src/completions/startCompletionsServer.unit.test.ts +131 -0
- package/src/completions/waitForSocket.test.ts +27 -0
- package/src/completions/waitForSocket.ts +27 -0
- package/src/config/configExists.ts +14 -0
- package/src/config/index.ts +6 -0
- package/src/config/readConfig.test.ts +152 -0
- package/src/config/readConfig.ts +64 -0
- package/src/config/resolveConfigPath.test.ts +20 -0
- package/src/config/resolveConfigPath.ts +11 -0
- package/src/config/types.ts +26 -0
- package/src/config/writeConfig.ts +49 -0
- package/src/constants.ts +78 -0
- package/src/domains/block/blockConfig.ts +53 -0
- package/src/domains/block/commands/index.ts +4 -0
- package/src/domains/block/commands/list.test.ts +111 -0
- package/src/domains/block/commands/list.ts +69 -0
- package/src/domains/block/commands/lookup.test.ts +187 -0
- package/src/domains/block/commands/lookup.ts +199 -0
- package/src/domains/block/formatters/index.ts +4 -0
- package/src/domains/block/formatters/list.test.ts +107 -0
- package/src/domains/block/formatters/list.ts +64 -0
- package/src/domains/block/formatters/lookup.test.ts +317 -0
- package/src/domains/block/formatters/lookup.ts +354 -0
- package/src/domains/block/formatters/types.ts +16 -0
- package/src/domains/block/helpers/index.ts +4 -0
- package/src/domains/block/helpers/resolveAspects.test.ts +64 -0
- package/src/domains/block/helpers/resolveAspects.ts +35 -0
- package/src/domains/block/index.ts +25 -0
- package/src/domains/block/mcp/index.ts +2 -0
- package/src/domains/block/mcp/specs.ts +199 -0
- package/src/domains/block/operations/index.ts +4 -0
- package/src/domains/block/operations/list.test.ts +80 -0
- package/src/domains/block/operations/list.ts +72 -0
- package/src/domains/block/operations/lookup.test.ts +108 -0
- package/src/domains/block/operations/lookup.ts +359 -0
- package/src/domains/block/orchestration/blockEmptyError.ts +19 -0
- package/src/domains/block/orchestration/buildBlockFilters.ts +12 -0
- package/src/domains/block/orchestration/enrichBlocks.ts +37 -0
- package/src/domains/block/orchestration/index.ts +5 -0
- package/src/domains/block/orchestration/resolveBlockList.ts +39 -0
- package/src/domains/block/orchestration/resolveBlockLookup.ts +21 -0
- package/src/domains/block/types.ts +30 -0
- package/src/domains/config/commands/channel.test.ts +101 -0
- package/src/domains/config/commands/channel.ts +80 -0
- package/src/domains/config/commands/index.ts +4 -0
- package/src/domains/config/commands/show.test.ts +61 -0
- package/src/domains/config/commands/show.ts +51 -0
- package/src/domains/config/commands/tier.test.ts +84 -0
- package/src/domains/config/commands/tier.ts +78 -0
- package/src/domains/config/formatters/channel.test.ts +56 -0
- package/src/domains/config/formatters/channel.ts +34 -0
- package/src/domains/config/formatters/index.ts +4 -0
- package/src/domains/config/formatters/show.test.ts +126 -0
- package/src/domains/config/formatters/show.ts +66 -0
- package/src/domains/config/formatters/tier.test.ts +70 -0
- package/src/domains/config/formatters/tier.ts +40 -0
- package/src/domains/config/index.ts +23 -0
- package/src/domains/config/mcp/index.ts +2 -0
- package/src/domains/config/mcp/specs.ts +108 -0
- package/src/domains/config/operations/index.ts +5 -0
- package/src/domains/config/operations/show.test.ts +60 -0
- package/src/domains/config/operations/show.ts +42 -0
- package/src/domains/config/operations/types.ts +13 -0
- package/src/domains/config/operations/validateChannel.test.ts +36 -0
- package/src/domains/config/operations/validateChannel.ts +24 -0
- package/src/domains/config/operations/validateTier.test.ts +56 -0
- package/src/domains/config/operations/validateTier.ts +35 -0
- package/src/domains/create/commands/component.test.ts +166 -0
- package/src/domains/create/commands/component.ts +129 -0
- package/src/domains/create/commands/index.ts +3 -0
- package/src/domains/create/commands/package.test.ts +35 -0
- package/src/domains/create/commands/package.ts +21 -0
- package/src/domains/create/index.ts +15 -0
- package/src/domains/create/mcp/index.ts +2 -0
- package/src/domains/create/mcp/specs.ts +174 -0
- package/src/domains/doctor/commands/doctor.test.ts +75 -0
- package/src/domains/doctor/commands/doctor.ts +43 -0
- package/src/domains/doctor/commands/index.ts +2 -0
- package/src/domains/doctor/formatters/doctor.test.ts +117 -0
- package/src/domains/doctor/formatters/doctor.ts +84 -0
- package/src/domains/doctor/formatters/index.ts +2 -0
- package/src/domains/doctor/index.ts +9 -0
- package/src/domains/doctor/mcp/index.ts +2 -0
- package/src/domains/doctor/mcp/specs.ts +88 -0
- package/src/domains/doctor/operations/checks/checkConfigFile.ts +28 -0
- package/src/domains/doctor/operations/checks/checkKeStore.ts +38 -0
- package/src/domains/doctor/operations/checks/checkMcpConfigured.ts +65 -0
- package/src/domains/doctor/operations/checks/checkNodeVersion.ts +25 -0
- package/src/domains/doctor/operations/checks/checkPragmaVersion.ts +20 -0
- package/src/domains/doctor/operations/checks/checkShellCompletions.ts +42 -0
- package/src/domains/doctor/operations/checks/checkSkillsSymlinked.ts +64 -0
- package/src/domains/doctor/operations/checks/index.ts +8 -0
- package/src/domains/doctor/operations/checks.test.ts +151 -0
- package/src/domains/doctor/operations/index.ts +3 -0
- package/src/domains/doctor/operations/runChecks.test.ts +89 -0
- package/src/domains/doctor/operations/runChecks.ts +38 -0
- package/src/domains/doctor/operations/types.ts +20 -0
- package/src/domains/graph/commands/index.ts +4 -0
- package/src/domains/graph/commands/inspect.test.ts +94 -0
- package/src/domains/graph/commands/inspect.ts +63 -0
- package/src/domains/graph/commands/query.test.ts +92 -0
- package/src/domains/graph/commands/query.ts +60 -0
- package/src/domains/graph/formatters/index.ts +4 -0
- package/src/domains/graph/formatters/inspect.ts +45 -0
- package/src/domains/graph/formatters/query.ts +37 -0
- package/src/domains/graph/helpers/index.ts +3 -0
- package/src/domains/graph/helpers/resolveUri.ts +70 -0
- package/src/domains/graph/index.ts +22 -0
- package/src/domains/graph/mcp/index.ts +2 -0
- package/src/domains/graph/mcp/specs.ts +82 -0
- package/src/domains/graph/operations/executeQuery.test.ts +68 -0
- package/src/domains/graph/operations/executeQuery.ts +32 -0
- package/src/domains/graph/operations/index.ts +4 -0
- package/src/domains/graph/operations/inspectUri.test.ts +101 -0
- package/src/domains/graph/operations/inspectUri.ts +61 -0
- package/src/domains/info/commands/index.ts +4 -0
- package/src/domains/info/commands/info.test.ts +88 -0
- package/src/domains/info/commands/info.ts +47 -0
- package/src/domains/info/commands/upgrade.test.ts +183 -0
- package/src/domains/info/commands/upgrade.ts +150 -0
- package/src/domains/info/constants.test.ts +22 -0
- package/src/domains/info/constants.ts +15 -0
- package/src/domains/info/formatters/index.ts +8 -0
- package/src/domains/info/formatters/info.test.ts +173 -0
- package/src/domains/info/formatters/info.ts +116 -0
- package/src/domains/info/formatters/upgrade.test.ts +133 -0
- package/src/domains/info/formatters/upgrade.ts +68 -0
- package/src/domains/info/index.ts +7 -0
- package/src/domains/info/operations/checkRegistryVersion.test.ts +124 -0
- package/src/domains/info/operations/checkRegistryVersion.ts +45 -0
- package/src/domains/info/operations/collectInfo.test.ts +111 -0
- package/src/domains/info/operations/collectInfo.ts +68 -0
- package/src/domains/info/operations/collectStoreSummary.test.ts +61 -0
- package/src/domains/info/operations/collectStoreSummary.ts +42 -0
- package/src/domains/info/operations/index.ts +5 -0
- package/src/domains/info/types.test-d.ts +35 -0
- package/src/domains/info/types.ts +46 -0
- package/src/domains/llm/commands/index.ts +3 -0
- package/src/domains/llm/commands/llm.ts +37 -0
- package/src/domains/llm/data/commandReference.ts +25 -0
- package/src/domains/llm/data/decisionTrees.ts +46 -0
- package/src/domains/llm/data/index.ts +4 -0
- package/src/domains/llm/formatters/index.ts +3 -0
- package/src/domains/llm/formatters/orientation.ts +53 -0
- package/src/domains/llm/index.ts +8 -0
- package/src/domains/llm/llmCommand.test.ts +93 -0
- package/src/domains/llm/mcp/index.ts +2 -0
- package/src/domains/llm/mcp/specs.ts +87 -0
- package/src/domains/llm/operations/collectContext.ts +47 -0
- package/src/domains/llm/operations/index.ts +3 -0
- package/src/domains/llm/types.ts +32 -0
- package/src/domains/modifier/commands/index.ts +4 -0
- package/src/domains/modifier/commands/list.test.ts +57 -0
- package/src/domains/modifier/commands/list.ts +33 -0
- package/src/domains/modifier/commands/lookup.test.ts +91 -0
- package/src/domains/modifier/commands/lookup.ts +105 -0
- package/src/domains/modifier/formatters/index.ts +4 -0
- package/src/domains/modifier/formatters/list.test.ts +38 -0
- package/src/domains/modifier/formatters/list.ts +35 -0
- package/src/domains/modifier/formatters/lookup.test.ts +33 -0
- package/src/domains/modifier/formatters/lookup.ts +38 -0
- package/src/domains/modifier/index.ts +22 -0
- package/src/domains/modifier/mcp/index.ts +2 -0
- package/src/domains/modifier/mcp/specs.ts +97 -0
- package/src/domains/modifier/operations/index.ts +4 -0
- package/src/domains/modifier/operations/list.test.ts +39 -0
- package/src/domains/modifier/operations/list.ts +41 -0
- package/src/domains/modifier/operations/lookup.test.ts +37 -0
- package/src/domains/modifier/operations/lookup.ts +57 -0
- package/src/domains/modifier/orchestration/index.ts +3 -0
- package/src/domains/modifier/orchestration/modifierEmptyError.ts +10 -0
- package/src/domains/modifier/orchestration/resolveModifierList.ts +16 -0
- package/src/domains/modifier/orchestration/resolveModifierLookup.ts +20 -0
- package/src/domains/modifier/types.ts +5 -0
- package/src/domains/ontology/commands/index.ts +4 -0
- package/src/domains/ontology/commands/list.test.ts +82 -0
- package/src/domains/ontology/commands/list.ts +46 -0
- package/src/domains/ontology/commands/show.test.ts +103 -0
- package/src/domains/ontology/commands/show.ts +66 -0
- package/src/domains/ontology/formatters/index.ts +4 -0
- package/src/domains/ontology/formatters/list.ts +37 -0
- package/src/domains/ontology/formatters/show.ts +74 -0
- package/src/domains/ontology/helpers/findNamespace.ts +23 -0
- package/src/domains/ontology/helpers/index.ts +7 -0
- package/src/domains/ontology/helpers/queryClasses.ts +50 -0
- package/src/domains/ontology/helpers/queryProperties.ts +57 -0
- package/src/domains/ontology/helpers/resolvePrefix.ts +45 -0
- package/src/domains/ontology/index.ts +26 -0
- package/src/domains/ontology/mcp/index.ts +2 -0
- package/src/domains/ontology/mcp/specs.ts +93 -0
- package/src/domains/ontology/operations/index.ts +5 -0
- package/src/domains/ontology/operations/listOntologies.test.ts +45 -0
- package/src/domains/ontology/operations/listOntologies.ts +101 -0
- package/src/domains/ontology/operations/showOntology.test.ts +65 -0
- package/src/domains/ontology/operations/showOntology.ts +41 -0
- package/src/domains/ontology/operations/showOntologyRaw.test.ts +39 -0
- package/src/domains/ontology/operations/showOntologyRaw.ts +50 -0
- package/src/domains/setup/commands/all.ts +58 -0
- package/src/domains/setup/commands/completions.ts +85 -0
- package/src/domains/setup/commands/entrypoints.test.ts +170 -0
- package/src/domains/setup/commands/index.ts +6 -0
- package/src/domains/setup/commands/lsp.ts +49 -0
- package/src/domains/setup/commands/mcp.ts +119 -0
- package/src/domains/setup/commands/skills.test.ts +64 -0
- package/src/domains/setup/commands/skills.ts +106 -0
- package/src/domains/setup/formatters/index.ts +2 -0
- package/src/domains/setup/formatters/skills.test.ts +103 -0
- package/src/domains/setup/formatters/skills.ts +112 -0
- package/src/domains/setup/formatters/types.ts +7 -0
- package/src/domains/setup/helpers/completionScripts.test.ts +58 -0
- package/src/domains/setup/helpers/completionScripts.ts +92 -0
- package/src/domains/setup/helpers/constants.ts +2 -0
- package/src/domains/setup/helpers/detectShell.test.ts +48 -0
- package/src/domains/setup/helpers/detectShell.ts +20 -0
- package/src/domains/setup/helpers/index.ts +12 -0
- package/src/domains/setup/helpers/runSetupTask.test.ts +279 -0
- package/src/domains/setup/helpers/runSetupTask.ts +229 -0
- package/src/domains/setup/index.ts +33 -0
- package/src/domains/setup/operations/index.ts +6 -0
- package/src/domains/setup/operations/setupAll.test.ts +48 -0
- package/src/domains/setup/operations/setupAll.ts +41 -0
- package/src/domains/setup/operations/setupCompletions.test.ts +94 -0
- package/src/domains/setup/operations/setupCompletions.ts +54 -0
- package/src/domains/setup/operations/setupLsp.test.ts +29 -0
- package/src/domains/setup/operations/setupLsp.ts +17 -0
- package/src/domains/setup/operations/setupMcp.test.ts +115 -0
- package/src/domains/setup/operations/setupMcp.ts +108 -0
- package/src/domains/setup/operations/setupSkills.test.ts +191 -0
- package/src/domains/setup/operations/setupSkills.ts +160 -0
- package/src/domains/setup/types.ts +18 -0
- package/src/domains/shared/ToolSpec.ts +49 -0
- package/src/domains/shared/bootStore.ts +77 -0
- package/src/domains/shared/buildQuery.ts +18 -0
- package/src/domains/shared/compactUri.test.ts +21 -0
- package/src/domains/shared/compactUri.ts +16 -0
- package/src/domains/shared/context.ts +15 -0
- package/src/domains/shared/contracts.ts +113 -0
- package/src/domains/shared/extractLocalName.test.ts +21 -0
- package/src/domains/shared/extractLocalName.ts +14 -0
- package/src/domains/shared/filters/buildChannelFilter.test.ts +52 -0
- package/src/domains/shared/filters/buildChannelFilter.ts +41 -0
- package/src/domains/shared/filters/buildFilterConfig.ts +16 -0
- package/src/domains/shared/filters/buildFilters.test.ts +33 -0
- package/src/domains/shared/filters/buildFilters.ts +30 -0
- package/src/domains/shared/filters/buildTierFilter.test.ts +78 -0
- package/src/domains/shared/filters/buildTierFilter.ts +69 -0
- package/src/domains/shared/filters/describeFilters.ts +14 -0
- package/src/domains/shared/filters/index.ts +10 -0
- package/src/domains/shared/formatters.ts +35 -0
- package/src/domains/shared/lookupMany.ts +45 -0
- package/src/domains/shared/namespaces.ts +18 -0
- package/src/domains/shared/packages.ts +76 -0
- package/src/domains/shared/prefixes.ts +37 -0
- package/src/domains/shared/runtime.ts +62 -0
- package/src/domains/shared/types.test-d.ts +127 -0
- package/src/domains/shared/types.ts +348 -0
- package/src/domains/skill/commands/index.ts +2 -0
- package/src/domains/skill/commands/list.test.ts +111 -0
- package/src/domains/skill/commands/list.ts +69 -0
- package/src/domains/skill/formatters/index.ts +2 -0
- package/src/domains/skill/formatters/list.test.ts +140 -0
- package/src/domains/skill/formatters/list.ts +119 -0
- package/src/domains/skill/formatters/types.ts +8 -0
- package/src/domains/skill/helpers/index.ts +6 -0
- package/src/domains/skill/helpers/parseFrontmatter.test.ts +122 -0
- package/src/domains/skill/helpers/parseFrontmatter.ts +112 -0
- package/src/domains/skill/helpers/resolveSkillSources.ts +34 -0
- package/src/domains/skill/index.ts +19 -0
- package/src/domains/skill/mcp/index.ts +2 -0
- package/src/domains/skill/mcp/specs.ts +38 -0
- package/src/domains/skill/operations/discover.test.ts +145 -0
- package/src/domains/skill/operations/discover.ts +68 -0
- package/src/domains/skill/operations/index.ts +4 -0
- package/src/domains/skill/operations/list.test.ts +68 -0
- package/src/domains/skill/operations/list.ts +47 -0
- package/src/domains/skill/types.ts +25 -0
- package/src/domains/standard/commands/categories.test.ts +70 -0
- package/src/domains/standard/commands/categories.ts +48 -0
- package/src/domains/standard/commands/index.ts +5 -0
- package/src/domains/standard/commands/list.test.ts +105 -0
- package/src/domains/standard/commands/list.ts +81 -0
- package/src/domains/standard/commands/lookup.test.ts +135 -0
- package/src/domains/standard/commands/lookup.ts +127 -0
- package/src/domains/standard/formatters/categories.test.ts +44 -0
- package/src/domains/standard/formatters/categories.ts +38 -0
- package/src/domains/standard/formatters/index.ts +6 -0
- package/src/domains/standard/formatters/list.test.ts +166 -0
- package/src/domains/standard/formatters/list.ts +156 -0
- package/src/domains/standard/formatters/lookup.test.ts +95 -0
- package/src/domains/standard/formatters/lookup.ts +86 -0
- package/src/domains/standard/formatters/types.ts +31 -0
- package/src/domains/standard/index.ts +32 -0
- package/src/domains/standard/mcp/index.ts +2 -0
- package/src/domains/standard/mcp/specs.ts +197 -0
- package/src/domains/standard/operations/categories.test.ts +61 -0
- package/src/domains/standard/operations/categories.ts +38 -0
- package/src/domains/standard/operations/index.ts +5 -0
- package/src/domains/standard/operations/list.test.ts +75 -0
- package/src/domains/standard/operations/list.ts +64 -0
- package/src/domains/standard/operations/lookup.test.ts +58 -0
- package/src/domains/standard/operations/lookup.ts +142 -0
- package/src/domains/standard/orchestration/buildStandardFilters.ts +11 -0
- package/src/domains/standard/orchestration/index.ts +4 -0
- package/src/domains/standard/orchestration/resolveStandardList.ts +42 -0
- package/src/domains/standard/orchestration/resolveStandardLookup.ts +20 -0
- package/src/domains/standard/orchestration/standardEmptyError.ts +19 -0
- package/src/domains/standard/types.ts +15 -0
- package/src/domains/tier/commands/index.ts +3 -0
- package/src/domains/tier/commands/list.test.ts +67 -0
- package/src/domains/tier/commands/list.ts +43 -0
- package/src/domains/tier/formatters/index.ts +3 -0
- package/src/domains/tier/formatters/list.test.ts +33 -0
- package/src/domains/tier/formatters/list.ts +40 -0
- package/src/domains/tier/index.ts +17 -0
- package/src/domains/tier/mcp/index.ts +2 -0
- package/src/domains/tier/mcp/specs.ts +38 -0
- package/src/domains/tier/operations/index.ts +3 -0
- package/src/domains/tier/operations/list.test.ts +32 -0
- package/src/domains/tier/operations/list.ts +33 -0
- package/src/domains/token/commands/add-config.test.ts +68 -0
- package/src/domains/token/commands/add-config.ts +62 -0
- package/src/domains/token/commands/index.ts +5 -0
- package/src/domains/token/commands/list.test.ts +82 -0
- package/src/domains/token/commands/list.ts +45 -0
- package/src/domains/token/commands/lookup.test.ts +125 -0
- package/src/domains/token/commands/lookup.ts +121 -0
- package/src/domains/token/formatters/index.ts +4 -0
- package/src/domains/token/formatters/list.test.ts +37 -0
- package/src/domains/token/formatters/list.ts +37 -0
- package/src/domains/token/formatters/lookup.test.ts +61 -0
- package/src/domains/token/formatters/lookup.ts +72 -0
- package/src/domains/token/index.ts +32 -0
- package/src/domains/token/mcp/index.ts +2 -0
- package/src/domains/token/mcp/specs.ts +145 -0
- package/src/domains/token/operations/add-config.test.ts +68 -0
- package/src/domains/token/operations/add-config.ts +61 -0
- package/src/domains/token/operations/index.ts +7 -0
- package/src/domains/token/operations/list.test.ts +50 -0
- package/src/domains/token/operations/list.ts +52 -0
- package/src/domains/token/operations/lookup.test.ts +42 -0
- package/src/domains/token/operations/lookup.ts +66 -0
- package/src/domains/token/orchestration/index.ts +3 -0
- package/src/domains/token/orchestration/resolveTokenList.ts +17 -0
- package/src/domains/token/orchestration/resolveTokenLookup.ts +20 -0
- package/src/domains/token/orchestration/tokenEmptyError.ts +17 -0
- package/src/domains/token/types.ts +6 -0
- package/src/error/PragmaError.test.ts +121 -0
- package/src/error/PragmaError.ts +164 -0
- package/src/error/constants.ts +12 -0
- package/src/error/index.ts +4 -0
- package/src/error/types.ts +41 -0
- package/src/index.ts +141 -0
- package/src/mcp/createMcpServer.test.ts +41 -0
- package/src/mcp/createMcpServer.ts +53 -0
- package/src/mcp/error/buildRecovery.test.ts +37 -0
- package/src/mcp/error/buildRecovery.ts +17 -0
- package/src/mcp/error/index.ts +12 -0
- package/src/mcp/error/serializeError.test.ts +121 -0
- package/src/mcp/error/serializeError.ts +31 -0
- package/src/mcp/error/serializeErrorPayload.test.ts +38 -0
- package/src/mcp/error/serializeErrorPayload.ts +27 -0
- package/src/mcp/error/types.ts +51 -0
- package/src/mcp/index.ts +15 -0
- package/src/mcp/registerResources.test.ts +236 -0
- package/src/mcp/registerResources.ts +303 -0
- package/src/mcp/runMcpServer.test.ts +66 -0
- package/src/mcp/runMcpServer.ts +24 -0
- package/src/mcp/tools/index.ts +55 -0
- package/src/mcp/tools/registerFromSpec.ts +97 -0
- package/src/mcp/tools/registerTools.test.ts +1124 -0
- package/src/mcp/types.ts +62 -0
- package/src/mcp/utils/estimateTokens.test.ts +14 -0
- package/src/mcp/utils/estimateTokens.ts +9 -0
- package/src/mcp/utils/index.ts +11 -0
- package/src/mcp/utils/wrapTool.test.ts +108 -0
- package/src/mcp/utils/wrapTool.ts +81 -0
- package/src/package-manager/constants.ts +29 -0
- package/src/package-manager/detectInstallSource.test.ts +23 -0
- package/src/package-manager/detectInstallSource.ts +111 -0
- package/src/package-manager/detectLocalInstall.test.ts +16 -0
- package/src/package-manager/detectLocalInstall.ts +43 -0
- package/src/package-manager/detectPackageManager.test.ts +81 -0
- package/src/package-manager/detectPackageManager.ts +30 -0
- package/src/package-manager/index.ts +6 -0
- package/src/package-manager/types.ts +12 -0
- package/src/pipeline/collectCommands.test.ts +37 -0
- package/src/pipeline/collectCommands.ts +47 -0
- package/src/pipeline/constants.ts +14 -0
- package/src/pipeline/createProgram.test.ts +112 -0
- package/src/pipeline/createProgram.ts +70 -0
- package/src/pipeline/formatTerminal.test.ts +43 -0
- package/src/pipeline/formatTerminal.ts +53 -0
- package/src/pipeline/index.ts +19 -0
- package/src/pipeline/mapExitCode.test.ts +41 -0
- package/src/pipeline/mapExitCode.ts +12 -0
- package/src/pipeline/parseGlobalFlags.ts +21 -0
- package/src/pipeline/renderError.test.ts +151 -0
- package/src/pipeline/renderError.ts +114 -0
- package/src/pipeline/resolveCommandKind.test.ts +68 -0
- package/src/pipeline/resolveCommandKind.ts +71 -0
- package/src/pipeline/runCli.orchestration.test.ts +418 -0
- package/src/pipeline/runCli.test.ts +70 -0
- package/src/pipeline/runCli.ts +215 -0
- package/src/pipeline/types.ts +17 -0
- package/src/testing/cli.ts +43 -0
- package/src/testing/createTestMcpClient.ts +64 -0
- package/src/testing/dsFixtures.ts +506 -0
- package/src/testing/fixtures/canonical-config.json +4 -0
- package/src/testing/fixtures/canonical.ttl +437 -0
- package/src/testing/fixtures/filtered-config.json +4 -0
- package/src/testing/fixtures.ts +34 -0
- package/src/testing/helpers/assertParity.ts +28 -0
- package/src/testing/helpers/createTestMcpClient.ts +40 -0
- package/src/testing/helpers/createTestRuntime.ts +67 -0
- package/src/testing/index.ts +8 -0
- package/src/testing/integration/agent-session.test.ts +148 -0
- package/src/testing/integration/boot.test.ts +67 -0
- package/src/testing/integration/mcp-surface.test.ts +574 -0
- package/src/testing/integration/parity.test.ts +192 -0
- package/src/testing/store.ts +39 -0
- package/src/testing/types.ts +20 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prefix map for ke store creation.
|
|
3
|
+
*
|
|
4
|
+
* Registered as PREFIX declarations in every SPARQL query.
|
|
5
|
+
* Single source of truth — rename a key here and P updates automatically.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { PrefixMap } from "@canonical/ke";
|
|
9
|
+
|
|
10
|
+
export const PREFIX_MAP = {
|
|
11
|
+
ds: "https://ds.canonical.com/",
|
|
12
|
+
cs: "http://pragma.canonical.com/codestandards#",
|
|
13
|
+
rdfs: "http://www.w3.org/2000/01/rdf-schema#",
|
|
14
|
+
owl: "http://www.w3.org/2002/07/owl#",
|
|
15
|
+
skos: "http://www.w3.org/2004/02/skos/core#",
|
|
16
|
+
} as const satisfies PrefixMap;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* SPARQL prefix accessors derived from {@link PREFIX_MAP}.
|
|
20
|
+
*
|
|
21
|
+
* Use in query templates: `${P.ds}Component` → `"ds:Component"`.
|
|
22
|
+
* Renaming a key in PREFIX_MAP automatically updates every query.
|
|
23
|
+
*/
|
|
24
|
+
export const P = Object.fromEntries(
|
|
25
|
+
Object.keys(PREFIX_MAP).map((k) => [k, `${k}:`]),
|
|
26
|
+
) as { readonly [K in keyof typeof PREFIX_MAP]: `${K}:` };
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Turtle `@prefix` declarations derived from {@link PREFIX_MAP}.
|
|
30
|
+
*
|
|
31
|
+
* Includes `xsd:` which TTL data files commonly use but SPARQL queries
|
|
32
|
+
* don't need (ke auto-injects PREFIX_MAP for queries).
|
|
33
|
+
*/
|
|
34
|
+
export const TTL_PREFIXES = [
|
|
35
|
+
...Object.entries(PREFIX_MAP).map(([k, uri]) => `@prefix ${k}: <${uri}> .`),
|
|
36
|
+
"@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .",
|
|
37
|
+
].join("\n");
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified boot path for pragma CLI, MCP, and completions server.
|
|
3
|
+
*
|
|
4
|
+
* `PragmaRuntime` encapsulates all boot-time state (store, config, cwd).
|
|
5
|
+
* `bootPragma()` is the single factory function that creates it. All three
|
|
6
|
+
* surfaces (CLI, MCP, completions) call `bootPragma()` instead of manually
|
|
7
|
+
* assembling store + config.
|
|
8
|
+
*
|
|
9
|
+
* @note Impure — reads config from filesystem and boots ke store (WASM + TTL).
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { SourceSpec, Store } from "@canonical/ke";
|
|
13
|
+
import { type PragmaConfig, readConfig } from "#config";
|
|
14
|
+
import { bootStore } from "./bootStore.js";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Boot-time state shared by CLI, MCP, and completions server.
|
|
18
|
+
*
|
|
19
|
+
* Four members:
|
|
20
|
+
* - `store` — the ke triple store, loaded and ready for SPARQL queries.
|
|
21
|
+
* - `config` — resolved pragma config (tier, channel).
|
|
22
|
+
* - `cwd` — working directory used for config and source resolution.
|
|
23
|
+
* - `dispose()` — tears down the store and frees WASM memory. Must be
|
|
24
|
+
* called exactly once; calling operations after dispose is undefined.
|
|
25
|
+
*/
|
|
26
|
+
export interface PragmaRuntime {
|
|
27
|
+
readonly store: Store;
|
|
28
|
+
readonly config: PragmaConfig;
|
|
29
|
+
readonly cwd: string;
|
|
30
|
+
dispose(): void;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Create a fully initialized `PragmaRuntime`.
|
|
35
|
+
*
|
|
36
|
+
* Reads config from `cwd` (defaults to `process.cwd()`), boots the ke
|
|
37
|
+
* store from resolved sources, and returns a runtime ready for operation
|
|
38
|
+
* calls. The caller owns the lifecycle and must call `dispose()`.
|
|
39
|
+
*
|
|
40
|
+
* @param options.cwd - Working directory for config and source resolution.
|
|
41
|
+
* @param options.sources - Override sources for testing (skip filesystem resolution).
|
|
42
|
+
* @throws PragmaError with code CONFIG_ERROR if config is invalid.
|
|
43
|
+
* @throws PragmaError with code STORE_ERROR if store fails to initialize.
|
|
44
|
+
*/
|
|
45
|
+
export async function bootPragma(options?: {
|
|
46
|
+
cwd?: string;
|
|
47
|
+
sources?: SourceSpec[];
|
|
48
|
+
}): Promise<PragmaRuntime> {
|
|
49
|
+
const cwd = options?.cwd ?? process.cwd();
|
|
50
|
+
const config = readConfig(cwd);
|
|
51
|
+
const store = await bootStore({
|
|
52
|
+
cwd,
|
|
53
|
+
sources: options?.sources,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
store,
|
|
58
|
+
config,
|
|
59
|
+
cwd,
|
|
60
|
+
dispose: () => store.dispose(),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compile-time type tests.
|
|
3
|
+
*
|
|
4
|
+
* Asserts that shared operation return types match their contracts.
|
|
5
|
+
* Checked by `tsc --noEmit`, not executed at runtime.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { Store, URI } from "@canonical/ke";
|
|
9
|
+
import { expectTypeOf } from "expect-type";
|
|
10
|
+
import { listBlocks, lookupBlock } from "../block/operations/index.js";
|
|
11
|
+
import { listModifiers, lookupModifier } from "../modifier/operations/index.js";
|
|
12
|
+
import {
|
|
13
|
+
listCategories,
|
|
14
|
+
listStandards,
|
|
15
|
+
lookupStandard,
|
|
16
|
+
} from "../standard/operations/index.js";
|
|
17
|
+
import { listTiers } from "../tier/operations/index.js";
|
|
18
|
+
import { listTokens, lookupToken } from "../token/operations/index.js";
|
|
19
|
+
import type {
|
|
20
|
+
AnatomyNode,
|
|
21
|
+
AnatomyTree,
|
|
22
|
+
BlockDetailed,
|
|
23
|
+
BlockDigest,
|
|
24
|
+
BlockSummary,
|
|
25
|
+
CategorySummary,
|
|
26
|
+
CodeBlock,
|
|
27
|
+
FilterConfig,
|
|
28
|
+
ModifierFamily,
|
|
29
|
+
StandardDetailed,
|
|
30
|
+
StandardRef,
|
|
31
|
+
StandardSummary,
|
|
32
|
+
TierEntry,
|
|
33
|
+
TokenDetailed,
|
|
34
|
+
TokenRef,
|
|
35
|
+
TokenSummary,
|
|
36
|
+
} from "./types.js";
|
|
37
|
+
|
|
38
|
+
// =============================================================================
|
|
39
|
+
// Type structure assertions
|
|
40
|
+
// =============================================================================
|
|
41
|
+
|
|
42
|
+
// BlockSummary
|
|
43
|
+
expectTypeOf<BlockSummary["uri"]>().toEqualTypeOf<URI>();
|
|
44
|
+
expectTypeOf<BlockSummary["name"]>().toBeString();
|
|
45
|
+
expectTypeOf<BlockSummary["type"]>().toEqualTypeOf<
|
|
46
|
+
"component" | "pattern" | "layout" | "subcomponent"
|
|
47
|
+
>();
|
|
48
|
+
expectTypeOf<BlockSummary["tier"]>().toBeString();
|
|
49
|
+
expectTypeOf<BlockSummary["modifiers"]>().toEqualTypeOf<readonly string[]>();
|
|
50
|
+
expectTypeOf<BlockSummary["nodeCount"]>().toBeNumber();
|
|
51
|
+
expectTypeOf<BlockSummary["tokenCount"]>().toBeNumber();
|
|
52
|
+
|
|
53
|
+
// BlockDigest extends BlockSummary
|
|
54
|
+
expectTypeOf<BlockDigest>().toMatchTypeOf<BlockSummary>();
|
|
55
|
+
expectTypeOf<BlockDigest["summary"]>().toEqualTypeOf<string | null>();
|
|
56
|
+
|
|
57
|
+
// BlockDetailed extends BlockSummary
|
|
58
|
+
expectTypeOf<BlockDetailed>().toMatchTypeOf<BlockDigest>();
|
|
59
|
+
expectTypeOf<BlockDetailed["anatomy"]>().toEqualTypeOf<AnatomyTree | null>();
|
|
60
|
+
expectTypeOf<BlockDetailed["tokens"]>().toEqualTypeOf<readonly TokenRef[]>();
|
|
61
|
+
expectTypeOf<BlockDetailed["standards"]>().toEqualTypeOf<
|
|
62
|
+
readonly StandardRef[]
|
|
63
|
+
>();
|
|
64
|
+
|
|
65
|
+
// AnatomyNode
|
|
66
|
+
expectTypeOf<AnatomyNode["type"]>().toEqualTypeOf<"named" | "anonymous">();
|
|
67
|
+
expectTypeOf<AnatomyNode["children"]>().toEqualTypeOf<readonly AnatomyNode[]>();
|
|
68
|
+
|
|
69
|
+
// StandardSummary
|
|
70
|
+
expectTypeOf<StandardSummary["uri"]>().toEqualTypeOf<URI>();
|
|
71
|
+
expectTypeOf<StandardSummary["name"]>().toBeString();
|
|
72
|
+
expectTypeOf<StandardSummary["category"]>().toBeString();
|
|
73
|
+
|
|
74
|
+
// StandardDetailed extends StandardSummary
|
|
75
|
+
expectTypeOf<StandardDetailed>().toMatchTypeOf<StandardSummary>();
|
|
76
|
+
expectTypeOf<StandardDetailed["dos"]>().toEqualTypeOf<readonly CodeBlock[]>();
|
|
77
|
+
expectTypeOf<StandardDetailed["donts"]>().toEqualTypeOf<readonly CodeBlock[]>();
|
|
78
|
+
|
|
79
|
+
// CodeBlock
|
|
80
|
+
expectTypeOf<CodeBlock["language"]>().toBeString();
|
|
81
|
+
expectTypeOf<CodeBlock["code"]>().toBeString();
|
|
82
|
+
|
|
83
|
+
// CategorySummary
|
|
84
|
+
expectTypeOf<CategorySummary["name"]>().toBeString();
|
|
85
|
+
expectTypeOf<CategorySummary["standardCount"]>().toBeNumber();
|
|
86
|
+
|
|
87
|
+
// ModifierFamily
|
|
88
|
+
expectTypeOf<ModifierFamily["uri"]>().toEqualTypeOf<URI>();
|
|
89
|
+
expectTypeOf<ModifierFamily["values"]>().toEqualTypeOf<readonly string[]>();
|
|
90
|
+
|
|
91
|
+
// TokenSummary
|
|
92
|
+
expectTypeOf<TokenSummary["uri"]>().toEqualTypeOf<URI>();
|
|
93
|
+
expectTypeOf<TokenSummary["name"]>().toBeString();
|
|
94
|
+
expectTypeOf<TokenSummary["category"]>().toBeString();
|
|
95
|
+
|
|
96
|
+
// TokenDetailed extends TokenSummary
|
|
97
|
+
expectTypeOf<TokenDetailed>().toMatchTypeOf<TokenSummary>();
|
|
98
|
+
|
|
99
|
+
// TierEntry
|
|
100
|
+
expectTypeOf<TierEntry["uri"]>().toEqualTypeOf<URI>();
|
|
101
|
+
expectTypeOf<TierEntry["path"]>().toBeString();
|
|
102
|
+
expectTypeOf<TierEntry["depth"]>().toBeNumber();
|
|
103
|
+
|
|
104
|
+
// FilterConfig
|
|
105
|
+
expectTypeOf<FilterConfig["channel"]>().toEqualTypeOf<
|
|
106
|
+
"normal" | "experimental" | "prerelease"
|
|
107
|
+
>();
|
|
108
|
+
|
|
109
|
+
// =============================================================================
|
|
110
|
+
// Operation return type assertions
|
|
111
|
+
// =============================================================================
|
|
112
|
+
|
|
113
|
+
declare const store: Store;
|
|
114
|
+
declare const filters: FilterConfig;
|
|
115
|
+
|
|
116
|
+
expectTypeOf(listBlocks).returns.resolves.toEqualTypeOf<BlockSummary[]>();
|
|
117
|
+
expectTypeOf(lookupBlock).returns.resolves.toEqualTypeOf<BlockDetailed>();
|
|
118
|
+
expectTypeOf(listStandards).returns.resolves.toEqualTypeOf<StandardSummary[]>();
|
|
119
|
+
expectTypeOf(lookupStandard).returns.resolves.toEqualTypeOf<StandardDetailed>();
|
|
120
|
+
expectTypeOf(listCategories).returns.resolves.toEqualTypeOf<
|
|
121
|
+
CategorySummary[]
|
|
122
|
+
>();
|
|
123
|
+
expectTypeOf(listModifiers).returns.resolves.toEqualTypeOf<ModifierFamily[]>();
|
|
124
|
+
expectTypeOf(lookupModifier).returns.resolves.toEqualTypeOf<ModifierFamily>();
|
|
125
|
+
expectTypeOf(listTokens).returns.resolves.toEqualTypeOf<TokenSummary[]>();
|
|
126
|
+
expectTypeOf(lookupToken).returns.resolves.toEqualTypeOf<TokenDetailed>();
|
|
127
|
+
expectTypeOf(listTiers).returns.resolves.toEqualTypeOf<TierEntry[]>();
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared operation return types.
|
|
3
|
+
*
|
|
4
|
+
* Contract between the operations layer (D3) and CLI/MCP adapters.
|
|
5
|
+
* Same data, different presentations.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { URI } from "@canonical/ke";
|
|
9
|
+
|
|
10
|
+
// =============================================================================
|
|
11
|
+
// Block
|
|
12
|
+
// =============================================================================
|
|
13
|
+
|
|
14
|
+
/** Summary view of a design-system block (component, pattern, or primitive). */
|
|
15
|
+
export interface BlockSummary {
|
|
16
|
+
/** Full RDF URI identifying this block in the ke store. */
|
|
17
|
+
readonly uri: URI;
|
|
18
|
+
/** Human-readable name (local name extracted from URI). */
|
|
19
|
+
readonly name: string;
|
|
20
|
+
/** Normalized ontology type for the block. */
|
|
21
|
+
readonly type: "component" | "pattern" | "layout" | "subcomponent";
|
|
22
|
+
/** Tier path this block belongs to (e.g., `"global"`, `"apps/lxd"`). */
|
|
23
|
+
readonly tier: string;
|
|
24
|
+
/** Active modifier names applied to this block. */
|
|
25
|
+
readonly modifiers: readonly string[];
|
|
26
|
+
/** Framework implementations declared for this block, with availability flags. */
|
|
27
|
+
readonly implementations: readonly {
|
|
28
|
+
framework: string;
|
|
29
|
+
available: boolean;
|
|
30
|
+
}[];
|
|
31
|
+
/** Number of anatomy nodes (DOM elements) in this block's anatomy tree. */
|
|
32
|
+
readonly nodeCount: number;
|
|
33
|
+
/** Number of design tokens referenced by this block. */
|
|
34
|
+
readonly tokenCount: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Digest view of a block for richer summary displays. */
|
|
38
|
+
export interface BlockDigest extends BlockSummary {
|
|
39
|
+
/** Summary guidance when present in the graph. */
|
|
40
|
+
readonly summary: string | null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Single node in a block's anatomy tree (recursive). */
|
|
44
|
+
export interface AnatomyNode {
|
|
45
|
+
/** Element name (e.g., `"trigger"`, `"panel"`). */
|
|
46
|
+
readonly name: string;
|
|
47
|
+
/** Whether the node is explicitly named or inferred as anonymous. */
|
|
48
|
+
readonly type: "named" | "anonymous";
|
|
49
|
+
/** Child nodes nested under this element. */
|
|
50
|
+
readonly children: readonly AnatomyNode[];
|
|
51
|
+
/** Named slot this node exposes, if any. */
|
|
52
|
+
readonly slot?: string;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Wrapper around the root of a block's anatomy tree. */
|
|
56
|
+
export interface AnatomyTree {
|
|
57
|
+
/** Top-level anatomy node from which all children descend. */
|
|
58
|
+
readonly root: AnatomyNode;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Detailed view of a block, extending the digest with anatomy, tokens, and standards. */
|
|
62
|
+
export interface BlockDetailed extends BlockDigest {
|
|
63
|
+
/** Guidance on when the block should be used. */
|
|
64
|
+
readonly whenToUse: string | null;
|
|
65
|
+
/** Guidance on when the block should not be used. */
|
|
66
|
+
readonly whenNotToUse: string | null;
|
|
67
|
+
/** Additional usage guidance. */
|
|
68
|
+
readonly guidelines: string | null;
|
|
69
|
+
/** YAML anatomy DSL payload when present. */
|
|
70
|
+
readonly anatomyDsl: string | null;
|
|
71
|
+
/** Legacy anatomy payload when present. */
|
|
72
|
+
readonly anatomyClassic: string | null;
|
|
73
|
+
/** Figma reference link when present. */
|
|
74
|
+
readonly figmaLink: string | null;
|
|
75
|
+
/** Full anatomy tree, or `null` if the block declares no anatomy. */
|
|
76
|
+
readonly anatomy: AnatomyTree | null;
|
|
77
|
+
/** Modifier families with their allowed values. */
|
|
78
|
+
readonly modifierValues: readonly {
|
|
79
|
+
family: string;
|
|
80
|
+
values: readonly string[];
|
|
81
|
+
}[];
|
|
82
|
+
/** Modifier families resolved as richer objects. */
|
|
83
|
+
readonly modifierFamilies: readonly {
|
|
84
|
+
uri: URI;
|
|
85
|
+
name: string;
|
|
86
|
+
values: readonly string[];
|
|
87
|
+
}[];
|
|
88
|
+
/** Property metadata resolved from blank nodes. */
|
|
89
|
+
readonly properties: readonly {
|
|
90
|
+
name: string;
|
|
91
|
+
propertyType: string;
|
|
92
|
+
optional: boolean;
|
|
93
|
+
defaultValue: string | null;
|
|
94
|
+
constraints: string | null;
|
|
95
|
+
}[];
|
|
96
|
+
/** Direct subcomponents of the block. */
|
|
97
|
+
readonly subcomponents: readonly {
|
|
98
|
+
uri: URI;
|
|
99
|
+
name: string;
|
|
100
|
+
}[];
|
|
101
|
+
/** File paths to framework-specific implementations. */
|
|
102
|
+
readonly implementationPaths: readonly { framework: string; path: string }[];
|
|
103
|
+
/** Design tokens referenced by this block. */
|
|
104
|
+
readonly tokens: readonly TokenRef[];
|
|
105
|
+
/** Standards (guidelines/rules) that apply to this block. */
|
|
106
|
+
readonly standards: readonly StandardRef[];
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// =============================================================================
|
|
110
|
+
// Standard
|
|
111
|
+
// =============================================================================
|
|
112
|
+
|
|
113
|
+
/** Summary view of a design-system standard (guideline or rule). */
|
|
114
|
+
export interface StandardSummary {
|
|
115
|
+
/** Full RDF URI identifying this standard in the ke store. */
|
|
116
|
+
readonly uri: URI;
|
|
117
|
+
/** Human-readable name of the standard. */
|
|
118
|
+
readonly name: string;
|
|
119
|
+
/** Category grouping (e.g., `"accessibility"`, `"layout"`). */
|
|
120
|
+
readonly category: string;
|
|
121
|
+
/** Brief prose description of what the standard prescribes. */
|
|
122
|
+
readonly description: string;
|
|
123
|
+
/** URI of the parent standard this one extends, if any. */
|
|
124
|
+
readonly extends?: string;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** Fenced code block used in standard do/don't examples. */
|
|
128
|
+
export interface CodeBlock {
|
|
129
|
+
/** Programming language identifier for syntax highlighting. */
|
|
130
|
+
readonly language: string;
|
|
131
|
+
/** Source code content of the example. */
|
|
132
|
+
readonly code: string;
|
|
133
|
+
/** Optional explanatory caption displayed alongside the code. */
|
|
134
|
+
readonly caption?: string;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** Detailed view of a standard, extending the summary with code examples. */
|
|
138
|
+
export interface StandardDetailed extends StandardSummary {
|
|
139
|
+
/** Positive examples demonstrating correct usage. */
|
|
140
|
+
readonly dos: readonly CodeBlock[];
|
|
141
|
+
/** Negative examples demonstrating incorrect usage. */
|
|
142
|
+
readonly donts: readonly CodeBlock[];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** Summary of a standards category with its member count. */
|
|
146
|
+
export interface CategorySummary {
|
|
147
|
+
/** Category name (e.g., `"accessibility"`, `"layout"`). */
|
|
148
|
+
readonly name: string;
|
|
149
|
+
/** Number of standards belonging to this category. */
|
|
150
|
+
readonly standardCount: number;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/** Optional filters for narrowing the standards list. */
|
|
154
|
+
export interface StandardListFilters {
|
|
155
|
+
/** Restrict results to a single category name. */
|
|
156
|
+
readonly category?: string;
|
|
157
|
+
/** Free-text search term matched against standard names and descriptions. */
|
|
158
|
+
readonly search?: string;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// =============================================================================
|
|
162
|
+
// Modifier
|
|
163
|
+
// =============================================================================
|
|
164
|
+
|
|
165
|
+
/** A modifier family (e.g., "size", "variant") with its allowed values. */
|
|
166
|
+
export interface ModifierFamily {
|
|
167
|
+
/** Full RDF URI identifying this modifier family. */
|
|
168
|
+
readonly uri: URI;
|
|
169
|
+
/** Human-readable family name. */
|
|
170
|
+
readonly name: string;
|
|
171
|
+
/** Allowed values within this family (e.g., `["small", "medium", "large"]`). */
|
|
172
|
+
readonly values: readonly string[];
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// =============================================================================
|
|
176
|
+
// Token
|
|
177
|
+
// =============================================================================
|
|
178
|
+
|
|
179
|
+
/** Summary view of a design token. */
|
|
180
|
+
export interface TokenSummary {
|
|
181
|
+
/** Full RDF URI identifying this token in the ke store. */
|
|
182
|
+
readonly uri: URI;
|
|
183
|
+
/** Human-readable token name (e.g., `"color-primary"`). */
|
|
184
|
+
readonly name: string;
|
|
185
|
+
/** Token category (e.g., `"color"`, `"spacing"`, `"typography"`). */
|
|
186
|
+
readonly category: string;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/** Detailed view of a token, extending the summary with per-theme resolved values. */
|
|
190
|
+
export interface TokenDetailed extends TokenSummary {
|
|
191
|
+
/** Resolved values keyed by theme (e.g., `{ theme: "dark", value: "#fff" }`). */
|
|
192
|
+
readonly values: readonly { theme: string; value: string }[];
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/** Lightweight reference to a token (name + URI), used in cross-references. */
|
|
196
|
+
export interface TokenRef {
|
|
197
|
+
/** Human-readable token name. */
|
|
198
|
+
readonly name: string;
|
|
199
|
+
/** Full RDF URI of the referenced token. */
|
|
200
|
+
readonly uri: URI;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// =============================================================================
|
|
204
|
+
// Standard cross-reference
|
|
205
|
+
// =============================================================================
|
|
206
|
+
|
|
207
|
+
/** Lightweight reference to a standard, used in block cross-references. */
|
|
208
|
+
export interface StandardRef {
|
|
209
|
+
/** Human-readable standard name. */
|
|
210
|
+
readonly name: string;
|
|
211
|
+
/** Full RDF URI of the referenced standard. */
|
|
212
|
+
readonly uri: URI;
|
|
213
|
+
/** Category the referenced standard belongs to. */
|
|
214
|
+
readonly category: string;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// =============================================================================
|
|
218
|
+
// Tier
|
|
219
|
+
// =============================================================================
|
|
220
|
+
|
|
221
|
+
/** A single entry in the tier hierarchy (e.g., `global`, `apps`, `apps/lxd`). */
|
|
222
|
+
export interface TierEntry {
|
|
223
|
+
/** Full RDF URI identifying this tier in the ke store. */
|
|
224
|
+
readonly uri: URI;
|
|
225
|
+
/** Slash-separated tier path (e.g., `"apps/lxd"`). */
|
|
226
|
+
readonly path: string;
|
|
227
|
+
/** Path of the parent tier, if this is not the root. */
|
|
228
|
+
readonly parent?: string;
|
|
229
|
+
/** Nesting depth in the tier hierarchy (0 = root). */
|
|
230
|
+
readonly depth: number;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// =============================================================================
|
|
234
|
+
// Graph
|
|
235
|
+
// =============================================================================
|
|
236
|
+
|
|
237
|
+
/** A predicate group from `graph inspect`: one predicate with all its objects. */
|
|
238
|
+
export interface PredicateGroup {
|
|
239
|
+
/** RDF predicate URI (e.g., `"rdfs:label"`). */
|
|
240
|
+
readonly predicate: string;
|
|
241
|
+
/** Object values (URIs or literals) associated with this predicate. */
|
|
242
|
+
readonly objects: readonly string[];
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/** Result of `graph inspect <uri>`: all triples where URI is subject. */
|
|
246
|
+
export interface InspectResult {
|
|
247
|
+
/** The inspected subject URI. */
|
|
248
|
+
readonly uri: string;
|
|
249
|
+
/** Predicate groups aggregating all outgoing triples. */
|
|
250
|
+
readonly groups: readonly PredicateGroup[];
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// =============================================================================
|
|
254
|
+
// Ontology
|
|
255
|
+
// =============================================================================
|
|
256
|
+
|
|
257
|
+
/** Summary of a loaded ontology namespace from `ontology list`. */
|
|
258
|
+
export interface OntologySummary {
|
|
259
|
+
/** Short prefix alias (e.g., `"ds"`, `"cs"`). */
|
|
260
|
+
readonly prefix: string;
|
|
261
|
+
/** Full namespace URI the prefix expands to. */
|
|
262
|
+
readonly namespace: string;
|
|
263
|
+
/** Number of OWL/RDFS classes defined in this namespace. */
|
|
264
|
+
readonly classCount: number;
|
|
265
|
+
/** Number of properties (object + datatype) defined in this namespace. */
|
|
266
|
+
readonly propertyCount: number;
|
|
267
|
+
readonly anatomyCount: number;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/** A class in an ontology's class hierarchy. */
|
|
271
|
+
export interface OntologyClass {
|
|
272
|
+
/** Full URI of the class. */
|
|
273
|
+
readonly uri: string;
|
|
274
|
+
/** Human-readable label (rdfs:label). */
|
|
275
|
+
readonly label: string;
|
|
276
|
+
/** URI of the direct superclass, if declared. */
|
|
277
|
+
readonly superclass?: string;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/** A property in an ontology namespace. */
|
|
281
|
+
export interface OntologyProperty {
|
|
282
|
+
/** Full URI of the property. */
|
|
283
|
+
readonly uri: string;
|
|
284
|
+
/** Human-readable label (rdfs:label). */
|
|
285
|
+
readonly label: string;
|
|
286
|
+
/** URI of the domain class this property applies to, if declared. */
|
|
287
|
+
readonly domain?: string;
|
|
288
|
+
/** URI of the range class or datatype, if declared. */
|
|
289
|
+
readonly range?: string;
|
|
290
|
+
/** Whether this is an object property (links classes) or datatype property (links to literals). */
|
|
291
|
+
readonly type: "object" | "datatype";
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/** Detailed view of a single ontology namespace from `ontology show`. */
|
|
295
|
+
export interface OntologyDetailed {
|
|
296
|
+
/** Short prefix alias (e.g., `"ds"`). */
|
|
297
|
+
readonly prefix: string;
|
|
298
|
+
/** Full namespace URI the prefix expands to. */
|
|
299
|
+
readonly namespace: string;
|
|
300
|
+
/** All classes defined in this namespace. */
|
|
301
|
+
readonly classes: readonly OntologyClass[];
|
|
302
|
+
/** All properties defined in this namespace. */
|
|
303
|
+
readonly properties: readonly OntologyProperty[];
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// =============================================================================
|
|
307
|
+
// Filter configuration
|
|
308
|
+
// =============================================================================
|
|
309
|
+
|
|
310
|
+
/** Runtime filter settings controlling tier and channel visibility in queries. */
|
|
311
|
+
export interface FilterConfig {
|
|
312
|
+
/** Active tier path, or `undefined` for all-tiers visibility. */
|
|
313
|
+
readonly tier: string | undefined;
|
|
314
|
+
/** Release channel determining which stability levels are visible. */
|
|
315
|
+
readonly channel: "normal" | "experimental" | "prerelease";
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// =============================================================================
|
|
319
|
+
// Disclosure
|
|
320
|
+
// =============================================================================
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Controls how much detail an operation returns.
|
|
324
|
+
*
|
|
325
|
+
* - `"summary"` — minimal fields (names and counts).
|
|
326
|
+
* - `"digest"` — intermediate detail with optional example length cap.
|
|
327
|
+
* - `"detailed"` — full content including code blocks and anatomy.
|
|
328
|
+
*/
|
|
329
|
+
export type Disclosure =
|
|
330
|
+
| { readonly level: "summary" }
|
|
331
|
+
| { readonly level: "digest"; readonly maxExampleLength?: number }
|
|
332
|
+
| { readonly level: "detailed" };
|
|
333
|
+
|
|
334
|
+
// =============================================================================
|
|
335
|
+
// Batch
|
|
336
|
+
// =============================================================================
|
|
337
|
+
|
|
338
|
+
/** Outcome of a batch operation: successful results alongside per-item errors. */
|
|
339
|
+
export interface BatchResult<T> {
|
|
340
|
+
/** Items that were processed successfully. */
|
|
341
|
+
readonly results: readonly T[];
|
|
342
|
+
/** Items that failed, each carrying the entity name, error code, and message. */
|
|
343
|
+
readonly errors: readonly {
|
|
344
|
+
name: string;
|
|
345
|
+
code: string;
|
|
346
|
+
message: string;
|
|
347
|
+
}[];
|
|
348
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import type { CommandDefinition } from "@canonical/cli-core";
|
|
5
|
+
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
|
|
6
|
+
import type { PragmaContext } from "../../shared/context.js";
|
|
7
|
+
import type { SkillListInput } from "../formatters/types.js";
|
|
8
|
+
import buildListCommand from "./list.js";
|
|
9
|
+
|
|
10
|
+
const TMP_ROOT = join(tmpdir(), `pragma-skill-cmd-${Date.now()}`);
|
|
11
|
+
|
|
12
|
+
const TEST_SOURCES = [
|
|
13
|
+
{
|
|
14
|
+
dir: join(TMP_ROOT, "node_modules/@canonical/design-system/skills"),
|
|
15
|
+
packageName: "@canonical/design-system",
|
|
16
|
+
},
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
vi.mock("../helpers/resolveSkillSources.js", () => ({
|
|
20
|
+
default: () => TEST_SOURCES,
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
beforeAll(() => {
|
|
24
|
+
mkdirSync(TMP_ROOT, { recursive: true });
|
|
25
|
+
|
|
26
|
+
const dir = join(TEST_SOURCES[0].dir, "design-audit");
|
|
27
|
+
mkdirSync(dir, { recursive: true });
|
|
28
|
+
writeFileSync(
|
|
29
|
+
join(dir, "SKILL.md"),
|
|
30
|
+
`---
|
|
31
|
+
name: design-audit
|
|
32
|
+
description: Audit a component against DS specs
|
|
33
|
+
metadata:
|
|
34
|
+
author: canonical
|
|
35
|
+
---
|
|
36
|
+
`,
|
|
37
|
+
);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
afterAll(() => {
|
|
41
|
+
rmSync(TMP_ROOT, { recursive: true, force: true });
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
function makeCtx(overrides: Partial<PragmaContext> = {}): PragmaContext {
|
|
45
|
+
return {
|
|
46
|
+
cwd: TMP_ROOT,
|
|
47
|
+
globalFlags: { llm: false, format: "text" as const, verbose: false },
|
|
48
|
+
store: {} as PragmaContext["store"],
|
|
49
|
+
config: { tier: undefined, channel: "normal" },
|
|
50
|
+
...overrides,
|
|
51
|
+
} as PragmaContext;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function executeOutput(
|
|
55
|
+
cmd: CommandDefinition,
|
|
56
|
+
params: Record<string, unknown>,
|
|
57
|
+
ctx: PragmaContext,
|
|
58
|
+
): Promise<{ value: unknown; text: string }> {
|
|
59
|
+
const result = await cmd.execute(params, ctx);
|
|
60
|
+
expect(result.tag).toBe("output");
|
|
61
|
+
if (result.tag !== "output") throw new Error("Expected output result");
|
|
62
|
+
const text = result.render.plain(result.value);
|
|
63
|
+
return { value: result.value, text };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
describe("buildListCommand", () => {
|
|
67
|
+
it("returns output result with skill data", async () => {
|
|
68
|
+
const ctx = makeCtx();
|
|
69
|
+
const cmd = buildListCommand(ctx);
|
|
70
|
+
const { value } = await executeOutput(cmd, {}, ctx);
|
|
71
|
+
const input = value as SkillListInput;
|
|
72
|
+
expect(input.skills).toHaveLength(1);
|
|
73
|
+
expect(input.skills[0].name).toBe("design-audit");
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it("renders plain text output", async () => {
|
|
77
|
+
const ctx = makeCtx();
|
|
78
|
+
const cmd = buildListCommand(ctx);
|
|
79
|
+
const { text } = await executeOutput(cmd, {}, ctx);
|
|
80
|
+
expect(text).toContain("design-audit");
|
|
81
|
+
expect(text).toContain("@canonical/design-system");
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it("renders LLM markdown", async () => {
|
|
85
|
+
const ctx = makeCtx({
|
|
86
|
+
globalFlags: { llm: true, format: "text" as const, verbose: false },
|
|
87
|
+
});
|
|
88
|
+
const cmd = buildListCommand(ctx);
|
|
89
|
+
const { text } = await executeOutput(cmd, {}, ctx);
|
|
90
|
+
expect(text).toContain("## Skills");
|
|
91
|
+
expect(text).toContain("**design-audit**");
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("renders JSON output", async () => {
|
|
95
|
+
const ctx = makeCtx({
|
|
96
|
+
globalFlags: { llm: false, format: "json" as const, verbose: false },
|
|
97
|
+
});
|
|
98
|
+
const cmd = buildListCommand(ctx);
|
|
99
|
+
const { text } = await executeOutput(cmd, {}, ctx);
|
|
100
|
+
const parsed = JSON.parse(text);
|
|
101
|
+
expect(Array.isArray(parsed)).toBe(true);
|
|
102
|
+
expect(parsed[0].name).toBe("design-audit");
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it("passes detailed flag to formatter input", async () => {
|
|
106
|
+
const ctx = makeCtx();
|
|
107
|
+
const cmd = buildListCommand(ctx);
|
|
108
|
+
const { value } = await executeOutput(cmd, { detailed: true }, ctx);
|
|
109
|
+
expect((value as SkillListInput).detailed).toBe(true);
|
|
110
|
+
});
|
|
111
|
+
});
|