@canonical/pragma-cli 0.30.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 +64 -35
- 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/parseConfigValues.ts +2 -0
- package/src/config/readConfigLayers.test.ts +2 -0
- package/src/config/readConfigLayers.ts +3 -0
- package/src/config/types.ts +7 -0
- package/src/constants.ts +3 -1
- 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/orchestration/enrichBlocks.ts +6 -3
- package/src/domains/block/stories.ts +9 -3
- package/src/domains/config/commands/channel.test.ts +16 -0
- package/src/domains/config/commands/channel.ts +14 -1
- package/src/domains/config/commands/framework.test.ts +14 -0
- package/src/domains/config/commands/framework.ts +13 -1
- package/src/domains/config/commands/tier.test.ts +7 -0
- package/src/domains/config/commands/tier.ts +14 -1
- package/src/domains/config/operations/validateTier.test.ts +9 -0
- package/src/domains/config/operations/validateTier.ts +10 -2
- 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/checkMcpCommands.ts +9 -6
- package/src/domains/doctor/operations/checks/checkPackageRefs.ts +30 -12
- package/src/domains/doctor/operations/checks.test.ts +6 -4
- 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/operations/inspectUri.test.ts +5 -5
- package/src/domains/graphql/commands/serve.test.ts +12 -6
- package/src/domains/graphql/commands/serve.ts +16 -6
- 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/operations/compileSchema.test.ts +2 -2
- package/src/domains/graphql/operations/createSchemaServer.test.ts +2 -2
- 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 +5 -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/index.ts +1 -0
- package/src/domains/info/types.ts +13 -0
- package/src/domains/llm/capabilities.test.ts +23 -3
- 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 +49 -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/sample.ts +2 -1
- package/src/domains/modifier/operations/lookup.ts +5 -3
- package/src/domains/modifier/stories.ts +9 -0
- package/src/domains/ontology/commands/list.test.ts +5 -3
- package/src/domains/ontology/commands/show.test.ts +85 -9
- 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 +358 -67
- 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/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.ts +53 -8
- package/src/domains/refs/operations/updateRefs.ts +0 -1
- package/src/domains/setup/commands/index.ts +1 -0
- package/src/domains/setup/commands/setup.ts +70 -0
- 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/shared/bootStore.bareCore.test.ts +63 -0
- package/src/domains/shared/bootStore.test.ts +82 -0
- package/src/domains/shared/bootStore.ts +56 -20
- 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.ts +48 -0
- package/src/domains/shared/loaders/gitLoader.ts +1 -2
- package/src/domains/shared/loaders/localLoader.ts +2 -18
- package/src/domains/shared/loaders/readPackageDir.test.ts +58 -0
- package/src/domains/shared/loaders/readPackageDir.ts +46 -8
- package/src/domains/shared/lookupMany.test.ts +15 -0
- package/src/domains/shared/lookupMany.ts +22 -6
- package/src/domains/shared/namespaces.ts +13 -5
- 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/resolveLookupExitCode.test.ts +48 -0
- package/src/domains/shared/resolveLookupExitCode.ts +42 -0
- package/src/domains/shared/semanticPackage.test.ts +89 -0
- package/src/domains/shared/semanticPackage.ts +17 -2
- package/src/domains/shared/stories/compileLookupCommand.ts +3 -1
- package/src/domains/shared/stories/compileLookupTool.ts +1 -1
- package/src/domains/shared/stories/pack/applyPackFilters.test.ts +49 -0
- package/src/domains/shared/stories/pack/applyPackFilters.ts +46 -11
- 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 +30 -0
- package/src/domains/shared/stories/pack/buildLookupQuery.ts +75 -1
- 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 +305 -7
- package/src/domains/shared/stories/pack/collectPackStories.ts +90 -8
- package/src/domains/shared/stories/pack/compilePackCommands.ts +17 -7
- package/src/domains/shared/stories/pack/compilePackStories.test.ts +607 -2
- package/src/domains/shared/stories/pack/compilePackStories.ts +544 -73
- package/src/domains/shared/stories/pack/compilePackToolSpecs.ts +20 -8
- package/src/domains/shared/stories/pack/index.ts +14 -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/standardParity.test.ts +293 -220
- package/src/domains/shared/stories/pack/types.ts +123 -3
- package/src/domains/shared/stories/pack/validateStoryPackDefinition.test.ts +502 -0
- package/src/domains/shared/stories/pack/validateStoryPackDefinition.ts +475 -24
- package/src/domains/shared/stories/types.ts +9 -1
- 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/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 +13 -1
- package/src/domains/trace/commands/resolveTraceLimit.test.ts +31 -0
- package/src/domains/trace/commands/show.ts +30 -4
- package/src/index.ts +1 -13
- package/src/mcp/registerResources.test.ts +2 -2
- package/src/mcp/resources/pickPrimaryType.test.ts +5 -5
- package/src/mcp/tools/index.ts +18 -10
- package/src/mcp/tools/registerTools.test.ts +106 -30
- package/src/pipeline/collectCommands.test.ts +151 -1
- package/src/pipeline/collectCommands.ts +34 -19
- 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 +162 -19
- package/src/testing/cli.ts +30 -2
- package/src/testing/dsFixtures.ts +21 -4
- package/src/testing/index.ts +1 -4
- package/src/testing/integration/__snapshots__/executor-golden.test.ts.snap +4 -4
- package/src/testing/integration/cli-user-stories.test.ts +63 -0
- package/src/testing/integration/cross-binary-byte-equality.test.ts +2 -2
- package/src/testing/integration/edge-cases.test.ts +62 -50
- package/src/testing/integration/executor-execution.test.ts +6 -4
- package/src/testing/integration/executor-golden.test.ts +2 -2
- package/src/testing/integration/mcp-surface.test.ts +40 -15
- package/src/testing/integration/parity.test.ts +119 -70
- package/src/testing/setupXdgIsolation.ts +16 -5
- package/src/testing/standardParityFixtures.ts +26 -83
- package/src/testing/store.ts +4 -4
- 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 -11
- package/src/domains/standard/commands/lookup.test.ts +0 -135
- package/src/domains/standard/commands/lookup.ts +0 -14
- 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 -89
- 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 -33
- 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/stories.test.ts +0 -24
- package/src/domains/standard/stories.ts +0 -151
- 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 -9
- 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 -12
- 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/domains/tier/stories.test.ts +0 -22
- package/src/domains/tier/stories.ts +0 -52
|
@@ -5,16 +5,19 @@
|
|
|
5
5
|
* that D3 operations query against.
|
|
6
6
|
*
|
|
7
7
|
* All @prefix declarations derived from {@link TTL_PREFIXES} so that
|
|
8
|
-
* a namespace rename in
|
|
8
|
+
* a namespace rename in DEFAULT_PREFIX_MAP propagates here automatically.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
DEFAULT_PREFIX_MAP,
|
|
13
|
+
TTL_PREFIXES,
|
|
14
|
+
} from "../domains/shared/prefixes.js";
|
|
12
15
|
|
|
13
16
|
/** Turtle @prefix block for ds: only (most data fixtures). */
|
|
14
|
-
const dsPrefix = `@prefix ds: <${
|
|
17
|
+
const dsPrefix = `@prefix ds: <${DEFAULT_PREFIX_MAP.ds}> .`;
|
|
15
18
|
|
|
16
19
|
/** Turtle @prefix block for cs: only (standards fixtures). */
|
|
17
|
-
const csPrefix = `@prefix cs: <${
|
|
20
|
+
const csPrefix = `@prefix cs: <${DEFAULT_PREFIX_MAP.cs}> .`;
|
|
18
21
|
|
|
19
22
|
// =============================================================================
|
|
20
23
|
// Ontology (TBox) — class and property definitions
|
|
@@ -225,6 +228,20 @@ cs:code a owl:DatatypeProperty ;
|
|
|
225
228
|
cs:extends a owl:ObjectProperty ;
|
|
226
229
|
rdfs:domain cs:CodeStandard ;
|
|
227
230
|
rdfs:range cs:CodeStandard .
|
|
231
|
+
|
|
232
|
+
# ---- TBox extras (header, comments, functional typing, SHACL) ----
|
|
233
|
+
|
|
234
|
+
ds:ontology a owl:Ontology ;
|
|
235
|
+
rdfs:label "Design System Ontology" ;
|
|
236
|
+
owl:versionInfo "0.1.0-test" .
|
|
237
|
+
|
|
238
|
+
ds:Component rdfs:comment "A reusable UI building block." .
|
|
239
|
+
|
|
240
|
+
ds:tier a owl:FunctionalProperty .
|
|
241
|
+
|
|
242
|
+
ds:ComponentShape a <http://www.w3.org/ns/shacl#NodeShape> ;
|
|
243
|
+
<http://www.w3.org/ns/shacl#targetClass> ds:Component ;
|
|
244
|
+
<http://www.w3.org/ns/shacl#property> ds:shapeName, ds:shapeTier .
|
|
228
245
|
`;
|
|
229
246
|
|
|
230
247
|
// =============================================================================
|
package/src/testing/index.ts
CHANGED
|
@@ -10,10 +10,7 @@ export {
|
|
|
10
10
|
GRAPHQL_ERROR_TTL,
|
|
11
11
|
GRAPHQL_FATAL_TTL,
|
|
12
12
|
} from "./graphqlFixtures.js";
|
|
13
|
-
export {
|
|
14
|
-
PARITY_GAPS,
|
|
15
|
-
STANDARD_PACK_STORY,
|
|
16
|
-
} from "./standardParityFixtures.js";
|
|
13
|
+
export { PARITY_GAPS } from "./standardParityFixtures.js";
|
|
17
14
|
export type { PragmaTestStoreOptions } from "./store.js";
|
|
18
15
|
export { createTestStore } from "./store.js";
|
|
19
16
|
export {
|
|
@@ -1182,9 +1182,9 @@ No changes were made."
|
|
|
1182
1182
|
exports[`golden: runSetupTask — setups > lsp — dry-run 1`] = `
|
|
1183
1183
|
"Dry run — the following operations would be performed:
|
|
1184
1184
|
|
|
1185
|
-
├─ Info
|
|
1185
|
+
├─ Info Ensuring the Terrazzo LSP VS Code extension is installed...
|
|
1186
1186
|
├─ Execute bunx @canonical/terrazzo-lsp-extension
|
|
1187
|
-
└─ Info ✓ Terrazzo LSP extension installed.
|
|
1187
|
+
└─ Info ✓ Terrazzo LSP extension is installed (up to date).
|
|
1188
1188
|
|
|
1189
1189
|
No changes were made."
|
|
1190
1190
|
`;
|
|
@@ -1193,14 +1193,14 @@ exports[`golden: runSetupTask — setups > lsp — dry-run json 1`] = `
|
|
|
1193
1193
|
"[
|
|
1194
1194
|
{
|
|
1195
1195
|
"action": "Log",
|
|
1196
|
-
"message": "
|
|
1196
|
+
"message": "Ensuring the Terrazzo LSP VS Code extension is installed..."
|
|
1197
1197
|
},
|
|
1198
1198
|
{
|
|
1199
1199
|
"action": "Exec"
|
|
1200
1200
|
},
|
|
1201
1201
|
{
|
|
1202
1202
|
"action": "Log",
|
|
1203
|
-
"message": "✓ Terrazzo LSP extension installed."
|
|
1203
|
+
"message": "✓ Terrazzo LSP extension is installed (up to date)."
|
|
1204
1204
|
}
|
|
1205
1205
|
]
|
|
1206
1206
|
"
|
|
@@ -52,6 +52,30 @@ function parseJson<T>(result: CommandResult): T {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
describe("CLI user stories", () => {
|
|
55
|
+
it("story: a first-time user is greeted once and gets a global config", () => {
|
|
56
|
+
const workspace = createWorkspace();
|
|
57
|
+
const freshXdg = mkdtempSync(join(tmpdir(), "pragma-firstrun-e2e-"));
|
|
58
|
+
tempDirs.add(freshXdg);
|
|
59
|
+
const env = { XDG_CONFIG_HOME: freshXdg };
|
|
60
|
+
|
|
61
|
+
// First invocation: greeting on stderr, config created, stdout untouched.
|
|
62
|
+
const first = runCommand(["info", "--format", "json"], workspace, env);
|
|
63
|
+
expect(first.exitCode).toBe(0);
|
|
64
|
+
expect(first.stderr).toContain("pre-release pragma CLI");
|
|
65
|
+
expect(first.stderr).toContain(join(freshXdg, "pragma", "config.json"));
|
|
66
|
+
expect(() => JSON.parse(first.stdout)).not.toThrow();
|
|
67
|
+
expect(
|
|
68
|
+
JSON.parse(
|
|
69
|
+
readFileSync(join(freshXdg, "pragma", "config.json"), "utf-8"),
|
|
70
|
+
),
|
|
71
|
+
).toEqual({});
|
|
72
|
+
|
|
73
|
+
// Second invocation: no greeting — first-run happens once.
|
|
74
|
+
const second = runCommand(["info", "--format", "json"], workspace, env);
|
|
75
|
+
expect(second.exitCode).toBe(0);
|
|
76
|
+
expect(second.stderr.trim()).toBe("");
|
|
77
|
+
}, 40_000);
|
|
78
|
+
|
|
55
79
|
it("story: a new contributor verifies the local installation with info", () => {
|
|
56
80
|
const workspace = createWorkspace();
|
|
57
81
|
|
|
@@ -195,4 +219,43 @@ describe("CLI user stories", () => {
|
|
|
195
219
|
expect(existsSync(indexFile)).toBe(true);
|
|
196
220
|
expect(readFileSync(indexFile, "utf-8")).toContain("./MySth");
|
|
197
221
|
}, 20_000);
|
|
222
|
+
|
|
223
|
+
it("story: --version works at the root, noun, and verb levels", () => {
|
|
224
|
+
const workspace = createWorkspace();
|
|
225
|
+
const root = runCommand(["--version"], workspace);
|
|
226
|
+
const verb = runCommand(["block", "list", "--version"], workspace);
|
|
227
|
+
|
|
228
|
+
expectSuccess(root);
|
|
229
|
+
expectSuccess(verb);
|
|
230
|
+
expect(root.stdout.trim()).toBe(verb.stdout.trim());
|
|
231
|
+
expect(root.stdout.trim()).toMatch(/^\d+\.\d+\.\d+/);
|
|
232
|
+
}, 20_000);
|
|
233
|
+
|
|
234
|
+
it("story: an unknown verb under a known noun lists that noun's verbs", () => {
|
|
235
|
+
const workspace = createWorkspace();
|
|
236
|
+
|
|
237
|
+
const result = runCommand(["standard", "frobnicate"], workspace);
|
|
238
|
+
|
|
239
|
+
expect(result.exitCode).not.toBe(0);
|
|
240
|
+
// Errors, then defers to the category that exists.
|
|
241
|
+
expect(result.stderr).toContain("unknown command 'frobnicate'");
|
|
242
|
+
expect(result.stderr).toContain("pragma standard <verb>");
|
|
243
|
+
expect(result.stderr).toContain("list");
|
|
244
|
+
expect(result.stderr).toContain("lookup");
|
|
245
|
+
}, 20_000);
|
|
246
|
+
|
|
247
|
+
it("story: a global flag before the noun still lists that noun's verbs", () => {
|
|
248
|
+
const workspace = createWorkspace();
|
|
249
|
+
|
|
250
|
+
// `--format json` sits before the noun; the flag *value* (`json`) must not
|
|
251
|
+
// be mistaken for the noun, or no verbs would be suggested.
|
|
252
|
+
const result = runCommand(
|
|
253
|
+
["--format", "json", "standard", "frobnicate"],
|
|
254
|
+
workspace,
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
expect(result.exitCode).not.toBe(0);
|
|
258
|
+
expect(result.stderr).toContain("pragma standard <verb>");
|
|
259
|
+
expect(result.stderr).toContain("lookup");
|
|
260
|
+
}, 20_000);
|
|
198
261
|
});
|
|
@@ -27,10 +27,10 @@ import {
|
|
|
27
27
|
executeGenerator,
|
|
28
28
|
runGeneratorTask,
|
|
29
29
|
} from "@canonical/cli-core";
|
|
30
|
+
import { generators as componentGenerators } from "@canonical/summon-component";
|
|
30
31
|
import type { GeneratorDefinition } from "@canonical/summon-core";
|
|
31
32
|
import { generators as packageGenerators } from "@canonical/summon-package";
|
|
32
33
|
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
33
|
-
import { COMPONENT_GENERATORS } from "../../domains/create/generators.js";
|
|
34
34
|
|
|
35
35
|
interface Case {
|
|
36
36
|
readonly name: string;
|
|
@@ -41,7 +41,7 @@ interface Case {
|
|
|
41
41
|
const cases: Case[] = [
|
|
42
42
|
{
|
|
43
43
|
name: "component/react",
|
|
44
|
-
gen:
|
|
44
|
+
gen: componentGenerators["component/react"] as GeneratorDefinition,
|
|
45
45
|
answers: { componentPath: "src/components/Button" },
|
|
46
46
|
},
|
|
47
47
|
{
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import type { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
11
11
|
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
|
12
12
|
import type { PragmaRuntime } from "../../domains/shared/runtime.js";
|
|
13
|
+
import { TOKEN_READ_SURFACE_ENABLED } from "../../domains/token/featureFlag.js";
|
|
13
14
|
import createTestMcpClient from "../helpers/createTestMcpClient.js";
|
|
14
15
|
import createTestRuntime from "../helpers/createTestRuntime.js";
|
|
15
16
|
|
|
@@ -122,21 +123,24 @@ describe("all-fail batch lookups", () => {
|
|
|
122
123
|
expect(data.errors[0]?.code).toBe("ENTITY_NOT_FOUND");
|
|
123
124
|
});
|
|
124
125
|
|
|
125
|
-
it(
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
126
|
+
it.skipIf(!TOKEN_READ_SURFACE_ENABLED)(
|
|
127
|
+
"token_lookup: unknown token → error",
|
|
128
|
+
async () => {
|
|
129
|
+
const res = await client.callTool({
|
|
130
|
+
name: "token_lookup",
|
|
131
|
+
arguments: { names: ["color.nonexistent"] },
|
|
132
|
+
});
|
|
133
|
+
const body = parseEnvelope(res);
|
|
134
|
+
expect(body.ok).toBe(true);
|
|
135
|
+
const data = body.data as {
|
|
136
|
+
results: unknown[];
|
|
137
|
+
errors: { query: string; code: string }[];
|
|
138
|
+
};
|
|
139
|
+
expect(data.results).toHaveLength(0);
|
|
140
|
+
expect(data.errors).toHaveLength(1);
|
|
141
|
+
expect(data.errors[0]?.code).toBe("ENTITY_NOT_FOUND");
|
|
142
|
+
},
|
|
143
|
+
);
|
|
140
144
|
});
|
|
141
145
|
|
|
142
146
|
// ---------------------------------------------------------------------------
|
|
@@ -144,33 +148,38 @@ describe("all-fail batch lookups", () => {
|
|
|
144
148
|
// ---------------------------------------------------------------------------
|
|
145
149
|
|
|
146
150
|
describe("empty result sets", () => {
|
|
147
|
-
it("standard_list with nonexistent category →
|
|
151
|
+
it("standard_list with nonexistent category → empty rows", async () => {
|
|
148
152
|
const res = await client.callTool({
|
|
149
153
|
name: "standard_list",
|
|
150
154
|
arguments: { category: "nonexistent_category" },
|
|
151
155
|
});
|
|
152
156
|
const body = parseEnvelope(res);
|
|
153
|
-
//
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
expect(
|
|
157
|
+
// The bundled pack's value-free category filter returns zero rows for
|
|
158
|
+
// an unmatched value; the old EMPTY_RESULTS error is a pinned
|
|
159
|
+
// PARITY_GAP of the standard cutover (packs have no emptyError hook).
|
|
160
|
+
expect(body.ok).toBe(true);
|
|
161
|
+
expect(body.data).toEqual([]);
|
|
162
|
+
expect((body.meta as { count: number }).count).toBe(0);
|
|
157
163
|
});
|
|
158
164
|
|
|
159
|
-
it(
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
165
|
+
it.skipIf(!TOKEN_READ_SURFACE_ENABLED)(
|
|
166
|
+
"token_list with nonexistent category → empty or error",
|
|
167
|
+
async () => {
|
|
168
|
+
const res = await client.callTool({
|
|
169
|
+
name: "token_list",
|
|
170
|
+
arguments: { category: "NonexistentType" },
|
|
171
|
+
});
|
|
172
|
+
const body = parseEnvelope(res);
|
|
173
|
+
if (body.ok) {
|
|
174
|
+
const data = body.data as unknown[];
|
|
175
|
+
expect(data).toHaveLength(0);
|
|
176
|
+
} else {
|
|
177
|
+
// Token list may throw on empty results
|
|
178
|
+
const error = body.error as { code: string };
|
|
179
|
+
expect(error.code).toBeDefined();
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
);
|
|
174
183
|
});
|
|
175
184
|
|
|
176
185
|
// ---------------------------------------------------------------------------
|
|
@@ -245,19 +254,22 @@ describe("condensed mode error rendering", () => {
|
|
|
245
254
|
expect(text).toContain("nonexistent");
|
|
246
255
|
});
|
|
247
256
|
|
|
248
|
-
it(
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
257
|
+
it.skipIf(!TOKEN_READ_SURFACE_ENABLED)(
|
|
258
|
+
"token_lookup condensed: includes error for unknown token",
|
|
259
|
+
async () => {
|
|
260
|
+
const res = await client.callTool({
|
|
261
|
+
name: "token_lookup",
|
|
262
|
+
arguments: {
|
|
263
|
+
names: ["color.primary", "color.nonexistent"],
|
|
264
|
+
condensed: true,
|
|
265
|
+
},
|
|
266
|
+
});
|
|
267
|
+
const body = parseEnvelope(res);
|
|
268
|
+
expect(body.condensed).toBe(true);
|
|
269
|
+
const text = body.text as string;
|
|
270
|
+
expect(text).toContain("color.primary");
|
|
271
|
+
expect(text).toContain("Errors");
|
|
272
|
+
expect(text).toContain("color.nonexistent");
|
|
273
|
+
},
|
|
274
|
+
);
|
|
263
275
|
});
|
|
@@ -20,10 +20,10 @@ import {
|
|
|
20
20
|
import { tmpdir } from "node:os";
|
|
21
21
|
import { join } from "node:path";
|
|
22
22
|
import { runGeneratorTask } from "@canonical/cli-core";
|
|
23
|
+
import { generators as componentGenerators } from "@canonical/summon-component";
|
|
23
24
|
import { generators as packageGenerators } from "@canonical/summon-package";
|
|
24
25
|
import type { Task } from "@canonical/task";
|
|
25
26
|
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
26
|
-
import { COMPONENT_GENERATORS } from "../../domains/create/generators.js";
|
|
27
27
|
import setupMcp from "../../domains/setup/operations/setupMcp.js";
|
|
28
28
|
|
|
29
29
|
interface Case {
|
|
@@ -37,15 +37,17 @@ const packageParams = { name: "@canonical/example", type: "library" };
|
|
|
37
37
|
const cases: Case[] = [
|
|
38
38
|
{
|
|
39
39
|
name: "component/react",
|
|
40
|
-
build: () =>
|
|
40
|
+
build: () =>
|
|
41
|
+
componentGenerators["component/react"].generate(componentParams),
|
|
41
42
|
},
|
|
42
43
|
{
|
|
43
44
|
name: "component/svelte",
|
|
44
|
-
build: () =>
|
|
45
|
+
build: () =>
|
|
46
|
+
componentGenerators["component/svelte"].generate(componentParams),
|
|
45
47
|
},
|
|
46
48
|
{
|
|
47
49
|
name: "component/lit",
|
|
48
|
-
build: () =>
|
|
50
|
+
build: () => componentGenerators["component/lit"].generate(componentParams),
|
|
49
51
|
},
|
|
50
52
|
{
|
|
51
53
|
name: "package/library",
|
|
@@ -16,9 +16,9 @@ import { dirname, resolve } from "node:path";
|
|
|
16
16
|
import { fileURLToPath } from "node:url";
|
|
17
17
|
import type { CommandContext, CommandResult } from "@canonical/cli-core";
|
|
18
18
|
import { executeGenerator } from "@canonical/cli-core";
|
|
19
|
+
import { generators as componentGenerators } from "@canonical/summon-component";
|
|
19
20
|
import { generators as packageGenerators } from "@canonical/summon-package";
|
|
20
21
|
import { describe, expect, it } from "vitest";
|
|
21
|
-
import { COMPONENT_GENERATORS } from "../../domains/create/generators.js";
|
|
22
22
|
import runSetupTask from "../../domains/setup/helpers/runSetupTask.js";
|
|
23
23
|
import setupCompletions from "../../domains/setup/operations/setupCompletions.js";
|
|
24
24
|
import setupLsp from "../../domains/setup/operations/setupLsp.js";
|
|
@@ -65,7 +65,7 @@ const packageParams = { name: "@canonical/example", type: "library" };
|
|
|
65
65
|
|
|
66
66
|
describe("golden: executeGenerator — components", () => {
|
|
67
67
|
for (const framework of ["react", "svelte", "lit"] as const) {
|
|
68
|
-
const gen =
|
|
68
|
+
const gen = componentGenerators[`component/${framework}`];
|
|
69
69
|
|
|
70
70
|
it(`${framework} — dry-run plan`, async () => {
|
|
71
71
|
const result = await executeGenerator(
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import type { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
10
10
|
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
|
11
11
|
import type { PragmaRuntime } from "../../domains/shared/runtime.js";
|
|
12
|
+
import { TOKEN_READ_SURFACE_ENABLED } from "../../domains/token/featureFlag.js";
|
|
12
13
|
import createTestMcpClient from "../helpers/createTestMcpClient.js";
|
|
13
14
|
import createTestRuntime from "../helpers/createTestRuntime.js";
|
|
14
15
|
|
|
@@ -55,7 +56,7 @@ describe("capabilities", () => {
|
|
|
55
56
|
expect(toolNames).toContain("block_list");
|
|
56
57
|
expect(toolNames).toContain("capabilities");
|
|
57
58
|
expect(data.tools.every((t) => t.use_when.length > 0)).toBe(true);
|
|
58
|
-
expect(data.counts.total).toBe(
|
|
59
|
+
expect(data.counts.total).toBe(TOKEN_READ_SURFACE_ENABLED ? 34 : 31);
|
|
59
60
|
expect(data.conventions).toBeDefined();
|
|
60
61
|
expect(data.version).toBeDefined();
|
|
61
62
|
});
|
|
@@ -190,7 +191,11 @@ describe("standard_lookup", () => {
|
|
|
190
191
|
results: { name: string; extends?: string }[];
|
|
191
192
|
};
|
|
192
193
|
expect(data.results[0]?.name).toBe("react/component/props");
|
|
193
|
-
|
|
194
|
+
// Pack entities keep cs:extends as the raw IRI in data (compaction is
|
|
195
|
+
// display-time only) — a pinned PARITY_GAP of the standard cutover.
|
|
196
|
+
expect(data.results[0]?.extends).toBe(
|
|
197
|
+
"http://pragma.canonical.com/codestandards#react_folder",
|
|
198
|
+
);
|
|
194
199
|
});
|
|
195
200
|
});
|
|
196
201
|
|
|
@@ -240,7 +245,7 @@ describe("modifier_lookup", () => {
|
|
|
240
245
|
// Token
|
|
241
246
|
// ---------------------------------------------------------------------------
|
|
242
247
|
|
|
243
|
-
describe("token_list", () => {
|
|
248
|
+
describe.skipIf(!TOKEN_READ_SURFACE_ENABLED)("token_list", () => {
|
|
244
249
|
it("returns tokens", async () => {
|
|
245
250
|
const res = await client.callTool({
|
|
246
251
|
name: "token_list",
|
|
@@ -252,7 +257,7 @@ describe("token_list", () => {
|
|
|
252
257
|
});
|
|
253
258
|
});
|
|
254
259
|
|
|
255
|
-
describe("token_lookup", () => {
|
|
260
|
+
describe.skipIf(!TOKEN_READ_SURFACE_ENABLED)("token_lookup", () => {
|
|
256
261
|
it("returns token with values", async () => {
|
|
257
262
|
const res = await client.callTool({
|
|
258
263
|
name: "token_lookup",
|
|
@@ -273,15 +278,16 @@ describe("token_lookup", () => {
|
|
|
273
278
|
// ---------------------------------------------------------------------------
|
|
274
279
|
|
|
275
280
|
describe("tier_list", () => {
|
|
276
|
-
it("returns tiers
|
|
281
|
+
it("returns the tiers (bundled pack)", async () => {
|
|
277
282
|
const res = await client.callTool({
|
|
278
283
|
name: "tier_list",
|
|
279
284
|
arguments: {},
|
|
280
285
|
});
|
|
281
286
|
const body = parseEnvelope(res);
|
|
282
287
|
expect(body.ok).toBe(true);
|
|
283
|
-
|
|
284
|
-
|
|
288
|
+
// Bundled tier pack: uniform `{uri, name}` rows (no bespoke hierarchy).
|
|
289
|
+
const data = body.data as { name: string }[];
|
|
290
|
+
expect(data.some((t) => t.name === "global")).toBe(true);
|
|
285
291
|
});
|
|
286
292
|
});
|
|
287
293
|
|
|
@@ -480,15 +486,34 @@ describe("disclosure", () => {
|
|
|
480
486
|
expect(meta.disclosure).toBe("digest");
|
|
481
487
|
});
|
|
482
488
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
489
|
+
// `standard list --detailed` was retired with the standard cutover (a
|
|
490
|
+
// pinned PARITY_GAP: pack lists are single-level); per-entity disclosure
|
|
491
|
+
// now lives on the lookup's `detail` parameter and its legacy aliases.
|
|
492
|
+
it("standard_lookup honors the detail parameter", async () => {
|
|
493
|
+
const summary = await client.callTool({
|
|
494
|
+
name: "standard_lookup",
|
|
495
|
+
arguments: {
|
|
496
|
+
names: ["react/component/folder-structure"],
|
|
497
|
+
detail: "summary",
|
|
498
|
+
},
|
|
487
499
|
});
|
|
488
|
-
const
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
expect(
|
|
500
|
+
const summaryData = parseEnvelope(summary).data as {
|
|
501
|
+
results: Record<string, unknown>[];
|
|
502
|
+
};
|
|
503
|
+
expect(summaryData.results[0]).not.toHaveProperty("dos");
|
|
504
|
+
|
|
505
|
+
const detailed = await client.callTool({
|
|
506
|
+
name: "standard_lookup",
|
|
507
|
+
arguments: {
|
|
508
|
+
names: ["react/component/folder-structure"],
|
|
509
|
+
detail: "detailed",
|
|
510
|
+
},
|
|
511
|
+
});
|
|
512
|
+
const detailedData = parseEnvelope(detailed).data as {
|
|
513
|
+
results: Record<string, unknown>[];
|
|
514
|
+
};
|
|
515
|
+
expect(detailedData.results[0]).toHaveProperty("dos");
|
|
516
|
+
expect(detailedData.results[0]).toHaveProperty("donts");
|
|
492
517
|
});
|
|
493
518
|
});
|
|
494
519
|
|