ai-developer-skill-os 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -0
- package/LICENSE +21 -0
- package/README.md +142 -0
- package/_template/SKILL.md +154 -0
- package/_template/examples/example-en.md +49 -0
- package/_template/examples/example-vi.md +49 -0
- package/bin/install.js +56 -0
- package/docs/CHI_TIET_SKILLS.md +117 -0
- package/docs/HUONG_DAN_SU_DUNG.md +102 -0
- package/package.json +34 -0
- package/skills/backend/auth-security/SKILL.md +94 -0
- package/skills/backend/backend-architecture/SKILL.md +123 -0
- package/skills/backend/database-engineer/SKILL.md +102 -0
- package/skills/backend/deployment/SKILL.md +94 -0
- package/skills/engineering/agent-orchestrator/SKILL.md +177 -0
- package/skills/engineering/api-integration/SKILL.md +378 -0
- package/skills/engineering/bug-fix/SKILL.md +211 -0
- package/skills/engineering/context-manager/SKILL.md +174 -0
- package/skills/engineering/git-engineer/SKILL.md +302 -0
- package/skills/engineering/migration/SKILL.md +282 -0
- package/skills/engineering/project-audit/SKILL.md +278 -0
- package/skills/engineering/refactor/SKILL.md +220 -0
- package/skills/frontend/accessibility-audit/SKILL.md +119 -0
- package/skills/frontend/component-generator/SKILL.md +134 -0
- package/skills/frontend/design-system/SKILL.md +135 -0
- package/skills/frontend/form-builder/SKILL.md +138 -0
- package/skills/frontend/frontend-architecture/SKILL.md +153 -0
- package/skills/frontend/frontend-debug/SKILL.md +131 -0
- package/skills/frontend/frontend-performance/SKILL.md +127 -0
- package/skills/frontend/frontend-testing/SKILL.md +144 -0
- package/skills/frontend/state-management/SKILL.md +138 -0
- package/skills/frontend/table-crud-generator/SKILL.md +125 -0
- package/skills/frontend/ui-builder/SKILL.md +150 -0
- package/skills.json +667 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: form-builder
|
|
3
|
+
description: >-
|
|
4
|
+
Xây dựng Form chuẩn xác với quản lý trạng thái, validate dữ liệu (Zod, Yup) và xử lý hiển thị lỗi.
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
category: frontend
|
|
7
|
+
tags: [form, validation, react-hook-form, zod, yup, formik]
|
|
8
|
+
platforms: [antigravity, claude-code, kilo-code, cursor, windsurf]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Form Builder
|
|
12
|
+
|
|
13
|
+
> **Language rule:**
|
|
14
|
+
> Use **English** for: field names, validation rules, code, technical concepts.
|
|
15
|
+
> Use **the user's language** for: explanations, error message text (unless specified otherwise), and summaries.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Trigger
|
|
20
|
+
|
|
21
|
+
Activate this skill when:
|
|
22
|
+
- User says "create a login form", "add a settings page", "build a contact form"
|
|
23
|
+
- User provides a data model and needs a UI to create/edit it
|
|
24
|
+
- A form needs complex validation logic added
|
|
25
|
+
- Refactoring a messy form into a structured library pattern (e.g., React Hook Form)
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Scope
|
|
30
|
+
|
|
31
|
+
- ✅ Define the form data schema and validation rules
|
|
32
|
+
- ✅ Manage form state efficiently (preventing unnecessary re-renders)
|
|
33
|
+
- ✅ Map form fields to the project's design system components
|
|
34
|
+
- ✅ Handle submission state (loading, success, error)
|
|
35
|
+
- ✅ Handle validation errors and display them accessibly
|
|
36
|
+
- ✅ Integrate with `api-integration` for submission
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Non-goals
|
|
41
|
+
|
|
42
|
+
- ❌ Do NOT reinvent form state management if a library is present
|
|
43
|
+
- ❌ Do NOT use raw HTML inputs if design system components exist
|
|
44
|
+
- ❌ Do NOT skip validation (client-side validation is required)
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Workflow
|
|
49
|
+
|
|
50
|
+
### Phase 1 — Schema Design
|
|
51
|
+
|
|
52
|
+
Define the exact shape of the data the form collects.
|
|
53
|
+
Determine validation rules for each field (required, min length, email format, etc.).
|
|
54
|
+
|
|
55
|
+
If the project uses Zod, Yup, or Joi, define the schema first.
|
|
56
|
+
*Example:*
|
|
57
|
+
```typescript
|
|
58
|
+
const userFormSchema = z.object({
|
|
59
|
+
email: z.string().email("Invalid email address"),
|
|
60
|
+
password: z.string().min(8, "Password must be at least 8 characters"),
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
### Phase 2 — State Management Selection
|
|
67
|
+
|
|
68
|
+
Check project dependencies for form libraries:
|
|
69
|
+
1. `react-hook-form` (Preferred for React)
|
|
70
|
+
2. `formik`
|
|
71
|
+
3. Custom Vue/Svelte bindings
|
|
72
|
+
4. Standard controlled components (`useState`) if no library exists and form is simple.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
### Phase 3 — Component Assembly
|
|
77
|
+
|
|
78
|
+
1. Set up the form wrapper and submission handler.
|
|
79
|
+
2. For each field in the schema, render the appropriate UI component (from `design-system`).
|
|
80
|
+
3. Connect the UI component to the form state (register / Controller).
|
|
81
|
+
4. Render error messages below fields if validation fails.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
### Phase 4 — Submission & Integration
|
|
86
|
+
|
|
87
|
+
- Add `isLoading` state to the submit button.
|
|
88
|
+
- Disable submit button during submission.
|
|
89
|
+
- On success: Show success message or redirect, and optionally reset form.
|
|
90
|
+
- On error: Display backend error messages (toast or form-level alert).
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Decision Tree
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
Does the project use a validation library (Zod, Yup)?
|
|
98
|
+
├── Yes → Use it to define schema and pass to form resolver
|
|
99
|
+
└── No → Implement standard HTML5 validation or simple manual validation logic
|
|
100
|
+
|
|
101
|
+
Is it a complex multi-step form (wizard)?
|
|
102
|
+
├── Yes → Break into sub-components, use global or lifted state for form data
|
|
103
|
+
└── No → Handle state locally within the single form component
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Output Format
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
📝 Form Built
|
|
112
|
+
─────────────────────────────────────────────────
|
|
113
|
+
Name: [FormName]
|
|
114
|
+
Schema: [Zod / Yup / Manual]
|
|
115
|
+
Library: [React Hook Form / Formik / Native]
|
|
116
|
+
|
|
117
|
+
Fields Implemented:
|
|
118
|
+
✅ email (string, required, email)
|
|
119
|
+
✅ password (string, required, min: 8)
|
|
120
|
+
|
|
121
|
+
Integration:
|
|
122
|
+
- Validation: Client-side wired up
|
|
123
|
+
- Submission: Wired to `[submitFunction]`
|
|
124
|
+
- Loading UI: Handled on submit button
|
|
125
|
+
|
|
126
|
+
🔗 Next Steps:
|
|
127
|
+
Make sure the API endpoint is ready to accept this payload.
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Validation Checklist
|
|
133
|
+
|
|
134
|
+
- [ ] Form uses existing design system components (Inputs, Buttons)
|
|
135
|
+
- [ ] Client-side validation is implemented
|
|
136
|
+
- [ ] Error messages are displayed properly
|
|
137
|
+
- [ ] Loading state disables the submit button
|
|
138
|
+
- [ ] Accessibility: Inputs have associated labels and error ARIA attributes
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: frontend-architecture
|
|
3
|
+
description: >-
|
|
4
|
+
Phân tích cấu trúc thư mục frontend và quyết định vị trí đặt file chuẩn xác theo kiến trúc hiện tại.
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
category: frontend
|
|
7
|
+
tags: [architecture, folder-structure, conventions, file-placement]
|
|
8
|
+
platforms: [antigravity, claude-code, kilo-code, cursor, windsurf]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Frontend Architecture
|
|
12
|
+
|
|
13
|
+
> **Language rule:**
|
|
14
|
+
> Use **English** for: code, folder names, architecture terms, technical rules.
|
|
15
|
+
> Use **the user's language** for: explanations, questions, and summaries.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Trigger
|
|
20
|
+
|
|
21
|
+
Activate this skill when:
|
|
22
|
+
- About to create new files or components
|
|
23
|
+
- User asks "where should I put this file?" or "how should I organize this?"
|
|
24
|
+
- Moving or refactoring code across different modules
|
|
25
|
+
- Inheriting an unfamiliar frontend project
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Scope
|
|
30
|
+
|
|
31
|
+
- ✅ Discover the existing frontend folder structure
|
|
32
|
+
- ✅ Define where new components, hooks, services, and types should be placed
|
|
33
|
+
- ✅ Enforce separation of concerns (e.g., UI vs. Business Logic vs. Data)
|
|
34
|
+
- ✅ Identify architectural patterns in use (e.g., Feature-based, Layer-based)
|
|
35
|
+
- ✅ Validate file placement before execution by other skills
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Non-goals
|
|
40
|
+
|
|
41
|
+
- ❌ Do NOT rewrite the entire project architecture unless explicitly asked
|
|
42
|
+
- ❌ Do NOT generate code (delegate to `component-generator` or `ui-builder`)
|
|
43
|
+
- ❌ Do NOT enforce personal preferences over established project conventions
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Severity Levels
|
|
48
|
+
|
|
49
|
+
| Level | Meaning |
|
|
50
|
+
|-------|---------|
|
|
51
|
+
| P0 | Architectural violation that breaks the build or creates circular dependencies |
|
|
52
|
+
| P1 | File placed in completely wrong layer (e.g., API logic in UI component) |
|
|
53
|
+
| P2 | Inconsistent folder or file naming |
|
|
54
|
+
| P3 | Minor deviation from convention |
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Workflow
|
|
59
|
+
|
|
60
|
+
### Phase 1 — Structure Discovery
|
|
61
|
+
|
|
62
|
+
*(Relies on `context-manager` if already loaded)*
|
|
63
|
+
|
|
64
|
+
Analyze the root source directory (e.g., `src/`, `app/`):
|
|
65
|
+
1. **Layer-based:** `components/`, `hooks/`, `services/`, `utils/`, `types/`
|
|
66
|
+
2. **Feature-based:** `features/auth/`, `features/products/`
|
|
67
|
+
3. **Framework-specific:** `app/` (Next.js App Router), `pages/` (Next.js Pages Router, Nuxt)
|
|
68
|
+
4. **Domain-driven:** `domains/user/`, `domains/payment/`
|
|
69
|
+
5. **FSD (Feature Sliced Design):** `app/`, `processes/`, `pages/`, `widgets/`, `features/`, `entities/`, `shared/`
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
### Phase 2 — Rule Extraction
|
|
74
|
+
|
|
75
|
+
Based on discovery, define the project's rules for:
|
|
76
|
+
- **Components:** Are they flat? Grouped by feature? Atomic design?
|
|
77
|
+
- **Hooks:** Shared in `src/hooks/` or collocated with components?
|
|
78
|
+
- **State:** Global store vs. feature stores?
|
|
79
|
+
- **API/Services:** Where are HTTP calls made?
|
|
80
|
+
- **Types:** Centralized `types/` or collocated?
|
|
81
|
+
- **Naming Conventions:** PascalCase, camelCase, kebab-case, `index.ts` usage?
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
### Phase 3 — File Placement Decision
|
|
86
|
+
|
|
87
|
+
When a new feature/component is requested, map it to the structure:
|
|
88
|
+
|
|
89
|
+
**Input:** "Create a User Profile card that fetches user data."
|
|
90
|
+
**Decision:**
|
|
91
|
+
- UI Component: `src/features/user/components/UserProfileCard.tsx`
|
|
92
|
+
- API Hook: `src/features/user/api/useUser.ts`
|
|
93
|
+
- Types: `src/features/user/types/index.ts`
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
### Phase 4 — Enforcement & Validation
|
|
98
|
+
|
|
99
|
+
Before passing control to a generation skill (like `ui-builder`), ensure the plan adheres to the rules.
|
|
100
|
+
|
|
101
|
+
- [ ] Does it mix concerns? (e.g., putting an API call directly in a shared UI button)
|
|
102
|
+
- [ ] Does it violate import boundaries? (e.g., a shared component importing from a specific feature)
|
|
103
|
+
- [ ] Is the naming consistent?
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Decision Tree
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
Is the project using a Feature-based structure?
|
|
111
|
+
├── Yes → Place feature-specific code in `features/<feature-name>/`
|
|
112
|
+
└── No → Use Layer-based structure (`components/`, `hooks/`, etc.)
|
|
113
|
+
|
|
114
|
+
Is the code shared across multiple domains/features?
|
|
115
|
+
├── Yes → Place in `shared/` or global `components/` / `hooks/`
|
|
116
|
+
└── No → Collocate with the specific domain/feature
|
|
117
|
+
|
|
118
|
+
Are there existing examples of this type of file?
|
|
119
|
+
├── Yes → Copy their placement and naming pattern
|
|
120
|
+
└── No → Propose a standard location and ask user to confirm
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Output Format
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
🏗️ Frontend Architecture Plan
|
|
129
|
+
─────────────────────────────────────────────────
|
|
130
|
+
Structure Type: [Feature-based / Layer-based / FSD / etc.]
|
|
131
|
+
Naming: [PascalCase for components, camelCase for functions]
|
|
132
|
+
|
|
133
|
+
File Placement:
|
|
134
|
+
📄 [path/to/new/file1.tsx] — [Why it goes here]
|
|
135
|
+
📄 [path/to/new/file2.ts] — [Why it goes here]
|
|
136
|
+
|
|
137
|
+
⚠️ Constraints enforced:
|
|
138
|
+
• [Constraint 1, e.g., "API calls must be in hooks, not components"]
|
|
139
|
+
• [Constraint 2, e.g., "Shared UI components cannot import from features/"]
|
|
140
|
+
|
|
141
|
+
🔗 Next Steps:
|
|
142
|
+
Delegating to `[skill-name]` to generate the files.
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Validation Checklist
|
|
148
|
+
|
|
149
|
+
- [ ] Structure type identified correctly
|
|
150
|
+
- [ ] File placement follows existing conventions
|
|
151
|
+
- [ ] Naming matches project standards
|
|
152
|
+
- [ ] Separation of concerns maintained
|
|
153
|
+
- [ ] Plan ready to be executed by generation skills
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: frontend-debug
|
|
3
|
+
description: >-
|
|
4
|
+
Chẩn đoán và sửa các lỗi đặc thù frontend như Hydration error, infinite re-render, stale closure và vỡ CSS.
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
category: frontend
|
|
7
|
+
tags: [debug, react, hydration, rerender, css, state-bug]
|
|
8
|
+
platforms: [antigravity, claude-code, kilo-code, cursor, windsurf]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Frontend Debugger
|
|
12
|
+
|
|
13
|
+
> **Language rule:**
|
|
14
|
+
> Use **English** for: code, error messages, stack traces, technical patterns.
|
|
15
|
+
> Use **the user's language** for: explanations, root cause summaries, and questions.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Trigger
|
|
20
|
+
|
|
21
|
+
Activate this skill when:
|
|
22
|
+
- User reports a UI-specific bug ("screen is blank", "button doesn't work")
|
|
23
|
+
- React throws a Hydration Error (`Text content did not match. Server: "A" Client: "B"`)
|
|
24
|
+
- React throws an infinite loop error (`Too many re-renders`)
|
|
25
|
+
- CSS styling is broken or overflowing unexpectedly
|
|
26
|
+
- Form validation behaves incorrectly
|
|
27
|
+
|
|
28
|
+
**Note:** For backend or general logic bugs, use `bug-fix`. For performance issues, use `frontend-performance`.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Scope
|
|
33
|
+
|
|
34
|
+
- ✅ Diagnose and fix React hydration mismatches (Next.js / SSR)
|
|
35
|
+
- ✅ Fix infinite loops in `useEffect` and missing dependencies
|
|
36
|
+
- ✅ Resolve state staleness (stale closures in async functions or hooks)
|
|
37
|
+
- ✅ Fix CSS layout issues (Flexbox/Grid blowouts, z-index stacking context)
|
|
38
|
+
- ✅ Provide a targeted, minimal fix that doesn't break other UI elements
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Non-goals
|
|
43
|
+
|
|
44
|
+
- ❌ Do NOT rewrite the entire component to fix a small CSS bug
|
|
45
|
+
- ❌ Do NOT disable hydration checks (`suppressHydrationWarning`) unless absolutely necessary and justified
|
|
46
|
+
- ❌ Do NOT apply quick-fixes (like `// @ts-ignore` or wrapping everything in `setTimeout`) without understanding the root cause
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Workflow
|
|
51
|
+
|
|
52
|
+
### Phase 1 — Reproduction & Isolation
|
|
53
|
+
|
|
54
|
+
1. Identify the exact error message or visual symptom.
|
|
55
|
+
2. Isolate the component causing the issue.
|
|
56
|
+
3. Determine the environment (SSR, CSR, mobile, specific browser).
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
### Phase 2 — Common Issue Diagnosis
|
|
61
|
+
|
|
62
|
+
**Hydration Errors (Next.js/SSR):**
|
|
63
|
+
- Cause: Rendering `window`, `localStorage`, or random data (e.g., `Math.random()`, Dates) on the first pass.
|
|
64
|
+
- Fix: Move client-only rendering inside a `useEffect` (isMounted pattern) or use dynamic imports with `ssr: false`.
|
|
65
|
+
|
|
66
|
+
**Too many re-renders:**
|
|
67
|
+
- Cause: Updating state directly in the render body, or inside a `useEffect` without proper dependencies.
|
|
68
|
+
- Fix: Move state updates into event handlers, or fix `useEffect` dependencies.
|
|
69
|
+
|
|
70
|
+
**Stale Closures:**
|
|
71
|
+
- Cause: A `useEffect` or `useCallback` is using old state because it's missing from the dependency array.
|
|
72
|
+
- Fix: Add dependencies, use refs (`useRef`) for mutable values, or use functional state updates (`setState(prev => prev + 1)`).
|
|
73
|
+
|
|
74
|
+
**CSS Z-Index/Stacking Issues:**
|
|
75
|
+
- Cause: Missing `position: relative/absolute` on parent, or a new stacking context was created.
|
|
76
|
+
- Fix: Inspect parent elements, adjust `z-index`, or use Portals for modals.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
### Phase 3 — Fix Application
|
|
81
|
+
|
|
82
|
+
Apply the minimal fix required to resolve the issue while preserving surrounding logic and styles.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Decision Tree
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
Is it a Hydration Error?
|
|
90
|
+
├── Yes → Is it caused by client-side APIs (window/localStorage)?
|
|
91
|
+
│ ├── Yes → Use `useEffect` to delay rendering until mounted
|
|
92
|
+
│ └── No → Check for mismatched HTML tags (e.g., <p> inside <p>)
|
|
93
|
+
└── No → Proceed to next check
|
|
94
|
+
|
|
95
|
+
Is it an infinite loop?
|
|
96
|
+
├── Yes → Check `useEffect` dependencies. Are objects/arrays re-created every render?
|
|
97
|
+
│ ├── Yes → Memoize them (`useMemo`) or move outside component
|
|
98
|
+
│ └── No → Ensure `setState` isn't called unconditionally in render
|
|
99
|
+
└── No → Proceed
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Output Format
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
🪲 Frontend Debug Report
|
|
108
|
+
─────────────────────────────────────────────────
|
|
109
|
+
Symptom: [Description of the bug]
|
|
110
|
+
Root Cause: [Explanation of why it failed, e.g., Stale Closure in useEffect]
|
|
111
|
+
|
|
112
|
+
🔧 Fix Applied:
|
|
113
|
+
[Brief description of the code change]
|
|
114
|
+
|
|
115
|
+
✅ Verification:
|
|
116
|
+
- Error no longer throws
|
|
117
|
+
- UI renders correctly
|
|
118
|
+
|
|
119
|
+
⚠️ Notes:
|
|
120
|
+
[Any side effects or things to watch out for]
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Validation Checklist
|
|
126
|
+
|
|
127
|
+
- [ ] Root cause clearly identified (not just patched)
|
|
128
|
+
- [ ] Fix is minimal and targeted
|
|
129
|
+
- [ ] No Hydration warnings remain
|
|
130
|
+
- [ ] Component doesn't infinitely loop
|
|
131
|
+
- [ ] No regression on related UI
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: frontend-performance
|
|
3
|
+
description: >-
|
|
4
|
+
Tối ưu hóa hiệu năng frontend: giảm kích thước bundle, chặn re-render thừa, lazy load và cải thiện Web Vitals.
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
category: frontend
|
|
7
|
+
tags: [performance, optimization, render, bundle-size, lazy-load, memoization]
|
|
8
|
+
platforms: [antigravity, claude-code, kilo-code, cursor, windsurf]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Frontend Performance Optimizer
|
|
12
|
+
|
|
13
|
+
> **Language rule:**
|
|
14
|
+
> Use **English** for: code, metrics (LCP, CLS, FID), technical terms (memoization, lazy loading).
|
|
15
|
+
> Use **the user's language** for: explanations, summaries, and questions.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Trigger
|
|
20
|
+
|
|
21
|
+
Activate this skill when:
|
|
22
|
+
- User reports "app is slow", "loading takes too long", or "UI freezes"
|
|
23
|
+
- Core Web Vitals (LCP, FID/INP, CLS) are failing
|
|
24
|
+
- React DevTools shows excessive re-renders
|
|
25
|
+
- `project-audit` flags a performance issue (P2)
|
|
26
|
+
- Need to optimize images, bundle size, or data fetching
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Scope
|
|
31
|
+
|
|
32
|
+
- ✅ **Render Optimization:** Prevent unnecessary re-renders (React `memo`, `useMemo`, `useCallback`).
|
|
33
|
+
- ✅ **Bundle Optimization:** Code splitting, lazy loading components/routes (`React.lazy`, Next.js `dynamic`).
|
|
34
|
+
- ✅ **Asset Optimization:** Image optimization (WebP, Next/Image, lazy loading `loading="lazy"`).
|
|
35
|
+
- ✅ **Data Fetching:** Caching, prefetching, pagination, virtualization for large lists.
|
|
36
|
+
- ✅ **Core Web Vitals:** Fix layout shifts (CLS), improve Largest Contentful Paint (LCP).
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Non-goals
|
|
41
|
+
|
|
42
|
+
- ❌ Do NOT blindly wrap everything in `useMemo` or `React.memo` (this can degrade performance).
|
|
43
|
+
- ❌ Do NOT optimize prematurely if there is no measured performance issue.
|
|
44
|
+
- ❌ Do NOT rewrite business logic unless it is the direct cause of the bottleneck.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Workflow
|
|
49
|
+
|
|
50
|
+
### Phase 1 — Identify the Bottleneck
|
|
51
|
+
|
|
52
|
+
Determine what kind of performance issue it is:
|
|
53
|
+
1. **Network/Load Time:** Slow initial page load, large bundle size, heavy images.
|
|
54
|
+
2. **Render/Runtime:** UI is sluggish, typing lags, animation stutters (too many re-renders).
|
|
55
|
+
3. **Data/Memory:** App crashes or slows down over time, large lists lagging.
|
|
56
|
+
|
|
57
|
+
### Phase 2 — Common Fixes by Category
|
|
58
|
+
|
|
59
|
+
#### 1. Fixing Unnecessary Re-renders (React)
|
|
60
|
+
- Move state down to the smallest possible component.
|
|
61
|
+
- Use `React.memo` for heavy pure components that receive the same props.
|
|
62
|
+
- Stable references: Use `useMemo` for expensive calculations or object props, and `useCallback` for function props passed to memoized children.
|
|
63
|
+
- *Warning:* Measure first! Memoization has an upfront cost.
|
|
64
|
+
|
|
65
|
+
#### 2. Fixing Bundle Size (Code Splitting)
|
|
66
|
+
- Are large libraries (like `lodash`, `moment`, `echarts`) imported entirely? Use named imports or alternative libraries.
|
|
67
|
+
- Lazy load routes or heavy components below the fold:
|
|
68
|
+
```typescript
|
|
69
|
+
const HeavyChart = React.lazy(() => import('./HeavyChart'));
|
|
70
|
+
// Wrap in <Suspense fallback={<Spinner />}>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
#### 3. Asset & UI Optimization
|
|
74
|
+
- Add fixed `width` and `height` to images to prevent Cumulative Layout Shift (CLS).
|
|
75
|
+
- Virtualize large lists (e.g., `react-window` or `@tanstack/react-virtual`) instead of rendering 1000 DOM nodes.
|
|
76
|
+
- Debounce rapid events (typing in search, window resize).
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
### Phase 3 — Implementation
|
|
81
|
+
|
|
82
|
+
Apply the targeted fix. Document why the fix improves performance.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Decision Tree
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
Is the issue related to initial load time?
|
|
90
|
+
├── Yes → Focus on Code Splitting (lazy loading), Image Optimization, and bundle size reduction.
|
|
91
|
+
└── No → Is the UI lagging during interaction?
|
|
92
|
+
├── Yes → Profile renders. Check for state updates triggering massive re-renders. Use `memo` or state colocation.
|
|
93
|
+
└── No → Is a specific list or table slow?
|
|
94
|
+
├── Yes → Implement virtualization (react-window) or pagination.
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Output Format
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
⚡ Performance Optimization Report
|
|
103
|
+
─────────────────────────────────────────────────
|
|
104
|
+
Target: [Component / Page]
|
|
105
|
+
Bottleneck: [Brief description, e.g., "Expensive list rendering on every keystroke"]
|
|
106
|
+
|
|
107
|
+
🔧 Fixes Applied:
|
|
108
|
+
✅ Extracted Search Input state to prevent list re-rendering
|
|
109
|
+
✅ Wrapped heavy `ChartComponent` in `React.memo`
|
|
110
|
+
✅ Lazy-loaded below-the-fold content (`Suspense`)
|
|
111
|
+
|
|
112
|
+
📈 Expected Impact:
|
|
113
|
+
- Reduced re-renders on typing from O(N) to O(1)
|
|
114
|
+
- Initial JS bundle size reduced by ~X KB
|
|
115
|
+
|
|
116
|
+
⚠️ Notes:
|
|
117
|
+
Please test this on lower-end devices to confirm smooth interactions.
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Validation Checklist
|
|
123
|
+
|
|
124
|
+
- [ ] Fix addresses the specific bottleneck
|
|
125
|
+
- [ ] No premature memoization applied blindly
|
|
126
|
+
- [ ] Layout shift (CLS) prevented (if changing images/layout)
|
|
127
|
+
- [ ] Application behavior remains completely unchanged
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: frontend-testing
|
|
3
|
+
description: >-
|
|
4
|
+
Viết Unit, Component và E2E test bằng Jest, Vitest, RTL, Cypress. Tập trung vào hành vi người dùng.
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
category: frontend
|
|
7
|
+
tags: [testing, jest, vitest, react-testing-library, cypress, playwright, tdd]
|
|
8
|
+
platforms: [antigravity, claude-code, kilo-code, cursor, windsurf]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Frontend Testing
|
|
12
|
+
|
|
13
|
+
> **Language rule:**
|
|
14
|
+
> Use **English** for: code, test descriptions (`it('should...')`), mock data, technical terms.
|
|
15
|
+
> Use **the user's language** for: explanations, summaries, and questions.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Trigger
|
|
20
|
+
|
|
21
|
+
Activate this skill when:
|
|
22
|
+
- User asks to "write tests for this", "add unit tests", or "test this component"
|
|
23
|
+
- Fixing a critical bug where a regression test is required
|
|
24
|
+
- Preparing for a major release and increasing test coverage
|
|
25
|
+
- Project audit flags missing tests for core business logic
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Scope
|
|
30
|
+
|
|
31
|
+
- ✅ **Unit Tests:** Test pure functions, utilities, and custom hooks.
|
|
32
|
+
- ✅ **Component Tests:** Test UI components using React Testing Library (RTL). Focus on user interactions and accessibility roles.
|
|
33
|
+
- ✅ **Mocking:** Mock API calls (MSW, Jest mocks), modules, and timers.
|
|
34
|
+
- ✅ **E2E Tests:** Write Cypress or Playwright tests for critical user flows.
|
|
35
|
+
- ✅ Follow the project's existing testing framework (Jest vs Vitest).
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Non-goals
|
|
40
|
+
|
|
41
|
+
- ❌ Do NOT test implementation details (e.g., checking if a specific state variable changed). Test what the user sees/does.
|
|
42
|
+
- ❌ Do NOT write brittle tests (e.g., querying by CSS class names). Use ARIA roles or `data-testid`.
|
|
43
|
+
- ❌ Do NOT introduce a new testing framework if one already exists.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Workflow
|
|
48
|
+
|
|
49
|
+
### Phase 1 — Environment Check
|
|
50
|
+
|
|
51
|
+
Identify the testing stack:
|
|
52
|
+
- Runner: Jest or Vitest?
|
|
53
|
+
- DOM: React Testing Library, Vue Test Utils?
|
|
54
|
+
- E2E: Cypress, Playwright?
|
|
55
|
+
- Mocking: MSW (Mock Service Worker), `jest.mock`, `vi.mock`?
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
### Phase 2 — Strategy & Coverage
|
|
60
|
+
|
|
61
|
+
Determine what needs testing:
|
|
62
|
+
1. **Critical Path:** Can the user complete the primary action?
|
|
63
|
+
2. **Edge Cases:** What happens on API failure? Empty state? Invalid input?
|
|
64
|
+
3. **Accessibility:** Can elements be found by role?
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
### Phase 3 — Writing the Test (RTL Example)
|
|
69
|
+
|
|
70
|
+
1. **Setup:** Render the component, wrap with necessary providers (Theme, Store, QueryClient).
|
|
71
|
+
2. **Query:** Find elements using `screen.getByRole`, `screen.getByLabelText`, or `screen.getByText`.
|
|
72
|
+
3. **Act:** Simulate user events using `userEvent` (preferred over `fireEvent`).
|
|
73
|
+
4. **Assert:** Expect elements to be in the document, disabled, or display specific text.
|
|
74
|
+
|
|
75
|
+
*Example:*
|
|
76
|
+
```typescript
|
|
77
|
+
it('submits the form when fields are valid', async () => {
|
|
78
|
+
const mockSubmit = vi.fn();
|
|
79
|
+
render(<LoginForm onSubmit={mockSubmit} />);
|
|
80
|
+
|
|
81
|
+
await userEvent.type(screen.getByLabelText(/email/i), 'test@example.com');
|
|
82
|
+
await userEvent.type(screen.getByLabelText(/password/i), 'password123');
|
|
83
|
+
await userEvent.click(screen.getByRole('button', { name: /login/i }));
|
|
84
|
+
|
|
85
|
+
expect(mockSubmit).toHaveBeenCalledWith({
|
|
86
|
+
email: 'test@example.com',
|
|
87
|
+
password: 'password123'
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
### Phase 4 — Mocking
|
|
95
|
+
|
|
96
|
+
If the component makes API calls:
|
|
97
|
+
- Prefer MSW (Mock Service Worker) for network-level mocking.
|
|
98
|
+
- Fallback: Mock the API service module or custom hook.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Decision Tree
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
Are we testing a pure function or utility?
|
|
106
|
+
├── Yes → Write a standard Unit Test (Jest/Vitest).
|
|
107
|
+
└── No → Are we testing a UI component?
|
|
108
|
+
├── Yes → Use React Testing Library (focus on user behavior).
|
|
109
|
+
└── No → Are we testing a full page flow?
|
|
110
|
+
├── Yes → Write an E2E test (Cypress/Playwright) or integration test.
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Output Format
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
🧪 Test Suite Generated
|
|
119
|
+
─────────────────────────────────────────────────
|
|
120
|
+
Target: [ComponentName or Utility]
|
|
121
|
+
Type: [Unit / Component / E2E]
|
|
122
|
+
Framework: [Vitest + RTL]
|
|
123
|
+
|
|
124
|
+
Tests Added:
|
|
125
|
+
✅ renders correctly in default state
|
|
126
|
+
✅ displays error message on API failure
|
|
127
|
+
✅ successfully submits user data
|
|
128
|
+
|
|
129
|
+
Mocking Used:
|
|
130
|
+
- MSW handlers for `/api/users`
|
|
131
|
+
- vi.fn() for onSubmit callback
|
|
132
|
+
|
|
133
|
+
🔗 Next Steps:
|
|
134
|
+
Run `npm run test` to execute the suite.
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Validation Checklist
|
|
140
|
+
|
|
141
|
+
- [ ] Queries use accessible methods (`getByRole`, `getByLabelText`)
|
|
142
|
+
- [ ] Events simulated with `userEvent` (if applicable)
|
|
143
|
+
- [ ] External dependencies/APIs are properly mocked
|
|
144
|
+
- [ ] Tests verify observable behavior, not internal state
|