class-ai-agent 1.2.3 → 1.3.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/.agent/README.md +33 -0
- package/.agent/SESSION.md +54 -0
- package/.agent/SESSION.template.md +46 -0
- package/.claude/CLAUDE.md +21 -6
- package/.claude/commands/build.md +5 -4
- package/.claude/commands/debug.md +2 -1
- package/.claude/commands/handoff.md +94 -0
- package/.claude/commands/plan.md +1 -0
- package/.claude/commands/publish-npm.md +119 -0
- package/.claude/commands/resume.md +107 -0
- package/.claude/commands/spec.md +2 -1
- package/.claude/references/agent-continuity.md +42 -0
- package/.claude/references/codegraph.md +50 -0
- package/.claude/rules/agent-continuity.md +39 -0
- package/.claude/skills/agent-continuity/SKILL.md +70 -0
- package/.cursor/CURSOR.md +37 -5
- package/.cursor/commands/build.md +5 -4
- package/.cursor/commands/debug.md +2 -1
- package/.cursor/commands/handoff.md +94 -0
- package/.cursor/commands/plan.md +1 -0
- package/.cursor/commands/publish-npm.md +119 -0
- package/.cursor/commands/resume.md +107 -0
- package/.cursor/commands/spec.md +2 -1
- package/.cursor/mcp.json +15 -0
- package/.cursor/references/agent-continuity.md +42 -0
- package/.cursor/references/codegraph.md +87 -0
- package/.cursor/rules/agent-continuity.mdc +44 -0
- package/.cursor/rules/codegraph.mdc +47 -0
- package/.cursor/rules/cursor-overview.mdc +10 -3
- package/.cursor/skills/agent-continuity/SKILL.md +70 -0
- package/.kiro/KIRO.md +146 -0
- package/.kiro/agents/backend.md +395 -0
- package/.kiro/agents/code-reviewer.md +110 -0
- package/.kiro/agents/copywriter-seo.md +236 -0
- package/.kiro/agents/frontend.md +384 -0
- package/.kiro/agents/project-manager.md +201 -0
- package/.kiro/agents/qa.md +221 -0
- package/.kiro/agents/security-auditor.md +143 -0
- package/.kiro/agents/systems-architect.md +211 -0
- package/.kiro/agents/test-engineer.md +123 -0
- package/.kiro/agents/ui-ux-designer.md +210 -0
- package/.kiro/commands/build.md +133 -0
- package/.kiro/commands/debug.md +243 -0
- package/.kiro/commands/deploy.md +40 -0
- package/.kiro/commands/fix-issue.md +42 -0
- package/.kiro/commands/handoff.md +94 -0
- package/.kiro/commands/plan.md +126 -0
- package/.kiro/commands/publish-npm.md +119 -0
- package/.kiro/commands/resume.md +107 -0
- package/.kiro/commands/review.md +50 -0
- package/.kiro/commands/simplify.md +222 -0
- package/.kiro/commands/spec.md +96 -0
- package/.kiro/commands/test.md +214 -0
- package/.kiro/references/accessibility-checklist.md +174 -0
- package/.kiro/references/agent-continuity.md +42 -0
- package/.kiro/references/codegraph.md +86 -0
- package/.kiro/references/performance-checklist.md +150 -0
- package/.kiro/references/security-checklist.md +94 -0
- package/.kiro/references/testing-patterns.md +183 -0
- package/.kiro/settings/mcp.json +15 -0
- package/.kiro/settings.json +8 -0
- package/.kiro/skills/agent-continuity/SKILL.md +70 -0
- package/.kiro/skills/code-review/SKILL.md +208 -0
- package/.kiro/skills/deploy/SKILL.md +68 -0
- package/.kiro/skills/deploy/deploy.md +735 -0
- package/.kiro/skills/incremental-implementation/SKILL.md +210 -0
- package/.kiro/skills/security-review/SKILL.md +71 -0
- package/.kiro/skills/tdd/SKILL.md +217 -0
- package/.kiro/skills/ui-ux-pro-max/SKILL.md +288 -0
- package/.kiro/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/.kiro/skills/ui-ux-pro-max/data/colors.csv +97 -0
- package/.kiro/skills/ui-ux-pro-max/data/icons.csv +101 -0
- package/.kiro/skills/ui-ux-pro-max/data/landing.csv +31 -0
- package/.kiro/skills/ui-ux-pro-max/data/products.csv +97 -0
- package/.kiro/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/.kiro/skills/ui-ux-pro-max/data/styles.csv +68 -0
- package/.kiro/skills/ui-ux-pro-max/data/typography.csv +58 -0
- package/.kiro/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/.kiro/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/.kiro/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/.kiro/skills/ui-ux-pro-max/scripts/core.py +253 -0
- package/.kiro/skills/ui-ux-pro-max/scripts/design_system.py +1067 -0
- package/.kiro/skills/ui-ux-pro-max/scripts/search.py +114 -0
- package/.kiro/steering/agent-continuity.md +44 -0
- package/.kiro/steering/api-conventions.md +85 -0
- package/.kiro/steering/clean-code.md +211 -0
- package/.kiro/steering/code-style.md +92 -0
- package/.kiro/steering/codegraph.md +47 -0
- package/.kiro/steering/database.md +66 -0
- package/.kiro/steering/error-handling.md +98 -0
- package/.kiro/steering/git-workflow.md +83 -0
- package/.kiro/steering/kiro-overview.md +38 -0
- package/.kiro/steering/monitoring.md +317 -0
- package/.kiro/steering/naming-conventions.md +266 -0
- package/.kiro/steering/project-structure.md +71 -0
- package/.kiro/steering/security.md +95 -0
- package/.kiro/steering/system-design.md +168 -0
- package/.kiro/steering/tech-stack.md +462 -0
- package/.kiro/steering/testing.md +110 -0
- package/AGENTS.md +13 -7
- package/README.md +122 -18
- package/bin/class-ai-agent.cjs +165 -11
- package/package.json +10 -4
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# Accessibility Checklist (WCAG 2.1 AA)
|
|
2
|
+
|
|
3
|
+
> Ensure your application is usable by everyone.
|
|
4
|
+
|
|
5
|
+
## Keyboard Navigation
|
|
6
|
+
|
|
7
|
+
- [ ] All interactive elements focusable with Tab
|
|
8
|
+
- [ ] Focus order is logical (follows visual order)
|
|
9
|
+
- [ ] Focus indicator visible (never `outline: none`)
|
|
10
|
+
- [ ] Skip link to main content
|
|
11
|
+
- [ ] No keyboard traps
|
|
12
|
+
- [ ] Custom components work with Enter/Space
|
|
13
|
+
|
|
14
|
+
```jsx
|
|
15
|
+
// ✅ Good: Custom button with keyboard support
|
|
16
|
+
<div
|
|
17
|
+
role="button"
|
|
18
|
+
tabIndex={0}
|
|
19
|
+
onClick={handleClick}
|
|
20
|
+
onKeyDown={(e) => {
|
|
21
|
+
if (e.key === 'Enter' || e.key === ' ') handleClick();
|
|
22
|
+
}}
|
|
23
|
+
>
|
|
24
|
+
Click me
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
// ✅ Better: Use native button
|
|
28
|
+
<button onClick={handleClick}>Click me</button>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Screen Readers
|
|
32
|
+
|
|
33
|
+
### Semantic HTML
|
|
34
|
+
- [ ] Use semantic elements (`<nav>`, `<main>`, `<article>`, etc.)
|
|
35
|
+
- [ ] Headings in logical order (h1 → h2 → h3)
|
|
36
|
+
- [ ] Lists use `<ul>`, `<ol>`, `<dl>`
|
|
37
|
+
- [ ] Tables have `<th>` with scope
|
|
38
|
+
|
|
39
|
+
### ARIA
|
|
40
|
+
- [ ] Images have alt text (empty `alt=""` for decorative)
|
|
41
|
+
- [ ] Form inputs have labels
|
|
42
|
+
- [ ] Buttons have accessible names
|
|
43
|
+
- [ ] Dynamic content announced (aria-live)
|
|
44
|
+
- [ ] Modals trap focus and have aria-modal
|
|
45
|
+
|
|
46
|
+
```jsx
|
|
47
|
+
// ✅ Good: Accessible form
|
|
48
|
+
<label htmlFor="email">Email</label>
|
|
49
|
+
<input id="email" type="email" aria-describedby="email-hint" />
|
|
50
|
+
<span id="email-hint">We'll never share your email</span>
|
|
51
|
+
|
|
52
|
+
// ✅ Good: Accessible icon button
|
|
53
|
+
<button aria-label="Close menu">
|
|
54
|
+
<CloseIcon aria-hidden="true" />
|
|
55
|
+
</button>
|
|
56
|
+
|
|
57
|
+
// ✅ Good: Live region for updates
|
|
58
|
+
<div aria-live="polite" aria-atomic="true">
|
|
59
|
+
{notification}
|
|
60
|
+
</div>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Visual Design
|
|
64
|
+
|
|
65
|
+
### Color
|
|
66
|
+
- [ ] Color contrast ratio ≥ 4.5:1 (text)
|
|
67
|
+
- [ ] Color contrast ratio ≥ 3:1 (large text, UI components)
|
|
68
|
+
- [ ] Information not conveyed by color alone
|
|
69
|
+
- [ ] Links distinguishable from text (underline or contrast)
|
|
70
|
+
|
|
71
|
+
### Text
|
|
72
|
+
- [ ] Text resizable to 200% without loss
|
|
73
|
+
- [ ] Line height ≥ 1.5
|
|
74
|
+
- [ ] No text in images (except logos)
|
|
75
|
+
|
|
76
|
+
### Motion
|
|
77
|
+
- [ ] Respect `prefers-reduced-motion`
|
|
78
|
+
- [ ] No flashing content (> 3 flashes/second)
|
|
79
|
+
- [ ] Animations can be paused
|
|
80
|
+
|
|
81
|
+
```css
|
|
82
|
+
/* Respect motion preferences */
|
|
83
|
+
@media (prefers-reduced-motion: reduce) {
|
|
84
|
+
* {
|
|
85
|
+
animation-duration: 0.01ms !important;
|
|
86
|
+
transition-duration: 0.01ms !important;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Forms
|
|
92
|
+
|
|
93
|
+
- [ ] All inputs have visible labels
|
|
94
|
+
- [ ] Required fields marked
|
|
95
|
+
- [ ] Error messages associated with inputs
|
|
96
|
+
- [ ] Autocomplete attributes used
|
|
97
|
+
- [ ] Form validation accessible
|
|
98
|
+
|
|
99
|
+
```jsx
|
|
100
|
+
// ✅ Accessible error message
|
|
101
|
+
<input
|
|
102
|
+
id="email"
|
|
103
|
+
aria-invalid={hasError}
|
|
104
|
+
aria-describedby={hasError ? 'email-error' : undefined}
|
|
105
|
+
/>
|
|
106
|
+
{hasError && (
|
|
107
|
+
<span id="email-error" role="alert">
|
|
108
|
+
Please enter a valid email address
|
|
109
|
+
</span>
|
|
110
|
+
)}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Interactive Components
|
|
114
|
+
|
|
115
|
+
### Buttons & Links
|
|
116
|
+
- [ ] Buttons for actions, links for navigation
|
|
117
|
+
- [ ] Link text is descriptive (not "click here")
|
|
118
|
+
- [ ] Disabled state communicated
|
|
119
|
+
|
|
120
|
+
### Modals/Dialogs
|
|
121
|
+
- [ ] Focus trapped inside modal
|
|
122
|
+
- [ ] Close with Escape key
|
|
123
|
+
- [ ] Focus returns on close
|
|
124
|
+
- [ ] `role="dialog"` and `aria-modal="true"`
|
|
125
|
+
|
|
126
|
+
### Menus & Dropdowns
|
|
127
|
+
- [ ] Arrow key navigation
|
|
128
|
+
- [ ] `role="menu"` and `role="menuitem"`
|
|
129
|
+
- [ ] Current item indicated
|
|
130
|
+
|
|
131
|
+
## Testing Tools
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
# Automated testing
|
|
135
|
+
npx axe-cli https://example.com
|
|
136
|
+
npx pa11y https://example.com
|
|
137
|
+
|
|
138
|
+
# Browser extensions
|
|
139
|
+
- axe DevTools (Chrome)
|
|
140
|
+
- WAVE (Chrome/Firefox)
|
|
141
|
+
- Accessibility Insights (Chrome)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Manual Testing
|
|
145
|
+
- [ ] Navigate with keyboard only
|
|
146
|
+
- [ ] Test with screen reader (VoiceOver/NVDA)
|
|
147
|
+
- [ ] Zoom to 200%
|
|
148
|
+
- [ ] Use high contrast mode
|
|
149
|
+
- [ ] Test with reduced motion
|
|
150
|
+
|
|
151
|
+
## ARIA Roles Quick Reference
|
|
152
|
+
|
|
153
|
+
| Role | Use For |
|
|
154
|
+
|------|---------|
|
|
155
|
+
| `button` | Clickable elements (prefer `<button>`) |
|
|
156
|
+
| `link` | Navigation (prefer `<a>`) |
|
|
157
|
+
| `dialog` | Modal windows |
|
|
158
|
+
| `alert` | Important messages |
|
|
159
|
+
| `status` | Status updates |
|
|
160
|
+
| `navigation` | Nav sections (prefer `<nav>`) |
|
|
161
|
+
| `main` | Main content (prefer `<main>`) |
|
|
162
|
+
| `region` | Distinct sections with label |
|
|
163
|
+
| `tablist`, `tab`, `tabpanel` | Tab interfaces |
|
|
164
|
+
|
|
165
|
+
## Common Issues
|
|
166
|
+
|
|
167
|
+
| Issue | Fix |
|
|
168
|
+
|-------|-----|
|
|
169
|
+
| Missing alt text | Add descriptive alt or `alt=""` |
|
|
170
|
+
| Low contrast | Increase color contrast |
|
|
171
|
+
| Missing form labels | Add `<label>` elements |
|
|
172
|
+
| Focus not visible | Don't remove outline, style it |
|
|
173
|
+
| Mouse-only interactions | Add keyboard handlers |
|
|
174
|
+
| Auto-playing media | Add controls, respect preferences |
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Agent continuity — quick reference
|
|
2
|
+
|
|
3
|
+
## Files
|
|
4
|
+
|
|
5
|
+
| Path | Role |
|
|
6
|
+
|------|------|
|
|
7
|
+
| `.agent/SESSION.md` | Live handoff (commit to git) |
|
|
8
|
+
| `.agent/SESSION.template.md` | Schema reference |
|
|
9
|
+
| `.agent/README.md` | Human overview |
|
|
10
|
+
| `tasks/todo.md` | Task checklist (workflow) |
|
|
11
|
+
| `SPEC.md` | Feature spec (workflow) |
|
|
12
|
+
|
|
13
|
+
## Commands
|
|
14
|
+
|
|
15
|
+
| Command | When |
|
|
16
|
+
|---------|------|
|
|
17
|
+
| **`/resume`** | Start of session — read SESSION, summarize, continue |
|
|
18
|
+
| **`/handoff`** | End of session — write SESSION, sync tasks |
|
|
19
|
+
|
|
20
|
+
## Read order (resume)
|
|
21
|
+
|
|
22
|
+
1. `.agent/SESSION.md`
|
|
23
|
+
2. `tasks/todo.md`
|
|
24
|
+
3. Linked spec from SESSION Pointers
|
|
25
|
+
|
|
26
|
+
## Install
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npx class-ai-agent
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Creates `.agent/` and seeds `SESSION.md` from template.
|
|
33
|
+
|
|
34
|
+
## Rules
|
|
35
|
+
|
|
36
|
+
- **Cursor:** `.cursor/rules/agent-continuity.mdc` (`alwaysApply`)
|
|
37
|
+
- **Claude:** `.claude/rules/agent-continuity.md`
|
|
38
|
+
- **Kiro:** `.kiro/steering/agent-continuity.md` (`inclusion: always`)
|
|
39
|
+
|
|
40
|
+
## Skill
|
|
41
|
+
|
|
42
|
+
`.cursor/skills/agent-continuity/SKILL.md` — full handoff/resume checklists.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# CodeGraph reference
|
|
2
|
+
|
|
3
|
+
[CodeGraph](https://github.com/colbymchenry/codegraph) is a local, tree-sitter–parsed knowledge graph exposed to agents via MCP. **class-ai-agent** installs Cursor and Kiro MCP wiring plus usage rules, and runs `codegraph init -i` after scaffolding.
|
|
4
|
+
|
|
5
|
+
## Kiro (included with class-ai-agent)
|
|
6
|
+
|
|
7
|
+
| Item | Path |
|
|
8
|
+
|------|------|
|
|
9
|
+
| MCP config | `.kiro/settings/mcp.json` |
|
|
10
|
+
| Usage rules | `.kiro/steering/codegraph.md` |
|
|
11
|
+
| Index (generated) | `.codegraph/` (gitignored) |
|
|
12
|
+
|
|
13
|
+
1. Restart Kiro after install so MCP connects.
|
|
14
|
+
2. Confirm **CodeGraph** appears under MCP in Kiro (IDE or CLI).
|
|
15
|
+
3. Use `codegraph_*` tools for structural questions; grep/read for literal text.
|
|
16
|
+
|
|
17
|
+
**Manual index:** `npx @colbymchenry/codegraph init -i`
|
|
18
|
+
|
|
19
|
+
**Skip auto-index on install:** `CODEGRAPH_SKIP_INIT=1 npx class-ai-agent`
|
|
20
|
+
|
|
21
|
+
## Kiro (included with class-ai-agent)
|
|
22
|
+
|
|
23
|
+
| Item | Path |
|
|
24
|
+
|------|------|
|
|
25
|
+
| MCP config | `.kiro/settings/mcp.json` |
|
|
26
|
+
| Usage rules | `.kiro/steering/codegraph.md` |
|
|
27
|
+
| Index (generated) | `.codegraph/` (gitignored) |
|
|
28
|
+
|
|
29
|
+
1. Restart Kiro after install so MCP connects.
|
|
30
|
+
2. Confirm **CodeGraph** under MCP in Kiro IDE or CLI settings.
|
|
31
|
+
3. Use `codegraph_*` tools for structural questions.
|
|
32
|
+
|
|
33
|
+
See `.kiro/references/codegraph.md` for full notes.
|
|
34
|
+
|
|
35
|
+
## Claude Code
|
|
36
|
+
|
|
37
|
+
Project scaffolding does **not** add Claude MCP config. Install CodeGraph globally:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npx @colbymchenry/codegraph
|
|
41
|
+
codegraph install --target=claude --yes
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Cursor
|
|
45
|
+
|
|
46
|
+
Cursor users get `.cursor/mcp.json` and `.cursor/rules/codegraph.mdc` from the same package. See `.cursor/references/codegraph.md`.
|
|
47
|
+
|
|
48
|
+
## Requirements
|
|
49
|
+
|
|
50
|
+
- **Node 20+** recommended for CodeGraph (class-ai-agent CLI itself supports Node 16.7+).
|
|
51
|
+
- First index can take a minute on large repos; progress prints during `npx class-ai-agent` install.
|
|
52
|
+
|
|
53
|
+
## Tool parameters
|
|
54
|
+
|
|
55
|
+
| Tool | Pass | Not |
|
|
56
|
+
|------|------|-----|
|
|
57
|
+
| `codegraph_search` | `query`, optional `limit` | — |
|
|
58
|
+
| `codegraph_context` | **`task`** (natural-language area), optional **`maxNodes`** | `query`, `limit` |
|
|
59
|
+
|
|
60
|
+
Example — wrong (search-style args on context):
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{ "query": "auth flow", "limit": 15 }
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
→ `Error: task must be a non-empty string`
|
|
67
|
+
|
|
68
|
+
Example — correct:
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{ "task": "how authentication flow works", "maxNodes": 15 }
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Session handoff** (`/resume`, `.agent/SESSION.md`) is not a CodeGraph call — read those files with the editor Read tool.
|
|
75
|
+
|
|
76
|
+
## Troubleshooting
|
|
77
|
+
|
|
78
|
+
| Issue | Action |
|
|
79
|
+
|-------|--------|
|
|
80
|
+
| `task must be a non-empty string` | Use `task` (not `query`) on `codegraph_context`; use `maxNodes` (not `limit`). For `/resume`, read `.agent/SESSION.md` instead. |
|
|
81
|
+
| MCP “not initialized” | Run `npx @colbymchenry/codegraph init -i` in project root |
|
|
82
|
+
| MCP not connecting | Reload Cursor; verify `.cursor/mcp.json`; test `npx @colbymchenry/codegraph serve --mcp` |
|
|
83
|
+
| Stale symbols after edit | Wait ~2s for watcher sync, or check staleness banner in tool output |
|
|
84
|
+
| Init failed during install | Run `npx @colbymchenry/codegraph init -i` manually |
|
|
85
|
+
|
|
86
|
+
Upstream: [colbymchenry/codegraph](https://github.com/colbymchenry/codegraph)
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# Performance Checklist
|
|
2
|
+
|
|
3
|
+
> Quick reference for performance optimization.
|
|
4
|
+
|
|
5
|
+
## Core Web Vitals Targets
|
|
6
|
+
|
|
7
|
+
| Metric | Good | Needs Work | Poor |
|
|
8
|
+
|--------|------|------------|------|
|
|
9
|
+
| **LCP** (Largest Contentful Paint) | < 2.5s | 2.5-4s | > 4s |
|
|
10
|
+
| **INP** (Interaction to Next Paint) | < 200ms | 200-500ms | > 500ms |
|
|
11
|
+
| **CLS** (Cumulative Layout Shift) | < 0.1 | 0.1-0.25 | > 0.25 |
|
|
12
|
+
|
|
13
|
+
## Frontend Performance
|
|
14
|
+
|
|
15
|
+
### Critical Render Path
|
|
16
|
+
- [ ] Minimize critical CSS (inline above-fold styles)
|
|
17
|
+
- [ ] Defer non-critical JavaScript
|
|
18
|
+
- [ ] Preload critical resources
|
|
19
|
+
- [ ] Optimize font loading (font-display: swap)
|
|
20
|
+
|
|
21
|
+
### Images
|
|
22
|
+
- [ ] Use modern formats (WebP, AVIF)
|
|
23
|
+
- [ ] Implement lazy loading
|
|
24
|
+
- [ ] Serve responsive sizes (srcset)
|
|
25
|
+
- [ ] Use CDN for static assets
|
|
26
|
+
- [ ] Set explicit width/height (prevent CLS)
|
|
27
|
+
|
|
28
|
+
### JavaScript
|
|
29
|
+
- [ ] Code splitting (dynamic imports)
|
|
30
|
+
- [ ] Tree shaking enabled
|
|
31
|
+
- [ ] Bundle size monitored (< 200KB initial)
|
|
32
|
+
- [ ] No unused dependencies
|
|
33
|
+
|
|
34
|
+
### React Specific
|
|
35
|
+
- [ ] Memoize expensive computations (useMemo)
|
|
36
|
+
- [ ] Prevent unnecessary re-renders (React.memo)
|
|
37
|
+
- [ ] Virtualize long lists (react-window)
|
|
38
|
+
- [ ] Use Suspense for code splitting
|
|
39
|
+
|
|
40
|
+
```javascript
|
|
41
|
+
// ✅ Good: Memoized component
|
|
42
|
+
const ExpensiveList = React.memo(({ items }) => {
|
|
43
|
+
return items.map(item => <Item key={item.id} {...item} />);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// ✅ Good: Memoized computation
|
|
47
|
+
const sortedItems = useMemo(
|
|
48
|
+
() => items.sort((a, b) => a.name.localeCompare(b.name)),
|
|
49
|
+
[items]
|
|
50
|
+
);
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Backend Performance
|
|
54
|
+
|
|
55
|
+
### Database
|
|
56
|
+
- [ ] Indexes on queried columns
|
|
57
|
+
- [ ] No N+1 queries
|
|
58
|
+
- [ ] Pagination implemented
|
|
59
|
+
- [ ] Connection pooling configured
|
|
60
|
+
- [ ] Query timeouts set
|
|
61
|
+
|
|
62
|
+
```javascript
|
|
63
|
+
// ❌ N+1 Problem
|
|
64
|
+
const users = await db.user.findMany();
|
|
65
|
+
for (const user of users) {
|
|
66
|
+
user.orders = await db.order.findMany({ where: { userId: user.id } });
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ✅ Fixed: Include relation
|
|
70
|
+
const users = await db.user.findMany({
|
|
71
|
+
include: { orders: true }
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Caching
|
|
76
|
+
- [ ] Cache frequently accessed data
|
|
77
|
+
- [ ] Appropriate TTLs set
|
|
78
|
+
- [ ] Cache invalidation strategy
|
|
79
|
+
- [ ] CDN for static content
|
|
80
|
+
|
|
81
|
+
```javascript
|
|
82
|
+
// Cache pattern
|
|
83
|
+
async function getUser(id) {
|
|
84
|
+
const cached = await redis.get(`user:${id}`);
|
|
85
|
+
if (cached) return JSON.parse(cached);
|
|
86
|
+
|
|
87
|
+
const user = await db.user.findUnique({ where: { id } });
|
|
88
|
+
await redis.setex(`user:${id}`, 3600, JSON.stringify(user));
|
|
89
|
+
return user;
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### API
|
|
94
|
+
- [ ] Response compression (gzip/brotli)
|
|
95
|
+
- [ ] Pagination for lists
|
|
96
|
+
- [ ] Field selection (select only needed)
|
|
97
|
+
- [ ] Async operations for slow tasks
|
|
98
|
+
|
|
99
|
+
```javascript
|
|
100
|
+
// ✅ Good: Paginated API
|
|
101
|
+
GET /api/users?page=1&limit=20&fields=id,name,email
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Measurement Commands
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Lighthouse (Chrome)
|
|
108
|
+
npx lighthouse https://example.com --output=json
|
|
109
|
+
|
|
110
|
+
# Bundle analysis
|
|
111
|
+
npx webpack-bundle-analyzer stats.json
|
|
112
|
+
|
|
113
|
+
# Check bundle size
|
|
114
|
+
npx bundlephobia <package-name>
|
|
115
|
+
|
|
116
|
+
# Database query analysis
|
|
117
|
+
EXPLAIN ANALYZE SELECT * FROM users WHERE email = '...';
|
|
118
|
+
|
|
119
|
+
# Redis latency
|
|
120
|
+
redis-cli --latency
|
|
121
|
+
|
|
122
|
+
# API response time
|
|
123
|
+
curl -o /dev/null -s -w '%{time_total}\n' https://api.example.com/users
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Performance Budget
|
|
127
|
+
|
|
128
|
+
| Resource | Budget |
|
|
129
|
+
|----------|--------|
|
|
130
|
+
| Initial JS | < 200KB |
|
|
131
|
+
| Initial CSS | < 50KB |
|
|
132
|
+
| Total page weight | < 1MB |
|
|
133
|
+
| Time to Interactive | < 3s |
|
|
134
|
+
| API response (p95) | < 200ms |
|
|
135
|
+
|
|
136
|
+
## Monitoring
|
|
137
|
+
|
|
138
|
+
- [ ] Real User Monitoring (RUM) enabled
|
|
139
|
+
- [ ] Synthetic monitoring configured
|
|
140
|
+
- [ ] Alerting on degradation
|
|
141
|
+
- [ ] Performance tracked in CI
|
|
142
|
+
|
|
143
|
+
```javascript
|
|
144
|
+
// Example: Track Core Web Vitals
|
|
145
|
+
import { onLCP, onINP, onCLS } from 'web-vitals';
|
|
146
|
+
|
|
147
|
+
onLCP(metric => sendToAnalytics('LCP', metric.value));
|
|
148
|
+
onINP(metric => sendToAnalytics('INP', metric.value));
|
|
149
|
+
onCLS(metric => sendToAnalytics('CLS', metric.value));
|
|
150
|
+
```
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Security Checklist
|
|
2
|
+
|
|
3
|
+
> Quick reference for security review. See `.claude/rules/security.md` for full rules.
|
|
4
|
+
|
|
5
|
+
## Pre-Commit Checks
|
|
6
|
+
|
|
7
|
+
- [ ] No secrets in code (API keys, passwords, tokens)
|
|
8
|
+
- [ ] `.gitignore` excludes sensitive files (`.env`, credentials)
|
|
9
|
+
- [ ] `.env.example` contains only placeholder values
|
|
10
|
+
- [ ] No hardcoded URLs with credentials
|
|
11
|
+
|
|
12
|
+
## Authentication
|
|
13
|
+
|
|
14
|
+
- [ ] Passwords hashed with bcrypt (rounds >= 12) or argon2
|
|
15
|
+
- [ ] Session cookies: `httpOnly`, `secure`, `sameSite: 'lax'`
|
|
16
|
+
- [ ] JWT tokens have reasonable expiry (15min access, 7d refresh)
|
|
17
|
+
- [ ] Rate limiting on auth endpoints (max 10 attempts/15min)
|
|
18
|
+
- [ ] Logout invalidates session/token
|
|
19
|
+
|
|
20
|
+
## Authorization
|
|
21
|
+
|
|
22
|
+
- [ ] Every endpoint checks authentication
|
|
23
|
+
- [ ] Resource ownership verified (no IDOR)
|
|
24
|
+
- [ ] API keys are scoped appropriately
|
|
25
|
+
- [ ] JWT signature, expiration, and issuer validated
|
|
26
|
+
- [ ] Admin functions protected
|
|
27
|
+
|
|
28
|
+
## Input Validation
|
|
29
|
+
|
|
30
|
+
- [ ] All user input validated at system boundary
|
|
31
|
+
- [ ] Allowlist validation preferred over blocklist
|
|
32
|
+
- [ ] String lengths constrained
|
|
33
|
+
- [ ] Numeric ranges validated
|
|
34
|
+
- [ ] File uploads restricted by type and size
|
|
35
|
+
- [ ] SQL queries parameterized (never string concat)
|
|
36
|
+
|
|
37
|
+
## Security Headers
|
|
38
|
+
|
|
39
|
+
```javascript
|
|
40
|
+
// Required headers
|
|
41
|
+
Content-Security-Policy: default-src 'self'
|
|
42
|
+
Strict-Transport-Security: max-age=31536000; includeSubDomains
|
|
43
|
+
X-Content-Type-Options: nosniff
|
|
44
|
+
X-Frame-Options: DENY
|
|
45
|
+
Permissions-Policy: geolocation=(), camera=()
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## CORS
|
|
49
|
+
|
|
50
|
+
- [ ] Restrictive origin allowlist (no `*` in production)
|
|
51
|
+
- [ ] Credentials mode appropriate
|
|
52
|
+
- [ ] Methods and headers restricted
|
|
53
|
+
|
|
54
|
+
## Data Protection
|
|
55
|
+
|
|
56
|
+
- [ ] Sensitive fields excluded from API responses
|
|
57
|
+
- [ ] No secrets in logs
|
|
58
|
+
- [ ] PII encrypted when required
|
|
59
|
+
- [ ] HTTPS enforced
|
|
60
|
+
- [ ] Database backups encrypted
|
|
61
|
+
|
|
62
|
+
## Dependencies
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# Run regularly
|
|
66
|
+
npm audit
|
|
67
|
+
npm audit fix
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
- [ ] No critical vulnerabilities
|
|
71
|
+
- [ ] Dependencies up to date
|
|
72
|
+
- [ ] Lock file committed
|
|
73
|
+
|
|
74
|
+
## Error Handling
|
|
75
|
+
|
|
76
|
+
- [ ] Generic error messages in production
|
|
77
|
+
- [ ] No stack traces exposed
|
|
78
|
+
- [ ] No database details in errors
|
|
79
|
+
- [ ] No internal paths revealed
|
|
80
|
+
|
|
81
|
+
## OWASP Top 10 Quick Check
|
|
82
|
+
|
|
83
|
+
| # | Vulnerability | Check |
|
|
84
|
+
|---|--------------|-------|
|
|
85
|
+
| 1 | Broken Access Control | Auth on all endpoints? |
|
|
86
|
+
| 2 | Cryptographic Failures | Secrets encrypted? HTTPS? |
|
|
87
|
+
| 3 | Injection | Inputs sanitized? Queries parameterized? |
|
|
88
|
+
| 4 | Insecure Design | Threat modeling done? |
|
|
89
|
+
| 5 | Security Misconfiguration | Headers set? Defaults changed? |
|
|
90
|
+
| 6 | Vulnerable Components | `npm audit` clean? |
|
|
91
|
+
| 7 | Auth Failures | Rate limiting? Strong passwords? |
|
|
92
|
+
| 8 | Data Integrity | Signatures verified? |
|
|
93
|
+
| 9 | Logging Failures | Security events logged? |
|
|
94
|
+
| 10 | SSRF | External URLs validated? |
|