@pageai/ralph-loop 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.
Files changed (120) hide show
  1. package/.agent/PROMPT.md +58 -0
  2. package/.agent/STEERING.md +3 -0
  3. package/.agent/logs/LOG.md +13 -0
  4. package/.agent/prd/.gitkeep +0 -0
  5. package/.agent/screenshots/.gitkeep +0 -0
  6. package/.agent/skills/component-refactoring/SKILL.md +247 -0
  7. package/.agent/skills/component-refactoring/references/complexity-patterns.md +485 -0
  8. package/.agent/skills/component-refactoring/references/component-splitting.md +419 -0
  9. package/.agent/skills/component-refactoring/references/hook-extraction.md +317 -0
  10. package/.agent/skills/e2e-tester/SKILL.md +595 -0
  11. package/.agent/skills/frontend-code-review/SKILL.md +73 -0
  12. package/.agent/skills/frontend-code-review/references/code-quality.md +28 -0
  13. package/.agent/skills/frontend-code-review/references/performance.md +36 -0
  14. package/.agent/skills/frontend-testing/SKILL.md +316 -0
  15. package/.agent/skills/frontend-testing/assets/component-test.template.tsx +293 -0
  16. package/.agent/skills/frontend-testing/assets/hook-test.template.ts +207 -0
  17. package/.agent/skills/frontend-testing/assets/utility-test.template.ts +154 -0
  18. package/.agent/skills/frontend-testing/references/async-testing.md +345 -0
  19. package/.agent/skills/frontend-testing/references/checklist.md +188 -0
  20. package/.agent/skills/frontend-testing/references/common-patterns.md +449 -0
  21. package/.agent/skills/frontend-testing/references/mocking.md +289 -0
  22. package/.agent/skills/frontend-testing/references/workflow.md +265 -0
  23. package/.agent/skills/prd-creator/JSON.md +613 -0
  24. package/.agent/skills/prd-creator/PRD.md +196 -0
  25. package/.agent/skills/prd-creator/SKILL.md +143 -0
  26. package/.agent/skills/skill-creator/SKILL.md +355 -0
  27. package/.agent/skills/skill-creator/references/output-patterns.md +86 -0
  28. package/.agent/skills/skill-creator/references/workflows.md +28 -0
  29. package/.agent/skills/skill-creator/scripts/init_skill.py +300 -0
  30. package/.agent/skills/skill-creator/scripts/package_skill.py +110 -0
  31. package/.agent/skills/vercel-react-best-practices/AGENTS.md +2249 -0
  32. package/.agent/skills/vercel-react-best-practices/SKILL.md +125 -0
  33. package/.agent/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  34. package/.agent/skills/vercel-react-best-practices/rules/advanced-use-latest.md +49 -0
  35. package/.agent/skills/vercel-react-best-practices/rules/async-api-routes.md +38 -0
  36. package/.agent/skills/vercel-react-best-practices/rules/async-defer-await.md +80 -0
  37. package/.agent/skills/vercel-react-best-practices/rules/async-dependencies.md +36 -0
  38. package/.agent/skills/vercel-react-best-practices/rules/async-parallel.md +28 -0
  39. package/.agent/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -0
  40. package/.agent/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +59 -0
  41. package/.agent/skills/vercel-react-best-practices/rules/bundle-conditional.md +31 -0
  42. package/.agent/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +49 -0
  43. package/.agent/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  44. package/.agent/skills/vercel-react-best-practices/rules/bundle-preload.md +50 -0
  45. package/.agent/skills/vercel-react-best-practices/rules/client-event-listeners.md +74 -0
  46. package/.agent/skills/vercel-react-best-practices/rules/client-swr-dedup.md +56 -0
  47. package/.agent/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +82 -0
  48. package/.agent/skills/vercel-react-best-practices/rules/js-cache-function-results.md +80 -0
  49. package/.agent/skills/vercel-react-best-practices/rules/js-cache-property-access.md +28 -0
  50. package/.agent/skills/vercel-react-best-practices/rules/js-cache-storage.md +70 -0
  51. package/.agent/skills/vercel-react-best-practices/rules/js-combine-iterations.md +32 -0
  52. package/.agent/skills/vercel-react-best-practices/rules/js-early-exit.md +50 -0
  53. package/.agent/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -0
  54. package/.agent/skills/vercel-react-best-practices/rules/js-index-maps.md +37 -0
  55. package/.agent/skills/vercel-react-best-practices/rules/js-length-check-first.md +49 -0
  56. package/.agent/skills/vercel-react-best-practices/rules/js-min-max-loop.md +82 -0
  57. package/.agent/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -0
  58. package/.agent/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -0
  59. package/.agent/skills/vercel-react-best-practices/rules/rendering-activity.md +26 -0
  60. package/.agent/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  61. package/.agent/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +40 -0
  62. package/.agent/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -0
  63. package/.agent/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  64. package/.agent/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  65. package/.agent/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -0
  66. package/.agent/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -0
  67. package/.agent/skills/vercel-react-best-practices/rules/rerender-dependencies.md +45 -0
  68. package/.agent/skills/vercel-react-best-practices/rules/rerender-derived-state.md +29 -0
  69. package/.agent/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +74 -0
  70. package/.agent/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  71. package/.agent/skills/vercel-react-best-practices/rules/rerender-memo.md +44 -0
  72. package/.agent/skills/vercel-react-best-practices/rules/rerender-transitions.md +40 -0
  73. package/.agent/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -0
  74. package/.agent/skills/vercel-react-best-practices/rules/server-cache-lru.md +41 -0
  75. package/.agent/skills/vercel-react-best-practices/rules/server-cache-react.md +26 -0
  76. package/.agent/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +79 -0
  77. package/.agent/skills/vercel-react-best-practices/rules/server-serialization.md +38 -0
  78. package/.agent/skills/vitest-best-practices/AGENTS.md +84 -0
  79. package/.agent/skills/vitest-best-practices/SKILL.md +130 -0
  80. package/.agent/skills/vitest-best-practices/references/aaa-pattern.md +260 -0
  81. package/.agent/skills/vitest-best-practices/references/assertions.md +393 -0
  82. package/.agent/skills/vitest-best-practices/references/async-testing.md +454 -0
  83. package/.agent/skills/vitest-best-practices/references/error-handling.md +382 -0
  84. package/.agent/skills/vitest-best-practices/references/organization.md +212 -0
  85. package/.agent/skills/vitest-best-practices/references/parameterized-tests.md +297 -0
  86. package/.agent/skills/vitest-best-practices/references/performance.md +528 -0
  87. package/.agent/skills/vitest-best-practices/references/snapshot-testing.md +483 -0
  88. package/.agent/skills/vitest-best-practices/references/test-doubles.md +499 -0
  89. package/.agent/skills/vitest-best-practices/references/vitest-features.md +529 -0
  90. package/.agent/skills/web-design-guidelines/SKILL.md +39 -0
  91. package/.agent/tasks/.gitkeep +0 -0
  92. package/.agent/tasks.json +1 -0
  93. package/.claude/agents/code-reviewer.md +172 -0
  94. package/.claude/commands/aw.md +50 -0
  95. package/.claude/hooks/play-sound.js +87 -0
  96. package/.claude/hooks/pre-tool-use.js +40 -0
  97. package/.claude/settings.json +54 -0
  98. package/.claude/settings.local.json +13 -0
  99. package/.mcp.json +31 -0
  100. package/AGENTS.md +44 -0
  101. package/CLAUDE.md +1 -0
  102. package/README.md +236 -0
  103. package/bin/cli.js +156 -0
  104. package/bin/lib/copy.js +149 -0
  105. package/bin/lib/display.js +137 -0
  106. package/package.json +65 -0
  107. package/ralph.sh +333 -0
  108. package/scripts/lib/args.sh +44 -0
  109. package/scripts/lib/cleanup.sh +53 -0
  110. package/scripts/lib/constants.sh +25 -0
  111. package/scripts/lib/display.sh +196 -0
  112. package/scripts/lib/logging.sh +30 -0
  113. package/scripts/lib/notify.sh +41 -0
  114. package/scripts/lib/output.sh +147 -0
  115. package/scripts/lib/preflight.sh +57 -0
  116. package/scripts/lib/preview.sh +77 -0
  117. package/scripts/lib/promise.sh +76 -0
  118. package/scripts/lib/spinner.sh +85 -0
  119. package/scripts/lib/terminal.sh +57 -0
  120. package/scripts/lib/timing.sh +223 -0
@@ -0,0 +1,529 @@
1
+ # 1.9 Vitest-Specific Features
2
+
3
+ Vitest provides powerful features beyond basic testing. Use them to write better, more maintainable tests.
4
+
5
+ ## Test Filtering
6
+
7
+ Use `.only`, `.skip`, and `.todo` to control test execution during development.
8
+
9
+ **✅ Correct: focusing on specific tests**
10
+ ```ts
11
+ describe('UserService', () => {
12
+ it.only('should create user', () => {
13
+ // Only this test runs
14
+ const user = createUser({ name: 'John' });
15
+ expect(user.name).toBe('John');
16
+ });
17
+
18
+ it('should update user', () => {
19
+ // Skipped while .only is active
20
+ });
21
+
22
+ it.skip('should delete user', () => {
23
+ // Temporarily disabled
24
+ });
25
+
26
+ it.todo('should restore deleted user');
27
+ // Placeholder for future test
28
+ });
29
+ ```
30
+
31
+ **⚠️ Warning: Remove `.only` before committing**
32
+ ```ts
33
+ // DON'T commit this!
34
+ it.only('should work', () => {
35
+ // Other tests won't run in CI
36
+ });
37
+ ```
38
+
39
+ ## Conditional Tests
40
+
41
+ Run tests conditionally based on environment.
42
+
43
+ **✅ Correct: platform-specific tests**
44
+ ```ts
45
+ describe('FileSystem', () => {
46
+ it.runIf(process.platform === 'win32')('should handle Windows paths', () => {
47
+ expect(normalizePath('C:\\Users\\test')).toBe('C:/Users/test');
48
+ });
49
+
50
+ it.skipIf(process.platform === 'win32')('should handle Unix paths', () => {
51
+ expect(normalizePath('/home/test')).toBe('/home/test');
52
+ });
53
+ });
54
+ ```
55
+
56
+ ## Concurrent Tests
57
+
58
+ Run independent tests in parallel for faster execution.
59
+
60
+ **✅ Correct: concurrent test execution**
61
+ ```ts
62
+ describe.concurrent('API endpoints', () => {
63
+ it('should fetch users', async () => {
64
+ const users = await api.getUsers();
65
+ expect(users).toHaveLength(10);
66
+ });
67
+
68
+ it('should fetch products', async () => {
69
+ const products = await api.getProducts();
70
+ expect(products).toHaveLength(20);
71
+ });
72
+
73
+ it('should fetch orders', async () => {
74
+ const orders = await api.getOrders();
75
+ expect(orders).toHaveLength(5);
76
+ });
77
+ });
78
+ // All three tests run in parallel
79
+ ```
80
+
81
+ **⚠️ Caution: Only use for isolated tests**
82
+ ```ts
83
+ describe.concurrent('Database tests', () => {
84
+ // ❌ BAD: These tests share state and will interfere!
85
+ it('should create user', async () => {
86
+ await db.insert({ id: 1, name: 'Alice' });
87
+ });
88
+
89
+ it('should count users', async () => {
90
+ const count = await db.count();
91
+ expect(count).toBe(1); // Flaky! Depends on other test
92
+ });
93
+ });
94
+ ```
95
+
96
+ ## Test Context
97
+
98
+ Use `test.extend` to create custom test fixtures.
99
+
100
+ **✅ Correct: reusable test fixtures**
101
+ ```ts
102
+ import { test as base, expect } from 'vitest';
103
+
104
+ interface TestContext {
105
+ userService: UserService;
106
+ db: Database;
107
+ }
108
+
109
+ const test = base.extend<TestContext>({
110
+ userService: async ({}, use) => {
111
+ const service = new UserService();
112
+ await use(service);
113
+ await service.cleanup();
114
+ },
115
+
116
+ db: async ({}, use) => {
117
+ const db = await createTestDatabase();
118
+ await use(db);
119
+ await db.close();
120
+ },
121
+ });
122
+
123
+ test('should create user', async ({ userService, db }) => {
124
+ const user = await userService.create({ name: 'John' });
125
+ const saved = await db.findById(user.id);
126
+ expect(saved).toEqual(user);
127
+ });
128
+ ```
129
+
130
+ ## Mocking Modules
131
+
132
+ Use `vi.mock()` to mock entire modules.
133
+
134
+ **✅ Correct: mocking external dependency**
135
+ ```ts
136
+ import { sendEmail } from './email-service';
137
+
138
+ vi.mock('./email-service', () => ({
139
+ sendEmail: vi.fn().mockResolvedValue({ success: true }),
140
+ }));
141
+
142
+ it('should send welcome email', async () => {
143
+ await onUserSignup({ email: 'user@example.com' });
144
+
145
+ expect(sendEmail).toHaveBeenCalledWith({
146
+ to: 'user@example.com',
147
+ template: 'welcome',
148
+ });
149
+ });
150
+ ```
151
+
152
+ **✅ Correct: partial module mock**
153
+ ```ts
154
+ vi.mock('./utils', async (importOriginal) => {
155
+ const actual = await importOriginal();
156
+ return {
157
+ ...actual,
158
+ fetchData: vi.fn(), // Mock only fetchData
159
+ };
160
+ });
161
+ ```
162
+
163
+ ## Spy On Methods
164
+
165
+ Use `vi.spyOn()` to spy on object methods.
166
+
167
+ **✅ Correct: spying on console methods**
168
+ ```ts
169
+ it('should log error message', () => {
170
+ const consoleSpy = vi.spyOn(console, 'error').mockImplementation();
171
+
172
+ logger.error('Something went wrong');
173
+
174
+ expect(consoleSpy).toHaveBeenCalledWith('[ERROR]', 'Something went wrong');
175
+
176
+ consoleSpy.mockRestore();
177
+ });
178
+ ```
179
+
180
+ ## Fake Timers
181
+
182
+ Control time in tests using fake timers.
183
+
184
+ **✅ Correct: testing debounce**
185
+ ```ts
186
+ describe('debounce', () => {
187
+ beforeEach(() => {
188
+ vi.useFakeTimers();
189
+ });
190
+
191
+ afterEach(() => {
192
+ vi.useRealTimers();
193
+ });
194
+
195
+ it('should delay function execution', () => {
196
+ const callback = vi.fn();
197
+ const debounced = debounce(callback, 1000);
198
+
199
+ debounced();
200
+ expect(callback).not.toHaveBeenCalled();
201
+
202
+ vi.advanceTimersByTime(1000);
203
+ expect(callback).toHaveBeenCalledTimes(1);
204
+ });
205
+
206
+ it('should reset timer on subsequent calls', () => {
207
+ const callback = vi.fn();
208
+ const debounced = debounce(callback, 1000);
209
+
210
+ debounced();
211
+ vi.advanceTimersByTime(500);
212
+ debounced(); // Resets timer
213
+ vi.advanceTimersByTime(500);
214
+ expect(callback).not.toHaveBeenCalled();
215
+
216
+ vi.advanceTimersByTime(500);
217
+ expect(callback).toHaveBeenCalledTimes(1);
218
+ });
219
+ });
220
+ ```
221
+
222
+ **✅ Correct: testing intervals**
223
+ ```ts
224
+ it('should poll every second', () => {
225
+ vi.useFakeTimers();
226
+
227
+ const callback = vi.fn();
228
+ const poller = new Poller(callback, 1000);
229
+
230
+ poller.start();
231
+ expect(callback).toHaveBeenCalledTimes(1);
232
+
233
+ vi.advanceTimersByTime(3000);
234
+ expect(callback).toHaveBeenCalledTimes(4); // Initial + 3 intervals
235
+
236
+ poller.stop();
237
+ vi.useRealTimers();
238
+ });
239
+ ```
240
+
241
+ ## Test Each
242
+
243
+ Use `test.each()` for parameterized tests.
244
+
245
+ **✅ Correct: testing multiple inputs**
246
+ ```ts
247
+ test.each([
248
+ { input: 2, expected: 4 },
249
+ { input: 3, expected: 9 },
250
+ { input: 4, expected: 16 },
251
+ ])('square($input) should equal $expected', ({ input, expected }) => {
252
+ expect(square(input)).toBe(expected);
253
+ });
254
+ ```
255
+
256
+ **✅ Correct: array syntax**
257
+ ```ts
258
+ test.each([
259
+ [1, 1],
260
+ [2, 4],
261
+ [3, 9],
262
+ ])('square(%i) = %i', (input, expected) => {
263
+ expect(square(input)).toBe(expected);
264
+ });
265
+ ```
266
+
267
+ ## Coverage
268
+
269
+ Generate code coverage reports to identify untested code.
270
+
271
+ **vitest.config.ts:**
272
+ ```ts
273
+ export default {
274
+ test: {
275
+ coverage: {
276
+ provider: 'v8',
277
+ reporter: ['text', 'html', 'lcov'],
278
+ exclude: [
279
+ 'node_modules/',
280
+ 'test/',
281
+ '**/*.test.ts',
282
+ '**/*.config.ts',
283
+ ],
284
+ thresholds: {
285
+ lines: 80,
286
+ functions: 80,
287
+ branches: 80,
288
+ statements: 80,
289
+ },
290
+ },
291
+ },
292
+ };
293
+ ```
294
+
295
+ **Run coverage:**
296
+ ```bash
297
+ vitest --coverage
298
+ ```
299
+
300
+ **✅ Correct: focus on meaningful coverage**
301
+ ```ts
302
+ // Don't chase 100% coverage blindly
303
+ // Focus on testing critical business logic
304
+
305
+ describe('PaymentProcessor', () => {
306
+ it('should process valid payment', () => {
307
+ // Critical path - must be tested
308
+ });
309
+
310
+ it('should reject invalid payment', () => {
311
+ // Error path - must be tested
312
+ });
313
+
314
+ it('should handle network timeout', () => {
315
+ // Edge case - important to test
316
+ });
317
+ });
318
+ ```
319
+
320
+ ## Watch Mode
321
+
322
+ Use watch mode for rapid test-driven development.
323
+
324
+ ```bash
325
+ # Watch mode with UI
326
+ vitest --ui
327
+
328
+ # Watch mode in terminal
329
+ vitest --watch
330
+
331
+ # Watch specific files
332
+ vitest watch src/services
333
+ ```
334
+
335
+ ## Benchmarking
336
+
337
+ Use `bench()` to measure performance.
338
+
339
+ **✅ Correct: comparing implementations**
340
+ ```ts
341
+ import { bench, describe } from 'vitest';
342
+
343
+ describe('Array operations', () => {
344
+ bench('for loop', () => {
345
+ const arr = Array.from({ length: 1000 }, (_, i) => i);
346
+ let sum = 0;
347
+ for (let i = 0; i < arr.length; i++) {
348
+ sum += arr[i];
349
+ }
350
+ return sum;
351
+ });
352
+
353
+ bench('forEach', () => {
354
+ const arr = Array.from({ length: 1000 }, (_, i) => i);
355
+ let sum = 0;
356
+ arr.forEach(n => sum += n);
357
+ return sum;
358
+ });
359
+
360
+ bench('reduce', () => {
361
+ const arr = Array.from({ length: 1000 }, (_, i) => i);
362
+ return arr.reduce((sum, n) => sum + n, 0);
363
+ });
364
+ });
365
+ ```
366
+
367
+ ## In-Source Testing
368
+
369
+ Define tests alongside implementation code.
370
+
371
+ **example.ts:**
372
+ ```ts
373
+ export function add(a: number, b: number): number {
374
+ return a + b;
375
+ }
376
+
377
+ if (import.meta.vitest) {
378
+ const { it, expect } = import.meta.vitest;
379
+
380
+ it('should add two numbers', () => {
381
+ expect(add(2, 3)).toBe(5);
382
+ });
383
+
384
+ it('should handle negative numbers', () => {
385
+ expect(add(-2, 3)).toBe(1);
386
+ });
387
+ }
388
+ ```
389
+
390
+ **vitest.config.ts:**
391
+ ```ts
392
+ export default {
393
+ test: {
394
+ includeSource: ['src/**/*.ts'],
395
+ },
396
+ define: {
397
+ 'import.meta.vitest': 'undefined',
398
+ },
399
+ };
400
+ ```
401
+
402
+ ## Type Testing
403
+
404
+ Test TypeScript types using `expectTypeOf`.
405
+
406
+ **✅ Correct: type assertions**
407
+ ```ts
408
+ import { expectTypeOf } from 'vitest';
409
+
410
+ it('should have correct return type', () => {
411
+ const result = fetchUser('123');
412
+
413
+ expectTypeOf(result).toEqualTypeOf<Promise<User>>();
414
+ });
415
+
416
+ it('should accept correct parameter types', () => {
417
+ expectTypeOf(createUser).parameter(0).toMatchTypeOf<UserInput>();
418
+ });
419
+
420
+ it('should infer correct generic type', () => {
421
+ const users = [{ id: 1, name: 'Alice' }];
422
+
423
+ expectTypeOf(users).toEqualTypeOf<Array<{ id: number; name: string }>>();
424
+ });
425
+ ```
426
+
427
+ ## Setup Files
428
+
429
+ Configure global test setup and teardown.
430
+
431
+ **vitest.config.ts:**
432
+ ```ts
433
+ export default {
434
+ test: {
435
+ setupFiles: ['./test/setup.ts'],
436
+ globalSetup: ['./test/global-setup.ts'],
437
+ },
438
+ };
439
+ ```
440
+
441
+ **test/setup.ts (runs before each test file):**
442
+ ```ts
443
+ import { beforeEach, afterEach } from 'vitest';
444
+
445
+ beforeEach(() => {
446
+ // Runs before each test
447
+ vi.clearAllMocks();
448
+ });
449
+
450
+ afterEach(() => {
451
+ // Runs after each test
452
+ vi.restoreAllMocks();
453
+ });
454
+ ```
455
+
456
+ **test/global-setup.ts (runs once before all tests):**
457
+ ```ts
458
+ export async function setup() {
459
+ // Start test database, etc.
460
+ console.log('Starting test environment...');
461
+ }
462
+
463
+ export async function teardown() {
464
+ // Clean up global resources
465
+ console.log('Cleaning up test environment...');
466
+ }
467
+ ```
468
+
469
+ ## Environment
470
+
471
+ Specify different test environments for different tests.
472
+
473
+ **✅ Correct: browser environment for DOM tests**
474
+ ```ts
475
+ /**
476
+ * @vitest-environment jsdom
477
+ */
478
+
479
+ import { render } from '@testing-library/react';
480
+
481
+ it('should render component', () => {
482
+ const { getByText } = render(<Button>Click me</Button>);
483
+ expect(getByText('Click me')).toBeInTheDocument();
484
+ });
485
+ ```
486
+
487
+ **✅ Correct: node environment for API tests**
488
+ ```ts
489
+ /**
490
+ * @vitest-environment node
491
+ */
492
+
493
+ it('should read file', async () => {
494
+ const content = await fs.readFile('./test.txt', 'utf-8');
495
+ expect(content).toContain('test data');
496
+ });
497
+ ```
498
+
499
+ ## Retry Flaky Tests
500
+
501
+ Retry flaky tests automatically.
502
+
503
+ **✅ Correct: retry configuration**
504
+ ```ts
505
+ // vitest.config.ts
506
+ export default {
507
+ test: {
508
+ retry: 2, // Retry failed tests up to 2 times
509
+ },
510
+ };
511
+ ```
512
+
513
+ **✅ Correct: per-test retry**
514
+ ```ts
515
+ it('flaky network test', { retry: 3 }, async () => {
516
+ const data = await fetchFromUnreliableAPI();
517
+ expect(data).toBeDefined();
518
+ });
519
+ ```
520
+
521
+ **⚠️ Better: Fix the flakiness instead of retrying**
522
+ ```ts
523
+ // Instead of retrying, mock the unreliable dependency
524
+ it('network test', async () => {
525
+ const mockFetch = vi.fn().mockResolvedValue({ data: 'test' });
526
+ const data = await fetchData(mockFetch);
527
+ expect(data).toBeDefined();
528
+ });
529
+ ```
@@ -0,0 +1,39 @@
1
+ ---
2
+ name: web-design-guidelines
3
+ description: Review UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "check accessibility", "audit design", "review UX", or "check my site against best practices".
4
+ argument-hint: <file-or-pattern>
5
+ metadata:
6
+ author: vercel
7
+ version: "1.0.0"
8
+ ---
9
+
10
+ # Web Interface Guidelines
11
+
12
+ Review files for compliance with Web Interface Guidelines.
13
+
14
+ ## How It Works
15
+
16
+ 1. Fetch the latest guidelines from the source URL below
17
+ 2. Read the specified files (or prompt user for files/pattern)
18
+ 3. Check against all rules in the fetched guidelines
19
+ 4. Output findings in the terse `file:line` format
20
+
21
+ ## Guidelines Source
22
+
23
+ Fetch fresh guidelines before each review:
24
+
25
+ ```
26
+ https://raw.githubusercontent.com/vercel-labs/web-interface-guidelines/main/command.md
27
+ ```
28
+
29
+ Use WebFetch to retrieve the latest rules. The fetched content contains all the rules and output format instructions.
30
+
31
+ ## Usage
32
+
33
+ When a user provides a file or pattern argument:
34
+ 1. Fetch guidelines from the source URL above
35
+ 2. Read the specified files
36
+ 3. Apply all rules from the fetched guidelines
37
+ 4. Output findings using the format specified in the guidelines
38
+
39
+ If no files specified, ask the user which files to review.
File without changes
@@ -0,0 +1 @@
1
+ []