@canonical/code-standards 0.1.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/docs/tsdoc.md ADDED
@@ -0,0 +1,213 @@
1
+ # TSDoc Standards
2
+
3
+ Standards for tsdoc development.
4
+
5
+ ## tsdoc/documentation-layers
6
+
7
+ File-level and export-level TSDoc serve fundamentally different purposes. Export-level documentation describes *what the symbol does* — its API contract, parameters, return semantics, and side effects. File-level documentation describes *why this module exists* — its architectural role, the design invariants it upholds, and how its exports relate to each other. In single-export files the file exists solely to house that export, so file-level documentation is redundant; document only the exported symbol. In multi-export files, a file-level block is warranted when it explains the cohesion principle that binds the exports together — the reason they live in one file rather than separate ones.
8
+
9
+ ### Do
10
+
11
+ (Do) In single-export files, document only at the export level — the API contract belongs on the symbol.
12
+ ```typescript
13
+ // resolveDefinition.ts — single export, no file-level block needed
14
+ /** Resolve definition locations for a CSS custom property. */
15
+ export default function resolveDefinition(cssVar: string, graph: TokenGraph) {
16
+ // ...
17
+ }
18
+ ```
19
+
20
+ (Do) In multi-export files, use a file-level block to explain the module's architectural purpose — why these exports are grouped.
21
+ ```typescript
22
+ // types.ts — multiple exports, file-level explains cohesion
23
+ /**
24
+ * Shared types for diagnostic rule modules.
25
+ *
26
+ * Each diagnostic check receives one of these context objects,
27
+ * ensuring a uniform interface across per-usage and file-level rules.
28
+ */
29
+
30
+ export interface UsageRuleContext { /* ... */ }
31
+ export interface FileRuleContext { /* ... */ }
32
+ ```
33
+
34
+ (Do) Use export-level TSDoc to describe the API contract: what the symbol does, its parameters, return value, and any side effects.
35
+ ```typescript
36
+ /**
37
+ * Check: css/missing-fallback — var() without a fallback on an unregistered property.
38
+ *
39
+ * Pushes a diagnostic when a var() usage has no fallback and the property
40
+ * is not registered via @property.
41
+ */
42
+ export default function checkMissingFallback(ctx: UsageRuleContext, results: Diagnostic[]) {
43
+ // ...
44
+ }
45
+ ```
46
+
47
+ ### Don't
48
+
49
+ (Don't) Add a file-level block in a single-export file that restates what the export-level doc already says.
50
+ ```typescript
51
+ // Bad: file-level repeats the export's own description
52
+ /** Resolve definitions for CSS custom property usages. */
53
+
54
+ /** Resolve definitions for CSS custom property usages. */
55
+ export default function resolveDefinition() { /* ... */ }
56
+ ```
57
+
58
+ (Don't) Use file-level docs to describe *what* an export does — that belongs on the export itself.
59
+ ```typescript
60
+ // Bad: file-level describes the function instead of the module's role
61
+ /** Build a completion item for a CSS variable. */
62
+
63
+ export default function buildCompletionItem(name: string) { /* ... */ }
64
+ ```
65
+
66
+ (Don't) Omit file-level docs on multi-export modules where the grouping rationale is non-obvious.
67
+ ```typescript
68
+ // Bad: reader cannot tell why these live together
69
+ export function isCompletionRequest(req: WorkerRequest) { /* ... */ }
70
+ export function isHoverRequest(req: WorkerRequest) { /* ... */ }
71
+ export function isDiagnosticsRequest(req: WorkerRequest) { /* ... */ }
72
+ ```
73
+
74
+ ---
75
+
76
+ ## tsdoc/module-tag-location
77
+
78
+ The `@module` TSDoc tag must appear only on barrel files such as `index.ts`. Ordinary source files must document their exported API directly and must not use file-level `@module` tags.
79
+
80
+ ### Do
81
+
82
+ (Do) Use `@module` on a barrel file that defines a package or folder-level API.
83
+ ```typescript
84
+ /**
85
+ * Public protocol API.
86
+ * @module protocol
87
+ */
88
+ export { createRequest, matchResponse } from './index.js';
89
+ ```
90
+
91
+ (Do) Document an ordinary source file at the exported symbol instead of using `@module`.
92
+ ```typescript
93
+ /** Build a completion item for a CSS variable. */
94
+ export default function buildCompletionItem(name: string) {
95
+ // ...
96
+ }
97
+ ```
98
+
99
+ ### Don't
100
+
101
+ (Don't) Add `@module` to a single-purpose implementation file.
102
+ ```typescript
103
+ /**
104
+ * Build a completion item.
105
+ * @module providers/completions/buildCompletionItem
106
+ */
107
+ export default function buildCompletionItem(name: string) {
108
+ // ...
109
+ }
110
+ ```
111
+
112
+ (Don't) Use file-level `@module` tags as a substitute for export documentation.
113
+ ```typescript
114
+ /** @module helpers/formatCurrency */
115
+ export default function formatCurrency(value: number) {
116
+ return `$${value}`;
117
+ }
118
+ ```
119
+
120
+ ---
121
+
122
+ ## tsdoc/self-contained
123
+
124
+ TSDoc comments must be self-contained — a reader should fully understand the documented symbol from its comment alone. External links (public specs, RFCs, GitHub issues) are allowed as supplementary references, but the comment itself must never depend on them for comprehension. If an external concept drives the implementation, distill the essential information into the comment.
125
+
126
+ ### Do
127
+
128
+ (Do) Explain the concept inline so the reader needs nothing else:
129
+ ```typescript
130
+ /**
131
+ * Encode a string as a percent-encoded URI component.
132
+ *
133
+ * Replaces every character that is not an unreserved character
134
+ * (A-Z, a-z, 0-9, `-`, `.`, `_`, `~`) with its UTF-8 percent-encoded form.
135
+ */
136
+ export function encodeComponent(value: string): string {
137
+ // ...
138
+ }
139
+ ```
140
+
141
+ (Do) Add an external link as a supplementary reference after a self-sufficient explanation:
142
+ ```typescript
143
+ /**
144
+ * Compare two semantic version strings.
145
+ *
146
+ * Compares major, minor, and patch numerically in that order.
147
+ * Returns a negative number if `a < b`, zero if equal, or a positive number if `a > b`.
148
+ * Pre-release versions (e.g. `1.0.0-alpha`) sort before their release counterpart.
149
+ *
150
+ * @see https://semver.org
151
+ */
152
+ export function compareVersions(a: string, b: string): number {
153
+ // ...
154
+ }
155
+ ```
156
+
157
+ (Do) Reference a GitHub issue for additional context when the comment already explains the behaviour:
158
+ ```typescript
159
+ /**
160
+ * Truncate session tokens to 64 characters before storage.
161
+ *
162
+ * Tokens longer than 64 characters exceed the column width in the
163
+ * sessions table and would be silently truncated by the database,
164
+ * so we enforce the limit explicitly.
165
+ *
166
+ * @see https://github.com/acme/backend/issues/412
167
+ */
168
+ export function truncateToken(token: string): string {
169
+ // ...
170
+ }
171
+ ```
172
+
173
+ ### Don't
174
+
175
+ (Don't) Point the reader to an external resource instead of explaining the behaviour:
176
+ ```typescript
177
+ /**
178
+ * Encode a URI component.
179
+ *
180
+ * Implements RFC 3986 §2.1.
181
+ * @see https://datatracker.ietf.org/doc/html/rfc3986#section-2.1
182
+ */
183
+ export function encodeComponent(value: string): string {
184
+ // ...
185
+ }
186
+ ```
187
+
188
+ (Don't) Reference a wiki or internal doc as a substitute for inline explanation:
189
+ ```typescript
190
+ /**
191
+ * Truncate session tokens before storage.
192
+ *
193
+ * See the security review document for rationale:
194
+ * https://wiki.internal/security/session-token-length
195
+ */
196
+ export function truncateToken(token: string): string {
197
+ // ...
198
+ }
199
+ ```
200
+
201
+ (Don't) Leave the reader unable to understand the symbol without following a link:
202
+ ```typescript
203
+ /**
204
+ * Compare two semantic version strings.
205
+ *
206
+ * @see https://semver.org for the full specification.
207
+ */
208
+ export function compareVersions(a: string, b: string): number {
209
+ // ...
210
+ }
211
+ ```
212
+
213
+ ---
package/docs/turtle.md ADDED
@@ -0,0 +1,179 @@
1
+ # Turtle Standards
2
+
3
+ Standards for turtle development.
4
+
5
+ ## turtle/naming/local-name-casing
6
+
7
+ Within a unified prefix namespace, differentiate between schema elements and instances using casing conventions for the local name (the part after the prefix colon):
8
+
9
+ - **PascalCase** for classes (e.g., `ds:Component`, `ds:UIElement`)
10
+ - **camelCase** for properties (e.g., `ds:name`, `ds:hasProperty`)
11
+ - **lowercase** (often with dots or hyphens) for instances (e.g., `ds:global.component.button`)
12
+
13
+ This convention allows a single prefix to serve both definitions and data, with the casing clearly indicating the type of resource.
14
+
15
+ ### Do
16
+
17
+ (Do) Use PascalCase for class names.
18
+ ```turtle
19
+ ds:Component a owl:Class .
20
+ ds:UIBlock a owl:Class .
21
+ ds:ModifierFamily a owl:Class .
22
+ ```
23
+
24
+ (Do) Use camelCase for property names.
25
+ ```turtle
26
+ ds:name a owl:DatatypeProperty .
27
+ ds:hasProperty a owl:ObjectProperty .
28
+ ds:parentComponent a owl:ObjectProperty .
29
+ ```
30
+
31
+ (Do) Use lowercase (with dots or hyphens as separators) for instance identifiers.
32
+ ```turtle
33
+ ds:global.component.button a ds:Component .
34
+ ds:global.modifier_family.importance a ds:ModifierFamily .
35
+ ```
36
+
37
+ ### Don't
38
+
39
+ (Don't) Use lowercase for class names.
40
+ ```turtle
41
+ # Bad: Class names should be PascalCase
42
+ ds:component a owl:Class .
43
+ ```
44
+
45
+ (Don't) Use PascalCase for instance identifiers.
46
+ ```turtle
47
+ # Bad: Instance names should be lowercase
48
+ ds:GlobalComponentButton a ds:Component .
49
+ ```
50
+
51
+ (Don't) Use PascalCase or uppercase for property names.
52
+ ```turtle
53
+ # Bad: Property names should be camelCase
54
+ ds:HasProperty a owl:ObjectProperty .
55
+ ds:NAME a owl:DatatypeProperty .
56
+ ```
57
+
58
+ ---
59
+
60
+ ## turtle/naming/unified-prefix
61
+
62
+ When a package uses a single namespace for both ontology and data, use a unified prefix with casing to distinguish between classes, properties, and instances. This simplifies prefix management and makes the relationship between schema and data more apparent.
63
+
64
+ The namespace URI should be a base URI without a fragment or trailing path segment for ontology vs data (e.g., `https://ds.canonical.com/` rather than separate `https://ds.canonical.com/ontology#` and `https://ds.canonical.com/data/`).
65
+
66
+ ### Do
67
+
68
+ (Do) Use a single prefix for both definitions and data.
69
+ ```turtle
70
+ # In both definitions/ and data/ files:
71
+ @prefix ds: <https://ds.canonical.com/> .
72
+
73
+ # Definitions use PascalCase/camelCase
74
+ ds:Component a owl:Class .
75
+ ds:name a owl:DatatypeProperty .
76
+
77
+ # Data uses lowercase
78
+ ds:global.component.button a ds:Component ;
79
+ ds:name "Button" .
80
+ ```
81
+
82
+ ### Don't
83
+
84
+ (Don't) Use separate prefixes for ontology and data when a unified prefix is preferred.
85
+ ```turtle
86
+ # Bad: Unnecessarily complex when unified prefix suffices
87
+ @prefix dso: <https://ds.canonical.com/ontology#> .
88
+ @prefix ds: <https://ds.canonical.com/data/> .
89
+
90
+ ds:global.component.button a dso:Component .
91
+ ```
92
+
93
+ ---
94
+
95
+ ## turtle/structure/definitions-vs-data
96
+
97
+ Turtle files must be organized into two directories based on their content:
98
+
99
+ - `definitions/` contains schema files (ontologies) with classes, properties, and datatypes
100
+ - `data/` contains instance files with actual data conforming to the schema
101
+
102
+ This separation allows tools to distinguish between schema and instance data, enables different validation rules, and makes the codebase easier to navigate.
103
+
104
+ ### Do
105
+
106
+ (Do) Place ontology definitions (classes, properties, datatypes) in the `definitions/` directory.
107
+ ```turtle
108
+ # definitions/ontology.ttl
109
+ @prefix ds: <https://ds.canonical.com/> .
110
+
111
+ ds:Component a owl:Class ;
112
+ rdfs:label "Component" .
113
+
114
+ ds:name a owl:DatatypeProperty ;
115
+ rdfs:domain ds:UIElement ;
116
+ rdfs:range xsd:string .
117
+ ```
118
+
119
+ (Do) Place instance data in the `data/` directory.
120
+ ```turtle
121
+ # data/global/component/button.ttl
122
+ @prefix ds: <https://ds.canonical.com/> .
123
+
124
+ ds:global.component.button a ds:Component ;
125
+ ds:name "Button" .
126
+ ```
127
+
128
+ ### Don't
129
+
130
+ (Don't) Mix class definitions and instance data in the same file.
131
+ ```turtle
132
+ # Bad: Mixing schema and data
133
+ ds:Component a owl:Class .
134
+ ds:global.component.button a ds:Component .
135
+ ```
136
+
137
+ (Don't) Place instance data in the `definitions/` directory.
138
+ ```
139
+ # Bad: Data file in definitions
140
+ definitions/
141
+ └── button.ttl # Contains instance data
142
+ ```
143
+
144
+ ---
145
+
146
+ ## turtle/syntax/prefix-declaration
147
+
148
+ Every Turtle file must declare all prefixes used within the file at the top of the file. Each prefix should be declared exactly once. Standard prefixes (rdf, rdfs, owl, xsd, skos) should be declared when used but are commonly understood.
149
+
150
+ ### Do
151
+
152
+ (Do) Declare all prefixes at the top of the file.
153
+ ```turtle
154
+ @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
155
+ @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
156
+ @prefix owl: <http://www.w3.org/2002/07/owl#> .
157
+ @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
158
+ @prefix ds: <https://ds.canonical.com/> .
159
+
160
+ ds:Component a owl:Class ;
161
+ rdfs:label "Component" .
162
+ ```
163
+
164
+ ### Don't
165
+
166
+ (Don't) Declare the same prefix multiple times.
167
+ ```turtle
168
+ # Bad: Duplicate prefix declaration
169
+ @prefix ds: <https://ds.canonical.com/> .
170
+ @prefix ds: <https://ds.canonical.com/> .
171
+ ```
172
+
173
+ (Don't) Use prefixes without declaring them.
174
+ ```turtle
175
+ # Bad: Missing prefix declaration for ds:
176
+ ds:Component a owl:Class .
177
+ ```
178
+
179
+ ---
package/package.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "@canonical/code-standards",
3
+ "version": "0.1.0",
4
+ "description": "Code standards ontology and documentation generator",
5
+ "type": "module",
6
+ "scripts": {
7
+ "docs": "bun src/scripts/generate-docs.ts"
8
+ }
9
+ }
@@ -0,0 +1,288 @@
1
+ # Add Standard
2
+
3
+ Create and add a new code standard to the code-standards package.
4
+
5
+ ## When to Use
6
+
7
+ Use this skill when:
8
+ - "Add a standard for..."
9
+ - "Create a coding standard..."
10
+ - "Document a new convention..."
11
+ - "Add guidance for..."
12
+
13
+ ## Workflow
14
+
15
+ ### 1. Check for Existing Standards
16
+
17
+ Before creating a new standard, always check if one already exists:
18
+
19
+ ```sparql
20
+ PREFIX cs: <http://pragma.canonical.com/codestandards#>
21
+
22
+ SELECT ?standard ?name ?description WHERE {
23
+ ?standard a cs:CodeStandard ;
24
+ cs:name ?name ;
25
+ cs:description ?description .
26
+ FILTER(CONTAINS(LCASE(?name), "your-topic"))
27
+ }
28
+ ```
29
+
30
+ Or use lookup:
31
+ ```
32
+ sem_lookup(type: "cs:CodeStandard", filters: {"cs:name": {"$contains": "your-topic"}})
33
+ ```
34
+
35
+ ### 2. Determine the Category
36
+
37
+ List existing categories to find the right fit:
38
+
39
+ ```sparql
40
+ PREFIX cs: <http://pragma.canonical.com/codestandards#>
41
+ PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
42
+
43
+ SELECT ?category ?label ?slug WHERE {
44
+ ?category a cs:Category ;
45
+ rdfs:label ?label ;
46
+ cs:slug ?slug .
47
+ }
48
+ ```
49
+
50
+ **Available Categories:**
51
+
52
+ | Category | Slug | Description |
53
+ |----------|------|-------------|
54
+ | React | `react` | React component development |
55
+ | CSS | `css` | CSS technical implementation |
56
+ | Styling | `styling` | Design system styling patterns |
57
+ | Code | `code` | General TypeScript standards |
58
+ | Storybook | `storybook` | Storybook documentation |
59
+ | Icons | `icons` | Icon implementation |
60
+
61
+ If no existing category fits, create a new one (see Section 5).
62
+
63
+ ### 3. Design the Standard Name
64
+
65
+ Standard names follow a hierarchical pattern: `{category}/{domain}/{topic}`
66
+
67
+ **Pattern:** `^[a-z]+(/[a-z0-9-]+){2,}$`
68
+
69
+ **Examples:**
70
+ - `react/component/structure/folder`
71
+ - `css/selectors/namespace`
72
+ - `styling/tokens/creation`
73
+ - `react/hooks/naming`
74
+
75
+ **Guidelines:**
76
+ - Use lowercase with hyphens for multi-word segments
77
+ - Minimum 3 segments (category/domain/topic)
78
+ - Be specific but not overly verbose
79
+ - Follow existing naming patterns in the same category
80
+
81
+ ### 4. Write the Standard
82
+
83
+ Create a new standard instance in the appropriate data file under `data/`.
84
+
85
+ **Template:**
86
+
87
+ ```turtle
88
+ cs:YourStandardName a cs:CodeStandard ;
89
+ cs:name "category/domain/topic" ;
90
+ cs:hasCategory cs:CategoryName ;
91
+ cs:description "Clear, concise description of what this standard covers and why it matters." ;
92
+ cs:dos """
93
+ (Do) First recommended practice with example.
94
+ ```code
95
+ // Example showing the correct approach
96
+ ```
97
+
98
+ (Do) Second recommended practice.
99
+ ```code
100
+ // Another example
101
+ ```
102
+ """ ;
103
+ cs:donts """
104
+ (Don't) First anti-pattern to avoid.
105
+ ```code
106
+ // Example showing what NOT to do
107
+ ```
108
+
109
+ (Don't) Second anti-pattern.
110
+ ```code
111
+ // Another bad example
112
+ ```
113
+ """ .
114
+ ```
115
+
116
+ **Required Properties:**
117
+ - `cs:name` - Hierarchical identifier (must match NamePattern)
118
+ - `cs:hasCategory` - Reference to a Category instance
119
+ - `cs:description` - What and why (plain text or markdown)
120
+ - `cs:dos` - What TO do with examples
121
+ - `cs:donts` - What NOT to do with examples
122
+
123
+ **Optional Properties:**
124
+ - `cs:extends` - Reference to a parent standard this builds upon
125
+
126
+ ### 5. Create a New Category (if needed)
127
+
128
+ If your standard doesn't fit existing categories:
129
+
130
+ ```turtle
131
+ cs:NewCategory a cs:Category ;
132
+ rdfs:label "Category Name"@en ;
133
+ rdfs:comment "Description of what this category covers"@en ;
134
+ cs:slug "slug-name" .
135
+ ```
136
+
137
+ ### 6. Extending Existing Standards
138
+
139
+ When your standard builds on another:
140
+
141
+ ```turtle
142
+ cs:SpecificStandard a cs:CodeStandard ;
143
+ cs:name "react/component/props/special-case" ;
144
+ cs:extends cs:ComponentProps ; # Reference to parent
145
+ cs:hasCategory cs:ReactCategory ;
146
+ cs:description "Specific guidance that builds on the general props standard." ;
147
+ # ... dos and donts ...
148
+ ```
149
+
150
+ Query to find potential parent standards:
151
+ ```sparql
152
+ PREFIX cs: <http://pragma.canonical.com/codestandards#>
153
+
154
+ SELECT ?standard ?name WHERE {
155
+ ?standard a cs:CodeStandard ;
156
+ cs:name ?name .
157
+ FILTER(STRSTARTS(?name, "react/component/props"))
158
+ }
159
+ ```
160
+
161
+ ### 7. Validate Before Committing
162
+
163
+ After writing the standard, validate the Turtle syntax:
164
+
165
+ ```bash
166
+ sem check code-standards
167
+ ```
168
+
169
+ Then verify the standard loads correctly:
170
+ ```
171
+ sem_lookup(type: "cs:CodeStandard", filters: {"cs:name": "your/new/standard"})
172
+ ```
173
+
174
+ ## File Organization
175
+
176
+ Standards are organized by category in `data/`:
177
+
178
+ ```
179
+ code-standards/
180
+ ├── definitions/
181
+ │ └── CodeStandard.ttl # Ontology schema
182
+ ├── data/
183
+ │ ├── react.ttl # React standards
184
+ │ ├── css.ttl # CSS standards
185
+ │ ├── styling.ttl # Styling standards
186
+ │ ├── code.ttl # General code standards
187
+ │ ├── storybook.ttl # Storybook standards
188
+ │ └── icons.ttl # Icon standards
189
+ └── skills/
190
+ └── standards-guide/
191
+ └── SKILL.md
192
+ ```
193
+
194
+ Add new standards to the file matching their category.
195
+
196
+ ## Writing Quality Standards
197
+
198
+ ### Description Guidelines
199
+ - Start with WHAT the standard covers
200
+ - Explain WHY it matters
201
+ - Keep it concise but complete
202
+ - Use markdown for complex descriptions
203
+
204
+ ### Do's Guidelines
205
+ - Start each item with `(Do)`
206
+ - Provide concrete, runnable examples
207
+ - Show the COMPLETE correct pattern
208
+ - Explain the reasoning when not obvious
209
+
210
+ ### Don'ts Guidelines
211
+ - Start each item with `(Don't)`
212
+ - Show realistic mistakes developers make
213
+ - Explain WHY it's problematic
214
+ - Mirror the structure of the do's section
215
+
216
+ ### Example Quality Checklist
217
+ - [ ] Examples are syntactically correct
218
+ - [ ] Examples are self-contained (can be understood without context)
219
+ - [ ] Examples use realistic code, not `foo`/`bar`
220
+ - [ ] Examples include comments explaining key points
221
+ - [ ] Both do's and don'ts cover the same scenarios
222
+
223
+ ## Complete Example
224
+
225
+ Adding a new standard for React error boundaries:
226
+
227
+ ```turtle
228
+ # In data/react.ttl
229
+
230
+ cs:ErrorBoundaryUsage a cs:CodeStandard ;
231
+ cs:name "react/component/error-boundaries" ;
232
+ cs:hasCategory cs:ReactCategory ;
233
+ 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." ;
234
+ cs:dos """
235
+ (Do) Wrap feature sections with error boundaries to isolate failures.
236
+ ```tsx
237
+ const Dashboard = () => (
238
+ <div className="ds dashboard">
239
+ <ErrorBoundary fallback={<WidgetError />}>
240
+ <AnalyticsWidget />
241
+ </ErrorBoundary>
242
+ <ErrorBoundary fallback={<WidgetError />}>
243
+ <ActivityWidget />
244
+ </ErrorBoundary>
245
+ </div>
246
+ );
247
+ ```
248
+
249
+ (Do) Provide meaningful fallback UI that helps users understand and recover.
250
+ ```tsx
251
+ const WidgetError = () => (
252
+ <div className="ds widget-error">
253
+ <p>This section couldn't load.</p>
254
+ <button onClick={() => window.location.reload()}>
255
+ Refresh page
256
+ </button>
257
+ </div>
258
+ );
259
+ ```
260
+ """ ;
261
+ cs:donts """
262
+ (Don't) Wrap the entire application in a single error boundary.
263
+ ```tsx
264
+ // Bad: One error anywhere crashes everything
265
+ const App = () => (
266
+ <ErrorBoundary>
267
+ <Header />
268
+ <Main />
269
+ <Footer />
270
+ </ErrorBoundary>
271
+ );
272
+ ```
273
+
274
+ (Don't) Use generic or unhelpful fallback messages.
275
+ ```tsx
276
+ // Bad: Doesn't help the user
277
+ const fallback = <div>Something went wrong</div>;
278
+ ```
279
+ """ .
280
+ ```
281
+
282
+ ## Tips
283
+
284
+ 1. **Check before creating**: Always search for existing standards first - you might need to extend rather than create new
285
+ 2. **Follow patterns**: Look at existing standards in the same category for style guidance
286
+ 3. **Be specific**: Vague standards are hard to follow - include concrete examples
287
+ 4. **Test your examples**: Make sure code examples actually work
288
+ 5. **Consider hierarchy**: Use `cs:extends` when your standard builds on another