@canonical/pragma-cli 0.36.0 → 0.38.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 +3 -2
- package/bundled-skills/adoption-a1-styles/SKILL.md +24 -0
- package/bundled-skills/adoption-a2-components/SKILL.md +22 -6
- package/bundled-skills/anatomy-author/ANATOMY_DSL_SPEC.md +1397 -327
- package/bundled-skills/anatomy-author/SKILL.md +840 -137
- package/bundled-skills/design-auditor/SKILL.md +133 -9
- package/bundled-skills/implement-component/SKILL.md +192 -23
- package/bundled-skills/specify-component/SKILL.md +124 -12
- package/bundled-skills/specify-pattern/SKILL.md +47 -8
- package/dist/package.json +23 -20
- package/dist/pragma.conf.js +963 -40
- package/dist/pragma.conf.js.map +1 -1
- package/dist/src/capabilities/capabilities/catalog.js +14 -5
- package/dist/src/capabilities/capabilities/catalog.js.map +1 -1
- package/dist/src/capabilities/capabilities/hints.js +33 -5
- package/dist/src/capabilities/capabilities/hints.js.map +1 -1
- package/dist/src/capabilities/config/show.render.js +30 -2
- package/dist/src/capabilities/config/show.render.js.map +1 -1
- package/dist/src/capabilities/create/create.verb.js +2 -1
- package/dist/src/capabilities/create/create.verb.js.map +1 -1
- package/dist/src/capabilities/create/createSurface.generated.js +23 -1
- package/dist/src/capabilities/create/createSurface.generated.js.map +1 -1
- package/dist/src/capabilities/doctor/checks/checkNodeVersion.js +11 -6
- package/dist/src/capabilities/doctor/checks/checkNodeVersion.js.map +1 -1
- package/dist/src/capabilities/doctor/checks/harnessInventory.js +1 -1
- package/dist/src/capabilities/doctor/checks/harnessInventory.js.map +1 -1
- package/dist/src/capabilities/doctor/checks/isSupportedNodeVersion.js +38 -0
- package/dist/src/capabilities/doctor/checks/isSupportedNodeVersion.js.map +1 -0
- package/dist/src/capabilities/doctor/checks/targetHealth.js +104 -14
- package/dist/src/capabilities/doctor/checks/targetHealth.js.map +1 -1
- package/dist/src/capabilities/graph/connect.render.js +101 -0
- package/dist/src/capabilities/graph/connect.render.js.map +1 -0
- package/dist/src/capabilities/graph/connect.types.js +21 -0
- package/dist/src/capabilities/graph/connect.types.js.map +1 -0
- package/dist/src/capabilities/graph/connect.verb.js +147 -0
- package/dist/src/capabilities/graph/connect.verb.js.map +1 -0
- package/dist/src/capabilities/graph/index.js +5 -3
- package/dist/src/capabilities/graph/index.js.map +1 -1
- package/dist/src/capabilities/graph/queryText.js +206 -0
- package/dist/src/capabilities/graph/queryText.js.map +1 -0
- package/dist/src/capabilities/graph/relationIndex.js +302 -0
- package/dist/src/capabilities/graph/relationIndex.js.map +1 -0
- package/dist/src/capabilities/graph/runConnect.js +456 -0
- package/dist/src/capabilities/graph/runConnect.js.map +1 -0
- package/dist/src/capabilities/graph/runQuery.js +21 -4
- package/dist/src/capabilities/graph/runQuery.js.map +1 -1
- package/dist/src/capabilities/setup/buildPlan.js +6 -2
- package/dist/src/capabilities/setup/buildPlan.js.map +1 -1
- package/dist/src/capabilities/setup/operations/index.js +7 -2
- package/dist/src/capabilities/setup/operations/index.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupCompletions.js +6 -2
- package/dist/src/capabilities/setup/operations/setupCompletions.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupConfig.js +4 -2
- package/dist/src/capabilities/setup/operations/setupConfig.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupGenerator.js +72 -14
- package/dist/src/capabilities/setup/operations/setupGenerator.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupLsp.js +372 -62
- package/dist/src/capabilities/setup/operations/setupLsp.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupMcp.js +150 -5
- package/dist/src/capabilities/setup/operations/setupMcp.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupSkills.js +4 -2
- package/dist/src/capabilities/setup/operations/setupSkills.js.map +1 -1
- package/dist/src/capabilities/setup/operations/writability.js +114 -0
- package/dist/src/capabilities/setup/operations/writability.js.map +1 -0
- package/dist/src/capabilities/setup/plan.js.map +1 -1
- package/dist/src/capabilities/setup/setup.verb.js +80 -31
- package/dist/src/capabilities/setup/setup.verb.js.map +1 -1
- package/dist/src/capabilities/setup/targets.js +124 -42
- package/dist/src/capabilities/setup/targets.js.map +1 -1
- package/dist/src/capabilities/shared/index.js +1 -1
- package/dist/src/capabilities/shared/index.js.map +1 -1
- package/dist/src/constants.js +7 -1
- package/dist/src/constants.js.map +1 -1
- package/dist/src/kernel/error/renderError.js +3 -2
- package/dist/src/kernel/error/renderError.js.map +1 -1
- package/dist/src/kernel/error/validOptions.js +41 -0
- package/dist/src/kernel/error/validOptions.js.map +1 -0
- package/dist/src/kernel/packs/compile.js +90 -6
- package/dist/src/kernel/packs/compile.js.map +1 -1
- package/dist/src/kernel/packs/cursor.js +135 -0
- package/dist/src/kernel/packs/cursor.js.map +1 -0
- package/dist/src/kernel/packs/graphql/buildLookupDocument.js +9 -2
- package/dist/src/kernel/packs/graphql/buildLookupDocument.js.map +1 -1
- package/dist/src/kernel/packs/paging.js +108 -0
- package/dist/src/kernel/packs/paging.js.map +1 -0
- package/dist/src/kernel/packs/renderPack.js +154 -5
- package/dist/src/kernel/packs/renderPack.js.map +1 -1
- package/dist/src/kernel/packs/resolveEntity.js +118 -19
- package/dist/src/kernel/packs/resolveEntity.js.map +1 -1
- package/dist/src/kernel/packs/runBodies.js +156 -18
- package/dist/src/kernel/packs/runBodies.js.map +1 -1
- package/dist/src/kernel/packs/schema.js +160 -12
- package/dist/src/kernel/packs/schema.js.map +1 -1
- package/dist/src/kernel/packs/sparql/authorQuery.js +227 -0
- package/dist/src/kernel/packs/sparql/authorQuery.js.map +1 -0
- package/dist/src/kernel/packs/sparql/buildListQuery.js +251 -0
- package/dist/src/kernel/packs/sparql/buildListQuery.js.map +1 -0
- package/dist/src/kernel/packs/sparql/buildLookupQuery.js +125 -22
- package/dist/src/kernel/packs/sparql/buildLookupQuery.js.map +1 -1
- package/dist/src/kernel/packs/sparql/filterValues.js +145 -0
- package/dist/src/kernel/packs/sparql/filterValues.js.map +1 -0
- package/dist/src/kernel/packs/sparql/index.js +24 -14
- package/dist/src/kernel/packs/sparql/index.js.map +1 -1
- package/dist/src/kernel/packs/sparql/runSelect.js +10 -4
- package/dist/src/kernel/packs/sparql/runSelect.js.map +1 -1
- package/dist/src/kernel/packs/sparql/searchTerm.js +25 -0
- package/dist/src/kernel/packs/sparql/searchTerm.js.map +1 -0
- package/dist/src/kernel/packs/storyRules.js +151 -0
- package/dist/src/kernel/packs/storyRules.js.map +1 -0
- package/dist/src/kernel/packs/tierScope.js +310 -0
- package/dist/src/kernel/packs/tierScope.js.map +1 -0
- package/dist/src/kernel/packs/types.js +80 -0
- package/dist/src/kernel/packs/types.js.map +1 -1
- package/dist/src/kernel/project/cli/buildProgram.js +10 -1
- package/dist/src/kernel/project/cli/buildProgram.js.map +1 -1
- package/dist/src/kernel/project/cli/dispatch.js +104 -3
- package/dist/src/kernel/project/cli/dispatch.js.map +1 -1
- package/dist/src/kernel/project/cli/rootHelp.js +8 -5
- package/dist/src/kernel/project/cli/rootHelp.js.map +1 -1
- package/dist/src/kernel/project/cli/suggestNames.js +31 -7
- package/dist/src/kernel/project/cli/suggestNames.js.map +1 -1
- package/dist/src/kernel/project/mcp/registerVerb.js +5 -1
- package/dist/src/kernel/project/mcp/registerVerb.js.map +1 -1
- package/dist/src/kernel/render/renderers.js +34 -2
- package/dist/src/kernel/render/renderers.js.map +1 -1
- package/dist/src/kernel/runtime/graphpack/embedded/pack.generated.js +2 -3
- package/dist/src/kernel/runtime/graphpack/embedded/pack.generated.js.map +1 -1
- package/dist/src/kernel/runtime/graphpack/embedded/pack.index.generated.js +1 -1
- package/dist/src/kernel/runtime/graphpack/embedded/pack.index.generated.js.map +1 -1
- package/dist/src/kernel/runtime/graphpack/embedded/pack.manifest.generated.js +4 -0
- package/dist/src/kernel/runtime/graphpack/embedded/pack.manifest.generated.js.map +1 -0
- package/dist/src/kernel/runtime/graphpack/embedded.js +13 -6
- package/dist/src/kernel/runtime/graphpack/embedded.js.map +1 -1
- package/dist/src/kernel/runtime/graphpack/read.js +17 -10
- package/dist/src/kernel/runtime/graphpack/read.js.map +1 -1
- package/dist/src/kernel/runtime/loadSession.js +3 -1
- package/dist/src/kernel/runtime/loadSession.js.map +1 -1
- package/dist/src/kernel/runtime/probe.js +1 -1
- package/dist/src/kernel/runtime/probe.js.map +1 -1
- package/dist/src/kernel/runtime/readEntity.js +19 -4
- package/dist/src/kernel/runtime/readEntity.js.map +1 -1
- package/dist/src/kernel/runtime/refs/parseRef.js +17 -1
- package/dist/src/kernel/runtime/refs/parseRef.js.map +1 -1
- package/dist/src/kernel/runtime/refs/resolve.js +38 -5
- package/dist/src/kernel/runtime/refs/resolve.js.map +1 -1
- package/dist/src/kernel/spec/emitReference.js +1 -1
- package/dist/src/kernel/spec/emitReference.js.map +1 -1
- package/package.json +23 -20
- package/pragma.conf.ts +983 -40
- package/src/capabilities/block.parity.test.ts +207 -27
- package/src/capabilities/block.shipped.exec.test.ts +156 -14
- package/src/capabilities/block.tierRank.exec.test.ts +46 -9
- package/src/capabilities/capabilities/catalog.ts +14 -5
- package/src/capabilities/capabilities/hints.ts +40 -5
- package/src/capabilities/config/collectConfigShow.test.ts +1 -0
- package/src/capabilities/config/set.test.ts +24 -25
- package/src/capabilities/config/show.render.test.ts +9 -4
- package/src/capabilities/config/show.render.ts +30 -2
- package/src/capabilities/create/byteEquality.test.ts +28 -1
- package/src/capabilities/create/create.test.ts +1 -0
- package/src/capabilities/create/create.verb.ts +2 -1
- package/src/capabilities/create/createGrammar.test.ts +4 -1
- package/src/capabilities/create/createSurface.generated.ts +23 -1
- package/src/capabilities/create/crossCli.subprocess.test.ts +10 -3
- package/src/capabilities/distribution.parity.test.ts +12 -11
- package/src/capabilities/distribution.test.ts +77 -7
- package/src/capabilities/doctor/checks/checkNodeVersion.test.ts +49 -0
- package/src/capabilities/doctor/checks/checkNodeVersion.ts +11 -7
- package/src/capabilities/doctor/checks/harnessInventory.test.ts +13 -6
- package/src/capabilities/doctor/checks/harnessInventory.ts +8 -4
- package/src/capabilities/doctor/checks/isSupportedNodeVersion.test.ts +111 -0
- package/src/capabilities/doctor/checks/isSupportedNodeVersion.ts +34 -0
- package/src/capabilities/doctor/checks/mcpCommand.test.ts +7 -1
- package/src/capabilities/doctor/checks/targetHealth.ts +114 -13
- package/src/capabilities/doctor/doctor.test.ts +327 -36
- package/src/capabilities/emptyRecovery.test.ts +84 -28
- package/src/capabilities/graph/connect.render.ts +141 -0
- package/src/capabilities/graph/connect.shipped.exec.test.ts +370 -0
- package/src/capabilities/graph/connect.test.ts +361 -0
- package/src/capabilities/graph/connect.types.ts +136 -0
- package/src/capabilities/graph/connect.verb.ts +165 -0
- package/src/capabilities/graph/index.ts +5 -3
- package/src/capabilities/graph/query.shipped.exec.test.ts +66 -0
- package/src/capabilities/graph/query.test.ts +17 -0
- package/src/capabilities/graph/queryText.test.ts +121 -0
- package/src/capabilities/graph/queryText.ts +240 -0
- package/src/capabilities/graph/relationIndex.ts +372 -0
- package/src/capabilities/graph/runConnect.ts +577 -0
- package/src/capabilities/graph/runQuery.ts +21 -6
- package/src/capabilities/lazy.test.ts +32 -2
- package/src/capabilities/listBudget.shipped.exec.test.ts +239 -0
- package/src/capabilities/listLookup.shipped.exec.test.ts +387 -0
- package/src/capabilities/listQuery.shipped.exec.test.ts +400 -0
- package/src/capabilities/resources/resources.test.ts +38 -2
- package/src/capabilities/setup/buildPlan.ts +7 -1
- package/src/capabilities/setup/operations/index.ts +14 -0
- package/src/capabilities/setup/operations/setupCompletions.ts +9 -2
- package/src/capabilities/setup/operations/setupConfig.ts +7 -2
- package/src/capabilities/setup/operations/setupGenerator.ts +93 -15
- package/src/capabilities/setup/operations/setupLsp.ts +544 -85
- package/src/capabilities/setup/operations/setupMcp.ts +212 -4
- package/src/capabilities/setup/operations/setupSkills.ts +7 -2
- package/src/capabilities/setup/operations/writability.test.ts +151 -0
- package/src/capabilities/setup/operations/writability.ts +135 -0
- package/src/capabilities/setup/plan.ts +11 -0
- package/src/capabilities/setup/setup.test.ts +992 -16
- package/src/capabilities/setup/setup.verb.ts +84 -36
- package/src/capabilities/setup/targets.ts +152 -48
- package/src/capabilities/setup/types.ts +41 -5
- package/src/capabilities/shared/index.ts +1 -0
- package/src/capabilities/sources/sources.test.ts +55 -0
- package/src/capabilities/surface.test.ts +59 -11
- package/src/capabilities/tier.parity.test.ts +2 -2
- package/src/capabilities/token.parity.test.ts +784 -0
- package/src/capabilities/tokenGraph.cli.test.ts +279 -0
- package/src/capabilities/tokenGraph.shipped.exec.test.ts +653 -0
- package/src/capabilities/variable.parity.test.ts +448 -0
- package/src/constants.ts +8 -0
- package/src/kernel/completion/shellDrive.test.ts +32 -30
- package/src/kernel/config/defaults.test.ts +21 -2
- package/src/kernel/config/readConfig.test.ts +1 -1
- package/src/kernel/error/renderError.ts +3 -2
- package/src/kernel/error/validOptions.test.ts +57 -0
- package/src/kernel/error/validOptions.ts +45 -0
- package/src/kernel/packs/collect.test.ts +2 -0
- package/src/kernel/packs/compile.test.ts +188 -15
- package/src/kernel/packs/compile.ts +109 -14
- package/src/kernel/packs/cursor.ts +135 -0
- package/src/kernel/packs/filteredEmpty.test.ts +213 -0
- package/src/kernel/packs/graphql/buildLookupDocument.ts +16 -9
- package/src/kernel/packs/graphqlSource.test.ts +152 -0
- package/src/kernel/packs/listNotice.test.ts +156 -0
- package/src/kernel/packs/paging.ts +110 -0
- package/src/kernel/packs/renderPack.ts +186 -13
- package/src/kernel/packs/resolveEntity.test.ts +62 -3
- package/src/kernel/packs/resolveEntity.ts +186 -26
- package/src/kernel/packs/runBodies.ts +196 -26
- package/src/kernel/packs/schema.ts +180 -13
- package/src/kernel/packs/sparql/authorQuery.test.ts +179 -0
- package/src/kernel/packs/sparql/authorQuery.ts +257 -0
- package/src/kernel/packs/sparql/buildListQuery.test.ts +344 -0
- package/src/kernel/packs/sparql/buildListQuery.ts +344 -0
- package/src/kernel/packs/sparql/buildLookupQuery.test.ts +138 -0
- package/src/kernel/packs/sparql/buildLookupQuery.ts +140 -20
- package/src/kernel/packs/sparql/filterValues.test.ts +86 -0
- package/src/kernel/packs/sparql/filterValues.ts +182 -0
- package/src/kernel/packs/sparql/index.ts +30 -14
- package/src/kernel/packs/sparql/runSelect.test.ts +63 -0
- package/src/kernel/packs/sparql/runSelect.ts +42 -2
- package/src/kernel/packs/sparql/searchTerm.ts +29 -0
- package/src/kernel/packs/storyRules.ts +180 -0
- package/src/kernel/packs/tierScope.test.ts +487 -0
- package/src/kernel/packs/tierScope.ts +409 -0
- package/src/kernel/packs/toolDescription.test.ts +13 -10
- package/src/kernel/packs/types.ts +311 -9
- package/src/kernel/project/cli/buildProgram.ts +17 -1
- package/src/kernel/project/cli/dispatch.test.ts +87 -0
- package/src/kernel/project/cli/dispatch.ts +114 -4
- package/src/kernel/project/cli/rootHelp.ts +8 -5
- package/src/kernel/project/cli/suggest.test.ts +35 -0
- package/src/kernel/project/cli/suggestNames.ts +34 -7
- package/src/kernel/project/mcp/registerVerb.ts +5 -1
- package/src/kernel/render/contracts.ts +2 -0
- package/src/kernel/render/prefixes.test.ts +2 -0
- package/src/kernel/render/renderers.test.ts +43 -0
- package/src/kernel/render/renderers.ts +34 -1
- package/src/kernel/runtime/graphpack/embedded/pack.generated.ts +2 -3
- package/src/kernel/runtime/graphpack/embedded/pack.index.generated.ts +1 -1
- package/src/kernel/runtime/graphpack/embedded/pack.manifest.generated.ts +3 -0
- package/src/kernel/runtime/graphpack/embedded.ts +14 -6
- package/src/kernel/runtime/graphpack/graphpack.test.ts +31 -5
- package/src/kernel/runtime/graphpack/read.ts +17 -13
- package/src/kernel/runtime/loadSession.ts +3 -1
- package/src/kernel/runtime/probe.ts +1 -1
- package/src/kernel/runtime/readEntity.ts +19 -4
- package/src/kernel/runtime/refs/parseRef.test.ts +49 -1
- package/src/kernel/runtime/refs/parseRef.ts +25 -1
- package/src/kernel/runtime/refs/resolve.ts +39 -5
- package/src/kernel/runtime/types.ts +30 -0
- package/src/kernel/spec/emitReference.ts +1 -1
- package/src/kernel/spec/surfaceConformance.test.ts +2 -2
- package/src/kernel/spec/types.ts +17 -0
- package/src/testing/PARITY_GAPS.ts +4 -4
- package/src/testing/behavioral/agentSession.mcp.test.ts +43 -39
- package/src/testing/behavioral/completion.test.ts +7 -6
- package/src/testing/behavioral/disclosure.test.ts +39 -37
- package/src/testing/behavioral/errorMatrix.mcp.test.ts +82 -64
- package/src/testing/behavioral/errorMatrix.storeless.test.ts +11 -10
- package/src/testing/behavioral/journeys.cli.test.ts +71 -32
- package/src/testing/behavioral/journeys.defaultPack.test.ts +6 -4
- package/src/testing/behavioral/journeys.firstInstall.test.ts +70 -5
- package/src/testing/behavioral/journeys.mcpLifecycle.mcp.test.ts +4 -3
- package/src/testing/behavioral/journeys.packageStories.test.ts +2 -1
- package/src/testing/behavioral/mcpSurface.test.ts +28 -25
- package/src/testing/behavioral/parity.test.ts +25 -23
- package/src/testing/eval/__snapshots__/eval.test.ts.snap +20 -0
- package/src/testing/eval/cases/effectful.ts +7 -1
- package/src/testing/eval/cases/readNouns.ts +100 -11
- package/src/testing/fixtures/blockGraph.ts +89 -5
- package/src/testing/fixtures/connectGraph.ts +159 -0
- package/src/testing/fixtures/graph/canonical.ts +128 -32
- package/src/testing/helpers/fsProbe.ts +88 -0
- package/src/testing/helpers/runCli.test.ts +44 -0
- package/src/testing/helpers/runCli.ts +27 -3
- package/src/testing/perf/budgets.test.ts +3 -1
- package/src/testing/perf/budgets.ts +138 -54
- package/dist/src/kernel/packs/sparql/applyFilters.js +0 -167
- package/dist/src/kernel/packs/sparql/applyFilters.js.map +0 -1
- package/dist/src/kernel/packs/sparql/applySearch.js +0 -25
- package/dist/src/kernel/packs/sparql/applySearch.js.map +0 -1
- package/src/kernel/packs/sparql/applyFilters.ts +0 -203
- package/src/kernel/packs/sparql/applySearch.ts +0 -33
|
@@ -146,17 +146,25 @@ Start with a broad inventory, then drill into specific concerns:
|
|
|
146
146
|
pragma block list # every component, pattern, layout and subcomponent, with type and tier
|
|
147
147
|
pragma modifier list # every modifier family with its values
|
|
148
148
|
pragma tier list # the tiers blocks can live in
|
|
149
|
+
pragma token list # the design-token symbols, by their dotted names
|
|
150
|
+
pragma variable list # the CSS custom properties those symbols are emitted as
|
|
149
151
|
pragma graph query "…" # the audit queries below
|
|
150
152
|
pragma graph inspect <IRI-or-ds:name> # every triple on one entity
|
|
153
|
+
pragma sources status # which pack is answering, and how many entities it holds
|
|
151
154
|
```
|
|
152
155
|
|
|
156
|
+
Run `sources status` before the first query and record what it says in the report's
|
|
157
|
+
scope line. Every count in an audit is a count from one pack at one version; a finding
|
|
158
|
+
that does not say which pack answered cannot be compared against the next audit.
|
|
159
|
+
|
|
153
160
|
Two graph-query mechanics to know (shared with the sibling skills):
|
|
154
161
|
|
|
155
|
-
- Common prefixes (`ds:`, `cs:`) are applied automatically — no PREFIX preamble.
|
|
156
|
-
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
162
|
+
- Common prefixes (`ds:`, `cs:`, `dt:`) are applied automatically — no PREFIX preamble.
|
|
163
|
+
- A prefixed name carrying dots or slashes parses inside a SPARQL body, so write the
|
|
164
|
+
name the graph prints: `ds:global.component.button` and
|
|
165
|
+
`dt:s4/web/cond/layer-ds-modifiers/root` both resolve. The full IRI
|
|
166
|
+
(`<https://ds.canonical.com/global.component.button>`) is accepted too and answers
|
|
167
|
+
identically — reach for it only when the namespace has no declared prefix.
|
|
160
168
|
|
|
161
169
|
Note that `block list` deliberately omits the `ds:Group` class — an audit that counts
|
|
162
170
|
only the list under-counts. The queries below go to the graph directly, so they see
|
|
@@ -166,10 +174,21 @@ groups too.
|
|
|
166
174
|
> output (counts, names, ratios) into documentation, PRs, or this skill.
|
|
167
175
|
|
|
168
176
|
One more live-data rule: before trusting any query, confirm its predicates against the
|
|
169
|
-
current ontology
|
|
170
|
-
`
|
|
171
|
-
|
|
172
|
-
|
|
177
|
+
current ontology. The properties are a section of their own and the flag asks for it —
|
|
178
|
+
`pragma ontology lookup ds` alone prints the classes:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
pragma ontology lookup ds --properties # ds: predicates: usage, summary, hasModifierFamily, …
|
|
182
|
+
pragma ontology lookup dt --properties # dt: predicates: covers, channelOf, …
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Both namespaces matter, and they split along a line worth knowing: the block-side
|
|
186
|
+
predicates live in `ds:`, and the token-side ones — `dt:covers`, `dt:channelOf` — live
|
|
187
|
+
in `dt:`, so a token audit that only checks `ds:` never finds the predicate it needs.
|
|
188
|
+
The vocabulary evolves — for example, `ds:usage` subsumed the former
|
|
189
|
+
`whenToUse`/`whenNotToUse` predicates, and queries against retired names return empty
|
|
190
|
+
tables, not errors. An empty result must be distinguished from a wrong query before it
|
|
191
|
+
becomes a finding.
|
|
173
192
|
|
|
174
193
|
## Audit Dimensions
|
|
175
194
|
|
|
@@ -198,6 +217,84 @@ where the team's practice is right and the standard is not, the finding becomes
|
|
|
198
217
|
proposed change to the standard — the standards are open to contribution, and audits
|
|
199
218
|
are where their gaps surface.
|
|
200
219
|
|
|
220
|
+
### 6. Token Audit
|
|
221
|
+
Which symbols exist, which families rebind them, and which blocks consume them?
|
|
222
|
+
|
|
223
|
+
The token graph is queryable, and a coverage question about tokens is answered there
|
|
224
|
+
rather than by reading stylesheets. The inventory reads first:
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
pragma token list --search focus # which symbols exist around a word
|
|
228
|
+
pragma token list --type color # the population of one type
|
|
229
|
+
pragma token list --channel-of color.text # the channels that provision one symbol
|
|
230
|
+
pragma token consumers --symbol color.text # which blocks consume a symbol, at which key and state
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
**`token list`** is the inventory. `--search <word>` matches name and description
|
|
234
|
+
(`--search focus` answers `## Token (7)`, the focus-ring family and its channel);
|
|
235
|
+
`--type <type>` filters by the symbol's own type; and `--limit` defaults to 300, so a
|
|
236
|
+
count is a PAGE until the output says otherwise. It says so plainly — "Showing 300
|
|
237
|
+
token entries, and more exist", with an `--after` cursor — so never read a count of
|
|
238
|
+
300 as a population; raise `--limit` and read the real one (`--type color` is 473,
|
|
239
|
+
not the 300 the default shows). `--channel-of` takes a SYMBOL, not a family name:
|
|
240
|
+
`--channel-of color.text` answers with `modifier.color.text` and
|
|
241
|
+
`surface.color.text`, the two channels that provision it. A family name there is an `INVALID_INPUT` error that lists the symbols
|
|
242
|
+
it would accept.
|
|
243
|
+
|
|
244
|
+
**A symbol's coverage — which families may rebind it — is `token lookup`'s
|
|
245
|
+
`### Covered by` section**, not `modifier lookup`'s. `pragma modifier lookup
|
|
246
|
+
Criticality` answers with the family's `### Values` (Error, Information, Success,
|
|
247
|
+
Warning) and is the read for what a family offers; `pragma token lookup color.text`
|
|
248
|
+
answers with the families that reach it. Audit from both ends: a family with values
|
|
249
|
+
nothing covers, and a symbol no family covers, are different findings.
|
|
250
|
+
|
|
251
|
+
The family end has no verb of its own — the predicate is `dt:covers`, and the query
|
|
252
|
+
below is the read (the Family Coverage query under Key Queries lists it per family):
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
pragma graph query "SELECT ?symbol WHERE { ds:global.modifier_family.criticality dt:covers ?symbol }"
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
`modifier lookup` renders the family's values and nothing else, so the family's OWN
|
|
259
|
+
documentation fields never appear in it — a family with a blank `ds:summary` looks
|
|
260
|
+
identical to a documented one. For a quality finding about the family itself, inspect
|
|
261
|
+
it: `pragma graph inspect ds:global.modifier_family.criticality`. This is the
|
|
262
|
+
present-but-blank trap again, one level up from the blocks.
|
|
263
|
+
|
|
264
|
+
`pragma variable lookup modifier-color-text` is the third view of the same fact, and
|
|
265
|
+
the most concrete one: one declaration row per modifier, each naming the selector, the
|
|
266
|
+
cascade layer, what it emits and the `file:line` — seventeen rows for that channel,
|
|
267
|
+
which is the family coverage as the stylesheet actually implements it.
|
|
268
|
+
|
|
269
|
+
**`token consumers` answers empty today, and that is a real finding, not a broken
|
|
270
|
+
command.** No pack records which block consumes which symbol so far: the bindings come
|
|
271
|
+
from the anatomies, the anatomies are being rewritten by hand, and the rows appear
|
|
272
|
+
once the authored anatomies are applied to the document and the pack is bumped. Until
|
|
273
|
+
then, do not report "no block consumes this symbol" as a coverage gap — the honest
|
|
274
|
+
finding is that consumption is not yet measurable, and `anatomy-author` is where the
|
|
275
|
+
work that makes it measurable happens.
|
|
276
|
+
|
|
277
|
+
Read the empty answer carefully, because under a `--symbol` filter it is ambiguous by
|
|
278
|
+
construction: it means either that nobody consumes THAT symbol, or that the store holds
|
|
279
|
+
no bindings at all. The filtered message does not distinguish them, and its wording is
|
|
280
|
+
in flux — do not learn it by heart. Run the verb unfiltered to tell them apart:
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
pragma token consumers # the store-wide answer: are there any bindings at all?
|
|
284
|
+
pragma token consumers --symbol color.text # then the one symbol
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
An unfiltered zero settles it — the store has no bindings, so no per-symbol result can
|
|
288
|
+
mean anything yet. Only once the unfiltered read returns rows does a filtered zero
|
|
289
|
+
become a statement about that symbol. A symbol name the store does not know is a
|
|
290
|
+
different outcome again: `INVALID_INPUT`, with the accepted symbols listed, and it
|
|
291
|
+
exits non-zero.
|
|
292
|
+
|
|
293
|
+
The same reads are available as MCP tools — `token_list`, `token_lookup`,
|
|
294
|
+
`token_consumers`, `variable_lookup`, `variable_chain`, `token_values` among them. Take
|
|
295
|
+
the current list from `pragma capabilities` rather than from this paragraph: the
|
|
296
|
+
catalog grows between releases.
|
|
297
|
+
|
|
201
298
|
## Key Queries
|
|
202
299
|
|
|
203
300
|
Documentation-completeness queries must catch BOTH the absent predicate and the empty
|
|
@@ -301,6 +398,23 @@ ORDER BY DESC(?usage)"
|
|
|
301
398
|
**What it asks**: which families are core and which are unused. A zero-usage family is
|
|
302
399
|
a question — premature abstraction, or adoption that has not landed yet?
|
|
303
400
|
|
|
401
|
+
### Consistency: Family Coverage — how many symbols each family rebinds
|
|
402
|
+
|
|
403
|
+
```bash
|
|
404
|
+
pragma graph query "SELECT ?familyName (COUNT(?symbol) as ?symbols) WHERE {
|
|
405
|
+
?family a ds:ModifierFamily ;
|
|
406
|
+
ds:name ?familyName .
|
|
407
|
+
OPTIONAL { ?family dt:covers ?symbol }
|
|
408
|
+
} GROUP BY ?familyName
|
|
409
|
+
ORDER BY DESC(?symbols)"
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
**What it asks**: the family end of the token audit — which families actually rebind
|
|
413
|
+
symbols, and which declare values that reach no symbol at all. Keep the `OPTIONAL` as
|
|
414
|
+
written: without it a family covering nothing drops out of the table, and those zero
|
|
415
|
+
rows are the finding. Pair this with the per-component usage count above — a family can
|
|
416
|
+
be widely covered in the token graph and carried by almost no component, or the reverse.
|
|
417
|
+
|
|
304
418
|
### Consistency: Components Without Modifier Families
|
|
305
419
|
|
|
306
420
|
```bash
|
|
@@ -433,6 +547,16 @@ they MEAN is judged against the team's intent:
|
|
|
433
547
|
"looks" off) and label them differently in the report.
|
|
434
548
|
- Follow up drill-downs with `pragma graph inspect <IRI>` on the specific blocks a
|
|
435
549
|
query surfaced, and `pragma block lookup <Name>` for the human-readable view.
|
|
550
|
+
- `block lookup` takes a DISPLAY name, a `ds:`-prefixed IRI, or a glob — not the bare
|
|
551
|
+
dotted name. A `block list` row prints `ds:apps_lxd.component.meter`; paste it with
|
|
552
|
+
the prefix and it resolves, drop the prefix and it is `ENTITY_NOT_FOUND`.
|
|
553
|
+
- A display name shared across tiers answers with EVERY tier's block, concatenated —
|
|
554
|
+
one `## <Name>` heading and one `- Tier:` line each, and they are DIFFERENT blocks,
|
|
555
|
+
independently authored, not repeats of one. `pragma block lookup Badge` returns the
|
|
556
|
+
global, launchpad and portal Badges in a single answer. Read the `- Tier:` lines,
|
|
557
|
+
count the headings, and pick; an audit that reads only the first heading silently
|
|
558
|
+
scopes itself to one tier. To go straight to one, use its `ds:` IRI
|
|
559
|
+
(`pragma block lookup ds:global.component.badge`).
|
|
436
560
|
|
|
437
561
|
## Limitations
|
|
438
562
|
|
|
@@ -126,19 +126,29 @@ Then, and only then, the breakdown.
|
|
|
126
126
|
1. **Read the spec.**
|
|
127
127
|
- Documented block: `pragma block lookup <Name>` — anatomy, modifiers, properties in
|
|
128
128
|
one read (MCP: block_lookup); `pragma graph inspect <uri>` for the full triple view.
|
|
129
|
-
A bare name
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
129
|
+
A bare name resolves `ds:name` globally, so where several tiers carry the name
|
|
130
|
+
the lookup answers with EVERY one of them — the full writeups concatenated, each
|
|
131
|
+
under its own `## <Name>` heading with its own `- Tier:` line. They are different
|
|
132
|
+
blocks, separately authored, not repeats of one: the global Badge and the
|
|
133
|
+
launchpad Badge have different summaries, properties and anatomies. So the read is
|
|
134
|
+
not "confirm the tier it picked" but "count the headings and pick": scroll the
|
|
135
|
+
whole answer, read every `- Tier:` line, and decide which block you are
|
|
136
|
+
implementing. Stopping at the first heading is how a reader silently implements
|
|
137
|
+
another tier's component.
|
|
138
|
+
|
|
139
|
+
To skip the disambiguation, address one block directly by its `ds:` IRI, which
|
|
140
|
+
`block lookup` accepts:
|
|
134
141
|
|
|
135
142
|
```bash
|
|
143
|
+
pragma block lookup ds:global.component.badge # exactly one block
|
|
136
144
|
pragma graph query "SELECT ?b WHERE { ?b ds:name ?n . FILTER(LCASE(?n) = LCASE('<Name>')) }" # every tier carrying the name
|
|
137
145
|
```
|
|
138
146
|
|
|
139
|
-
|
|
140
|
-
`
|
|
141
|
-
|
|
147
|
+
The bare dotted name is NOT a key: `block list` prints
|
|
148
|
+
`ds:apps_lxd.component.meter`, and pasting that row's name without its `ds:`
|
|
149
|
+
prefix comes back `ENTITY_NOT_FOUND`. Keep the prefix, or use the display name.
|
|
150
|
+
Step 2 derives the package from the tier of the block confirmed HERE, so make
|
|
151
|
+
that choice explicit before moving on.
|
|
142
152
|
|
|
143
153
|
**Check the entry is a spec before building on it — whatever class it is.**
|
|
144
154
|
A row resolving is not the same as a block being documented: many entries
|
|
@@ -175,18 +185,37 @@ Then, and only then, the breakdown.
|
|
|
175
185
|
The inspect renders `ds:hasProperty` only as opaque blank-node labels; for the
|
|
176
186
|
property content use the lookup's Properties section — only when the lookup
|
|
177
187
|
resolved the block you want — or bind the property query to the block confirmed
|
|
178
|
-
above. (A `block list` row prints the `ds:` form
|
|
179
|
-
as-is
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
returns an EMPTY table, not an error.)
|
|
188
|
+
above. (A `block list` row prints the `ds:` form, and both `graph inspect` and a
|
|
189
|
+
SPARQL body take it as-is — a prefixed name carrying dots parses. The full IRI
|
|
190
|
+
(`<https://ds.canonical.com/global.component.button>`) is accepted too, and is
|
|
191
|
+
what `graph query` prints back. What does NOT work is the bracketed prefixed
|
|
192
|
+
form `<ds:…>`: it silently returns an EMPTY table, not an error.)
|
|
184
193
|
|
|
185
194
|
```bash
|
|
186
|
-
pragma graph query "SELECT ?p ?v WHERE {
|
|
195
|
+
pragma graph query "SELECT ?p ?v WHERE { ds:global.component.button ds:hasProperty ?x . ?x ?p ?v }"
|
|
187
196
|
```
|
|
188
197
|
- New block: the `specs/…` file its specify flow produced.
|
|
189
|
-
2. **
|
|
198
|
+
2. **Check whether it is already implemented, before scaffolding anything.** The graph
|
|
199
|
+
records implementations, and a block that already has one is not a scaffolding job:
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
pragma implementation list --search <Name> # which library implements it, on which platform, and the source file
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
A row names the library, the platform and a link to the head of the source. Read
|
|
206
|
+
what it points at before deciding: an implementation on the target platform means
|
|
207
|
+
the work is an EXTENSION of that file, not a new component next to it — and running
|
|
208
|
+
`pragma create` anyway leaves two components for one block. An implementation on
|
|
209
|
+
another platform (a react one when the target is svelte) is still the reference to
|
|
210
|
+
read for API and structure. Only when the search returns nothing for the target
|
|
211
|
+
platform is a fresh scaffold the right move. Search by display name: a match on the
|
|
212
|
+
block name also surfaces the groups built from it, so read the block name on each
|
|
213
|
+
row rather than taking the first.
|
|
214
|
+
|
|
215
|
+
If a same-platform implementation exists and the request was to build a new one,
|
|
216
|
+
that is a decision to raise with the person, not to resolve by scaffolding.
|
|
217
|
+
|
|
218
|
+
3. **Confirm the target package and tier.** The spec names its tier; `pragma tier list`
|
|
190
219
|
shows what exists. Where a package exists for the tier, its name follows a
|
|
191
220
|
convention — the graph carries no package field: `@canonical/<framework>-ds-global`
|
|
192
221
|
for the `global` tier, `@canonical/<framework>-ds-app` for the shared `apps` tier,
|
|
@@ -197,7 +226,7 @@ Then, and only then, the breakdown.
|
|
|
197
226
|
resolves in the workspace before installing or scaffolding into it. Tiers outside
|
|
198
227
|
`global`/`apps*` have no package convention today: there the target package is a
|
|
199
228
|
decision to raise, not to derive.
|
|
200
|
-
|
|
229
|
+
4. **Pull the applicable standards NOW.**
|
|
201
230
|
|
|
202
231
|
```bash
|
|
203
232
|
pragma standard categories # what categories exist today
|
|
@@ -243,11 +272,22 @@ Then, and only then, the breakdown.
|
|
|
243
272
|
pragma graph query "SELECT ?s ?kind ?caption ?code WHERE { ?s cs:hasCategory <http://pragma.canonical.com/codestandards#testing.coverage> . { ?s cs:do ?x . BIND('do' AS ?kind) } UNION { ?s cs:dont ?x . BIND('dont' AS ?kind) } ?x cs:description ?caption . OPTIONAL { ?x cs:code ?code } }"
|
|
244
273
|
```
|
|
245
274
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
275
|
+
Prefixed names with dots parse inside a SPARQL body, so `cs:testing.coverage` and
|
|
276
|
+
`cs:react.component.barrel_exports` can be written in place of the full `<…>` form
|
|
277
|
+
and answer identically. The full form is never wrong, and is what `graph query`
|
|
278
|
+
prints back.
|
|
279
|
+
|
|
280
|
+
**`pragma standard lookup <id>` is not the read path for most standards, so do not
|
|
281
|
+
start there.** It resolves only the standards carrying a `cs:name` title — today a
|
|
282
|
+
few do — and an id taken straight out of `standard list`'s own output
|
|
283
|
+
(`css.selectors.namespace`) comes back `ENTITY_NOT_FOUND` with the standard's title
|
|
284
|
+
offered as a "suggestion", which reads like a typo rather than like the tool
|
|
285
|
+
answering a different question. The reliable pair is the two reads above:
|
|
286
|
+
`pragma standard list --category <c>` for what exists, and the Do/Don't graph query
|
|
287
|
+
for the pairs. `pragma standard sample` has the same title-only limit. Treat a
|
|
288
|
+
`lookup` miss as saying nothing about whether the standard exists — the category
|
|
289
|
+
listing is what says that. (MCP: standard_categories / standard_list / graph_query /
|
|
290
|
+
graph_inspect.)
|
|
251
291
|
|
|
252
292
|
## Scaffold
|
|
253
293
|
|
|
@@ -258,7 +298,7 @@ pragma create component react src/components/Button
|
|
|
258
298
|
- The framework is a tree segment — `pragma create component <framework> <path>` with
|
|
259
299
|
`react`, `svelte`, or `lit` as the segment; the path's final segment is the
|
|
260
300
|
PascalCase component name.
|
|
261
|
-
- Run it from inside the target package confirmed in pre-flight step
|
|
301
|
+
- Run it from inside the target package confirmed in pre-flight step 3 — the path is
|
|
262
302
|
package-relative (in the ds packages, components live at `src/lib/component/<Name>`,
|
|
263
303
|
so the path there is `src/lib/component/Button`, not the generic example above).
|
|
264
304
|
- Plan-first: preview with `--dry-run`, apply non-interactively with `--yes`, reverse
|
|
@@ -294,6 +334,135 @@ standards either way; when no pairs exist, work from those standards' descriptio
|
|
|
294
334
|
A standard you disagree with is feedback for the standards repo, not a license to
|
|
295
335
|
deviate silently.
|
|
296
336
|
|
|
337
|
+
### The variable to write, and what it stands for
|
|
338
|
+
|
|
339
|
+
The stylesheet is where the component meets the tokens, and the seam is queryable — so
|
|
340
|
+
no custom property goes into a stylesheet on a guess. What the reads below cannot do is
|
|
341
|
+
guarantee an answer: a symbol the anatomy names may have no counterpart in the live
|
|
342
|
+
token graph, and that is a finding to raise, not a blank to fill. The rule that follows
|
|
343
|
+
from it is the one to carry through this whole section: a name that does not resolve
|
|
344
|
+
stops the work on that declaration; it never licenses a value.
|
|
345
|
+
|
|
346
|
+
Six reads, each answering one question:
|
|
347
|
+
|
|
348
|
+
```bash
|
|
349
|
+
pragma block lookup Button # the anatomy the implementation owes: its nodes, keys and symbols
|
|
350
|
+
pragma token list --search radius # which symbols exist around a word, when the exact name is unknown
|
|
351
|
+
pragma token lookup color.text # one symbol: its type, description and every definition behind it
|
|
352
|
+
pragma token values --symbol modifier.color.text # what it resolves to at each position
|
|
353
|
+
pragma variable lookup color-text # which CSS variable, declared where, emitting what
|
|
354
|
+
pragma variable chain --variable color-text # what that variable finally reaches
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
**`block lookup`** carries the `### Anatomy (DSL)` section — the structure and the
|
|
358
|
+
style bindings the implementation owes. Read it as the contract, but read it with one
|
|
359
|
+
caveat: the anatomies are being rewritten by hand and written back to the document, and
|
|
360
|
+
until a block's rewrite has landed and the pack has been rebuilt, that section still
|
|
361
|
+
answers with the retired notation (slash paths like `color/text/muted`, `stack`,
|
|
362
|
+
`flow`, and `sth` placeholders). A slash path there is not a symbol to look up — the
|
|
363
|
+
dotted name is, and `anatomy-author` carries the notation in full. The section that
|
|
364
|
+
will list a block's token bindings directly arrives with those bindings; it is not in
|
|
365
|
+
the lookup's output yet.
|
|
366
|
+
|
|
367
|
+
Swapping the slashes for dots is a spelling change, and it is only the first thing to
|
|
368
|
+
try. It succeeds where the symbol kept its name and fails where the taxonomy moved
|
|
369
|
+
under it, and those two failures look identical at the prompt — both are
|
|
370
|
+
`ENTITY_NOT_FOUND`. So a miss on the dotted name is not the end of the read; it is the
|
|
371
|
+
start of a search:
|
|
372
|
+
|
|
373
|
+
```bash
|
|
374
|
+
pragma token list --search radius # the family, under whatever name it has now
|
|
375
|
+
pragma token list --type dimension --limit 1000
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
Three outcomes, and they are different findings. The search turns up the same decision
|
|
379
|
+
under a new name — use it, and say in the PR that the anatomy still carries the old
|
|
380
|
+
one. The search turns up a family that was restructured rather than renamed, so the
|
|
381
|
+
decision the anatomy named no longer exists in that shape — that is a design question
|
|
382
|
+
for the token owners, and it belongs in the PR as one. Or the search turns up nothing
|
|
383
|
+
at all — also a finding, and the same answer: raise it. In none of the three do you
|
|
384
|
+
pick a near-miss symbol or write a raw value, because a token-typed property in the
|
|
385
|
+
anatomy is a design decision already made, and `cs:css.properties.values` — pulled in
|
|
386
|
+
pre-flight — bans a raw value in exactly that place. A blocked declaration named in the
|
|
387
|
+
PR is a better outcome than a stylesheet that resolves and is wrong.
|
|
388
|
+
|
|
389
|
+
**`token list`** is the search read, and it needs its filters to be trusted. It pages
|
|
390
|
+
at 300 rows sorted by name, so the first page of a bare `pragma token list` is colour
|
|
391
|
+
tokens and nothing else — every dimension, number, fontWeight and typography symbol is
|
|
392
|
+
off it. The output says so, in a heading that ends "and more exist" and a closing line
|
|
393
|
+
offering an `--after` cursor, but a bare list piped into `grep` swallows both and reads
|
|
394
|
+
as a system-wide absence. Never conclude "the graph has no such token" from an
|
|
395
|
+
unnarrowed list. Narrow instead: `--search <word>` over name and description,
|
|
396
|
+
`--type <type>` for one type's population, `--channel-of <symbol>` for the channels
|
|
397
|
+
provisioning one symbol (it takes a SYMBOL, not a family name — a family there is an
|
|
398
|
+
`INVALID_INPUT` error that lists what it would accept), and `--limit` raised past 300
|
|
399
|
+
when a full population is what you actually want.
|
|
400
|
+
|
|
401
|
+
**`token lookup <symbol>`** answers with the symbol's `- Type:` and `- Description:`, a
|
|
402
|
+
`### Definitions` list naming the file each definition comes from, a `### Covered by`
|
|
403
|
+
list of the modifier families that may rebind it, and a `### Values` list. That is what
|
|
404
|
+
tells you whether the symbol you are about to consume is the right one — the
|
|
405
|
+
description is written for exactly this decision. It does not tell you which STYLE KEY
|
|
406
|
+
the symbol is legal on: each key admits symbols from its own namespaces, and neither
|
|
407
|
+
`token lookup` nor `token list` knows about that rule. A symbol that resolves here can
|
|
408
|
+
still be the wrong symbol for the property you are writing — `anatomy-author` carries
|
|
409
|
+
the per-key namespaces, and `anatomies validate --authored` is what enforces them.
|
|
410
|
+
|
|
411
|
+
**`token values --symbol <symbol>`** is one row per position. For a channel it shows
|
|
412
|
+
the routing: `modifier.color.text | criticality.error | color.text.error` says that
|
|
413
|
+
under `.error`, reading the channel gets you the error text colour. For a flat symbol
|
|
414
|
+
it shows the resolved value per coordinate, `mode.dark` included.
|
|
415
|
+
|
|
416
|
+
**`variable lookup <name>`** takes the custom property WITHOUT its leading dashes and
|
|
417
|
+
is the read that tells you what to write in CSS. It answers with the `- Symbol:` the
|
|
418
|
+
variable stands for, its `- Tier:` and `- Visibility:`, and a `### Declarations` list:
|
|
419
|
+
one row per declaration, each naming the `selector` it is declared under, the
|
|
420
|
+
`inAtRule` cascade layer, what it `emits`, and the `file:line` it is declared at. A
|
|
421
|
+
`- Visibility: dt:visibility.internal` variable is not a component's to read directly
|
|
422
|
+
— `modifier-color-text` is internal, and a component reads it only as the head of the
|
|
423
|
+
chain the anatomy gives it.
|
|
424
|
+
|
|
425
|
+
The verb has THREE outcomes, and the third is the one that catches people out:
|
|
426
|
+
|
|
427
|
+
1. **It resolves and carries a `- Symbol:` line.** The variable stands for that symbol.
|
|
428
|
+
This is the ordinary case, and the symbol is what you check against the anatomy.
|
|
429
|
+
2. **It resolves and carries NO `- Symbol:` line at all.** The variable is a derived
|
|
430
|
+
one — a state product or a delta, autogenerated rather than authored — and it stands
|
|
431
|
+
for no symbol. `hover--color-foreground-secondary` is one: it resolves, its `emits`
|
|
432
|
+
is an `oklch(from …)` expression, and there is no symbol behind it. Do not read the
|
|
433
|
+
missing line as a failed lookup, and do not treat the variable as a token. Ask what
|
|
434
|
+
it reaches instead:
|
|
435
|
+
|
|
436
|
+
```bash
|
|
437
|
+
pragma variable chain --variable hover--color-foreground-secondary
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
3. **`ENTITY_NOT_FOUND`.** The graph has never heard of the name.
|
|
441
|
+
|
|
442
|
+
That third outcome does NOT mean "yours to invent". It means one of two things, and
|
|
443
|
+
which one depends on the anatomy. For a property the anatomy never mentions —
|
|
444
|
+
`button-gap`, `icon-size`, a local alias the stylesheet declares for its own
|
|
445
|
+
convenience — it is genuinely component-local: yours to declare, standing for no token,
|
|
446
|
+
and that is the end of it. But for a token-typed property the anatomy DOES name, an
|
|
447
|
+
unresolved name is a gap between the anatomy and the token graph: either the anatomy is
|
|
448
|
+
still in the retired notation, and the rewrite has not landed for that block yet, or
|
|
449
|
+
the token was retired. Neither is a licence to write a value. Stop that declaration and
|
|
450
|
+
raise it, by the rule three paragraphs up.
|
|
451
|
+
|
|
452
|
+
So the question to ask of every `ENTITY_NOT_FOUND` is not "is it in the graph" but
|
|
453
|
+
"does the anatomy name it". The anatomy names it: raise it. The anatomy is silent:
|
|
454
|
+
declare it locally.
|
|
455
|
+
|
|
456
|
+
**`variable chain --variable <name>`** is the transitive walk — every
|
|
457
|
+
`variable | variable | symbol` triple the variable reaches through what its
|
|
458
|
+
declarations reference. Use it when `lookup`'s `emits` is another `var()` and you need
|
|
459
|
+
to know where the indirection ends: `color-text` reaches `color.palette.black` and
|
|
460
|
+
`color.palette.white`, which is `light-dark()` spelled out.
|
|
461
|
+
|
|
462
|
+
The same reads are MCP tools — `block_lookup`, `token_list`, `token_lookup`,
|
|
463
|
+
`token_values`, `variable_lookup`, `variable_chain` — taking the same arguments.
|
|
464
|
+
`pragma capabilities` prints the current catalog, which grows between releases.
|
|
465
|
+
|
|
297
466
|
## Post-flight
|
|
298
467
|
|
|
299
468
|
- Fill in the stories and tests the scaffold stubbed — the spec's properties, modifiers,
|
|
@@ -162,12 +162,29 @@ Before anything is invented, find what already exists:
|
|
|
162
162
|
|
|
163
163
|
```bash
|
|
164
164
|
pragma block list # every component, pattern, layout and subcomponent, with its type and tier
|
|
165
|
-
pragma block lookup <Name-or-glob> # full spec of candidates: anatomy, modifiers, properties (MCP: block_lookup)
|
|
165
|
+
pragma block lookup <Name-or-glob> # full spec of candidates: anatomy, modifiers, properties (MCP: block_lookup)
|
|
166
166
|
pragma block sample # real entry shapes — read these BEFORE writing queries
|
|
167
167
|
pragma modifier list # the modifier families blocks draw from
|
|
168
168
|
pragma tier list # the tiers a block can live in
|
|
169
169
|
```
|
|
170
170
|
|
|
171
|
+
**`block lookup` fans a shared name out across tiers, and the repeats are not
|
|
172
|
+
repeats.** A display name several tiers carry — or a glob matching them — answers with
|
|
173
|
+
one full writeup per tier, each under its own `## <Name>` heading with its own
|
|
174
|
+
`- Tier:` line, and those are DIFFERENT blocks: `Badge` returns the global, launchpad
|
|
175
|
+
and portal Badges, three independently authored specs with different summaries,
|
|
176
|
+
properties and anatomies. For this step that matters twice over. The answer is the
|
|
177
|
+
prior art, so skipping past the second and third headings as noise is how an
|
|
178
|
+
apps-tier block that already does the job goes unnoticed — read every one. And an
|
|
179
|
+
apps-tier block carrying the name is a different verdict from a global one: the first
|
|
180
|
+
may be a promotion candidate, the second means the gap is not a gap.
|
|
181
|
+
|
|
182
|
+
Three key forms, and only three: the display name, the `ds:`-prefixed IRI
|
|
183
|
+
(`pragma block lookup ds:global.component.badge`, which answers with exactly one
|
|
184
|
+
block), and a glob. The bare dotted name is not one of them — `block list` prints
|
|
185
|
+
`ds:apps_lxd.component.meter`, and pasting that row without its `ds:` prefix comes
|
|
186
|
+
back `ENTITY_NOT_FOUND`.
|
|
187
|
+
|
|
171
188
|
Search by name fragment when the naming is uncertain:
|
|
172
189
|
|
|
173
190
|
```bash
|
|
@@ -177,6 +194,16 @@ pragma graph query "SELECT ?b ?name WHERE { ?b ds:name ?name . FILTER(CONTAINS(L
|
|
|
177
194
|
> The covered set is whatever the graph answers today. Query it live — never copy its
|
|
178
195
|
> output into documentation, PRs, or this skill.
|
|
179
196
|
|
|
197
|
+
That query matches `ds:name` on ANY entity, so its rows are not necessarily blocks —
|
|
198
|
+
a modifier value (`ds:global.modifier.in_progress`) and a documentation tag will come
|
|
199
|
+
back alongside them, and neither is prior art. A non-empty table can still mean "no
|
|
200
|
+
block of this name exists". Read each row's IRI, or bind the type when the name is
|
|
201
|
+
noisy:
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
pragma graph query "SELECT ?b ?name ?type WHERE { VALUES ?type { ds:Component ds:Pattern ds:Layout ds:Subcomponent ds:Group } ?b a ?type ; ds:name ?name . FILTER(CONTAINS(LCASE(?name), 'crumb')) }"
|
|
205
|
+
```
|
|
206
|
+
|
|
180
207
|
Outcome gate: **either "exists — stop or extend it" or a NAMED gap.** No spec is written
|
|
181
208
|
without one of those two sentences, naming the blocks that were checked.
|
|
182
209
|
|
|
@@ -185,11 +212,17 @@ without one of those two sentences, naming the blocks that were checked.
|
|
|
185
212
|
Read the shape the entry must satisfy:
|
|
186
213
|
|
|
187
214
|
```bash
|
|
188
|
-
pragma ontology lookup ds # the design-system vocabulary
|
|
215
|
+
pragma ontology lookup ds # the design-system vocabulary: its CLASSES
|
|
216
|
+
pragma ontology lookup ds --properties # the predicates an entry carries — a section of its own, behind the flag
|
|
189
217
|
pragma ontology lookup ds --class UIBlock # the block-level properties every entry carries
|
|
190
218
|
pragma ontology lookup ds --class Component # what Component itself declares
|
|
191
219
|
```
|
|
192
220
|
|
|
221
|
+
The bare `ontology lookup ds` prints the classes and stops there; the predicates come
|
|
222
|
+
only with `--properties`. So a field name checked against the bare output looks absent
|
|
223
|
+
when it is not — confirm `ds:usage`, `ds:guidelines`, `ds:hasProperty` and the rest
|
|
224
|
+
against the properties section before writing a query or a spec field around them.
|
|
225
|
+
|
|
193
226
|
`--class` shows only what a class declares itself — usage, guidelines, properties,
|
|
194
227
|
and tier are declared on `ds:UIBlock` and inherited by its subclasses; `summary` and
|
|
195
228
|
`name` sit further up the chain on `ds:Entity`
|
|
@@ -281,19 +314,98 @@ Delegate to the `anatomy-author` skill:
|
|
|
281
314
|
pragma skill lookup anatomy-author
|
|
282
315
|
```
|
|
283
316
|
|
|
317
|
+
**Read the repository's copy, not only the printed one, and prefer it where they
|
|
318
|
+
differ.** `skills/anatomy-author/SKILL.md` in canonical/design-system is the authority;
|
|
319
|
+
the copy `pragma skill lookup` prints is bundled into a pragma release and lags the
|
|
320
|
+
repository until the next one. So a section this step names and the printout does not
|
|
321
|
+
show is old text in the printout, not a section that is missing — open the repository
|
|
322
|
+
file before concluding anything is absent.
|
|
323
|
+
|
|
284
324
|
The skill covers named and anonymous nodes, edges with cardinality, slot names, and
|
|
285
325
|
CTI-inspired style keys; the full ANATOMY_DSL_SPEC ships beside it as
|
|
286
326
|
`ANATOMY_DSL_SPEC.md` in the installed `anatomy-author` skill folder (the lookup
|
|
287
|
-
renders SKILL.md only — open that file directly for the complete spec).
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
327
|
+
renders SKILL.md only — open that file directly for the complete spec).
|
|
328
|
+
|
|
329
|
+
**A modifier family the spec claims is expressed in the anatomy by CONSUMING its
|
|
330
|
+
channel, never by naming it.** There is no style key, `@state` or `switch`
|
|
331
|
+
discriminator that takes a family name, so an anatomy that supports Criticality on its
|
|
332
|
+
fill colour says so by binding the channel of the symbol the fill reads —
|
|
333
|
+
`appearance.background: [modifier.color.foreground.primary, color.foreground.primary]`
|
|
334
|
+
for a filled surface, `typography.color: [modifier.color.text, color.text]` for text.
|
|
335
|
+
Which channels exist is the token graph's answer, not a guess:
|
|
336
|
+
`pragma token list --channel-of color.background` reports a surface channel and no
|
|
337
|
+
modifier one, so `modifier.color.background` is not a symbol and cannot be bound. The
|
|
338
|
+
family lands in
|
|
339
|
+
the channel: `pragma token values --symbol modifier.color.text` shows
|
|
340
|
+
`anticipation.caution` routing to `color.text.warning`, which is how Button's
|
|
341
|
+
Anticipation support reaches its text without Button's anatomy ever saying
|
|
342
|
+
"Anticipation". So when step 6 recorded a Modifier Families section, this step's job is
|
|
343
|
+
to name, per family, WHICH key carries it and which channel that key reads — and to
|
|
344
|
+
check the family actually covers that symbol (`pragma token lookup <symbol>`, the
|
|
345
|
+
`### Covered by` list). A family covering none of the symbols the anatomy binds is a
|
|
346
|
+
finding for the token owners, not something to express in the tree.
|
|
347
|
+
|
|
348
|
+
**Where the produced DSL lands.** An anatomy is a file of its own, not a section of
|
|
349
|
+
this spec: it goes to `anatomies/authored/<tier>/<uri>.yaml` in canonical/design-system,
|
|
350
|
+
with the file name spelling the dotted uri. There it is checked offline with
|
|
351
|
+
`bun src/cli.ts anatomies validate --authored`, reviewed as a file in a pull request,
|
|
352
|
+
and written to the block's `anatomy_dsl` cell by `anatomies write`; after that write the
|
|
353
|
+
document is the source of record. Never write into design-system `data/`, which the
|
|
354
|
+
pull sync regenerates. `anatomy-author`'s "Where the anatomy lands" section is the
|
|
355
|
+
authority on that path — this step's job is to hand it a specified component and take
|
|
356
|
+
back the file name it wrote.
|
|
357
|
+
|
|
358
|
+
### 8. Pair with tokens
|
|
359
|
+
|
|
360
|
+
Tokens here means token symbols — `color.text`, `dimension.200` — never CSS variables.
|
|
361
|
+
A variable such as `--color-text` is the web platform's name for a symbol, one name per
|
|
362
|
+
platform, and it is the implementer's concern: the anatomy names the symbol, and
|
|
363
|
+
`implement-component` reads `pragma variable lookup` to find what to write in CSS. A spec
|
|
364
|
+
that named variables would be tied to one platform and would miss every symbol the web
|
|
365
|
+
has not emitted yet.
|
|
366
|
+
|
|
367
|
+
The spec does not bind tokens — that is the anatomy's job, one style key at a time. What
|
|
368
|
+
this step owes is the check that the symbols the component will need actually exist, so
|
|
369
|
+
a specification does not promise a colour or a spacing role the token graph has never
|
|
370
|
+
declared:
|
|
292
371
|
|
|
293
|
-
|
|
372
|
+
```bash
|
|
373
|
+
pragma token list --search focus # which symbols exist around a word
|
|
374
|
+
pragma token lookup color.text # one symbol in full: type, description, definitions
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
`token list` pages at 300 rows sorted by name, so a bare `pragma token list` returns
|
|
378
|
+
colour tokens and nothing else — every dimension, number and typography symbol is off
|
|
379
|
+
the first page, behind an "and more exist" heading and an `--after` cursor that a pipe
|
|
380
|
+
into `grep` swallows. Always narrow (`--search`, `--type`) or raise `--limit` before
|
|
381
|
+
concluding a family is absent; an unnarrowed list is not evidence.
|
|
382
|
+
|
|
383
|
+
A name that comes back `ENTITY_NOT_FOUND` is a finding for the spec — either the
|
|
384
|
+
component reads an existing symbol instead, or a new token is a decision to raise with
|
|
385
|
+
the token owners, and either answer belongs in the spec rather than in the anatomy that
|
|
386
|
+
follows. (MCP: `token_list`, `token_lookup`.)
|
|
387
|
+
|
|
388
|
+
**`token lookup` resolving is the FIRST check, not the whole one.** It answers whether a
|
|
389
|
+
symbol exists; it says nothing about which style key the symbol may go on. Each key
|
|
390
|
+
admits symbols from one namespace only, and a symbol that reads as exactly on-topic can
|
|
391
|
+
still be outside it: `typography.text.tertiary` is a real composite typography token and
|
|
392
|
+
"12px tertiary text" is exactly what a small label wants, yet `typography.size` admits
|
|
393
|
+
`dimension.` symbols alone, so the binding is unlawful and
|
|
394
|
+
`dimension.size.fontSize.250` is what belongs there. Neither `token lookup` nor
|
|
395
|
+
`token list` knows that rule.
|
|
396
|
+
|
|
397
|
+
So the pairing has two checks, in order: `token lookup <symbol>` for existence, then the
|
|
398
|
+
anatomy gate for admissibility.
|
|
399
|
+
|
|
400
|
+
```bash
|
|
401
|
+
bun src/cli.ts anatomies validate --authored # in canonical/design-system
|
|
402
|
+
```
|
|
294
403
|
|
|
295
|
-
|
|
296
|
-
|
|
404
|
+
It names the file, the node, the key, the symbol and the namespaces the key admits. Run
|
|
405
|
+
it before reporting step 8 as done, and treat a namespace rejection the way you treat an
|
|
406
|
+
`ENTITY_NOT_FOUND`: a finding to resolve against the roster
|
|
407
|
+
(`node_modules/@canonical/anatomy-dsl/definitions/style-keys.yaml`, which states the
|
|
408
|
+
`valueKind` and the namespace per key), never a value to force through.
|
|
297
409
|
|
|
298
410
|
## Response format
|
|
299
411
|
|
|
@@ -309,8 +421,8 @@ Spec: specs/<tier>.<type>.<snake_name>.md
|
|
|
309
421
|
- [ ] 4. Benchmarked against: … (adopt/reject decisions stated)
|
|
310
422
|
- [ ] 5. State gate: fired/not fired (States & interaction section: yes/no)
|
|
311
423
|
- [ ] 6. Documentation written to the sync-safe location
|
|
312
|
-
- [ ] 7. Anatomy DSL written via anatomy-author
|
|
313
|
-
- [ ] 8. Token pairing:
|
|
424
|
+
- [ ] 7. Anatomy DSL written via anatomy-author (file: anatomies/authored/…)
|
|
425
|
+
- [ ] 8. Token pairing: symbols checked against the token graph AND the anatomy gate run (findings: …)
|
|
314
426
|
```
|
|
315
427
|
|
|
316
428
|
## Related skills
|