jettypod 3.0.1

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 (122) hide show
  1. package/.claude/PROTECT_SKILLS.md +28 -0
  2. package/.claude/settings.json +24 -0
  3. package/.claude/settings.local.json +16 -0
  4. package/.claude/skills/epic-discover/SKILL.md +262 -0
  5. package/.claude/skills/feature-discover/SKILL.md +393 -0
  6. package/.claude/skills/speed-mode/SKILL.md +364 -0
  7. package/.claude/skills/stable-mode/SKILL.md +591 -0
  8. package/.github/workflows/test-safety.yml +85 -0
  9. package/README.md +25 -0
  10. package/SPEED-STABLE-AUDIT.md +853 -0
  11. package/SYSTEM-BEHAVIOR.md +1241 -0
  12. package/TEST_SAFETY_AUDIT.md +314 -0
  13. package/TEST_SAFETY_IMPLEMENTATION.md +97 -0
  14. package/cucumber.js +8 -0
  15. package/docs/COMMAND_REFERENCE.md +903 -0
  16. package/docs/DECISIONS.md +68 -0
  17. package/docs/README.md +48 -0
  18. package/docs/STANDARDS-SYSTEM-DOCUMENTATION.md +374 -0
  19. package/docs/TEST-REWRITE-PLAN.md +261 -0
  20. package/docs/ai-test-writing-requirements.md +219 -0
  21. package/docs/claude-code-skills.md +607 -0
  22. package/docs/core-jettypod-methodology/comprehensive-jettypod-methodology.md +582 -0
  23. package/docs/core-jettypod-methodology/deprecated/jettypod-comprehensive-standards.md +1222 -0
  24. package/docs/core-jettypod-methodology/deprecated/jettypod-operating-guide.md +3399 -0
  25. package/docs/core-jettypod-methodology/deprecated/jettypod-technical-checklist.md +1325 -0
  26. package/docs/core-jettypod-methodology/deprecated/jettypod-vibe-coding-framework.md +1544 -0
  27. package/docs/core-jettypod-methodology/deprecated/prompt-engineering-guide.md +320 -0
  28. package/docs/core-jettypod-methodology/deprecated/vibe-coding-cheatsheet (1).md +516 -0
  29. package/docs/core-jettypod-methodology/deprecated/vibe-coding-framework.md +1544 -0
  30. package/docs/features/jettypod-standards-explained.md +543 -0
  31. package/docs/features/standards-inventory.md +257 -0
  32. package/docs/gap-analysis-current-vs-comprehensive-methodology.md +939 -0
  33. package/docs/jettypod-system-overview.md +409 -0
  34. package/features/auto-generate-production-chores.feature +14 -0
  35. package/features/claude-md-protection/steps.js +487 -0
  36. package/features/decisions/index.js +490 -0
  37. package/features/decisions/index.test.js +208 -0
  38. package/features/git-hooks/git-hooks.feature +30 -0
  39. package/features/git-hooks/index.js +93 -0
  40. package/features/git-hooks/index.test.js +137 -0
  41. package/features/git-hooks/post-commit +56 -0
  42. package/features/git-hooks/post-merge +47 -0
  43. package/features/git-hooks/pre-commit +28 -0
  44. package/features/git-hooks/simple-steps.js +53 -0
  45. package/features/git-hooks/simple-test.feature +10 -0
  46. package/features/git-hooks/steps.js +196 -0
  47. package/features/jettypod-update-command.feature +46 -0
  48. package/features/mode-prompts/index.js +95 -0
  49. package/features/mode-prompts/simple-steps.js +44 -0
  50. package/features/mode-prompts/simple-test.feature +9 -0
  51. package/features/mode-prompts/validation.test.js +120 -0
  52. package/features/refactor-mode/steps.js +217 -0
  53. package/features/refactor-mode.feature +49 -0
  54. package/features/skills-update/index.test.js +216 -0
  55. package/features/step_definitions/auto-generate-production-chores.steps.js +162 -0
  56. package/features/step_definitions/terminal-logo.steps.js +145 -0
  57. package/features/step_definitions/update-command.steps.js +183 -0
  58. package/features/terminal-logo/index.js +39 -0
  59. package/features/terminal-logo/terminal-logo.feature +30 -0
  60. package/features/update-command/index.js +181 -0
  61. package/features/update-command/index.test.js +225 -0
  62. package/features/work-commands/bug-workflow-display.feature +22 -0
  63. package/features/work-commands/index.js +311 -0
  64. package/features/work-commands/simple-steps.js +69 -0
  65. package/features/work-commands/stable-tests.feature +57 -0
  66. package/features/work-commands/steps.js +1120 -0
  67. package/features/work-commands/validation.test.js +88 -0
  68. package/features/work-commands/work-commands.feature +13 -0
  69. package/features/work-tracking/discovery-validation.test.js +228 -0
  70. package/features/work-tracking/index.js +1511 -0
  71. package/features/work-tracking/mode-required.feature +112 -0
  72. package/features/work-tracking/phase-tracking.test.js +482 -0
  73. package/features/work-tracking/prototype-tracking.test.js +485 -0
  74. package/features/work-tracking/tree-view.test.js +310 -0
  75. package/features/work-tracking/work-set-mode.feature +71 -0
  76. package/features/work-tracking/work-start-mode.feature +88 -0
  77. package/full-test.txt +0 -0
  78. package/install.sh +89 -0
  79. package/jettypod.js +1640 -0
  80. package/lib/bug-workflow.js +94 -0
  81. package/lib/bug-workflow.test.js +177 -0
  82. package/lib/claudemd.js +130 -0
  83. package/lib/claudemd.test.js +195 -0
  84. package/lib/comprehensive-standards-full.json +1778 -0
  85. package/lib/config.js +181 -0
  86. package/lib/config.test.js +511 -0
  87. package/lib/constants.js +107 -0
  88. package/lib/constants.test.js +164 -0
  89. package/lib/current-work.js +130 -0
  90. package/lib/current-work.test.js +146 -0
  91. package/lib/database-project-config.test.js +107 -0
  92. package/lib/database.js +256 -0
  93. package/lib/database.test.js +106 -0
  94. package/lib/decisions-generator.js +102 -0
  95. package/lib/decisions-generator.test.js +457 -0
  96. package/lib/decisions-helpers.js +119 -0
  97. package/lib/decisions-helpers.test.js +310 -0
  98. package/lib/discovery-checkpoint.js +83 -0
  99. package/lib/docs-generator.js +280 -0
  100. package/lib/external-checklist.js +177 -0
  101. package/lib/git.js +142 -0
  102. package/lib/git.test.js +145 -0
  103. package/lib/logo.js +3 -0
  104. package/lib/migrations/001-epic-to-parent.js +24 -0
  105. package/lib/migrations/002-default-work-item-modes.js +37 -0
  106. package/lib/migrations/002-default-work-item-modes.test.js +351 -0
  107. package/lib/migrations/003-epic-discovery-fields.js +52 -0
  108. package/lib/migrations/004-discovery-decisions-table.js +32 -0
  109. package/lib/migrations/005-migrate-decision-data.js +62 -0
  110. package/lib/migrations/006-feature-phase-field.js +61 -0
  111. package/lib/migrations/007-prototype-tracking.js +38 -0
  112. package/lib/migrations/008-scenario-file-field.js +24 -0
  113. package/lib/migrations/index.js +74 -0
  114. package/lib/production-helpers.js +69 -0
  115. package/lib/project-state.test.js +92 -0
  116. package/lib/test-helpers.js +184 -0
  117. package/lib/test-helpers.test.js +255 -0
  118. package/package.json +36 -0
  119. package/prototypes/test/index.html +1 -0
  120. package/setup-dist-repo.sh +68 -0
  121. package/test-safety-check.sh +80 -0
  122. package/work-item-tracking-plan.md +199 -0
@@ -0,0 +1,1778 @@
1
+ {
2
+ "version": "2.0.0",
3
+ "description": "Complete standards library from JettyPod Comprehensive Standards document",
4
+ "standards": {
5
+ "project.structure.directory": {
6
+ "id": "project.structure.directory",
7
+ "bundle": "core",
8
+ "category": "structure",
9
+ "priority": "critical",
10
+ "stages": ["empty"],
11
+ "rule": "Feature-based directory structure",
12
+ "shortRule": "Feature-based structure",
13
+ "example": "/features, /shared, /core",
14
+ "antipattern": "Flat structure with all files in src/",
15
+ "details": {
16
+ "structure": "feature-based",
17
+ "rules": [
18
+ "Features contain their own components, hooks, utils",
19
+ "Shared must be used by 2+ features",
20
+ "Core is for auth, db, config only"
21
+ ]
22
+ },
23
+ "showInClaude": false,
24
+ "violations": 0,
25
+ "threshold": 3
26
+ },
27
+ "file.naming.component": {
28
+ "id": "file.naming.component",
29
+ "bundle": "core",
30
+ "category": "naming",
31
+ "priority": "critical",
32
+ "stages": ["empty"],
33
+ "rule": "PascalCase.tsx for React components",
34
+ "shortRule": "PascalCase.tsx for components",
35
+ "example": "UserProfile.tsx",
36
+ "antipattern": "user-profile.tsx",
37
+ "detector": "\\.tsx$",
38
+ "showInClaude": false,
39
+ "violations": 0,
40
+ "threshold": 3
41
+ },
42
+ "file.naming.utility": {
43
+ "id": "file.naming.utility",
44
+ "bundle": "core",
45
+ "category": "naming",
46
+ "priority": "critical",
47
+ "stages": ["empty"],
48
+ "rule": "camelCase.ts for utility files",
49
+ "shortRule": "camelCase for utils",
50
+ "example": "formatDate.ts",
51
+ "antipattern": "format-date.ts",
52
+ "detector": "utils.*\\.ts$",
53
+ "showInClaude": false,
54
+ "violations": 0,
55
+ "threshold": 3
56
+ },
57
+ "file.naming.hooks": {
58
+ "id": "file.naming.hooks",
59
+ "bundle": "react",
60
+ "category": "naming",
61
+ "priority": "critical",
62
+ "stages": ["empty"],
63
+ "rule": "useCamelCase.ts for custom hooks",
64
+ "shortRule": "useCamelCase for hooks",
65
+ "example": "useAuth.ts",
66
+ "antipattern": "auth-hook.ts",
67
+ "detector": "^use[A-Z].*\\.ts$",
68
+ "showInClaude": false,
69
+ "violations": 0,
70
+ "threshold": 3
71
+ },
72
+ "file.naming.constants": {
73
+ "id": "file.naming.constants",
74
+ "bundle": "core",
75
+ "category": "naming",
76
+ "priority": "high",
77
+ "stages": ["empty"],
78
+ "rule": "SCREAMING_SNAKE.ts for constants files",
79
+ "shortRule": "SCREAMING_SNAKE for constants",
80
+ "example": "API_ENDPOINTS.ts",
81
+ "antipattern": "apiEndpoints.ts",
82
+ "showInClaude": false,
83
+ "violations": 0,
84
+ "threshold": 3
85
+ },
86
+ "file.naming.types": {
87
+ "id": "file.naming.types",
88
+ "bundle": "typescript",
89
+ "category": "naming",
90
+ "priority": "high",
91
+ "stages": ["empty"],
92
+ "rule": "PascalCase.types.ts for type definitions",
93
+ "shortRule": "PascalCase.types.ts",
94
+ "example": "User.types.ts",
95
+ "antipattern": "user-types.ts",
96
+ "showInClaude": false,
97
+ "violations": 0,
98
+ "threshold": 3
99
+ },
100
+ "file.naming.tests": {
101
+ "id": "file.naming.tests",
102
+ "bundle": "testing",
103
+ "category": "naming",
104
+ "priority": "high",
105
+ "stages": ["growing"],
106
+ "rule": "same-as-source.test.ts for test files",
107
+ "shortRule": "*.test.ts for tests",
108
+ "example": "UserProfile.test.tsx",
109
+ "antipattern": "test-user-profile.tsx",
110
+ "showInClaude": false,
111
+ "violations": 0,
112
+ "threshold": 3
113
+ },
114
+ "file.naming.styles": {
115
+ "id": "file.naming.styles",
116
+ "bundle": "styling",
117
+ "category": "naming",
118
+ "priority": "medium",
119
+ "stages": ["starting"],
120
+ "rule": "same-as-component.css for style files",
121
+ "shortRule": "Component.module.css",
122
+ "example": "UserProfile.module.css",
123
+ "antipattern": "styles.css",
124
+ "showInClaude": false,
125
+ "violations": 0,
126
+ "threshold": 5
127
+ },
128
+ "database.schema.naming.tables": {
129
+ "id": "database.schema.naming.tables",
130
+ "bundle": "database",
131
+ "category": "database",
132
+ "priority": "critical",
133
+ "stages": ["starting"],
134
+ "rule": "snake_case_plural for table names",
135
+ "shortRule": "snake_case_plural tables",
136
+ "example": "users, order_items",
137
+ "antipattern": "Users, OrderItems, user",
138
+ "showInClaude": false,
139
+ "violations": 0,
140
+ "threshold": 2
141
+ },
142
+ "database.schema.naming.columns": {
143
+ "id": "database.schema.naming.columns",
144
+ "bundle": "database",
145
+ "category": "database",
146
+ "priority": "critical",
147
+ "stages": ["starting"],
148
+ "rule": "snake_case for column names",
149
+ "shortRule": "snake_case columns",
150
+ "example": "created_at, user_id",
151
+ "antipattern": "createdAt, userId",
152
+ "showInClaude": false,
153
+ "violations": 0,
154
+ "threshold": 2
155
+ },
156
+ "database.schema.naming.indexes": {
157
+ "id": "database.schema.naming.indexes",
158
+ "bundle": "database",
159
+ "category": "database",
160
+ "priority": "high",
161
+ "stages": ["growing"],
162
+ "rule": "idx_table_columns for indexes",
163
+ "shortRule": "idx_ prefix for indexes",
164
+ "example": "idx_users_email",
165
+ "antipattern": "users_email_index",
166
+ "showInClaude": false,
167
+ "violations": 0,
168
+ "threshold": 3
169
+ },
170
+ "database.schema.naming.foreign_keys": {
171
+ "id": "database.schema.naming.foreign_keys",
172
+ "bundle": "database",
173
+ "category": "database",
174
+ "priority": "high",
175
+ "stages": ["growing"],
176
+ "rule": "fk_table_column for foreign keys",
177
+ "shortRule": "fk_ prefix for foreign keys",
178
+ "example": "fk_orders_user_id",
179
+ "antipattern": "orders_user_fk",
180
+ "showInClaude": false,
181
+ "violations": 0,
182
+ "threshold": 3
183
+ },
184
+ "database.schema.required_columns": {
185
+ "id": "database.schema.required_columns",
186
+ "bundle": "database",
187
+ "category": "database",
188
+ "priority": "critical",
189
+ "stages": ["starting"],
190
+ "rule": "id, created_at, updated_at required on all tables",
191
+ "shortRule": "Required columns on all tables",
192
+ "example": "id UUID, created_at timestamp, updated_at timestamp",
193
+ "antipattern": "Missing timestamps",
194
+ "showInClaude": false,
195
+ "violations": 0,
196
+ "threshold": 1
197
+ },
198
+ "database.schema.soft_deletes": {
199
+ "id": "database.schema.soft_deletes",
200
+ "bundle": "database",
201
+ "category": "database",
202
+ "priority": "high",
203
+ "stages": ["growing"],
204
+ "rule": "Use deleted_at instead of DELETE",
205
+ "shortRule": "Soft deletes only",
206
+ "example": "deleted_at timestamp",
207
+ "antipattern": "DELETE FROM users",
208
+ "showInClaude": false,
209
+ "violations": 0,
210
+ "threshold": 2
211
+ },
212
+ "database.schema.json_columns": {
213
+ "id": "database.schema.json_columns",
214
+ "bundle": "database",
215
+ "category": "database",
216
+ "priority": "medium",
217
+ "stages": ["growing"],
218
+ "rule": "Use JSONB for PostgreSQL, JSON for MySQL",
219
+ "shortRule": "JSONB for Postgres",
220
+ "example": "metadata JSONB",
221
+ "antipattern": "metadata TEXT",
222
+ "showInClaude": false,
223
+ "violations": 0,
224
+ "threshold": 3
225
+ },
226
+ "api.response.success_format": {
227
+ "id": "api.response.success_format",
228
+ "bundle": "api",
229
+ "category": "api",
230
+ "priority": "critical",
231
+ "stages": ["starting"],
232
+ "rule": "Consistent success response envelope",
233
+ "shortRule": "Success envelope format",
234
+ "example": "{success: true, data: {}, meta: {timestamp, version}}",
235
+ "antipattern": "Raw data without envelope",
236
+ "details": {
237
+ "structure": {
238
+ "success": true,
239
+ "data": "actual data",
240
+ "meta": {
241
+ "timestamp": "ISO 8601",
242
+ "version": "1.0",
243
+ "requestId": "UUID"
244
+ }
245
+ }
246
+ },
247
+ "showInClaude": false,
248
+ "violations": 0,
249
+ "threshold": 2
250
+ },
251
+ "api.response.error_format": {
252
+ "id": "api.response.error_format",
253
+ "bundle": "api",
254
+ "category": "api",
255
+ "priority": "critical",
256
+ "stages": ["starting"],
257
+ "rule": "Consistent error response format",
258
+ "shortRule": "Error envelope format",
259
+ "example": "{success: false, error: {code, message, details, traceId}}",
260
+ "antipattern": "Raw error string",
261
+ "details": {
262
+ "structure": {
263
+ "success": false,
264
+ "error": {
265
+ "code": "VALIDATION_ERROR",
266
+ "message": "Human readable",
267
+ "details": {},
268
+ "traceId": "UUID"
269
+ }
270
+ }
271
+ },
272
+ "showInClaude": false,
273
+ "violations": 0,
274
+ "threshold": 2
275
+ },
276
+ "api.response.pagination": {
277
+ "id": "api.response.pagination",
278
+ "bundle": "api",
279
+ "category": "api",
280
+ "priority": "high",
281
+ "stages": ["growing"],
282
+ "rule": "Standard pagination format",
283
+ "shortRule": "Pagination format",
284
+ "example": "{data: [], pagination: {page, limit, total, hasMore}}",
285
+ "antipattern": "Inconsistent pagination",
286
+ "showInClaude": false,
287
+ "violations": 0,
288
+ "threshold": 3
289
+ },
290
+ "frontend.data.id_format": {
291
+ "id": "frontend.data.id_format",
292
+ "bundle": "core",
293
+ "category": "data",
294
+ "priority": "critical",
295
+ "stages": ["empty"],
296
+ "rule": "Use string UUIDs for IDs, never numbers",
297
+ "shortRule": "UUID strings for IDs",
298
+ "example": "'550e8400-e29b-41d4-a716-446655440000'",
299
+ "antipattern": "123 (number ID)",
300
+ "showInClaude": true,
301
+ "violations": 0,
302
+ "threshold": 1
303
+ },
304
+ "frontend.data.date_format": {
305
+ "id": "frontend.data.date_format",
306
+ "bundle": "core",
307
+ "category": "data",
308
+ "priority": "critical",
309
+ "stages": ["empty"],
310
+ "rule": "ISO 8601 strings for dates",
311
+ "shortRule": "ISO 8601 date strings",
312
+ "example": "'2024-01-01T00:00:00Z'",
313
+ "antipattern": "Date objects in state",
314
+ "showInClaude": false,
315
+ "violations": 0,
316
+ "threshold": 2
317
+ },
318
+ "frontend.data.money_format": {
319
+ "id": "frontend.data.money_format",
320
+ "bundle": "core",
321
+ "category": "data",
322
+ "priority": "critical",
323
+ "stages": ["starting"],
324
+ "rule": "Store money as cents (integer)",
325
+ "shortRule": "Money as cents",
326
+ "example": "1999 for $19.99",
327
+ "antipattern": "19.99 as float",
328
+ "showInClaude": true,
329
+ "violations": 0,
330
+ "threshold": 1
331
+ },
332
+ "frontend.data.phone_format": {
333
+ "id": "frontend.data.phone_format",
334
+ "bundle": "core",
335
+ "category": "data",
336
+ "priority": "high",
337
+ "stages": ["starting"],
338
+ "rule": "E.164 format for phone numbers",
339
+ "shortRule": "E.164 phone format",
340
+ "example": "+14155552671",
341
+ "antipattern": "(415) 555-2671",
342
+ "showInClaude": false,
343
+ "violations": 0,
344
+ "threshold": 3
345
+ },
346
+ "frontend.data.empty_states": {
347
+ "id": "frontend.data.empty_states",
348
+ "bundle": "core",
349
+ "category": "data",
350
+ "priority": "high",
351
+ "stages": ["empty"],
352
+ "rule": "Consistent empty state values",
353
+ "shortRule": "Empty state patterns",
354
+ "example": "lists: [], objects: null, strings: '', numbers: 0",
355
+ "antipattern": "lists: null, objects: {}",
356
+ "showInClaude": false,
357
+ "violations": 0,
358
+ "threshold": 3
359
+ },
360
+ "component.structure.order": {
361
+ "id": "component.structure.order",
362
+ "bundle": "react",
363
+ "category": "structure",
364
+ "priority": "critical",
365
+ "stages": ["empty"],
366
+ "rule": "Imports → Types → Constants → Component → Export",
367
+ "shortRule": "Standard component order",
368
+ "example": "Props at top, hooks next, handlers, then JSX",
369
+ "antipattern": "Mixed ordering, hooks after JSX",
370
+ "showInClaude": false,
371
+ "violations": 0,
372
+ "threshold": 3
373
+ },
374
+ "component.exports.named_only": {
375
+ "id": "component.exports.named_only",
376
+ "bundle": "react",
377
+ "category": "imports",
378
+ "priority": "high",
379
+ "stages": ["starting"],
380
+ "rule": "Use named exports only, no default exports",
381
+ "shortRule": "Named exports only",
382
+ "example": "export function UserProfile",
383
+ "antipattern": "export default UserProfile",
384
+ "detector": "export default",
385
+ "showInClaude": false,
386
+ "violations": 0,
387
+ "threshold": 5
388
+ },
389
+ "state.local_state": {
390
+ "id": "state.local_state",
391
+ "bundle": "react",
392
+ "category": "state",
393
+ "priority": "critical",
394
+ "stages": ["empty"],
395
+ "rule": "useState for component-specific UI state",
396
+ "shortRule": "useState for local state",
397
+ "example": "const [isOpen, setIsOpen] = useState(false)",
398
+ "antipattern": "Global state for local UI",
399
+ "showInClaude": false,
400
+ "violations": 0,
401
+ "threshold": 3
402
+ },
403
+ "state.shared_state": {
404
+ "id": "state.shared_state",
405
+ "bundle": "react",
406
+ "category": "state",
407
+ "priority": "critical",
408
+ "stages": ["starting"],
409
+ "rule": "Context for feature-wide state (2+ components)",
410
+ "shortRule": "Context for shared state",
411
+ "example": "const ThemeContext = createContext()",
412
+ "antipattern": "Props drilling through 3+ levels",
413
+ "showInClaude": false,
414
+ "violations": 0,
415
+ "threshold": 2
416
+ },
417
+ "state.global_state": {
418
+ "id": "state.global_state",
419
+ "bundle": "state",
420
+ "category": "state",
421
+ "priority": "high",
422
+ "stages": ["growing"],
423
+ "rule": "Zustand for app-wide state",
424
+ "shortRule": "Zustand for global state",
425
+ "example": "const useStore = create((set) => ({...}))",
426
+ "antipattern": "Context for everything",
427
+ "showInClaude": false,
428
+ "violations": 0,
429
+ "threshold": 3
430
+ },
431
+ "state.server_state": {
432
+ "id": "state.server_state",
433
+ "bundle": "api",
434
+ "category": "state",
435
+ "priority": "critical",
436
+ "stages": ["starting"],
437
+ "rule": "TanStack Query for API data",
438
+ "shortRule": "TanStack Query for server state",
439
+ "example": "useQuery(['users'], fetchUsers)",
440
+ "antipattern": "useState for API data",
441
+ "showInClaude": true,
442
+ "violations": 0,
443
+ "threshold": 1
444
+ },
445
+ "state.no_server_in_usestate": {
446
+ "id": "state.no_server_in_usestate",
447
+ "bundle": "react",
448
+ "category": "state",
449
+ "priority": "critical",
450
+ "stages": ["empty"],
451
+ "rule": "Never put server data in useState",
452
+ "shortRule": "No server data in useState",
453
+ "example": "const {data} = useQuery()",
454
+ "antipattern": "const [users, setUsers] = useState(fetchUsers())",
455
+ "detector": "useState.*fetch|axios|api",
456
+ "showInClaude": true,
457
+ "violations": 0,
458
+ "threshold": 1
459
+ },
460
+ "state.form_local": {
461
+ "id": "state.form_local",
462
+ "bundle": "forms",
463
+ "category": "state",
464
+ "priority": "high",
465
+ "stages": ["starting"],
466
+ "rule": "Form state stays local unless explicitly shared",
467
+ "shortRule": "Form state local by default",
468
+ "example": "const [formData, setFormData] = useState()",
469
+ "antipattern": "Global form state",
470
+ "showInClaude": false,
471
+ "violations": 0,
472
+ "threshold": 3
473
+ },
474
+ "state.optimistic_updates": {
475
+ "id": "state.optimistic_updates",
476
+ "bundle": "api",
477
+ "category": "state",
478
+ "priority": "medium",
479
+ "stages": ["growing"],
480
+ "rule": "Use optimistic updates for better UX",
481
+ "shortRule": "Optimistic updates",
482
+ "example": "Update UI immediately, rollback on error",
483
+ "antipattern": "Wait for server response",
484
+ "showInClaude": false,
485
+ "violations": 0,
486
+ "threshold": 5
487
+ },
488
+ "state.derive_dont_sync": {
489
+ "id": "state.derive_dont_sync",
490
+ "bundle": "react",
491
+ "category": "state",
492
+ "priority": "high",
493
+ "stages": ["starting"],
494
+ "rule": "Derive state when possible, don't sync",
495
+ "shortRule": "Derive, don't sync",
496
+ "example": "const isValid = formData.email && formData.password",
497
+ "antipattern": "useEffect to sync isValid state",
498
+ "showInClaude": false,
499
+ "violations": 0,
500
+ "threshold": 3
501
+ },
502
+ "naming.boolean_prefixes": {
503
+ "id": "naming.boolean_prefixes",
504
+ "bundle": "core",
505
+ "category": "naming",
506
+ "priority": "high",
507
+ "stages": ["empty"],
508
+ "rule": "is/has/should prefixes for booleans",
509
+ "shortRule": "Boolean prefixes",
510
+ "example": "isLoading, hasError, shouldUpdate",
511
+ "antipattern": "loading, error, update",
512
+ "showInClaude": false,
513
+ "violations": 0,
514
+ "threshold": 3
515
+ },
516
+ "naming.handler_prefixes": {
517
+ "id": "naming.handler_prefixes",
518
+ "bundle": "react",
519
+ "category": "naming",
520
+ "priority": "high",
521
+ "stages": ["empty"],
522
+ "rule": "handle prefix for event handlers",
523
+ "shortRule": "handle prefix",
524
+ "example": "handleSubmit, handleClick",
525
+ "antipattern": "onSubmit, submitForm",
526
+ "showInClaude": false,
527
+ "violations": 0,
528
+ "threshold": 3
529
+ },
530
+ "naming.callback_prefixes": {
531
+ "id": "naming.callback_prefixes",
532
+ "bundle": "react",
533
+ "category": "naming",
534
+ "priority": "high",
535
+ "stages": ["empty"],
536
+ "rule": "on prefix for callback props",
537
+ "shortRule": "on prefix for callbacks",
538
+ "example": "onSave, onClick, onComplete",
539
+ "antipattern": "save, click, complete",
540
+ "showInClaude": false,
541
+ "violations": 0,
542
+ "threshold": 3
543
+ },
544
+ "hooks.structure.data": {
545
+ "id": "hooks.structure.data",
546
+ "bundle": "react",
547
+ "category": "hooks",
548
+ "priority": "high",
549
+ "stages": ["starting"],
550
+ "rule": "Data hooks return {data, error, isLoading}",
551
+ "shortRule": "Consistent hook returns",
552
+ "example": "useUser returns {data, error, isLoading}",
553
+ "antipattern": "Just returning data",
554
+ "showInClaude": false,
555
+ "violations": 0,
556
+ "threshold": 3
557
+ },
558
+ "hooks.structure.actions": {
559
+ "id": "hooks.structure.actions",
560
+ "bundle": "react",
561
+ "category": "hooks",
562
+ "priority": "high",
563
+ "stages": ["starting"],
564
+ "rule": "Action hooks return {mutate, isLoading, error}",
565
+ "shortRule": "Action hook pattern",
566
+ "example": "useSaveUser returns {mutate, isLoading, error}",
567
+ "antipattern": "Just returning function",
568
+ "showInClaude": false,
569
+ "violations": 0,
570
+ "threshold": 3
571
+ },
572
+ "hooks.cleanup": {
573
+ "id": "hooks.cleanup",
574
+ "bundle": "react",
575
+ "category": "hooks",
576
+ "priority": "critical",
577
+ "stages": ["starting"],
578
+ "rule": "Clean up subscriptions/timers in hooks",
579
+ "shortRule": "Hook cleanup required",
580
+ "example": "return () => clearInterval(timer)",
581
+ "antipattern": "No cleanup function",
582
+ "showInClaude": false,
583
+ "violations": 0,
584
+ "threshold": 2
585
+ },
586
+ "hooks.memoize": {
587
+ "id": "hooks.memoize",
588
+ "bundle": "performance",
589
+ "category": "hooks",
590
+ "priority": "medium",
591
+ "stages": ["growing"],
592
+ "rule": "Memoize expensive computations in hooks",
593
+ "shortRule": "Memoize expensive ops",
594
+ "example": "useMemo(() => expensiveCalc(), [deps])",
595
+ "antipattern": "Recalculating every render",
596
+ "showInClaude": false,
597
+ "violations": 0,
598
+ "threshold": 5
599
+ },
600
+ "styling.method": {
601
+ "id": "styling.method",
602
+ "bundle": "styling",
603
+ "category": "styling",
604
+ "priority": "critical",
605
+ "stages": ["empty"],
606
+ "rule": "Tailwind CSS for styling",
607
+ "shortRule": "Use Tailwind CSS",
608
+ "example": "className='flex items-center'",
609
+ "antipattern": "Inline styles or CSS-in-JS",
610
+ "showInClaude": false,
611
+ "violations": 0,
612
+ "threshold": 2
613
+ },
614
+ "styling.mobile_first": {
615
+ "id": "styling.mobile_first",
616
+ "bundle": "styling",
617
+ "category": "styling",
618
+ "priority": "high",
619
+ "stages": ["starting"],
620
+ "rule": "Mobile-first responsive design",
621
+ "shortRule": "Mobile-first design",
622
+ "example": "Default mobile, sm: tablet, lg: desktop",
623
+ "antipattern": "Desktop-first with max-width",
624
+ "showInClaude": false,
625
+ "violations": 0,
626
+ "threshold": 3
627
+ },
628
+ "styling.dark_mode": {
629
+ "id": "styling.dark_mode",
630
+ "bundle": "styling",
631
+ "category": "styling",
632
+ "priority": "high",
633
+ "stages": ["growing"],
634
+ "rule": "Dark mode support from start",
635
+ "shortRule": "Dark mode support",
636
+ "example": "dark:bg-gray-900",
637
+ "antipattern": "Light mode only",
638
+ "showInClaude": false,
639
+ "violations": 0,
640
+ "threshold": 3
641
+ },
642
+ "styling.design_tokens": {
643
+ "id": "styling.design_tokens",
644
+ "bundle": "styling",
645
+ "category": "styling",
646
+ "priority": "high",
647
+ "stages": ["starting"],
648
+ "rule": "Use design tokens for consistency",
649
+ "shortRule": "Use design tokens",
650
+ "example": "text-primary, bg-surface",
651
+ "antipattern": "text-blue-500 everywhere",
652
+ "showInClaude": false,
653
+ "violations": 0,
654
+ "threshold": 3
655
+ },
656
+ "styling.spacing": {
657
+ "id": "styling.spacing",
658
+ "bundle": "styling",
659
+ "category": "styling",
660
+ "priority": "high",
661
+ "stages": ["empty"],
662
+ "rule": "4px base unit for spacing",
663
+ "shortRule": "4px spacing unit",
664
+ "example": "p-1 (4px), p-2 (8px), p-4 (16px)",
665
+ "antipattern": "Random pixel values",
666
+ "showInClaude": false,
667
+ "violations": 0,
668
+ "threshold": 3
669
+ },
670
+ "styling.semantic_colors": {
671
+ "id": "styling.semantic_colors",
672
+ "bundle": "styling",
673
+ "category": "styling",
674
+ "priority": "high",
675
+ "stages": ["starting"],
676
+ "rule": "Semantic color naming",
677
+ "shortRule": "Semantic colors",
678
+ "example": "primary, secondary, danger, success",
679
+ "antipattern": "blue, red, green",
680
+ "showInClaude": false,
681
+ "violations": 0,
682
+ "threshold": 3
683
+ },
684
+ "components.ui_library": {
685
+ "id": "components.ui_library",
686
+ "bundle": "ui",
687
+ "category": "components",
688
+ "priority": "high",
689
+ "stages": ["starting"],
690
+ "rule": "Use Radix UI primitives with shadcn/ui",
691
+ "shortRule": "Radix + shadcn/ui",
692
+ "example": "import { Button } from '@/components/ui/button'",
693
+ "antipattern": "Building from scratch",
694
+ "showInClaude": false,
695
+ "violations": 0,
696
+ "threshold": 2
697
+ },
698
+ "components.icons": {
699
+ "id": "components.icons",
700
+ "bundle": "ui",
701
+ "category": "components",
702
+ "priority": "medium",
703
+ "stages": ["starting"],
704
+ "rule": "Use Lucide React for icons",
705
+ "shortRule": "Lucide React icons",
706
+ "example": "import { Search } from 'lucide-react'",
707
+ "antipattern": "Mixed icon libraries",
708
+ "showInClaude": false,
709
+ "violations": 0,
710
+ "threshold": 5
711
+ },
712
+ "forms.library": {
713
+ "id": "forms.library",
714
+ "bundle": "forms",
715
+ "category": "forms",
716
+ "priority": "critical",
717
+ "stages": ["starting"],
718
+ "rule": "React Hook Form with Zod validation",
719
+ "shortRule": "React Hook Form + Zod",
720
+ "example": "useForm with zodResolver",
721
+ "antipattern": "Manual form state management",
722
+ "showInClaude": false,
723
+ "violations": 0,
724
+ "threshold": 2
725
+ },
726
+ "forms.validation.timing": {
727
+ "id": "forms.validation.timing",
728
+ "bundle": "forms",
729
+ "category": "forms",
730
+ "priority": "high",
731
+ "stages": ["starting"],
732
+ "rule": "Show errors on blur or submit, not onChange",
733
+ "shortRule": "Validate on blur/submit",
734
+ "example": "mode: 'onBlur'",
735
+ "antipattern": "Instant validation on every keystroke",
736
+ "showInClaude": false,
737
+ "violations": 0,
738
+ "threshold": 3
739
+ },
740
+ "forms.required_marker": {
741
+ "id": "forms.required_marker",
742
+ "bundle": "forms",
743
+ "category": "forms",
744
+ "priority": "medium",
745
+ "stages": ["starting"],
746
+ "rule": "* after label for required fields",
747
+ "shortRule": "* for required fields",
748
+ "example": "Email *",
749
+ "antipattern": "(required) or no indicator",
750
+ "showInClaude": false,
751
+ "violations": 0,
752
+ "threshold": 5
753
+ },
754
+ "api.style": {
755
+ "id": "api.style",
756
+ "bundle": "api",
757
+ "category": "api",
758
+ "priority": "critical",
759
+ "stages": ["starting"],
760
+ "rule": "REST API with standard verbs",
761
+ "shortRule": "RESTful API",
762
+ "example": "GET /users, POST /users, PUT /users/:id",
763
+ "antipattern": "RPC-style endpoints",
764
+ "showInClaude": false,
765
+ "violations": 0,
766
+ "threshold": 2
767
+ },
768
+ "api.authentication": {
769
+ "id": "api.authentication",
770
+ "bundle": "auth",
771
+ "category": "security",
772
+ "priority": "critical",
773
+ "stages": ["starting"],
774
+ "rule": "JWT in httpOnly cookie",
775
+ "shortRule": "JWT in httpOnly cookie",
776
+ "example": "Set-Cookie: token=...; HttpOnly; Secure",
777
+ "antipattern": "JWT in localStorage",
778
+ "showInClaude": true,
779
+ "violations": 0,
780
+ "threshold": 1
781
+ },
782
+ "api.authorization": {
783
+ "id": "api.authorization",
784
+ "bundle": "auth",
785
+ "category": "security",
786
+ "priority": "critical",
787
+ "stages": ["growing"],
788
+ "rule": "RBAC with permissions",
789
+ "shortRule": "RBAC permissions",
790
+ "example": "role: 'admin', permissions: ['read', 'write']",
791
+ "antipattern": "Simple role checks only",
792
+ "showInClaude": false,
793
+ "violations": 0,
794
+ "threshold": 2
795
+ },
796
+ "api.rate_limiting": {
797
+ "id": "api.rate_limiting",
798
+ "bundle": "api",
799
+ "category": "security",
800
+ "priority": "high",
801
+ "stages": ["growing"],
802
+ "rule": "100 requests per minute per IP",
803
+ "shortRule": "Rate limiting required",
804
+ "example": "X-RateLimit-Remaining: 95",
805
+ "antipattern": "No rate limiting",
806
+ "showInClaude": false,
807
+ "violations": 0,
808
+ "threshold": 2
809
+ },
810
+ "api.cors": {
811
+ "id": "api.cors",
812
+ "bundle": "api",
813
+ "category": "security",
814
+ "priority": "critical",
815
+ "stages": ["starting"],
816
+ "rule": "Explicit CORS whitelist only",
817
+ "shortRule": "CORS whitelist",
818
+ "example": "Access-Control-Allow-Origin: https://app.example.com",
819
+ "antipattern": "Access-Control-Allow-Origin: *",
820
+ "showInClaude": true,
821
+ "violations": 0,
822
+ "threshold": 1
823
+ },
824
+ "error.frontend.network": {
825
+ "id": "error.frontend.network",
826
+ "bundle": "core",
827
+ "category": "error-handling",
828
+ "priority": "critical",
829
+ "stages": ["starting"],
830
+ "rule": "Show toast for network errors, log to Sentry",
831
+ "shortRule": "Toast + Sentry for errors",
832
+ "example": "toast.error('Network error'); Sentry.captureException()",
833
+ "antipattern": "Silent failures",
834
+ "showInClaude": false,
835
+ "violations": 0,
836
+ "threshold": 2
837
+ },
838
+ "error.frontend.validation": {
839
+ "id": "error.frontend.validation",
840
+ "bundle": "forms",
841
+ "category": "error-handling",
842
+ "priority": "high",
843
+ "stages": ["starting"],
844
+ "rule": "Inline field errors for validation",
845
+ "shortRule": "Inline validation errors",
846
+ "example": "Error message below field",
847
+ "antipattern": "Alert for validation errors",
848
+ "showInClaude": false,
849
+ "violations": 0,
850
+ "threshold": 3
851
+ },
852
+ "error.frontend.auth": {
853
+ "id": "error.frontend.auth",
854
+ "bundle": "auth",
855
+ "category": "error-handling",
856
+ "priority": "critical",
857
+ "stages": ["starting"],
858
+ "rule": "Redirect to login on 401/403",
859
+ "shortRule": "Redirect on auth errors",
860
+ "example": "if (401) router.push('/login')",
861
+ "antipattern": "Show error message for auth failures",
862
+ "showInClaude": false,
863
+ "violations": 0,
864
+ "threshold": 2
865
+ },
866
+ "error.frontend.boundaries": {
867
+ "id": "error.frontend.boundaries",
868
+ "bundle": "react",
869
+ "category": "error-handling",
870
+ "priority": "critical",
871
+ "stages": ["growing"],
872
+ "rule": "Error boundaries for unexpected errors",
873
+ "shortRule": "Use error boundaries",
874
+ "example": "<ErrorBoundary fallback={<ErrorPage />}>",
875
+ "antipattern": "Uncaught errors crash app",
876
+ "showInClaude": false,
877
+ "violations": 0,
878
+ "threshold": 2
879
+ },
880
+ "error.backend.validation": {
881
+ "id": "error.backend.validation",
882
+ "bundle": "api",
883
+ "category": "error-handling",
884
+ "priority": "critical",
885
+ "stages": ["starting"],
886
+ "rule": "Return 400 with field errors",
887
+ "shortRule": "400 for validation",
888
+ "example": "400 {errors: {email: 'Invalid format'}}",
889
+ "antipattern": "500 for validation errors",
890
+ "showInClaude": false,
891
+ "violations": 0,
892
+ "threshold": 2
893
+ },
894
+ "error.backend.auth": {
895
+ "id": "error.backend.auth",
896
+ "bundle": "auth",
897
+ "category": "error-handling",
898
+ "priority": "critical",
899
+ "stages": ["starting"],
900
+ "rule": "401 unauthorized, 403 forbidden",
901
+ "shortRule": "Proper auth status codes",
902
+ "example": "401 for no token, 403 for insufficient permissions",
903
+ "antipattern": "200 with error message",
904
+ "showInClaude": false,
905
+ "violations": 0,
906
+ "threshold": 2
907
+ },
908
+ "error.logging": {
909
+ "id": "error.logging",
910
+ "bundle": "observability",
911
+ "category": "error-handling",
912
+ "priority": "critical",
913
+ "stages": ["growing"],
914
+ "rule": "Always include user ID, trace ID, stack",
915
+ "shortRule": "Structured error logging",
916
+ "example": "{userId, traceId, stack, timestamp}",
917
+ "antipattern": "console.error(message)",
918
+ "showInClaude": false,
919
+ "violations": 0,
920
+ "threshold": 2
921
+ },
922
+ "testing.unit.coverage": {
923
+ "id": "testing.unit.coverage",
924
+ "bundle": "testing",
925
+ "category": "testing",
926
+ "priority": "high",
927
+ "stages": ["mature"],
928
+ "rule": "Unit test coverage > 80%",
929
+ "shortRule": "> 80% coverage",
930
+ "example": "All functions and hooks tested",
931
+ "antipattern": "< 50% coverage",
932
+ "showInClaude": false,
933
+ "violations": 0,
934
+ "threshold": 3
935
+ },
936
+ "testing.integration": {
937
+ "id": "testing.integration",
938
+ "bundle": "testing",
939
+ "category": "testing",
940
+ "priority": "high",
941
+ "stages": ["mature"],
942
+ "rule": "Test all critical API paths",
943
+ "shortRule": "API integration tests",
944
+ "example": "Test auth flow, CRUD operations",
945
+ "antipattern": "Only unit tests",
946
+ "showInClaude": false,
947
+ "violations": 0,
948
+ "threshold": 3
949
+ },
950
+ "testing.e2e": {
951
+ "id": "testing.e2e",
952
+ "bundle": "testing",
953
+ "category": "testing",
954
+ "priority": "medium",
955
+ "stages": ["production"],
956
+ "rule": "E2E tests for critical user journeys",
957
+ "shortRule": "E2E critical paths",
958
+ "example": "Playwright tests for signup/login",
959
+ "antipattern": "No E2E tests",
960
+ "showInClaude": false,
961
+ "violations": 0,
962
+ "threshold": 5
963
+ },
964
+ "testing.naming": {
965
+ "id": "testing.naming",
966
+ "bundle": "testing",
967
+ "category": "testing",
968
+ "priority": "medium",
969
+ "stages": ["growing"],
970
+ "rule": "describe/it pattern with clear descriptions",
971
+ "shortRule": "describe/it pattern",
972
+ "example": "describe('UserAuth', () => { it('should login', () => {})})",
973
+ "antipattern": "test('test1', ...)",
974
+ "showInClaude": false,
975
+ "violations": 0,
976
+ "threshold": 5
977
+ },
978
+ "testing.mocking": {
979
+ "id": "testing.mocking",
980
+ "bundle": "testing",
981
+ "category": "testing",
982
+ "priority": "high",
983
+ "stages": ["growing"],
984
+ "rule": "Mock external services, not internal modules",
985
+ "shortRule": "Mock externals only",
986
+ "example": "Mock API calls, not your own functions",
987
+ "antipattern": "Mocking everything",
988
+ "showInClaude": false,
989
+ "violations": 0,
990
+ "threshold": 3
991
+ },
992
+ "typescript.strict": {
993
+ "id": "typescript.strict",
994
+ "bundle": "typescript",
995
+ "category": "types",
996
+ "priority": "critical",
997
+ "stages": ["starting"],
998
+ "rule": "Strict mode enabled in tsconfig",
999
+ "shortRule": "TypeScript strict mode",
1000
+ "example": "strict: true",
1001
+ "antipattern": "Loose TypeScript",
1002
+ "showInClaude": false,
1003
+ "violations": 0,
1004
+ "threshold": 1
1005
+ },
1006
+ "typescript.no_any": {
1007
+ "id": "typescript.no_any",
1008
+ "bundle": "typescript",
1009
+ "category": "types",
1010
+ "priority": "critical",
1011
+ "stages": ["empty"],
1012
+ "rule": "No 'any' type - use 'unknown'",
1013
+ "shortRule": "No any, use unknown",
1014
+ "example": "unknown",
1015
+ "antipattern": "any",
1016
+ "detector": ":\\s*any|<any>|as any",
1017
+ "showInClaude": true,
1018
+ "violations": 0,
1019
+ "threshold": 1
1020
+ },
1021
+ "typescript.explicit_returns": {
1022
+ "id": "typescript.explicit_returns",
1023
+ "bundle": "typescript",
1024
+ "category": "types",
1025
+ "priority": "high",
1026
+ "stages": ["growing"],
1027
+ "rule": "Explicit return types for exported functions",
1028
+ "shortRule": "Explicit return types",
1029
+ "example": "function getUser(): User",
1030
+ "antipattern": "function getUser() // inferred",
1031
+ "showInClaude": false,
1032
+ "violations": 0,
1033
+ "threshold": 3
1034
+ },
1035
+ "typescript.interface_vs_type": {
1036
+ "id": "typescript.interface_vs_type",
1037
+ "bundle": "typescript",
1038
+ "category": "types",
1039
+ "priority": "medium",
1040
+ "stages": ["starting"],
1041
+ "rule": "Interface for objects, type for unions/primitives",
1042
+ "shortRule": "interface vs type",
1043
+ "example": "interface User {}, type Status = 'active' | 'inactive'",
1044
+ "antipattern": "type User = {}, interface Status",
1045
+ "showInClaude": false,
1046
+ "violations": 0,
1047
+ "threshold": 5
1048
+ },
1049
+ "typescript.no_enums": {
1050
+ "id": "typescript.no_enums",
1051
+ "bundle": "typescript",
1052
+ "category": "types",
1053
+ "priority": "medium",
1054
+ "stages": ["starting"],
1055
+ "rule": "Avoid enums - use const objects",
1056
+ "shortRule": "No enums",
1057
+ "example": "const Status = { Active: 'active' } as const",
1058
+ "antipattern": "enum Status { Active }",
1059
+ "showInClaude": false,
1060
+ "violations": 0,
1061
+ "threshold": 5
1062
+ },
1063
+ "git.branch_strategy": {
1064
+ "id": "git.branch_strategy",
1065
+ "bundle": "git",
1066
+ "category": "git",
1067
+ "priority": "high",
1068
+ "stages": ["starting"],
1069
+ "rule": "feature/*, fix/*, hotfix/* branch naming",
1070
+ "shortRule": "Branch naming",
1071
+ "example": "feature/user-auth, fix/login-bug",
1072
+ "antipattern": "random-branch-name",
1073
+ "showInClaude": false,
1074
+ "violations": 0,
1075
+ "threshold": 3
1076
+ },
1077
+ "git.commit_format": {
1078
+ "id": "git.commit_format",
1079
+ "bundle": "git",
1080
+ "category": "git",
1081
+ "priority": "high",
1082
+ "stages": ["empty"],
1083
+ "rule": "type(scope): description",
1084
+ "shortRule": "Conventional commits",
1085
+ "example": "feat(auth): add password reset",
1086
+ "antipattern": "Fixed stuff",
1087
+ "showInClaude": false,
1088
+ "violations": 0,
1089
+ "threshold": 3
1090
+ },
1091
+ "git.main_branch": {
1092
+ "id": "git.main_branch",
1093
+ "bundle": "git",
1094
+ "category": "git",
1095
+ "priority": "critical",
1096
+ "stages": ["starting"],
1097
+ "rule": "main branch for production-ready code only",
1098
+ "shortRule": "Protected main branch",
1099
+ "example": "All changes via PR",
1100
+ "antipattern": "Direct commits to main",
1101
+ "showInClaude": false,
1102
+ "violations": 0,
1103
+ "threshold": 1
1104
+ },
1105
+ "env.naming": {
1106
+ "id": "env.naming",
1107
+ "bundle": "config",
1108
+ "category": "configuration",
1109
+ "priority": "high",
1110
+ "stages": ["empty"],
1111
+ "rule": "SCREAMING_SNAKE_CASE for env vars",
1112
+ "shortRule": "SCREAMING_SNAKE env vars",
1113
+ "example": "DATABASE_URL, API_KEY",
1114
+ "antipattern": "databaseUrl, api-key",
1115
+ "showInClaude": false,
1116
+ "violations": 0,
1117
+ "threshold": 3
1118
+ },
1119
+ "env.prefixes": {
1120
+ "id": "env.prefixes",
1121
+ "bundle": "config",
1122
+ "category": "configuration",
1123
+ "priority": "high",
1124
+ "stages": ["starting"],
1125
+ "rule": "NEXT_PUBLIC_* or VITE_* for public vars",
1126
+ "shortRule": "Public var prefixes",
1127
+ "example": "NEXT_PUBLIC_API_URL",
1128
+ "antipattern": "API_URL (exposed to client)",
1129
+ "showInClaude": false,
1130
+ "violations": 0,
1131
+ "threshold": 2
1132
+ },
1133
+ "env.required": {
1134
+ "id": "env.required",
1135
+ "bundle": "config",
1136
+ "category": "configuration",
1137
+ "priority": "critical",
1138
+ "stages": ["starting"],
1139
+ "rule": "NODE_ENV, DATABASE_URL, API_URL, JWT_SECRET required",
1140
+ "shortRule": "Required env vars",
1141
+ "example": ".env.example with all required",
1142
+ "antipattern": "Missing critical env vars",
1143
+ "showInClaude": false,
1144
+ "violations": 0,
1145
+ "threshold": 1
1146
+ },
1147
+ "comments.why_not_what": {
1148
+ "id": "comments.why_not_what",
1149
+ "bundle": "core",
1150
+ "category": "documentation",
1151
+ "priority": "medium",
1152
+ "stages": ["growing"],
1153
+ "rule": "Comments explain why, not what",
1154
+ "shortRule": "Why, not what",
1155
+ "example": "// Using cache to reduce API calls",
1156
+ "antipattern": "// Set user to null",
1157
+ "showInClaude": false,
1158
+ "violations": 0,
1159
+ "threshold": 5
1160
+ },
1161
+ "comments.todo_format": {
1162
+ "id": "comments.todo_format",
1163
+ "bundle": "core",
1164
+ "category": "documentation",
1165
+ "priority": "low",
1166
+ "stages": ["growing"],
1167
+ "rule": "TODO: [owner] - description",
1168
+ "shortRule": "TODO format",
1169
+ "example": "// TODO: [john] - Add validation",
1170
+ "antipattern": "// TODO fix this",
1171
+ "showInClaude": false,
1172
+ "violations": 0,
1173
+ "threshold": 10
1174
+ },
1175
+ "imports.order": {
1176
+ "id": "imports.order",
1177
+ "bundle": "core",
1178
+ "category": "imports",
1179
+ "priority": "medium",
1180
+ "stages": ["starting"],
1181
+ "rule": "External → Internal → Relative → Types",
1182
+ "shortRule": "Import order",
1183
+ "example": "React, then @/components, then ./utils, then types",
1184
+ "antipattern": "Random import order",
1185
+ "showInClaude": false,
1186
+ "violations": 0,
1187
+ "threshold": 5
1188
+ },
1189
+ "imports.aliases": {
1190
+ "id": "imports.aliases",
1191
+ "bundle": "core",
1192
+ "category": "imports",
1193
+ "priority": "high",
1194
+ "stages": ["starting"],
1195
+ "rule": "Use path aliases (@/components, @/utils)",
1196
+ "shortRule": "Path aliases",
1197
+ "example": "@/components/Button",
1198
+ "antipattern": "../../../components/Button",
1199
+ "showInClaude": false,
1200
+ "violations": 0,
1201
+ "threshold": 3
1202
+ },
1203
+ "validation.email": {
1204
+ "id": "validation.email",
1205
+ "bundle": "validation",
1206
+ "category": "validation",
1207
+ "priority": "high",
1208
+ "stages": ["starting"],
1209
+ "rule": "RFC 5322 compliant email validation",
1210
+ "shortRule": "RFC 5322 email",
1211
+ "example": "z.string().email()",
1212
+ "antipattern": "Simple regex",
1213
+ "showInClaude": false,
1214
+ "violations": 0,
1215
+ "threshold": 3
1216
+ },
1217
+ "validation.phone": {
1218
+ "id": "validation.phone",
1219
+ "bundle": "validation",
1220
+ "category": "validation",
1221
+ "priority": "high",
1222
+ "stages": ["starting"],
1223
+ "rule": "E.164 format with country code",
1224
+ "shortRule": "E.164 phone validation",
1225
+ "example": "+14155552671",
1226
+ "antipattern": "(415) 555-2671",
1227
+ "showInClaude": false,
1228
+ "violations": 0,
1229
+ "threshold": 3
1230
+ },
1231
+ "validation.sanitization": {
1232
+ "id": "validation.sanitization",
1233
+ "bundle": "security",
1234
+ "category": "validation",
1235
+ "priority": "critical",
1236
+ "stages": ["starting"],
1237
+ "rule": "DOMPurify for user HTML content",
1238
+ "shortRule": "Sanitize HTML",
1239
+ "example": "DOMPurify.sanitize(userContent)",
1240
+ "antipattern": "dangerouslySetInnerHTML with raw input",
1241
+ "showInClaude": true,
1242
+ "violations": 0,
1243
+ "threshold": 1
1244
+ },
1245
+ "accessibility.keyboard": {
1246
+ "id": "accessibility.keyboard",
1247
+ "bundle": "a11y",
1248
+ "category": "accessibility",
1249
+ "priority": "critical",
1250
+ "stages": ["growing"],
1251
+ "rule": "All interactive elements keyboard navigable",
1252
+ "shortRule": "Keyboard navigation",
1253
+ "example": "tabIndex, onKeyDown handlers",
1254
+ "antipattern": "onClick only",
1255
+ "showInClaude": false,
1256
+ "violations": 0,
1257
+ "threshold": 2
1258
+ },
1259
+ "accessibility.labels": {
1260
+ "id": "accessibility.labels",
1261
+ "bundle": "a11y",
1262
+ "category": "accessibility",
1263
+ "priority": "critical",
1264
+ "stages": ["growing"],
1265
+ "rule": "Screen reader labels for all inputs",
1266
+ "shortRule": "Screen reader labels",
1267
+ "example": "aria-label, htmlFor",
1268
+ "antipattern": "Unlabeled inputs",
1269
+ "showInClaude": false,
1270
+ "violations": 0,
1271
+ "threshold": 2
1272
+ },
1273
+ "accessibility.contrast": {
1274
+ "id": "accessibility.contrast",
1275
+ "bundle": "a11y",
1276
+ "category": "accessibility",
1277
+ "priority": "high",
1278
+ "stages": ["growing"],
1279
+ "rule": "WCAG AA color contrast (4.5:1)",
1280
+ "shortRule": "WCAG AA contrast",
1281
+ "example": "Check with axe DevTools",
1282
+ "antipattern": "Low contrast text",
1283
+ "showInClaude": false,
1284
+ "violations": 0,
1285
+ "threshold": 3
1286
+ },
1287
+ "performance.bundle_size": {
1288
+ "id": "performance.bundle_size",
1289
+ "bundle": "performance",
1290
+ "category": "performance",
1291
+ "priority": "high",
1292
+ "stages": ["mature"],
1293
+ "rule": "< 200KB gzipped initial bundle",
1294
+ "shortRule": "< 200KB initial bundle",
1295
+ "example": "Code splitting, tree shaking",
1296
+ "antipattern": "1MB+ initial load",
1297
+ "showInClaude": false,
1298
+ "violations": 0,
1299
+ "threshold": 3
1300
+ },
1301
+ "performance.code_splitting": {
1302
+ "id": "performance.code_splitting",
1303
+ "bundle": "performance",
1304
+ "category": "performance",
1305
+ "priority": "high",
1306
+ "stages": ["mature"],
1307
+ "rule": "Route-based code splitting",
1308
+ "shortRule": "Route code splitting",
1309
+ "example": "lazy(() => import('./Page'))",
1310
+ "antipattern": "All code in one bundle",
1311
+ "showInClaude": false,
1312
+ "violations": 0,
1313
+ "threshold": 3
1314
+ },
1315
+ "performance.images": {
1316
+ "id": "performance.images",
1317
+ "bundle": "performance",
1318
+ "category": "performance",
1319
+ "priority": "high",
1320
+ "stages": ["growing"],
1321
+ "rule": "WebP with fallback, lazy loading",
1322
+ "shortRule": "Optimized images",
1323
+ "example": "next/image, loading='lazy'",
1324
+ "antipattern": "Unoptimized PNGs",
1325
+ "showInClaude": false,
1326
+ "violations": 0,
1327
+ "threshold": 3
1328
+ },
1329
+ "security.no_secrets": {
1330
+ "id": "security.no_secrets",
1331
+ "bundle": "security",
1332
+ "category": "security",
1333
+ "priority": "critical",
1334
+ "stages": ["empty"],
1335
+ "rule": "Never commit secrets or API keys",
1336
+ "shortRule": "No secrets in code",
1337
+ "example": "process.env.API_KEY",
1338
+ "antipattern": "const apiKey = 'sk-abc123'",
1339
+ "detector": "(api[_-]?key|secret|password|token)\\s*=\\s*[\"']",
1340
+ "showInClaude": true,
1341
+ "violations": 0,
1342
+ "threshold": 0
1343
+ },
1344
+ "security.parameterized_queries": {
1345
+ "id": "security.parameterized_queries",
1346
+ "bundle": "database",
1347
+ "category": "security",
1348
+ "priority": "critical",
1349
+ "stages": ["starting"],
1350
+ "rule": "Always use parameterized queries",
1351
+ "shortRule": "Parameterized queries",
1352
+ "example": "query('SELECT * FROM users WHERE id = ?', [id])",
1353
+ "antipattern": "query(`SELECT * FROM users WHERE id = ${id}`)",
1354
+ "showInClaude": true,
1355
+ "violations": 0,
1356
+ "threshold": 0
1357
+ },
1358
+ "security.password_hashing": {
1359
+ "id": "security.password_hashing",
1360
+ "bundle": "auth",
1361
+ "category": "security",
1362
+ "priority": "critical",
1363
+ "stages": ["starting"],
1364
+ "rule": "bcrypt with 10+ rounds or Argon2",
1365
+ "shortRule": "bcrypt/Argon2 passwords",
1366
+ "example": "bcrypt.hash(password, 10)",
1367
+ "antipattern": "MD5, SHA1, plain text",
1368
+ "showInClaude": true,
1369
+ "violations": 0,
1370
+ "threshold": 0
1371
+ },
1372
+ "monitoring.error_tracking": {
1373
+ "id": "monitoring.error_tracking",
1374
+ "bundle": "observability",
1375
+ "category": "monitoring",
1376
+ "priority": "high",
1377
+ "stages": ["production"],
1378
+ "rule": "Sentry or similar for error tracking",
1379
+ "shortRule": "Error tracking service",
1380
+ "example": "Sentry.captureException()",
1381
+ "antipattern": "No error tracking",
1382
+ "showInClaude": false,
1383
+ "violations": 0,
1384
+ "threshold": 2
1385
+ },
1386
+ "monitoring.performance": {
1387
+ "id": "monitoring.performance",
1388
+ "bundle": "observability",
1389
+ "category": "monitoring",
1390
+ "priority": "medium",
1391
+ "stages": ["production"],
1392
+ "rule": "APM for performance monitoring",
1393
+ "shortRule": "APM monitoring",
1394
+ "example": "DataDog, New Relic",
1395
+ "antipattern": "No performance monitoring",
1396
+ "showInClaude": false,
1397
+ "violations": 0,
1398
+ "threshold": 5
1399
+ },
1400
+ "deployment.environments": {
1401
+ "id": "deployment.environments",
1402
+ "bundle": "deployment",
1403
+ "category": "deployment",
1404
+ "priority": "high",
1405
+ "stages": ["mature"],
1406
+ "rule": "dev, staging, production environments",
1407
+ "shortRule": "Multiple environments",
1408
+ "example": "Separate configs per environment",
1409
+ "antipattern": "Direct to production",
1410
+ "showInClaude": false,
1411
+ "violations": 0,
1412
+ "threshold": 2
1413
+ },
1414
+ "deployment.rollback": {
1415
+ "id": "deployment.rollback",
1416
+ "bundle": "deployment",
1417
+ "category": "deployment",
1418
+ "priority": "critical",
1419
+ "stages": ["production"],
1420
+ "rule": "Keep 3 previous versions for rollback",
1421
+ "shortRule": "Rollback capability",
1422
+ "example": "Blue-green deployment",
1423
+ "antipattern": "No rollback plan",
1424
+ "showInClaude": false,
1425
+ "violations": 0,
1426
+ "threshold": 1
1427
+ },
1428
+ "documentation.readme": {
1429
+ "id": "documentation.readme",
1430
+ "bundle": "docs",
1431
+ "category": "documentation",
1432
+ "priority": "high",
1433
+ "stages": ["growing"],
1434
+ "rule": "README with setup, tech stack, common tasks",
1435
+ "shortRule": "Complete README",
1436
+ "example": "Quick start in < 5 steps",
1437
+ "antipattern": "No documentation",
1438
+ "showInClaude": false,
1439
+ "violations": 0,
1440
+ "threshold": 2
1441
+ },
1442
+ "documentation.api": {
1443
+ "id": "documentation.api",
1444
+ "bundle": "api",
1445
+ "category": "documentation",
1446
+ "priority": "high",
1447
+ "stages": ["mature"],
1448
+ "rule": "OpenAPI/Swagger documentation",
1449
+ "shortRule": "API documentation",
1450
+ "example": "Swagger UI at /docs",
1451
+ "antipattern": "Undocumented APIs",
1452
+ "showInClaude": false,
1453
+ "violations": 0,
1454
+ "threshold": 3
1455
+ },
1456
+ "documentation.components": {
1457
+ "id": "documentation.components",
1458
+ "bundle": "ui",
1459
+ "category": "documentation",
1460
+ "priority": "medium",
1461
+ "stages": ["mature"],
1462
+ "rule": "Storybook for component documentation",
1463
+ "shortRule": "Component docs",
1464
+ "example": "Stories for all components",
1465
+ "antipattern": "No component documentation",
1466
+ "showInClaude": false,
1467
+ "violations": 0,
1468
+ "threshold": 5
1469
+ },
1470
+ "business_logic.service_layer": {
1471
+ "id": "business_logic.service_layer",
1472
+ "bundle": "architecture",
1473
+ "category": "architecture",
1474
+ "priority": "high",
1475
+ "stages": ["growing"],
1476
+ "rule": "Thin controllers, rich services",
1477
+ "shortRule": "Service layer pattern",
1478
+ "example": "UserService.createUser()",
1479
+ "antipattern": "Business logic in controllers",
1480
+ "showInClaude": false,
1481
+ "violations": 0,
1482
+ "threshold": 3
1483
+ },
1484
+ "business_logic.dependency_injection": {
1485
+ "id": "business_logic.dependency_injection",
1486
+ "bundle": "architecture",
1487
+ "category": "architecture",
1488
+ "priority": "medium",
1489
+ "stages": ["mature"],
1490
+ "rule": "Inject dependencies, don't import directly",
1491
+ "shortRule": "Dependency injection",
1492
+ "example": "constructor(userService: UserService)",
1493
+ "antipattern": "import userService from './userService'",
1494
+ "showInClaude": false,
1495
+ "violations": 0,
1496
+ "threshold": 5
1497
+ },
1498
+ "caching.client": {
1499
+ "id": "caching.client",
1500
+ "bundle": "performance",
1501
+ "category": "caching",
1502
+ "priority": "high",
1503
+ "stages": ["growing"],
1504
+ "rule": "5 minute stale time, 10 minute cache time",
1505
+ "shortRule": "Client caching strategy",
1506
+ "example": "staleTime: 300000",
1507
+ "antipattern": "No caching or infinite cache",
1508
+ "showInClaude": false,
1509
+ "violations": 0,
1510
+ "threshold": 3
1511
+ },
1512
+ "caching.redis": {
1513
+ "id": "caching.redis",
1514
+ "bundle": "performance",
1515
+ "category": "caching",
1516
+ "priority": "high",
1517
+ "stages": ["mature"],
1518
+ "rule": "Redis for sessions and API responses",
1519
+ "shortRule": "Redis caching",
1520
+ "example": "15 min session TTL, 5 min API cache",
1521
+ "antipattern": "No server-side caching",
1522
+ "showInClaude": false,
1523
+ "violations": 0,
1524
+ "threshold": 3
1525
+ },
1526
+ "feature_flags.service": {
1527
+ "id": "feature_flags.service",
1528
+ "bundle": "deployment",
1529
+ "category": "deployment",
1530
+ "priority": "medium",
1531
+ "stages": ["mature"],
1532
+ "rule": "LaunchDarkly or similar for feature flags",
1533
+ "shortRule": "Feature flag service",
1534
+ "example": "if (featureFlag('new-feature'))",
1535
+ "antipattern": "Hard-coded feature switches",
1536
+ "showInClaude": false,
1537
+ "violations": 0,
1538
+ "threshold": 5
1539
+ },
1540
+ "analytics.implementation": {
1541
+ "id": "analytics.implementation",
1542
+ "bundle": "analytics",
1543
+ "category": "analytics",
1544
+ "priority": "medium",
1545
+ "stages": ["growing"],
1546
+ "rule": "Google Analytics or similar",
1547
+ "shortRule": "Analytics tracking",
1548
+ "example": "gtag('event', 'button_clicked')",
1549
+ "antipattern": "No analytics",
1550
+ "showInClaude": false,
1551
+ "violations": 0,
1552
+ "threshold": 5
1553
+ },
1554
+ "analytics.privacy": {
1555
+ "id": "analytics.privacy",
1556
+ "bundle": "analytics",
1557
+ "category": "analytics",
1558
+ "priority": "critical",
1559
+ "stages": ["growing"],
1560
+ "rule": "No PII in analytics, respect DNT",
1561
+ "shortRule": "Analytics privacy",
1562
+ "example": "User ID only, no email/name",
1563
+ "antipattern": "Tracking personal info",
1564
+ "showInClaude": false,
1565
+ "violations": 0,
1566
+ "threshold": 1
1567
+ },
1568
+ "i18n.structure": {
1569
+ "id": "i18n.structure",
1570
+ "bundle": "i18n",
1571
+ "category": "i18n",
1572
+ "priority": "medium",
1573
+ "stages": ["mature"],
1574
+ "rule": "react-i18next with locale files",
1575
+ "shortRule": "i18n setup",
1576
+ "example": "/locales/en/common.json",
1577
+ "antipattern": "Hardcoded strings",
1578
+ "showInClaude": false,
1579
+ "violations": 0,
1580
+ "threshold": 5
1581
+ },
1582
+ "realtime.websockets": {
1583
+ "id": "realtime.websockets",
1584
+ "bundle": "realtime",
1585
+ "category": "realtime",
1586
+ "priority": "high",
1587
+ "stages": ["mature"],
1588
+ "rule": "Socket.io with authentication",
1589
+ "shortRule": "WebSocket setup",
1590
+ "example": "Authenticate on connect",
1591
+ "antipattern": "Unauthenticated sockets",
1592
+ "showInClaude": false,
1593
+ "violations": 0,
1594
+ "threshold": 2
1595
+ },
1596
+ "email.service": {
1597
+ "id": "email.service",
1598
+ "bundle": "email",
1599
+ "category": "email",
1600
+ "priority": "high",
1601
+ "stages": ["growing"],
1602
+ "rule": "SendGrid, SES, or Postmark",
1603
+ "shortRule": "Email service",
1604
+ "example": "Transactional email service",
1605
+ "antipattern": "Direct SMTP",
1606
+ "showInClaude": false,
1607
+ "violations": 0,
1608
+ "threshold": 3
1609
+ },
1610
+ "file_upload.validation": {
1611
+ "id": "file_upload.validation",
1612
+ "bundle": "uploads",
1613
+ "category": "uploads",
1614
+ "priority": "critical",
1615
+ "stages": ["growing"],
1616
+ "rule": "Whitelist file types, max 10MB default",
1617
+ "shortRule": "Upload validation",
1618
+ "example": "accept='.jpg,.png' max='10MB'",
1619
+ "antipattern": "Unrestricted uploads",
1620
+ "showInClaude": false,
1621
+ "violations": 0,
1622
+ "threshold": 1
1623
+ },
1624
+ "file_upload.storage": {
1625
+ "id": "file_upload.storage",
1626
+ "bundle": "uploads",
1627
+ "category": "uploads",
1628
+ "priority": "high",
1629
+ "stages": ["growing"],
1630
+ "rule": "S3/Cloudinary for permanent storage",
1631
+ "shortRule": "Cloud storage",
1632
+ "example": "Direct to S3 presigned URLs",
1633
+ "antipattern": "Local server storage",
1634
+ "showInClaude": false,
1635
+ "violations": 0,
1636
+ "threshold": 2
1637
+ }
1638
+ },
1639
+ "bundles": {
1640
+ "core": {
1641
+ "name": "Core",
1642
+ "description": "Essential standards for any project",
1643
+ "autoInclude": true
1644
+ },
1645
+ "react": {
1646
+ "name": "React",
1647
+ "description": "React-specific patterns and practices",
1648
+ "autoInclude": false,
1649
+ "detection": "dependencies.react"
1650
+ },
1651
+ "typescript": {
1652
+ "name": "TypeScript",
1653
+ "description": "TypeScript type safety",
1654
+ "autoInclude": false,
1655
+ "detection": "tsconfig.json"
1656
+ },
1657
+ "api": {
1658
+ "name": "API",
1659
+ "description": "API design patterns",
1660
+ "autoInclude": false
1661
+ },
1662
+ "database": {
1663
+ "name": "Database",
1664
+ "description": "Database conventions",
1665
+ "autoInclude": false
1666
+ },
1667
+ "forms": {
1668
+ "name": "Forms",
1669
+ "description": "Form handling patterns",
1670
+ "autoInclude": false
1671
+ },
1672
+ "security": {
1673
+ "name": "Security",
1674
+ "description": "Security best practices",
1675
+ "autoInclude": false
1676
+ },
1677
+ "auth": {
1678
+ "name": "Authentication",
1679
+ "description": "Authentication and authorization",
1680
+ "autoInclude": false
1681
+ },
1682
+ "testing": {
1683
+ "name": "Testing",
1684
+ "description": "Testing patterns",
1685
+ "autoInclude": false
1686
+ },
1687
+ "performance": {
1688
+ "name": "Performance",
1689
+ "description": "Performance optimizations",
1690
+ "autoInclude": false
1691
+ },
1692
+ "styling": {
1693
+ "name": "Styling",
1694
+ "description": "CSS and styling approaches",
1695
+ "autoInclude": false
1696
+ },
1697
+ "ui": {
1698
+ "name": "UI Components",
1699
+ "description": "Component library choices",
1700
+ "autoInclude": false
1701
+ },
1702
+ "state": {
1703
+ "name": "State Management",
1704
+ "description": "Advanced state management",
1705
+ "autoInclude": false
1706
+ },
1707
+ "git": {
1708
+ "name": "Git",
1709
+ "description": "Version control practices",
1710
+ "autoInclude": false
1711
+ },
1712
+ "config": {
1713
+ "name": "Configuration",
1714
+ "description": "Environment and config management",
1715
+ "autoInclude": false
1716
+ },
1717
+ "validation": {
1718
+ "name": "Validation",
1719
+ "description": "Data validation patterns",
1720
+ "autoInclude": false
1721
+ },
1722
+ "a11y": {
1723
+ "name": "Accessibility",
1724
+ "description": "WCAG compliance",
1725
+ "autoInclude": false
1726
+ },
1727
+ "observability": {
1728
+ "name": "Observability",
1729
+ "description": "Monitoring and logging",
1730
+ "autoInclude": false
1731
+ },
1732
+ "deployment": {
1733
+ "name": "Deployment",
1734
+ "description": "Deployment strategies",
1735
+ "autoInclude": false
1736
+ },
1737
+ "docs": {
1738
+ "name": "Documentation",
1739
+ "description": "Documentation requirements",
1740
+ "autoInclude": false
1741
+ },
1742
+ "architecture": {
1743
+ "name": "Architecture",
1744
+ "description": "Architectural patterns",
1745
+ "autoInclude": false
1746
+ },
1747
+ "caching": {
1748
+ "name": "Caching",
1749
+ "description": "Caching strategies",
1750
+ "autoInclude": false
1751
+ },
1752
+ "analytics": {
1753
+ "name": "Analytics",
1754
+ "description": "Analytics and tracking",
1755
+ "autoInclude": false
1756
+ },
1757
+ "i18n": {
1758
+ "name": "Internationalization",
1759
+ "description": "Multi-language support",
1760
+ "autoInclude": false
1761
+ },
1762
+ "realtime": {
1763
+ "name": "Realtime",
1764
+ "description": "WebSocket and realtime patterns",
1765
+ "autoInclude": false
1766
+ },
1767
+ "email": {
1768
+ "name": "Email",
1769
+ "description": "Email service patterns",
1770
+ "autoInclude": false
1771
+ },
1772
+ "uploads": {
1773
+ "name": "File Uploads",
1774
+ "description": "File upload handling",
1775
+ "autoInclude": false
1776
+ }
1777
+ }
1778
+ }