@canonical/pragma-cli 0.29.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 +13 -13
- 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 -153
- 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 +76 -1
- package/src/config/writeConfig.ts +25 -55
- package/src/domains/block/commands/list.ts +5 -90
- package/src/domains/block/commands/lookup.ts +8 -167
- package/src/domains/block/mcp/specs.ts +16 -196
- package/src/domains/block/orchestration/resolveBlockLookup.ts +2 -1
- 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 +18 -1
- package/src/domains/config/commands/framework.ts +13 -7
- 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 +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/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/commands/component.ts +5 -5
- package/src/domains/doctor/operations/checks/checkConfigFile.ts +19 -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 +2 -14
- 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 +158 -7
- package/src/domains/doctor/operations/runChecks.test.ts +15 -6
- package/src/domains/doctor/operations/runChecks.ts +2 -0
- 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 +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 +40 -0
- package/src/domains/graphql/commands/serve.ts +131 -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/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 +21 -45
- 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/index.ts +5 -0
- package/src/domains/info/operations/collectInfo.test.ts +14 -3
- package/src/domains/info/operations/collectInfo.ts +12 -15
- package/src/domains/llm/capabilities.test.ts +4 -4
- package/src/domains/llm/data/toolCatalog.ts +6 -0
- package/src/domains/modifier/commands/list.ts +5 -38
- package/src/domains/modifier/commands/lookup.ts +8 -79
- package/src/domains/modifier/mcp/specs.ts +15 -94
- package/src/domains/modifier/orchestration/resolveModifierLookup.ts +2 -1
- 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/updateRefs.ts +2 -37
- 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 +6 -3
- 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/loaders/bundledLoader.test.ts +248 -0
- package/src/domains/shared/loaders/bundledLoader.ts +110 -12
- package/src/domains/shared/loaders/gitLoader.ts +2 -2
- package/src/domains/shared/loaders/index.ts +4 -1
- package/src/domains/shared/loaders/localLoader.ts +18 -4
- package/src/domains/shared/loaders/readPackageDir.ts +36 -1
- 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 +34 -2
- package/src/domains/shared/mergeAndParseRefs.test.ts +89 -0
- package/src/domains/shared/mergeAndParseRefs.ts +44 -0
- package/src/domains/shared/packages.ts +10 -17
- package/src/domains/shared/resolveConfiguredGraphs.test.ts +27 -0
- package/src/domains/shared/resolveConfiguredGraphs.ts +41 -0
- package/src/domains/shared/runtime.ts +4 -63
- package/src/domains/shared/semanticPackage.ts +17 -1
- 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/expandGlob.ts +1 -0
- package/src/domains/shared/suggestions/suggestNames.ts +43 -10
- 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/standard/commands/list.ts +5 -84
- package/src/domains/standard/commands/lookup.ts +8 -93
- package/src/domains/standard/mcp/specs.ts +16 -171
- package/src/domains/standard/orchestration/resolveStandardLookup.ts +2 -1
- 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/mcp/specs.ts +5 -1
- package/src/domains/token/orchestration/resolveTokenLookup.ts +2 -1
- package/src/domains/trace/tracePlugin.test.ts +1 -1
- 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 +9 -0
- package/src/mcp/tools/registerTools.test.ts +65 -8
- package/src/mcp/types.ts +4 -0
- package/src/pipeline/collectCommands.ts +8 -1
- package/src/pipeline/runCli.ts +40 -6
- package/src/testing/createTestMcpClient.ts +4 -1
- package/src/testing/index.ts +10 -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 +1 -1
- 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", () => {
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
} from "./loaders/index.js";
|
|
25
25
|
import { DEFAULT_PACKAGES } from "./packages.js";
|
|
26
26
|
import { PREFIX_MAP } from "./prefixes.js";
|
|
27
|
-
import type {
|
|
27
|
+
import type { SemanticPackage } from "./semanticPackage.js";
|
|
28
28
|
import { resolveSemanticPackages } from "./semanticPackage.js";
|
|
29
29
|
|
|
30
30
|
export interface BootStoreOptions {
|
|
@@ -38,6 +38,8 @@ export interface BootStoreOptions {
|
|
|
38
38
|
refs?: ReadonlyArray<PackageRef>;
|
|
39
39
|
/** Enable query tracing (from config). Env var PRAGMA_TRACE=1 overrides. */
|
|
40
40
|
trace?: boolean;
|
|
41
|
+
/** Additional namespace prefixes merged over the built-in prefix map. */
|
|
42
|
+
prefixes?: Readonly<Record<string, string>>;
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
export interface BootResult {
|
|
@@ -59,12 +61,13 @@ export interface BootResult {
|
|
|
59
61
|
export async function bootStore(
|
|
60
62
|
options: BootStoreOptions = {},
|
|
61
63
|
): Promise<BootResult> {
|
|
64
|
+
const prefixes = { ...PREFIX_MAP, ...options.prefixes };
|
|
62
65
|
try {
|
|
63
66
|
// Testing/programmatic override — use explicit sources
|
|
64
67
|
if (options.sources) {
|
|
65
68
|
const store = await createStore({
|
|
66
69
|
sources: options.sources,
|
|
67
|
-
prefixes
|
|
70
|
+
prefixes,
|
|
68
71
|
cache: options.cache,
|
|
69
72
|
cwd: options.cwd,
|
|
70
73
|
});
|
|
@@ -110,7 +113,7 @@ export async function bootStore(
|
|
|
110
113
|
|
|
111
114
|
const store = await createStore({
|
|
112
115
|
sources: [],
|
|
113
|
-
prefixes
|
|
116
|
+
prefixes,
|
|
114
117
|
cache: options.cache,
|
|
115
118
|
cwd: options.cwd,
|
|
116
119
|
plugins,
|
|
@@ -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,6 +50,15 @@ 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 {
|
|
@@ -58,6 +67,8 @@ export interface LookupResult<T> {
|
|
|
58
67
|
message: string;
|
|
59
68
|
suggestions?: readonly string[];
|
|
60
69
|
}[];
|
|
70
|
+
/** Populated by `lookupMany`; may be absent on hand-built results. */
|
|
71
|
+
readonly meta?: LookupResultMeta;
|
|
61
72
|
}
|
|
62
73
|
|
|
63
74
|
export interface ShowContract<T> {
|