claude-toolkit 0.1.9 → 0.1.18

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 (40) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +3 -0
  3. package/bin/cli.ts +0 -0
  4. package/core/skills/ct-testing-patterns/SKILL.md +117 -0
  5. package/core/skills/{typescript-conventions → ct-typescript-conventions}/SKILL.md +41 -0
  6. package/core/skills/{verification-before-completion → ct-verification-before-completion}/SKILL.md +10 -0
  7. package/docs/README.md +3 -0
  8. package/docs/best-practices/testing/README.md +84 -0
  9. package/docs/best-practices/testing/playwright-e2e.md +649 -0
  10. package/docs/best-practices/testing/storybook-interaction.md +445 -0
  11. package/docs/best-practices/testing/vitest-unit.md +451 -0
  12. package/docs/skills/systematic-debugging.md +1 -1
  13. package/docs/skills/testing-patterns.md +30 -1
  14. package/docs/skills/typescript-conventions.md +42 -1
  15. package/docs/skills/verification-before-completion.md +14 -2
  16. package/docs/stacks/cloudflare-d1-kv.md +35 -1
  17. package/docs/stacks/i18n-typesafe.md +1 -1
  18. package/docs/stacks/playwright-patterns.md +179 -0
  19. package/docs/stacks/protobuf-contracts.md +1 -1
  20. package/docs/stacks/rust-wasm-patterns.md +2 -2
  21. package/docs/stacks/solidjs-patterns.md +1 -1
  22. package/docs/stacks/storybook-patterns.md +160 -0
  23. package/docs/stacks/vanilla-extract-patterns.md +1 -1
  24. package/docs/stacks/vite-vitest-patterns.md +485 -0
  25. package/package.json +3 -3
  26. package/stacks/cloudflare/skills/{cloudflare-d1-kv → ct-cloudflare-d1-kv}/SKILL.md +22 -0
  27. package/stacks/playwright/skills/ct-playwright-patterns/SKILL.md +168 -0
  28. package/stacks/playwright/stack.json +39 -0
  29. package/stacks/solidjs/stack.json +7 -1
  30. package/stacks/storybook/skills/ct-storybook-patterns/SKILL.md +149 -0
  31. package/stacks/storybook/stack.json +46 -0
  32. package/stacks/vite/skills/ct-vite-vitest-patterns/SKILL.md +492 -0
  33. package/stacks/vite/stack.json +66 -0
  34. package/core/skills/testing-patterns/SKILL.md +0 -52
  35. /package/core/skills/{systematic-debugging → ct-systematic-debugging}/SKILL.md +0 -0
  36. /package/stacks/i18n-typesafe/skills/{i18n-typesafe → ct-i18n-typesafe}/SKILL.md +0 -0
  37. /package/stacks/protobuf/skills/{protobuf-contracts → ct-protobuf-contracts}/SKILL.md +0 -0
  38. /package/stacks/rust-wasm/skills/{rust-wasm-patterns → ct-rust-wasm-patterns}/SKILL.md +0 -0
  39. /package/stacks/solidjs/skills/{solidjs-patterns → ct-solidjs-patterns}/SKILL.md +0 -0
  40. /package/stacks/vanilla-extract/skills/{vanilla-extract-patterns → ct-vanilla-extract-patterns}/SKILL.md +0 -0
@@ -0,0 +1,445 @@
1
+ # Storybook Interaction Testing
2
+
3
+ > Sources: [Storybook 10 Blog](https://storybook.js.org/blog/storybook-10/), [Storybook 9.0 Release](https://storybook.js.org/releases/9.0), [Interaction Testing Docs](https://storybook.js.org/docs/writing-tests/interaction-testing), [storybook-solidjs-vite](https://www.npmjs.com/package/storybook-solidjs-vite), [Vitest Addon Docs](https://storybook.js.org/docs/writing-tests/integrations/vitest-addon)
4
+
5
+ Storybook serves as the middle layer of the testing pyramid: component-level interaction testing, visual regression, and accessibility auditing -- all in a real browser environment.
6
+
7
+ ## SolidJS Integration
8
+
9
+ The integration is community-maintained via two packages:
10
+
11
+ - **`storybook-solidjs`** -- the renderer
12
+ - **`storybook-solidjs-vite`** -- Vite builder integration (v10.0.x)
13
+
14
+ ### Critical: Decorator Reactivity
15
+
16
+ SolidJS components run once; Storybook re-executes decorators on every args/globals change. Standard decorators cause **duplicate DOM elements** with SolidJS.
17
+
18
+ Always use `createJSXDecorator` for JSX-returning decorators:
19
+
20
+ ```typescript
21
+ import { createJSXDecorator } from "storybook-solidjs";
22
+
23
+ // CORRECT -- prevents double-rendering
24
+ const ThemeDecorator = createJSXDecorator((Story, context) => (
25
+ <ThemeProvider>
26
+ <Story />
27
+ </ThemeProvider>
28
+ ));
29
+
30
+ export default {
31
+ decorators: [ThemeDecorator],
32
+ };
33
+ ```
34
+
35
+ ### CSF Format
36
+
37
+ Use **CSF 3** for SolidJS. CSF Factories (Storybook 10's new format) are React-only as of 10.3.
38
+
39
+ ## Writing Stories (CSF 3)
40
+
41
+ ```typescript
42
+ // Button.stories.tsx
43
+ import type { Meta, StoryObj } from "storybook-solidjs";
44
+ import { Button } from "./Button";
45
+
46
+ const meta = {
47
+ title: "Components/Button",
48
+ component: Button,
49
+ tags: ["autodocs"],
50
+ argTypes: {
51
+ variant: {
52
+ control: "select",
53
+ options: ["primary", "secondary", "ghost"],
54
+ },
55
+ size: {
56
+ control: "radio",
57
+ options: ["sm", "md", "lg"],
58
+ },
59
+ },
60
+ } satisfies Meta<typeof Button>;
61
+
62
+ export default meta;
63
+ type Story = StoryObj<typeof meta>;
64
+
65
+ export const Primary: Story = {
66
+ args: {
67
+ variant: "primary",
68
+ children: "Click me",
69
+ },
70
+ };
71
+
72
+ export const Loading: Story = {
73
+ args: {
74
+ variant: "primary",
75
+ loading: true,
76
+ children: "Submitting...",
77
+ },
78
+ };
79
+
80
+ export const Disabled: Story = {
81
+ args: {
82
+ variant: "primary",
83
+ disabled: true,
84
+ children: "Unavailable",
85
+ },
86
+ };
87
+ ```
88
+
89
+ ### Story Coverage Checklist
90
+
91
+ Every component should have stories covering:
92
+
93
+ - All visual states (default, hover, focus, active, disabled, loading, error, empty, success)
94
+ - Viewport sizes (mobile, tablet, desktop) where layout differs
95
+ - Theme variants (light/dark) if applicable
96
+ - Edge cases (long text, missing data, boundary values)
97
+
98
+ ## Interaction Testing with Play Functions
99
+
100
+ Play functions turn stories into executable tests. Import everything from `@storybook/test` (instrumented versions of Testing Library + Vitest utilities):
101
+
102
+ ```typescript
103
+ import { expect, fn, userEvent, within, waitFor } from "@storybook/test";
104
+
105
+ export const SubmitForm: Story = {
106
+ args: {
107
+ onSubmit: fn(), // Storybook-instrumented spy
108
+ },
109
+ play: async ({ canvasElement, args, step }) => {
110
+ const canvas = within(canvasElement);
111
+
112
+ await step("Fill in the form", async () => {
113
+ await userEvent.type(canvas.getByLabelText("Email"), "user@example.com");
114
+ await userEvent.type(canvas.getByLabelText("Password"), "secret123");
115
+ });
116
+
117
+ await step("Submit the form", async () => {
118
+ await userEvent.click(canvas.getByRole("button", { name: "Sign in" }));
119
+ });
120
+
121
+ await step("Verify submission", async () => {
122
+ await expect(args.onSubmit).toHaveBeenCalledOnce();
123
+ await expect(args.onSubmit).toHaveBeenCalledWith({
124
+ email: "user@example.com",
125
+ password: "secret123",
126
+ });
127
+ });
128
+ },
129
+ };
130
+ ```
131
+
132
+ ### Key Rules
133
+
134
+ 1. **Always `await` expect calls.** This enables proper logging in the Interactions panel.
135
+ 2. **Use `step()` to organize** complex interactions into labeled groups.
136
+ 3. **Use `fn()` for spying.** Storybook auto-restores mocks between stories.
137
+ 4. **Never import from `@testing-library/dom` directly.** Use `@storybook/test` for instrumented versions.
138
+
139
+ ## Running Stories as Tests in CI
140
+
141
+ The **Vitest addon** (`@storybook/addon-vitest`) replaces the old `@storybook/test-runner`. It transforms stories into real Vitest tests via a plugin, running in browser mode with Playwright.
142
+
143
+ ### Advantages Over the Old Test Runner
144
+
145
+ - Does not need a running Storybook instance
146
+ - Uses Vitest browser mode (real Chromium) for accurate rendering
147
+ - Results appear alongside your Vitest unit tests
148
+ - Faster execution, simpler architecture
149
+
150
+ ### Configuration (Vitest 4.x)
151
+
152
+ Use a separate test project:
153
+
154
+ ```typescript
155
+ // vitest.config.storybook.ts
156
+ import { defineConfig } from "vitest/config";
157
+ import { storybookTest } from "@storybook/addon-vitest/vitest-plugin";
158
+
159
+ export default defineConfig({
160
+ plugins: [storybookTest()],
161
+ test: {
162
+ name: "storybook",
163
+ browser: {
164
+ enabled: true,
165
+ provider: "playwright",
166
+ instances: [{ browser: "chromium" }],
167
+ },
168
+ setupFiles: [".storybook/vitest.setup.ts"],
169
+ },
170
+ });
171
+ ```
172
+
173
+ ```json
174
+ {
175
+ "scripts": {
176
+ "test:storybook": "vitest --project storybook"
177
+ }
178
+ }
179
+ ```
180
+
181
+ ## Accessibility Testing
182
+
183
+ Storybook's a11y integration (built on axe-core) catches ~57% of WCAG issues automatically.
184
+
185
+ ### Global Configuration
186
+
187
+ ```typescript
188
+ // .storybook/preview.ts
189
+ export default {
190
+ parameters: {
191
+ a11y: {
192
+ test: "error", // "off" | "todo" | "error"
193
+ },
194
+ },
195
+ tags: ["a11y-test"],
196
+ };
197
+ ```
198
+
199
+ - **`"error"`**: Fail in CI on any violation.
200
+ - **`"todo"`**: Log violations without failing (for gradual adoption).
201
+ - **`"off"`**: Disable for specific stories.
202
+
203
+ ### Per-Story Overrides
204
+
205
+ ```typescript
206
+ export const CustomA11y: Story = {
207
+ parameters: {
208
+ a11y: {
209
+ config: {
210
+ rules: [
211
+ { id: "color-contrast", enabled: true },
212
+ ],
213
+ },
214
+ },
215
+ },
216
+ };
217
+ ```
218
+
219
+ ## Visual Regression Testing
220
+
221
+ ### Chromatic (by Storybook Team)
222
+
223
+ - Cloud service that captures screenshots of every story
224
+ - Pixel-perfect diffing across Chrome, Firefox, Safari, Edge
225
+ - Manages baselines across branches and team members
226
+ - Free tier available; paid for scale
227
+
228
+ ### Integration
229
+
230
+ ```bash
231
+ bunx chromatic --project-token=<token>
232
+ ```
233
+
234
+ Add to CI as a quality gate after `test:storybook` passes.
235
+
236
+ ## MSW for API-Dependent Components
237
+
238
+ ### Global Setup
239
+
240
+ ```typescript
241
+ // .storybook/preview.ts
242
+ import { initialize, mswLoader } from "msw-storybook-addon";
243
+
244
+ initialize();
245
+
246
+ export default {
247
+ loaders: [mswLoader],
248
+ };
249
+ ```
250
+
251
+ ### Per-Story Handlers
252
+
253
+ ```typescript
254
+ import { http, HttpResponse } from "msw";
255
+
256
+ export const WithUserData: Story = {
257
+ parameters: {
258
+ msw: {
259
+ handlers: [
260
+ http.get("/api/user", () =>
261
+ HttpResponse.json({ name: "Alice", email: "alice@example.com" })
262
+ ),
263
+ ],
264
+ },
265
+ },
266
+ };
267
+
268
+ export const WithError: Story = {
269
+ parameters: {
270
+ msw: {
271
+ handlers: [
272
+ http.get("/api/user", () =>
273
+ new HttpResponse(null, { status: 500 })
274
+ ),
275
+ ],
276
+ },
277
+ },
278
+ };
279
+ ```
280
+
281
+ ### Best Practices
282
+
283
+ - Keep "success" handlers in a shared `mocks/handlers.ts` module
284
+ - Override with error/edge-case handlers at the story level
285
+ - Configure MSW to error on unhandled requests
286
+
287
+ ### Module Mocking (Storybook 10)
288
+
289
+ Storybook 10 introduced `sb.mock` for module-level mocking (services, utilities). Register in `.storybook/preview.ts` only:
290
+
291
+ ```typescript
292
+ // .storybook/preview.ts
293
+ import { sb } from "@storybook/test";
294
+
295
+ sb.mock("../src/api/client", () => ({
296
+ fetchUser: async () => ({ name: "Mock User" }),
297
+ }));
298
+ ```
299
+
300
+ MSW remains the right tool for network-level mocking; `sb.mock` is for internal module replacement.
301
+
302
+ ## Portable Stories
303
+
304
+ Reuse Storybook stories in your existing Vitest tests with `composeStories`:
305
+
306
+ ```typescript
307
+ // Button.test.tsx
308
+ import { composeStories } from "storybook-solidjs";
309
+ import * as stories from "./Button.stories";
310
+ import { render } from "@solidjs/testing-library";
311
+
312
+ const { Primary, Loading, Disabled } = composeStories(stories);
313
+
314
+ test("renders primary button", () => {
315
+ const { getByRole } = render(() => <Primary />);
316
+ expect(getByRole("button")).toBeInTheDocument();
317
+ });
318
+
319
+ test("can override args in test", () => {
320
+ const { getByRole } = render(() => <Primary children="Override" />);
321
+ expect(getByRole("button")).toHaveTextContent("Override");
322
+ });
323
+ ```
324
+
325
+ This preserves all story annotations (args, decorators, loaders, play functions) in unit tests.
326
+
327
+ ## vanilla-extract Integration
328
+
329
+ **Zero additional configuration needed.** Storybook uses your `vite.config.ts`, which already includes `@vanilla-extract/vite-plugin`. Styles compile automatically.
330
+
331
+ ### Theme Decorator
332
+
333
+ ```typescript
334
+ // .storybook/preview.ts
335
+ import { createJSXDecorator } from "storybook-solidjs";
336
+ import "../src/styles/global.css";
337
+
338
+ const withTheme = createJSXDecorator((Story) => (
339
+ <div class={themeClass}>
340
+ <Story />
341
+ </div>
342
+ ));
343
+
344
+ export default {
345
+ decorators: [withTheme],
346
+ };
347
+ ```
348
+
349
+ ## Organization at Scale
350
+
351
+ ### File Structure
352
+
353
+ Organize by feature/domain, not by component type:
354
+
355
+ ```
356
+ src/
357
+ features/
358
+ auth/
359
+ LoginForm.tsx
360
+ LoginForm.css.ts
361
+ LoginForm.stories.tsx # Co-located
362
+ LoginForm.test.tsx # Unit tests alongside
363
+ components/
364
+ Button/
365
+ Button.tsx
366
+ Button.css.ts
367
+ Button.stories.tsx
368
+ ```
369
+
370
+ ### Tags for Filtering
371
+
372
+ Use tags to control which stories run in different contexts:
373
+
374
+ ```typescript
375
+ const meta = {
376
+ tags: ["autodocs", "a11y-test", "interaction-test"],
377
+ // ...
378
+ } satisfies Meta<typeof Component>;
379
+ ```
380
+
381
+ ### Storybook Main Config
382
+
383
+ ```typescript
384
+ // .storybook/main.ts
385
+ import type { StorybookConfig } from "storybook-solidjs-vite";
386
+
387
+ const config: StorybookConfig = {
388
+ stories: ["../src/**/*.stories.@(ts|tsx)"],
389
+ framework: "storybook-solidjs-vite",
390
+ addons: [
391
+ "@storybook/addon-essentials",
392
+ "@storybook/addon-a11y",
393
+ "@storybook/addon-vitest",
394
+ ],
395
+ };
396
+
397
+ export default config;
398
+ ```
399
+
400
+ ## Component Documentation
401
+
402
+ ### Autodocs
403
+
404
+ Enable globally or per-component:
405
+
406
+ ```typescript
407
+ const meta = {
408
+ tags: ["autodocs"],
409
+ // ...
410
+ } satisfies Meta<typeof Button>;
411
+ ```
412
+
413
+ Generates prop tables from TypeScript interfaces. Add JSDoc comments on props interfaces for richer docs.
414
+
415
+ ### MDX for Custom Docs
416
+
417
+ ```mdx
418
+ {/* Button.mdx */}
419
+ import { Meta, Canvas, Controls } from "@storybook/blocks";
420
+ import * as ButtonStories from "./Button.stories";
421
+
422
+ <Meta of={ButtonStories} />
423
+
424
+ # Button
425
+
426
+ Our primary interaction element.
427
+
428
+ <Canvas of={ButtonStories.Primary} />
429
+ <Controls of={ButtonStories.Primary} />
430
+ ```
431
+
432
+ ## Anti-Patterns
433
+
434
+ | Anti-Pattern | Fix |
435
+ |---|---|
436
+ | Destructuring SolidJS props in stories | Pass props via `args`; use `createJSXDecorator` for decorators |
437
+ | Importing from `@testing-library/dom` directly | Import from `@storybook/test` for instrumented versions |
438
+ | Not awaiting `expect()` in play functions | Always `await expect(...)` |
439
+ | Hardcoding test data in stories | Use `args` and story composition |
440
+ | Giant monolithic story files | One story file per component |
441
+ | Skipping error/edge-case stories | Always include loading, error, empty, boundary states |
442
+ | Using `@storybook/test-runner` with Vite | Use `@storybook/addon-vitest` instead |
443
+ | Not resolving unhandled MSW requests | Configure MSW to error on unhandled requests |
444
+ | Using inline styles in stories | Use theme tokens and `.css.ts` files |
445
+ | Registering `sb.mock` in story files | Register in `.storybook/preview.ts` only |