@canonical/pragma-cli 0.35.0 → 0.37.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.
Files changed (295) hide show
  1. package/README.md +2 -2
  2. package/bundled-skills/add-standard/SKILL.md +338 -0
  3. package/bundled-skills/adoption-a1-styles/SKILL.md +269 -0
  4. package/bundled-skills/adoption-a2-components/SKILL.md +291 -0
  5. package/bundled-skills/adoption-a3-forms/SKILL.md +260 -0
  6. package/bundled-skills/anatomy-author/ANATOMY_DSL_SPEC.md +406 -0
  7. package/bundled-skills/anatomy-author/SKILL.md +1226 -0
  8. package/bundled-skills/design-auditor/SKILL.md +455 -0
  9. package/bundled-skills/implement-component/SKILL.md +333 -0
  10. package/bundled-skills/specify-component/SKILL.md +331 -0
  11. package/bundled-skills/specify-pattern/SKILL.md +292 -0
  12. package/dist/package.json +24 -20
  13. package/dist/pragma.conf.js +266 -34
  14. package/dist/pragma.conf.js.map +1 -1
  15. package/dist/src/bin.js +1 -1
  16. package/dist/src/bin.js.map +1 -1
  17. package/dist/src/capabilities/capabilities/hints.js +1 -1
  18. package/dist/src/capabilities/capabilities/hints.js.map +1 -1
  19. package/dist/src/capabilities/colophon/colophon.render.js +1 -1
  20. package/dist/src/capabilities/colophon/colophon.render.js.map +1 -1
  21. package/dist/src/capabilities/create/create.verb.js +2 -1
  22. package/dist/src/capabilities/create/create.verb.js.map +1 -1
  23. package/dist/src/capabilities/create/createSurface.generated.js +23 -1
  24. package/dist/src/capabilities/create/createSurface.generated.js.map +1 -1
  25. package/dist/src/capabilities/create/mount.js +4 -3
  26. package/dist/src/capabilities/create/mount.js.map +1 -1
  27. package/dist/src/capabilities/doctor/checks/checkNodeVersion.js +11 -6
  28. package/dist/src/capabilities/doctor/checks/checkNodeVersion.js.map +1 -1
  29. package/dist/src/capabilities/doctor/checks/checkPackageRefs.js +60 -4
  30. package/dist/src/capabilities/doctor/checks/checkPackageRefs.js.map +1 -1
  31. package/dist/src/capabilities/doctor/checks/checkShellCompletions.js +8 -8
  32. package/dist/src/capabilities/doctor/checks/checkShellCompletions.js.map +1 -1
  33. package/dist/src/capabilities/doctor/checks/harnessInventory.js +195 -0
  34. package/dist/src/capabilities/doctor/checks/harnessInventory.js.map +1 -0
  35. package/dist/src/capabilities/doctor/checks/index.js +6 -6
  36. package/dist/src/capabilities/doctor/checks/isSupportedNodeVersion.js +38 -0
  37. package/dist/src/capabilities/doctor/checks/isSupportedNodeVersion.js.map +1 -0
  38. package/dist/src/capabilities/doctor/checks/targetHealth.js +194 -50
  39. package/dist/src/capabilities/doctor/checks/targetHealth.js.map +1 -1
  40. package/dist/src/capabilities/doctor/doctor.render.js +43 -64
  41. package/dist/src/capabilities/doctor/doctor.render.js.map +1 -1
  42. package/dist/src/capabilities/doctor/doctor.verb.js +6 -2
  43. package/dist/src/capabilities/doctor/doctor.verb.js.map +1 -1
  44. package/dist/src/capabilities/doctor/runChecks.js +14 -11
  45. package/dist/src/capabilities/doctor/runChecks.js.map +1 -1
  46. package/dist/src/capabilities/graph/query.render.js +2 -2
  47. package/dist/src/capabilities/graph/query.render.js.map +1 -1
  48. package/dist/src/capabilities/info/collectInfo.js +8 -2
  49. package/dist/src/capabilities/info/collectInfo.js.map +1 -1
  50. package/dist/src/capabilities/info/info.render.js +6 -2
  51. package/dist/src/capabilities/info/info.render.js.map +1 -1
  52. package/dist/src/capabilities/prompt/prompt.render.js +2 -2
  53. package/dist/src/capabilities/prompt/prompt.render.js.map +1 -1
  54. package/dist/src/capabilities/setup/buildPlan.js +43 -39
  55. package/dist/src/capabilities/setup/buildPlan.js.map +1 -1
  56. package/dist/src/capabilities/setup/mode.js +2 -2
  57. package/dist/src/capabilities/setup/operations/index.js +4 -4
  58. package/dist/src/capabilities/setup/operations/index.js.map +1 -1
  59. package/dist/src/capabilities/setup/operations/setupCompletions.js +6 -2
  60. package/dist/src/capabilities/setup/operations/setupCompletions.js.map +1 -1
  61. package/dist/src/capabilities/setup/operations/setupConfig.js +4 -2
  62. package/dist/src/capabilities/setup/operations/setupConfig.js.map +1 -1
  63. package/dist/src/capabilities/setup/operations/setupGenerator.js +156 -58
  64. package/dist/src/capabilities/setup/operations/setupGenerator.js.map +1 -1
  65. package/dist/src/capabilities/setup/operations/setupLsp.js +136 -38
  66. package/dist/src/capabilities/setup/operations/setupLsp.js.map +1 -1
  67. package/dist/src/capabilities/setup/operations/setupMcp.js +101 -52
  68. package/dist/src/capabilities/setup/operations/setupMcp.js.map +1 -1
  69. package/dist/src/capabilities/setup/operations/setupSkills.js +329 -49
  70. package/dist/src/capabilities/setup/operations/setupSkills.js.map +1 -1
  71. package/dist/src/capabilities/setup/plan.js.map +1 -1
  72. package/dist/src/capabilities/setup/plan.render.js +144 -66
  73. package/dist/src/capabilities/setup/plan.render.js.map +1 -1
  74. package/dist/src/capabilities/setup/setup.render.js +1 -1
  75. package/dist/src/capabilities/setup/setup.verb.js +165 -63
  76. package/dist/src/capabilities/setup/setup.verb.js.map +1 -1
  77. package/dist/src/capabilities/setup/targets.js +122 -51
  78. package/dist/src/capabilities/setup/targets.js.map +1 -1
  79. package/dist/src/capabilities/shared/index.js +7 -6
  80. package/dist/src/capabilities/shared/index.js.map +1 -1
  81. package/dist/src/capabilities/shared/packageManager.js +300 -54
  82. package/dist/src/capabilities/shared/packageManager.js.map +1 -1
  83. package/dist/src/capabilities/skill/discover.js +97 -11
  84. package/dist/src/capabilities/skill/discover.js.map +1 -1
  85. package/dist/src/capabilities/skill/render.js +2 -2
  86. package/dist/src/capabilities/skill/render.js.map +1 -1
  87. package/dist/src/capabilities/sources/installSkills.js +145 -3
  88. package/dist/src/capabilities/sources/installSkills.js.map +1 -1
  89. package/dist/src/capabilities/sources/runUpdate.js +68 -2
  90. package/dist/src/capabilities/sources/runUpdate.js.map +1 -1
  91. package/dist/src/capabilities/sources/update.verb.js +3 -3
  92. package/dist/src/capabilities/sources/update.verb.js.map +1 -1
  93. package/dist/src/capabilities/upgrade/runUpgrade.js +43 -7
  94. package/dist/src/capabilities/upgrade/runUpgrade.js.map +1 -1
  95. package/dist/src/capabilities/upgrade/upgrade.render.js +10 -2
  96. package/dist/src/capabilities/upgrade/upgrade.render.js.map +1 -1
  97. package/dist/src/constants.js +13 -2
  98. package/dist/src/constants.js.map +1 -1
  99. package/dist/src/kernel/index.js +11 -2
  100. package/dist/src/kernel/index.js.map +1 -1
  101. package/dist/src/kernel/interactivity.js +68 -0
  102. package/dist/src/kernel/interactivity.js.map +1 -0
  103. package/dist/src/kernel/packs/renderPack.js +3 -3
  104. package/dist/src/kernel/packs/renderPack.js.map +1 -1
  105. package/dist/src/kernel/packs/resolveEntity.js +63 -12
  106. package/dist/src/kernel/packs/resolveEntity.js.map +1 -1
  107. package/dist/src/kernel/packs/runBodies.js +57 -4
  108. package/dist/src/kernel/packs/runBodies.js.map +1 -1
  109. package/dist/src/kernel/packs/schema.js +54 -2
  110. package/dist/src/kernel/packs/schema.js.map +1 -1
  111. package/dist/src/kernel/packs/sparql/applyFilters.js +104 -5
  112. package/dist/src/kernel/packs/sparql/applyFilters.js.map +1 -1
  113. package/dist/src/kernel/packs/sparql/buildLookupQuery.js +310 -43
  114. package/dist/src/kernel/packs/sparql/buildLookupQuery.js.map +1 -1
  115. package/dist/src/kernel/packs/types.js.map +1 -1
  116. package/dist/src/kernel/project/cli/buildProgram.js +1 -1
  117. package/dist/src/kernel/project/cli/buildProgram.js.map +1 -1
  118. package/dist/src/kernel/project/cli/dispatch.js +46 -24
  119. package/dist/src/kernel/project/cli/dispatch.js.map +1 -1
  120. package/dist/src/kernel/project/cli/globalFlags.js +4 -1
  121. package/dist/src/kernel/project/cli/globalFlags.js.map +1 -1
  122. package/dist/src/kernel/project/cli/helpFormat.js +1 -2
  123. package/dist/src/kernel/project/cli/helpFormat.js.map +1 -1
  124. package/dist/src/kernel/project/cli/rootHelp.js +42 -9
  125. package/dist/src/kernel/project/cli/rootHelp.js.map +1 -1
  126. package/dist/src/kernel/project/mcp/registerVerb.js +16 -1
  127. package/dist/src/kernel/project/mcp/registerVerb.js.map +1 -1
  128. package/dist/src/kernel/render/renderers.js +1 -1
  129. package/dist/src/kernel/render/style.js +29 -9
  130. package/dist/src/kernel/render/style.js.map +1 -1
  131. package/dist/src/kernel/render/vocabulary.js +174 -0
  132. package/dist/src/kernel/render/vocabulary.js.map +1 -0
  133. package/dist/src/kernel/runtime/graphpack/embedded/pack.generated.js +2 -3
  134. package/dist/src/kernel/runtime/graphpack/embedded/pack.generated.js.map +1 -1
  135. package/dist/src/kernel/runtime/graphpack/embedded/pack.index.generated.js +1 -1
  136. package/dist/src/kernel/runtime/graphpack/embedded/pack.index.generated.js.map +1 -1
  137. package/dist/src/kernel/runtime/graphpack/embedded/pack.manifest.generated.js +4 -0
  138. package/dist/src/kernel/runtime/graphpack/embedded/pack.manifest.generated.js.map +1 -0
  139. package/dist/src/kernel/runtime/graphpack/embedded.js +13 -6
  140. package/dist/src/kernel/runtime/graphpack/embedded.js.map +1 -1
  141. package/dist/src/kernel/runtime/graphpack/read.js +14 -9
  142. package/dist/src/kernel/runtime/graphpack/read.js.map +1 -1
  143. package/dist/src/kernel/runtime/loadSession.js +3 -1
  144. package/dist/src/kernel/runtime/loadSession.js.map +1 -1
  145. package/dist/src/kernel/runtime/probe.js +1 -1
  146. package/dist/src/kernel/runtime/probe.js.map +1 -1
  147. package/dist/src/kernel/runtime/refs/parseRef.js +17 -1
  148. package/dist/src/kernel/runtime/refs/parseRef.js.map +1 -1
  149. package/dist/src/kernel/runtime/refs/resolve.js +9 -3
  150. package/dist/src/kernel/runtime/refs/resolve.js.map +1 -1
  151. package/dist/src/kernel/spec/emitReference.js +1 -1
  152. package/dist/src/kernel/spec/emitReference.js.map +1 -1
  153. package/package.json +24 -20
  154. package/pragma.conf.ts +272 -34
  155. package/src/bin.ts +8 -1
  156. package/src/capabilities/block.parity.test.ts +25 -11
  157. package/src/capabilities/block.shipped.exec.test.ts +282 -0
  158. package/src/capabilities/block.tierRank.exec.test.ts +300 -0
  159. package/src/capabilities/capabilities/hints.ts +1 -1
  160. package/src/capabilities/colophon/colophon.render.ts +1 -2
  161. package/src/capabilities/colophon/colophon.test.ts +2 -2
  162. package/src/capabilities/config/collectConfigShow.test.ts +1 -0
  163. package/src/capabilities/create/byteEquality.test.ts +28 -1
  164. package/src/capabilities/create/create.test.ts +1 -0
  165. package/src/capabilities/create/create.verb.ts +2 -1
  166. package/src/capabilities/create/createGrammar.test.ts +5 -2
  167. package/src/capabilities/create/createSurface.generated.ts +23 -1
  168. package/src/capabilities/create/crossCli.subprocess.test.ts +10 -3
  169. package/src/capabilities/create/mount.ts +3 -3
  170. package/src/capabilities/distribution.parity.test.ts +4 -0
  171. package/src/capabilities/doctor/checks/checkNodeVersion.test.ts +49 -0
  172. package/src/capabilities/doctor/checks/checkNodeVersion.ts +11 -7
  173. package/src/capabilities/doctor/checks/checkPackageRefs.ts +69 -4
  174. package/src/capabilities/doctor/checks/checkShellCompletions.test.ts +6 -4
  175. package/src/capabilities/doctor/checks/checkShellCompletions.ts +8 -8
  176. package/src/capabilities/doctor/checks/harnessInventory.test.ts +219 -0
  177. package/src/capabilities/doctor/checks/harnessInventory.ts +298 -0
  178. package/src/capabilities/doctor/checks/index.ts +6 -6
  179. package/src/capabilities/doctor/checks/isSupportedNodeVersion.test.ts +111 -0
  180. package/src/capabilities/doctor/checks/isSupportedNodeVersion.ts +34 -0
  181. package/src/capabilities/doctor/checks/mcpCommand.test.ts +7 -1
  182. package/src/capabilities/doctor/checks/targetHealth.ts +229 -59
  183. package/src/capabilities/doctor/doctor.render.test.ts +108 -32
  184. package/src/capabilities/doctor/doctor.render.ts +56 -80
  185. package/src/capabilities/doctor/doctor.test.ts +247 -35
  186. package/src/capabilities/doctor/doctor.verb.ts +7 -2
  187. package/src/capabilities/doctor/runChecks.ts +14 -11
  188. package/src/capabilities/doctor/types.ts +15 -24
  189. package/src/capabilities/emptyRecovery.test.ts +10 -2
  190. package/src/capabilities/graph/query.render.ts +2 -2
  191. package/src/capabilities/info/collectInfo.ts +8 -1
  192. package/src/capabilities/info/info.render.ts +6 -2
  193. package/src/capabilities/info/info.test.ts +37 -1
  194. package/src/capabilities/info/types.ts +10 -2
  195. package/src/capabilities/lazy.test.ts +26 -2
  196. package/src/capabilities/listLookup.shipped.exec.test.ts +340 -0
  197. package/src/capabilities/prompt/prompt.render.ts +2 -2
  198. package/src/capabilities/renderVocabularySync.test.ts +82 -0
  199. package/src/capabilities/resources/resources.test.ts +38 -2
  200. package/src/capabilities/scopeTypeSync.test.ts +29 -15
  201. package/src/capabilities/setup/buildPlan.ts +45 -41
  202. package/src/capabilities/setup/index.ts +1 -1
  203. package/src/capabilities/setup/mode.ts +2 -2
  204. package/src/capabilities/setup/operations/index.ts +6 -1
  205. package/src/capabilities/setup/operations/setupCompletions.ts +9 -2
  206. package/src/capabilities/setup/operations/setupConfig.ts +7 -2
  207. package/src/capabilities/setup/operations/setupGenerator.ts +227 -84
  208. package/src/capabilities/setup/operations/setupLsp.ts +203 -38
  209. package/src/capabilities/setup/operations/setupMcp.ts +139 -62
  210. package/src/capabilities/setup/operations/setupSkills.ts +399 -60
  211. package/src/capabilities/setup/plan.render.ts +171 -76
  212. package/src/capabilities/setup/plan.ts +17 -12
  213. package/src/capabilities/setup/setup.mcp.correctness.test.ts +9 -9
  214. package/src/capabilities/setup/setup.render.test.ts +50 -36
  215. package/src/capabilities/setup/setup.render.ts +1 -1
  216. package/src/capabilities/setup/setup.test.ts +1126 -50
  217. package/src/capabilities/setup/setup.verb.ts +174 -68
  218. package/src/capabilities/setup/targets.ts +138 -60
  219. package/src/capabilities/setup/types.ts +10 -18
  220. package/src/capabilities/shared/index.ts +18 -6
  221. package/src/capabilities/shared/packageManager.test.ts +421 -6
  222. package/src/capabilities/shared/packageManager.ts +394 -59
  223. package/src/capabilities/skill/bundledSkills.test.ts +347 -0
  224. package/src/capabilities/skill/discover.ts +100 -11
  225. package/src/capabilities/skill/render.ts +2 -2
  226. package/src/capabilities/skill/skill.test.ts +17 -4
  227. package/src/capabilities/sources/installSkills.ts +181 -3
  228. package/src/capabilities/sources/runUpdate.ts +78 -2
  229. package/src/capabilities/sources/sources.test.ts +228 -0
  230. package/src/capabilities/sources/update.verb.ts +3 -3
  231. package/src/capabilities/surface.test.ts +14 -6
  232. package/src/capabilities/upgrade/runUpgrade.ts +45 -6
  233. package/src/capabilities/upgrade/types.ts +10 -2
  234. package/src/capabilities/upgrade/upgrade.render.ts +9 -2
  235. package/src/capabilities/upgrade/upgrade.test.ts +72 -0
  236. package/src/constants.ts +14 -1
  237. package/src/identity.test.ts +18 -5
  238. package/src/kernel/completion/entitySource.test.ts +15 -2
  239. package/src/kernel/completion/safety.test.ts +16 -9
  240. package/src/kernel/config/defaults.test.ts +19 -3
  241. package/src/kernel/config/readConfig.test.ts +1 -1
  242. package/src/kernel/index.ts +11 -2
  243. package/src/kernel/interactivity.test.ts +76 -0
  244. package/src/kernel/interactivity.ts +69 -0
  245. package/src/kernel/packs/compile.test.ts +92 -0
  246. package/src/kernel/packs/renderPack.ts +3 -3
  247. package/src/kernel/packs/resolveEntity.test.ts +75 -14
  248. package/src/kernel/packs/resolveEntity.ts +88 -24
  249. package/src/kernel/packs/runBodies.ts +84 -19
  250. package/src/kernel/packs/schema.ts +60 -4
  251. package/src/kernel/packs/sparql/applyFilters.ts +125 -4
  252. package/src/kernel/packs/sparql/buildLookupQuery.test.ts +290 -0
  253. package/src/kernel/packs/sparql/buildLookupQuery.ts +327 -45
  254. package/src/kernel/packs/toolDescription.test.ts +35 -1
  255. package/src/kernel/packs/types.ts +125 -2
  256. package/src/kernel/project/cli/buildProgram.test.ts +73 -2
  257. package/src/kernel/project/cli/buildProgram.ts +8 -1
  258. package/src/kernel/project/cli/dispatch.test.ts +5 -4
  259. package/src/kernel/project/cli/dispatch.ts +48 -25
  260. package/src/kernel/project/cli/globalFlags.ts +4 -1
  261. package/src/kernel/project/cli/helpFormat.ts +1 -2
  262. package/src/kernel/project/cli/rootHelp.ts +44 -8
  263. package/src/kernel/project/mcp/registerVerb.ts +20 -1
  264. package/src/kernel/render/prefixes.test.ts +2 -0
  265. package/src/kernel/render/renderers.ts +1 -1
  266. package/src/kernel/render/style.ts +32 -9
  267. package/src/kernel/render/vocabulary.ts +276 -0
  268. package/src/kernel/runtime/graphpack/embedded/pack.generated.ts +2 -3
  269. package/src/kernel/runtime/graphpack/embedded/pack.index.generated.ts +1 -1
  270. package/src/kernel/runtime/graphpack/embedded/pack.manifest.generated.ts +3 -0
  271. package/src/kernel/runtime/graphpack/embedded.ts +14 -6
  272. package/src/kernel/runtime/graphpack/graphpack.test.ts +31 -5
  273. package/src/kernel/runtime/graphpack/read.ts +14 -12
  274. package/src/kernel/runtime/loadSession.ts +3 -1
  275. package/src/kernel/runtime/probe.ts +1 -1
  276. package/src/kernel/runtime/refs/parseRef.test.ts +49 -1
  277. package/src/kernel/runtime/refs/parseRef.ts +25 -1
  278. package/src/kernel/runtime/refs/resolve.ts +9 -3
  279. package/src/kernel/runtime/types.ts +17 -0
  280. package/src/kernel/spec/emitReference.ts +1 -1
  281. package/src/kernel/spec/types.ts +35 -6
  282. package/src/testing/PARITY_GAPS.ts +9 -3
  283. package/src/testing/behavioral/docExamples.test.ts +4 -2
  284. package/src/testing/behavioral/errorMatrix.mcp.test.ts +110 -7
  285. package/src/testing/behavioral/journeys.firstInstall.test.ts +7 -2
  286. package/src/testing/behavioral/journeys.packageStories.test.ts +6 -3
  287. package/src/testing/eval/__snapshots__/eval.test.ts.snap +26 -1
  288. package/src/testing/eval/cases/readNouns.ts +245 -9
  289. package/src/testing/fixtures/blockGraph.ts +28 -13
  290. package/src/testing/fixtures/graph/canonical.ts +95 -12
  291. package/src/testing/helpers/runCli.test.ts +44 -0
  292. package/src/testing/helpers/runCli.ts +27 -3
  293. package/dist/src/capabilities/shared/bands.js +0 -16
  294. package/dist/src/capabilities/shared/bands.js.map +0 -1
  295. 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, shell completions, agent skills, and the LSP extension. Each installer can target your project's configuration, your user-level (global) configuration, 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`.
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 says what to fix. `pragma info` shows the version, the configuration in effect, and update status; `pragma upgrade` updates the CLI itself.
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.