@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
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standard read stories — the single declaration of `standard list` and
|
|
3
|
+
* `standard lookup` for both surfaces.
|
|
4
|
+
*
|
|
5
|
+
* The story kernel compiles these into the CLI commands and MCP tools,
|
|
6
|
+
* so descriptions, parameters, resolution, and rendering live here once.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { createListView, createLookupView } from "#tui";
|
|
10
|
+
import type { LookupStory, ReadStory } from "../shared/stories/index.js";
|
|
11
|
+
import type { StandardDetailed } from "../shared/types/index.js";
|
|
12
|
+
import {
|
|
13
|
+
createInkLookupOptions,
|
|
14
|
+
listFormatters,
|
|
15
|
+
lookupFormatters,
|
|
16
|
+
type StandardListOutput,
|
|
17
|
+
type StandardLookupInput,
|
|
18
|
+
} from "./formatters/index.js";
|
|
19
|
+
import {
|
|
20
|
+
resolveStandardList,
|
|
21
|
+
resolveStandardLookup,
|
|
22
|
+
} from "./orchestration/index.js";
|
|
23
|
+
import { standardConfig } from "./standardConfig.js";
|
|
24
|
+
import type { StandardListResolution } from "./types.js";
|
|
25
|
+
|
|
26
|
+
/** The `standard list` / `standard_list` read story. */
|
|
27
|
+
export const standardListStory: ReadStory<
|
|
28
|
+
StandardListResolution,
|
|
29
|
+
StandardListOutput
|
|
30
|
+
> = {
|
|
31
|
+
noun: "standard",
|
|
32
|
+
verb: "list",
|
|
33
|
+
description: "List all code standards",
|
|
34
|
+
toolDescription:
|
|
35
|
+
"List code standards. Optionally filter by category or search term. Use digest/detailed for progressive disclosure.",
|
|
36
|
+
params: [
|
|
37
|
+
{
|
|
38
|
+
name: "category",
|
|
39
|
+
type: "string",
|
|
40
|
+
description: "Filter by category",
|
|
41
|
+
toolDescription: "Filter by category name",
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: "search",
|
|
45
|
+
type: "string",
|
|
46
|
+
description: "Search in name and description",
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: "digest",
|
|
50
|
+
type: "boolean",
|
|
51
|
+
description: "Show description and first example for each standard",
|
|
52
|
+
default: false,
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: "detailed",
|
|
56
|
+
type: "boolean",
|
|
57
|
+
description: "Show full dos/donts for each standard",
|
|
58
|
+
default: false,
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
examples: [
|
|
62
|
+
"pragma standard list",
|
|
63
|
+
"pragma standard list --category react",
|
|
64
|
+
'pragma standard list --search "folder"',
|
|
65
|
+
"pragma standard list --digest",
|
|
66
|
+
"pragma standard list --detailed",
|
|
67
|
+
"pragma standard list --llm",
|
|
68
|
+
],
|
|
69
|
+
resolve: (rt, params) =>
|
|
70
|
+
resolveStandardList(rt, {
|
|
71
|
+
category: params.category as string | undefined,
|
|
72
|
+
search: params.search as string | undefined,
|
|
73
|
+
digest: params.digest === true,
|
|
74
|
+
detailed: params.detailed === true,
|
|
75
|
+
}),
|
|
76
|
+
toOutput: (resolution) => ({
|
|
77
|
+
items: resolution.items,
|
|
78
|
+
details: resolution.details,
|
|
79
|
+
disclosure: resolution.disclosure,
|
|
80
|
+
}),
|
|
81
|
+
formatters: listFormatters,
|
|
82
|
+
toEnvelope: (resolution) => {
|
|
83
|
+
if (resolution.disclosure.level === "summary") {
|
|
84
|
+
return {
|
|
85
|
+
data: resolution.items,
|
|
86
|
+
meta: { count: resolution.items.length },
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
const output: StandardListOutput = {
|
|
90
|
+
items: resolution.items,
|
|
91
|
+
details: resolution.details,
|
|
92
|
+
disclosure: resolution.disclosure,
|
|
93
|
+
};
|
|
94
|
+
return {
|
|
95
|
+
data: JSON.parse(listFormatters.json(output)),
|
|
96
|
+
meta: {
|
|
97
|
+
count: resolution.items.length,
|
|
98
|
+
disclosure: resolution.disclosure.level,
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
},
|
|
102
|
+
renderInk: (output) =>
|
|
103
|
+
createListView({
|
|
104
|
+
heading: "Standards",
|
|
105
|
+
domain: "standard",
|
|
106
|
+
items: output.items,
|
|
107
|
+
columns: standardConfig.listColumns,
|
|
108
|
+
}),
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
/** The `standard lookup` / `standard_lookup` read story. */
|
|
112
|
+
export const standardLookupStory: LookupStory<
|
|
113
|
+
StandardDetailed,
|
|
114
|
+
StandardLookupInput
|
|
115
|
+
> = {
|
|
116
|
+
noun: "standard",
|
|
117
|
+
description: "Look up detailed information for a standard by name or IRI",
|
|
118
|
+
toolDescription:
|
|
119
|
+
"Get detailed information about one or more code standards including dos and donts with code examples.",
|
|
120
|
+
namesDescription: "Standard names or IRIs",
|
|
121
|
+
namesToolDescription: "Standard names or IRIs to look up",
|
|
122
|
+
detailedParam: {
|
|
123
|
+
description: "Include dos and donts with code blocks",
|
|
124
|
+
toolDescription:
|
|
125
|
+
"Return full details with dos/donts (default: true for MCP)",
|
|
126
|
+
},
|
|
127
|
+
examples: [
|
|
128
|
+
"pragma standard lookup react/component/folder-structure",
|
|
129
|
+
"pragma standard lookup react/component/folder-structure react/component/props",
|
|
130
|
+
"pragma standard lookup react/component/folder-structure --detailed",
|
|
131
|
+
"pragma standard lookup react/component/folder-structure --llm",
|
|
132
|
+
"pragma standard lookup cs:react_props",
|
|
133
|
+
],
|
|
134
|
+
resolve: async (rt, names) => {
|
|
135
|
+
const contract = await resolveStandardLookup(rt.store, names);
|
|
136
|
+
return contract.result;
|
|
137
|
+
},
|
|
138
|
+
toFmtInput: (standard, view) => ({ standard, detailed: view.detailed }),
|
|
139
|
+
formatters: lookupFormatters,
|
|
140
|
+
project: (standard) => {
|
|
141
|
+
const { uri, name, category, description } = standard;
|
|
142
|
+
return { uri, name, category, description };
|
|
143
|
+
},
|
|
144
|
+
renderInk: (result, view) =>
|
|
145
|
+
createLookupView({
|
|
146
|
+
results: result.results,
|
|
147
|
+
errors: result.errors,
|
|
148
|
+
domain: "standard",
|
|
149
|
+
options: createInkLookupOptions(view.detailed),
|
|
150
|
+
}),
|
|
151
|
+
};
|
|
@@ -1,59 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
* Wires the `pragma tier list` CLI command.
|
|
3
|
-
*
|
|
4
|
-
* Lists all tiers defined in the design system ontology. Throws a
|
|
5
|
-
* structured recovery error when no tiers are found.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
type CommandDefinition,
|
|
10
|
-
createOutputResult,
|
|
11
|
-
} from "@canonical/cli-core";
|
|
12
|
-
import { PragmaError } from "#error";
|
|
13
|
-
import { createListView } from "#tui";
|
|
1
|
+
import type { CommandDefinition } from "@canonical/cli-core";
|
|
14
2
|
import type { PragmaContext } from "../../shared/context.js";
|
|
15
|
-
import
|
|
16
|
-
import {
|
|
17
|
-
import type { TierEntry } from "../../shared/types/tier.js";
|
|
18
|
-
import { listFormatters } from "../formatters/index.js";
|
|
19
|
-
import { listTiers } from "../operations/index.js";
|
|
20
|
-
|
|
21
|
-
const tierListColumns: readonly ColumnDef<TierEntry>[] = [
|
|
22
|
-
{ key: "uri", label: "IRI" },
|
|
23
|
-
{ key: "path", label: "Path" },
|
|
24
|
-
{ key: "parent", label: "Parent" },
|
|
25
|
-
];
|
|
3
|
+
import { compileReadCommand } from "../../shared/stories/index.js";
|
|
4
|
+
import { tierListStory } from "../stories.js";
|
|
26
5
|
|
|
6
|
+
/** Wire the `pragma tier list` CLI command from the tier list story. */
|
|
27
7
|
export default function listCommand(ctx: PragmaContext): CommandDefinition {
|
|
28
|
-
return
|
|
29
|
-
path: ["tier", "list"],
|
|
30
|
-
description: "List all tiers in the design system ontology",
|
|
31
|
-
parameters: [],
|
|
32
|
-
meta: {
|
|
33
|
-
examples: ["pragma tier list", "pragma tier list --llm"],
|
|
34
|
-
},
|
|
35
|
-
async execute() {
|
|
36
|
-
const tiers = await listTiers(ctx.store);
|
|
37
|
-
|
|
38
|
-
if (tiers.length === 0) {
|
|
39
|
-
throw PragmaError.emptyResults("tier", {
|
|
40
|
-
recovery: {
|
|
41
|
-
message:
|
|
42
|
-
"Ensure design system packages are installed: bun add -D @canonical/ds-global",
|
|
43
|
-
},
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return createOutputResult(tiers, {
|
|
48
|
-
plain: selectFormatter(ctx, listFormatters),
|
|
49
|
-
ink: (data) =>
|
|
50
|
-
createListView({
|
|
51
|
-
heading: "Tiers",
|
|
52
|
-
domain: "tier",
|
|
53
|
-
items: data,
|
|
54
|
-
columns: tierListColumns,
|
|
55
|
-
}),
|
|
56
|
-
});
|
|
57
|
-
},
|
|
58
|
-
};
|
|
8
|
+
return compileReadCommand(ctx, tierListStory);
|
|
59
9
|
}
|
|
@@ -1,38 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* MCP tool specs for the tier domain
|
|
2
|
+
* MCP tool specs for the tier domain — tier_list, compiled from the tier
|
|
3
|
+
* read story in `../stories.ts`.
|
|
3
4
|
*/
|
|
4
5
|
|
|
6
|
+
import { compileReadTool } from "../../shared/stories/index.js";
|
|
5
7
|
import type { ToolSpec } from "../../shared/ToolSpec.js";
|
|
6
|
-
import {
|
|
7
|
-
import { listTiers } from "../operations/index.js";
|
|
8
|
+
import { tierListStory } from "../stories.js";
|
|
8
9
|
|
|
9
|
-
const specs: readonly ToolSpec[] = [
|
|
10
|
-
{
|
|
11
|
-
name: "tier_list",
|
|
12
|
-
description: "List all tiers in the design system ontology with hierarchy.",
|
|
13
|
-
params: {
|
|
14
|
-
condensed: {
|
|
15
|
-
type: "boolean",
|
|
16
|
-
description: "Token-optimized output",
|
|
17
|
-
optional: true,
|
|
18
|
-
},
|
|
19
|
-
},
|
|
20
|
-
readOnly: true,
|
|
21
|
-
async execute(rt, { condensed }) {
|
|
22
|
-
const result = await listTiers(rt.store);
|
|
23
|
-
|
|
24
|
-
if (condensed) {
|
|
25
|
-
const text = tierListFmt.llm(result);
|
|
26
|
-
return {
|
|
27
|
-
condensed: true,
|
|
28
|
-
text,
|
|
29
|
-
tokens: `~${Math.ceil(text.length / 4)}`,
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return { data: result, meta: { count: result.length } };
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
];
|
|
10
|
+
const specs: readonly ToolSpec[] = [compileReadTool(tierListStory)];
|
|
37
11
|
|
|
38
12
|
export default specs;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { URI } from "@canonical/ke";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
import { tierListStory } from "./stories.js";
|
|
4
|
+
|
|
5
|
+
const tier = {
|
|
6
|
+
uri: "https://ds.example/global" as URI,
|
|
7
|
+
path: "global",
|
|
8
|
+
depth: 0,
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
describe("tierListStory", () => {
|
|
12
|
+
it("renders the ink list view", () => {
|
|
13
|
+
const view = tierListStory.renderInk?.([tier]);
|
|
14
|
+
expect(typeof view).toBe("string");
|
|
15
|
+
expect(view).toContain("Tiers");
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("rejects only empty results", () => {
|
|
19
|
+
expect(tierListStory.emptyError?.([], {})).toBeDefined();
|
|
20
|
+
expect(tierListStory.emptyError?.([tier], {})).toBeUndefined();
|
|
21
|
+
});
|
|
22
|
+
});
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tier read story — the single declaration of `tier list` for both
|
|
3
|
+
* surfaces.
|
|
4
|
+
*
|
|
5
|
+
* The story kernel compiles this into the CLI command and MCP tool,
|
|
6
|
+
* so description, resolution, and rendering live here once.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { PragmaError } from "#error";
|
|
10
|
+
import { createListView } from "#tui";
|
|
11
|
+
import type { ColumnDef } from "../shared/contracts.js";
|
|
12
|
+
import type { ReadStory } from "../shared/stories/index.js";
|
|
13
|
+
import type { TierEntry } from "../shared/types/index.js";
|
|
14
|
+
import { listFormatters } from "./formatters/index.js";
|
|
15
|
+
import { listTiers } from "./operations/index.js";
|
|
16
|
+
|
|
17
|
+
const tierListColumns: readonly ColumnDef<TierEntry>[] = [
|
|
18
|
+
{ key: "uri", label: "IRI" },
|
|
19
|
+
{ key: "path", label: "Path" },
|
|
20
|
+
{ key: "parent", label: "Parent" },
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
/** The `tier list` / `tier_list` read story. */
|
|
24
|
+
export const tierListStory: ReadStory<TierEntry[], TierEntry[]> = {
|
|
25
|
+
noun: "tier",
|
|
26
|
+
verb: "list",
|
|
27
|
+
description: "List all tiers in the design system ontology",
|
|
28
|
+
toolDescription:
|
|
29
|
+
"List all tiers in the design system ontology with hierarchy.",
|
|
30
|
+
params: [],
|
|
31
|
+
examples: ["pragma tier list", "pragma tier list --llm"],
|
|
32
|
+
resolve: (rt) => listTiers(rt.store),
|
|
33
|
+
toOutput: (tiers) => tiers,
|
|
34
|
+
formatters: listFormatters,
|
|
35
|
+
toEnvelope: (tiers) => ({ data: tiers, meta: { count: tiers.length } }),
|
|
36
|
+
emptyError: (tiers) =>
|
|
37
|
+
tiers.length === 0
|
|
38
|
+
? PragmaError.emptyResults("tier", {
|
|
39
|
+
recovery: {
|
|
40
|
+
message:
|
|
41
|
+
"Ensure semantic packages are resolvable — run `pragma doctor` to inspect package refs.",
|
|
42
|
+
},
|
|
43
|
+
})
|
|
44
|
+
: undefined,
|
|
45
|
+
renderInk: (tiers) =>
|
|
46
|
+
createListView({
|
|
47
|
+
heading: "Tiers",
|
|
48
|
+
domain: "tier",
|
|
49
|
+
items: tiers,
|
|
50
|
+
columns: tierListColumns,
|
|
51
|
+
}),
|
|
52
|
+
};
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { writeFileSync } from "node:fs";
|
|
9
9
|
import { PragmaError } from "#error";
|
|
10
|
+
import { lookupToolMeta } from "../../shared/lookupMany.js";
|
|
10
11
|
import type { ToolSpec } from "../../shared/ToolSpec.js";
|
|
11
12
|
import {
|
|
12
13
|
createLookupFormatters as createTokenLookupFmt,
|
|
@@ -101,7 +102,10 @@ const specs: readonly ToolSpec[] = [
|
|
|
101
102
|
};
|
|
102
103
|
}
|
|
103
104
|
|
|
104
|
-
return {
|
|
105
|
+
return {
|
|
106
|
+
data: { results: result.results, errors: result.errors },
|
|
107
|
+
meta: lookupToolMeta(result),
|
|
108
|
+
};
|
|
105
109
|
},
|
|
106
110
|
},
|
|
107
111
|
|
|
@@ -18,11 +18,12 @@ export default async function resolveTokenLookup(
|
|
|
18
18
|
const lookupResult: LookupResult<TokenDetailed> =
|
|
19
19
|
names.length > 0
|
|
20
20
|
? await lookupMany(names, (query) => lookupToken(store, query))
|
|
21
|
-
: { results: [], errors: [] };
|
|
21
|
+
: { results: [], errors: [], meta: { internalErrorCount: 0 } };
|
|
22
22
|
|
|
23
23
|
const result: LookupResult<TokenDetailed> = {
|
|
24
24
|
results: lookupResult.results,
|
|
25
25
|
errors: [...lookupResult.errors, ...globErrors],
|
|
26
|
+
meta: lookupResult.meta ?? { internalErrorCount: 0 },
|
|
26
27
|
};
|
|
27
28
|
|
|
28
29
|
return {
|
|
@@ -152,7 +152,7 @@ describe("createTracePlugin", () => {
|
|
|
152
152
|
|
|
153
153
|
// bindings should be at most 2 (may be 0 with empty store)
|
|
154
154
|
expect(record.bindings).toBeDefined();
|
|
155
|
-
expect(record.bindings
|
|
155
|
+
expect(record.bindings?.length).toBeLessThanOrEqual(2);
|
|
156
156
|
});
|
|
157
157
|
|
|
158
158
|
it("generates a session ID when not provided", async () => {
|