@canonical/pragma-cli 0.27.1-experimental.0 → 0.30.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 +67 -15
- package/dist/pragma +0 -0
- package/package.json +16 -17
- 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 +215 -0
- package/src/config/readConfig.test.ts +104 -13
- package/src/config/readConfig.ts +12 -117
- package/src/config/readConfigLayers.test.ts +107 -0
- package/src/config/readConfigLayers.ts +115 -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 +88 -2
- package/src/config/writeConfig.ts +25 -43
- package/src/constants.ts +12 -1
- package/src/domains/block/commands/index.ts +2 -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 +55 -0
- package/src/domains/block/formatters/index.ts +2 -1
- package/src/domains/block/formatters/sample.ts +21 -0
- package/src/domains/block/index.ts +3 -3
- package/src/domains/block/mcp/specs.ts +36 -168
- package/src/domains/block/operations/index.ts +2 -1
- package/src/domains/block/operations/lookup.ts +9 -0
- package/src/domains/block/operations/sample.ts +41 -0
- package/src/domains/block/orchestration/blockEmptyError.test.ts +26 -0
- package/src/domains/block/orchestration/resolveBlockLookup.ts +11 -3
- package/src/domains/block/stories.test.ts +28 -0
- package/src/domains/block/stories.ts +254 -0
- package/src/domains/config/commands/channel.test.ts +14 -3
- package/src/domains/config/commands/channel.ts +11 -7
- package/src/domains/config/commands/configScope.ts +46 -0
- package/src/domains/config/commands/framework.test.ts +105 -0
- package/src/domains/config/commands/framework.ts +91 -0
- package/src/domains/config/commands/index.ts +2 -0
- package/src/domains/config/commands/show.ts +5 -45
- package/src/domains/config/commands/tier.test.ts +13 -2
- package/src/domains/config/commands/tier.ts +11 -7
- package/src/domains/config/commands/trace.test.ts +165 -0
- package/src/domains/config/commands/trace.ts +83 -0
- 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 +37 -0
- package/src/domains/config/formatters/index.ts +2 -0
- 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 +28 -0
- package/src/domains/config/index.ts +15 -2
- package/src/domains/config/mcp/specs.ts +33 -53
- package/src/domains/config/operations/index.ts +1 -0
- 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/validateFramework.ts +24 -0
- package/src/domains/config/stories.ts +42 -0
- package/src/domains/config/tasks/index.ts +3 -0
- package/src/domains/config/tasks/setChannel.ts +13 -22
- package/src/domains/config/tasks/setFramework.ts +21 -0
- package/src/domains/config/tasks/setTier.ts +10 -23
- package/src/domains/config/tasks/setTrace.ts +20 -0
- package/src/domains/config/tasks/writeConfigField.ts +41 -0
- package/src/domains/create/commands/component.ts +5 -5
- package/src/domains/doctor/operations/checks/checkConfigFile.ts +19 -5
- package/src/domains/doctor/operations/checks/checkKeStore.ts +5 -5
- package/src/domains/doctor/operations/checks/checkMcpCommands.ts +130 -0
- package/src/domains/doctor/operations/checks/checkMcpConfigured.ts +1 -1
- package/src/domains/doctor/operations/checks/checkPackageRefs.ts +30 -48
- 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 +162 -8
- package/src/domains/doctor/operations/runChecks.test.ts +85 -4
- package/src/domains/doctor/operations/runChecks.ts +50 -12
- package/src/domains/graph/helpers/resolveUri.test.ts +50 -0
- package/src/domains/graph/helpers/resolveUri.ts +28 -21
- package/src/domains/graphql/commands/build.test.ts +196 -0
- package/src/domains/graphql/commands/build.ts +117 -0
- package/src/domains/graphql/commands/check.test.ts +141 -0
- package/src/domains/graphql/commands/check.ts +81 -0
- package/src/domains/graphql/commands/index.ts +5 -0
- package/src/domains/graphql/commands/serve.test.ts +40 -0
- package/src/domains/graphql/commands/serve.ts +131 -0
- package/src/domains/graphql/constants.ts +10 -0
- package/src/domains/graphql/formatters/index.ts +3 -0
- package/src/domains/graphql/formatters/report.ts +78 -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 +6 -0
- package/src/domains/graphql/helpers/parsePrefixes.test.ts +44 -0
- package/src/domains/graphql/helpers/parsePrefixes.ts +38 -0
- package/src/domains/graphql/helpers/resolveSourceFiles.test.ts +56 -0
- package/src/domains/graphql/helpers/resolveSourceFiles.ts +45 -0
- 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 +24 -0
- package/src/domains/graphql/operations/compileSchema.test.ts +95 -0
- package/src/domains/graphql/operations/compileSchema.ts +107 -0
- package/src/domains/graphql/operations/createSchemaServer.test.ts +50 -0
- package/src/domains/graphql/operations/createSchemaServer.ts +75 -0
- package/src/domains/graphql/operations/index.ts +12 -0
- package/src/domains/graphql/types.ts +29 -0
- package/src/domains/info/operations/collectInfo.test.ts +16 -5
- package/src/domains/info/operations/collectInfo.ts +16 -19
- package/src/domains/llm/capabilities.test.ts +91 -0
- package/src/domains/llm/commands/capabilities.ts +28 -0
- package/src/domains/llm/commands/index.ts +1 -0
- package/src/domains/llm/data/commandReference.ts +90 -18
- package/src/domains/llm/data/decisionTrees.ts +15 -13
- package/src/domains/llm/data/index.ts +2 -0
- package/src/domains/llm/data/toolCatalog.ts +190 -0
- package/src/domains/llm/formatters/capabilities.ts +50 -0
- package/src/domains/llm/formatters/index.ts +1 -0
- package/src/domains/llm/index.ts +3 -2
- package/src/domains/llm/mcp/index.ts +1 -1
- package/src/domains/llm/mcp/specs.ts +59 -52
- package/src/domains/llm/types.ts +40 -0
- package/src/domains/modifier/commands/index.ts +2 -1
- 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 +53 -0
- package/src/domains/modifier/formatters/index.ts +2 -1
- package/src/domains/modifier/formatters/sample.ts +15 -0
- package/src/domains/modifier/index.ts +7 -3
- package/src/domains/modifier/mcp/specs.ts +38 -70
- package/src/domains/modifier/operations/index.ts +2 -1
- package/src/domains/modifier/operations/lookup.ts +9 -0
- package/src/domains/modifier/operations/sample.ts +32 -0
- package/src/domains/modifier/orchestration/modifierEmptyError.test.ts +26 -0
- package/src/domains/modifier/orchestration/modifierEmptyError.ts +7 -2
- package/src/domains/modifier/orchestration/resolveModifierLookup.ts +15 -2
- package/src/domains/modifier/stories.test.ts +20 -0
- package/src/domains/modifier/stories.ts +77 -0
- package/src/domains/ontology/commands/list.ts +5 -58
- package/src/domains/ontology/commands/show.ts +6 -58
- package/src/domains/ontology/formatters/show.ts +7 -1
- package/src/domains/ontology/mcp/specs.ts +7 -84
- package/src/domains/ontology/stories.test.ts +36 -0
- package/src/domains/ontology/stories.ts +108 -0
- package/src/domains/refs/operations/index.ts +1 -1
- package/src/domains/refs/operations/paths.ts +29 -1
- package/src/domains/refs/operations/updateRefs.test.ts +6 -3
- package/src/domains/refs/operations/updateRefs.ts +2 -36
- 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/operations/setupMcp.test.ts +6 -1
- package/src/domains/shared/bootStore.ts +92 -50
- 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 +12 -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 +109 -0
- package/src/domains/shared/loaders/bundledLoader.test.ts +248 -0
- package/src/domains/shared/loaders/bundledLoader.ts +206 -0
- package/src/domains/shared/loaders/gitLoader.ts +31 -0
- package/src/domains/shared/loaders/index.ts +9 -0
- package/src/domains/shared/loaders/localLoader.ts +87 -0
- package/src/domains/shared/loaders/readPackageDir.ts +147 -0
- 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 +120 -0
- package/src/domains/shared/lookupMany.ts +43 -3
- package/src/domains/shared/mergeAndParseRefs.test.ts +89 -0
- package/src/domains/shared/mergeAndParseRefs.ts +44 -0
- package/src/domains/shared/packages.ts +14 -120
- package/src/domains/shared/pickRandom.ts +22 -0
- package/src/domains/shared/resolveConfiguredGraphs.test.ts +27 -0
- package/src/domains/shared/resolveConfiguredGraphs.ts +41 -0
- package/src/domains/shared/runtime.ts +7 -63
- package/src/domains/shared/sampleFormatters.ts +47 -0
- package/src/domains/shared/semanticPackage.ts +112 -0
- package/src/domains/shared/stories/compileLookupCommand.test.ts +145 -0
- package/src/domains/shared/stories/compileLookupCommand.ts +100 -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 +102 -0
- package/src/domains/shared/stories/pack/applyPackFilters.ts +76 -0
- package/src/domains/shared/stories/pack/buildLookupQuery.test.ts +51 -0
- package/src/domains/shared/stories/pack/buildLookupQuery.ts +80 -0
- package/src/domains/shared/stories/pack/collectPackStories.test.ts +108 -0
- package/src/domains/shared/stories/pack/collectPackStories.ts +76 -0
- package/src/domains/shared/stories/pack/compilePackCommands.ts +40 -0
- package/src/domains/shared/stories/pack/compilePackStories.test.ts +146 -0
- package/src/domains/shared/stories/pack/compilePackStories.ts +253 -0
- package/src/domains/shared/stories/pack/compilePackToolSpecs.ts +43 -0
- package/src/domains/shared/stories/pack/index.ts +28 -0
- package/src/domains/shared/stories/pack/runSelectQuery.ts +31 -0
- package/src/domains/shared/stories/pack/standardParity.test.ts +308 -0
- package/src/domains/shared/stories/pack/types.ts +104 -0
- package/src/domains/shared/stories/pack/validateStoryPackDefinition.test.ts +240 -0
- package/src/domains/shared/stories/pack/validateStoryPackDefinition.ts +408 -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 +171 -0
- package/src/domains/shared/suggestions/detectCrossDomain.test.ts +43 -0
- package/src/domains/shared/suggestions/detectCrossDomain.ts +116 -0
- package/src/domains/shared/suggestions/expandGlob.test.ts +92 -0
- package/src/domains/shared/suggestions/expandGlob.ts +52 -0
- package/src/domains/shared/suggestions/expandLookupQueries.ts +57 -0
- package/src/domains/shared/suggestions/index.ts +7 -0
- package/src/domains/shared/suggestions/listDomainNames.ts +61 -0
- package/src/domains/shared/suggestions/suggestNames.test.ts +70 -0
- package/src/domains/shared/suggestions/suggestNames.ts +130 -0
- package/src/domains/shared/types/index.ts +1 -0
- package/src/domains/shared/types/runtime.ts +4 -1
- package/src/domains/shared/types/sample.ts +17 -0
- 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 +48 -16
- 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/standard/commands/index.ts +2 -1
- package/src/domains/standard/commands/list.ts +5 -84
- package/src/domains/standard/commands/lookup.ts +8 -93
- package/src/domains/standard/commands/sample.ts +57 -0
- package/src/domains/standard/formatters/index.ts +2 -1
- package/src/domains/standard/formatters/sample.ts +15 -0
- package/src/domains/standard/index.ts +8 -1
- package/src/domains/standard/mcp/specs.ts +44 -152
- package/src/domains/standard/operations/index.ts +2 -1
- package/src/domains/standard/operations/lookup.ts +9 -0
- package/src/domains/standard/operations/sample.ts +35 -0
- package/src/domains/standard/orchestration/resolveStandardLookup.ts +15 -2
- package/src/domains/standard/orchestration/standardEmptyError.test.ts +33 -0
- package/src/domains/standard/orchestration/standardEmptyError.ts +16 -6
- package/src/domains/standard/stories.test.ts +24 -0
- package/src/domains/standard/stories.ts +151 -0
- package/src/domains/tier/commands/list.ts +5 -55
- package/src/domains/tier/mcp/specs.ts +5 -31
- package/src/domains/tier/stories.test.ts +22 -0
- package/src/domains/tier/stories.ts +52 -0
- package/src/domains/token/commands/index.ts +2 -1
- package/src/domains/token/commands/sample.ts +53 -0
- package/src/domains/token/formatters/index.ts +2 -1
- package/src/domains/token/formatters/sample.ts +16 -0
- package/src/domains/token/index.ts +8 -1
- package/src/domains/token/mcp/specs.ts +52 -2
- package/src/domains/token/operations/index.ts +2 -1
- package/src/domains/token/operations/lookup.ts +9 -0
- package/src/domains/token/operations/sample.ts +32 -0
- package/src/domains/token/orchestration/resolveTokenLookup.ts +15 -2
- package/src/domains/token/orchestration/tokenEmptyError.test.ts +33 -0
- package/src/domains/token/orchestration/tokenEmptyError.ts +5 -2
- package/src/domains/trace/commands/clear.ts +71 -0
- package/src/domains/trace/commands/index.ts +5 -0
- package/src/domains/trace/commands/sessions.ts +32 -0
- package/src/domains/trace/commands/show.ts +145 -0
- package/src/domains/trace/formatters/index.ts +9 -0
- package/src/domains/trace/formatters/sessions.ts +80 -0
- package/src/domains/trace/formatters/show.ts +122 -0
- package/src/domains/trace/index.ts +17 -0
- package/src/domains/trace/operations/index.ts +8 -0
- package/src/domains/trace/operations/listSessions.test.ts +55 -0
- package/src/domains/trace/operations/listSessions.ts +52 -0
- package/src/domains/trace/operations/readTraceLog.test.ts +100 -0
- package/src/domains/trace/operations/readTraceLog.ts +104 -0
- package/src/domains/trace/tracePlugin.test.ts +171 -0
- package/src/domains/trace/tracePlugin.ts +159 -0
- package/src/domains/trace/types.ts +65 -0
- package/src/error/PragmaError.ts +15 -2
- package/src/error/types.ts +15 -1
- package/src/mcp/error/serializeErrorPayload.ts +7 -0
- package/src/mcp/error/types.ts +8 -0
- package/src/mcp/registerResources.test.ts +405 -75
- package/src/mcp/registerResources.ts +5 -299
- 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 +9 -0
- package/src/mcp/tools/registerTools.test.ts +84 -12
- package/src/mcp/types.ts +4 -0
- package/src/mcp/utils/wrapTool.test.ts +1 -0
- package/src/pipeline/collectCommands.ts +15 -2
- package/src/pipeline/renderError.ts +15 -0
- package/src/pipeline/resolveCommandKind.ts +8 -1
- package/src/pipeline/runCli.ts +51 -6
- package/src/testing/createTestMcpClient.ts +5 -1
- package/src/testing/graphqlFixtures.ts +72 -0
- package/src/testing/index.ts +17 -0
- package/src/testing/integration/__snapshots__/executor-golden.test.ts.snap +1207 -0
- package/src/testing/integration/cross-binary-byte-equality.test.ts +129 -0
- package/src/testing/integration/executor-execution.test.ts +101 -0
- package/src/testing/integration/executor-golden.test.ts +145 -0
- package/src/testing/integration/mcp-surface.test.ts +11 -5
- package/src/testing/integration/parity.test.ts +17 -12
- package/src/testing/regression/0001-skill-discovery-granularity.test.ts +71 -0
- package/src/testing/setupXdgIsolation.ts +15 -0
- package/src/testing/standardParityFixtures.ts +92 -0
- package/src/testing/storyFixtures.ts +63 -0
- package/src/pipeline/runInteractiveCommand.ts +0 -198
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
import { createInterface } from "node:readline";
|
|
2
1
|
import {
|
|
2
|
+
answerPromptWithDefaults,
|
|
3
3
|
type CommandResult,
|
|
4
4
|
createExitResult,
|
|
5
5
|
createOutputResult,
|
|
6
6
|
formatEffectLine,
|
|
7
7
|
isVisibleEffect,
|
|
8
|
+
runGeneratorTask,
|
|
8
9
|
} from "@canonical/cli-core";
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
type Task,
|
|
15
|
-
} from "@canonical/task";
|
|
10
|
+
import { dryRun, type Effect, type Task } from "@canonical/task";
|
|
11
|
+
import { runUndo } from "@canonical/task/node";
|
|
12
|
+
import createInteractivePromptSession, {
|
|
13
|
+
type InteractivePromptSession,
|
|
14
|
+
} from "../../shared/createInteractivePromptSession.js";
|
|
16
15
|
import type { LogLevel } from "../types.js";
|
|
17
16
|
|
|
18
17
|
/** Options controlling how {@link runSetupTask} executes. */
|
|
@@ -26,55 +25,41 @@ export interface SetupTaskOptions {
|
|
|
26
25
|
}
|
|
27
26
|
|
|
28
27
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* @returns The default value for the prompt type.
|
|
28
|
+
* Pick the prompt handler for a run: auto-confirm defaults under `--yes`, else
|
|
29
|
+
* an interactive readline session (whose lifetime the caller owns via the
|
|
30
|
+
* returned `dispose`).
|
|
33
31
|
*/
|
|
34
|
-
function
|
|
35
|
-
effect: Effect & { _tag: "Prompt" }
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (
|
|
40
|
-
return
|
|
41
|
-
|
|
42
|
-
|
|
32
|
+
function selectPromptHandler(yes: boolean): {
|
|
33
|
+
handler: (effect: Effect & { _tag: "Prompt" }) => Promise<unknown>;
|
|
34
|
+
wasInterrupted: () => boolean;
|
|
35
|
+
dispose: () => void;
|
|
36
|
+
} {
|
|
37
|
+
if (yes) {
|
|
38
|
+
return {
|
|
39
|
+
handler: answerPromptWithDefaults,
|
|
40
|
+
wasInterrupted: () => false,
|
|
41
|
+
dispose: () => {},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
const session: InteractivePromptSession = createInteractivePromptSession();
|
|
45
|
+
return {
|
|
46
|
+
handler: session.answerPrompt,
|
|
47
|
+
wasInterrupted: session.wasInterrupted,
|
|
48
|
+
dispose: session.dispose,
|
|
49
|
+
};
|
|
43
50
|
}
|
|
44
51
|
|
|
45
52
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* @param effect - A Prompt effect to resolve interactively.
|
|
50
|
-
* @returns The user's answer.
|
|
53
|
+
* Build a task log sink that writes to stderr, hiding debug lines unless
|
|
54
|
+
* verbose is set.
|
|
51
55
|
*/
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
):
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const hint = defaultYes ? "Y/n" : "y/N";
|
|
60
|
-
const rl = createInterface({
|
|
61
|
-
input: process.stdin,
|
|
62
|
-
output: process.stderr,
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
const answer = await new Promise<string>((resolve) => {
|
|
66
|
-
rl.question(`${q.message} [${hint}] `, (ans) => {
|
|
67
|
-
rl.close();
|
|
68
|
-
resolve(ans.trim());
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
if (answer === "") return defaultYes;
|
|
73
|
-
return answer.toLowerCase().startsWith("y");
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Non-confirm prompts fall back to defaults in D15
|
|
77
|
-
return q.default;
|
|
56
|
+
function createStderrLogger(
|
|
57
|
+
verbose: boolean,
|
|
58
|
+
): (level: LogLevel, message: string) => void {
|
|
59
|
+
return (level, message) => {
|
|
60
|
+
if (level === "debug" && !verbose) return;
|
|
61
|
+
process.stderr.write(`${message}\n`);
|
|
62
|
+
};
|
|
78
63
|
}
|
|
79
64
|
|
|
80
65
|
/**
|
|
@@ -150,7 +135,8 @@ function formatDryRunJson(effects: readonly Effect[]): string {
|
|
|
150
135
|
* Supports three execution modes:
|
|
151
136
|
* - `--dry-run`: collects effects without executing, formats for display.
|
|
152
137
|
* - `--undo`: walks the task tree, collects undo operations, executes in reverse.
|
|
153
|
-
* - default:
|
|
138
|
+
* - default: execution through {@link runGeneratorTask}, with readline-based
|
|
139
|
+
* prompts on stderr.
|
|
154
140
|
*
|
|
155
141
|
* @param task - The setup Task to execute.
|
|
156
142
|
* @param options - Execution options (dryRun, undo, yes, verbose, llm, format).
|
|
@@ -182,14 +168,12 @@ export default async function runSetupTask(
|
|
|
182
168
|
|
|
183
169
|
// Undo mode: walk the task tree, collect undos, execute in reverse
|
|
184
170
|
if (options.undo) {
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
process.stderr.write(`${message}\n`);
|
|
192
|
-
};
|
|
171
|
+
const {
|
|
172
|
+
handler: promptHandler,
|
|
173
|
+
wasInterrupted,
|
|
174
|
+
dispose,
|
|
175
|
+
} = selectPromptHandler(options.yes ?? false);
|
|
176
|
+
const onLog = createStderrLogger(verbose);
|
|
193
177
|
|
|
194
178
|
try {
|
|
195
179
|
const result = await runUndo(task, { promptHandler, onLog });
|
|
@@ -202,28 +186,36 @@ export default async function runSetupTask(
|
|
|
202
186
|
}
|
|
203
187
|
return createExitResult(0);
|
|
204
188
|
} catch (err) {
|
|
189
|
+
if (wasInterrupted()) {
|
|
190
|
+
return createExitResult(130);
|
|
191
|
+
}
|
|
205
192
|
const message = err instanceof Error ? err.message : String(err);
|
|
206
193
|
process.stderr.write(`Undo failed: ${message}\n`);
|
|
207
194
|
return createExitResult(1);
|
|
195
|
+
} finally {
|
|
196
|
+
dispose();
|
|
208
197
|
}
|
|
209
198
|
}
|
|
210
199
|
|
|
211
200
|
// Production execution
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
process.stderr.write(`${message}\n`);
|
|
219
|
-
};
|
|
201
|
+
const {
|
|
202
|
+
handler: promptHandler,
|
|
203
|
+
wasInterrupted,
|
|
204
|
+
dispose,
|
|
205
|
+
} = selectPromptHandler(options.yes ?? false);
|
|
206
|
+
const onLog = createStderrLogger(verbose);
|
|
220
207
|
|
|
221
208
|
try {
|
|
222
|
-
await
|
|
209
|
+
await runGeneratorTask(task, { promptHandler, onLog });
|
|
223
210
|
return createExitResult(0);
|
|
224
211
|
} catch (err) {
|
|
212
|
+
if (wasInterrupted()) {
|
|
213
|
+
return createExitResult(130);
|
|
214
|
+
}
|
|
225
215
|
const message = err instanceof Error ? err.message : String(err);
|
|
226
216
|
process.stderr.write(`Setup failed: ${message}\n`);
|
|
227
217
|
return createExitResult(1);
|
|
218
|
+
} finally {
|
|
219
|
+
dispose();
|
|
228
220
|
}
|
|
229
221
|
}
|
|
@@ -10,7 +10,12 @@ const mockExists =
|
|
|
10
10
|
function mocks(
|
|
11
11
|
existsPredicate: (path: string) => boolean,
|
|
12
12
|
): Map<string, (effect: Effect) => unknown> {
|
|
13
|
-
return new Map
|
|
13
|
+
return new Map<string, (effect: Effect) => unknown>([
|
|
14
|
+
["Exists", mockExists(existsPredicate)],
|
|
15
|
+
// An existing config reads back as an empty-but-valid JSON object, so a
|
|
16
|
+
// write merges into it rather than failing closed on the dry-run placeholder.
|
|
17
|
+
["ReadFile", () => "{}"],
|
|
18
|
+
]);
|
|
14
19
|
}
|
|
15
20
|
|
|
16
21
|
describe("setupMcp", () => {
|
|
@@ -1,85 +1,127 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Boot a ke store from
|
|
2
|
+
* Boot a ke store from resolved semantic packages.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Resolves packages via the loader chain (local > git > bundled),
|
|
5
|
+
* then loads all graph content into the store.
|
|
6
6
|
*
|
|
7
7
|
* @note Impure — reads filesystem, creates ke store.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
import {
|
|
11
|
+
createStore,
|
|
12
|
+
definePlugin,
|
|
13
|
+
type Plugin,
|
|
14
|
+
type SourceSpec,
|
|
15
|
+
type Store,
|
|
16
|
+
} from "@canonical/ke";
|
|
14
17
|
import { PragmaError } from "../../error/index.js";
|
|
15
18
|
import type { PackageRef } from "../refs/operations/parseRef.js";
|
|
16
|
-
import {
|
|
19
|
+
import { parsePackageEntry } from "../refs/operations/parseRef.js";
|
|
20
|
+
import {
|
|
21
|
+
createBundledLoader,
|
|
22
|
+
createGitLoader,
|
|
23
|
+
createLocalLoader,
|
|
24
|
+
} from "./loaders/index.js";
|
|
25
|
+
import { DEFAULT_PACKAGES } from "./packages.js";
|
|
17
26
|
import { PREFIX_MAP } from "./prefixes.js";
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
* Convention-based TTL directories to scan in each package.
|
|
21
|
-
* Only directories that exist are globbed — packages that lack
|
|
22
|
-
* a `data/` or `definitions/` dir are silently skipped.
|
|
23
|
-
*/
|
|
24
|
-
const TTL_DIRS: readonly { dir: string; glob: string }[] = [
|
|
25
|
-
{ dir: "definitions", glob: "definitions/**/*.ttl" },
|
|
26
|
-
{ dir: "data", glob: "data/**/*.ttl" },
|
|
27
|
-
];
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Resolve default TTL sources from resolved packages.
|
|
31
|
-
*
|
|
32
|
-
* Uses convention-based TTL discovery: definitions and data globs
|
|
33
|
-
* relative to each package root. Only adds globs for directories
|
|
34
|
-
* that actually exist in the package.
|
|
35
|
-
*
|
|
36
|
-
* @param refs - Parsed package references. Omit for defaults.
|
|
37
|
-
*/
|
|
38
|
-
export function defaultSources(refs?: ReadonlyArray<PackageRef>): SourceSpec[] {
|
|
39
|
-
const sources: SourceSpec[] = [];
|
|
40
|
-
const resolved = resolvePackages(refs);
|
|
41
|
-
|
|
42
|
-
for (const { dir } of resolved) {
|
|
43
|
-
for (const entry of TTL_DIRS) {
|
|
44
|
-
if (existsSync(join(dir, entry.dir))) {
|
|
45
|
-
sources.push(join(dir, entry.glob));
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return sources;
|
|
51
|
-
}
|
|
27
|
+
import type { SemanticPackage } from "./semanticPackage.js";
|
|
28
|
+
import { resolveSemanticPackages } from "./semanticPackage.js";
|
|
52
29
|
|
|
53
30
|
export interface BootStoreOptions {
|
|
54
|
-
/** Override sources (skip
|
|
31
|
+
/** Override sources (skip package resolution — for testing). */
|
|
55
32
|
sources?: SourceSpec[];
|
|
56
33
|
/** Working directory for resolving relative paths. */
|
|
57
34
|
cwd?: string;
|
|
58
35
|
/** Cache path for serialized store. */
|
|
59
36
|
cache?: string;
|
|
60
|
-
/** Parsed package references for
|
|
37
|
+
/** Parsed package references for loader-based resolution. */
|
|
61
38
|
refs?: ReadonlyArray<PackageRef>;
|
|
39
|
+
/** Enable query tracing (from config). Env var PRAGMA_TRACE=1 overrides. */
|
|
40
|
+
trace?: boolean;
|
|
41
|
+
/** Additional namespace prefixes merged over the built-in prefix map. */
|
|
42
|
+
prefixes?: Readonly<Record<string, string>>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface BootResult {
|
|
46
|
+
/** The initialized ke store. */
|
|
47
|
+
readonly store: Store;
|
|
48
|
+
/** Resolved semantic packages (empty when sources override is used). */
|
|
49
|
+
readonly packages: readonly SemanticPackage[];
|
|
62
50
|
}
|
|
63
51
|
|
|
64
52
|
/**
|
|
65
53
|
* Boot a ke store from configuration.
|
|
66
54
|
*
|
|
55
|
+
* When `sources` is provided, uses them directly (testing path).
|
|
56
|
+
* Otherwise, resolves packages via the loader chain and loads their
|
|
57
|
+
* graph content into the store.
|
|
58
|
+
*
|
|
67
59
|
* @throws PragmaError with code STORE_ERROR on failure.
|
|
68
60
|
*/
|
|
69
61
|
export async function bootStore(
|
|
70
62
|
options: BootStoreOptions = {},
|
|
71
|
-
): Promise<
|
|
72
|
-
const
|
|
73
|
-
|
|
63
|
+
): Promise<BootResult> {
|
|
64
|
+
const prefixes = { ...PREFIX_MAP, ...options.prefixes };
|
|
74
65
|
try {
|
|
66
|
+
// Testing/programmatic override — use explicit sources
|
|
67
|
+
if (options.sources) {
|
|
68
|
+
const store = await createStore({
|
|
69
|
+
sources: options.sources,
|
|
70
|
+
prefixes,
|
|
71
|
+
cache: options.cache,
|
|
72
|
+
cwd: options.cwd,
|
|
73
|
+
});
|
|
74
|
+
return { store, packages: [] };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Resolve packages via loader chain: local > git > bundled
|
|
78
|
+
const refs =
|
|
79
|
+
options.refs && options.refs.length > 0
|
|
80
|
+
? options.refs
|
|
81
|
+
: DEFAULT_PACKAGES.map(parsePackageEntry);
|
|
82
|
+
// Precedence: local (file:// + node_modules) > git cache > bundled
|
|
83
|
+
const loaders = [
|
|
84
|
+
createLocalLoader(),
|
|
85
|
+
createGitLoader(),
|
|
86
|
+
createBundledLoader(),
|
|
87
|
+
];
|
|
88
|
+
const packages = await resolveSemanticPackages(refs, loaders);
|
|
89
|
+
|
|
90
|
+
// Collect all graph content from resolved packages
|
|
91
|
+
const allGraphs = packages.flatMap((pkg) => pkg.graphs);
|
|
92
|
+
|
|
93
|
+
// Use a ke plugin to load graph content during store creation.
|
|
94
|
+
// The onReady hook has access to ctx.load() which loads raw content.
|
|
95
|
+
const graphLoaderPlugin = definePlugin({
|
|
96
|
+
name: "pragma-graph-loader",
|
|
97
|
+
onReady(ctx) {
|
|
98
|
+
for (const graph of allGraphs) {
|
|
99
|
+
ctx.load(graph.content, { format: graph.format });
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// biome-ignore lint: Plugin generic variance requires explicit unknown
|
|
105
|
+
const plugins: Plugin<any>[] = [graphLoaderPlugin];
|
|
106
|
+
const traceEnabled =
|
|
107
|
+
process.env.PRAGMA_TRACE === "1" || options.trace === true;
|
|
108
|
+
if (traceEnabled) {
|
|
109
|
+
const { createTracePlugin } = await import("../trace/tracePlugin.js");
|
|
110
|
+
const { traceDir } = await import("../refs/operations/paths.js");
|
|
111
|
+
plugins.push(createTracePlugin({ traceDir: traceDir() }));
|
|
112
|
+
}
|
|
113
|
+
|
|
75
114
|
const store = await createStore({
|
|
76
|
-
sources,
|
|
77
|
-
prefixes
|
|
115
|
+
sources: [],
|
|
116
|
+
prefixes,
|
|
78
117
|
cache: options.cache,
|
|
79
118
|
cwd: options.cwd,
|
|
119
|
+
plugins,
|
|
80
120
|
});
|
|
81
|
-
|
|
121
|
+
|
|
122
|
+
return { store, packages };
|
|
82
123
|
} catch (error) {
|
|
124
|
+
if (error instanceof PragmaError) throw error;
|
|
83
125
|
throw PragmaError.storeError(
|
|
84
126
|
error instanceof Error ? error.message : String(error),
|
|
85
127
|
{
|
|
@@ -18,4 +18,15 @@ describe("compactUri", () => {
|
|
|
18
18
|
"https://example.com/thing",
|
|
19
19
|
);
|
|
20
20
|
});
|
|
21
|
+
|
|
22
|
+
it("picks the longest matching namespace when namespaces overlap", () => {
|
|
23
|
+
const overlapping = {
|
|
24
|
+
base: "https://ex.org/",
|
|
25
|
+
sub: "https://ex.org/sub/",
|
|
26
|
+
} as const;
|
|
27
|
+
// Both `base` and `sub` are prefixes of the URI; the longer wins.
|
|
28
|
+
expect(compactUri("https://ex.org/sub/Thing", overlapping)).toBe(
|
|
29
|
+
"sub:Thing",
|
|
30
|
+
);
|
|
31
|
+
});
|
|
21
32
|
});
|
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Convert a full URI to its compact prefixed form
|
|
3
|
-
*
|
|
2
|
+
* Convert a full URI to its compact prefixed form using the longest matching
|
|
3
|
+
* namespace. When two registered namespaces are both prefixes of the URI
|
|
4
|
+
* (e.g. a base namespace and a sub-namespace), the longer — more specific —
|
|
5
|
+
* one wins. Falls back to the original URI when no namespace matches.
|
|
4
6
|
*/
|
|
5
7
|
export default function compactUri(
|
|
6
8
|
fullUri: string,
|
|
7
9
|
prefixes: Readonly<Record<string, string>>,
|
|
8
10
|
): string {
|
|
11
|
+
let best: { prefix: string; namespace: string } | undefined;
|
|
9
12
|
for (const [prefix, namespace] of Object.entries(prefixes)) {
|
|
10
|
-
if (fullUri.startsWith(namespace))
|
|
11
|
-
|
|
13
|
+
if (!fullUri.startsWith(namespace)) continue;
|
|
14
|
+
if (best === undefined || namespace.length > best.namespace.length) {
|
|
15
|
+
best = { prefix, namespace };
|
|
12
16
|
}
|
|
13
17
|
}
|
|
14
18
|
|
|
15
|
-
return fullUri;
|
|
19
|
+
if (best === undefined) return fullUri;
|
|
20
|
+
return `${best.prefix}:${fullUri.slice(best.namespace.length)}`;
|
|
16
21
|
}
|
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
* cli-core remains unaware of Store or FilterConfig.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import type { GlobalFlags,
|
|
10
|
+
import type { GlobalFlags, PromptSessionFactory } from "@canonical/cli-core";
|
|
11
11
|
import type { PragmaRuntime } from "./types/index.js";
|
|
12
12
|
|
|
13
13
|
export interface PragmaContext extends PragmaRuntime {
|
|
14
14
|
readonly globalFlags: GlobalFlags;
|
|
15
|
-
readonly
|
|
15
|
+
readonly promptSession?: PromptSessionFactory | undefined;
|
|
16
16
|
}
|
|
@@ -50,13 +50,25 @@ export interface ListResult<T> {
|
|
|
50
50
|
| { readonly level: "detailed" };
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
/** Aggregate metadata about a multi-query lookup. */
|
|
54
|
+
export interface LookupResultMeta {
|
|
55
|
+
/**
|
|
56
|
+
* Number of queries that failed with an unexpected (non-Pragma) error.
|
|
57
|
+
* Each such failure is also present in `errors` with code `INTERNAL_ERROR`.
|
|
58
|
+
*/
|
|
59
|
+
readonly internalErrorCount: number;
|
|
60
|
+
}
|
|
61
|
+
|
|
53
62
|
export interface LookupResult<T> {
|
|
54
63
|
readonly results: readonly T[];
|
|
55
64
|
readonly errors: readonly {
|
|
56
65
|
query: string;
|
|
57
66
|
code: string;
|
|
58
67
|
message: string;
|
|
68
|
+
suggestions?: readonly string[];
|
|
59
69
|
}[];
|
|
70
|
+
/** Populated by `lookupMany`; may be absent on hand-built results. */
|
|
71
|
+
readonly meta?: LookupResultMeta;
|
|
60
72
|
}
|
|
61
73
|
|
|
62
74
|
export interface ShowContract<T> {
|