@massu/core 0.5.0 → 0.6.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 (119) hide show
  1. package/README.md +40 -0
  2. package/agents/massu-architecture-reviewer.md +104 -0
  3. package/agents/massu-blast-radius-analyzer.md +84 -0
  4. package/agents/massu-competitive-scorer.md +126 -0
  5. package/agents/massu-help-sync.md +73 -0
  6. package/agents/massu-migration-writer.md +94 -0
  7. package/agents/massu-output-scorer.md +87 -0
  8. package/agents/massu-pattern-reviewer.md +84 -0
  9. package/agents/massu-plan-auditor.md +170 -0
  10. package/agents/massu-schema-sync-verifier.md +70 -0
  11. package/agents/massu-security-reviewer.md +98 -0
  12. package/agents/massu-ux-reviewer.md +106 -0
  13. package/commands/_shared-preamble.md +53 -23
  14. package/commands/_shared-references/auto-learning-protocol.md +71 -0
  15. package/commands/_shared-references/blast-radius-protocol.md +76 -0
  16. package/commands/_shared-references/security-pre-screen.md +64 -0
  17. package/commands/_shared-references/test-first-protocol.md +87 -0
  18. package/commands/_shared-references/verification-table.md +55 -0
  19. package/commands/massu-article-review.md +343 -0
  20. package/commands/massu-autoresearch/references/eval-runner.md +84 -0
  21. package/commands/massu-autoresearch/references/safety-rails.md +125 -0
  22. package/commands/massu-autoresearch/references/scoring-protocol.md +151 -0
  23. package/commands/massu-autoresearch.md +258 -0
  24. package/commands/massu-batch.md +44 -12
  25. package/commands/massu-bearings.md +42 -8
  26. package/commands/massu-checkpoint.md +588 -0
  27. package/commands/massu-ci-fix.md +2 -2
  28. package/commands/massu-command-health.md +132 -0
  29. package/commands/massu-command-improve.md +232 -0
  30. package/commands/massu-commit.md +205 -44
  31. package/commands/massu-create-plan.md +239 -57
  32. package/commands/massu-data/references/common-queries.md +79 -0
  33. package/commands/massu-data/references/table-guide.md +50 -0
  34. package/commands/massu-data.md +66 -0
  35. package/commands/massu-dead-code.md +29 -34
  36. package/commands/massu-debug/references/auto-learning.md +61 -0
  37. package/commands/massu-debug/references/codegraph-tracing.md +80 -0
  38. package/commands/massu-debug/references/common-shortcuts.md +98 -0
  39. package/commands/massu-debug/references/investigation-phases.md +294 -0
  40. package/commands/massu-debug/references/report-format.md +107 -0
  41. package/commands/massu-debug.md +105 -386
  42. package/commands/massu-docs.md +1 -1
  43. package/commands/massu-full-audit.md +61 -0
  44. package/commands/massu-gap-enhancement-analyzer.md +276 -16
  45. package/commands/massu-golden-path/references/approval-points.md +216 -0
  46. package/commands/massu-golden-path/references/competitive-mode.md +273 -0
  47. package/commands/massu-golden-path/references/error-handling.md +121 -0
  48. package/commands/massu-golden-path/references/phase-0-requirements.md +53 -0
  49. package/commands/massu-golden-path/references/phase-1-plan-creation.md +168 -0
  50. package/commands/massu-golden-path/references/phase-2-implementation.md +403 -0
  51. package/commands/massu-golden-path/references/phase-2.5-gap-analyzer.md +170 -0
  52. package/commands/massu-golden-path/references/phase-3-simplify.md +40 -0
  53. package/commands/massu-golden-path/references/phase-3.5-security-audit.md +108 -0
  54. package/commands/massu-golden-path/references/phase-4-commit.md +94 -0
  55. package/commands/massu-golden-path/references/phase-5-push.md +116 -0
  56. package/commands/massu-golden-path/references/phase-5.5-production-verify.md +170 -0
  57. package/commands/massu-golden-path/references/phase-6-completion.md +113 -0
  58. package/commands/massu-golden-path/references/qa-evaluator-spec.md +137 -0
  59. package/commands/massu-golden-path/references/sprint-contract-protocol.md +117 -0
  60. package/commands/massu-golden-path/references/vr-visual-calibration.md +73 -0
  61. package/commands/massu-golden-path.md +121 -844
  62. package/commands/massu-guide.md +72 -69
  63. package/commands/massu-hooks.md +27 -12
  64. package/commands/massu-hotfix.md +221 -144
  65. package/commands/massu-incident.md +49 -20
  66. package/commands/massu-infra-audit.md +187 -0
  67. package/commands/massu-learning-audit.md +211 -0
  68. package/commands/massu-loop/references/auto-learning.md +49 -0
  69. package/commands/massu-loop/references/checkpoint-audit.md +40 -0
  70. package/commands/massu-loop/references/guardrails.md +17 -0
  71. package/commands/massu-loop/references/iteration-structure.md +115 -0
  72. package/commands/massu-loop/references/loop-controller.md +188 -0
  73. package/commands/massu-loop/references/plan-extraction.md +78 -0
  74. package/commands/massu-loop/references/vr-plan-spec.md +140 -0
  75. package/commands/massu-loop-playwright.md +9 -9
  76. package/commands/massu-loop.md +115 -670
  77. package/commands/massu-new-pattern.md +423 -0
  78. package/commands/massu-perf.md +422 -0
  79. package/commands/massu-plan-audit.md +1 -1
  80. package/commands/massu-plan.md +389 -122
  81. package/commands/massu-production-verify.md +433 -0
  82. package/commands/massu-push.md +62 -378
  83. package/commands/massu-recap.md +29 -3
  84. package/commands/massu-rollback.md +613 -0
  85. package/commands/massu-scaffold-hook.md +2 -4
  86. package/commands/massu-scaffold-page.md +2 -3
  87. package/commands/massu-scaffold-router.md +1 -2
  88. package/commands/massu-security.md +619 -0
  89. package/commands/massu-simplify.md +115 -85
  90. package/commands/massu-squirrels.md +2 -2
  91. package/commands/massu-tdd.md +38 -22
  92. package/commands/massu-test.md +3 -3
  93. package/commands/massu-type-mismatch-audit.md +469 -0
  94. package/commands/massu-ui-audit.md +587 -0
  95. package/commands/massu-verify-playwright.md +287 -32
  96. package/commands/massu-verify.md +150 -46
  97. package/dist/cli.js +146 -95
  98. package/package.json +6 -2
  99. package/patterns/build-patterns.md +302 -0
  100. package/patterns/component-patterns.md +246 -0
  101. package/patterns/display-patterns.md +185 -0
  102. package/patterns/form-patterns.md +890 -0
  103. package/patterns/integration-testing-checklist.md +445 -0
  104. package/patterns/security-patterns.md +219 -0
  105. package/patterns/testing-patterns.md +569 -0
  106. package/patterns/tool-routing.md +81 -0
  107. package/patterns/ui-patterns.md +371 -0
  108. package/protocols/plan-implementation.md +267 -0
  109. package/protocols/recovery.md +225 -0
  110. package/protocols/verification.md +404 -0
  111. package/reference/command-taxonomy.md +178 -0
  112. package/reference/cr-rules-reference.md +76 -0
  113. package/reference/hook-execution-order.md +148 -0
  114. package/reference/lessons-learned.md +175 -0
  115. package/reference/patterns-quickref.md +208 -0
  116. package/reference/standards.md +135 -0
  117. package/reference/subagents-reference.md +17 -0
  118. package/reference/vr-verification-reference.md +867 -0
  119. package/src/commands/install-commands.ts +149 -53
@@ -0,0 +1,302 @@
1
+ # Build Patterns
2
+
3
+ **Purpose**: Patterns for resolving build issues in Next.js applications with Prisma, native modules, and Edge Runtime.
4
+
5
+ **When to Read**: When encountering build errors, hangs, or warnings. Before adding heavy dependencies.
6
+
7
+ ---
8
+
9
+ ## Client/Server Code Separation
10
+
11
+ ### The Problem
12
+
13
+ PrismaClient gets bundled into browser JavaScript when imported in client components, causing:
14
+ - Build failures
15
+ - Massive bundle sizes
16
+ - Runtime errors
17
+
18
+ ### The Pattern: Domain Split Files
19
+
20
+ ```
21
+ src/lib/services/
22
+ ├── contacts-types.ts ← Types only (shared client + server)
23
+ ├── contacts-service.ts ← Server logic (PrismaClient, DB queries)
24
+ └── contacts-client.ts ← Client-safe utilities (formatting, validation)
25
+ ```
26
+
27
+ **Rule**: Files ending in `-service.ts` contain server code. Client components MUST NOT import them.
28
+
29
+ ```typescript
30
+ // contacts-types.ts — SAFE for client import
31
+ export interface Contact {
32
+ id: string;
33
+ name: string;
34
+ email: string;
35
+ }
36
+
37
+ export type ContactCreateInput = {
38
+ name: string;
39
+ email: string;
40
+ };
41
+
42
+ // contacts-service.ts — SERVER ONLY
43
+ import { db } from '@/lib/db';
44
+
45
+ export async function getContacts(): Promise<Contact[]> {
46
+ return db.contacts.findMany();
47
+ }
48
+ ```
49
+
50
+ ### Detection
51
+
52
+ ```bash
53
+ # Find client components importing server code
54
+ grep -rn "from '@/lib/db'" src/components/ --include="*.tsx"
55
+ # Expected: 0 matches
56
+
57
+ # Find barrel exports that leak server code
58
+ grep -rn "export \* from.*service" src/lib/
59
+ # Check if any client component imports the barrel
60
+ ```
61
+
62
+ ---
63
+
64
+ ## Native Module Externalization
65
+
66
+ ### The Problem
67
+
68
+ Modules like `jsdom`, `canvas`, `sharp`, and `puppeteer` contain native binaries that cannot be bundled by webpack/turbopack. They cause build hangs or failures.
69
+
70
+ ### The Pattern
71
+
72
+ **Step 1: Add to `serverExternalPackages` in `next.config.js`:**
73
+ ```javascript
74
+ /** @type {import('next').NextConfig} */
75
+ const nextConfig = {
76
+ serverExternalPackages: [
77
+ 'jsdom', 'canvas', 'sharp', 'puppeteer', 'puppeteer-core',
78
+ '@sparticuz/chromium', 'pdfkit', 'pdf-parse'
79
+ ],
80
+ };
81
+ ```
82
+
83
+ **Step 2: Add webpack externals as fallback:**
84
+ ```javascript
85
+ webpack: (config, { isServer }) => {
86
+ if (isServer) {
87
+ config.externals = config.externals || [];
88
+ config.externals.push({
89
+ jsdom: 'commonjs jsdom',
90
+ canvas: 'commonjs canvas',
91
+ sharp: 'commonjs sharp',
92
+ });
93
+ }
94
+ return config;
95
+ },
96
+ ```
97
+
98
+ **Step 3: Use dynamic imports:**
99
+ ```typescript
100
+ // WRONG - Static import causes build issues
101
+ import { JSDOM } from 'jsdom';
102
+
103
+ // CORRECT - Dynamic import
104
+ const { JSDOM } = await import('jsdom');
105
+ ```
106
+
107
+ ### Known Problematic Packages
108
+
109
+ | Package | Issue | Solution |
110
+ |---------|-------|---------|
111
+ | `jsdom` | ESM + native deps | Dynamic import + externalize |
112
+ | `canvas` | Native binary | Externalize |
113
+ | `sharp` | Native binary | serverExternalPackages |
114
+ | `puppeteer` | Chromium binary | Externalize + dynamic import |
115
+ | `cheerio` | Heavy dependency tree | Dynamic import |
116
+ | `pdfkit` | Native deps | Externalize |
117
+
118
+ ---
119
+
120
+ ## Edge Runtime Compatibility
121
+
122
+ ### The Rule
123
+
124
+ Files that run in Edge Runtime (middleware, edge functions) CANNOT use Node.js APIs.
125
+
126
+ **Banned in Edge Runtime:**
127
+ - `fs` / `path` / `crypto` (Node.js builtins)
128
+ - `pino` / `winston` (logging libraries with Node.js deps)
129
+ - `PrismaClient` (requires Node.js)
130
+ - Any package that imports Node.js builtins
131
+
132
+ ### Detection
133
+
134
+ ```bash
135
+ # Check middleware for Node.js imports
136
+ grep -rn "require('fs')\|require('path')\|require('crypto')" src/middleware.ts
137
+ # Expected: 0 matches
138
+
139
+ # Check for logging library imports in edge files
140
+ grep -rn "from 'pino'\|from 'winston'" src/middleware.ts
141
+ # Expected: 0 matches
142
+ ```
143
+
144
+ ### Alternative for Edge Runtime
145
+
146
+ ```typescript
147
+ // WRONG - pino in middleware
148
+ import pino from 'pino';
149
+
150
+ // CORRECT - console in middleware (Edge Runtime safe)
151
+ console.log('[middleware]', 'Processing request');
152
+
153
+ // CORRECT - Use Web Crypto API instead of Node crypto
154
+ const hash = await crypto.subtle.digest('SHA-256', data);
155
+ ```
156
+
157
+ ---
158
+
159
+ ## Import Chain Protection
160
+
161
+ ### The Problem
162
+
163
+ Even `import type` triggers webpack/turbopack analysis of the entire module graph. If a type-only import points to a file that imports heavy dependencies, the bundler will try to resolve them.
164
+
165
+ ### The Pattern
166
+
167
+ ```typescript
168
+ // WRONG - Type import still triggers analysis of heavy-deps.ts
169
+ import type { HeavyType } from '@/lib/heavy-deps';
170
+
171
+ // CORRECT - Inline the type definition
172
+ interface HeavyType {
173
+ id: string;
174
+ data: Record<string, unknown>;
175
+ }
176
+ ```
177
+
178
+ ### Detection
179
+
180
+ ```bash
181
+ # Find imports from known heavy modules in client code
182
+ grep -rn "from '@/lib/db'" src/components/ --include="*.tsx"
183
+ grep -rn "from '@/lib/services/.*-service'" src/components/ --include="*.tsx"
184
+ # Expected: 0 matches for both
185
+ ```
186
+
187
+ ---
188
+
189
+ ## Build Warnings
190
+
191
+ ### Zero-Warning Builds
192
+
193
+ All builds MUST produce zero warnings. Common warning sources and fixes:
194
+
195
+ | Warning | Cause | Fix |
196
+ |---------|-------|-----|
197
+ | CSS color deprecation | Hardcoded hex/rgb values | Use CSS variables: `var(--color-name)` |
198
+ | Unused variable | Dead code | Remove or prefix with `_` |
199
+ | Missing key prop | Map without key | Add `key={item.id}` |
200
+ | React hook deps | Missing useEffect dependency | Add to dependency array or wrap in useCallback |
201
+
202
+ ### Semantic Color Classes
203
+
204
+ Use semantic CSS classes instead of hardcoded colors:
205
+
206
+ ```css
207
+ /* WRONG */
208
+ .badge { color: #22c55e; }
209
+
210
+ /* CORRECT */
211
+ .badge-primary { color: var(--color-primary); }
212
+ .badge-success { color: var(--color-success); }
213
+ .badge-warning { color: var(--color-warning); }
214
+ .badge-error { color: var(--color-error); }
215
+ ```
216
+
217
+ ---
218
+
219
+ ## next-intl Setup
220
+
221
+ If using next-intl for internationalization, ALL three pieces are required:
222
+
223
+ 1. **Plugin in `next.config.js`:**
224
+ ```javascript
225
+ const withNextIntl = require('next-intl/plugin')();
226
+ module.exports = withNextIntl(nextConfig);
227
+ ```
228
+
229
+ 2. **`src/i18n/request.ts`:**
230
+ ```typescript
231
+ import { getRequestConfig } from 'next-intl/server';
232
+ export default getRequestConfig(async () => ({
233
+ locale: 'en',
234
+ messages: (await import(`../../messages/en.json`)).default
235
+ }));
236
+ ```
237
+
238
+ 3. **Provider in layout:**
239
+ ```typescript
240
+ import { NextIntlClientProvider } from 'next-intl';
241
+ <NextIntlClientProvider locale="en" messages={messages}>
242
+ {children}
243
+ </NextIntlClientProvider>
244
+ ```
245
+
246
+ Missing any one of these causes build failures.
247
+
248
+ ---
249
+
250
+ ## Suspense Boundaries
251
+
252
+ Pages using `use(params)` or `useSearchParams()` MUST be wrapped in Suspense:
253
+
254
+ ```typescript
255
+ // page.tsx
256
+ import { Suspense } from 'react';
257
+
258
+ export default function Page() {
259
+ return (
260
+ <Suspense fallback={<LoadingState />}>
261
+ <PageContent />
262
+ </Suspense>
263
+ );
264
+ }
265
+ ```
266
+
267
+ Without Suspense, static generation fails with cryptic errors.
268
+
269
+ ---
270
+
271
+ ## React Query v5 Callbacks
272
+
273
+ ```typescript
274
+ // WRONG - onSuccess removed in React Query v5
275
+ api.contacts.list.useQuery(undefined, {
276
+ onSuccess: (data) => setContacts(data), // TypeScript error
277
+ });
278
+
279
+ // CORRECT - Destructure data directly
280
+ const { data: contacts } = api.contacts.list.useQuery();
281
+ ```
282
+
283
+ See `patterns/component-patterns.md` for the full React Query v5 pattern.
284
+
285
+ ---
286
+
287
+ ## Quick Reference
288
+
289
+ | Rule | Pattern | Error if Violated |
290
+ |------|---------|-------------------|
291
+ | JSDOM dynamic import | `await import('jsdom')` | ESM error on Vercel |
292
+ | Cheerio dynamic import | `await import('cheerio')` | Build hang on Vercel |
293
+ | Import type from heavy deps | Inline types instead | Build hang (47+ min) |
294
+ | Client/Server boundary | No `@/lib/db` in client | PrismaClient bundled |
295
+ | next-intl setup | Plugin + request.ts + Provider | Build fails |
296
+ | Suspense boundaries | Wrap `use(params)` pages | Static generation fails |
297
+ | React Query v5 callbacks | Destructure data, no `onSuccess` in useQuery | TypeScript error |
298
+
299
+ ---
300
+
301
+ **Document Status**: ACTIVE
302
+ **Compliance**: Mandatory for all build-related work
@@ -0,0 +1,246 @@
1
+ # Component Patterns
2
+
3
+ **Purpose**: Standard patterns for UI components, forms, search inputs, and common interactive elements.
4
+
5
+ **When to Read**: Before creating or modifying UI components.
6
+
7
+ ---
8
+
9
+ ## Toast Notifications
10
+
11
+ ### Standard Pattern: Sonner
12
+
13
+ ```typescript
14
+ // CORRECT - Use Sonner directly
15
+ import { toast } from 'sonner';
16
+
17
+ // Success
18
+ toast.success('Changes saved successfully');
19
+
20
+ // Error
21
+ toast.error('Failed to save changes');
22
+
23
+ // With description
24
+ toast.success('Contact created', {
25
+ description: 'John Doe has been added to your contacts'
26
+ });
27
+
28
+ // Promise toast (loading → success/error)
29
+ toast.promise(mutation.mutateAsync(data), {
30
+ loading: 'Saving...',
31
+ success: 'Saved successfully',
32
+ error: 'Failed to save'
33
+ });
34
+ ```
35
+
36
+ ### WRONG - Deprecated useToast Hook
37
+
38
+ ```typescript
39
+ // WRONG - Legacy hook pattern, do NOT use
40
+ const { toast } = useToast();
41
+ toast({ title: 'Success', description: '...' });
42
+ ```
43
+
44
+ **Why Sonner**: Single import, consistent API, auto-dismiss, better DX.
45
+
46
+ ---
47
+
48
+ ## Loading State
49
+
50
+ ```typescript
51
+ import { LoadingState } from '@/components/common/LoadingState';
52
+
53
+ // In page or component
54
+ if (isLoading) {
55
+ return <LoadingState />;
56
+ }
57
+
58
+ // With custom message
59
+ if (isLoading) {
60
+ return <LoadingState message="Loading contacts..." />;
61
+ }
62
+ ```
63
+
64
+ **Rule**: ALL loading states MUST use the `LoadingState` component. Never use raw spinners or "Loading..." text.
65
+
66
+ ---
67
+
68
+ ## Empty State
69
+
70
+ ```typescript
71
+ import { EmptyState } from '@/components/common/EmptyState';
72
+
73
+ // Basic
74
+ if (data?.length === 0) {
75
+ return (
76
+ <EmptyState
77
+ title="No contacts found"
78
+ description="Add your first contact to get started"
79
+ action={{
80
+ label: "Add Contact",
81
+ onClick: () => setIsCreating(true)
82
+ }}
83
+ />
84
+ );
85
+ }
86
+ ```
87
+
88
+ **Rule**: ALL empty states MUST use the `EmptyState` component with actionable guidance.
89
+
90
+ ---
91
+
92
+ ## Form Inputs
93
+
94
+ ### Checkbox
95
+
96
+ ```typescript
97
+ import { Checkbox } from '@/components/ui/checkbox';
98
+
99
+ <div className="flex items-center space-x-2">
100
+ <Checkbox
101
+ id="agree"
102
+ checked={agreed}
103
+ onCheckedChange={setAgreed}
104
+ />
105
+ <label htmlFor="agree" className="text-sm">
106
+ I agree to the terms
107
+ </label>
108
+ </div>
109
+ ```
110
+
111
+ ### Select
112
+
113
+ ```typescript
114
+ import {
115
+ Select,
116
+ SelectContent,
117
+ SelectItem,
118
+ SelectTrigger,
119
+ SelectValue,
120
+ } from '@/components/ui/select';
121
+
122
+ // CRITICAL: Never use value="" - causes React crash
123
+ // Use __none__ for "no selection" option
124
+ <Select value={status} onValueChange={setStatus}>
125
+ <SelectTrigger>
126
+ <SelectValue placeholder="Select status" />
127
+ </SelectTrigger>
128
+ <SelectContent>
129
+ <SelectItem value="__none__">All Statuses</SelectItem>
130
+ <SelectItem value="active">Active</SelectItem>
131
+ <SelectItem value="inactive">Inactive</SelectItem>
132
+ </SelectContent>
133
+ </Select>
134
+ ```
135
+
136
+ ### DatePicker
137
+
138
+ ```typescript
139
+ import { DatePicker } from '@/components/ui/date-picker';
140
+
141
+ <DatePicker
142
+ date={selectedDate}
143
+ onSelect={setSelectedDate}
144
+ placeholder="Select date"
145
+ />
146
+ ```
147
+
148
+ ---
149
+
150
+ ## Search Input
151
+
152
+ ```typescript
153
+ // Standard search input with consistent styling
154
+ <Input
155
+ placeholder="Search..."
156
+ value={searchQuery}
157
+ onChange={(e) => setSearchQuery(e.target.value)}
158
+ className="page-search-input"
159
+ />
160
+ ```
161
+
162
+ **Rule**: ALL search inputs MUST use the `page-search-input` class for consistent styling.
163
+
164
+ ---
165
+
166
+ ## Query Keys (React Query / tRPC)
167
+
168
+ ```typescript
169
+ // CORRECT - Double brackets for tRPC query keys
170
+ queryKey: [['contacts', 'list']]
171
+
172
+ // WRONG - Single brackets
173
+ queryKey: ['contacts', 'list'] // Will not match tRPC invalidation
174
+ ```
175
+
176
+ **Why**: tRPC wraps query keys in an additional array. Using single brackets means `queryClient.invalidateQueries()` won't match.
177
+
178
+ ---
179
+
180
+ ## Form Validation (Zod + react-hook-form)
181
+
182
+ ```typescript
183
+ import { useForm } from 'react-hook-form';
184
+ import { zodResolver } from '@hookform/resolvers/zod';
185
+ import { z } from 'zod';
186
+
187
+ const schema = z.object({
188
+ name: z.string().min(1, 'Name is required'),
189
+ email: z.string().email('Invalid email'),
190
+ phone: z.string().optional(),
191
+ });
192
+
193
+ type FormData = z.infer<typeof schema>;
194
+
195
+ const {
196
+ register,
197
+ handleSubmit,
198
+ formState: { errors },
199
+ } = useForm<FormData>({
200
+ resolver: zodResolver(schema),
201
+ });
202
+ ```
203
+
204
+ **Rule**: ALL forms MUST use react-hook-form with Zod validation. See `patterns/form-patterns.md` for complete guide.
205
+
206
+ ---
207
+
208
+ ## ESLint Integration
209
+
210
+ Custom ESLint rules enforce component patterns:
211
+
212
+ | Rule | What It Catches |
213
+ |------|----------------|
214
+ | `no-deprecated-toast` | useToast() hook usage |
215
+ | `no-raw-loading` | Inline loading spinners instead of LoadingState |
216
+ | `no-empty-select-value` | `value=""` on Select.Item |
217
+ | `no-single-bracket-querykey` | Single bracket query keys |
218
+
219
+ ### Detection Commands
220
+
221
+ ```bash
222
+ # Check for deprecated toast usage
223
+ grep -rn "useToast" src/ --include="*.tsx" --include="*.ts"
224
+ # Expected: 0 matches (all should use sonner)
225
+
226
+ # Check for empty select values
227
+ grep -rn 'value=""' src/ --include="*.tsx"
228
+ # Expected: 0 matches
229
+
230
+ # Check for single bracket query keys
231
+ grep -rn "queryKey: \['" src/ --include="*.tsx" --include="*.ts"
232
+ # Expected: 0 matches (should be double brackets)
233
+ ```
234
+
235
+ ---
236
+
237
+ ## Related Documentation
238
+
239
+ - **Form Patterns**: `patterns/form-patterns.md`
240
+ - **UI Patterns**: `patterns/ui-patterns.md`
241
+ - **Display Patterns**: `patterns/display-patterns.md`
242
+
243
+ ---
244
+
245
+ **Document Status**: ACTIVE
246
+ **Compliance**: Mandatory for all component work