@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
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ParameterDefinition } from "@canonical/cli-core";
|
|
2
|
+
import { PragmaError } from "#error";
|
|
3
|
+
import type { ConfigScope } from "../../../config/index.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The `--global` / `--local` target-layer flags shared by every config
|
|
7
|
+
* write command. Without either flag the write follows the global-first
|
|
8
|
+
* rule: nearest existing project file, else the global XDG file.
|
|
9
|
+
*/
|
|
10
|
+
export const SCOPE_PARAMETERS: readonly ParameterDefinition[] = [
|
|
11
|
+
{
|
|
12
|
+
name: "global",
|
|
13
|
+
description:
|
|
14
|
+
"Write to the global config ($XDG_CONFIG_HOME/pragma/config.json, default ~/.config/pragma/config.json)",
|
|
15
|
+
type: "boolean",
|
|
16
|
+
default: false,
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: "local",
|
|
20
|
+
description: "Write to ./pragma.config.json in the current directory",
|
|
21
|
+
type: "boolean",
|
|
22
|
+
default: false,
|
|
23
|
+
},
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Resolve the explicit write scope from parsed command parameters.
|
|
28
|
+
*
|
|
29
|
+
* @param params - Parsed command parameters.
|
|
30
|
+
* @returns The explicit scope, or `undefined` for the default rule.
|
|
31
|
+
* @throws PragmaError with code `INVALID_INPUT` when both flags are set.
|
|
32
|
+
*/
|
|
33
|
+
export function resolveConfigScope(
|
|
34
|
+
params: Record<string, unknown>,
|
|
35
|
+
): ConfigScope | undefined {
|
|
36
|
+
const global = params.global === true;
|
|
37
|
+
const local = params.local === true;
|
|
38
|
+
if (global && local) {
|
|
39
|
+
throw PragmaError.invalidInput("scope", "--global --local", {
|
|
40
|
+
recovery: { message: "Pass at most one of --global or --local." },
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
if (global) return "global";
|
|
44
|
+
if (local) return "local";
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
mkdirSync,
|
|
3
|
+
mkdtempSync,
|
|
4
|
+
readFileSync,
|
|
5
|
+
rmSync,
|
|
6
|
+
writeFileSync,
|
|
7
|
+
} from "node:fs";
|
|
2
8
|
import { tmpdir } from "node:os";
|
|
3
9
|
import { join } from "node:path";
|
|
4
10
|
import type { Store } from "@canonical/ke";
|
|
@@ -18,13 +24,24 @@ function makeCtx(cwd: string): PragmaContext {
|
|
|
18
24
|
|
|
19
25
|
describe("config framework command", () => {
|
|
20
26
|
let dir: string;
|
|
27
|
+
let xdgDir: string;
|
|
28
|
+
let originalXdg: string | undefined;
|
|
21
29
|
|
|
22
30
|
beforeEach(() => {
|
|
23
31
|
dir = mkdtempSync(join(tmpdir(), "pragma-cmd-framework-"));
|
|
32
|
+
// Bound the config walk at the fixture root, seed an empty project
|
|
33
|
+
// file so writes stay local, and isolate the global XDG layer.
|
|
34
|
+
mkdirSync(join(dir, ".git"));
|
|
35
|
+
writeFileSync(join(dir, "pragma.config.json"), "{}");
|
|
36
|
+
originalXdg = process.env.XDG_CONFIG_HOME;
|
|
37
|
+
xdgDir = mkdtempSync(join(tmpdir(), "pragma-cmd-framework-xdg-"));
|
|
38
|
+
process.env.XDG_CONFIG_HOME = xdgDir;
|
|
24
39
|
});
|
|
25
40
|
|
|
26
41
|
afterEach(() => {
|
|
42
|
+
process.env.XDG_CONFIG_HOME = originalXdg;
|
|
27
43
|
rmSync(dir, { recursive: true, force: true });
|
|
44
|
+
rmSync(xdgDir, { recursive: true, force: true });
|
|
28
45
|
});
|
|
29
46
|
|
|
30
47
|
it("sets framework to react", async () => {
|
|
@@ -45,6 +62,20 @@ describe("config framework command", () => {
|
|
|
45
62
|
expect(readConfig(dir).framework).toBe("lit");
|
|
46
63
|
});
|
|
47
64
|
|
|
65
|
+
it("rejects a value combined with --reset", async () => {
|
|
66
|
+
const ctx = makeCtx(dir);
|
|
67
|
+
await expect(
|
|
68
|
+
buildFrameworkCommand(ctx).execute({ value: "react", reset: true }, ctx),
|
|
69
|
+
).rejects.toMatchObject({ code: "INVALID_INPUT" });
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("rejects an explicit empty-string value", async () => {
|
|
73
|
+
const ctx = makeCtx(dir);
|
|
74
|
+
await expect(
|
|
75
|
+
buildFrameworkCommand(ctx).execute({ value: "" }, ctx),
|
|
76
|
+
).rejects.toMatchObject({ code: "INVALID_INPUT" });
|
|
77
|
+
});
|
|
78
|
+
|
|
48
79
|
it("rejects an invalid framework", async () => {
|
|
49
80
|
const ctx = makeCtx(dir);
|
|
50
81
|
await expect(
|
|
@@ -3,13 +3,15 @@ import {
|
|
|
3
3
|
type CommandResult,
|
|
4
4
|
createOutputResult,
|
|
5
5
|
} from "@canonical/cli-core";
|
|
6
|
-
import { runTask } from "@canonical/task";
|
|
6
|
+
import { runTask } from "@canonical/task/node";
|
|
7
7
|
import { readConfig } from "#config";
|
|
8
|
+
import { PragmaError } from "#error";
|
|
8
9
|
import type { PragmaContext } from "../../shared/context.js";
|
|
9
10
|
import { selectFormatter } from "../../shared/formatters.js";
|
|
10
11
|
import { frameworkFormatters } from "../formatters/index.js";
|
|
11
12
|
import { validateFramework } from "../operations/index.js";
|
|
12
13
|
import { setFrameworkTask } from "../tasks/index.js";
|
|
14
|
+
import { resolveConfigScope, SCOPE_PARAMETERS } from "./configScope.js";
|
|
13
15
|
|
|
14
16
|
/**
|
|
15
17
|
* Build the `pragma config framework` command definition.
|
|
@@ -41,6 +43,7 @@ export default function buildFrameworkCommand(
|
|
|
41
43
|
type: "boolean",
|
|
42
44
|
default: false,
|
|
43
45
|
},
|
|
46
|
+
...SCOPE_PARAMETERS,
|
|
44
47
|
],
|
|
45
48
|
meta: {
|
|
46
49
|
examples: [
|
|
@@ -53,18 +56,33 @@ export default function buildFrameworkCommand(
|
|
|
53
56
|
execute: async (
|
|
54
57
|
params: Record<string, unknown>,
|
|
55
58
|
): Promise<CommandResult> => {
|
|
59
|
+
const scope = resolveConfigScope(params);
|
|
56
60
|
const reset = params.reset === true;
|
|
57
61
|
const value = params.value as string | undefined;
|
|
58
62
|
|
|
63
|
+
// Contradictory input: a value AND --reset. Reject rather than silently
|
|
64
|
+
// letting one win.
|
|
65
|
+
if (reset && value !== undefined) {
|
|
66
|
+
throw PragmaError.invalidInput("framework", value, {
|
|
67
|
+
recovery: {
|
|
68
|
+
message: "Pass either a framework value or --reset, not both.",
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
59
73
|
if (reset) {
|
|
60
|
-
await runTask(
|
|
74
|
+
const result = await runTask(
|
|
75
|
+
setFrameworkTask(ctx.cwd, undefined, scope),
|
|
76
|
+
);
|
|
61
77
|
const format = selectFormatter(ctx, frameworkFormatters.reset);
|
|
62
|
-
return createOutputResult(
|
|
63
|
-
|
|
64
|
-
|
|
78
|
+
return createOutputResult(
|
|
79
|
+
{ field: "framework", path: result.path },
|
|
80
|
+
{ plain: format },
|
|
81
|
+
);
|
|
65
82
|
}
|
|
66
83
|
|
|
67
|
-
|
|
84
|
+
// No value at all → query. An explicit empty string is invalid input.
|
|
85
|
+
if (value === undefined) {
|
|
68
86
|
const config = readConfig(ctx.cwd);
|
|
69
87
|
const format = selectFormatter(ctx, frameworkFormatters.query);
|
|
70
88
|
return createOutputResult(config.framework ?? "none", {
|
|
@@ -74,10 +92,10 @@ export default function buildFrameworkCommand(
|
|
|
74
92
|
|
|
75
93
|
const framework = validateFramework(value);
|
|
76
94
|
|
|
77
|
-
await runTask(setFrameworkTask(ctx.cwd, framework));
|
|
95
|
+
const result = await runTask(setFrameworkTask(ctx.cwd, framework, scope));
|
|
78
96
|
const format = selectFormatter(ctx, frameworkFormatters.set);
|
|
79
97
|
return createOutputResult(
|
|
80
|
-
{ field: "framework", value: framework },
|
|
98
|
+
{ field: "framework", value: framework, path: result.path },
|
|
81
99
|
{ plain: format },
|
|
82
100
|
);
|
|
83
101
|
},
|
|
@@ -1,51 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type CommandDefinition,
|
|
3
|
-
type CommandResult,
|
|
4
|
-
createOutputResult,
|
|
5
|
-
} from "@canonical/cli-core";
|
|
6
|
-
import { configExists, readConfig, resolveConfigPath } from "#config";
|
|
7
|
-
import { detectInstallSource } from "#package-manager";
|
|
1
|
+
import type { CommandDefinition } from "@canonical/cli-core";
|
|
8
2
|
import type { PragmaContext } from "../../shared/context.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { resolveConfigShow } from "../operations/index.js";
|
|
3
|
+
import { compileReadCommand } from "../../shared/stories/index.js";
|
|
4
|
+
import { configShowStory } from "../stories.js";
|
|
12
5
|
|
|
13
|
-
/**
|
|
14
|
-
* Build the `pragma config show` command definition.
|
|
15
|
-
*
|
|
16
|
-
* Displays the resolved configuration including tier, channel,
|
|
17
|
-
* package manager, and config file location.
|
|
18
|
-
*
|
|
19
|
-
* @param ctx - Pragma context providing cwd and formatter selection.
|
|
20
|
-
* @returns The command definition for `pragma config show`.
|
|
21
|
-
* @note Impure
|
|
22
|
-
*/
|
|
6
|
+
/** Wire the `pragma config show` CLI command from the config show story. */
|
|
23
7
|
export default function buildShowCommand(
|
|
24
8
|
ctx: PragmaContext,
|
|
25
9
|
): CommandDefinition {
|
|
26
|
-
return
|
|
27
|
-
path: ["config", "show"],
|
|
28
|
-
description: "Display resolved configuration",
|
|
29
|
-
parameters: [],
|
|
30
|
-
meta: {
|
|
31
|
-
examples: ["pragma config show"],
|
|
32
|
-
},
|
|
33
|
-
execute: async (): Promise<CommandResult> => {
|
|
34
|
-
const config = readConfig(ctx.cwd);
|
|
35
|
-
const install = detectInstallSource();
|
|
36
|
-
const cfgPath = resolveConfigPath(ctx.cwd);
|
|
37
|
-
const cfgExists = configExists(ctx.cwd);
|
|
38
|
-
|
|
39
|
-
const data = resolveConfigShow(config, {
|
|
40
|
-
packageManager: install.packageManager,
|
|
41
|
-
installSource: install.label,
|
|
42
|
-
configFilePath: cfgPath,
|
|
43
|
-
configFileExists: cfgExists,
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
return createOutputResult(data, {
|
|
47
|
-
plain: selectFormatter(ctx, showFormatters),
|
|
48
|
-
});
|
|
49
|
-
},
|
|
50
|
-
};
|
|
10
|
+
return compileReadCommand(ctx, configShowStory);
|
|
51
11
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
1
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { tmpdir } from "node:os";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import type { Store } from "@canonical/ke";
|
|
@@ -18,13 +18,24 @@ function makeCtx(cwd: string): PragmaContext {
|
|
|
18
18
|
|
|
19
19
|
describe("config tier command", () => {
|
|
20
20
|
let dir: string;
|
|
21
|
+
let xdgDir: string;
|
|
22
|
+
let originalXdg: string | undefined;
|
|
21
23
|
|
|
22
24
|
beforeEach(() => {
|
|
23
25
|
dir = mkdtempSync(join(tmpdir(), "pragma-cmd-tier-"));
|
|
26
|
+
// Bound the config walk at the fixture root, seed an empty project
|
|
27
|
+
// file so writes stay local, and isolate the global XDG layer.
|
|
28
|
+
mkdirSync(join(dir, ".git"));
|
|
29
|
+
writeFileSync(join(dir, "pragma.config.json"), "{}");
|
|
30
|
+
originalXdg = process.env.XDG_CONFIG_HOME;
|
|
31
|
+
xdgDir = mkdtempSync(join(tmpdir(), "pragma-cmd-tier-xdg-"));
|
|
32
|
+
process.env.XDG_CONFIG_HOME = xdgDir;
|
|
24
33
|
});
|
|
25
34
|
|
|
26
35
|
afterEach(() => {
|
|
36
|
+
process.env.XDG_CONFIG_HOME = originalXdg;
|
|
27
37
|
rmSync(dir, { recursive: true, force: true });
|
|
38
|
+
rmSync(xdgDir, { recursive: true, force: true });
|
|
28
39
|
});
|
|
29
40
|
|
|
30
41
|
it("resets tier via --reset flag", async () => {
|
|
@@ -51,7 +62,7 @@ describe("config tier command", () => {
|
|
|
51
62
|
expect(result.tag).toBe("output");
|
|
52
63
|
if (result.tag === "output") {
|
|
53
64
|
const text = result.render.plain(result.value);
|
|
54
|
-
expect(text).
|
|
65
|
+
expect(text).toContain("Reset tier to default.");
|
|
55
66
|
}
|
|
56
67
|
});
|
|
57
68
|
|
|
@@ -81,4 +92,11 @@ describe("config tier command", () => {
|
|
|
81
92
|
expect(text).toBe("No tier set (all tiers visible).");
|
|
82
93
|
}
|
|
83
94
|
});
|
|
95
|
+
|
|
96
|
+
it("rejects a tier path combined with --reset", async () => {
|
|
97
|
+
const ctx = makeCtx(dir);
|
|
98
|
+
await expect(
|
|
99
|
+
buildTierCommand(ctx).execute({ path: "apps/lxd", reset: true }, ctx),
|
|
100
|
+
).rejects.toMatchObject({ code: "INVALID_INPUT" });
|
|
101
|
+
});
|
|
84
102
|
});
|
|
@@ -3,13 +3,15 @@ import {
|
|
|
3
3
|
type CommandResult,
|
|
4
4
|
createOutputResult,
|
|
5
5
|
} from "@canonical/cli-core";
|
|
6
|
-
import { runTask } from "@canonical/task";
|
|
6
|
+
import { runTask } from "@canonical/task/node";
|
|
7
7
|
import { readConfig } from "#config";
|
|
8
|
+
import { PragmaError } from "#error";
|
|
8
9
|
import type { PragmaContext } from "../../shared/context.js";
|
|
9
10
|
import { selectFormatter } from "../../shared/formatters.js";
|
|
10
11
|
import { tierFormatters } from "../formatters/index.js";
|
|
11
12
|
import { validateTier } from "../operations/index.js";
|
|
12
13
|
import { setTierTask } from "../tasks/index.js";
|
|
14
|
+
import { resolveConfigScope, SCOPE_PARAMETERS } from "./configScope.js";
|
|
13
15
|
|
|
14
16
|
/**
|
|
15
17
|
* Build the `pragma config tier` command definition.
|
|
@@ -40,6 +42,7 @@ export default function buildTierCommand(
|
|
|
40
42
|
type: "boolean",
|
|
41
43
|
default: false,
|
|
42
44
|
},
|
|
45
|
+
...SCOPE_PARAMETERS,
|
|
43
46
|
],
|
|
44
47
|
meta: {
|
|
45
48
|
examples: ["pragma config tier apps/lxd", "pragma config tier --reset"],
|
|
@@ -47,18 +50,32 @@ export default function buildTierCommand(
|
|
|
47
50
|
execute: async (
|
|
48
51
|
params: Record<string, unknown>,
|
|
49
52
|
): Promise<CommandResult> => {
|
|
53
|
+
const scope = resolveConfigScope(params);
|
|
50
54
|
const reset = params.reset === true;
|
|
51
55
|
const tierPath = params.path as string | undefined;
|
|
52
56
|
|
|
57
|
+
// Contradictory input: a tier path AND --reset. Reject rather than
|
|
58
|
+
// silently letting one win.
|
|
59
|
+
if (reset && tierPath !== undefined) {
|
|
60
|
+
throw PragmaError.invalidInput("tier", tierPath, {
|
|
61
|
+
recovery: {
|
|
62
|
+
message: "Pass either a tier path or --reset, not both.",
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
53
67
|
if (reset) {
|
|
54
|
-
await runTask(setTierTask(ctx.cwd, undefined));
|
|
68
|
+
const result = await runTask(setTierTask(ctx.cwd, undefined, scope));
|
|
55
69
|
const format = selectFormatter(ctx, tierFormatters.reset);
|
|
56
|
-
return createOutputResult(
|
|
57
|
-
|
|
58
|
-
|
|
70
|
+
return createOutputResult(
|
|
71
|
+
{ field: "tier", path: result.path },
|
|
72
|
+
{ plain: format },
|
|
73
|
+
);
|
|
59
74
|
}
|
|
60
75
|
|
|
61
|
-
|
|
76
|
+
// No path at all → query. An explicit empty string is invalid input and
|
|
77
|
+
// is rejected by validateTier below.
|
|
78
|
+
if (tierPath === undefined) {
|
|
62
79
|
const config = readConfig(ctx.cwd);
|
|
63
80
|
const format = selectFormatter(ctx, tierFormatters.query);
|
|
64
81
|
return createOutputResult(config.tier, {
|
|
@@ -69,10 +86,10 @@ export default function buildTierCommand(
|
|
|
69
86
|
// Validate tier against ontology
|
|
70
87
|
await validateTier(ctx.store, tierPath);
|
|
71
88
|
|
|
72
|
-
await runTask(setTierTask(ctx.cwd, tierPath));
|
|
89
|
+
const result = await runTask(setTierTask(ctx.cwd, tierPath, scope));
|
|
73
90
|
const format = selectFormatter(ctx, tierFormatters.set);
|
|
74
91
|
return createOutputResult(
|
|
75
|
-
{ field: "tier", value: tierPath },
|
|
92
|
+
{ field: "tier", value: tierPath, path: result.path },
|
|
76
93
|
{ plain: format },
|
|
77
94
|
);
|
|
78
95
|
},
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
mkdirSync,
|
|
3
|
+
mkdtempSync,
|
|
4
|
+
readFileSync,
|
|
5
|
+
rmSync,
|
|
6
|
+
writeFileSync,
|
|
7
|
+
} from "node:fs";
|
|
2
8
|
import { tmpdir } from "node:os";
|
|
3
9
|
import { join } from "node:path";
|
|
4
10
|
import type { Store } from "@canonical/ke";
|
|
@@ -18,13 +24,24 @@ function makeCtx(cwd: string): PragmaContext {
|
|
|
18
24
|
|
|
19
25
|
describe("config trace command", () => {
|
|
20
26
|
let dir: string;
|
|
27
|
+
let xdgDir: string;
|
|
28
|
+
let originalXdg: string | undefined;
|
|
21
29
|
|
|
22
30
|
beforeEach(() => {
|
|
23
31
|
dir = mkdtempSync(join(tmpdir(), "pragma-cmd-trace-"));
|
|
32
|
+
// Bound the config walk at the fixture root, seed an empty project
|
|
33
|
+
// file so writes stay local, and isolate the global XDG layer.
|
|
34
|
+
mkdirSync(join(dir, ".git"));
|
|
35
|
+
writeFileSync(join(dir, "pragma.config.json"), "{}");
|
|
36
|
+
originalXdg = process.env.XDG_CONFIG_HOME;
|
|
37
|
+
xdgDir = mkdtempSync(join(tmpdir(), "pragma-cmd-trace-xdg-"));
|
|
38
|
+
process.env.XDG_CONFIG_HOME = xdgDir;
|
|
24
39
|
});
|
|
25
40
|
|
|
26
41
|
afterEach(() => {
|
|
42
|
+
process.env.XDG_CONFIG_HOME = originalXdg;
|
|
27
43
|
rmSync(dir, { recursive: true, force: true });
|
|
44
|
+
rmSync(xdgDir, { recursive: true, force: true });
|
|
28
45
|
});
|
|
29
46
|
|
|
30
47
|
it("enables tracing", async () => {
|
|
@@ -54,7 +71,7 @@ describe("config trace command", () => {
|
|
|
54
71
|
|
|
55
72
|
expect(result.tag).toBe("output");
|
|
56
73
|
if (result.tag === "output") {
|
|
57
|
-
expect(result.render.plain(result.value)).
|
|
74
|
+
expect(result.render.plain(result.value)).toContain("Tracing enabled.");
|
|
58
75
|
}
|
|
59
76
|
});
|
|
60
77
|
|
|
@@ -3,13 +3,14 @@ import {
|
|
|
3
3
|
type CommandResult,
|
|
4
4
|
createOutputResult,
|
|
5
5
|
} from "@canonical/cli-core";
|
|
6
|
-
import { runTask } from "@canonical/task";
|
|
6
|
+
import { runTask } from "@canonical/task/node";
|
|
7
7
|
import { readConfig } from "#config";
|
|
8
8
|
import { PragmaError } from "#error";
|
|
9
9
|
import type { PragmaContext } from "../../shared/context.js";
|
|
10
10
|
import { selectFormatter } from "../../shared/formatters.js";
|
|
11
11
|
import { traceFormatters } from "../formatters/index.js";
|
|
12
12
|
import { setTraceTask } from "../tasks/index.js";
|
|
13
|
+
import { resolveConfigScope, SCOPE_PARAMETERS } from "./configScope.js";
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Build the `pragma config trace` command definition.
|
|
@@ -30,6 +31,7 @@ export default function buildTraceCommand(
|
|
|
30
31
|
type: "string",
|
|
31
32
|
positional: true,
|
|
32
33
|
},
|
|
34
|
+
...SCOPE_PARAMETERS,
|
|
33
35
|
],
|
|
34
36
|
meta: {
|
|
35
37
|
examples: [
|
|
@@ -43,6 +45,7 @@ export default function buildTraceCommand(
|
|
|
43
45
|
execute: async (
|
|
44
46
|
params: Record<string, unknown>,
|
|
45
47
|
): Promise<CommandResult> => {
|
|
48
|
+
const scope = resolveConfigScope(params);
|
|
46
49
|
const value = params.value as string | undefined;
|
|
47
50
|
|
|
48
51
|
// Query mode — no argument
|
|
@@ -68,11 +71,11 @@ export default function buildTraceCommand(
|
|
|
68
71
|
|
|
69
72
|
// Set mode
|
|
70
73
|
const enabled = value === "on";
|
|
71
|
-
await runTask(setTraceTask(ctx.cwd, enabled));
|
|
74
|
+
const result = await runTask(setTraceTask(ctx.cwd, enabled, scope));
|
|
72
75
|
|
|
73
76
|
const format = selectFormatter(ctx, traceFormatters.set);
|
|
74
77
|
return createOutputResult(
|
|
75
|
-
{ field: "trace", value: enabled },
|
|
78
|
+
{ field: "trace", value: enabled, path: result.path },
|
|
76
79
|
{ plain: format },
|
|
77
80
|
);
|
|
78
81
|
},
|
|
@@ -2,14 +2,22 @@ import { describe, expect, it } from "vitest";
|
|
|
2
2
|
import formatters from "./channel.js";
|
|
3
3
|
|
|
4
4
|
describe("channelFormatters.set", () => {
|
|
5
|
-
const data = {
|
|
5
|
+
const data = {
|
|
6
|
+
field: "channel",
|
|
7
|
+
value: "experimental",
|
|
8
|
+
path: "/repo/pragma.config.json",
|
|
9
|
+
};
|
|
6
10
|
|
|
7
11
|
it("plain renders set message", () => {
|
|
8
|
-
expect(formatters.set.plain(data)).toBe(
|
|
12
|
+
expect(formatters.set.plain(data)).toBe(
|
|
13
|
+
'Set channel to "experimental".\nWrote /repo/pragma.config.json',
|
|
14
|
+
);
|
|
9
15
|
});
|
|
10
16
|
|
|
11
17
|
it("llm renders set message", () => {
|
|
12
|
-
expect(formatters.set.llm(data)).toBe(
|
|
18
|
+
expect(formatters.set.llm(data)).toBe(
|
|
19
|
+
'Set channel to "experimental".\nWrote /repo/pragma.config.json',
|
|
20
|
+
);
|
|
13
21
|
});
|
|
14
22
|
|
|
15
23
|
it("json returns valid JSON", () => {
|
|
@@ -21,15 +29,21 @@ describe("channelFormatters.set", () => {
|
|
|
21
29
|
|
|
22
30
|
describe("channelFormatters.reset", () => {
|
|
23
31
|
it("plain renders reset message", () => {
|
|
24
|
-
expect(
|
|
32
|
+
expect(
|
|
33
|
+
formatters.reset.plain({ field: "channel", path: "/repo/p.json" }),
|
|
34
|
+
).toBe("Reset channel to default.\nWrote /repo/p.json");
|
|
25
35
|
});
|
|
26
36
|
|
|
27
37
|
it("llm renders reset message", () => {
|
|
28
|
-
expect(
|
|
38
|
+
expect(
|
|
39
|
+
formatters.reset.llm({ field: "channel", path: "/repo/p.json" }),
|
|
40
|
+
).toBe("Reset channel to default.\nWrote /repo/p.json");
|
|
29
41
|
});
|
|
30
42
|
|
|
31
43
|
it("json returns valid JSON", () => {
|
|
32
|
-
const parsed = JSON.parse(
|
|
44
|
+
const parsed = JSON.parse(
|
|
45
|
+
formatters.reset.json({ field: "channel", path: "/repo/p.json" }),
|
|
46
|
+
);
|
|
33
47
|
expect(parsed.field).toBe("channel");
|
|
34
48
|
expect(parsed.reset).toBe(true);
|
|
35
49
|
});
|
|
@@ -9,19 +9,22 @@ import type { Formatters } from "../../shared/formatters.js";
|
|
|
9
9
|
*/
|
|
10
10
|
const channelFormatters = {
|
|
11
11
|
set: {
|
|
12
|
-
plain: (d: { field: string; value: string }) =>
|
|
13
|
-
`Set ${d.field} to "${d.value}"
|
|
14
|
-
llm: (d: { field: string; value: string }) =>
|
|
15
|
-
`Set ${d.field} to "${d.value}"
|
|
16
|
-
json: (d: { field: string; value: string }) =>
|
|
17
|
-
JSON.stringify({ field: d.field, value: d.value }),
|
|
18
|
-
} satisfies Formatters<{ field: string; value: string }>,
|
|
12
|
+
plain: (d: { field: string; value: string; path: string }) =>
|
|
13
|
+
`Set ${d.field} to "${d.value}".\nWrote ${d.path}`,
|
|
14
|
+
llm: (d: { field: string; value: string; path: string }) =>
|
|
15
|
+
`Set ${d.field} to "${d.value}".\nWrote ${d.path}`,
|
|
16
|
+
json: (d: { field: string; value: string; path: string }) =>
|
|
17
|
+
JSON.stringify({ field: d.field, value: d.value, path: d.path }),
|
|
18
|
+
} satisfies Formatters<{ field: string; value: string; path: string }>,
|
|
19
19
|
|
|
20
20
|
reset: {
|
|
21
|
-
plain: (
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
plain: (d: { field: string; path: string }) =>
|
|
22
|
+
`Reset channel to default.\nWrote ${d.path}`,
|
|
23
|
+
llm: (d: { field: string; path: string }) =>
|
|
24
|
+
`Reset channel to default.\nWrote ${d.path}`,
|
|
25
|
+
json: (d: { field: string; path: string }) =>
|
|
26
|
+
JSON.stringify({ field: "channel", reset: true, path: d.path }),
|
|
27
|
+
} satisfies Formatters<{ field: string; path: string }>,
|
|
25
28
|
|
|
26
29
|
query: {
|
|
27
30
|
plain: (channel: string) => `Current channel: ${channel}`,
|
|
@@ -9,19 +9,22 @@ import type { Formatters } from "../../shared/formatters.js";
|
|
|
9
9
|
*/
|
|
10
10
|
const frameworkFormatters = {
|
|
11
11
|
set: {
|
|
12
|
-
plain: (d: { field: string; value: string }) =>
|
|
13
|
-
`Set ${d.field} to "${d.value}"
|
|
14
|
-
llm: (d: { field: string; value: string }) =>
|
|
15
|
-
`Set ${d.field} to "${d.value}"
|
|
16
|
-
json: (d: { field: string; value: string }) =>
|
|
17
|
-
JSON.stringify({ field: d.field, value: d.value }),
|
|
18
|
-
} satisfies Formatters<{ field: string; value: string }>,
|
|
12
|
+
plain: (d: { field: string; value: string; path: string }) =>
|
|
13
|
+
`Set ${d.field} to "${d.value}".\nWrote ${d.path}`,
|
|
14
|
+
llm: (d: { field: string; value: string; path: string }) =>
|
|
15
|
+
`Set ${d.field} to "${d.value}".\nWrote ${d.path}`,
|
|
16
|
+
json: (d: { field: string; value: string; path: string }) =>
|
|
17
|
+
JSON.stringify({ field: d.field, value: d.value, path: d.path }),
|
|
18
|
+
} satisfies Formatters<{ field: string; value: string; path: string }>,
|
|
19
19
|
|
|
20
20
|
reset: {
|
|
21
|
-
plain: (
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
plain: (d: { field: string; path: string }) =>
|
|
22
|
+
`Reset framework to default.\nWrote ${d.path}`,
|
|
23
|
+
llm: (d: { field: string; path: string }) =>
|
|
24
|
+
`Reset framework to default.\nWrote ${d.path}`,
|
|
25
|
+
json: (d: { field: string; path: string }) =>
|
|
26
|
+
JSON.stringify({ field: "framework", reset: true, path: d.path }),
|
|
27
|
+
} satisfies Formatters<{ field: string; path: string }>,
|
|
25
28
|
|
|
26
29
|
query: {
|
|
27
30
|
plain: (framework: string) => `Current framework: ${framework}`,
|
|
@@ -11,6 +11,15 @@ const WITH_TIER: ConfigShowData = {
|
|
|
11
11
|
installSource: "bun (global)",
|
|
12
12
|
configFilePath: "/project/pragma.config.json",
|
|
13
13
|
configFileExists: true,
|
|
14
|
+
globalConfigPath: "/home/u/.config/pragma/config.json",
|
|
15
|
+
globalConfigExists: false,
|
|
16
|
+
origins: {
|
|
17
|
+
tier: "project",
|
|
18
|
+
channel: "project",
|
|
19
|
+
packages: "default",
|
|
20
|
+
trace: "default",
|
|
21
|
+
framework: "default",
|
|
22
|
+
},
|
|
14
23
|
};
|
|
15
24
|
|
|
16
25
|
const WITHOUT_TIER: ConfigShowData = {
|
|
@@ -22,6 +31,15 @@ const WITHOUT_TIER: ConfigShowData = {
|
|
|
22
31
|
installSource: "bun (local)",
|
|
23
32
|
configFilePath: "/project/pragma.config.json",
|
|
24
33
|
configFileExists: false,
|
|
34
|
+
globalConfigPath: "/home/u/.config/pragma/config.json",
|
|
35
|
+
globalConfigExists: false,
|
|
36
|
+
origins: {
|
|
37
|
+
tier: "project",
|
|
38
|
+
channel: "project",
|
|
39
|
+
packages: "default",
|
|
40
|
+
trace: "default",
|
|
41
|
+
framework: "default",
|
|
42
|
+
},
|
|
25
43
|
};
|
|
26
44
|
|
|
27
45
|
const PRERELEASE: ConfigShowData = {
|
|
@@ -33,6 +51,15 @@ const PRERELEASE: ConfigShowData = {
|
|
|
33
51
|
installSource: "pnpm (global)",
|
|
34
52
|
configFilePath: "/project/pragma.config.json",
|
|
35
53
|
configFileExists: true,
|
|
54
|
+
globalConfigPath: "/home/u/.config/pragma/config.json",
|
|
55
|
+
globalConfigExists: false,
|
|
56
|
+
origins: {
|
|
57
|
+
tier: "project",
|
|
58
|
+
channel: "project",
|
|
59
|
+
packages: "default",
|
|
60
|
+
trace: "default",
|
|
61
|
+
framework: "default",
|
|
62
|
+
},
|
|
36
63
|
};
|
|
37
64
|
|
|
38
65
|
describe("formatters.plain", () => {
|