@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
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ See [docs/getting-started.md](docs/getting-started.md) for a full walkthrough.
|
|
|
22
22
|
|
|
23
23
|
## CLI Commands
|
|
24
24
|
|
|
25
|
-
pragma organizes commands into 17 domains — counting every directory under `src/domains/` except `shared/`, which holds cross-domain infrastructure rather than commands. The
|
|
25
|
+
pragma organizes commands into 17 domains — counting every directory under `src/domains/` except `shared/`, which holds cross-domain infrastructure rather than commands. The day-to-day domains are documented below; two are specialised and not covered here: `graphql` (compile TTL ontologies into GraphQL schema artifacts) and `trace` (query access tracing). Every command supports three output modes: plain text (default), `--llm` (condensed Markdown), and `--format json` (structured JSON).
|
|
26
26
|
|
|
27
27
|
### Block
|
|
28
28
|
|
|
@@ -36,7 +36,7 @@ pragma organizes commands into 17 domains — counting every directory under `sr
|
|
|
36
36
|
| Command | Description |
|
|
37
37
|
|---------|-------------|
|
|
38
38
|
| `pragma standard list` | List all code standards |
|
|
39
|
-
| `pragma standard lookup <name>` | Show standard
|
|
39
|
+
| `pragma standard lookup <name>` | Show standard details (`--detailed` adds do/don't examples) |
|
|
40
40
|
| `pragma standard categories` | List standard categories with counts |
|
|
41
41
|
|
|
42
42
|
### Modifier
|
|
@@ -46,13 +46,17 @@ pragma organizes commands into 17 domains — counting every directory under `sr
|
|
|
46
46
|
| `pragma modifier list` | List all modifier families |
|
|
47
47
|
| `pragma modifier lookup <name>` | Show modifier family with values |
|
|
48
48
|
|
|
49
|
-
###
|
|
49
|
+
### Tokens
|
|
50
50
|
|
|
51
51
|
| Command | Description |
|
|
52
52
|
|---------|-------------|
|
|
53
|
-
| `pragma
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
| `pragma tokens add-config` | Add Terrazzo config for token build |
|
|
54
|
+
|
|
55
|
+
> **Note:** The token *read* commands (`token list`, `token lookup`, `token sample`)
|
|
56
|
+
> are currently disabled behind a feature flag
|
|
57
|
+
> (`src/domains/token/featureFlag.ts`) because the published design-system
|
|
58
|
+
> data does not yet contain token instances. They will return once token
|
|
59
|
+
> data ships.
|
|
56
60
|
|
|
57
61
|
### Tier
|
|
58
62
|
|
|
@@ -65,7 +69,10 @@ pragma organizes commands into 17 domains — counting every directory under `sr
|
|
|
65
69
|
| Command | Description |
|
|
66
70
|
|---------|-------------|
|
|
67
71
|
| `pragma ontology list` | List loaded ontology namespaces |
|
|
68
|
-
| `pragma ontology show <prefix>` | Show
|
|
72
|
+
| `pragma ontology show <prefix>` | Show the TBox: name, metadata, class hierarchy tree with instance counts and relations |
|
|
73
|
+
| `pragma ontology show <prefix> --properties` | Also show datatype properties (attributes) |
|
|
74
|
+
| `pragma ontology show <prefix> --full-uris` | Show full URIs instead of compact prefixed IRIs |
|
|
75
|
+
| `pragma ontology show <prefix> --class <Class>` | Deep-dive into one class: super chain, direct/inherited properties, reverse references, sample instances, and ready-to-run follow-up queries |
|
|
69
76
|
|
|
70
77
|
### Graph
|
|
71
78
|
|
|
@@ -97,15 +104,16 @@ pragma organizes commands into 17 domains — counting every directory under `sr
|
|
|
97
104
|
|
|
98
105
|
### Setup
|
|
99
106
|
|
|
100
|
-
All setup commands support `--dry-run
|
|
107
|
+
All setup commands support `--dry-run`; `--yes` and `--undo` are supported
|
|
108
|
+
where shown below.
|
|
101
109
|
|
|
102
110
|
| Command | Description |
|
|
103
111
|
|---------|-------------|
|
|
104
|
-
| `pragma setup
|
|
105
|
-
| `pragma setup mcp` | Configure pragma MCP server for AI harnesses |
|
|
106
|
-
| `pragma setup completions` | Install shell completions (bash/zsh/fish) |
|
|
107
|
-
| `pragma setup skills` | Symlink agent skills into harness config |
|
|
108
|
-
| `pragma setup lsp` |
|
|
112
|
+
| `pragma setup` | Run all setup steps (completions + LSP + MCP); supports `--yes`, `--undo` |
|
|
113
|
+
| `pragma setup mcp` | Configure pragma MCP server for AI harnesses; supports `--yes`, `--undo` |
|
|
114
|
+
| `pragma setup completions` | Install shell completions (bash/zsh/fish); supports `--undo` |
|
|
115
|
+
| `pragma setup skills` | Symlink agent skills into harness config; supports `--yes` |
|
|
116
|
+
| `pragma setup lsp` | Install the Terrazzo LSP VS Code extension; supports `--undo` |
|
|
109
117
|
|
|
110
118
|
### Create
|
|
111
119
|
|
|
@@ -113,8 +121,9 @@ Create commands scaffold new code using summon generators. They support `--undo`
|
|
|
113
121
|
|
|
114
122
|
| Command | Description |
|
|
115
123
|
|---------|-------------|
|
|
116
|
-
| `pragma create component <
|
|
117
|
-
| `pragma create package
|
|
124
|
+
| `pragma create component <framework> [path]` | Scaffold a new design system component |
|
|
125
|
+
| `pragma create package` | Scaffold a new monorepo package (`--name`, `--type`, …) |
|
|
126
|
+
| `pragma create application [path]` | Scaffold a complete React application with SSR and routing |
|
|
118
127
|
|
|
119
128
|
### Doctor
|
|
120
129
|
|
|
@@ -126,8 +135,19 @@ Create commands scaffold new code using summon generators. They support `--undo`
|
|
|
126
135
|
|
|
127
136
|
| Command | Description |
|
|
128
137
|
|---------|-------------|
|
|
129
|
-
| `pragma info` | Show pragma version,
|
|
130
|
-
|
|
138
|
+
| `pragma info` | Show pragma version, config, update status, and store summary |
|
|
139
|
+
|
|
140
|
+
### Upgrade
|
|
141
|
+
|
|
142
|
+
| Command | Description |
|
|
143
|
+
|---------|-------------|
|
|
144
|
+
| `pragma upgrade` | Upgrade the pragma CLI to the latest version (`--dry-run` to check only) |
|
|
145
|
+
|
|
146
|
+
### Refs
|
|
147
|
+
|
|
148
|
+
| Command | Description |
|
|
149
|
+
|---------|-------------|
|
|
150
|
+
| `pragma update-refs` | Fetch or clone git-referenced semantic packages into the local cache (needed before `skill list` can discover skills) |
|
|
131
151
|
|
|
132
152
|
## Global Flags
|
|
133
153
|
|
|
@@ -144,7 +164,7 @@ Setup and create commands support `--undo` to reverse previous operations. The u
|
|
|
144
164
|
```bash
|
|
145
165
|
pragma setup mcp --undo # Remove MCP configuration
|
|
146
166
|
pragma setup completions --undo # Remove shell completions
|
|
147
|
-
pragma create component Foo --undo # Remove scaffolded component files
|
|
167
|
+
pragma create component react src/lib/Foo --undo # Remove scaffolded component files
|
|
148
168
|
```
|
|
149
169
|
|
|
150
170
|
## MCP Integration
|
|
@@ -174,27 +194,27 @@ Or add manually to your `.mcp.json`:
|
|
|
174
194
|
}
|
|
175
195
|
```
|
|
176
196
|
|
|
177
|
-
### MCP Tools (
|
|
197
|
+
### MCP Tools (28)
|
|
178
198
|
|
|
179
199
|
All tools return a consistent envelope: `{ ok: true, data, meta }` for success, `{ ok: true, condensed: true, text, tokens }` for condensed mode, or `{ ok: false, error }` with structured recovery on failure.
|
|
180
200
|
|
|
181
|
-
#### Read Tools (
|
|
201
|
+
#### Read Tools (18)
|
|
202
|
+
|
|
203
|
+
Lookup tools accept a `names` array, so several entities can be fetched in
|
|
204
|
+
one call (partial results are returned alongside per-name errors).
|
|
182
205
|
|
|
183
206
|
| Tool | Description |
|
|
184
207
|
|------|-------------|
|
|
185
208
|
| `block_list` | List blocks with optional tier filtering and disclosure levels |
|
|
186
209
|
| `block_lookup` | Look up detailed block info (anatomy, modifiers, tokens, standards) |
|
|
187
|
-
| `
|
|
210
|
+
| `block_sample` | Return random complete block instances for shape discovery |
|
|
188
211
|
| `standard_list` | List code standards with optional category/search filtering |
|
|
189
212
|
| `standard_lookup` | Look up standard with do/don't code examples |
|
|
190
|
-
| `standard_batch_lookup` | Look up multiple standards by name in a single call |
|
|
191
213
|
| `standard_categories` | List standard categories with counts |
|
|
214
|
+
| `standard_sample` | Return random complete standard instances for shape discovery |
|
|
192
215
|
| `modifier_list` | List modifier families |
|
|
193
216
|
| `modifier_lookup` | Look up modifier family with values |
|
|
194
|
-
| `
|
|
195
|
-
| `token_list` | List design tokens with optional category filtering |
|
|
196
|
-
| `token_lookup` | Look up token with theme-resolved values |
|
|
197
|
-
| `token_batch_lookup` | Look up multiple tokens by name in a single call |
|
|
217
|
+
| `modifier_sample` | Return random complete modifier instances for shape discovery |
|
|
198
218
|
| `tier_list` | List all tiers in the hierarchy |
|
|
199
219
|
| `config_show` | Show current tier and channel configuration |
|
|
200
220
|
| `ontology_list` | List loaded ontology namespaces with class/property counts |
|
|
@@ -204,7 +224,10 @@ All tools return a consistent envelope: `{ ok: true, data, meta }` for success,
|
|
|
204
224
|
| `skill_list` | List discovered agent skills |
|
|
205
225
|
| `skill_lookup` | Get full SKILL.md content for skills by name |
|
|
206
226
|
|
|
207
|
-
|
|
227
|
+
`token_list`, `token_lookup`, and `token_sample` are feature-flagged off
|
|
228
|
+
until token data ships (see the Tokens note above).
|
|
229
|
+
|
|
230
|
+
#### Write Tools (6)
|
|
208
231
|
|
|
209
232
|
| Tool | Description |
|
|
210
233
|
|------|-------------|
|
|
@@ -213,6 +236,7 @@ All tools return a consistent envelope: `{ ok: true, data, meta }` for success,
|
|
|
213
236
|
| `tokens_add_config` | Add Terrazzo token build configuration |
|
|
214
237
|
| `create_component` | Scaffold a new design system component |
|
|
215
238
|
| `create_package` | Scaffold a new monorepo package |
|
|
239
|
+
| `create_application` | Scaffold a complete React application |
|
|
216
240
|
|
|
217
241
|
#### Orientation Tools (2)
|
|
218
242
|
|
|
@@ -282,12 +306,12 @@ Error responses include a `recovery` object that tells agents what tool to call
|
|
|
282
306
|
|
|
283
307
|
### Batch Results
|
|
284
308
|
|
|
285
|
-
|
|
309
|
+
Lookup tools accept a `names` array and return partial results — valid items in `results`, failures in `errors`:
|
|
286
310
|
|
|
287
311
|
```json
|
|
288
312
|
{
|
|
289
313
|
"results": [{ "name": "Button", ... }],
|
|
290
|
-
"errors": [{ "
|
|
314
|
+
"errors": [{ "query": "Buton", "code": "ENTITY_NOT_FOUND", "message": "...", "suggestions": ["Button"] }]
|
|
291
315
|
}
|
|
292
316
|
```
|
|
293
317
|
|
|
@@ -358,16 +382,21 @@ format is experimental and may change.
|
|
|
358
382
|
|
|
359
383
|
## Error Handling
|
|
360
384
|
|
|
361
|
-
|
|
385
|
+
Lookup errors report each failed name with typo suggestions:
|
|
362
386
|
|
|
363
387
|
```
|
|
364
|
-
|
|
388
|
+
**Errors:**
|
|
389
|
+
- Buton: block "Buton" not found.
|
|
390
|
+
Did you mean: Button?
|
|
391
|
+
```
|
|
365
392
|
|
|
366
|
-
|
|
367
|
-
- Button
|
|
368
|
-
- ButtonGroup
|
|
393
|
+
Other errors carry a code and, where available, a recovery hint:
|
|
369
394
|
|
|
370
|
-
|
|
395
|
+
```
|
|
396
|
+
## Error: EMPTY_RESULTS
|
|
397
|
+
No standards found.
|
|
398
|
+
Filters: category=nope
|
|
399
|
+
Recovery: `pragma standard list`
|
|
371
400
|
```
|
|
372
401
|
|
|
373
402
|
With `--format json`, errors are returned as structured JSON with error code, suggestions, and recovery. With `--llm`, errors are rendered as Markdown.
|
package/dist/pragma
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonical/pragma-cli",
|
|
3
3
|
"description": "CLI and MCP server for Canonical's design system.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.31.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "src/index.ts",
|
|
7
7
|
"types": "src/index.ts",
|
|
@@ -60,9 +60,9 @@
|
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@biomejs/biome": "2.4.9",
|
|
63
|
-
"@canonical/biome-config": "^0.
|
|
64
|
-
"@canonical/typescript-config": "^0.
|
|
65
|
-
"@canonical/webarchitect": "^0.
|
|
63
|
+
"@canonical/biome-config": "^0.31.0",
|
|
64
|
+
"@canonical/typescript-config": "^0.31.0",
|
|
65
|
+
"@canonical/webarchitect": "^0.31.0",
|
|
66
66
|
"@types/bun": "^1.3.10",
|
|
67
67
|
"@types/node": "^24.12.0",
|
|
68
68
|
"@types/react": "^19.2.14",
|
|
@@ -72,16 +72,18 @@
|
|
|
72
72
|
},
|
|
73
73
|
"dependencies": {
|
|
74
74
|
"@canonical/anatomy-dsl": "^0.2.2",
|
|
75
|
-
"@canonical/cli-core": "^0.
|
|
75
|
+
"@canonical/cli-core": "^0.31.0",
|
|
76
76
|
"@canonical/code-standards": "^0.1.2",
|
|
77
77
|
"@canonical/design-system": "^0.1.2",
|
|
78
|
-
"@canonical/harnesses": "^0.
|
|
79
|
-
"@canonical/ke": "^0.
|
|
80
|
-
"@canonical/ke-graphql": "^0.
|
|
81
|
-
"@canonical/summon
|
|
82
|
-
"@canonical/summon-
|
|
83
|
-
"@canonical/summon-
|
|
84
|
-
"@canonical/
|
|
78
|
+
"@canonical/harnesses": "^0.31.0",
|
|
79
|
+
"@canonical/ke": "^0.31.0",
|
|
80
|
+
"@canonical/ke-graphql": "^0.31.0",
|
|
81
|
+
"@canonical/summon": "^0.31.0",
|
|
82
|
+
"@canonical/summon-application": "^0.31.0",
|
|
83
|
+
"@canonical/summon-component": "^0.31.0",
|
|
84
|
+
"@canonical/summon-core": "^0.31.0",
|
|
85
|
+
"@canonical/summon-package": "^0.31.0",
|
|
86
|
+
"@canonical/task": "^0.31.0",
|
|
85
87
|
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
86
88
|
"chalk": "^5.6.2",
|
|
87
89
|
"commander": "^14.0.3",
|
|
@@ -90,5 +92,5 @@
|
|
|
90
92
|
"react": "^19.2.4",
|
|
91
93
|
"zod": "^3.25.0"
|
|
92
94
|
},
|
|
93
|
-
"gitHead": "
|
|
95
|
+
"gitHead": "d4a67ebe42e62b8cf3de77f42f537309ca88d672"
|
|
94
96
|
}
|
|
@@ -16,3 +16,10 @@ export const POLL_INTERVAL_MS = 50;
|
|
|
16
16
|
|
|
17
17
|
/** Maximum time to wait for a spawned server to become ready. */
|
|
18
18
|
export const SPAWN_TIMEOUT_MS = 5_000;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Maximum time to wait for a query response before giving up. Bounds the
|
|
22
|
+
* whole client call so a wedged or slow server can never hang the shell's
|
|
23
|
+
* tab-completion — the query resolves to no candidates instead.
|
|
24
|
+
*/
|
|
25
|
+
export const QUERY_TIMEOUT_MS = 3_000;
|
|
@@ -37,6 +37,16 @@ function makeTree(): CompletionTree {
|
|
|
37
37
|
);
|
|
38
38
|
},
|
|
39
39
|
},
|
|
40
|
+
{
|
|
41
|
+
name: "detailed",
|
|
42
|
+
description: "Show full detail",
|
|
43
|
+
type: "boolean",
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: "anatomyOnly",
|
|
47
|
+
description: "Show anatomy only",
|
|
48
|
+
type: "boolean",
|
|
49
|
+
},
|
|
40
50
|
],
|
|
41
51
|
execute: async () => createExitResult(0),
|
|
42
52
|
},
|
|
@@ -90,4 +100,26 @@ describe("handleQuery", () => {
|
|
|
90
100
|
const result = await handleQuery("block list something", makeTree(), ctx);
|
|
91
101
|
expect(result).toBe("");
|
|
92
102
|
});
|
|
103
|
+
|
|
104
|
+
it("strips the leading program name shells forward", async () => {
|
|
105
|
+
// Every generated shell script forwards the full command line, so the
|
|
106
|
+
// program name arrives as the first word.
|
|
107
|
+
const result = await handleQuery("pragma blo", makeTree(), ctx);
|
|
108
|
+
expect(result).toBe("block");
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it("lists nouns when only the program name is present", async () => {
|
|
112
|
+
const result = await handleQuery("pragma", makeTree(), ctx);
|
|
113
|
+
expect(result).toBe("block\nstandard");
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it("completes verb flags when the word starts with a dash", async () => {
|
|
117
|
+
const result = await handleQuery("block get --", makeTree(), ctx);
|
|
118
|
+
expect(result).toBe("--anatomy-only\n--detailed");
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it("filters verb flags by the dash-prefixed partial", async () => {
|
|
122
|
+
const result = await handleQuery("block get --d", makeTree(), ctx);
|
|
123
|
+
expect(result).toBe("--detailed");
|
|
124
|
+
});
|
|
93
125
|
});
|
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
import type { CommandContext, CompletionTree } from "@canonical/cli-core";
|
|
2
2
|
import { resolveCompletion } from "@canonical/cli-core";
|
|
3
|
+
import { PROGRAM_NAME } from "../constants.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Split a raw shell partial into completion words, dropping the leading
|
|
7
|
+
* program name.
|
|
8
|
+
*
|
|
9
|
+
* Every generated shell script forwards the full command line — including the
|
|
10
|
+
* `pragma` program name as the first word — so without this strip the resolver
|
|
11
|
+
* mistakes `pragma` for the noun and returns no candidates. An empty partial
|
|
12
|
+
* (first-Tab, no word yet) resolves to a single empty word so noun completion
|
|
13
|
+
* still fires.
|
|
14
|
+
*
|
|
15
|
+
* @param partial - The raw partial input string from the shell.
|
|
16
|
+
* @returns The completion words with any leading program name removed.
|
|
17
|
+
*/
|
|
18
|
+
function splitCompletionWords(partial: string): string[] {
|
|
19
|
+
const words = partial.length === 0 ? [""] : partial.split(" ");
|
|
20
|
+
return words.at(0) === PROGRAM_NAME ? words.slice(1) : words;
|
|
21
|
+
}
|
|
3
22
|
|
|
4
23
|
/**
|
|
5
24
|
* Resolve a partial CLI input against a completion tree and return
|
|
@@ -22,7 +41,7 @@ export default async function handleQuery(
|
|
|
22
41
|
tree: CompletionTree,
|
|
23
42
|
ctx: CommandContext,
|
|
24
43
|
): Promise<string> {
|
|
25
|
-
const words = partial
|
|
44
|
+
const words = splitCompletionWords(partial);
|
|
26
45
|
const result = resolveCompletion(tree, words);
|
|
27
46
|
if (!result.completer) return "";
|
|
28
47
|
const candidates = await result.completer(result.partial, ctx);
|
|
@@ -26,12 +26,15 @@ vi.mock("./waitForSocket.js", () => ({
|
|
|
26
26
|
|
|
27
27
|
describe("queryCompletions", () => {
|
|
28
28
|
let stdoutSpy: ReturnType<typeof vi.spyOn>;
|
|
29
|
+
const unrefMock = vi.fn();
|
|
29
30
|
|
|
30
31
|
beforeEach(() => {
|
|
31
32
|
vi.clearAllMocks();
|
|
32
33
|
stdoutSpy = vi
|
|
33
34
|
.spyOn(process.stdout, "write")
|
|
34
35
|
.mockImplementation(() => true);
|
|
36
|
+
// The spawned server handle is unref'd so the client can exit immediately.
|
|
37
|
+
spawnMock.mockReturnValue({ unref: unrefMock });
|
|
35
38
|
vi.stubGlobal("Bun", { spawn: spawnMock });
|
|
36
39
|
});
|
|
37
40
|
|
|
@@ -67,6 +70,8 @@ describe("queryCompletions", () => {
|
|
|
67
70
|
|
|
68
71
|
expect(unlinkSyncMock).toHaveBeenCalledWith("/tmp/pragma-completions.sock");
|
|
69
72
|
expect(spawnMock).toHaveBeenCalledTimes(1);
|
|
73
|
+
// The server handle is detached so the client is not held alive by it.
|
|
74
|
+
expect(unrefMock).toHaveBeenCalledTimes(1);
|
|
70
75
|
expect(waitForSocketMock).toHaveBeenCalled();
|
|
71
76
|
expect(querySocketMock).toHaveBeenCalledTimes(2);
|
|
72
77
|
expect(stdoutSpy).toHaveBeenCalledWith("block\n");
|
|
@@ -38,12 +38,26 @@ export default async function queryCompletions(partial: string): Promise<void> {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
// No running server — spawn one.
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
// No running server — spawn one. Re-invoke THIS executable so completion
|
|
42
|
+
// works from the shipped binary as well as from source: when the entry file
|
|
43
|
+
// exists on disk (source run) spawn `bun run bin.ts`; otherwise (a compiled
|
|
44
|
+
// standalone binary, where bin.ts is embedded, not a file) spawn the binary
|
|
45
|
+
// itself. The old code always spawned `bun run <dir>/../bin.ts`, which does
|
|
46
|
+
// not exist inside a compiled binary, so its server never started and every
|
|
47
|
+
// completion silently returned nothing.
|
|
48
|
+
const entryPath = resolve(import.meta.dirname, "../bin.ts");
|
|
49
|
+
const spawnArgs = existsSync(entryPath)
|
|
50
|
+
? [process.execPath, "run", entryPath, "_completions-server"]
|
|
51
|
+
: [process.execPath, "_completions-server"];
|
|
52
|
+
const server = Bun.spawn(spawnArgs, {
|
|
44
53
|
stdio: ["ignore", "ignore", "ignore"],
|
|
45
54
|
cwd: process.cwd(),
|
|
46
55
|
});
|
|
56
|
+
// Detach the server from the client's lifecycle. Without this the child keeps
|
|
57
|
+
// the client's event loop alive until the server's idle timeout (~10s) fires,
|
|
58
|
+
// so every tab-completion appears to hang for ~10s and the client tears the
|
|
59
|
+
// server down on exit — defeating the persistent-server fast path entirely.
|
|
60
|
+
server.unref();
|
|
47
61
|
|
|
48
62
|
const ready = await waitForSocket(socketPath, SPAWN_TIMEOUT_MS);
|
|
49
63
|
if (!ready) {
|
|
@@ -67,4 +67,35 @@ describe("querySocket", () => {
|
|
|
67
67
|
"connect failed",
|
|
68
68
|
);
|
|
69
69
|
});
|
|
70
|
+
|
|
71
|
+
it("times out and closes the socket when the server never replies", async () => {
|
|
72
|
+
vi.useFakeTimers();
|
|
73
|
+
const end = vi.fn();
|
|
74
|
+
|
|
75
|
+
connectMock.mockImplementation(
|
|
76
|
+
(options: {
|
|
77
|
+
socket: {
|
|
78
|
+
open: (socket: {
|
|
79
|
+
write: () => void;
|
|
80
|
+
flush: () => void;
|
|
81
|
+
end: () => void;
|
|
82
|
+
}) => void;
|
|
83
|
+
};
|
|
84
|
+
}) => {
|
|
85
|
+
// Open but never send data or close — simulate a wedged server.
|
|
86
|
+
options.socket.open({ write: () => {}, flush: () => {}, end });
|
|
87
|
+
return Promise.resolve({});
|
|
88
|
+
},
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
const promise = querySocket("/tmp/pragma.sock", "blo");
|
|
93
|
+
const assertion = expect(promise).rejects.toThrow(/timed out/);
|
|
94
|
+
await vi.advanceTimersByTimeAsync(5000);
|
|
95
|
+
await assertion;
|
|
96
|
+
expect(end).toHaveBeenCalledTimes(1);
|
|
97
|
+
} finally {
|
|
98
|
+
vi.useRealTimers();
|
|
99
|
+
}
|
|
100
|
+
});
|
|
70
101
|
});
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
+
import { QUERY_TIMEOUT_MS } from "./constants.js";
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Connect to a Unix domain socket, send a partial string, and
|
|
3
5
|
* collect the response.
|
|
4
6
|
*
|
|
5
|
-
* Opens a Bun
|
|
6
|
-
*
|
|
7
|
-
*
|
|
7
|
+
* Opens a Bun connection to the socket, writes the partial terminated by a
|
|
8
|
+
* newline, and accumulates response chunks until the server closes the
|
|
9
|
+
* connection. The whole exchange is bounded by {@link QUERY_TIMEOUT_MS}: if a
|
|
10
|
+
* wedged or slow server never replies, the promise rejects rather than hanging
|
|
11
|
+
* the shell's tab-completion indefinitely.
|
|
8
12
|
*
|
|
9
13
|
* @param socketPath - Absolute path to the Unix domain socket.
|
|
10
14
|
* @param partial - The partial CLI input to send for completion.
|
|
@@ -18,10 +22,31 @@ export default function querySocket(
|
|
|
18
22
|
): Promise<string> {
|
|
19
23
|
return new Promise<string>((resolve, reject) => {
|
|
20
24
|
const chunks: Buffer[] = [];
|
|
25
|
+
let settled = false;
|
|
26
|
+
let openSocket: { end: () => void } | undefined;
|
|
27
|
+
|
|
28
|
+
const timer = setTimeout(() => {
|
|
29
|
+
if (settled) return;
|
|
30
|
+
settled = true;
|
|
31
|
+
// Close the connection so a hung server does not leak an open socket.
|
|
32
|
+
openSocket?.end();
|
|
33
|
+
reject(
|
|
34
|
+
new Error(`Completion query timed out after ${QUERY_TIMEOUT_MS}ms`),
|
|
35
|
+
);
|
|
36
|
+
}, QUERY_TIMEOUT_MS);
|
|
37
|
+
|
|
38
|
+
const settle = (run: () => void): void => {
|
|
39
|
+
if (settled) return;
|
|
40
|
+
settled = true;
|
|
41
|
+
clearTimeout(timer);
|
|
42
|
+
run();
|
|
43
|
+
};
|
|
44
|
+
|
|
21
45
|
Bun.connect({
|
|
22
46
|
unix: socketPath,
|
|
23
47
|
socket: {
|
|
24
48
|
open(socket) {
|
|
49
|
+
openSocket = socket;
|
|
25
50
|
socket.write(`${partial}\n`);
|
|
26
51
|
socket.flush();
|
|
27
52
|
},
|
|
@@ -29,16 +54,18 @@ export default function querySocket(
|
|
|
29
54
|
chunks.push(Buffer.from(data));
|
|
30
55
|
},
|
|
31
56
|
close() {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
.
|
|
35
|
-
|
|
57
|
+
settle(() =>
|
|
58
|
+
resolve(
|
|
59
|
+
Buffer.concat(chunks)
|
|
60
|
+
.toString("utf-8")
|
|
61
|
+
.replace(/\r?\n$/, ""),
|
|
62
|
+
),
|
|
36
63
|
);
|
|
37
64
|
},
|
|
38
65
|
error(_socket, err) {
|
|
39
|
-
reject(err);
|
|
66
|
+
settle(() => reject(err));
|
|
40
67
|
},
|
|
41
68
|
},
|
|
42
|
-
}).catch(reject);
|
|
69
|
+
}).catch((err) => settle(() => reject(err)));
|
|
43
70
|
});
|
|
44
71
|
}
|
|
@@ -92,6 +92,7 @@ export default function parseConfigValues(
|
|
|
92
92
|
const packages = parsePackagesField(parsed.packages);
|
|
93
93
|
const stories = parseStoriesField(parsed.stories, sourcePath);
|
|
94
94
|
const prefixes = parsePrefixesField(parsed.prefixes);
|
|
95
|
+
const detail = typeof parsed.detail === "string" ? parsed.detail : undefined;
|
|
95
96
|
|
|
96
97
|
return {
|
|
97
98
|
...(tier !== undefined ? { tier } : {}),
|
|
@@ -101,6 +102,7 @@ export default function parseConfigValues(
|
|
|
101
102
|
...(framework !== undefined ? { framework } : {}),
|
|
102
103
|
...(stories ? { stories } : {}),
|
|
103
104
|
...(prefixes ? { prefixes } : {}),
|
|
105
|
+
...(detail !== undefined ? { detail } : {}),
|
|
104
106
|
};
|
|
105
107
|
}
|
|
106
108
|
|
|
@@ -44,6 +44,7 @@ describe("readConfigLayers", () => {
|
|
|
44
44
|
framework: "default",
|
|
45
45
|
stories: "default",
|
|
46
46
|
prefixes: "default",
|
|
47
|
+
detail: "default",
|
|
47
48
|
});
|
|
48
49
|
expect(layers.global.exists).toBe(false);
|
|
49
50
|
expect(layers.project.exists).toBe(false);
|
|
@@ -77,6 +78,7 @@ describe("readConfigLayers", () => {
|
|
|
77
78
|
framework: "default",
|
|
78
79
|
stories: "default",
|
|
79
80
|
prefixes: "default",
|
|
81
|
+
detail: "default",
|
|
80
82
|
});
|
|
81
83
|
});
|
|
82
84
|
|
|
@@ -68,6 +68,7 @@ export default function readConfigLayers(
|
|
|
68
68
|
const framework = pick("framework");
|
|
69
69
|
const stories = pick("stories");
|
|
70
70
|
const prefixes = pick("prefixes");
|
|
71
|
+
const detail = pick("detail");
|
|
71
72
|
|
|
72
73
|
const config: PragmaConfig = {
|
|
73
74
|
tier: tier.value,
|
|
@@ -77,6 +78,7 @@ export default function readConfigLayers(
|
|
|
77
78
|
...(framework.value !== undefined ? { framework: framework.value } : {}),
|
|
78
79
|
...(stories.value ? { stories: stories.value } : {}),
|
|
79
80
|
...(prefixes.value ? { prefixes: prefixes.value } : {}),
|
|
81
|
+
...(detail.value !== undefined ? { detail: detail.value } : {}),
|
|
80
82
|
};
|
|
81
83
|
|
|
82
84
|
return {
|
|
@@ -89,6 +91,7 @@ export default function readConfigLayers(
|
|
|
89
91
|
framework: framework.origin,
|
|
90
92
|
stories: stories.origin,
|
|
91
93
|
prefixes: prefixes.origin,
|
|
94
|
+
detail: detail.origin,
|
|
92
95
|
},
|
|
93
96
|
global: { path: globalPath, exists: globalFile.exists },
|
|
94
97
|
project: { path: projectPath, exists: projectFile.exists },
|
package/src/config/types.ts
CHANGED
|
@@ -39,6 +39,11 @@ interface PragmaConfig {
|
|
|
39
39
|
* registered on the store (usable in queries) and used for display.
|
|
40
40
|
*/
|
|
41
41
|
prefixes?: Readonly<Record<string, string>> | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* Default progressive-disclosure level for disclosure-capable commands
|
|
44
|
+
* (e.g. `"digest"`, `"detailed"`). An explicit `--detail` flag overrides it.
|
|
45
|
+
*/
|
|
46
|
+
detail?: string | undefined;
|
|
42
47
|
}
|
|
43
48
|
|
|
44
49
|
/** Partial update payload for writing config changes. */
|
|
@@ -67,6 +72,7 @@ interface ConfigFileValues {
|
|
|
67
72
|
readonly framework?: Framework;
|
|
68
73
|
readonly stories?: ReadonlyArray<StoryPackDefinition>;
|
|
69
74
|
readonly prefixes?: Readonly<Record<string, string>>;
|
|
75
|
+
readonly detail?: string;
|
|
70
76
|
}
|
|
71
77
|
|
|
72
78
|
/** Which config layer supplied an effective field value. */
|
|
@@ -81,6 +87,7 @@ interface ConfigOrigins {
|
|
|
81
87
|
readonly framework: ConfigOrigin;
|
|
82
88
|
readonly stories: ConfigOrigin;
|
|
83
89
|
readonly prefixes: ConfigOrigin;
|
|
90
|
+
readonly detail: ConfigOrigin;
|
|
84
91
|
}
|
|
85
92
|
|
|
86
93
|
/** A resolved config file layer. */
|
package/src/constants.ts
CHANGED
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import pkg from "../package.json" with { type: "json" };
|
|
10
|
-
|
|
10
|
+
// DEFAULT_PREFIX_MAP carries the transitional DS prefixes (ds/cs) this map
|
|
11
|
+
// still keys on; remove in P4 when DS prefixes ship from their packages.
|
|
12
|
+
import { DEFAULT_PREFIX_MAP as PREFIX_MAP } from "./domains/shared/prefixes.js";
|
|
11
13
|
|
|
12
14
|
/** CLI program name used in help text and error messages. */
|
|
13
15
|
const PROGRAM_NAME = "pragma";
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
} from "@canonical/cli-core";
|
|
12
12
|
import type { PragmaContext } from "../../shared/context.js";
|
|
13
13
|
import { selectFormatter } from "../../shared/formatters.js";
|
|
14
|
+
import parseSampleCount from "../../shared/parseSampleCount.js";
|
|
14
15
|
import type { BlockDetailed, SampleOutput } from "../../shared/types/index.js";
|
|
15
16
|
import { sampleFormatters } from "../formatters/index.js";
|
|
16
17
|
import { sampleBlocks } from "../operations/index.js";
|
|
@@ -38,7 +39,7 @@ export default function sampleCommand(ctx: PragmaContext): CommandDefinition {
|
|
|
38
39
|
examples: ["pragma block sample", "pragma block sample --count 3"],
|
|
39
40
|
},
|
|
40
41
|
async execute(params) {
|
|
41
|
-
const count =
|
|
42
|
+
const count = parseSampleCount(params.count);
|
|
42
43
|
const filters = buildBlockFilters(ctx);
|
|
43
44
|
const result = await sampleBlocks(ctx.store, filters, count);
|
|
44
45
|
|