@canonical/pragma-cli 0.29.0 → 0.31.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 +128 -47
- package/dist/pragma +0 -0
- package/package.json +15 -13
- package/src/completions/constants.ts +7 -0
- package/src/completions/handleQuery.test.ts +32 -0
- package/src/completions/handleQuery.ts +20 -1
- package/src/completions/queryCompletions.test.ts +5 -0
- package/src/completions/queryCompletions.ts +17 -3
- package/src/completions/querySocket.test.ts +31 -0
- package/src/completions/querySocket.ts +36 -9
- package/src/config/defaultConfig.test.ts +33 -0
- package/src/config/defaultConfig.ts +59 -0
- package/src/config/defaults.json +17 -0
- package/src/config/findProjectConfigPath.test.ts +53 -0
- package/src/config/findProjectConfigPath.ts +36 -0
- package/src/config/index.ts +17 -2
- package/src/config/mergeConfigFileUpdate.ts +58 -0
- package/src/config/parseConfigValues.ts +217 -0
- package/src/config/readConfig.test.ts +104 -13
- package/src/config/readConfig.ts +12 -153
- package/src/config/readConfigLayers.test.ts +109 -0
- package/src/config/readConfigLayers.ts +118 -0
- package/src/config/resolveGlobalConfigPath.ts +13 -0
- package/src/config/resolveWriteConfigPath.test.ts +53 -0
- package/src/config/resolveWriteConfigPath.ts +31 -0
- package/src/config/types.ts +83 -1
- package/src/config/writeConfig.ts +25 -55
- package/src/constants.ts +3 -1
- package/src/domains/block/commands/list.ts +5 -90
- package/src/domains/block/commands/lookup.ts +8 -167
- package/src/domains/block/commands/sample.ts +2 -1
- package/src/domains/block/formatters/list.test.ts +3 -3
- package/src/domains/block/formatters/lookup.test.ts +5 -5
- package/src/domains/block/mcp/specs.ts +16 -196
- package/src/domains/block/orchestration/enrichBlocks.ts +6 -3
- package/src/domains/block/orchestration/resolveBlockLookup.ts +2 -1
- package/src/domains/block/stories.test.ts +28 -0
- package/src/domains/block/stories.ts +260 -0
- package/src/domains/config/commands/channel.test.ts +30 -3
- package/src/domains/config/commands/channel.ts +25 -8
- package/src/domains/config/commands/configScope.ts +46 -0
- package/src/domains/config/commands/framework.test.ts +32 -1
- package/src/domains/config/commands/framework.ts +26 -8
- package/src/domains/config/commands/show.ts +5 -45
- package/src/domains/config/commands/tier.test.ts +20 -2
- package/src/domains/config/commands/tier.ts +25 -8
- package/src/domains/config/commands/trace.test.ts +19 -2
- package/src/domains/config/commands/trace.ts +6 -3
- package/src/domains/config/formatters/channel.test.ts +20 -6
- package/src/domains/config/formatters/channel.ts +14 -11
- package/src/domains/config/formatters/framework.ts +14 -11
- package/src/domains/config/formatters/show.test.ts +27 -0
- package/src/domains/config/formatters/show.ts +27 -4
- package/src/domains/config/formatters/tier.test.ts +26 -10
- package/src/domains/config/formatters/tier.ts +19 -11
- package/src/domains/config/formatters/trace.ts +7 -7
- package/src/domains/config/mcp/specs.ts +33 -53
- package/src/domains/config/operations/show.test.ts +18 -0
- package/src/domains/config/operations/show.ts +7 -1
- package/src/domains/config/operations/types.ts +7 -0
- package/src/domains/config/operations/validateTier.test.ts +9 -0
- package/src/domains/config/operations/validateTier.ts +10 -2
- package/src/domains/config/stories.ts +42 -0
- package/src/domains/config/tasks/index.ts +1 -0
- package/src/domains/config/tasks/setChannel.ts +13 -28
- package/src/domains/config/tasks/setFramework.ts +11 -30
- package/src/domains/config/tasks/setTier.ts +10 -29
- package/src/domains/config/tasks/setTrace.ts +10 -28
- package/src/domains/config/tasks/writeConfigField.ts +41 -0
- package/src/domains/create/generatorPack/bundled.ts +49 -0
- package/src/domains/create/generatorPack/compileGeneratorPack.test.ts +159 -0
- package/src/domains/create/generatorPack/compileGeneratorPack.ts +312 -0
- package/src/domains/create/index.ts +13 -7
- package/src/domains/create/mcp/specs.ts +6 -161
- package/src/domains/create/renderGeneratorUi.test.ts +103 -0
- package/src/domains/create/renderGeneratorUi.ts +65 -0
- package/src/domains/doctor/formatters/doctor.test.ts +50 -2
- package/src/domains/doctor/formatters/doctor.ts +90 -38
- package/src/domains/doctor/operations/checks/checkConfigFile.ts +19 -5
- package/src/domains/doctor/operations/checks/checkMcpCommands.ts +133 -0
- package/src/domains/doctor/operations/checks/checkMcpConfigured.ts +1 -1
- package/src/domains/doctor/operations/checks/checkPackageRefs.ts +32 -26
- package/src/domains/doctor/operations/checks/checkSkillsSymlinked.ts +1 -1
- package/src/domains/doctor/operations/checks/index.ts +1 -0
- package/src/domains/doctor/operations/checks.test.ts +160 -7
- package/src/domains/doctor/operations/runChecks.test.ts +15 -6
- package/src/domains/doctor/operations/runChecks.ts +2 -0
- package/src/domains/doctor/operations/types.ts +23 -1
- package/src/domains/graph/commands/inspect.test.ts +2 -2
- package/src/domains/graph/commands/query.test.ts +5 -3
- package/src/domains/graph/formatters/inspect.ts +7 -7
- package/src/domains/graph/formatters/query.test.ts +87 -0
- package/src/domains/graph/formatters/query.ts +42 -5
- package/src/domains/graph/helpers/resolveUri.test.ts +50 -0
- package/src/domains/graph/helpers/resolveUri.ts +28 -21
- package/src/domains/graph/operations/inspectUri.test.ts +5 -5
- package/src/domains/graphql/commands/build.test.ts +5 -3
- package/src/domains/graphql/commands/build.ts +8 -16
- package/src/domains/graphql/commands/check.test.ts +5 -3
- package/src/domains/graphql/commands/check.ts +7 -13
- package/src/domains/graphql/commands/index.ts +1 -0
- package/src/domains/graphql/commands/serve.test.ts +46 -0
- package/src/domains/graphql/commands/serve.ts +141 -0
- package/src/domains/graphql/constants.ts +10 -0
- package/src/domains/graphql/helpers/gatherSources.test.ts +92 -0
- package/src/domains/graphql/helpers/gatherSources.ts +58 -0
- package/src/domains/graphql/helpers/index.ts +2 -0
- package/src/domains/graphql/helpers/parsePrefixes.test.ts +3 -3
- package/src/domains/graphql/helpers/parsePrefixes.ts +3 -3
- package/src/domains/graphql/helpers/resolveSourceFiles.test.ts +9 -0
- package/src/domains/graphql/helpers/resolveSourceFiles.ts +24 -3
- package/src/domains/graphql/helpers/routeGraphql.test.ts +43 -0
- package/src/domains/graphql/helpers/routeGraphql.ts +28 -0
- package/src/domains/graphql/index.ts +9 -6
- package/src/domains/graphql/operations/compileSchema.test.ts +23 -47
- package/src/domains/graphql/operations/compileSchema.ts +23 -25
- package/src/domains/graphql/operations/createSchemaServer.test.ts +50 -0
- package/src/domains/graphql/operations/createSchemaServer.ts +75 -0
- package/src/domains/graphql/operations/ensureSchemaArtifact.test.ts +167 -0
- package/src/domains/graphql/operations/ensureSchemaArtifact.ts +178 -0
- package/src/domains/graphql/operations/index.ts +10 -0
- package/src/domains/info/formatters/upgrade.test.ts +7 -4
- package/src/domains/info/formatters/upgrade.ts +3 -1
- package/src/domains/info/operations/collectEntityCounts.test.ts +156 -0
- package/src/domains/info/operations/collectEntityCounts.ts +123 -0
- package/src/domains/info/operations/collectInfo.test.ts +14 -3
- package/src/domains/info/operations/collectInfo.ts +12 -15
- package/src/domains/info/operations/index.ts +1 -0
- package/src/domains/info/types.ts +13 -0
- package/src/domains/llm/capabilities.test.ts +24 -4
- package/src/domains/llm/commands/capabilities.ts +12 -3
- package/src/domains/llm/commands/llm.ts +5 -1
- package/src/domains/llm/data/commandReference.ts +20 -11
- package/src/domains/llm/data/decisionTrees.ts +10 -5
- package/src/domains/llm/data/toolCatalog.ts +55 -18
- package/src/domains/llm/formatters/orientation.ts +5 -1
- package/src/domains/llm/llmCommand.test.ts +11 -3
- package/src/domains/llm/mcp/specs.ts +3 -4
- package/src/domains/llm/operations/collectContext.test.ts +64 -0
- package/src/domains/llm/operations/collectContext.ts +7 -17
- package/src/domains/modifier/commands/list.ts +5 -38
- package/src/domains/modifier/commands/lookup.ts +8 -79
- package/src/domains/modifier/commands/sample.ts +2 -1
- package/src/domains/modifier/mcp/specs.ts +15 -94
- package/src/domains/modifier/operations/lookup.ts +5 -3
- package/src/domains/modifier/orchestration/resolveModifierLookup.ts +2 -1
- package/src/domains/modifier/stories.test.ts +20 -0
- package/src/domains/modifier/stories.ts +86 -0
- package/src/domains/ontology/commands/list.test.ts +5 -3
- package/src/domains/ontology/commands/list.ts +5 -58
- package/src/domains/ontology/commands/show.test.ts +85 -9
- package/src/domains/ontology/commands/show.ts +6 -58
- package/src/domains/ontology/formatters/index.ts +1 -0
- package/src/domains/ontology/formatters/list.ts +37 -12
- package/src/domains/ontology/formatters/show.ts +361 -64
- package/src/domains/ontology/helpers/buildClassTree.ts +89 -0
- package/src/domains/ontology/helpers/completeClassNames.ts +43 -0
- package/src/domains/ontology/helpers/expandOntologyIris.ts +79 -0
- package/src/domains/ontology/helpers/index.ts +14 -0
- package/src/domains/ontology/helpers/queryClasses.ts +32 -16
- package/src/domains/ontology/helpers/queryProperties.ts +39 -6
- package/src/domains/ontology/helpers/queryTboxFacts.ts +160 -0
- package/src/domains/ontology/mcp/specs.ts +7 -84
- package/src/domains/ontology/operations/listOntologies.test.ts +80 -3
- package/src/domains/ontology/operations/listOntologies.ts +126 -30
- package/src/domains/ontology/operations/showOntology.test.ts +131 -12
- package/src/domains/ontology/operations/showOntology.ts +289 -7
- package/src/domains/ontology/operations/showOntologyRaw.test.ts +4 -2
- package/src/domains/ontology/stories.test.ts +36 -0
- package/src/domains/ontology/stories.ts +153 -0
- package/src/domains/refs/operations/updateRefs.ts +2 -38
- package/src/domains/setup/commands/index.ts +1 -0
- package/src/domains/setup/commands/setup.ts +70 -0
- package/src/domains/setup/commands/skills.test.ts +6 -2
- package/src/domains/setup/commands/skills.ts +6 -2
- package/src/domains/setup/helpers/runSetupTask.test.ts +148 -150
- package/src/domains/setup/helpers/runSetupTask.ts +62 -70
- package/src/domains/setup/index.ts +7 -3
- package/src/domains/setup/operations/setupLsp.test.ts +3 -2
- package/src/domains/setup/operations/setupLsp.ts +7 -2
- package/src/domains/setup/operations/setupMcp.test.ts +6 -1
- package/src/domains/shared/bootStore.bareCore.test.ts +63 -0
- package/src/domains/shared/bootStore.test.ts +82 -0
- package/src/domains/shared/bootStore.ts +57 -18
- package/src/domains/shared/compactUri.test.ts +11 -0
- package/src/domains/shared/compactUri.ts +10 -5
- package/src/domains/shared/context.ts +2 -2
- package/src/domains/shared/contracts.ts +11 -0
- package/src/domains/shared/createInteractivePromptSession.test.ts +439 -0
- package/src/domains/shared/createInteractivePromptSession.ts +236 -0
- package/src/domains/shared/emptyErrorRecovery.test.ts +23 -26
- package/src/domains/shared/extractLocalName.test.ts +3 -3
- package/src/domains/shared/formatters.ts +23 -2
- package/src/domains/shared/listTiers.ts +40 -0
- package/src/domains/shared/loaders/bundledLoader.test.ts +248 -0
- package/src/domains/shared/loaders/bundledLoader.ts +158 -12
- package/src/domains/shared/loaders/gitLoader.ts +1 -2
- package/src/domains/shared/loaders/index.ts +4 -1
- package/src/domains/shared/loaders/localLoader.ts +2 -4
- package/src/domains/shared/loaders/readPackageDir.test.ts +58 -0
- package/src/domains/shared/loaders/readPackageDir.ts +82 -9
- package/src/domains/shared/loaders/storyAssetsPlugin.test.ts +84 -0
- package/src/domains/shared/loaders/storyAssetsPlugin.ts +46 -0
- package/src/domains/shared/lookupMany.test.ts +135 -0
- package/src/domains/shared/lookupMany.ts +50 -2
- package/src/domains/shared/mergeAndParseRefs.test.ts +89 -0
- package/src/domains/shared/mergeAndParseRefs.ts +44 -0
- package/src/domains/shared/namespaces.ts +13 -5
- package/src/domains/shared/packages.ts +10 -17
- package/src/domains/shared/parseSampleCount.test.ts +47 -0
- package/src/domains/shared/parseSampleCount.ts +45 -0
- package/src/domains/shared/prefixes.test.ts +211 -0
- package/src/domains/shared/prefixes.ts +182 -15
- package/src/domains/shared/renderers.ts +5 -5
- package/src/domains/shared/resolveConfiguredGraphs.test.ts +27 -0
- package/src/domains/shared/resolveConfiguredGraphs.ts +41 -0
- package/src/domains/shared/resolveLookupExitCode.test.ts +48 -0
- package/src/domains/shared/resolveLookupExitCode.ts +42 -0
- package/src/domains/shared/runtime.ts +4 -63
- package/src/domains/shared/semanticPackage.test.ts +89 -0
- package/src/domains/shared/semanticPackage.ts +34 -3
- package/src/domains/shared/stories/compileLookupCommand.test.ts +145 -0
- package/src/domains/shared/stories/compileLookupCommand.ts +102 -0
- package/src/domains/shared/stories/compileLookupTool.test.ts +105 -0
- package/src/domains/shared/stories/compileLookupTool.ts +96 -0
- package/src/domains/shared/stories/compileReadCommand.test.ts +121 -0
- package/src/domains/shared/stories/compileReadCommand.ts +48 -0
- package/src/domains/shared/stories/compileReadTool.test.ts +64 -0
- package/src/domains/shared/stories/compileReadTool.ts +38 -0
- package/src/domains/shared/stories/condense.test.ts +18 -0
- package/src/domains/shared/stories/condense.ts +15 -0
- package/src/domains/shared/stories/index.ts +20 -0
- package/src/domains/shared/stories/normalizeNames.test.ts +20 -0
- package/src/domains/shared/stories/normalizeNames.ts +22 -0
- package/src/domains/shared/stories/pack/applyPackFilters.test.ts +151 -0
- package/src/domains/shared/stories/pack/applyPackFilters.ts +111 -0
- package/src/domains/shared/stories/pack/applyPackSearch.test.ts +57 -0
- package/src/domains/shared/stories/pack/applyPackSearch.ts +41 -0
- package/src/domains/shared/stories/pack/buildLookupQuery.test.ts +81 -0
- package/src/domains/shared/stories/pack/buildLookupQuery.ts +154 -0
- package/src/domains/shared/stories/pack/bundled/index.ts +23 -0
- package/src/domains/shared/stories/pack/bundled/standardPack.ts +164 -0
- package/src/domains/shared/stories/pack/bundled/tierPack.ts +50 -0
- package/src/domains/shared/stories/pack/collectPackStories.test.ts +406 -0
- package/src/domains/shared/stories/pack/collectPackStories.ts +158 -0
- package/src/domains/shared/stories/pack/compilePackCommands.ts +50 -0
- package/src/domains/shared/stories/pack/compilePackStories.test.ts +751 -0
- package/src/domains/shared/stories/pack/compilePackStories.ts +724 -0
- package/src/domains/shared/stories/pack/compilePackToolSpecs.ts +55 -0
- package/src/domains/shared/stories/pack/index.ts +42 -0
- package/src/domains/shared/stories/pack/reservedVerbs.test.ts +213 -0
- package/src/domains/shared/stories/pack/reservedVerbs.ts +170 -0
- package/src/domains/shared/stories/pack/runSelectQuery.ts +31 -0
- package/src/domains/shared/stories/pack/standardParity.test.ts +381 -0
- package/src/domains/shared/stories/pack/types.ts +224 -0
- package/src/domains/shared/stories/pack/validateStoryPackDefinition.test.ts +742 -0
- package/src/domains/shared/stories/pack/validateStoryPackDefinition.ts +859 -0
- package/src/domains/shared/stories/projectCliParameters.test.ts +59 -0
- package/src/domains/shared/stories/projectCliParameters.ts +57 -0
- package/src/domains/shared/stories/projectToolParams.test.ts +50 -0
- package/src/domains/shared/stories/projectToolParams.ts +32 -0
- package/src/domains/shared/stories/requirePragmaContext.test.ts +23 -0
- package/src/domains/shared/stories/requirePragmaContext.ts +23 -0
- package/src/domains/shared/stories/resolveLookupDetailed.test.ts +57 -0
- package/src/domains/shared/stories/resolveLookupDetailed.ts +27 -0
- package/src/domains/shared/stories/types.ts +179 -0
- package/src/domains/shared/suggestions/expandGlob.ts +1 -0
- package/src/domains/shared/suggestions/suggestNames.ts +43 -10
- package/src/domains/shared/types/index.ts +5 -9
- package/src/domains/shared/types/ontology.ts +119 -24
- package/src/domains/shared/types/standard.ts +9 -52
- package/src/domains/skill/commands/index.ts +3 -1
- package/src/domains/skill/commands/list.test.ts +6 -2
- package/src/domains/skill/commands/list.ts +5 -63
- package/src/domains/skill/commands/lookup.test.ts +118 -0
- package/src/domains/skill/commands/lookup.ts +14 -0
- package/src/domains/skill/formatters/index.ts +1 -0
- package/src/domains/skill/formatters/lookup.test.ts +46 -0
- package/src/domains/skill/formatters/lookup.ts +57 -0
- package/src/domains/skill/helpers/resolveSkillSources.ts +0 -1
- package/src/domains/skill/index.ts +7 -3
- package/src/domains/skill/mcp/specs.ts +10 -29
- package/src/domains/skill/operations/discover.test.ts +61 -30
- package/src/domains/skill/operations/discover.ts +28 -37
- package/src/domains/skill/operations/index.ts +2 -1
- package/src/domains/skill/operations/list.test.ts +15 -7
- package/src/domains/skill/operations/lookup.test.ts +91 -0
- package/src/domains/skill/operations/lookup.ts +70 -0
- package/src/domains/skill/stories.test.ts +43 -0
- package/src/domains/skill/stories.ts +103 -0
- package/src/domains/skill/types.ts +8 -0
- package/src/domains/token/commands/lookup.test.ts +8 -0
- package/src/domains/token/commands/lookup.ts +12 -0
- package/src/domains/token/commands/sample.ts +2 -1
- package/src/domains/token/featureFlag.ts +17 -0
- package/src/domains/token/index.ts +5 -0
- package/src/domains/token/mcp/specs.ts +18 -2
- package/src/domains/token/orchestration/resolveTokenLookup.ts +2 -1
- package/src/domains/trace/commands/resolveTraceLimit.test.ts +31 -0
- package/src/domains/trace/commands/show.ts +30 -4
- package/src/domains/trace/tracePlugin.test.ts +1 -1
- package/src/index.ts +1 -13
- package/src/mcp/registerResources.test.ts +382 -74
- package/src/mcp/registerResources.ts +5 -348
- package/src/mcp/resources/buildGraphIndex.ts +167 -0
- package/src/mcp/resources/buildResourceList.test.ts +97 -0
- package/src/mcp/resources/buildResourceList.ts +176 -0
- package/src/mcp/resources/classifyEntity.test.ts +40 -0
- package/src/mcp/resources/classifyEntity.ts +27 -0
- package/src/mcp/resources/constants.ts +105 -0
- package/src/mcp/resources/displayPredicates.ts +62 -0
- package/src/mcp/resources/pickFirstValue.test.ts +29 -0
- package/src/mcp/resources/pickFirstValue.ts +26 -0
- package/src/mcp/resources/pickPrimaryType.test.ts +41 -0
- package/src/mcp/resources/pickPrimaryType.ts +26 -0
- package/src/mcp/resources/rankUriCompletions.test.ts +52 -0
- package/src/mcp/resources/rankUriCompletions.ts +64 -0
- package/src/mcp/resources/readEntity.ts +169 -0
- package/src/mcp/resources/registerResources.ts +126 -0
- package/src/mcp/resources/types.ts +128 -0
- package/src/mcp/tools/index.ts +22 -5
- package/src/mcp/tools/registerTools.test.ts +167 -34
- package/src/mcp/types.ts +4 -0
- package/src/pipeline/collectCommands.test.ts +151 -1
- package/src/pipeline/collectCommands.ts +35 -13
- package/src/pipeline/createProgram.test.ts +5 -1
- package/src/pipeline/createProgram.ts +2 -2
- package/src/pipeline/firstRun.test.ts +80 -0
- package/src/pipeline/firstRun.ts +99 -0
- package/src/pipeline/parseGlobalFlags.test.ts +102 -1
- package/src/pipeline/parseGlobalFlags.ts +98 -9
- package/src/pipeline/resolveCommandKind.test.ts +12 -0
- package/src/pipeline/resolveCommandKind.ts +4 -0
- package/src/pipeline/rootHelp.test.ts +87 -0
- package/src/pipeline/rootHelp.ts +265 -0
- package/src/pipeline/runCli.orchestration.test.ts +28 -12
- package/src/pipeline/runCli.test.ts +17 -4
- package/src/pipeline/runCli.ts +202 -25
- package/src/testing/cli.ts +30 -2
- package/src/testing/createTestMcpClient.ts +4 -1
- package/src/testing/dsFixtures.ts +21 -4
- package/src/testing/index.ts +7 -0
- package/src/testing/integration/__snapshots__/executor-golden.test.ts.snap +1207 -0
- package/src/testing/integration/cli-user-stories.test.ts +63 -0
- package/src/testing/integration/cross-binary-byte-equality.test.ts +129 -0
- package/src/testing/integration/edge-cases.test.ts +62 -50
- package/src/testing/integration/executor-execution.test.ts +103 -0
- package/src/testing/integration/executor-golden.test.ts +145 -0
- package/src/testing/integration/mcp-surface.test.ts +40 -15
- package/src/testing/integration/parity.test.ts +136 -82
- package/src/testing/regression/0001-skill-discovery-granularity.test.ts +71 -0
- package/src/testing/setupXdgIsolation.ts +26 -0
- package/src/testing/standardParityFixtures.ts +35 -0
- package/src/testing/store.ts +4 -4
- package/src/testing/storyFixtures.ts +63 -0
- package/src/domains/create/commands/component.test.ts +0 -166
- package/src/domains/create/commands/component.ts +0 -123
- package/src/domains/create/commands/index.ts +0 -3
- package/src/domains/create/commands/package.test.ts +0 -35
- package/src/domains/create/commands/package.ts +0 -21
- package/src/domains/create/generators.ts +0 -8
- package/src/domains/standard/commands/categories.test.ts +0 -70
- package/src/domains/standard/commands/categories.ts +0 -48
- package/src/domains/standard/commands/index.ts +0 -6
- package/src/domains/standard/commands/list.test.ts +0 -105
- package/src/domains/standard/commands/list.ts +0 -90
- package/src/domains/standard/commands/lookup.test.ts +0 -135
- package/src/domains/standard/commands/lookup.ts +0 -99
- package/src/domains/standard/commands/sample.ts +0 -57
- package/src/domains/standard/formatters/categories.test.ts +0 -44
- package/src/domains/standard/formatters/categories.ts +0 -38
- package/src/domains/standard/formatters/index.ts +0 -10
- package/src/domains/standard/formatters/list.test.ts +0 -169
- package/src/domains/standard/formatters/list.ts +0 -184
- package/src/domains/standard/formatters/lookup.test.ts +0 -95
- package/src/domains/standard/formatters/lookup.ts +0 -101
- package/src/domains/standard/formatters/sample.ts +0 -15
- package/src/domains/standard/formatters/types.ts +0 -31
- package/src/domains/standard/index.ts +0 -40
- package/src/domains/standard/mcp/index.ts +0 -2
- package/src/domains/standard/mcp/specs.ts +0 -244
- package/src/domains/standard/operations/categories.test.ts +0 -61
- package/src/domains/standard/operations/categories.ts +0 -38
- package/src/domains/standard/operations/index.ts +0 -6
- package/src/domains/standard/operations/list.test.ts +0 -75
- package/src/domains/standard/operations/list.ts +0 -64
- package/src/domains/standard/operations/lookup.test.ts +0 -58
- package/src/domains/standard/operations/lookup.ts +0 -151
- package/src/domains/standard/operations/sample.ts +0 -35
- package/src/domains/standard/orchestration/buildStandardFilters.ts +0 -11
- package/src/domains/standard/orchestration/index.ts +0 -4
- package/src/domains/standard/orchestration/resolveStandardList.ts +0 -45
- package/src/domains/standard/orchestration/resolveStandardLookup.ts +0 -32
- package/src/domains/standard/orchestration/standardEmptyError.test.ts +0 -33
- package/src/domains/standard/orchestration/standardEmptyError.ts +0 -29
- package/src/domains/standard/standardConfig.ts +0 -42
- package/src/domains/standard/types.ts +0 -15
- package/src/domains/tier/commands/index.ts +0 -3
- package/src/domains/tier/commands/list.test.ts +0 -67
- package/src/domains/tier/commands/list.ts +0 -59
- package/src/domains/tier/formatters/index.ts +0 -3
- package/src/domains/tier/formatters/list.test.ts +0 -33
- package/src/domains/tier/formatters/list.ts +0 -45
- package/src/domains/tier/index.ts +0 -17
- package/src/domains/tier/mcp/index.ts +0 -2
- package/src/domains/tier/mcp/specs.ts +0 -38
- package/src/domains/tier/operations/index.ts +0 -3
- package/src/domains/tier/operations/list.test.ts +0 -32
- package/src/domains/tier/operations/list.ts +0 -33
- package/src/pipeline/runInteractiveCommand.ts +0 -198
|
@@ -1,12 +1,44 @@
|
|
|
1
1
|
import type { Store } from "@canonical/ke";
|
|
2
2
|
import { PragmaError } from "#error";
|
|
3
|
-
import
|
|
3
|
+
import compactUri from "../../shared/compactUri.js";
|
|
4
|
+
import { PREFIX_MAP } from "../../shared/prefixes.js";
|
|
5
|
+
import type {
|
|
6
|
+
OntologyClass,
|
|
7
|
+
OntologyClassFocus,
|
|
8
|
+
OntologyConstraint,
|
|
9
|
+
OntologyDetailed,
|
|
10
|
+
OntologyMeta,
|
|
11
|
+
OntologyProperty,
|
|
12
|
+
OntologyQueryHint,
|
|
13
|
+
} from "../../shared/types/index.js";
|
|
14
|
+
import buildClassTree, { flattenClassTree } from "../helpers/buildClassTree.js";
|
|
4
15
|
import queryClasses from "../helpers/queryClasses.js";
|
|
16
|
+
import type { RawOntologyProperty } from "../helpers/queryProperties.js";
|
|
5
17
|
import queryProperties from "../helpers/queryProperties.js";
|
|
18
|
+
import {
|
|
19
|
+
queryConstraints,
|
|
20
|
+
queryInstanceCounts,
|
|
21
|
+
queryOntologyMeta,
|
|
22
|
+
querySampleInstances,
|
|
23
|
+
} from "../helpers/queryTboxFacts.js";
|
|
6
24
|
import resolvePrefix from "../helpers/resolvePrefix.js";
|
|
7
25
|
|
|
26
|
+
/** Options for {@link showOntology}. */
|
|
27
|
+
export interface ShowOntologyOptions {
|
|
28
|
+
/** Class to deep-dive into (label, local name, or compact IRI). */
|
|
29
|
+
readonly class?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
8
32
|
/**
|
|
9
|
-
* Returns
|
|
33
|
+
* Returns the complete TBox structure for a namespace: the class hierarchy
|
|
34
|
+
* (topologically ordered, direct properties attached, instance counts),
|
|
35
|
+
* unattached properties, SHACL constraint summaries, the owl:Ontology
|
|
36
|
+
* header, and — when `options.class` is given — a per-class deep dive.
|
|
37
|
+
*
|
|
38
|
+
* This is the **single** structure every output mode projects; plain,
|
|
39
|
+
* `--llm`, `--format json`, and the MCP envelope must render from it and
|
|
40
|
+
* nothing else. All IRIs are compacted against the store's prefix map,
|
|
41
|
+
* which is included in the result for lossless expansion.
|
|
10
42
|
*
|
|
11
43
|
* Accepts a short prefix (e.g. `ds`) or a full namespace URI.
|
|
12
44
|
*
|
|
@@ -14,20 +46,29 @@ import resolvePrefix from "../helpers/resolvePrefix.js";
|
|
|
14
46
|
*
|
|
15
47
|
* @param store - The ke store to query.
|
|
16
48
|
* @param prefixOrUri - A short prefix or full namespace URI.
|
|
49
|
+
* @param options - Optional class focus.
|
|
17
50
|
* @returns An {@link OntologyDetailed} with classes and properties.
|
|
18
51
|
* @throws PragmaError.invalidInput if the prefix or namespace is unknown.
|
|
19
|
-
* @throws PragmaError.notFound if the namespace has no classes or
|
|
52
|
+
* @throws PragmaError.notFound if the namespace has no classes or
|
|
53
|
+
* properties, or the focused class does not exist.
|
|
20
54
|
*/
|
|
21
55
|
export default async function showOntology(
|
|
22
56
|
store: Store,
|
|
23
57
|
prefixOrUri: string,
|
|
58
|
+
options: ShowOntologyOptions = {},
|
|
24
59
|
): Promise<OntologyDetailed> {
|
|
25
60
|
const { prefix, namespace } = resolvePrefix(prefixOrUri, store.prefixes);
|
|
26
61
|
|
|
27
|
-
const
|
|
28
|
-
|
|
62
|
+
const [rawClasses, rawProperties, instanceCounts, rawConstraints, rawMeta] =
|
|
63
|
+
await Promise.all([
|
|
64
|
+
queryClasses(store, namespace),
|
|
65
|
+
queryProperties(store, namespace),
|
|
66
|
+
queryInstanceCounts(store, namespace),
|
|
67
|
+
queryConstraints(store, namespace),
|
|
68
|
+
queryOntologyMeta(store, namespace),
|
|
69
|
+
]);
|
|
29
70
|
|
|
30
|
-
if (
|
|
71
|
+
if (rawClasses.length === 0 && rawProperties.length === 0) {
|
|
31
72
|
throw PragmaError.notFound("ontology", prefixOrUri, {
|
|
32
73
|
recovery: {
|
|
33
74
|
message: "List loaded ontologies.",
|
|
@@ -37,5 +78,246 @@ export default async function showOntology(
|
|
|
37
78
|
});
|
|
38
79
|
}
|
|
39
80
|
|
|
40
|
-
|
|
81
|
+
// Core RDF vocabularies (xsd etc.) plus the store's resolved package
|
|
82
|
+
// prefixes; the store map wins on collisions.
|
|
83
|
+
const compactionMap: Readonly<Record<string, string>> = {
|
|
84
|
+
...PREFIX_MAP,
|
|
85
|
+
...store.prefixes,
|
|
86
|
+
};
|
|
87
|
+
const usedPrefixes = new Set<string>([prefix]);
|
|
88
|
+
const compact = (uri: string): string => {
|
|
89
|
+
const compacted = compactUri(uri, compactionMap);
|
|
90
|
+
const colon = compacted.indexOf(":");
|
|
91
|
+
if (compacted !== uri && colon > 0) {
|
|
92
|
+
usedPrefixes.add(compacted.slice(0, colon));
|
|
93
|
+
}
|
|
94
|
+
return compacted;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const toProperty = (raw: RawOntologyProperty): OntologyProperty => ({
|
|
98
|
+
iri: compact(raw.uri),
|
|
99
|
+
label: raw.label,
|
|
100
|
+
kind: raw.kind,
|
|
101
|
+
...(raw.domain ? { domain: compact(raw.domain) } : {}),
|
|
102
|
+
...(raw.range ? { range: compact(raw.range) } : {}),
|
|
103
|
+
...(raw.functional ? { functional: true as const } : {}),
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Attach properties to their domain class; the rest are unattached.
|
|
107
|
+
const classUris = new Set(rawClasses.map((c) => c.uri));
|
|
108
|
+
const byDomain = new Map<string, OntologyProperty[]>();
|
|
109
|
+
const unattached: OntologyProperty[] = [];
|
|
110
|
+
for (const raw of rawProperties) {
|
|
111
|
+
if (raw.domain !== undefined && classUris.has(raw.domain)) {
|
|
112
|
+
const attached = byDomain.get(raw.domain) ?? [];
|
|
113
|
+
attached.push(toProperty(raw));
|
|
114
|
+
byDomain.set(raw.domain, attached);
|
|
115
|
+
} else {
|
|
116
|
+
unattached.push(toProperty(raw));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const unordered: OntologyClass[] = rawClasses.map((raw) => {
|
|
121
|
+
const instances = instanceCounts.get(raw.uri) ?? 0;
|
|
122
|
+
return {
|
|
123
|
+
iri: compact(raw.uri),
|
|
124
|
+
label: raw.label,
|
|
125
|
+
...(raw.comment ? { comment: raw.comment } : {}),
|
|
126
|
+
subClassOf: raw.subClassOf.map(compact),
|
|
127
|
+
...(instances > 0 ? { instances } : {}),
|
|
128
|
+
properties: (byDomain.get(raw.uri) ?? []).sort((a, b) =>
|
|
129
|
+
a.label.localeCompare(b.label),
|
|
130
|
+
),
|
|
131
|
+
};
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// Canonical ordering: pre-order walk of the tree every renderer shares.
|
|
135
|
+
const classes = flattenClassTree(buildClassTree(unordered));
|
|
136
|
+
|
|
137
|
+
const constraints: OntologyConstraint[] = rawConstraints.map((raw) => ({
|
|
138
|
+
shape: compact(raw.shape),
|
|
139
|
+
...(raw.targetClass ? { targetClass: compact(raw.targetClass) } : {}),
|
|
140
|
+
propertyCount: raw.propertyCount,
|
|
141
|
+
}));
|
|
142
|
+
|
|
143
|
+
const meta: OntologyMeta | undefined = rawMeta
|
|
144
|
+
? {
|
|
145
|
+
...(rawMeta.title ? { title: rawMeta.title } : {}),
|
|
146
|
+
...(rawMeta.version ? { version: rawMeta.version } : {}),
|
|
147
|
+
...(rawMeta.imports.length > 0
|
|
148
|
+
? { imports: rawMeta.imports.map(compact) }
|
|
149
|
+
: {}),
|
|
150
|
+
}
|
|
151
|
+
: undefined;
|
|
152
|
+
|
|
153
|
+
const focus = options.class
|
|
154
|
+
? await buildFocus(store, options.class, {
|
|
155
|
+
prefix,
|
|
156
|
+
namespace,
|
|
157
|
+
classes,
|
|
158
|
+
unattached,
|
|
159
|
+
constraints,
|
|
160
|
+
instanceCounts,
|
|
161
|
+
rawClassUris: rawClasses.map((c) => c.uri),
|
|
162
|
+
compactionMap,
|
|
163
|
+
})
|
|
164
|
+
: undefined;
|
|
165
|
+
|
|
166
|
+
const prefixes = Object.fromEntries(
|
|
167
|
+
[...usedPrefixes]
|
|
168
|
+
.sort()
|
|
169
|
+
.map((p) => [p, compactionMap[p]])
|
|
170
|
+
.filter(([, ns]) => ns !== undefined),
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
return {
|
|
174
|
+
prefix,
|
|
175
|
+
namespace,
|
|
176
|
+
prefixes,
|
|
177
|
+
...(meta ? { meta } : {}),
|
|
178
|
+
classes,
|
|
179
|
+
unattached: unattached.sort((a, b) => a.label.localeCompare(b.label)),
|
|
180
|
+
...(constraints.length > 0 ? { constraints } : {}),
|
|
181
|
+
...(focus ? { focus } : {}),
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
interface FocusContext {
|
|
186
|
+
readonly prefix: string;
|
|
187
|
+
readonly namespace: string;
|
|
188
|
+
readonly classes: readonly OntologyClass[];
|
|
189
|
+
readonly unattached: readonly OntologyProperty[];
|
|
190
|
+
readonly constraints: readonly OntologyConstraint[];
|
|
191
|
+
readonly instanceCounts: ReadonlyMap<string, number>;
|
|
192
|
+
readonly rawClassUris: readonly string[];
|
|
193
|
+
readonly compactionMap: Readonly<Record<string, string>>;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Assemble the per-class deep dive from the already-loaded structure plus
|
|
198
|
+
* one sample-instances query. Everything else (chain, subclasses, reverse
|
|
199
|
+
* references, inherited properties) derives from the namespace data.
|
|
200
|
+
*/
|
|
201
|
+
async function buildFocus(
|
|
202
|
+
store: Store,
|
|
203
|
+
classQuery: string,
|
|
204
|
+
ctx: FocusContext,
|
|
205
|
+
): Promise<OntologyClassFocus> {
|
|
206
|
+
const needle = classQuery.toLowerCase();
|
|
207
|
+
const target = ctx.classes.find(
|
|
208
|
+
(c) =>
|
|
209
|
+
c.iri.toLowerCase() === needle ||
|
|
210
|
+
c.label.toLowerCase() === needle ||
|
|
211
|
+
localName(c.iri).toLowerCase() === needle,
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
if (!target) {
|
|
215
|
+
throw PragmaError.notFound("class", classQuery, {
|
|
216
|
+
suggestions: ctx.classes
|
|
217
|
+
.map((c) => localName(c.iri))
|
|
218
|
+
.filter((name) => name.toLowerCase().includes(needle))
|
|
219
|
+
.slice(0, 5),
|
|
220
|
+
recovery: {
|
|
221
|
+
message: "Show the namespace's class hierarchy.",
|
|
222
|
+
cli: `pragma ontology show ${ctx.prefix}`,
|
|
223
|
+
mcp: { tool: "ontology_show", params: { prefix: ctx.prefix } },
|
|
224
|
+
},
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const byIri = new Map(ctx.classes.map((c) => [c.iri, c]));
|
|
229
|
+
|
|
230
|
+
// Superclass chain within the namespace, nearest first, cycle-safe.
|
|
231
|
+
const superChain: string[] = [];
|
|
232
|
+
let cursor = target.subClassOf.find((p) => byIri.has(p));
|
|
233
|
+
while (cursor !== undefined && !superChain.includes(cursor)) {
|
|
234
|
+
superChain.push(cursor);
|
|
235
|
+
cursor = byIri.get(cursor)?.subClassOf.find((p) => byIri.has(p));
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const inheritedProperties = superChain.flatMap(
|
|
239
|
+
(iri) => byIri.get(iri)?.properties ?? [],
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
const allProperties = [
|
|
243
|
+
...ctx.classes.flatMap((c) => c.properties),
|
|
244
|
+
...ctx.unattached,
|
|
245
|
+
];
|
|
246
|
+
|
|
247
|
+
// The focused class's full URI is recoverable from the raw list (same
|
|
248
|
+
// index space as ctx.classes before ordering is irrelevant — match by
|
|
249
|
+
// compacted form).
|
|
250
|
+
const fullUri =
|
|
251
|
+
ctx.rawClassUris.find(
|
|
252
|
+
(uri) => compactUri(uri, ctx.compactionMap) === target.iri,
|
|
253
|
+
) ?? target.iri;
|
|
254
|
+
|
|
255
|
+
const sampleInstances = (await querySampleInstances(store, fullUri)).map(
|
|
256
|
+
(uri) => compactUri(uri, ctx.compactionMap),
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
const referencedBy = allProperties
|
|
260
|
+
.filter((p) => p.range === target.iri && p.domain !== target.iri)
|
|
261
|
+
.sort((a, b) => a.label.localeCompare(b.label));
|
|
262
|
+
|
|
263
|
+
return {
|
|
264
|
+
iri: target.iri,
|
|
265
|
+
label: target.label,
|
|
266
|
+
...(target.comment ? { comment: target.comment } : {}),
|
|
267
|
+
superChain,
|
|
268
|
+
subclasses: ctx.classes
|
|
269
|
+
.filter((c) => c.subClassOf.includes(target.iri))
|
|
270
|
+
.map((c) => c.iri)
|
|
271
|
+
.sort(),
|
|
272
|
+
instances: ctx.instanceCounts.get(fullUri) ?? 0,
|
|
273
|
+
directProperties: target.properties,
|
|
274
|
+
inheritedProperties,
|
|
275
|
+
referencedBy,
|
|
276
|
+
sampleInstances,
|
|
277
|
+
queries: buildQueryHints(target, referencedBy, sampleInstances),
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Ready-to-run SPARQL for the natural follow-ups from a class deep dive.
|
|
283
|
+
* Compact IRIs are used throughout — `pragma graph query` resolves them
|
|
284
|
+
* against the store's prefix map, so each hint is directly pasteable.
|
|
285
|
+
*/
|
|
286
|
+
function buildQueryHints(
|
|
287
|
+
target: OntologyClass,
|
|
288
|
+
referencedBy: readonly OntologyProperty[],
|
|
289
|
+
sampleInstances: readonly string[],
|
|
290
|
+
): OntologyQueryHint[] {
|
|
291
|
+
const hints: OntologyQueryHint[] = [
|
|
292
|
+
{
|
|
293
|
+
label: `instances of ${target.iri}`,
|
|
294
|
+
sparql: `SELECT ?instance WHERE { ?instance a ${target.iri} } LIMIT 20`,
|
|
295
|
+
},
|
|
296
|
+
];
|
|
297
|
+
|
|
298
|
+
const relation =
|
|
299
|
+
target.properties.find((p) => p.kind === "object") ??
|
|
300
|
+
referencedBy.find((p) => p.kind === "object");
|
|
301
|
+
if (relation) {
|
|
302
|
+
hints.push({
|
|
303
|
+
label: `traverse ${relation.iri}`,
|
|
304
|
+
sparql: `SELECT ?from ?to WHERE { ?from ${relation.iri} ?to } LIMIT 10`,
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const sample = sampleInstances[0];
|
|
309
|
+
if (sample !== undefined) {
|
|
310
|
+
hints.push({
|
|
311
|
+
label: `everything about ${sample}`,
|
|
312
|
+
sparql: `SELECT ?predicate ?object WHERE { ${sample} ?predicate ?object }`,
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return hints;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
function localName(iri: string): string {
|
|
320
|
+
const colon = iri.lastIndexOf(":");
|
|
321
|
+
const slash = iri.lastIndexOf("/");
|
|
322
|
+
return iri.slice(Math.max(colon, slash) + 1);
|
|
41
323
|
}
|
|
@@ -2,7 +2,7 @@ import type { Store } from "@canonical/ke";
|
|
|
2
2
|
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
|
3
3
|
import { PragmaError } from "#error";
|
|
4
4
|
import { createTestStore, DS_ALL_TTL } from "#testing";
|
|
5
|
-
import {
|
|
5
|
+
import { DEFAULT_PREFIX_MAP } from "../../shared/prefixes.js";
|
|
6
6
|
import showOntologyRaw from "./showOntologyRaw.js";
|
|
7
7
|
|
|
8
8
|
let store: Store;
|
|
@@ -21,7 +21,9 @@ describe("showOntologyRaw", () => {
|
|
|
21
21
|
const triples = await showOntologyRaw(store, "ds");
|
|
22
22
|
expect(triples.length).toBeGreaterThan(0);
|
|
23
23
|
|
|
24
|
-
const hasDs = triples.some((t) =>
|
|
24
|
+
const hasDs = triples.some((t) =>
|
|
25
|
+
t.subject.startsWith(DEFAULT_PREFIX_MAP.ds),
|
|
26
|
+
);
|
|
25
27
|
expect(hasDs).toBe(true);
|
|
26
28
|
});
|
|
27
29
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { ontologyListStory, ontologyShowStory } from "./stories.js";
|
|
3
|
+
|
|
4
|
+
describe("ontologyListStory", () => {
|
|
5
|
+
it("renders the ink list view", () => {
|
|
6
|
+
const view = ontologyListStory.renderInk?.([]);
|
|
7
|
+
expect(typeof view).toBe("string");
|
|
8
|
+
expect(view).toContain("Ontologies");
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it("rejects only empty results", () => {
|
|
12
|
+
expect(ontologyListStory.emptyError?.([], {})).toBeDefined();
|
|
13
|
+
expect(
|
|
14
|
+
ontologyListStory.emptyError?.(
|
|
15
|
+
[
|
|
16
|
+
{
|
|
17
|
+
prefix: "ds",
|
|
18
|
+
namespace: "https://ds.example/",
|
|
19
|
+
classCount: 1,
|
|
20
|
+
propertyCount: 1,
|
|
21
|
+
anatomyCount: 0,
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
{},
|
|
25
|
+
),
|
|
26
|
+
).toBeUndefined();
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe("ontologyShowStory", () => {
|
|
31
|
+
it("guards against a missing prefix", () => {
|
|
32
|
+
expect(ontologyShowStory.guardParams?.({})).toBeDefined();
|
|
33
|
+
expect(ontologyShowStory.guardParams?.({ prefix: "" })).toBeDefined();
|
|
34
|
+
expect(ontologyShowStory.guardParams?.({ prefix: "ds" })).toBeUndefined();
|
|
35
|
+
});
|
|
36
|
+
});
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ontology read stories — the single declaration of `ontology list` and
|
|
3
|
+
* `ontology show` for both surfaces.
|
|
4
|
+
*
|
|
5
|
+
* The story kernel compiles these into the CLI commands and MCP tools.
|
|
6
|
+
* Both surfaces now render through the same formatters, so MCP condensed
|
|
7
|
+
* output matches CLI `--llm` output by construction (previously the MCP
|
|
8
|
+
* specs re-implemented the Markdown inline and had drifted).
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { PragmaError } from "#error";
|
|
12
|
+
import { createListView } from "#tui";
|
|
13
|
+
import type { ColumnDef } from "../shared/contracts.js";
|
|
14
|
+
import {
|
|
15
|
+
type ReadStory,
|
|
16
|
+
requirePragmaContext,
|
|
17
|
+
} from "../shared/stories/index.js";
|
|
18
|
+
import type {
|
|
19
|
+
OntologyDetailed,
|
|
20
|
+
OntologySummary,
|
|
21
|
+
} from "../shared/types/index.js";
|
|
22
|
+
import type { OntologyShowInput } from "./formatters/index.js";
|
|
23
|
+
import { listFormatters, showFormatters } from "./formatters/index.js";
|
|
24
|
+
import completeClassNames from "./helpers/completeClassNames.js";
|
|
25
|
+
import expandOntologyIris from "./helpers/expandOntologyIris.js";
|
|
26
|
+
import { listOntologies, showOntology } from "./operations/index.js";
|
|
27
|
+
|
|
28
|
+
const ontologyListColumns: readonly ColumnDef<OntologySummary>[] = [
|
|
29
|
+
{ key: "prefix", label: "Prefix" },
|
|
30
|
+
{ key: "namespace", label: "Namespace" },
|
|
31
|
+
{ key: "version", label: "Version" },
|
|
32
|
+
{ key: "classCount", label: "Classes" },
|
|
33
|
+
{ key: "relationCount", label: "Relations" },
|
|
34
|
+
{ key: "attributeCount", label: "Attributes" },
|
|
35
|
+
{ key: "shapeCount", label: "Shapes" },
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
/** The `ontology list` / `ontology_list` read story. */
|
|
39
|
+
export const ontologyListStory: ReadStory<
|
|
40
|
+
OntologySummary[],
|
|
41
|
+
readonly OntologySummary[]
|
|
42
|
+
> = {
|
|
43
|
+
noun: "ontology",
|
|
44
|
+
verb: "list",
|
|
45
|
+
description: "List loaded ontologies",
|
|
46
|
+
toolDescription:
|
|
47
|
+
"List all ontologies loaded in the knowledge graph with class and property counts.",
|
|
48
|
+
params: [],
|
|
49
|
+
examples: ["pragma ontology list", "pragma ontology list --llm"],
|
|
50
|
+
resolve: (rt) => listOntologies(rt.store),
|
|
51
|
+
toOutput: (ontologies) => ontologies,
|
|
52
|
+
formatters: listFormatters,
|
|
53
|
+
toEnvelope: (ontologies) => ({
|
|
54
|
+
data: ontologies,
|
|
55
|
+
meta: { count: ontologies.length },
|
|
56
|
+
}),
|
|
57
|
+
emptyError: (ontologies) =>
|
|
58
|
+
ontologies.length === 0
|
|
59
|
+
? PragmaError.emptyResults("ontology", {
|
|
60
|
+
recovery: {
|
|
61
|
+
message: "Ensure design system packages are installed.",
|
|
62
|
+
},
|
|
63
|
+
})
|
|
64
|
+
: undefined,
|
|
65
|
+
renderInk: (ontologies) =>
|
|
66
|
+
createListView({
|
|
67
|
+
heading: "Ontologies",
|
|
68
|
+
domain: "ontology",
|
|
69
|
+
items: ontologies,
|
|
70
|
+
columns: ontologyListColumns,
|
|
71
|
+
}),
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/** The `ontology show <prefix>` / `ontology_show` read story. */
|
|
75
|
+
export const ontologyShowStory: ReadStory<OntologyDetailed, OntologyShowInput> =
|
|
76
|
+
{
|
|
77
|
+
noun: "ontology",
|
|
78
|
+
verb: "show",
|
|
79
|
+
description: "Show ontology schema details",
|
|
80
|
+
toolDescription:
|
|
81
|
+
"Show the TBox for a namespace: class hierarchy with instance counts and relations, plus metadata and constraints.",
|
|
82
|
+
params: [
|
|
83
|
+
{
|
|
84
|
+
name: "prefix",
|
|
85
|
+
type: "string",
|
|
86
|
+
description: "Ontology prefix (e.g. 'ds', 'cs')",
|
|
87
|
+
positional: true,
|
|
88
|
+
required: true,
|
|
89
|
+
complete: async (partial, cmdCtx) => {
|
|
90
|
+
const ctx = requirePragmaContext(cmdCtx);
|
|
91
|
+
const all = await listOntologies(ctx.store);
|
|
92
|
+
return all
|
|
93
|
+
.map((o) => o.prefix)
|
|
94
|
+
.filter(
|
|
95
|
+
(p) =>
|
|
96
|
+
p.length > 0 &&
|
|
97
|
+
p.toLowerCase().startsWith(partial.toLowerCase()),
|
|
98
|
+
);
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: "class",
|
|
103
|
+
type: "string",
|
|
104
|
+
description:
|
|
105
|
+
"Deep-dive into one class (label, local name, or compact IRI)",
|
|
106
|
+
toolDescription:
|
|
107
|
+
"Class to deep-dive into: super chain, direct + inherited properties, reverse references, sample instances, and follow-up queries",
|
|
108
|
+
complete: async (partial, cmdCtx) => {
|
|
109
|
+
const ctx = requirePragmaContext(cmdCtx);
|
|
110
|
+
return completeClassNames(ctx.store, partial);
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: "properties",
|
|
115
|
+
type: "boolean",
|
|
116
|
+
description:
|
|
117
|
+
"Include datatype properties (attributes); default shows relations only",
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
name: "fullUris",
|
|
121
|
+
type: "boolean",
|
|
122
|
+
description: "Show full URIs instead of compact prefixed IRIs",
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
examples: [
|
|
126
|
+
"pragma ontology show ds",
|
|
127
|
+
"pragma ontology show ds --properties",
|
|
128
|
+
"pragma ontology show ds --full-uris --format json",
|
|
129
|
+
"pragma ontology show ds --class Component",
|
|
130
|
+
],
|
|
131
|
+
resolve: (rt, params) =>
|
|
132
|
+
showOntology(rt.store, params.prefix as string, {
|
|
133
|
+
class: params.class as string | undefined,
|
|
134
|
+
}),
|
|
135
|
+
// --full-uris is applied here, once, so every projection (plain, llm,
|
|
136
|
+
// json, MCP condensed) inherits the same encoding from the same place.
|
|
137
|
+
toOutput: (ontology, params) => ({
|
|
138
|
+
ontology: params.fullUris ? expandOntologyIris(ontology) : ontology,
|
|
139
|
+
showProperties: Boolean(params.properties),
|
|
140
|
+
}),
|
|
141
|
+
formatters: showFormatters,
|
|
142
|
+
toEnvelope: (ontology) => ({ data: ontology }),
|
|
143
|
+
guardParams: (params) =>
|
|
144
|
+
typeof params.prefix === "string" && params.prefix.length > 0
|
|
145
|
+
? undefined
|
|
146
|
+
: PragmaError.invalidInput("prefix", "(empty)", {
|
|
147
|
+
recovery: {
|
|
148
|
+
message: "List loaded ontologies to find valid prefixes.",
|
|
149
|
+
cli: "pragma ontology list",
|
|
150
|
+
mcp: { tool: "ontology_list" },
|
|
151
|
+
},
|
|
152
|
+
}),
|
|
153
|
+
};
|
|
@@ -8,12 +8,10 @@
|
|
|
8
8
|
import { existsSync, readdirSync } from "node:fs";
|
|
9
9
|
import { join } from "node:path";
|
|
10
10
|
import { readConfig } from "#config";
|
|
11
|
-
import {
|
|
11
|
+
import { mergeAndParseRefs } from "../../shared/mergeAndParseRefs.js";
|
|
12
12
|
import { cloneRef, fetchRef, pruneCache } from "./gitOps.js";
|
|
13
13
|
import type { PackageRef, RawPackageEntry } from "./parseRef.js";
|
|
14
|
-
import { parsePackageEntry } from "./parseRef.js";
|
|
15
14
|
import { cacheRoot, gitCacheDir } from "./paths.js";
|
|
16
|
-
import readGlobalRefs from "./readGlobalRefs.js";
|
|
17
15
|
|
|
18
16
|
// ---------------------------------------------------------------------------
|
|
19
17
|
// Types
|
|
@@ -56,7 +54,7 @@ export default async function updateRefs(
|
|
|
56
54
|
options: UpdateRefsOptions,
|
|
57
55
|
): Promise<UpdateResult[]> {
|
|
58
56
|
const config = readConfig(options.cwd);
|
|
59
|
-
const refs =
|
|
57
|
+
const refs = mergeAndParseRefs(config.packages);
|
|
60
58
|
const results: UpdateResult[] = [];
|
|
61
59
|
|
|
62
60
|
for (const ref of refs) {
|
|
@@ -137,40 +135,6 @@ export default async function updateRefs(
|
|
|
137
135
|
// Helpers
|
|
138
136
|
// ---------------------------------------------------------------------------
|
|
139
137
|
|
|
140
|
-
/** Merge global + project entries, parse into PackageRef[]. */
|
|
141
|
-
function mergeEntries(
|
|
142
|
-
projectPackages?: ReadonlyArray<RawPackageEntry>,
|
|
143
|
-
): PackageRef[] {
|
|
144
|
-
const globalEntries = readGlobalRefs();
|
|
145
|
-
|
|
146
|
-
if (
|
|
147
|
-
(!projectPackages || projectPackages.length === 0) &&
|
|
148
|
-
globalEntries.length === 0
|
|
149
|
-
) {
|
|
150
|
-
return DEFAULT_PACKAGES.map((pkg) => parsePackageEntry(pkg));
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
const merged = new Map<string, RawPackageEntry>();
|
|
154
|
-
|
|
155
|
-
for (const entry of DEFAULT_PACKAGES) {
|
|
156
|
-
const name = typeof entry === "string" ? entry : entry.name;
|
|
157
|
-
merged.set(name, entry);
|
|
158
|
-
}
|
|
159
|
-
for (const entry of globalEntries) {
|
|
160
|
-
const name = typeof entry === "string" ? entry : entry.name;
|
|
161
|
-
merged.set(name, entry);
|
|
162
|
-
}
|
|
163
|
-
if (projectPackages) {
|
|
164
|
-
merged.clear();
|
|
165
|
-
for (const entry of projectPackages) {
|
|
166
|
-
const name = typeof entry === "string" ? entry : entry.name;
|
|
167
|
-
merged.set(name, entry);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
return [...merged.values()].map(parsePackageEntry);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
138
|
/**
|
|
175
139
|
* Remove cache directories that don't match any configured git ref.
|
|
176
140
|
* Returns list of removed directories.
|
|
@@ -3,4 +3,5 @@ export { default as allCommand } from "./all.js";
|
|
|
3
3
|
export { default as completionsCommand } from "./completions.js";
|
|
4
4
|
export { default as lspCommand } from "./lsp.js";
|
|
5
5
|
export { default as mcpCommand } from "./mcp.js";
|
|
6
|
+
export { default as setupCommand } from "./setup.js";
|
|
6
7
|
export { default as skillsCommand } from "./skills.js";
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wires the top-level `pragma setup` command.
|
|
3
|
+
*
|
|
4
|
+
* `setup` is one level more general than `create <thing>`: it configures the
|
|
5
|
+
* whole local environment (completions, LSP, MCP). Unlike `create`, its steps
|
|
6
|
+
* perform *read* effects whose results drive control flow — detecting AI
|
|
7
|
+
* harnesses, checking what is already installed — so it must run for real and
|
|
8
|
+
* report the real outcome. It therefore executes through {@link runSetupTask}
|
|
9
|
+
* (real execution, streamed output) rather than the generator preview-then-
|
|
10
|
+
* execute path, which would render a dry-run preview whose stubbed reads report
|
|
11
|
+
* the wrong state (e.g. "no harnesses detected").
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type { CommandDefinition, CommandResult } from "@canonical/cli-core";
|
|
15
|
+
import runSetupTask from "../helpers/runSetupTask.js";
|
|
16
|
+
import setupAll from "../operations/setupAll.js";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Build the top-level `pragma setup` command definition.
|
|
20
|
+
*
|
|
21
|
+
* @returns The command definition for `pragma setup`.
|
|
22
|
+
* @note Impure
|
|
23
|
+
*/
|
|
24
|
+
export default function buildSetupCommand(): CommandDefinition {
|
|
25
|
+
return {
|
|
26
|
+
path: ["setup"],
|
|
27
|
+
description:
|
|
28
|
+
"Configure this project's environment: completions, LSP, and MCP",
|
|
29
|
+
parameters: [
|
|
30
|
+
{
|
|
31
|
+
name: "dryRun",
|
|
32
|
+
description: "Preview changes without writing",
|
|
33
|
+
type: "boolean",
|
|
34
|
+
default: false,
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: "undo",
|
|
38
|
+
description: "Reverse a previous setup",
|
|
39
|
+
type: "boolean",
|
|
40
|
+
default: false,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: "yes",
|
|
44
|
+
description: "Skip all confirmation prompts",
|
|
45
|
+
type: "boolean",
|
|
46
|
+
default: false,
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
meta: {
|
|
50
|
+
examples: [
|
|
51
|
+
"pragma setup",
|
|
52
|
+
"pragma setup --yes",
|
|
53
|
+
"pragma setup --dry-run",
|
|
54
|
+
"pragma setup --undo",
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
execute: async (
|
|
58
|
+
params: Record<string, unknown>,
|
|
59
|
+
ctx,
|
|
60
|
+
): Promise<CommandResult> =>
|
|
61
|
+
runSetupTask(setupAll(ctx.cwd), {
|
|
62
|
+
dryRun: params.dryRun === true,
|
|
63
|
+
undo: params.undo === true,
|
|
64
|
+
yes: params.yes === true,
|
|
65
|
+
verbose: ctx.globalFlags.verbose,
|
|
66
|
+
llm: ctx.globalFlags.llm,
|
|
67
|
+
format: ctx.globalFlags.format,
|
|
68
|
+
}),
|
|
69
|
+
};
|
|
70
|
+
}
|