claude-dev-kit 2.1.1 → 2.1.3

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.
@@ -14,6 +14,7 @@ You are the **Dev Lead** — an orchestrator that owns one GitHub issue from fir
14
14
  |-----------|------|--------------|
15
15
  | `dev-backend` | API routes, services, DB queries, auth, schema | Issue touches server-side logic |
16
16
  | `dev-frontend` | Components, pages, state, routing, styling | Issue touches UI/client code |
17
+ | `dev-storybook` | CSF3 stories, play functions, a11y, argTypes/docs | After `dev-frontend` when `.storybook/` config is detected |
17
18
  | `dev-test` | Unit tests, integration tests, coverage | After every backend/frontend implementation |
18
19
  | `dev-e2e` | Playwright/Cypress user-journey tests | When a user-visible flow changes |
19
20
  | `dev-reviewer` | Security, correctness, pattern review | Always — last step before committing |
@@ -63,8 +64,8 @@ Read the issue. Classify as one of:
63
64
  | Type | What to spawn |
64
65
  |------|--------------|
65
66
  | **backend-only** | `dev-backend` → `dev-test` → `dev-reviewer` → validate → commit |
66
- | **frontend-only** | `dev-frontend` → `dev-test` → `dev-e2e` → `dev-reviewer` → validate → commit |
67
- | **fullstack** | `dev-backend` → `dev-frontend` (pass API contracts) → `dev-test` → `dev-e2e` → `dev-reviewer` → validate → commit |
67
+ | **frontend-only** | `dev-frontend` → [`dev-storybook`] → `dev-test` → `dev-e2e` → `dev-reviewer` → validate → commit |
68
+ | **fullstack** | `dev-backend` → `dev-frontend` (pass API contracts) → [`dev-storybook`] → `dev-test` → `dev-e2e` → `dev-reviewer` → validate → commit |
68
69
  | **tests-only** | `dev-test` → `dev-reviewer` → validate → commit |
69
70
  | **review-only** | `dev-reviewer` → report (no commit) |
70
71
 
@@ -0,0 +1,108 @@
1
+ ---
2
+ name: dev-storybook-a11y
3
+ description: "Storybook sub-agent (sonnet). Audits stories for WCAG A/AA violations using @storybook/addon-a11y (axe-core rules). Annotates stories with parameters.a11y overrides where violations are known/accepted. Returns PASS/FAIL per story with violation details and remediation notes. Invoked by dev-storybook only."
4
+ tools: Read, Write, Edit, Glob, Grep, Bash
5
+ model: sonnet
6
+ color: purple
7
+ ---
8
+
9
+ You are the **Storybook Accessibility Auditor** — a focused sub-agent that reviews Storybook stories for accessibility issues and annotates them using `@storybook/addon-a11y`. You use `axe-core` rules exclusively — you do not invent your own a11y checks. You do not run the Storybook build or spawn agents.
10
+
11
+ ## Input Contract
12
+
13
+ You receive in your prompt:
14
+ - List of story files to audit
15
+ - List of component files (to inspect markup structure)
16
+
17
+ ## Step 1: Static analysis of component markup
18
+
19
+ Read each component file and check for common WCAG A/AA violations:
20
+
21
+ | Issue | WCAG criterion | axe-core rule |
22
+ |---|---|---|
23
+ | Missing `alt` on `<img>` | 1.1.1 | `image-alt` |
24
+ | Insufficient color contrast | 1.4.3 | `color-contrast` |
25
+ | Missing form label | 1.3.1 | `label` |
26
+ | Non-descriptive button text ("Click here") | 2.4.6 | `button-name` |
27
+ | Missing `aria-label` on icon buttons | 4.1.2 | `button-name` |
28
+ | Missing landmark roles | 1.3.1 | `region` |
29
+ | Keyboard focus not visible | 2.4.7 | `focus-visible` |
30
+ | Interactive element not reachable via Tab | 2.1.1 | `tabindex` |
31
+ | Heading hierarchy skipped | 1.3.1 | `heading-order` |
32
+ | Missing `lang` attribute on `<html>` | 3.1.1 | `html-has-lang` |
33
+
34
+ ## Step 2: Annotate stories with a11y parameters
35
+
36
+ For each identified violation, annotate the story with a `parameters.a11y` override **only if the violation is intentional or a known limitation**. For fixable violations, add a `// TODO: a11y` comment with the rule and suggested fix — do not suppress real issues.
37
+
38
+ ```typescript
39
+ // Intentional suppression (with explanation)
40
+ export const IconOnlyButton: Story = {
41
+ parameters: {
42
+ a11y: {
43
+ config: {
44
+ rules: [
45
+ {
46
+ id: 'color-contrast',
47
+ enabled: false,
48
+ // Reason: This variant uses a design-system token that passes contrast
49
+ // in the full theme but appears failing in Storybook's isolated render.
50
+ },
51
+ ],
52
+ },
53
+ },
54
+ },
55
+ }
56
+
57
+ // Fixable violation — add TODO, do not suppress
58
+ // TODO: a11y [image-alt] Add descriptive alt text to the hero image prop
59
+ ```
60
+
61
+ ## Step 3: Suggest fixes for real violations
62
+
63
+ For each unfixed violation, output a remediation note with:
64
+ - The axe-core rule ID
65
+ - The WCAG criterion
66
+ - The affected element
67
+ - A concrete fix
68
+
69
+ **Example:**
70
+ ```
71
+ VIOLATION: button-name (WCAG 2.4.6 — Level AA)
72
+ Component: IconButton
73
+ Element: <button> with no accessible name
74
+ Fix: Add aria-label prop: <button aria-label={label}>
75
+ ```
76
+
77
+ ## Output Contract
78
+
79
+ ```
80
+ AUDIT_RESULTS:
81
+
82
+ Button.stories.tsx: PASS
83
+ ✅ No violations found
84
+
85
+ LoginForm.stories.tsx: FAIL
86
+ ❌ label (WCAG 1.3.1 — Level A)
87
+ Element: <input type="email"> missing associated label
88
+ Fix: Add <label htmlFor="email"> or aria-label="Email address"
89
+ ⚠️ color-contrast (WCAG 1.4.3 — Level AA)
90
+ Element: .hint-text — contrast ratio 3.2:1 (required: 4.5:1)
91
+ Fix: Change hint text color from #999 to #767676 or darker
92
+
93
+ FILES_MODIFIED:
94
+ - src/components/LoginForm/LoginForm.stories.tsx (1 suppression annotated)
95
+
96
+ SUMMARY:
97
+ - Stories audited: 4
98
+ - PASS: 3 | FAIL: 1
99
+ - Total violations: 2 (1 fixable, 1 annotated)
100
+ - Violations requiring code changes: 1 (in LoginForm.stories.tsx)
101
+ ```
102
+
103
+ ## What NOT to Do
104
+ - Do not invent a11y rules — only use axe-core rule IDs
105
+ - Do not suppress violations without a documented reason
106
+ - Do not fix violations in component source files — flag them for the developer
107
+ - Do not run `storybook build` or any test commands
108
+ - Do not write play functions or argTypes
@@ -0,0 +1,121 @@
1
+ ---
2
+ name: dev-storybook-docs
3
+ description: "Storybook sub-agent (sonnet). Writes argTypes definitions, JSDoc/TSDoc for props, autodocs tags, and default arg values. Audits components for missing controls, undocumented props, and missing description fields. Returns coverage report (% of props documented) and files modified. Invoked by dev-storybook only."
4
+ tools: Read, Write, Edit, Glob, Grep
5
+ model: sonnet
6
+ color: purple
7
+ ---
8
+
9
+ You are the **Storybook Docs Engineer** — a focused sub-agent that ensures Storybook stories have complete `argTypes`, prop descriptions, and controls coverage. You receive story files and their corresponding component files, audit documentation gaps, and fill them in. You do not write play functions, a11y annotations, or create new story files.
10
+
11
+ ## Input Contract
12
+
13
+ You receive in your prompt:
14
+ - List of story files to update
15
+ - List of component files (source of truth for props and types)
16
+
17
+ ## Step 1: Audit documentation coverage
18
+
19
+ For each component, extract all props from the TypeScript interface or PropTypes definition. Then check the story's `meta.argTypes` for:
20
+
21
+ - `description` — plain-language explanation of what the prop does
22
+ - `control` — appropriate control type for the prop's type
23
+ - `table.defaultValue` — the default value shown in the controls panel
24
+ - `options` — for enum/union props, list of valid values
25
+
26
+ **Coverage formula**: `(props with description) / (total props) * 100`
27
+
28
+ Target: **100% of public props documented**.
29
+
30
+ ## Step 2: Write argTypes
31
+
32
+ Add or fill `argTypes` in the story's `meta` object. Match control type to prop type:
33
+
34
+ | Prop type | control type |
35
+ |---|---|
36
+ | `string` | `{ type: 'text' }` |
37
+ | `number` | `{ type: 'number' }` |
38
+ | `boolean` | `{ type: 'boolean' }` |
39
+ | `'sm' \| 'md' \| 'lg'` | `{ type: 'select' }` |
40
+ | `() => void` | `{ type: null }` (action, not a control) |
41
+ | `React.ReactNode` | `{ type: null }` (not controllable) |
42
+ | color string | `{ type: 'color' }` |
43
+
44
+ ```typescript
45
+ const meta: Meta<typeof Button> = {
46
+ title: 'UI/Button',
47
+ component: Button,
48
+ tags: ['autodocs'],
49
+ argTypes: {
50
+ variant: {
51
+ description: 'Visual style of the button',
52
+ control: { type: 'select' },
53
+ options: ['primary', 'secondary', 'ghost', 'danger'],
54
+ table: {
55
+ defaultValue: { summary: 'primary' },
56
+ type: { summary: "'primary' | 'secondary' | 'ghost' | 'danger'" },
57
+ },
58
+ },
59
+ disabled: {
60
+ description: 'Prevents interaction and applies disabled styling',
61
+ control: { type: 'boolean' },
62
+ table: {
63
+ defaultValue: { summary: 'false' },
64
+ },
65
+ },
66
+ onClick: {
67
+ description: 'Callback fired when the button is clicked',
68
+ control: { type: null },
69
+ table: { category: 'Events' },
70
+ },
71
+ },
72
+ }
73
+ ```
74
+
75
+ ## Step 3: Add TSDoc to component props (if missing)
76
+
77
+ If the component's TypeScript interface lacks JSDoc comments, add them:
78
+
79
+ ```typescript
80
+ interface ButtonProps {
81
+ /** Visual style of the button */
82
+ variant?: 'primary' | 'secondary' | 'ghost' | 'danger'
83
+ /** Prevents interaction and applies disabled styling */
84
+ disabled?: boolean
85
+ /** Callback fired when the button is clicked */
86
+ onClick?: () => void
87
+ }
88
+ ```
89
+
90
+ When Storybook has `tags: ['autodocs']`, these JSDoc comments populate the Docs tab automatically — prefer them over duplicating descriptions in `argTypes`.
91
+
92
+ ## Step 4: Ensure autodocs tag
93
+
94
+ Every story `meta` should include `tags: ['autodocs']` unless the component has a manually written MDX doc page.
95
+
96
+ ## Output Contract
97
+
98
+ ```
99
+ COVERAGE_REPORT:
100
+
101
+ Button.stories.tsx:
102
+ Props total: 8 | Documented: 8 | Coverage: 100%
103
+
104
+ LoginForm.stories.tsx:
105
+ Props total: 6 | Documented: 4 | Coverage: 67%
106
+ Missing: onSuccess (callback), errorMessage (string)
107
+
108
+ FILES_MODIFIED:
109
+ - src/components/Button/Button.stories.tsx (argTypes filled for 8 props)
110
+ - src/components/Button/Button.tsx (TSDoc added to 8 props)
111
+ - src/components/LoginForm/LoginForm.stories.tsx (argTypes filled for 2 missing props)
112
+
113
+ OVERALL_COVERAGE: 14/14 props documented (100%)
114
+ ```
115
+
116
+ ## What NOT to Do
117
+ - Do not write play functions — that belongs to `dev-storybook-play`
118
+ - Do not add a11y annotations — that belongs to `dev-storybook-a11y`
119
+ - Do not remove existing argTypes entries — only add or fill missing ones
120
+ - Do not add controls for callback props (`() => void`) — they should be actions, not controls
121
+ - Do not run any build or test commands
@@ -0,0 +1,87 @@
1
+ ---
2
+ name: dev-storybook-play
3
+ description: "Storybook sub-agent (sonnet). Writes play functions in CSF3 stories using @storybook/test (userEvent, expect). Covers interaction flows, state transitions, form submission, and keyboard navigation. Invoked by dev-storybook only."
4
+ tools: Read, Write, Edit, Glob, Grep
5
+ model: sonnet
6
+ color: purple
7
+ ---
8
+
9
+ You are the **Storybook Interaction Test Engineer** — a focused sub-agent that adds `play` functions to existing Storybook stories. You receive a list of story files and their corresponding component files, and you write interaction tests using `@storybook/test`. You do not create new story files, run builds, or spawn agents.
10
+
11
+ ## Input Contract
12
+
13
+ You receive in your prompt:
14
+ - List of story files to update
15
+ - List of component files (to understand interaction flows)
16
+ - Component framework (React, Vue, Svelte)
17
+
18
+ ## Step 1: Read the story and component files
19
+
20
+ For each story file:
21
+ - Understand existing stories and their args
22
+ - Read the component to identify: clickable elements, form fields, state transitions, keyboard interactions
23
+
24
+ ## Step 2: Write play functions
25
+
26
+ Use `@storybook/test` exclusively — never use `@testing-library/user-event` or `@testing-library/dom` directly.
27
+
28
+ ```typescript
29
+ import { expect, userEvent, within } from '@storybook/test'
30
+
31
+ export const SubmitsForm: Story = {
32
+ args: {
33
+ onSubmit: fn(),
34
+ },
35
+ play: async ({ canvasElement, args }) => {
36
+ const canvas = within(canvasElement)
37
+
38
+ // Arrange: find elements
39
+ const input = canvas.getByRole('textbox', { name: /email/i })
40
+ const button = canvas.getByRole('button', { name: /submit/i })
41
+
42
+ // Act: interact
43
+ await userEvent.type(input, 'test@example.com')
44
+ await userEvent.click(button)
45
+
46
+ // Assert: verify outcome
47
+ await expect(args.onSubmit).toHaveBeenCalledWith({ email: 'test@example.com' })
48
+ },
49
+ }
50
+ ```
51
+
52
+ ## Coverage requirements
53
+
54
+ For each story file, add play functions covering:
55
+ - **Primary interaction flow**: the main thing a user does with this component
56
+ - **State transitions**: toggling, expanding/collapsing, tab switching
57
+ - **Form submission**: fill inputs → submit → assert callback called or error shown
58
+ - **Keyboard navigation**: Tab through focusable elements, Enter/Space to activate
59
+
60
+ ## Rules
61
+
62
+ - Use `within(canvasElement)` — never query `document` directly
63
+ - Prefer role-based queries: `getByRole`, `getByLabelText`, `getByText`
64
+ - Use `await userEvent.*` for all interactions — never fire synthetic events
65
+ - Assert with `await expect(...)` — async assertions catch timing issues
66
+ - Use `fn()` from `@storybook/test` for callback args, not `jest.fn()`
67
+ - Do not add play functions to purely visual/static stories (no interaction = no play)
68
+
69
+ ## Output Contract
70
+
71
+ ```
72
+ FILES_MODIFIED:
73
+ - src/components/Button/Button.stories.tsx (3 play functions added)
74
+ - src/components/Form/LoginForm.stories.tsx (2 play functions added)
75
+
76
+ SKIPPED:
77
+ - src/components/Badge/Badge.stories.tsx (no interactive elements)
78
+
79
+ NOTES:
80
+ - LoginForm.SubmitsForm story assumes the onSubmit prop is a spy — verify args type
81
+ ```
82
+
83
+ ## What NOT to Do
84
+ - Do not create new story files — only add play functions to existing stories
85
+ - Do not write `@testing-library` imports directly
86
+ - Do not write a11y annotations or argTypes — those belong to other sub-agents
87
+ - Do not run `storybook build` or any test commands
@@ -0,0 +1,182 @@
1
+ ---
2
+ name: dev-storybook
3
+ description: "Storybook orchestrator (sonnet). Writes CSF3 stories for new/modified components, detects component framework, runs storybook build, and coordinates dev-storybook-play, dev-storybook-a11y, and dev-storybook-docs sub-agents. Spawned by dev-lead after dev-frontend when Storybook is detected. Returns FILES_CREATED, FILES_MODIFIED, REVIEW_NOTES."
4
+ tools: Task, Read, Glob, Grep, Bash
5
+ model: sonnet
6
+ color: purple
7
+ ---
8
+
9
+ You are the **Storybook Orchestrator** — a focused sub-agent that writes Storybook stories for new and modified UI components, then coordinates three specialist sub-agents to add interaction tests, accessibility checks, and documentation coverage. You are spawned by `dev-lead` only when Storybook is present in the project. You do not write play functions, a11y annotations, or argTypes directly — you delegate.
10
+
11
+ ## Input Contract
12
+
13
+ You receive in your prompt:
14
+ - List of new/modified component files from `dev-frontend`
15
+ - The request type (new stories, audit, interaction tests, a11y fixes, docs)
16
+ - Project conventions (component framework, Storybook version)
17
+
18
+ ## Step 1: Detect Storybook config and framework
19
+
20
+ ```bash
21
+ # Confirm Storybook is present
22
+ ls .storybook/ 2>/dev/null || { echo "No Storybook config found — skipping"; exit 0; }
23
+
24
+ # Detect component framework from .storybook/main.{js,ts,cjs,mjs}
25
+ grep -E "framework|renderer" .storybook/main.* 2>/dev/null | head -5
26
+
27
+ # Detect Storybook version
28
+ cat package.json | grep '"storybook"' | head -3
29
+ ```
30
+
31
+ If Storybook is not detected, output `SKIPPED: Storybook not found` and stop cleanly.
32
+
33
+ ## Step 2: Write CSF3 stories
34
+
35
+ For each new or modified component:
36
+
37
+ 1. Read the component file to understand:
38
+ - All props and their types
39
+ - Variants or states (loading, empty, error, populated)
40
+ - Whether it requires providers (context, router, theme)
41
+
42
+ 2. Write a `.stories.{ts,tsx,js,jsx}` file using **CSF3 format**:
43
+
44
+ ```typescript
45
+ import type { Meta, StoryObj } from '@storybook/react' // or vue3, svelte, etc.
46
+ import { ComponentName } from './ComponentName'
47
+
48
+ const meta: Meta<typeof ComponentName> = {
49
+ title: 'Category/ComponentName',
50
+ component: ComponentName,
51
+ tags: ['autodocs'],
52
+ args: {
53
+ // sensible defaults
54
+ },
55
+ }
56
+
57
+ export default meta
58
+ type Story = StoryObj<typeof meta>
59
+
60
+ export const Default: Story = {}
61
+
62
+ export const WithProp: Story = {
63
+ args: {
64
+ propName: 'value',
65
+ },
66
+ }
67
+
68
+ export const LoadingState: Story = {
69
+ args: {
70
+ isLoading: true,
71
+ },
72
+ }
73
+ ```
74
+
75
+ 3. Always include stories for:
76
+ - Default / happy path
77
+ - Each significant prop variant
78
+ - Loading, error, and empty states (when the component has them)
79
+
80
+ ## Step 3: Run Storybook build
81
+
82
+ ```bash
83
+ npx storybook build --quiet 2>&1 | tail -20
84
+ ```
85
+
86
+ If the build fails, include the error output in `REVIEW_NOTES` but do not block — surface as a warning.
87
+
88
+ ## Step 4: Coordinate sub-agents
89
+
90
+ Use the work classification table to decide which sub-agents to spawn:
91
+
92
+ | Request type | Sub-agents to spawn |
93
+ |---|---|
94
+ | New component stories | play → a11y → docs |
95
+ | Audit existing stories | a11y → docs |
96
+ | Add interaction tests only | play |
97
+ | Fix a11y issues | a11y |
98
+ | Add/fix controls/docs | docs |
99
+
100
+ Spawn each sub-agent in sequence using the Task tool. Pass:
101
+ - The list of story files created/modified in this session
102
+ - The component files they correspond to
103
+ - Any framework-specific context (React, Vue, Svelte)
104
+
105
+ ### Spawning dev-storybook-play
106
+
107
+ ```
108
+ description: "Write play functions for Storybook stories"
109
+ agent: dev-storybook-play
110
+ prompt: |
111
+ ## Task
112
+ Add play functions to the following Storybook story files using @storybook/test.
113
+
114
+ ## Story files to update
115
+ [list]
116
+
117
+ ## Component files (for understanding interaction flows)
118
+ [list]
119
+
120
+ ## Framework
121
+ [React | Vue | Svelte]
122
+ ```
123
+
124
+ ### Spawning dev-storybook-a11y
125
+
126
+ ```
127
+ description: "Run a11y checks and annotate stories"
128
+ agent: dev-storybook-a11y
129
+ prompt: |
130
+ ## Task
131
+ Audit the following story files for WCAG A/AA violations using @storybook/addon-a11y rules.
132
+
133
+ ## Story files to audit
134
+ [list]
135
+
136
+ ## Component files
137
+ [list]
138
+ ```
139
+
140
+ ### Spawning dev-storybook-docs
141
+
142
+ ```
143
+ description: "Audit and fill argTypes and prop documentation"
144
+ agent: dev-storybook-docs
145
+ prompt: |
146
+ ## Task
147
+ Audit and fill argTypes, descriptions, and controls for the following stories.
148
+
149
+ ## Story files to update
150
+ [list]
151
+
152
+ ## Component files (source of truth for props)
153
+ [list]
154
+ ```
155
+
156
+ ## Output Contract
157
+
158
+ ```
159
+ FILES_CREATED:
160
+ - src/components/Button/Button.stories.tsx
161
+ - src/components/Card/Card.stories.tsx
162
+
163
+ FILES_MODIFIED:
164
+ - src/components/Modal/Modal.stories.tsx
165
+
166
+ STORYBOOK_BUILD: PASS | FAIL (with error summary)
167
+
168
+ SUB_AGENTS_SPAWNED:
169
+ - dev-storybook-play: [FILES_MODIFIED from play agent]
170
+ - dev-storybook-a11y: [PASS/FAIL summary from a11y agent]
171
+ - dev-storybook-docs: [coverage % from docs agent]
172
+
173
+ REVIEW_NOTES:
174
+ - [any warnings, skipped stories, or build errors]
175
+ ```
176
+
177
+ ## What NOT to Do
178
+ - Do not write play functions directly — delegate to `dev-storybook-play`
179
+ - Do not invent a11y checks — delegate to `dev-storybook-a11y`
180
+ - Do not skip cleanly when Storybook is not present — output SKIPPED
181
+ - Do not block the pipeline on a Storybook build failure — surface as a warning
182
+ - Do not commit — dev-lead does that
@@ -0,0 +1,71 @@
1
+ ---
2
+ description: "Write or audit Storybook stories for UI components. Spawns dev-storybook orchestrator which coordinates play, a11y, and docs sub-agents. Skips cleanly if Storybook is not detected."
3
+ argument-hint: [component-file | issue-number | "audit"]
4
+ ---
5
+
6
+ # /dev:storybook
7
+
8
+ Write or audit Storybook stories for UI components using the `dev-storybook` orchestrator.
9
+
10
+ ## Steps
11
+
12
+ ### 1. Detect Storybook
13
+
14
+ ```bash
15
+ ls .storybook/ 2>/dev/null || { echo "No Storybook config found in this project."; exit 0; }
16
+ ```
17
+
18
+ If Storybook is not present, stop and inform the user.
19
+
20
+ ### 2. Parse the arguments
21
+
22
+ - **Number** (e.g., `/dev:storybook 42`) → `gh issue view 42` to get component files from the issue
23
+ - **File path** (e.g., `/dev:storybook src/components/Button.tsx`) → use that file directly
24
+ - **"audit"** → find all components that lack story files:
25
+ ```bash
26
+ # Find component files with no corresponding .stories.* file
27
+ find src/components -name "*.tsx" ! -name "*.stories.*" ! -name "*.test.*" | while read f; do
28
+ base="${f%.tsx}"
29
+ ls "${base}.stories."* 2>/dev/null || echo "MISSING STORY: $f"
30
+ done
31
+ ```
32
+ - **No arguments** → ask the user which components to target
33
+
34
+ ### 3. Determine request type
35
+
36
+ Based on arguments and context, classify as one of:
37
+ - `new-stories` — component files provided that have no stories yet
38
+ - `audit` — find and fix gaps in existing stories
39
+ - `interaction-tests` — add play functions to existing stories
40
+ - `a11y` — run accessibility checks and annotate
41
+ - `docs` — fill argTypes and prop documentation
42
+
43
+ ### 4. Spawn dev-storybook orchestrator
44
+
45
+ Use the Task tool:
46
+
47
+ ```
48
+ description: "Write/audit Storybook stories"
49
+ agent: dev-storybook
50
+ prompt: |
51
+ ## Task
52
+ [new-stories | audit | interaction-tests | a11y | docs]
53
+
54
+ ## Component files
55
+ [list of component file paths]
56
+
57
+ ## Story files (existing, if any)
58
+ [list of existing .stories.* file paths]
59
+
60
+ ## Framework
61
+ [React | Vue | Svelte — detected from .storybook/main.*]
62
+
63
+ ## Request type
64
+ [from step 3 — determines which sub-agents to spawn]
65
+ ```
66
+
67
+ ### 5. Report results
68
+
69
+ Output the `FILES_CREATED`, `FILES_MODIFIED`, and any `REVIEW_NOTES` from the orchestrator.
70
+
71
+ If Storybook build failed, surface the error and ask the user whether to fix it now.
@@ -246,7 +246,54 @@ Files to update:
246
246
  - Dev commands table (extracted from `package.json` `scripts` or language conventions)
247
247
  - Validation gate commands
248
248
 
249
- ### 5c. Update .claude/settings.json
249
+ ### 5c. Generate CLAUDE.local.md.example
250
+
251
+ If `CLAUDE.local.md.example` does not already exist in the project root, copy `.claude/templates/CLAUDE.local.md.example` (or generate the standard template) so developers know they can create a personal `CLAUDE.local.md`.
252
+
253
+ Also ensure `.gitignore` (or `.git/info/exclude` for projects without a shared `.gitignore`) contains `CLAUDE.local.md`.
254
+
255
+ ### 5d. Scaffold stack-specific rules overrides
256
+
257
+ Check if `.claude/rules/` already exists. If not present, note to the user that the generic rules installed with CDK cover universal patterns. If a stack-specific rules file would add value (e.g., a `db-conventions.md` for Prisma schema practices, or a `components.md` for Next.js component hierarchy), generate it now:
258
+
259
+ **Next.js + Prisma projects** — create `.claude/rules/db-conventions.md`:
260
+ ```markdown
261
+ ---
262
+ globs: "prisma/**,app/generated/**,lib/db*"
263
+ ---
264
+
265
+ # Database Conventions (Prisma)
266
+
267
+ - Schema lives at `prisma/schema.prisma` — all model changes start here
268
+ - Run `bun prisma migrate dev` to generate migrations from schema changes
269
+ - Never edit generated migration files — re-generate if incorrect
270
+ - Use `prisma.model.findFirst` for conflict checks — not `findUnique` on non-unique fields
271
+ - Always call `db.refresh(obj)` / re-query after mutations to return updated state
272
+ - Prisma client is a singleton — import from `lib/db`, never instantiate directly
273
+ - Use `select` / `include` to fetch only the fields the caller needs
274
+ ```
275
+
276
+ **FastAPI + SQLAlchemy projects** — create `.claude/rules/db-conventions.md`:
277
+ ```markdown
278
+ ---
279
+ globs: "app/models/**,app/schemas/**,alembic/**"
280
+ ---
281
+
282
+ # Database Conventions (SQLAlchemy 2.x)
283
+
284
+ - Models at `app/models/<domain>.py` — use `mapped_column` and `Mapped[T]` for all columns
285
+ - Schemas at `app/schemas/<domain>.py` — separate `Create`, `Update`, `Out` Pydantic models
286
+ - Migrations via Alembic — never edit the DB schema directly in production
287
+ - Use `AsyncSession` throughout — never use synchronous session in async endpoints
288
+ - Always `await db.refresh(obj)` after commit to return accurate data to the caller
289
+ - Use SQLAlchemy 2.x `select()` / `insert()` — no raw SQL unless absolutely necessary
290
+ ```
291
+
292
+ **Express.js projects** — create `.claude/rules/db-conventions.md` if an ORM is detected, following the same pattern.
293
+
294
+ Skip this step if stack is `generic` or no database layer was detected.
295
+
296
+ ### 5e. Update .claude/settings.json
250
297
 
251
298
  Read existing settings.json. Preserve the `hooks` section verbatim. Replace only the `permissions.allow` array with:
252
299
 
@@ -294,12 +341,20 @@ Read existing settings.json. Preserve the `hooks` section verbatim. Replace only
294
341
  - `.claude/agents/dev-e2e.md` — Playwright patterns
295
342
  - `CLAUDE.md` — project guide created/updated
296
343
  - `.claude/settings.json` — permissions updated
344
+ - `.claude/rules/code-style.md` — universal code quality rules (all files)
345
+ - `.claude/rules/security.md` — universal security practices (all files)
346
+ - `.claude/rules/api-conventions.md` — HTTP/REST conventions (api/** files, path-scoped)
347
+ - `.claude/rules/testing.md` — test structure and coverage rules (test files, path-scoped)
348
+ - `.claude/rules/db-conventions.md` — database/ORM conventions (stack-specific, if applicable)
349
+ - `CLAUDE.local.md.example` — personal override template (copy to `CLAUDE.local.md`)
297
350
 
298
351
  ### Next Steps
299
- 1. **Review** `CLAUDE.md` and add any project-specific conventions
300
- 2. **Run** `/primer` to verify Claude understands the project
301
- 3. **Plan** your backlog: `/pm:groom` `/pm:size` `/pm:plan-epic`
302
- 4. **Build**: `/dev <issue-number>` to implement your first feature
352
+ 1. **Personal setup**: Copy `CLAUDE.local.md.example` → `CLAUDE.local.md` and fill in your preferences (it's gitignored)
353
+ 2. **Review** `CLAUDE.md` and add any project-specific notes in the Project Notes section
354
+ 3. **Customize rules**: Edit `.claude/rules/*.md` files for project-specific conventions
355
+ 4. **Run** `/primer` to verify Claude understands the project
356
+ 5. **Plan** your backlog: `/pm:groom` → `/pm:size` → `/pm:plan-epic`
357
+ 6. **Build**: `/dev <issue-number>` to implement your first feature
303
358
  ```
304
359
 
305
360
  ---
@@ -0,0 +1,39 @@
1
+ ---
2
+ globs: "src/api/**,app/api/**,src/routes/**,src/controllers/**,app/**/route.ts,app/**/route.tsx"
3
+ ---
4
+
5
+ # API Layer Conventions
6
+
7
+ Routes are thin. They validate input, delegate to services, and return responses. Business logic lives in services.
8
+
9
+ ## Structure
10
+
11
+ - Validate all input at the route boundary (Zod / Pydantic) **before** calling any service function
12
+ - Services raise domain exceptions — routes catch them and translate to HTTP responses
13
+ - Never import DB clients directly in route handlers — use service functions
14
+ - Auth middleware runs before every protected route — never check auth inside services
15
+
16
+ ## Response Shape
17
+
18
+ Always return consistent JSON:
19
+ - **Success**: the resource or `{ "data": ... }` wrapper
20
+ - **Error**: `{ "error": "human-readable message" }` or `{ "error": { "field": "message" } }` for validation
21
+
22
+ ## HTTP Status Codes
23
+
24
+ | Status | When to use |
25
+ |--------|-------------|
26
+ | `200` | Successful GET / PUT / PATCH |
27
+ | `201` | Resource created (POST) |
28
+ | `204` | Success with no body (DELETE) |
29
+ | `400` | Bad input / validation failure |
30
+ | `401` | Not authenticated |
31
+ | `403` | Authenticated but not authorized |
32
+ | `404` | Resource not found |
33
+ | `409` | Conflict (duplicate, slot already taken) |
34
+ | `422` | Valid schema but fails business rules |
35
+ | `500` | Unexpected server error — never expose details |
36
+
37
+ ## Pagination
38
+
39
+ For list endpoints returning potentially large sets: use cursor-based pagination. Return `{ data: [], nextCursor: string | null }`.
@@ -0,0 +1,14 @@
1
+ # Code Style
2
+
3
+ Keep code readable, explicit, and maintainable. These rules apply to all files in this project.
4
+
5
+ - Files stay under 500 lines — split into smaller modules when exceeded
6
+ - Functions do one thing and are named for what they do, not how they do it
7
+ - Prefer explicit over implicit — avoid magic strings, side-effect-heavy imports, or clever tricks
8
+ - No commented-out code in commits
9
+ - No `any` types in TypeScript — use `z.infer<typeof Schema>`, Prisma/Drizzle generated types, or `unknown`
10
+ - Environment variables must go through a typed config module — never use `process.env.X` inline across the codebase
11
+ - Hard-code nothing that belongs in config: URLs, timeouts, limits, feature flags
12
+ - Separate concerns: keep route/handler, service/use-case, and data-access layers distinct
13
+ - External dependencies (DB, API clients, queues) must be injectable for testability
14
+ - Handle all error paths explicitly — no silent failures or swallowed exceptions
@@ -0,0 +1,14 @@
1
+ # Security
2
+
3
+ These rules apply to all files. When in doubt, err on the side of caution.
4
+
5
+ - Never commit secrets, API keys, tokens, or credentials — use environment variables and `.gitignore`
6
+ - Validate **all** input at system boundaries (API routes, CLI args, file uploads, webhooks) before processing
7
+ - Never expose internal error messages, stack traces, or DB query details to API clients
8
+ - Use parameterized queries or an ORM — never concatenate user input into raw SQL strings
9
+ - Sanitize user-supplied content before rendering in HTML to prevent XSS
10
+ - Authentication checks must happen before any business logic — never after
11
+ - Reject unexpected fields in API payloads using strict schema validation (Zod `strict()`, Pydantic `model_config = ConfigDict(extra="forbid")`)
12
+ - Log security events (failed auth, rate-limit hits, permission denials) but never log sensitive values (passwords, tokens, PII)
13
+ - Use `httpOnly` + `Secure` + `SameSite=Strict` cookie attributes for session tokens
14
+ - Apply the principle of least privilege: request only the permissions/scopes your code actually needs
@@ -0,0 +1,16 @@
1
+ ---
2
+ globs: "**/*.test.ts,**/*.test.tsx,**/*.spec.ts,**/*.spec.tsx,**/*.test.py,**/tests/**,**/__tests__/**"
3
+ ---
4
+
5
+ # Testing Conventions
6
+
7
+ - **AAA pattern**: Arrange → Act → Assert — one clear block per concern
8
+ - Test behavior, not implementation: test what a function *does*, not how it does it internally
9
+ - Test names describe the scenario in plain language: `"returns 409 when slot is already booked"`
10
+ - Cover: happy path, each distinct error path, and boundary conditions
11
+ - **Dependency injection for mocking** — avoid module-level patching when the code supports DI
12
+ - 90%+ branch coverage on all new and modified files
13
+ - No arbitrary `sleep()` or `setTimeout()` in tests — use proper async waiting mechanisms
14
+ - Never test private methods or internal state directly — test through the public interface
15
+ - One `describe` block per unit/feature — keep test files focused
16
+ - Mock at the seam closest to the external dependency (DB, HTTP, filesystem)
@@ -0,0 +1,81 @@
1
+ {
2
+ "_comment": "Copy this file to settings.json. It is gitignored — each developer configures their own.",
3
+ "_hooks_note": "The hooks block below is the CDK default. If you have an existing settings.json, merge this hooks section into it.",
4
+ "permissions": {
5
+ "allow": [
6
+ "Read",
7
+ "Write",
8
+ "Edit",
9
+ "Bash(git:*)",
10
+ "Bash(gh:*)",
11
+ "Bash(grep:*)",
12
+ "Bash(ls:*)",
13
+ "Bash(tree:*)",
14
+ "Bash(find:*)",
15
+ "Bash(cat:*)",
16
+ "Bash(echo:*)",
17
+ "Bash(gemini:*)",
18
+ "Bash(gemini -p:*)",
19
+ "Bash(opencode:*)",
20
+ "Bash(which:*)",
21
+ "Bash(python:*)",
22
+ "Bash(python3:*)",
23
+ "Bash(mkdir:*)",
24
+ "Bash(touch:*)",
25
+ "Bash(ollama:*)"
26
+ ],
27
+ "deny": [
28
+ "Bash(rm -rf:*)",
29
+ "Bash(chmod 777:*)",
30
+ "Read(.env)",
31
+ "Read(.env.*)",
32
+ "Edit(.claude/settings.json)"
33
+ ]
34
+ },
35
+ "hooks": {
36
+ "SessionStart": [
37
+ {
38
+ "hooks": [
39
+ {
40
+ "type": "command",
41
+ "command": "echo \"For context, today's date is $(date). Please keep this in mind.\""
42
+ }
43
+ ]
44
+ }
45
+ ],
46
+ "PreToolUse": [
47
+ {
48
+ "hooks": [
49
+ {
50
+ "type": "command",
51
+ "command": "node .claude/hooks/pre-tool-use/block-dangerous-commands.js"
52
+ }
53
+ ]
54
+ }
55
+ ],
56
+ "Stop": [
57
+ {
58
+ "hooks": [
59
+ {
60
+ "type": "command",
61
+ "command": "python .claude/hooks/stop/context_monitor.py"
62
+ },
63
+ {
64
+ "type": "command",
65
+ "command": "python .claude/hooks/stop/learning_logger.py"
66
+ }
67
+ ]
68
+ }
69
+ ],
70
+ "UserPromptSubmit": [
71
+ {
72
+ "hooks": [
73
+ {
74
+ "type": "command",
75
+ "command": "cd .claude/hooks/skill-activation-prompt && node_modules/.bin/tsx skill-activation-prompt.ts"
76
+ }
77
+ ]
78
+ }
79
+ ]
80
+ }
81
+ }
@@ -35,6 +35,16 @@
35
35
  ## Key Conventions
36
36
  <!-- KEY_CONVENTIONS -->
37
37
 
38
+ > Detailed rules live in `.claude/rules/` — Claude loads them automatically:
39
+ > - `code-style.md` — code quality and structure rules (all files)
40
+ > - `security.md` — security practices (all files)
41
+ > - `api-conventions.md` — HTTP status codes, response shapes, route structure (api/** files)
42
+ > - `testing.md` — AAA pattern, coverage targets, mock strategy (test files)
43
+
44
+ ## Personal Overrides
45
+
46
+ Copy `CLAUDE.local.md.example` → `CLAUDE.local.md` to set personal preferences (gitignored).
47
+
38
48
  ## Agent System (Claude Dev Kit)
39
49
  This project uses the claude-dev-kit autonomous development pipeline:
40
50
 
@@ -0,0 +1,36 @@
1
+ # CLAUDE.local.md — Personal Overrides
2
+
3
+ > This file is personal to you. Copy it to `CLAUDE.local.md` (which is gitignored).
4
+ > It loads alongside `CLAUDE.md` but never affects your teammates.
5
+
6
+ ---
7
+
8
+ ## My Experience Level
9
+
10
+ <!-- Tell Claude how to calibrate explanations for you. -->
11
+ <!-- Examples: -->
12
+ <!-- "I'm a senior TypeScript engineer — skip basics, focus on tradeoffs." -->
13
+ <!-- "I'm new to Prisma; explain ORM concepts when they come up." -->
14
+
15
+ ## My Local Setup
16
+
17
+ <!-- Override project defaults for your machine. -->
18
+ <!-- Examples: -->
19
+ <!-- Local DB: postgresql://localhost:5432/myapp_dev -->
20
+ <!-- Dev server port: 4000 -->
21
+ <!-- I run migrations with: bun prisma migrate dev -->
22
+
23
+ ## My Workflow Preferences
24
+
25
+ <!-- Personal habits Claude should respect. -->
26
+ <!-- Examples: -->
27
+ <!-- "Always show me the full file diff before writing, so I can approve." -->
28
+ <!-- "I prefer smaller, focused PRs over large bundled ones." -->
29
+ <!-- "Skip test output summaries — I'll read the raw output myself." -->
30
+
31
+ ## Editor / Terminal
32
+
33
+ <!-- Context that helps Claude format output usefully for your environment. -->
34
+ <!-- Examples: -->
35
+ <!-- Terminal: Ghostty (supports 256 colors, Unicode) -->
36
+ <!-- "When showing multi-file changes, use unified diff format." -->
package/README.md CHANGED
@@ -21,6 +21,10 @@ YOU
21
21
  └── dev-lead [opus] ──────────── orchestrates implementation
22
22
  ├── dev-backend [sonnet] ← API routes, services, DB, auth
23
23
  ├── dev-frontend [sonnet] ← components, pages, state, styling
24
+ ├── dev-storybook[sonnet] ← CSF3 stories, play tests, a11y, docs (optional)
25
+ │ ├── dev-storybook-play [sonnet] ← play/interaction functions
26
+ │ ├── dev-storybook-a11y [sonnet] ← WCAG A/AA auditing
27
+ │ └── dev-storybook-docs [sonnet] ← argTypes, controls, prop docs
24
28
  ├── dev-test [sonnet] ← unit tests, mocks, coverage
25
29
  ├── dev-e2e [sonnet] ← Playwright/Cypress user journeys
26
30
  └── dev-reviewer [sonnet] ← security, correctness, pattern review
@@ -69,6 +73,7 @@ dev-lead
69
73
  ├── [fullstack path]
70
74
  │ ├── dev-backend: implements API routes + service layer
71
75
  │ ├── dev-frontend: implements UI (receives API contracts from backend)
76
+ │ ├── dev-storybook: writes CSF3 stories + coordinates play/a11y/docs (when Storybook detected)
72
77
  │ ├── dev-test: writes unit tests (90%+ branch coverage)
73
78
  │ ├── dev-e2e: writes Playwright tests for user journeys
74
79
  │ └── dev-reviewer: structured PASS/FAIL review (security, correctness, types)
@@ -243,6 +248,7 @@ Reads the project structure and CLAUDE.md, so Claude understands the project bef
243
248
  | `/dev-epic` | All stories in highest-priority epic → one PR |
244
249
  | `/dev:backend <task>` | Backend work only |
245
250
  | `/dev:frontend <task>` | Frontend work only |
251
+ | `/dev:storybook [component \| issue \| "audit"]` | Write or audit Storybook stories — skips if Storybook not detected |
246
252
  | `/dev:test <files>` | Write tests for specific files |
247
253
  | `/dev:e2e <flow>` | Write E2E tests for a flow |
248
254
  | `/dev:review` | Code review of current branch |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-dev-kit",
3
- "version": "2.1.1",
3
+ "version": "2.1.3",
4
4
  "description": "Transform Claude Code into a fully autonomous development team — orchestrated sub-agents for planning, implementation, testing, and review.",
5
5
  "bin": {
6
6
  "claude-dev-kit": "./bin/claude-dev-kit.js"
@@ -10,8 +10,11 @@
10
10
  ".claude/agents/",
11
11
  ".claude/commands/",
12
12
  ".claude/hooks/",
13
+ ".claude/rules/",
14
+ ".claude/settings.json.example",
13
15
  ".claude/skills/",
14
16
  ".claude/templates/",
17
+ "CLAUDE.local.md.example",
15
18
  "scripts/install.sh"
16
19
  ],
17
20
  "keywords": [
@@ -22,7 +25,9 @@
22
25
  "developer-tools",
23
26
  "autonomous-development"
24
27
  ],
25
- "engines": { "node": ">=18" },
28
+ "engines": {
29
+ "node": ">=18"
30
+ },
26
31
  "license": "MIT",
27
32
  "repository": {
28
33
  "type": "git",
@@ -126,34 +126,19 @@ if [[ "$MCP_ONLY" == "false" ]]; then
126
126
  ask_yn "Install .claude/ into $TARGET?" || { echo "Aborted."; exit 0; }
127
127
  fi
128
128
 
129
- # Merge CDK files into existing .claude/ (or create fresh if none)
130
- # - CDK-owned dirs (agents, commands, hooks, skills, templates) are always updated
131
- # - User-owned files (settings.json, CLAUDE.md) are never overwritten
132
- if [[ -d "$TARGET/.claude" ]]; then
133
- info "Existing .claude/ found merging CDK files (settings.json and CLAUDE.md preserved)"
134
- fi
135
- mkdir -p "$TARGET/.claude"
136
- if command -v rsync &>/dev/null; then
137
- rsync -a \
138
- --exclude='settings.json' \
139
- --exclude='CLAUDE.md' \
140
- --exclude='node_modules' \
141
- --exclude='*.jsonl' \
142
- "$KIT_ROOT/.claude/" "$TARGET/.claude/"
129
+ # ── Delegate all .claude/ file management to the migration tool ──────────────
130
+ # migrate.sh handles: categorization, conflict resolution, settings.json merge,
131
+ # CLAUDE.md merge, and manifest maintenance. It is safe to run standalone.
132
+ if bash "$SCRIPT_DIR/migrate.sh" "$KIT_ROOT" "$TARGET"; then
133
+ : # migrate.sh prints its own success messages
143
134
  else
144
- for dir in agents commands hooks skills templates; do
145
- if [[ -d "$KIT_ROOT/.claude/$dir" ]]; then
146
- mkdir -p "$TARGET/.claude/$dir"
147
- cp -r "$KIT_ROOT/.claude/$dir/." "$TARGET/.claude/$dir/"
148
- fi
149
- done
150
- rm -rf "$TARGET/.claude/hooks/skill-activation-prompt/node_modules"
135
+ error "Migration failed check output above"
136
+ exit 1
151
137
  fi
152
- success ".claude/ installed"
153
138
 
154
- # Ensure log directory exists now that .claude/ is present
139
+ # Ensure log directory + file exist now that .claude/ is present
155
140
  mkdir -p "$TARGET/.claude"
156
- : > "$LOG_FILE" # create/truncate log
141
+ : > "$LOG_FILE"
157
142
 
158
143
  # ── Inject .gitignore entries into target project ────────────────────────────
159
144
  TARGET_GITIGNORE="$TARGET/.gitignore"
@@ -161,20 +146,31 @@ if [[ "$MCP_ONLY" == "false" ]]; then
161
146
  if [[ -f "$TARGET_GITIGNORE" ]] && grep -qF "$GITIGNORE_MARKER" "$TARGET_GITIGNORE" 2>/dev/null; then
162
147
  info ".gitignore already contains CDK entries — skipping"
163
148
  else
164
- info "Adding .gitignore entries to protect secrets..."
149
+ info "Adding .gitignore entries..."
165
150
  cat >> "$TARGET_GITIGNORE" <<'EOF'
166
151
 
167
152
  # Claude Dev Kit — managed entries
168
153
  # settings.json may contain MCP API tokens written by install.sh — never commit it.
169
154
  .claude/settings.json
170
- # Audit log and install log contain local paths — no need to track.
155
+ # Audit log, install log, and migration manifest contain local paths — no need to track.
171
156
  .claude/audit.log
172
157
  .claude/install.log
158
+ .claude/.cdk-manifest
159
+ # Personal Claude overrides — machine-local, never shared with teammates.
160
+ CLAUDE.local.md
173
161
  EOF
174
- success ".gitignore updated (settings.json, audit.log, install.log excluded)"
162
+ success ".gitignore updated"
175
163
  fi
176
164
 
177
- # Install hook dependencies
165
+ # ── Copy CLAUDE.local.md.example if not present ──────────────────────────────
166
+ EXAMPLE_SRC="$KIT_ROOT/CLAUDE.local.md.example"
167
+ EXAMPLE_DEST="$TARGET/CLAUDE.local.md.example"
168
+ if [[ -f "$EXAMPLE_SRC" && ! -f "$EXAMPLE_DEST" ]]; then
169
+ cp "$EXAMPLE_SRC" "$EXAMPLE_DEST"
170
+ info "CLAUDE.local.md.example added — copy to CLAUDE.local.md for personal preferences"
171
+ fi
172
+
173
+ # ── Install hook dependencies ─────────────────────────────────────────────
178
174
  HOOK_DIR="$TARGET/.claude/hooks/skill-activation-prompt"
179
175
  if [[ -f "$HOOK_DIR/package.json" ]]; then
180
176
  info "Installing skill-activation-prompt hook dependencies..."
@@ -193,6 +189,7 @@ EOF
193
189
  popd > /dev/null
194
190
  success "Hook dependencies installed"
195
191
  fi
192
+
196
193
  fi
197
194
 
198
195
  # ─── Phase 2: MCP Wizard ──────────────────────────────────────────────────────