@canonical/pragma-cli 0.35.0 → 0.36.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 +2 -2
- package/bundled-skills/add-standard/SKILL.md +338 -0
- package/bundled-skills/adoption-a1-styles/SKILL.md +269 -0
- package/bundled-skills/adoption-a2-components/SKILL.md +291 -0
- package/bundled-skills/adoption-a3-forms/SKILL.md +260 -0
- package/bundled-skills/anatomy-author/ANATOMY_DSL_SPEC.md +406 -0
- package/bundled-skills/anatomy-author/SKILL.md +1226 -0
- package/bundled-skills/design-auditor/SKILL.md +455 -0
- package/bundled-skills/implement-component/SKILL.md +333 -0
- package/bundled-skills/specify-component/SKILL.md +331 -0
- package/bundled-skills/specify-pattern/SKILL.md +292 -0
- package/dist/package.json +16 -15
- package/dist/pragma.conf.js +236 -34
- package/dist/pragma.conf.js.map +1 -1
- package/dist/src/bin.js +1 -1
- package/dist/src/bin.js.map +1 -1
- package/dist/src/capabilities/colophon/colophon.render.js +1 -1
- package/dist/src/capabilities/colophon/colophon.render.js.map +1 -1
- package/dist/src/capabilities/create/mount.js +4 -3
- package/dist/src/capabilities/create/mount.js.map +1 -1
- package/dist/src/capabilities/doctor/checks/checkPackageRefs.js +60 -4
- package/dist/src/capabilities/doctor/checks/checkPackageRefs.js.map +1 -1
- package/dist/src/capabilities/doctor/checks/checkShellCompletions.js +8 -8
- package/dist/src/capabilities/doctor/checks/checkShellCompletions.js.map +1 -1
- package/dist/src/capabilities/doctor/checks/harnessInventory.js +195 -0
- package/dist/src/capabilities/doctor/checks/harnessInventory.js.map +1 -0
- package/dist/src/capabilities/doctor/checks/index.js +6 -6
- package/dist/src/capabilities/doctor/checks/targetHealth.js +194 -50
- package/dist/src/capabilities/doctor/checks/targetHealth.js.map +1 -1
- package/dist/src/capabilities/doctor/doctor.render.js +43 -64
- package/dist/src/capabilities/doctor/doctor.render.js.map +1 -1
- package/dist/src/capabilities/doctor/doctor.verb.js +6 -2
- package/dist/src/capabilities/doctor/doctor.verb.js.map +1 -1
- package/dist/src/capabilities/doctor/runChecks.js +14 -11
- package/dist/src/capabilities/doctor/runChecks.js.map +1 -1
- package/dist/src/capabilities/graph/query.render.js +2 -2
- package/dist/src/capabilities/graph/query.render.js.map +1 -1
- package/dist/src/capabilities/info/collectInfo.js +8 -2
- package/dist/src/capabilities/info/collectInfo.js.map +1 -1
- package/dist/src/capabilities/info/info.render.js +6 -2
- package/dist/src/capabilities/info/info.render.js.map +1 -1
- package/dist/src/capabilities/prompt/prompt.render.js +2 -2
- package/dist/src/capabilities/prompt/prompt.render.js.map +1 -1
- package/dist/src/capabilities/setup/buildPlan.js +43 -39
- package/dist/src/capabilities/setup/buildPlan.js.map +1 -1
- package/dist/src/capabilities/setup/mode.js +2 -2
- package/dist/src/capabilities/setup/operations/index.js +4 -4
- package/dist/src/capabilities/setup/operations/index.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupGenerator.js +92 -45
- package/dist/src/capabilities/setup/operations/setupGenerator.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupLsp.js +88 -36
- package/dist/src/capabilities/setup/operations/setupLsp.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupMcp.js +97 -51
- package/dist/src/capabilities/setup/operations/setupMcp.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupSkills.js +325 -47
- package/dist/src/capabilities/setup/operations/setupSkills.js.map +1 -1
- package/dist/src/capabilities/setup/plan.js.map +1 -1
- package/dist/src/capabilities/setup/plan.render.js +144 -66
- package/dist/src/capabilities/setup/plan.render.js.map +1 -1
- package/dist/src/capabilities/setup/setup.render.js +1 -1
- package/dist/src/capabilities/setup/setup.verb.js +86 -33
- package/dist/src/capabilities/setup/setup.verb.js.map +1 -1
- package/dist/src/capabilities/setup/targets.js +110 -45
- package/dist/src/capabilities/setup/targets.js.map +1 -1
- package/dist/src/capabilities/shared/index.js +6 -5
- package/dist/src/capabilities/shared/index.js.map +1 -1
- package/dist/src/capabilities/shared/packageManager.js +300 -54
- package/dist/src/capabilities/shared/packageManager.js.map +1 -1
- package/dist/src/capabilities/skill/discover.js +97 -11
- package/dist/src/capabilities/skill/discover.js.map +1 -1
- package/dist/src/capabilities/skill/render.js +2 -2
- package/dist/src/capabilities/skill/render.js.map +1 -1
- package/dist/src/capabilities/sources/installSkills.js +145 -3
- package/dist/src/capabilities/sources/installSkills.js.map +1 -1
- package/dist/src/capabilities/sources/runUpdate.js +68 -2
- package/dist/src/capabilities/sources/runUpdate.js.map +1 -1
- package/dist/src/capabilities/sources/update.verb.js +3 -3
- package/dist/src/capabilities/sources/update.verb.js.map +1 -1
- package/dist/src/capabilities/upgrade/runUpgrade.js +43 -7
- package/dist/src/capabilities/upgrade/runUpgrade.js.map +1 -1
- package/dist/src/capabilities/upgrade/upgrade.render.js +10 -2
- package/dist/src/capabilities/upgrade/upgrade.render.js.map +1 -1
- package/dist/src/constants.js +6 -1
- package/dist/src/constants.js.map +1 -1
- package/dist/src/kernel/index.js +11 -2
- package/dist/src/kernel/index.js.map +1 -1
- package/dist/src/kernel/interactivity.js +68 -0
- package/dist/src/kernel/interactivity.js.map +1 -0
- package/dist/src/kernel/packs/renderPack.js +3 -3
- package/dist/src/kernel/packs/renderPack.js.map +1 -1
- package/dist/src/kernel/packs/resolveEntity.js +63 -12
- package/dist/src/kernel/packs/resolveEntity.js.map +1 -1
- package/dist/src/kernel/packs/runBodies.js +57 -4
- package/dist/src/kernel/packs/runBodies.js.map +1 -1
- package/dist/src/kernel/packs/schema.js +54 -2
- package/dist/src/kernel/packs/schema.js.map +1 -1
- package/dist/src/kernel/packs/sparql/applyFilters.js +104 -5
- package/dist/src/kernel/packs/sparql/applyFilters.js.map +1 -1
- package/dist/src/kernel/packs/sparql/buildLookupQuery.js +306 -43
- package/dist/src/kernel/packs/sparql/buildLookupQuery.js.map +1 -1
- package/dist/src/kernel/packs/types.js.map +1 -1
- package/dist/src/kernel/project/cli/buildProgram.js +1 -1
- package/dist/src/kernel/project/cli/buildProgram.js.map +1 -1
- package/dist/src/kernel/project/cli/dispatch.js +23 -23
- package/dist/src/kernel/project/cli/dispatch.js.map +1 -1
- package/dist/src/kernel/project/cli/globalFlags.js +4 -1
- package/dist/src/kernel/project/cli/globalFlags.js.map +1 -1
- package/dist/src/kernel/project/cli/helpFormat.js +1 -2
- package/dist/src/kernel/project/cli/helpFormat.js.map +1 -1
- package/dist/src/kernel/project/cli/rootHelp.js +34 -4
- package/dist/src/kernel/project/cli/rootHelp.js.map +1 -1
- package/dist/src/kernel/project/mcp/registerVerb.js +16 -1
- package/dist/src/kernel/project/mcp/registerVerb.js.map +1 -1
- package/dist/src/kernel/render/renderers.js +1 -1
- package/dist/src/kernel/render/style.js +29 -9
- package/dist/src/kernel/render/style.js.map +1 -1
- package/dist/src/kernel/render/vocabulary.js +174 -0
- package/dist/src/kernel/render/vocabulary.js.map +1 -0
- package/dist/src/kernel/spec/emitReference.js +1 -1
- package/dist/src/kernel/spec/emitReference.js.map +1 -1
- package/package.json +16 -15
- package/pragma.conf.ts +241 -34
- package/src/bin.ts +8 -1
- package/src/capabilities/block.parity.test.ts +25 -11
- package/src/capabilities/block.shipped.exec.test.ts +282 -0
- package/src/capabilities/block.tierRank.exec.test.ts +300 -0
- package/src/capabilities/colophon/colophon.render.ts +1 -2
- package/src/capabilities/colophon/colophon.test.ts +2 -2
- package/src/capabilities/create/createGrammar.test.ts +1 -1
- package/src/capabilities/create/mount.ts +3 -3
- package/src/capabilities/distribution.parity.test.ts +4 -0
- package/src/capabilities/doctor/checks/checkPackageRefs.ts +69 -4
- package/src/capabilities/doctor/checks/checkShellCompletions.test.ts +6 -4
- package/src/capabilities/doctor/checks/checkShellCompletions.ts +8 -8
- package/src/capabilities/doctor/checks/harnessInventory.test.ts +219 -0
- package/src/capabilities/doctor/checks/harnessInventory.ts +298 -0
- package/src/capabilities/doctor/checks/index.ts +6 -6
- package/src/capabilities/doctor/checks/targetHealth.ts +229 -59
- package/src/capabilities/doctor/doctor.render.test.ts +108 -32
- package/src/capabilities/doctor/doctor.render.ts +56 -80
- package/src/capabilities/doctor/doctor.test.ts +247 -35
- package/src/capabilities/doctor/doctor.verb.ts +7 -2
- package/src/capabilities/doctor/runChecks.ts +14 -11
- package/src/capabilities/doctor/types.ts +15 -24
- package/src/capabilities/emptyRecovery.test.ts +10 -2
- package/src/capabilities/graph/query.render.ts +2 -2
- package/src/capabilities/info/collectInfo.ts +8 -1
- package/src/capabilities/info/info.render.ts +6 -2
- package/src/capabilities/info/info.test.ts +37 -1
- package/src/capabilities/info/types.ts +10 -2
- package/src/capabilities/prompt/prompt.render.ts +2 -2
- package/src/capabilities/renderVocabularySync.test.ts +82 -0
- package/src/capabilities/scopeTypeSync.test.ts +29 -15
- package/src/capabilities/setup/buildPlan.ts +45 -41
- package/src/capabilities/setup/index.ts +1 -1
- package/src/capabilities/setup/mode.ts +2 -2
- package/src/capabilities/setup/operations/index.ts +6 -1
- package/src/capabilities/setup/operations/setupGenerator.ts +144 -70
- package/src/capabilities/setup/operations/setupLsp.ts +129 -37
- package/src/capabilities/setup/operations/setupMcp.ts +132 -61
- package/src/capabilities/setup/operations/setupSkills.ts +392 -58
- package/src/capabilities/setup/plan.render.ts +171 -76
- package/src/capabilities/setup/plan.ts +17 -12
- package/src/capabilities/setup/setup.mcp.correctness.test.ts +9 -9
- package/src/capabilities/setup/setup.render.test.ts +50 -36
- package/src/capabilities/setup/setup.render.ts +1 -1
- package/src/capabilities/setup/setup.test.ts +881 -50
- package/src/capabilities/setup/setup.verb.ts +91 -33
- package/src/capabilities/setup/targets.ts +120 -52
- package/src/capabilities/setup/types.ts +10 -18
- package/src/capabilities/shared/index.ts +17 -6
- package/src/capabilities/shared/packageManager.test.ts +421 -6
- package/src/capabilities/shared/packageManager.ts +394 -59
- package/src/capabilities/skill/bundledSkills.test.ts +347 -0
- package/src/capabilities/skill/discover.ts +100 -11
- package/src/capabilities/skill/render.ts +2 -2
- package/src/capabilities/skill/skill.test.ts +17 -4
- package/src/capabilities/sources/installSkills.ts +181 -3
- package/src/capabilities/sources/runUpdate.ts +78 -2
- package/src/capabilities/sources/sources.test.ts +228 -0
- package/src/capabilities/sources/update.verb.ts +3 -3
- package/src/capabilities/surface.test.ts +2 -2
- package/src/capabilities/upgrade/runUpgrade.ts +45 -6
- package/src/capabilities/upgrade/types.ts +10 -2
- package/src/capabilities/upgrade/upgrade.render.ts +9 -2
- package/src/capabilities/upgrade/upgrade.test.ts +72 -0
- package/src/constants.ts +6 -1
- package/src/identity.test.ts +18 -5
- package/src/kernel/completion/entitySource.test.ts +15 -2
- package/src/kernel/completion/safety.test.ts +16 -9
- package/src/kernel/config/defaults.test.ts +2 -1
- package/src/kernel/index.ts +11 -2
- package/src/kernel/interactivity.test.ts +76 -0
- package/src/kernel/interactivity.ts +69 -0
- package/src/kernel/packs/compile.test.ts +92 -0
- package/src/kernel/packs/renderPack.ts +3 -3
- package/src/kernel/packs/resolveEntity.test.ts +75 -14
- package/src/kernel/packs/resolveEntity.ts +88 -24
- package/src/kernel/packs/runBodies.ts +84 -19
- package/src/kernel/packs/schema.ts +60 -4
- package/src/kernel/packs/sparql/applyFilters.ts +125 -4
- package/src/kernel/packs/sparql/buildLookupQuery.test.ts +290 -0
- package/src/kernel/packs/sparql/buildLookupQuery.ts +323 -45
- package/src/kernel/packs/toolDescription.test.ts +35 -1
- package/src/kernel/packs/types.ts +125 -2
- package/src/kernel/project/cli/buildProgram.test.ts +73 -2
- package/src/kernel/project/cli/buildProgram.ts +8 -1
- package/src/kernel/project/cli/dispatch.test.ts +5 -4
- package/src/kernel/project/cli/dispatch.ts +25 -24
- package/src/kernel/project/cli/globalFlags.ts +4 -1
- package/src/kernel/project/cli/helpFormat.ts +1 -2
- package/src/kernel/project/cli/rootHelp.ts +36 -3
- package/src/kernel/project/mcp/registerVerb.ts +20 -1
- package/src/kernel/render/renderers.ts +1 -1
- package/src/kernel/render/style.ts +32 -9
- package/src/kernel/render/vocabulary.ts +276 -0
- package/src/kernel/spec/emitReference.ts +1 -1
- package/src/kernel/spec/types.ts +35 -6
- package/src/testing/PARITY_GAPS.ts +9 -3
- package/src/testing/behavioral/docExamples.test.ts +4 -2
- package/src/testing/behavioral/errorMatrix.mcp.test.ts +110 -7
- package/src/testing/behavioral/journeys.firstInstall.test.ts +7 -2
- package/src/testing/behavioral/journeys.packageStories.test.ts +6 -3
- package/src/testing/eval/__snapshots__/eval.test.ts.snap +26 -1
- package/src/testing/eval/cases/readNouns.ts +245 -9
- package/src/testing/fixtures/blockGraph.ts +28 -13
- package/src/testing/fixtures/graph/canonical.ts +95 -12
- package/dist/src/capabilities/shared/bands.js +0 -16
- package/dist/src/capabilities/shared/bands.js.map +0 -1
- package/src/capabilities/shared/bands.ts +0 -16
package/README.md
CHANGED
|
@@ -147,7 +147,7 @@ pragma setup
|
|
|
147
147
|
pragma doctor
|
|
148
148
|
```
|
|
149
149
|
|
|
150
|
-
`pragma setup` is one wizard for the whole environment: MCP registration,
|
|
150
|
+
`pragma setup` is one wizard for the whole environment: your config file, MCP registration, TAB completion, agent skills, and the editor extension. Each installer can configure your home directory (global, the default), this project alone, or both — `--scope project|global|both`, with `--global`/`--local` as shorthands. Preview everything it would write with `pragma setup --dry-run`, or run one installer directly: `pragma setup mcp`, `setup completions`, `setup skills`, `setup lsp`.
|
|
151
151
|
|
|
152
152
|
The LSP step installs the Terrazzo extension, and the extension's own log is the fastest way to confirm it took. Open your editor's Output panel, select the `terrazzo-lsp` channel, and look for a startup block like this (timestamps dropped, paths shortened):
|
|
153
153
|
|
|
@@ -162,7 +162,7 @@ The LSP step installs the Terrazzo extension, and the extension's own log is the
|
|
|
162
162
|
|
|
163
163
|
The token count is the line to read: `terrazzo-lsp ready` says the server started, but a run that loaded 0 tokens resolved its artifact path to nothing and will complete nothing. With tokens loaded, type `color: var(--` in a stylesheet — the design tokens should appear as completions.
|
|
164
164
|
|
|
165
|
-
`pragma doctor` checks the environment (Node version, store health, registrations) and
|
|
165
|
+
`pragma doctor` checks the environment (Node version, store health, registrations) globally and in this project, and names the next step on every row that has one. `pragma info` shows the version, the configuration in effect, and update status; `pragma upgrade` updates the CLI itself.
|
|
166
166
|
|
|
167
167
|
## Point it at your own design system
|
|
168
168
|
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: add-standard
|
|
3
|
+
description: Create and add a new code standard to the code-standards package
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Add Standard
|
|
7
|
+
|
|
8
|
+
Create and add a new code standard to the code-standards package.
|
|
9
|
+
|
|
10
|
+
## When to Use
|
|
11
|
+
|
|
12
|
+
Use this skill when:
|
|
13
|
+
- "Add a standard for..."
|
|
14
|
+
- "Create a coding standard..."
|
|
15
|
+
- "Document a new convention..."
|
|
16
|
+
- "Add guidance for..."
|
|
17
|
+
|
|
18
|
+
## Workflow
|
|
19
|
+
|
|
20
|
+
### 1. Check for Existing Standards
|
|
21
|
+
|
|
22
|
+
Before creating a new standard, always check if one already exists:
|
|
23
|
+
|
|
24
|
+
```sparql
|
|
25
|
+
PREFIX cs: <http://pragma.canonical.com/codestandards#>
|
|
26
|
+
|
|
27
|
+
SELECT ?standard ?description WHERE {
|
|
28
|
+
?standard a cs:CodeStandard ;
|
|
29
|
+
cs:description ?description .
|
|
30
|
+
FILTER(CONTAINS(LCASE(STR(?standard)), "your-topic"))
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Or use lookup:
|
|
35
|
+
```
|
|
36
|
+
sem_lookup(type: "cs:CodeStandard", filters: {"@id": {"$contains": "your-topic"}})
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### 2. Determine the Category
|
|
40
|
+
|
|
41
|
+
List existing categories to find the right fit:
|
|
42
|
+
|
|
43
|
+
```sparql
|
|
44
|
+
PREFIX cs: <http://pragma.canonical.com/codestandards#>
|
|
45
|
+
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
|
46
|
+
|
|
47
|
+
SELECT ?category ?label ?slug WHERE {
|
|
48
|
+
?category a cs:Category ;
|
|
49
|
+
rdfs:label ?label ;
|
|
50
|
+
cs:slug ?slug .
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Available Categories:**
|
|
55
|
+
|
|
56
|
+
| Category | Slug | Description |
|
|
57
|
+
|----------|------|-------------|
|
|
58
|
+
| React | `react` | React component development |
|
|
59
|
+
| CSS | `css` | CSS technical implementation |
|
|
60
|
+
| Styling | `styling` | Design system styling patterns |
|
|
61
|
+
| Code | `code` | General TypeScript standards |
|
|
62
|
+
| Storybook | `storybook` | Storybook documentation |
|
|
63
|
+
| Icons | `icons` | Icon implementation |
|
|
64
|
+
| Packaging | `packaging` | Package structure and exports |
|
|
65
|
+
| Rust | `rust` | Idiomatic Rust development |
|
|
66
|
+
| Git | `git` | Git workflow conventions |
|
|
67
|
+
| TSDoc | `tsdoc` | Documentation conventions |
|
|
68
|
+
| Turtle | `turtle` | RDF/Turtle authoring |
|
|
69
|
+
| UI Blocks | `ui-blocks` | Framework-agnostic capabilities and patterns for UI blocks |
|
|
70
|
+
|
|
71
|
+
If no existing category fits, create a new one (see Section 5).
|
|
72
|
+
|
|
73
|
+
### 3. Design the Standard Identifier
|
|
74
|
+
|
|
75
|
+
Standard identifiers follow a hierarchical compact IRI pattern: `cs:{category}.{domain}.{topic}`
|
|
76
|
+
|
|
77
|
+
**Pattern:** `^cs:[a-z]+(\.[a-z0-9_]+){2,}$`
|
|
78
|
+
|
|
79
|
+
**Examples:**
|
|
80
|
+
- `cs:react.component.structure.folder`
|
|
81
|
+
- `cs:css.selectors.namespace`
|
|
82
|
+
- `cs:styling.tokens.creation`
|
|
83
|
+
- `cs:react.hooks.naming`
|
|
84
|
+
|
|
85
|
+
**Guidelines:**
|
|
86
|
+
- Use lowercase with underscores for multi-word segments
|
|
87
|
+
- Category is always the first segment after `cs:`
|
|
88
|
+
- Be specific but not overly verbose
|
|
89
|
+
- Follow existing naming patterns in the same category
|
|
90
|
+
- Treat the subject IRI as the only canonical identifier
|
|
91
|
+
- Use `cs:name` only for an optional human-readable display title
|
|
92
|
+
|
|
93
|
+
### 4. Write the Standard
|
|
94
|
+
|
|
95
|
+
Create a new standard instance in the appropriate data file under `data/`.
|
|
96
|
+
|
|
97
|
+
**Template:**
|
|
98
|
+
|
|
99
|
+
```turtle
|
|
100
|
+
cs:category.domain.topic a cs:CodeStandard ;
|
|
101
|
+
cs:name "Human Readable Title" ;
|
|
102
|
+
cs:hasCategory cs:category ;
|
|
103
|
+
cs:description "Clear, concise description of what this standard covers and why it matters." ;
|
|
104
|
+
cs:do [
|
|
105
|
+
cs:description "First recommended practice." ;
|
|
106
|
+
cs:language "typescript" ;
|
|
107
|
+
cs:code """
|
|
108
|
+
// Example showing the correct approach
|
|
109
|
+
const good = true;
|
|
110
|
+
"""
|
|
111
|
+
] ;
|
|
112
|
+
cs:do [
|
|
113
|
+
cs:description "Second recommended practice." ;
|
|
114
|
+
cs:language "typescript" ;
|
|
115
|
+
cs:code """
|
|
116
|
+
// Another correct example
|
|
117
|
+
const alsoGood = true;
|
|
118
|
+
"""
|
|
119
|
+
] ;
|
|
120
|
+
cs:dont [
|
|
121
|
+
cs:description "First anti-pattern to avoid." ;
|
|
122
|
+
cs:language "typescript" ;
|
|
123
|
+
cs:code """
|
|
124
|
+
// Example showing what NOT to do
|
|
125
|
+
const bad = true;
|
|
126
|
+
"""
|
|
127
|
+
] ;
|
|
128
|
+
cs:dont [
|
|
129
|
+
cs:description "Second anti-pattern." ;
|
|
130
|
+
cs:language "typescript" ;
|
|
131
|
+
cs:code """
|
|
132
|
+
// Another bad example
|
|
133
|
+
const alsoBad = true;
|
|
134
|
+
"""
|
|
135
|
+
] .
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Each `cs:do` and `cs:dont` is a blank node (`cs:Example`) with structured fields:
|
|
139
|
+
- `cs:description` — What the example demonstrates (required)
|
|
140
|
+
- `cs:language` — Language of the code block, e.g. `"typescript"`, `"rust"`, `"css"`, `"bash"`, `"svg"` (optional, omit when no code)
|
|
141
|
+
- `cs:code` — The code content (optional, omit for description-only examples)
|
|
142
|
+
|
|
143
|
+
**Required Properties:**
|
|
144
|
+
- subject IRI - Canonical compact identifier
|
|
145
|
+
- `cs:hasCategory` - Reference to a Category instance
|
|
146
|
+
- `cs:description` - What and why (plain text or markdown)
|
|
147
|
+
- `cs:do` - One or more positive examples (blank nodes)
|
|
148
|
+
- `cs:dont` - One or more negative examples (blank nodes)
|
|
149
|
+
|
|
150
|
+
**Optional Properties:**
|
|
151
|
+
- `cs:name` - Human-readable display title
|
|
152
|
+
- `cs:extends` - Reference to a parent standard this builds upon
|
|
153
|
+
|
|
154
|
+
### 5. Create a New Category (if needed)
|
|
155
|
+
|
|
156
|
+
If your standard doesn't fit existing categories:
|
|
157
|
+
|
|
158
|
+
```turtle
|
|
159
|
+
cs:new_category a cs:Category ;
|
|
160
|
+
rdfs:label "Category Name"@en ;
|
|
161
|
+
rdfs:comment "Description of what this category covers"@en ;
|
|
162
|
+
cs:slug "slug-name" .
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### 6. Extending Existing Standards
|
|
166
|
+
|
|
167
|
+
When your standard builds on another:
|
|
168
|
+
|
|
169
|
+
```turtle
|
|
170
|
+
cs:react.component.props.special_case a cs:CodeStandard ;
|
|
171
|
+
cs:name "React Props Special Case" ;
|
|
172
|
+
cs:extends cs:react.component.props ;
|
|
173
|
+
cs:hasCategory cs:react ;
|
|
174
|
+
cs:description "Specific guidance that builds on the general props standard." ;
|
|
175
|
+
cs:do [
|
|
176
|
+
cs:description "Example of the specific pattern." ;
|
|
177
|
+
cs:language "typescript" ;
|
|
178
|
+
cs:code """
|
|
179
|
+
// ...
|
|
180
|
+
"""
|
|
181
|
+
] ;
|
|
182
|
+
cs:dont [
|
|
183
|
+
cs:description "Anti-pattern to avoid." ;
|
|
184
|
+
cs:language "typescript" ;
|
|
185
|
+
cs:code """
|
|
186
|
+
// ...
|
|
187
|
+
"""
|
|
188
|
+
] .
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Query to find potential parent standards:
|
|
192
|
+
```sparql
|
|
193
|
+
PREFIX cs: <http://pragma.canonical.com/codestandards#>
|
|
194
|
+
|
|
195
|
+
SELECT ?standard WHERE {
|
|
196
|
+
?standard a cs:CodeStandard .
|
|
197
|
+
FILTER(STRSTARTS(STR(?standard), STR(cs:react.component.props)))
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### 7. Validate Before Committing
|
|
202
|
+
|
|
203
|
+
After writing the standard, validate the Turtle syntax:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
sem check code-standards
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Then verify the standard loads correctly:
|
|
210
|
+
```
|
|
211
|
+
sem_lookup(type: "cs:CodeStandard", filters: {"@id": "cs:category.domain.topic"})
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
The `@id` must always use the canonical compact IRI. Do not look up standards by `cs:name`.
|
|
215
|
+
|
|
216
|
+
## File Organization
|
|
217
|
+
|
|
218
|
+
Standards are organized by category in `data/`:
|
|
219
|
+
|
|
220
|
+
```
|
|
221
|
+
code-standards/
|
|
222
|
+
├── definitions/
|
|
223
|
+
│ └── CodeStandard.ttl # Ontology schema
|
|
224
|
+
├── data/
|
|
225
|
+
│ ├── react.ttl # React standards
|
|
226
|
+
│ ├── css.ttl # CSS standards
|
|
227
|
+
│ ├── styling.ttl # Styling standards
|
|
228
|
+
│ ├── code.ttl # General code standards
|
|
229
|
+
│ ├── storybook.ttl # Storybook standards
|
|
230
|
+
│ └── icons.ttl # Icon standards
|
|
231
|
+
└── skills/
|
|
232
|
+
└── standards-guide/
|
|
233
|
+
└── SKILL.md
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Add new standards to the file matching their category.
|
|
237
|
+
|
|
238
|
+
## Writing Quality Standards
|
|
239
|
+
|
|
240
|
+
### Description Guidelines
|
|
241
|
+
- Start with WHAT the standard covers
|
|
242
|
+
- Explain WHY it matters
|
|
243
|
+
- Keep it concise but complete
|
|
244
|
+
- Use markdown for complex descriptions
|
|
245
|
+
|
|
246
|
+
### Do Examples Guidelines
|
|
247
|
+
- Each `cs:do` blank node is one discrete positive example
|
|
248
|
+
- `cs:description` explains what the example demonstrates
|
|
249
|
+
- `cs:language` must match the code block language (e.g. `"typescript"`, `"css"`, `"rust"`)
|
|
250
|
+
- `cs:code` contains the actual code — no markdown fences needed
|
|
251
|
+
- Provide concrete, runnable examples
|
|
252
|
+
- Show the COMPLETE correct pattern
|
|
253
|
+
|
|
254
|
+
### Don't Examples Guidelines
|
|
255
|
+
- Each `cs:dont` blank node is one discrete negative example
|
|
256
|
+
- Show realistic mistakes developers make
|
|
257
|
+
- `cs:description` should explain WHY it's problematic
|
|
258
|
+
- Mirror the structure of the do examples where possible
|
|
259
|
+
|
|
260
|
+
### Example Quality Checklist
|
|
261
|
+
- [ ] Examples are syntactically correct
|
|
262
|
+
- [ ] Examples are self-contained (can be understood without context)
|
|
263
|
+
- [ ] Examples use realistic code, not `foo`/`bar`
|
|
264
|
+
- [ ] Examples include comments explaining key points
|
|
265
|
+
- [ ] Both do's and don'ts cover the same scenarios
|
|
266
|
+
|
|
267
|
+
## Complete Example
|
|
268
|
+
|
|
269
|
+
Adding a new standard for React error boundaries:
|
|
270
|
+
|
|
271
|
+
```turtle
|
|
272
|
+
# In data/react.ttl
|
|
273
|
+
|
|
274
|
+
cs:react.component.error_boundaries a cs:CodeStandard ;
|
|
275
|
+
cs:name "React Error Boundaries" ;
|
|
276
|
+
cs:hasCategory cs:react ;
|
|
277
|
+
cs:description "Error boundaries must be used to catch JavaScript errors in component trees and display fallback UI. They should be placed strategically to isolate failures without breaking the entire application." ;
|
|
278
|
+
cs:do [
|
|
279
|
+
cs:description "Wrap feature sections with error boundaries to isolate failures." ;
|
|
280
|
+
cs:language "tsx" ;
|
|
281
|
+
cs:code """
|
|
282
|
+
const Dashboard = () => (
|
|
283
|
+
<div className="ds dashboard">
|
|
284
|
+
<ErrorBoundary fallback={<WidgetError />}>
|
|
285
|
+
<AnalyticsWidget />
|
|
286
|
+
</ErrorBoundary>
|
|
287
|
+
<ErrorBoundary fallback={<WidgetError />}>
|
|
288
|
+
<ActivityWidget />
|
|
289
|
+
</ErrorBoundary>
|
|
290
|
+
</div>
|
|
291
|
+
);
|
|
292
|
+
"""
|
|
293
|
+
] ;
|
|
294
|
+
cs:do [
|
|
295
|
+
cs:description "Provide meaningful fallback UI that helps users understand and recover." ;
|
|
296
|
+
cs:language "tsx" ;
|
|
297
|
+
cs:code """
|
|
298
|
+
const WidgetError = () => (
|
|
299
|
+
<div className="ds widget-error">
|
|
300
|
+
<p>This section couldn't load.</p>
|
|
301
|
+
<button onClick={() => window.location.reload()}>
|
|
302
|
+
Refresh page
|
|
303
|
+
</button>
|
|
304
|
+
</div>
|
|
305
|
+
);
|
|
306
|
+
"""
|
|
307
|
+
] ;
|
|
308
|
+
cs:dont [
|
|
309
|
+
cs:description "Wrap the entire application in a single error boundary." ;
|
|
310
|
+
cs:language "tsx" ;
|
|
311
|
+
cs:code """
|
|
312
|
+
// Bad: One error anywhere crashes everything
|
|
313
|
+
const App = () => (
|
|
314
|
+
<ErrorBoundary>
|
|
315
|
+
<Header />
|
|
316
|
+
<Main />
|
|
317
|
+
<Footer />
|
|
318
|
+
</ErrorBoundary>
|
|
319
|
+
);
|
|
320
|
+
"""
|
|
321
|
+
] ;
|
|
322
|
+
cs:dont [
|
|
323
|
+
cs:description "Use generic or unhelpful fallback messages." ;
|
|
324
|
+
cs:language "tsx" ;
|
|
325
|
+
cs:code """
|
|
326
|
+
// Bad: Doesn't help the user
|
|
327
|
+
const fallback = <div>Something went wrong</div>;
|
|
328
|
+
"""
|
|
329
|
+
] .
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
## Tips
|
|
333
|
+
|
|
334
|
+
1. **Check before creating**: Always search for existing standards first - you might need to extend rather than create new
|
|
335
|
+
2. **Follow patterns**: Look at existing standards in the same category for style guidance
|
|
336
|
+
3. **Be specific**: Vague standards are hard to follow - include concrete examples
|
|
337
|
+
4. **Test your examples**: Make sure code examples actually work
|
|
338
|
+
5. **Consider hierarchy**: Use `cs:extends` when your standard builds on another
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: adoption-a1-styles
|
|
3
|
+
description: Adopt Canonical design-system styles, fonts, and icons in an application (adoption track A1); also runs as a guided tutorial on a worked example
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Adoption A1 — Styles, fonts, icons
|
|
7
|
+
|
|
8
|
+
The first track of adopting the design system: the visual foundation — reset,
|
|
9
|
+
typography, tokens, fonts, icons — before any component swap. Complete this track and
|
|
10
|
+
the app looks and reads like the design system even while it still renders its old
|
|
11
|
+
components.
|
|
12
|
+
|
|
13
|
+
## When to Use
|
|
14
|
+
|
|
15
|
+
- Starting design-system adoption in an application — this is the first track
|
|
16
|
+
- The app needs the visual foundation (reset, typography, tokens, fonts, icons) before
|
|
17
|
+
any component swap
|
|
18
|
+
|
|
19
|
+
## When NOT to Use
|
|
20
|
+
|
|
21
|
+
- The foundation is already installed and verified — continue with
|
|
22
|
+
`adoption-a2-components`
|
|
23
|
+
- Authoring design-system content rather than adopting it — see `specify-component`
|
|
24
|
+
and its sibling skills
|
|
25
|
+
|
|
26
|
+
## Opening move: ask, or offer the tutorial
|
|
27
|
+
|
|
28
|
+
Activation is an opening, not a starting gun. Unless the first message already names
|
|
29
|
+
the work, ask for the starting point — as a suggestion carrying an example, not as a
|
|
30
|
+
form to fill in:
|
|
31
|
+
|
|
32
|
+
> To get started, point me at the app — the repo or directory — and say whether it
|
|
33
|
+
> already pulls in any Canonical styles.
|
|
34
|
+
|
|
35
|
+
"I don't know what's in there" is a fine answer: the install and verify steps
|
|
36
|
+
establish it. Ask again only for what the next step genuinely blocks on.
|
|
37
|
+
|
|
38
|
+
If the activation message already carries the starting point, do not re-ask — say what
|
|
39
|
+
you took it to be, and go.
|
|
40
|
+
|
|
41
|
+
Offer the tutorial in the same breath, because this track doubles as one:
|
|
42
|
+
|
|
43
|
+
> Or if you'd rather see what this track changes before touching your app, I can run
|
|
44
|
+
> it as a tutorial: I'll take a plausible example — a small Vite React app — and walk
|
|
45
|
+
> you through the track on it.
|
|
46
|
+
|
|
47
|
+
Tutorial mode is the step narration below, turned up: the same outcome-path-conclusion
|
|
48
|
+
frame, with the reasoning behind each change made explicit. It runs on a scratch
|
|
49
|
+
example, not on the person's app — nothing in their repo changes unless they ask.
|
|
50
|
+
|
|
51
|
+
## Every step is narrated: outcome, path, conclusion
|
|
52
|
+
|
|
53
|
+
Every step is addressed to the person — once before it runs, once when it ends. This is
|
|
54
|
+
not tutorial manner. It holds in the ordinary flow too: the person is the design
|
|
55
|
+
authority, and they can only steer a step they saw coming. A decision gate met cold is
|
|
56
|
+
a decision they cannot really make.
|
|
57
|
+
|
|
58
|
+
**Open** the step with what it is FOR — the outcome it should leave behind — and how
|
|
59
|
+
you are about to get there. **Close** it with a sentence saying what it established and
|
|
60
|
+
what that means for the step after. One sentence each is enough; the failure mode is
|
|
61
|
+
silence, not length, and a step whose outcome looks obvious still gets its sentence
|
|
62
|
+
rather than a shrug.
|
|
63
|
+
|
|
64
|
+
Do:
|
|
65
|
+
|
|
66
|
+
> **Fonts, then styles.** The outcome is an app whose type and tokens come from the
|
|
67
|
+
> design system, with the fonts loaded before the styles that expect them. The path is
|
|
68
|
+
> the two `@import` lines below, in the root stylesheet, fonts first.
|
|
69
|
+
>
|
|
70
|
+
> …
|
|
71
|
+
>
|
|
72
|
+
> So: type and tokens are live and Ubuntu Sans is self-hosted — which leaves the
|
|
73
|
+
> surface classes as the step that decides whether the density channel emits real
|
|
74
|
+
> values at all.
|
|
75
|
+
|
|
76
|
+
Don't:
|
|
77
|
+
|
|
78
|
+
> Added the two imports. Fonts load.
|
|
79
|
+
|
|
80
|
+
Both carry the same facts. Only the first says what the step was trying to achieve and
|
|
81
|
+
what it settled — and only the first lets the person cut in with the thing they know
|
|
82
|
+
and the graph does not, which is the whole reason they are here.
|
|
83
|
+
|
|
84
|
+
## Asked about the skill: methodology and outcomes first
|
|
85
|
+
|
|
86
|
+
A question about what this skill does — what it covers, what its steps are, how it
|
|
87
|
+
works — is answered in that order: the METHOD it applies and the OUTCOMES it leaves
|
|
88
|
+
the person holding come first, the step-by-step breakdown comes after.
|
|
89
|
+
|
|
90
|
+
Two or three sentences of method is enough: what the skill treats as its object, the
|
|
91
|
+
discipline that makes it work, and what exists at the end that did not exist before.
|
|
92
|
+
The enumeration then reads as steps in service of something, rather than as a list to
|
|
93
|
+
be got through.
|
|
94
|
+
|
|
95
|
+
What this prevents is a table of contents standing in for an answer. A reply opening
|
|
96
|
+
with the step names tells someone who already knows the skill nothing new, and someone
|
|
97
|
+
who does not, nothing at all.
|
|
98
|
+
|
|
99
|
+
So, asked what this skill is:
|
|
100
|
+
|
|
101
|
+
> It installs the visual foundation — reset, typography, tokens, fonts, icons — before
|
|
102
|
+
> any component is swapped, under the live code standards. Complete it and the app
|
|
103
|
+
> looks and reads like the design system while it still renders its old components,
|
|
104
|
+
> which is what makes every later track land on the right ground.
|
|
105
|
+
|
|
106
|
+
Then, and only then, the breakdown.
|
|
107
|
+
|
|
108
|
+
## Install
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
bun add @canonical/styles @canonical/ds-assets
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
One import of `@canonical/styles` aggregates the normalize/reset, typography, and design
|
|
115
|
+
tokens. Two things come with it:
|
|
116
|
+
|
|
117
|
+
- Cascade layers `@layer normalize, ds.reset, ds.modifiers, ds.components` — component
|
|
118
|
+
styles beat modifiers beat reset regardless of import order, so adopting apps do not
|
|
119
|
+
fight specificity.
|
|
120
|
+
- `color-scheme: light dark` on `:root` — the foundation is theme-aware out of the box.
|
|
121
|
+
|
|
122
|
+
## Code standards are the gate
|
|
123
|
+
|
|
124
|
+
Styling work in this track falls under the live code standards — the `styling`, `css`,
|
|
125
|
+
and `icons` categories at minimum (take the actual set from the live output, not from
|
|
126
|
+
this list). Pull them BEFORE touching a stylesheet and hold the Do/Don't pairs open
|
|
127
|
+
while editing, so they shape the change as it is written, not only in review:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
pragma standard categories # the live category set — never from memory
|
|
131
|
+
pragma standard list --category styling # repeat per applicable category
|
|
132
|
+
pragma standard lookup <name> --detail detailed
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Apps follow the code standards as closely as the work allows. Where a change has to
|
|
136
|
+
deviate from a pulled standard, record the deviation in the PR next to the standard's
|
|
137
|
+
name — and ideally file it as an issue, either to bring the app into line later or to
|
|
138
|
+
propose a change to the standard itself. The standards apply even when the app has no
|
|
139
|
+
pragma dependency, and they are open to contribution: a missing or wrong standard is
|
|
140
|
+
something to propose a change for, not to silently work around.
|
|
141
|
+
|
|
142
|
+
## Fonts before styles
|
|
143
|
+
|
|
144
|
+
Fonts are opt-in and must be imported FIRST. The canonical form, in the root stylesheet:
|
|
145
|
+
|
|
146
|
+
```css
|
|
147
|
+
@import url("@canonical/styles/fonts");
|
|
148
|
+
@import url("@canonical/styles");
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
(Equivalent JS-side: import the fonts CSS, then `import "@canonical/styles"`.) The
|
|
152
|
+
fonts entry loads Ubuntu Sans as variable fonts, self-hosted from
|
|
153
|
+
`@canonical/ds-assets` via its `@font-face` rules — no external font host.
|
|
154
|
+
|
|
155
|
+
## Declare the surface: context and density classes
|
|
156
|
+
|
|
157
|
+
The density system is class-driven, and it starts at the root. The app's root element
|
|
158
|
+
(`<body>`, or the app's root container) must carry TWO classes:
|
|
159
|
+
|
|
160
|
+
```html
|
|
161
|
+
<body class="app comfortable">
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
- **Context** — `app`, `site`, or `docs`: which surface this is. Applications take
|
|
165
|
+
`app`; marketing/brochure surfaces take `site`; documentation surfaces take `docs`
|
|
166
|
+
(`docs` shares `site`'s values).
|
|
167
|
+
- **Density** — `comfortable` or `dense`: picks within the context's pair.
|
|
168
|
+
`comfortable` is the default choice unless the product's design calls for `dense`.
|
|
169
|
+
|
|
170
|
+
The requirement, stated as a rule: the root carries EXACTLY ONE class from each
|
|
171
|
+
family — a context (`app` | `site` | `docs`) AND a density (`comfortable` | `dense`).
|
|
172
|
+
That makes six valid combinations (`app comfortable`, `app dense`, `site comfortable`,
|
|
173
|
+
`site dense`, `docs comfortable`, `docs dense`) and nothing else: a single class, a
|
|
174
|
+
value outside either set, or two values from the same family is an invalid surface
|
|
175
|
+
declaration. `app comfortable` is the default for applications; adoption is not done
|
|
176
|
+
until the root carries a valid pair.
|
|
177
|
+
|
|
178
|
+
Components never read these classes directly — they read the `--density-*` custom
|
|
179
|
+
properties the classes emit (control heights, inline padding, vertical spacing rungs,
|
|
180
|
+
baseline seating). A section can locally tighten by carrying its own `dense` class on
|
|
181
|
+
an ancestor of just that region.
|
|
182
|
+
|
|
183
|
+
**Failure mode: missing root classes fail SILENTLY.** The primitives fall back to
|
|
184
|
+
app-comfortable values, so an application looks right by accident — while a site or
|
|
185
|
+
docs surface, or any intended `dense` region, quietly renders with the wrong control
|
|
186
|
+
heights and spacing. This step has historically been forgotten precisely because
|
|
187
|
+
nothing errors. If control heights or spacing look subtly off, check the root classes
|
|
188
|
+
before debugging component CSS.
|
|
189
|
+
|
|
190
|
+
## The /icons serving contract (and its silent failure)
|
|
191
|
+
|
|
192
|
+
Icons are per-file SVGs in `@canonical/ds-assets` (`icons/<name>.svg`, 16x16 viewBox,
|
|
193
|
+
`currentColor` fill, a single `<g id="<name>">`), referenced at RUNTIME: the React
|
|
194
|
+
`Icon` component renders
|
|
195
|
+
|
|
196
|
+
```html
|
|
197
|
+
<use href="/icons/<name>.svg#<name>" />
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
with `rootPath="/icons"` as the default, overridable via the `rootPath` prop.
|
|
201
|
+
|
|
202
|
+
**The app must expose `@canonical/ds-assets`' `icons/` directory at `/icons`** — copy or
|
|
203
|
+
symlink it into the static dir, or add a static mount in the server/bundler config — or
|
|
204
|
+
pass `rootPath` to point where the app does serve them.
|
|
205
|
+
|
|
206
|
+
**Failure mode: an unserved icon renders EMPTY, silently.** No error, no broken-image
|
|
207
|
+
glyph — an external `<use>` reference that 404s resolves to nothing. If icons "don't
|
|
208
|
+
show up", check the network tab for `/icons/<name>.svg` before debugging anything else.
|
|
209
|
+
|
|
210
|
+
For TypeScript apps, the valid icon names ship as data:
|
|
211
|
+
|
|
212
|
+
```ts
|
|
213
|
+
import { ICON_NAMES, type IconName } from "@canonical/ds-assets";
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Storybook freebies
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
bun add -d @canonical/storybook-config
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
```ts
|
|
223
|
+
// .storybook/main.ts
|
|
224
|
+
import { createConfig } from "@canonical/storybook-config";
|
|
225
|
+
|
|
226
|
+
export default createConfig("react"); // or "svelte" | "sveltekit" | "lit"
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
This single call:
|
|
230
|
+
|
|
231
|
+
- serves the whole `@canonical/ds-assets` package via `staticDirs`, so `/icons/*` just
|
|
232
|
+
works in Storybook — do not mistake that for your APP serving them;
|
|
233
|
+
- ships the shared addons and shell theme;
|
|
234
|
+
- fixes the full-height preview chain.
|
|
235
|
+
|
|
236
|
+
One caveat: declare `tags: ["autodocs"]` inline in your own `.storybook/preview.ts` —
|
|
237
|
+
Storybook statically parses that file and does not reliably pick up tags spread from an
|
|
238
|
+
imported preview.
|
|
239
|
+
|
|
240
|
+
## Verify
|
|
241
|
+
|
|
242
|
+
- [ ] Computed `font-family` on body text shows Ubuntu Sans.
|
|
243
|
+
- [ ] The root element carries one context class (`app`/`site`/`docs`) and one
|
|
244
|
+
density class (`comfortable`/`dense`).
|
|
245
|
+
- [ ] Computed `--density-line-height` on a control matches the intended cell
|
|
246
|
+
(e.g. `32px` for app-comfortable, `36px` for site-comfortable) — a fallback
|
|
247
|
+
value on a class-less root passes visual inspection and still fails this check
|
|
248
|
+
on non-app surfaces.
|
|
249
|
+
- [ ] `/icons/<name>.svg` returns 200 with SVG content, and an icon visibly renders.
|
|
250
|
+
- [ ] The `@layer normalize, ds.reset, ds.modifiers, ds.components` rule is present in
|
|
251
|
+
the served CSS.
|
|
252
|
+
- [ ] Typography baseline behaves. Note: the baseline grid is computed with the CSS
|
|
253
|
+
`mod()` function and cannot be downleveled — check the support table in the
|
|
254
|
+
`@canonical/styles-typography` README against the browsers you target.
|
|
255
|
+
|
|
256
|
+
## Next
|
|
257
|
+
|
|
258
|
+
Foundation in place — continue with `adoption-a2-components`.
|
|
259
|
+
|
|
260
|
+
## Support
|
|
261
|
+
|
|
262
|
+
If this skill leads somewhere broken — a command that errors, guidance that
|
|
263
|
+
contradicts what the live system answers, a gap the flow cannot cover — you are not
|
|
264
|
+
stuck:
|
|
265
|
+
|
|
266
|
+
- Raise an issue in the pragma repo: https://github.com/canonical/pragma/issues —
|
|
267
|
+
include the skill name, what was run, and expected vs. actual outcome.
|
|
268
|
+
- Or contact the design-system team owners directly through your organization's
|
|
269
|
+
professional messaging channels for assistance.
|