@codihaus/claude-skills 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +167 -0
- package/bin/cli.js +58 -0
- package/package.json +46 -0
- package/skills/_quality-attributes.md +392 -0
- package/skills/_registry.md +189 -0
- package/skills/debrief/SKILL.md +647 -0
- package/skills/debrief/references/change-request-template.md +124 -0
- package/skills/debrief/references/file-patterns.md +173 -0
- package/skills/debrief/references/group-codes.md +72 -0
- package/skills/debrief/references/research-queries.md +106 -0
- package/skills/debrief/references/use-case-template.md +141 -0
- package/skills/debrief/scripts/generate_questionnaire.py +195 -0
- package/skills/dev-arch/SKILL.md +747 -0
- package/skills/dev-changelog/SKILL.md +378 -0
- package/skills/dev-coding/SKILL.md +470 -0
- package/skills/dev-coding-backend/SKILL.md +361 -0
- package/skills/dev-coding-frontend/SKILL.md +534 -0
- package/skills/dev-coding-frontend/references/nextjs.md +477 -0
- package/skills/dev-review/SKILL.md +548 -0
- package/skills/dev-scout/SKILL.md +723 -0
- package/skills/dev-scout/references/feature-patterns.md +210 -0
- package/skills/dev-scout/references/file-patterns.md +252 -0
- package/skills/dev-scout/references/tech-detection.md +211 -0
- package/skills/dev-scout/scripts/scout-analyze.sh +280 -0
- package/skills/dev-specs/SKILL.md +577 -0
- package/skills/dev-specs/references/checklist.md +176 -0
- package/skills/dev-specs/references/spec-templates.md +460 -0
- package/skills/dev-test/SKILL.md +364 -0
- package/skills/utils/diagram/SKILL.md +205 -0
- package/skills/utils/diagram/references/common-errors.md +305 -0
- package/skills/utils/diagram/references/diagram-types.md +636 -0
- package/skills/utils/docs-graph/SKILL.md +204 -0
- package/skills/utils/gemini/SKILL.md +292 -0
- package/skills/utils/gemini/scripts/gemini-scan.py +340 -0
- package/skills/utils/gemini/scripts/setup.sh +169 -0
- package/src/commands/add.js +64 -0
- package/src/commands/doctor.js +179 -0
- package/src/commands/init.js +251 -0
- package/src/commands/list.js +88 -0
- package/src/commands/remove.js +60 -0
- package/src/commands/update.js +72 -0
- package/src/index.js +26 -0
- package/src/utils/config.js +272 -0
- package/src/utils/deps.js +599 -0
- package/src/utils/skills.js +253 -0
- package/templates/CLAUDE.md.template +58 -0
|
@@ -0,0 +1,534 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dev-coding-frontend
|
|
3
|
+
description: Frontend implementation patterns and workflows
|
|
4
|
+
version: 1.3.0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /dev-coding-frontend - Frontend Implementation
|
|
8
|
+
|
|
9
|
+
> **Skill Awareness**: See `skills/_registry.md` for all available skills.
|
|
10
|
+
> - **Loaded by**: `/dev-coding` when UI work needed
|
|
11
|
+
> - **Tools**: shadcn MCP (components), Playwright (visual), Context7 (docs)
|
|
12
|
+
> - **References**: Load tech-specific from `references/` (nextjs.md, vue.md, etc.)
|
|
13
|
+
> - **Before**: Backend API contract should be documented
|
|
14
|
+
> - **After**: `/dev-test` auto-runs to verify UI works
|
|
15
|
+
|
|
16
|
+
Frontend-specific patterns for UI components, pages, and client-side logic.
|
|
17
|
+
|
|
18
|
+
## When Loaded
|
|
19
|
+
|
|
20
|
+
This skill is loaded by `/dev-coding` when:
|
|
21
|
+
- Spec requires UI components
|
|
22
|
+
- Spec requires pages/routes
|
|
23
|
+
- Spec requires client-side logic
|
|
24
|
+
|
|
25
|
+
## Workflow
|
|
26
|
+
|
|
27
|
+
### Step 1: Understand Frontend Requirements
|
|
28
|
+
|
|
29
|
+
From the UC spec, extract:
|
|
30
|
+
|
|
31
|
+
```markdown
|
|
32
|
+
## Frontend Requirements Checklist
|
|
33
|
+
|
|
34
|
+
[ ] Pages/Routes needed?
|
|
35
|
+
- Path
|
|
36
|
+
- Layout
|
|
37
|
+
- Auth required?
|
|
38
|
+
|
|
39
|
+
[ ] Components needed?
|
|
40
|
+
- New components
|
|
41
|
+
- Modify existing
|
|
42
|
+
- Shared vs feature-specific
|
|
43
|
+
|
|
44
|
+
[ ] State management?
|
|
45
|
+
- Local state
|
|
46
|
+
- Global state
|
|
47
|
+
- Server state (API data)
|
|
48
|
+
|
|
49
|
+
[ ] Forms?
|
|
50
|
+
- Fields
|
|
51
|
+
- Validation rules
|
|
52
|
+
- Submit handling
|
|
53
|
+
|
|
54
|
+
[ ] API integration?
|
|
55
|
+
- Endpoints to call
|
|
56
|
+
- Request/response handling
|
|
57
|
+
- Loading/error states
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Step 2: Review API Contract
|
|
61
|
+
|
|
62
|
+
If backend was just implemented (or exists), review:
|
|
63
|
+
|
|
64
|
+
```markdown
|
|
65
|
+
## Available API
|
|
66
|
+
|
|
67
|
+
From backend implementation notes:
|
|
68
|
+
|
|
69
|
+
### POST /api/auth/login
|
|
70
|
+
- Request: `{ email, password }`
|
|
71
|
+
- Response: `{ token, user }`
|
|
72
|
+
- Errors: 400 (validation), 401 (credentials)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Know this BEFORE building UI to match shapes.
|
|
76
|
+
|
|
77
|
+
### Step 3: Component Architecture
|
|
78
|
+
|
|
79
|
+
**Decide component structure:**
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
Feature component structure:
|
|
83
|
+
src/
|
|
84
|
+
├── components/
|
|
85
|
+
│ ├── ui/ # Shared/base components
|
|
86
|
+
│ │ ├── Button.tsx
|
|
87
|
+
│ │ └── Input.tsx
|
|
88
|
+
│ └── features/
|
|
89
|
+
│ └── auth/ # Feature-specific
|
|
90
|
+
│ ├── LoginForm.tsx
|
|
91
|
+
│ └── SignupForm.tsx
|
|
92
|
+
├── app/ (or pages/)
|
|
93
|
+
│ └── login/
|
|
94
|
+
│ └── page.tsx # Page that uses LoginForm
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Follow project conventions** (from scout):
|
|
98
|
+
- Where components live
|
|
99
|
+
- Naming pattern
|
|
100
|
+
- Export style
|
|
101
|
+
|
|
102
|
+
### Step 4: Build Components
|
|
103
|
+
|
|
104
|
+
**Order:** Base components → Feature components → Pages
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
1. Check if base components exist (Button, Input, etc.)
|
|
108
|
+
2. Create feature components
|
|
109
|
+
3. Create/modify pages
|
|
110
|
+
4. Wire up routing
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Component Pattern:**
|
|
114
|
+
|
|
115
|
+
```tsx
|
|
116
|
+
// Follow project conventions
|
|
117
|
+
// This is a common pattern, adapt to project
|
|
118
|
+
|
|
119
|
+
interface LoginFormProps {
|
|
120
|
+
onSuccess?: (user: User) => void;
|
|
121
|
+
redirectTo?: string;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function LoginForm({ onSuccess, redirectTo = '/' }: LoginFormProps) {
|
|
125
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
126
|
+
const [error, setError] = useState<string | null>(null);
|
|
127
|
+
|
|
128
|
+
const handleSubmit = async (e: FormEvent) => {
|
|
129
|
+
e.preventDefault();
|
|
130
|
+
setIsLoading(true);
|
|
131
|
+
setError(null);
|
|
132
|
+
|
|
133
|
+
try {
|
|
134
|
+
const result = await login(formData);
|
|
135
|
+
onSuccess?.(result.user);
|
|
136
|
+
router.push(redirectTo);
|
|
137
|
+
} catch (err) {
|
|
138
|
+
setError(err.message);
|
|
139
|
+
} finally {
|
|
140
|
+
setIsLoading(false);
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
return (
|
|
145
|
+
<form onSubmit={handleSubmit}>
|
|
146
|
+
{error && <Alert variant="error">{error}</Alert>}
|
|
147
|
+
{/* Form fields */}
|
|
148
|
+
<Button type="submit" disabled={isLoading}>
|
|
149
|
+
{isLoading ? 'Loading...' : 'Login'}
|
|
150
|
+
</Button>
|
|
151
|
+
</form>
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Step 5: API Integration
|
|
157
|
+
|
|
158
|
+
**Create API client functions:**
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
// lib/api/auth.ts
|
|
162
|
+
export async function login(credentials: LoginCredentials) {
|
|
163
|
+
const response = await fetch('/api/auth/login', {
|
|
164
|
+
method: 'POST',
|
|
165
|
+
headers: { 'Content-Type': 'application/json' },
|
|
166
|
+
body: JSON.stringify(credentials),
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
if (!response.ok) {
|
|
170
|
+
const error = await response.json();
|
|
171
|
+
throw new Error(error.message || 'Login failed');
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return response.json();
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Handle states:**
|
|
179
|
+
|
|
180
|
+
```tsx
|
|
181
|
+
// Loading state
|
|
182
|
+
{isLoading && <Spinner />}
|
|
183
|
+
|
|
184
|
+
// Error state
|
|
185
|
+
{error && <Alert variant="error">{error}</Alert>}
|
|
186
|
+
|
|
187
|
+
// Empty state
|
|
188
|
+
{items.length === 0 && <EmptyState message="No items found" />}
|
|
189
|
+
|
|
190
|
+
// Success state
|
|
191
|
+
{items.map(item => <ItemCard key={item.id} item={item} />)}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Step 6: Form Handling
|
|
195
|
+
|
|
196
|
+
**Validation Pattern:**
|
|
197
|
+
|
|
198
|
+
```tsx
|
|
199
|
+
// Client-side validation
|
|
200
|
+
const validateForm = (data: FormData) => {
|
|
201
|
+
const errors: Record<string, string> = {};
|
|
202
|
+
|
|
203
|
+
if (!data.email) {
|
|
204
|
+
errors.email = 'Email is required';
|
|
205
|
+
} else if (!isValidEmail(data.email)) {
|
|
206
|
+
errors.email = 'Invalid email format';
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (!data.password) {
|
|
210
|
+
errors.password = 'Password is required';
|
|
211
|
+
} else if (data.password.length < 8) {
|
|
212
|
+
errors.password = 'Password must be at least 8 characters';
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return errors;
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
// Show errors
|
|
219
|
+
{errors.email && <span className="error">{errors.email}</span>}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
**Form Libraries** (use if project has them):
|
|
223
|
+
- react-hook-form
|
|
224
|
+
- formik
|
|
225
|
+
- native form handling
|
|
226
|
+
|
|
227
|
+
### Step 7: Quick Verification
|
|
228
|
+
|
|
229
|
+
Before `/dev-test` auto-runs, do quick sanity checks:
|
|
230
|
+
|
|
231
|
+
**Visual verification:**
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
// Option 1: Playwright snapshot
|
|
235
|
+
await mcp__playwright__browser_navigate({ url: 'http://localhost:3000/login' });
|
|
236
|
+
await mcp__playwright__browser_snapshot({});
|
|
237
|
+
|
|
238
|
+
// Option 2: Manual check
|
|
239
|
+
// Navigate to page in browser, verify appearance
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
**Quick checklist:**
|
|
243
|
+
```
|
|
244
|
+
[ ] Page renders without console errors
|
|
245
|
+
[ ] Components display correctly
|
|
246
|
+
[ ] Forms accept input
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Step 8: Hand Off to Testing
|
|
250
|
+
|
|
251
|
+
After frontend complete, `/dev-coding` auto-triggers `/dev-test` which:
|
|
252
|
+
|
|
253
|
+
```
|
|
254
|
+
1. Navigate to implemented page
|
|
255
|
+
2. Execute user flow from spec
|
|
256
|
+
3. Capture console errors
|
|
257
|
+
4. Capture network failures
|
|
258
|
+
5. Report issues or confirm pass
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
**What /dev-test catches:**
|
|
262
|
+
- Console errors (React errors, JS exceptions)
|
|
263
|
+
- Network failures (API 4xx/5xx, CORS, timeouts)
|
|
264
|
+
- Missing elements (render failures)
|
|
265
|
+
- Broken interactions (form submit, navigation)
|
|
266
|
+
|
|
267
|
+
**Verification checklist (covered by /dev-test):**
|
|
268
|
+
```
|
|
269
|
+
[auto] Page renders without errors
|
|
270
|
+
[auto] Console clean (no errors/warnings)
|
|
271
|
+
[auto] API calls succeed (2xx responses)
|
|
272
|
+
[auto] User flow completes
|
|
273
|
+
[ ] Mobile responsive (manual if required)
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## Common Patterns
|
|
277
|
+
|
|
278
|
+
### Conditional Rendering
|
|
279
|
+
|
|
280
|
+
```tsx
|
|
281
|
+
// Auth guard
|
|
282
|
+
{isAuthenticated ? <Dashboard /> : <Redirect to="/login" />}
|
|
283
|
+
|
|
284
|
+
// Loading
|
|
285
|
+
{isLoading ? <Spinner /> : <Content />}
|
|
286
|
+
|
|
287
|
+
// Permission
|
|
288
|
+
{user.canEdit && <EditButton />}
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Data Fetching
|
|
292
|
+
|
|
293
|
+
```tsx
|
|
294
|
+
// Server component (Next.js App Router)
|
|
295
|
+
async function PostsPage() {
|
|
296
|
+
const posts = await getPosts(); // Fetches on server
|
|
297
|
+
return <PostList posts={posts} />;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Client component with useEffect
|
|
301
|
+
function PostsPage() {
|
|
302
|
+
const [posts, setPosts] = useState([]);
|
|
303
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
304
|
+
|
|
305
|
+
useEffect(() => {
|
|
306
|
+
getPosts().then(setPosts).finally(() => setIsLoading(false));
|
|
307
|
+
}, []);
|
|
308
|
+
|
|
309
|
+
if (isLoading) return <Spinner />;
|
|
310
|
+
return <PostList posts={posts} />;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// With SWR/React Query
|
|
314
|
+
function PostsPage() {
|
|
315
|
+
const { data: posts, error, isLoading } = useSWR('/api/posts', fetcher);
|
|
316
|
+
|
|
317
|
+
if (isLoading) return <Spinner />;
|
|
318
|
+
if (error) return <Error message={error.message} />;
|
|
319
|
+
return <PostList posts={posts} />;
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Navigation
|
|
324
|
+
|
|
325
|
+
```tsx
|
|
326
|
+
// Next.js
|
|
327
|
+
import { useRouter } from 'next/navigation';
|
|
328
|
+
const router = useRouter();
|
|
329
|
+
router.push('/dashboard');
|
|
330
|
+
|
|
331
|
+
// React Router
|
|
332
|
+
import { useNavigate } from 'react-router-dom';
|
|
333
|
+
const navigate = useNavigate();
|
|
334
|
+
navigate('/dashboard');
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Toast/Notifications
|
|
338
|
+
|
|
339
|
+
```tsx
|
|
340
|
+
// Success feedback
|
|
341
|
+
toast.success('Saved successfully');
|
|
342
|
+
|
|
343
|
+
// Error feedback
|
|
344
|
+
toast.error('Failed to save. Please try again.');
|
|
345
|
+
|
|
346
|
+
// Use project's toast library (sonner, react-hot-toast, etc.)
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
## Accessibility Checklist
|
|
350
|
+
|
|
351
|
+
```
|
|
352
|
+
[ ] Images have alt text
|
|
353
|
+
[ ] Form inputs have labels
|
|
354
|
+
[ ] Buttons have accessible names
|
|
355
|
+
[ ] Color contrast sufficient
|
|
356
|
+
[ ] Keyboard navigation works
|
|
357
|
+
[ ] Focus states visible
|
|
358
|
+
[ ] Screen reader tested (if critical)
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
## Responsive Checklist
|
|
362
|
+
|
|
363
|
+
```
|
|
364
|
+
[ ] Mobile layout (< 768px)
|
|
365
|
+
[ ] Tablet layout (768px - 1024px)
|
|
366
|
+
[ ] Desktop layout (> 1024px)
|
|
367
|
+
[ ] Touch targets large enough (44px minimum)
|
|
368
|
+
[ ] No horizontal scroll on mobile
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
## Debugging
|
|
372
|
+
|
|
373
|
+
### Component Not Rendering
|
|
374
|
+
|
|
375
|
+
```bash
|
|
376
|
+
# Check console for errors
|
|
377
|
+
# Browser DevTools → Console
|
|
378
|
+
|
|
379
|
+
# Check if component imported correctly
|
|
380
|
+
# Check if props passed correctly
|
|
381
|
+
# Check conditional rendering logic
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
### API Call Failing
|
|
385
|
+
|
|
386
|
+
```bash
|
|
387
|
+
# Check Network tab in DevTools
|
|
388
|
+
# Verify URL, method, headers
|
|
389
|
+
# Check CORS if cross-origin
|
|
390
|
+
# Verify backend is running
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
### Styling Issues
|
|
394
|
+
|
|
395
|
+
```bash
|
|
396
|
+
# Check if styles imported
|
|
397
|
+
# Check class names (typos)
|
|
398
|
+
# Check CSS specificity
|
|
399
|
+
# Check for conflicting styles
|
|
400
|
+
# Use DevTools Elements panel
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### Using Playwright for Debug
|
|
404
|
+
|
|
405
|
+
```typescript
|
|
406
|
+
// Take screenshot of current state
|
|
407
|
+
await mcp__playwright__browser_take_screenshot({
|
|
408
|
+
filename: 'debug-screenshot.png'
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
// Check console messages
|
|
412
|
+
await mcp__playwright__browser_console_messages({
|
|
413
|
+
level: 'error'
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
// Check network requests
|
|
417
|
+
await mcp__playwright__browser_network_requests({});
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
## Tech-Specific References
|
|
421
|
+
|
|
422
|
+
Load additional patterns based on detected tech:
|
|
423
|
+
|
|
424
|
+
| Tech | Reference File |
|
|
425
|
+
|------|---------------|
|
|
426
|
+
| Next.js | `references/nextjs.md` |
|
|
427
|
+
| Vue | `references/vue.md` |
|
|
428
|
+
| React | `references/react.md` |
|
|
429
|
+
| shadcn/ui | `references/shadcn.md` |
|
|
430
|
+
| Tailwind | `references/tailwind.md` |
|
|
431
|
+
|
|
432
|
+
These files contain tech-specific patterns, gotchas, and best practices. Add them as your projects use different stacks.
|
|
433
|
+
|
|
434
|
+
## Tools
|
|
435
|
+
|
|
436
|
+
### shadcn/ui Components (MCP)
|
|
437
|
+
|
|
438
|
+
When project uses shadcn/ui, use these tools to get components:
|
|
439
|
+
|
|
440
|
+
```
|
|
441
|
+
1. Check available components
|
|
442
|
+
→ mcp__shadcn__list_components
|
|
443
|
+
|
|
444
|
+
2. Get component source code
|
|
445
|
+
→ mcp__shadcn__get_component("button")
|
|
446
|
+
→ mcp__shadcn__get_component("dialog")
|
|
447
|
+
|
|
448
|
+
3. Get usage examples
|
|
449
|
+
→ mcp__shadcn__get_component_demo("button")
|
|
450
|
+
→ mcp__shadcn__get_component_demo("form")
|
|
451
|
+
|
|
452
|
+
4. Get component metadata
|
|
453
|
+
→ mcp__shadcn__get_component_metadata("card")
|
|
454
|
+
|
|
455
|
+
5. Get pre-built blocks (dashboard, login, etc.)
|
|
456
|
+
→ mcp__shadcn__list_blocks
|
|
457
|
+
→ mcp__shadcn__get_block("login-01")
|
|
458
|
+
→ mcp__shadcn__get_block("dashboard-01")
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
**Workflow with shadcn:**
|
|
462
|
+
|
|
463
|
+
```
|
|
464
|
+
1. Check if project uses shadcn/ui
|
|
465
|
+
→ Look for components.json
|
|
466
|
+
→ Look for @/components/ui/
|
|
467
|
+
|
|
468
|
+
2. If yes, use shadcn tools:
|
|
469
|
+
→ List available components
|
|
470
|
+
→ Get source for needed components
|
|
471
|
+
→ Get demos for usage patterns
|
|
472
|
+
→ Get blocks for complex layouts
|
|
473
|
+
|
|
474
|
+
3. Adapt to project's style
|
|
475
|
+
→ Check existing component customizations
|
|
476
|
+
→ Follow project's variant patterns
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
**Example:**
|
|
480
|
+
|
|
481
|
+
```
|
|
482
|
+
Need: Login form with validation
|
|
483
|
+
|
|
484
|
+
1. mcp__shadcn__get_block("login-01")
|
|
485
|
+
→ Get full login block
|
|
486
|
+
|
|
487
|
+
2. mcp__shadcn__get_component_demo("form")
|
|
488
|
+
→ See form validation patterns
|
|
489
|
+
|
|
490
|
+
3. Adapt to project's API endpoints
|
|
491
|
+
→ Change form action
|
|
492
|
+
→ Match project's auth flow
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### Playwright (Visual Testing)
|
|
496
|
+
|
|
497
|
+
Use Playwright for visual verification during development:
|
|
498
|
+
|
|
499
|
+
```
|
|
500
|
+
# Take screenshot to verify UI
|
|
501
|
+
mcp__playwright__browser_take_screenshot
|
|
502
|
+
|
|
503
|
+
# Get accessibility snapshot
|
|
504
|
+
mcp__playwright__browser_snapshot
|
|
505
|
+
|
|
506
|
+
# Check for console errors
|
|
507
|
+
mcp__playwright__browser_console_messages({ level: "error" })
|
|
508
|
+
|
|
509
|
+
# Verify network requests
|
|
510
|
+
mcp__playwright__browser_network_requests
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
### Context7 (Documentation Lookup)
|
|
514
|
+
|
|
515
|
+
Look up framework/library documentation:
|
|
516
|
+
|
|
517
|
+
```
|
|
518
|
+
1. Find library ID
|
|
519
|
+
→ mcp__context7__resolve-library-id({
|
|
520
|
+
libraryName: "react-hook-form",
|
|
521
|
+
query: "form validation"
|
|
522
|
+
})
|
|
523
|
+
|
|
524
|
+
2. Query documentation
|
|
525
|
+
→ mcp__context7__query-docs({
|
|
526
|
+
libraryId: "/react-hook-form/react-hook-form",
|
|
527
|
+
query: "how to validate email field"
|
|
528
|
+
})
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
**Use Context7 for:**
|
|
532
|
+
- Framework-specific patterns (Next.js, Vue, etc.)
|
|
533
|
+
- Library APIs (React Query, Zustand, etc.)
|
|
534
|
+
- CSS framework docs (Tailwind, etc.)
|